Skip to main content

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.md and resolved in wordpress-plugin/neuroon-search/includes/admin-page-wrapper.php.

Tab structure

TabVisiblePurpose
SettingsAlwaysAPI Key, Shop ID, Verify / Unverify, Developer Tools (URL override if WP_DEBUG).
ProductsAfter verifyingDataTables 1.13.6 server-side with per-product status, manual sync, Reset & Resync All.
WidgetAfter verifyingWidget Token generation / paste, color, locale, container.
DiagnosticsAfter verifyingBridge 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 expanding error_message).
  • NOT_SYNCED — orange (excluded by local rules: draft, no price, etc.).

AJAX endpoints

The admin exposes the following wp_ajax_* hooks:

ActionMethodPurpose
neuroon_start_syncPOSTStarts the queue: marks selected items as PENDING and kicks off the loop.
neuroon_sync_batchPOSTProcesses a batch (100 products) and returns partial results.
neuroon_sync_statusGETPolling: returns counters per status.
neuroon_resync_allPOSTMarks every product as PENDING (FULL sync).
neuroon_clear_failedPOSTClears 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.md and handlers in wordpress-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)

KeyTTLPurpose
neuroon_shop_info_{md5(api_key)}5 minQuotas (maxProducts, productsCount, etc.).
neuroon_rate_limit_{endpoint}dynamicActive block on 429.
neuroon_admin_notice45 sOne-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 = FAILED and their error_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 endpoint and retry_after).

Next steps