WordPress · Admin dashboard
The plugin adds a single menu under Settings → Neuroon Search with several tabs. The default active tab depends on verification status: if you are not verified, only Settings is shown; once verified, Products, Widget and Diagnostics are enabled (progressive disclosure).
Citation: "default tab based on verification status" pattern described in
wordpress-plugin/CLAUDE.mdand resolved inwordpress-plugin/neuroon-search/includes/admin-page-wrapper.php.
Tab structure
| Tab | Visible | Purpose |
|---|---|---|
| Settings | Always | API Key, Shop ID, Verify / Unverify, Developer Tools (URL override if WP_DEBUG). |
| Products | After verifying | DataTables 1.13.6 server-side with per-product status, manual sync, Reset & Resync All. |
| Widget | After verifying | Widget Token generation / paste, color, locale, container. |
| Diagnostics | After verifying | Bridge status, API ping, rate limit counters, latest errors. |
Capabilities
Every admin action is protected by:
if (!current_user_can('manage_options')) {
wp_die(__('Insufficient permissions'));
}
That is, only administrators (manage_options capability) can touch the plugin. Nonces (wp_nonce_field / check_admin_referer / check_ajax_referer) block CSRF on every form.
Citation: security requirements (capabilities + nonces) listed in
wordpress-plugin/CLAUDE.md(Security Requirements section).
DataTables (Products tab)
The products table uses DataTables 1.13.6 server-side served locally from assets/vendor/ (no CDN), with paging, search and sort delegated to WP. This avoids extra CDN latency and the risk of blocking in restricted environments.
Rows by status (color-coded):
PENDING— gray.PROCESSING— blue (spinner animation).SYNCED— green.FAILED— red (with tooltip expandingerror_message).NOT_SYNCED— orange (excluded by local rules: draft, no price, etc.).
AJAX endpoints
The admin exposes the following wp_ajax_* hooks:
| Action | Method | Purpose |
|---|---|---|
neuroon_start_sync | POST | Starts the queue: marks selected items as PENDING and kicks off the loop. |
neuroon_sync_batch | POST | Processes a batch (100 products) and returns partial results. |
neuroon_sync_status | GET | Polling: returns counters per status. |
neuroon_resync_all | POST | Marks every product as PENDING (FULL sync). |
neuroon_clear_failed | POST | Clears FAILED rows so the next round retries them. |
Each handler does:
check_ajax_referer('neuroon_sync_nonce', 'nonce');
if (!current_user_can('manage_options')) {
wp_send_json_error('Insufficient permissions');
}
Citation: secure AJAX pattern in
wordpress-plugin/CLAUDE.mdand handlers inwordpress-plugin/neuroon-search/includes/product-sync-ajax.php.
Rate limit display
The admin shows the rate limit status per endpoint using transients:
neuroon_rate_limit_sync(per-minute window, 100/min).neuroon_rate_limit_shop-info(60/min).neuroon_rate_limit_verification(20/min).
When the plugin receives a 429, it parses Retry-After and blocks new calls until the transient expires. The UI prints a countdown timer.
Admin messages (transients)
Messages between POST handlers and the view are passed via:
set_transient('neuroon_admin_notice', array(
'type' => 'success',
'message' => __('Domain verified', 'neuroon-search')
), 45);
Citation:
wordpress-plugin/CLAUDE.md(Error Handling Pattern section).
This avoids the "post-redirect-get" pattern with query params exposed in the URL.
Local cache (transients)
| Key | TTL | Purpose |
|---|---|---|
neuroon_shop_info_{md5(api_key)} | 5 min | Quotas (maxProducts, productsCount, etc.). |
neuroon_rate_limit_{endpoint} | dynamic | Active block on 429. |
neuroon_admin_notice | 45 s | One-shot messages. |
Diagnostics tab
Prints:
- Plugin version (
NEUROON_VERSION). - Loaded widget version (
NEUROON_WIDGET_VERSION+ SRI hash). - Result of the latest
GET /api/plugin/shops/me. - Cart bridge status (jQuery detected / not detected).
- Last 10 entries with
status = FAILEDand theirerror_message. - Run health-check button that fires a live call and shows it raw.
Logs
With WP_DEBUG_LOG = true, plugin errors are written to wp-content/debug.log. The plugin logs:
- HTTP errors on API calls (status + body truncated to 1 KB).
- Exceptions in WC hooks.
- Rate-limit blocking events (with
endpointandretry_after).
Next steps
- Product sync — batch loop details.
- Cart bridge — how it connects with the widget.
- Authentication · Rate Limits — full policy.