LAFU Sales Reports

CataSync feeds 4/6: OMA public feed URL, staff MCP tool, Feeds UI with field repeater

FeatureOpenView on roadmap· 12 days ago

Imported from GitHub issue El-SaMa/oma#247 by @El-SaMa.


Part of the Product feeds epic. Needs "Feeds model and builder" live in the engine.

What

Staff manage feeds in OMA; comparison sites (hinta.fi, Hintaseuranta, Hintaopas/Prisjakt, ...) fetch them from a public OMA URL.

Public URL

  • Next route apps/web/app/feeds/[token]/route.ts, served as https://oma.lanetti.fi/feeds/<token>.xml (or .csv). It calls core-api, which calls engine GET /v1/feeds/by-token/:token. Stream the body with the engine's content type, Cache-Control: public, max-age=900.
  • Unknown or disabled token: plain 404 with no detail. Rate limit per IP with the limiter already used for public routes. Never redirect; never expose internal hosts. Run scripts/public-smoke.mjs after deploy.
  • Tokens: 32 random bytes, base64url. Only the sha256 is stored. Shown once on create, duplicate and rotate, with a copy button.

Staff MCP tool

  • oma.admin_catasync_feeds with action: list (siteId), get (feedId), preview (feedId, limit), create (siteId, name, preset or full definition), update, duplicate, rotate_token, delete, rebuild.
  • Writes return a proposal + confirmToken and apply via oma.confirm_tool (handler in services/core-api/src/platform/confirm.ts). Engine client methods + types in services/core-api/src/catasync/engine.ts. Zod schema in services/mcp-server/src/tools.ts. Register in the tool registry like the other oma.admin_catasync_* tools.
  • Tests in services/core-api/src/agent-tools/tools-catasync.test.ts: validation, proposal shape, token only returned by create/duplicate/rotate confirms.

UI (apps/web/components/catasync/)

  • Shops > (shop) > new side-nav item Feeds (vertical side nav, never a second tab row).
  • Feed list as shadow cards: name, destination (URL / Google), format, item count, last built, skipped count, enabled toggle; buttons Edit, Duplicate, Copy URL, Rotate link, Delete (confirm modal).
  • New feed modal: name, preset (Google XML, hinta.fi, Hintaseuranta, Hintaopas (Prisjakt), CSV basic, Empty), destination, format.
  • Edit feed modal (wide):
    • settings and filters sections
    • the fields repeater: one row per field with drag handle (reorder), field name, kind (Source / Fixed text / Template), source select or value input, transform, max length, required, CDATA (XML only), remove; an "Add field" button
    • a live preview panel: first 5 items + skipped counts by reason, refreshed on save
  • Error codes mapped in catasync-shared.ts; every string en/fi/sv native.

Acceptance

  • Every oma.admin_catasync_feeds action called live through the MCP after deploy, on maxfort.
  • Public URL fetched from outside the LAN (a non-VPN host) returns the feed; a wrong token returns 404.
  • Public smoke passes after deploy.
  • Handbook: making a feed, presets, giving the URL to a comparison site, rotating a link.

Binding rules (read before coding)

  • Read CLAUDE.md and every .cursor/rules/*.mdc with alwaysApply: true first. 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 from src/db.mjs; core-api = TypeScript).
  • Every staff action goes through the admin MCP (admin-mcp-first.mdc): executor in services/core-api/src/agent-tools/tools-catasync.ts, confirm handler in services/core-api/src/platform/confirm.ts for writes, registry entry, zod schema in services/mcp-server/src/tools.ts, test in tools-catasync.test.ts. The UI calls the same tool (via apps/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-intl key with native en, fi, sv (Finnish must read native, not translated). No em/en dashes in prose. Run node 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 main right after each commit (rebase on origin/main first).
  • Deploy: engine with bash scripts/catasync-engine-roll.sh figaro; OMA only via the train bash scripts/deploy-quick.sh (never set OMA_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-connector with 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.

Comments (0)

No comments yet.

Join the discussion

Sign in to leave a comment on this thread.

HollahoopGet yours