# Mothercare TDL Factory API contract The public UI uses tdl-data.js for the reviewable static catalogue. The production API is designed for a Cloudflare Worker, D1/Postgres adapter or Supabase Edge Function. ## Public catalogue - GET /api/v1/tdls?query=&category=&source=&page=1&pageSize=24 - GET /api/v1/tdls/:slug - GET /api/v1/tdls/:slug/compatibility `GET /api/v1/tdls/:slug` returns the published duration variants as `variants[]` with `durationCode`, `durationLabel`, `regularAmount`, `offerAmount`, `currency`, `gstRate` and `isAvailable`. The browser may display these values, but the order endpoint always re-reads the active variant from the database. ## Checkout and payments 1. POST /api/v1/orders validates product version, customer, `durationCode` and the active `tdl_product_variants` row server-side. Never trust the browser's amount. 2. POST /api/v1/orders/:orderNumber/payment-intent creates a Razorpay or Stripe payment order. 3. POST /api/v1/payments/webhook verifies provider signature and marks the order PAID. 4. GET /api/v1/orders/:orderNumber returns customer-safe order status. ## TDL licensing - POST /api/v1/licenses/activate accepts a one-time licence key, company fingerprint, device fingerprint and app version. - POST /api/v1/licenses/heartbeat refreshes activation status and returns entitlements. - POST /api/v1/licenses/deactivate releases an activation after authentication. - GET /api/v1/licenses/:publicId/download-token creates a short-lived download token. Use hashed licence keys and hashed company/device fingerprints. Keep provider secrets and signing keys in managed secrets, never in browser JavaScript. ## Admin operations All admin endpoints require a session with admin:tdl scope and a server-side audit log: - POST /api/v1/admin/tdls - PATCH /api/v1/admin/tdls/:id - POST /api/v1/admin/tdls/:id/publish - POST /api/v1/admin/tdls/:id/pause - POST /api/v1/admin/tdls/:id/variants - PATCH /api/v1/admin/tdls/:id/variants/:variantId - POST /api/v1/admin/tdls/:id/variants/:variantId/archive - GET /api/v1/admin/orders - POST /api/v1/admin/licenses/:id/revoke - GET /api/v1/admin/audit-logs Production sequence: catalogue -> order -> payment intent -> hosted gateway -> signed webhook -> paid order -> signed licence -> secure download -> activation heartbeat. ## Account access and admin governance The account page supports three public roles and a protected control desk. The production service must enforce these checks on the server with an HttpOnly session cookie; browser storage is only a static preview fallback. - `POST /api/v1/auth/signup` — create a `CUSTOMER`, `JOB_SEEKER` or `EMPLOYER` profile after validating email ownership and password policy. - `POST /api/v1/auth/login` — issue a short-lived session for the requested role; `ADMIN` and `OWNER` sessions require the `admin:tdl` scope. - `POST /api/v1/auth/password-reset` — always return a generic response, create a single-use hashed token with a 30-minute expiry and send the link to the signed-up email. - `POST /api/v1/auth/password-reset/confirm` — consume the token and replace the password hash; revoke active sessions. - `GET /api/v1/auth/me` and `POST /api/v1/auth/logout` — read and close the current server session. - `GET /api/v1/admin/tdls` — list draft, published and paused catalogue records for an authorised admin. - `POST /api/v1/admin/tdls/:id/upload` — issue an R2 signed upload URL, then verify checksum, file type and ownership before publishing the package. - `GET /api/v1/admin/tracking` — return order, licence, account and audit summaries with server-side pagination. - `GET /api/v1/admin/owners`, `POST /api/v1/admin/owners` and `DELETE /api/v1/admin/owners/:accountId` — grant or revoke the `FULL_ADMIN` owner scope for a signed-up account. Every grant and revoke is written to the audit log. The static site includes the complete reviewable role flow and a device-local demo so the pages can be tested without bindings. Move password hashes, reset mail, sessions, upload bytes and owner checks to these endpoints before production use.