Review queue
Every AI generation lands here unless auto_approve = Yes. Marketing → SEO Suite → AI Meta Suggestions.
Status lifecycle
┌──→ pending ──→ approved ──→ applied
trigger ────┤
└──→ failed (terminal — see error column)
| Status | Meaning |
|---|---|
pending | Generated successfully, awaiting human approval |
approved | Human approved but apply has not yet run (rare — only happens if Approve & Apply fails midway) |
applied | Written to entity meta_title + meta_description |
rejected | Editor explicitly rejected — kept for history but never applied |
failed | Generation failed (API error, JSON parse error, etc.) — see error column |
Per-row actions
- Approve & Apply → calls
SuggestionApplier, writes meta to product/category/CMS, sets status=applied. The admin success message names the entity and the store the value was written to (e.g. "Suggestion #14 applied to Joust Duffle Bag (store en). Values are store-scoped — switch the admin scope selector to see them.") so editors aren't confused when the field looks empty at default admin scope (see below). - Reject → sets status=
rejected
Rows with status=applied, failed, or rejected show no per-row actions.
Where the value actually lands — store-scope visibility
meta_title and meta_description are store-view-scoped EAV attributes on Magento products and categories. When you Approve & Apply a suggestion generated for store en (store_id=1), the EAV row written is (product_id, attribute_id, store_id=1). Opening the product edit page from the catalog grid loads it at Default Config / All Store Views scope (store_id=0) — and that scope shows the global value, not the en-scope one. So the meta fields can look blank even though the value was saved correctly.
To see the applied value: switch the scope selector at the top-left of the product edit page to the matching store view. The "Use Default Value" checkbox next to each field will be unticked and the AI text will be in the input.
Same applies for CMS pages — Magento CMS pages have store-scoped meta too. Categories follow the same EAV pattern as products.
Mass actions
- Approve & Apply — batches the same flow for multiple rows (skips already-finalised statuses)
- Reject — bulk reject
- Delete — permanently remove rows from the queue (does not revert applied changes)
Columns
| Column | Source |
|---|---|
| ID | entity_id (PK of the suggestion table, not the target product) |
| Entity | product, category, cms_page |
| Target ID | Product/category/cms_page ID |
| Store | The store_id the suggestion was generated for |
| Suggested Meta Title / Description | The Claude output (post-truncation) |
| Model | claude-haiku-4-5 etc. |
| Out Tokens | Output tokens billed |
| Cached | Cache-read input tokens (cost ~10% of fresh input) |
| Status | See lifecycle above |
| Batch | The batch_id set by the trigger (CLI: cli-YYYYMMDD-HHMMSS, cron: cron-…-store{N}, in-context: not persisted) |
| Created | When the row was inserted |
Filters
Filter by status, entity type, batch_id, model, dates. Useful patterns:
- Status = pending → daily review queue
- Status = failed + Batch starts with
cron-→ check cron run failures - Batch = a specific run → review a specific bulk job before approving
What "Apply" actually writes
For each entity type:
- Product →
setData('meta_title', ...),setData('meta_description', ...),productRepository->save() - Category → same with
categoryRepository->save() - CMS page →
setMetaTitle(),setMetaDescription(),pageRepository->save()
Save fires the standard Magento save events (controller_action_predispatch_*, plugins on the repository, etc.) — so any other modules that observe meta_title changes will see them too.
Cleaning up old rows
There's no automatic retention — the queue grows unbounded unless you delete old rows. For high-volume catalogs, consider:
- A scheduled
bin/magentoscript that deletesappliedrows older than 90 days - Mass-delete from the admin grid filtered by Date < N days ago
Roadmapped for v2.9: a config-driven retention cron.
Failure recovery
If a run produces lots of failed rows, click into the row to see the error field. Common causes:
- API key missing/invalid → fix in config and re-run via CLI with same
--batchID - Rate-limited → reduce
cron_budget_per_runor split CLI batches with--limit - JSON parse error → usually transient; rerun the affected target IDs
Failed rows are kept in the queue (don't auto-clean) so you have an audit trail of cost spent on unsuccessful generations.
Privacy / data residency
Anthropic processes the prompts in the US (Anthropic) or EU (via Bedrock if you reroute, but the SEO Suite calls the Anthropic API directly). The data sent is product/category source data — names, descriptions, SKUs, prices. If your catalog contains regulated data (e.g. medical products with sensitive descriptions), review your Anthropic enterprise terms before enabling.