Skip to content

title: API (production): phase 1 design (Oct–Dec 2026) component: API level: phase period: sprints S2–S5 (1 Nov – 26 Dec 2026); S1 work carried in status: draft 1 (25 Oct) owner: MMDEP Design (Claude) decisions: TD-049, TD-050, TD-057 overall: api/overall.md queues: docs/prompts/api-lane-p/S2/QUEUE.md (P1–P4)


API (production): phase 1

1. Goal

By the end of phase 1 the production API is the secured, documented, honest door to MF data: write routes need keys, NAV has no duplicates, every route is in the contract, and MM-Cron writes only through it.

2. Baseline (collector, 25 Oct)

Check Value
/api/health 404 (missing)
/api/schemes 200, 10,008 schemes, ~4.0 s
/api/scheme/nav?scheme_code=120245 200, 3,379 rows, 3 duplicate dates, one 10-day gap (Feb 2025), latest 23 Oct
/api/index/nav?symbol=NIFTY 50 200, 2,723 rows, 10 duplicate dates, latest 23 Oct
/category 200, 180 categories; flags returned as 1 (to verify against the database, HO-18 #7)
Write routes No key enforced; /save-nav key hard-coded in code (KN)
Contract No OpenAPI, no data dictionary (HO-18 #1–2)

3. Work streams and milestones

Stream S2 (1–14 Nov) S3 (15–28 Nov) S4 (29 Nov–12 Dec) S5 (13–26 Dec)
A. Write security (P1) Enforcement LLD (Claude reviews); keys issued per consumer; log-only on staging and production Enforced on staging (day 1); enforced on production after 7 clean log-only days, Atul approves Read-route rate limits and caching; non-public reads keyed Old hard-coded key retired everywhere
B. NAV integrity (P2) Read-only audit: duplicate keys and gaps for every scheme and index; writer root cause (with Lane S S5 inventory) De-dup and persistence-contract LLD (Claude reviews); rehearsal on staging Production de-dup and unique key, Atul approves; backup and rollback first Freshness alert stable; gap report published
C. Release 2 (P3) /api/health, /category stored flags plus effective menu tree, stale-connection fix, /api/index/nav and /api/nfos/active fixes from staging: one RC, MWMC and MCRM UAT, Atul approves — — —
D. Contract OpenAPI draft from code (S4 Lane S); fund-factsheet contract (P4) for MWMC Contract tests on stgapi in CI; data dictionary, catalogue tables Dictionary, MF tables; every route in the contract Breaking-change check in CI (contract diff)
E. Ingest routes (for MM-Cron) Spec in the OpenAPI file: scheme, fund-details, holdings, AUM, TER, performance, NFO, index, run-log (TD-057) Built and on staging; MM-Cron staging runs use them On production with keys; MM-Cron production enabled family by family Direct-write code paths removed
F. Holdings — New holdings read route on mm_portfolio / mm_portfolio_items; old route unchanged (TD-058) Consumers moved (MWMC fund pages) Old route marked deprecated
G. Operations Production release sha recorded; structured logs Error tracking; backups verified, restore drill on staging (roadmap §3) Incident runbook —
H. APIs only Direct-reader inventory complete (websites, plugins, webapp) Missing read routes specified for the top readers First website reads moved to the API (MWMC) Plan for the rest (phase 2)

Release cadence: one production release per sprint (S2 to S5), each a single RC MR from api-phase1-staging-release with evidence and consumer UAT. Security and data fixes ride the release; emergency fixes follow the same gate faster.

4. Ingest routes (TD-057)

One pattern for every MM-Cron record type, so MM-Cron's publisher has a single client:

POST /api/ingest/<type>          type ∈ nav | scheme | aum | ter | performance | nfo | fund-details | holdings | index | runs
Header: X-MM-Key: <consumer key>  (environment-specific; production rejects staging keys)
Body:   { "run_id": "...", "source_id": "S6", "raw_sha256": "...", "schema": "mmcron/v1", "records": [ ... ] }
Reply:  { "run_id": "...", "accepted": n, "unchanged": n, "corrected": n, "rejected": [ {"index": i, "reason": "..."} ] }
  • Idempotent: a repeat of the same body gives unchanged, never duplicates.
  • Corrections are recorded, not silently applied (TD-050).
  • The reply is the API acknowledgement that closes MM-Cron's traceability chain (KN).
  • /save-nav stays for existing callers. It becomes a thin alias of /api/ingest/nav once the P2 rule is in, so both follow one persistence rule.
  • Schemas come from the MM-Cron adapter schema (sprint-2 LLD), so they are defined once.

5. Interfaces that change

Interface Change Breaking? Consumers to check
All write routes Key header required Yes, for writers MM-Cron, admin panel, staging loader, website forms (server side)
/category Stored flags instead of 1; new effective menu tree Possibly (flag values) MWMC, WPDev, MCRM
NAV routes No duplicate dates after P2; as_of added Additive plus a data fix PE, MWMC, websites
/api/health New No Collector
/api/ingest/* New No MM-Cron
Holdings New route; old unchanged No MWMC, PE

6. Risks

Risk Impact Mitigation
Key enforcement breaks an unknown writer (a form, a script) Lost leads or stopped jobs 7 days log-only: every unkeyed write is logged with its caller; enforcement only when the log shows none left
NAV de-dup removes the wrong row Wrong history for funds Audit first; rule decided per duplicate type; backup table; staging rehearsal; Atul approves; rollback script tested
Unique constraint on ~37M rows locks the table API slow or down Built on a copy then swapped, or added online off-hours; timed on staging first
Shared host: API, WordPress and stgapi compete Slow pages stgapi caps (TD-051); /api/schemes caching (4 s today)
Production runtime sha unknown Unsafe rollback First release records it, and keeps the previous artifact
One agent for Lane P and Lane S until API-2 Throughput Queues ordered by risk; low-risk items to the harness

7. What "done" means for phase 1

  • [ ] Every write route rejects calls without a valid key on production (log shows zero unkeyed writes for 7 days).
  • [ ] Zero duplicate (scheme_code, nav_date) and (symbol, date) in production; a unique key prevents new ones; the collector's duplicate column is empty.
  • [ ] /api/health returns the release sha on production and staging.
  • [ ] Every route is in docs/openapi.yaml; contract tests pass on stgapi in CI; the dictionary covers catalogue and MF tables.
  • [ ] MM-Cron writes only through /api/ingest/* and /save-nav with keys.
  • [ ] /category returns stored flags and the effective menu tree, accepted by MCRM and MWMC UAT.
  • [ ] Every production release in phase 1 had an RC MR, evidence, UAT lines, a recorded sha and a rollback.