CataSync feeds 1/6: connector 0.9.0 read endpoint /catalog
Imported from GitHub issue El-SaMa/oma#244 by @El-SaMa.
Part of the Product feeds epic. Build first.
What
Add a signed, read-only REST route POST /wp-json/lafu-catasync/v1/catalog to ops/catasync/plugins/lafu-catasync-connector that returns published products with everything a feed needs. Version 0.9.0.
Exact spec
- Register in
includes/class-lafu-catasync-connector-rest.phpnext to/inventory, samepermission_callback(Lafu_Catasync_Connector_Auth::verify), same WooCommerce-missing guard. - Params:
page(>=1),per_page(1..100, default 100), optionalmodified_after(ISO 8601 UTC; return only products withdate_modifiedafter it). - Implement
Lafu_Catasync_Connector_Products::catalog( $page, $per_page, $modified_after )inclass-lafu-catasync-connector-products.phpusingwc_get_productswithstatus => publish,type => simple, variable,orderby => ID,order => ASC,paginate => true, plusdate_modified => '>' . timestampwhen given. - Variable products: one row per purchasable, published variation (with
item_group_id= parent id) plus no row for the parent. Simple: one row. - Row fields (all strings or null, never PHP notices):
id,parent_id,sku,ean(get_global_unique_id),mpn(meta_lafu_catasync_mpnif present else null),name,short_descriptionanddescription(raw HTML,editcontext),permalink(get_permalink),image(main image URL),gallery(array of URLs, max 10),regular_price,sale_price,price(wc_get_price_including_taxwith the shop's tax display, 2 decimals),currency(get_woocommerce_currency),stock_status,stock_quantity,backorders,weight,shipping_class(slug or null),categories(array of full paths likeTietokoneet > Näytönohjaimet),brand(firstproduct_brandterm name or null),energy_class(meta_lafu_eu_energy_class),lead_text(meta_lafu_catasync_lead_text),catasync_id(meta_lafu_catasync_idor null),date_modified(ISO UTC). - Response:
{ items: [...], total, pages, now }wherenowis the server time ISO UTC (engine uses it as the nextmodified_after). - Performance: prime caches (
_prime_post_caches,update_meta_cache) for the page; no per-rowget_termsloops beyond what WooCommerce caches. A 100-row page must answer in under 2 s on niletech. readme.txtchangelog +Stable tag+ plugin header +LAFU_CATASYNC_CONNECTOR_VERSIONall 0.9.0.
Not in scope
No writes, no settings page changes, no Google code in the plugin.
Acceptance
- Gate
scripts/wp-plugin-gate-remote.sh ops/catasync/plugins/lafu-catasync-connector= 0 errors 0 warnings; security check written in the PR/commit notes (auth, escaping not needed for JSON, no unbounded queries). - Installed on maxfort.fi first; signed call returns rows for simple and variable products,
modified_afterfilters correctly, timing logged. - Then installed on niletech the same way earlier versions were (see
ops/catasync/README/ handbook CataSync section "Connector"); 100-row page < 2 s measured. - Handbook line added (connector routes list).
Binding rules (read before coding)
- Read
CLAUDE.mdand every.cursor/rules/*.mdcwithalwaysApply: truefirst. They win over your defaults. - No OpenAI / AI calls anywhere in this feature. CataSync AI switch (
ai_enabled) stays off. Never turn it on. - Smallest correct change. Match the surrounding code style (engine = plain ESM
.mjs, mysql2 pool fromsrc/db.mjs; core-api = TypeScript). - Every staff action goes through the admin MCP (
admin-mcp-first.mdc): executor inservices/core-api/src/agent-tools/tools-catasync.ts, confirm handler inservices/core-api/src/platform/confirm.tsfor writes, registry entry, zod schema inservices/mcp-server/src/tools.ts, test intools-catasync.test.ts. The UI calls the same tool (viaapps/web/lib/catasync/admin-actions.ts), never a separate path. - UI: vertical side nav only (never a second tab row), forms in modals, shadow cards, full width (
portal-chrome.mdc). - Every string:
next-intlkey with native en, fi, sv (Finnish must read native, not translated). No em/en dashes in prose. Runnode scripts/i18n-validate.mjs. - Handbook: update
apps/web/content/admin-docs/products/catasync.md(new section) for every behaviour you add. - Secrets (tokens, Google tokens, feed tokens) never in logs, commits, handbook or chat.
- Commits: author ELSAMA only, no Co-authored-by / AI attribution. Push to
mainright after each commit (rebase onorigin/mainfirst). - Deploy: engine with
bash scripts/catasync-engine-roll.sh figaro; OMA only via the trainbash scripts/deploy-quick.sh(never setOMA_DEPLOY_SERVICES, never build on the VM). Check the live SHA contains your commit. - WordPress plugin changes: bump version, pass
scripts/wp-plugin-gate-remote.sh ops/catasync/plugins/lafu-catasync-connectorwith 0 errors 0 warnings + security check (wp-plugin-dod.mdc). Install on maxfort.fi first (test shop), only then niletech. - Never change niletech prices, statuses, shipping rows or the Code Snippets / table-rate plugins as part of this work.
- Clean up test data and temp files when done.