← INDEXCH 08 / 1009 MCP →

CHAPTER 08Webservices (API)

Req. prefix: APv0.3 draft

The API is the system's real surface for forecast-modification management; the UI (Ch. 07) and MCP (Ch. 09) are clients of it. Master data has no write surface anywhere (D-23) and only minimal reference reads here. Operations are specified technology-agnostically; the HTTP/JSON notation below is illustrative. Any protocol offering equivalent operations, payloads and error semantics conforms.

AP-01Parity: every forecast-modification, reporting, batch and admin capability of Ch. 04–07 and Ch. 10 is an API operation. There is no UI-only or MCP-only function; the sole UI-only surface is the read-only master-data browser (S5), which the API mirrors only as the reference reads of GET /masterdata/… (D-23).
AP-02Authentication: login with one of the two fixed accounts yields a bearer token; all other operations require it. No authorization differences between accounts (OV non-goals).

8.1Operation catalogue

GroupOperation (illustrative)Behaviour / spec refs
EntriesGET /entriesList; filters = UI-01 columns; pagination; sort
POST /entriesCreate → synchronous disaggregation (HE-06); response = entry incl. state, error_message, LO row count
GET /entries/{id}Entry detail
PUT /entries/{id}Update → synchronous re-disaggregation, atomic replace (DM-12)
DELETE /entries/{id}Hard delete entry + its LO rows (HE Lifecycle)
POST /entries/{id}/disaggregateManual per-entry re-run
PreviewPOST /entries/previewDry-run: full entry payload in → would-be disaggregation summary or error out; nothing persisted (UI-05)
LOGET /entries/{id}/loThe entry's LO rows; paginated
POST /lo/queryAggregation query: group-by set (hierarchy level, location, week/month/quarter, entry) + filters → aggregated cells. Powers S3. ≤ 2 s (DF-12). Default excludes stale (HE-09); flag include_stale
BatchPOST /batch/runStart batch (409 if one is running, DF-09)
GET /batch/currentLive progress (entries done/total, elapsed)
GET /batch/lastFull DF-08 report
ReferenceGET /masterdata/…Read products/hierarchy/attributes (incl. distinct values per attribute name for the UI-04 pickers), locations, customers, calendar. No writes exist (D-23)
AdminPOST /admin/resetRestore seed profile (body: profile id); OV-05 / DE-04
POST /admin/regenerate-forecastRegenerate the synthetic forecast with a new deterministic seed (DE-08); sets all entries RequiresDisaggregation (HE-07)
GET /admin/statusActive profile, counts (entries, LO rows), last regeneration & batch timestamps
ExportPOST /lo/exportSame body as /lo/query, streams CSV (UI-10)
AuthPOST /auth/loginusername/password → token (AP-02)

8.2Payload & error model

AP-03Entry payloads carry the full Ch. 03 §3.7 attribute set; the product scope is the uniform pair {"attribute": …, "value": …} of DM-02. State and error_message are server-assigned and read-only in requests.
AP-04Validation failures (HE-04) return a machine-readable error: stable code, human message, and details[] naming each offending field/key. Disaggregation failures are not API errors: the operation succeeds and returns the entry in InError.
AP-05Every write response and error MUST be sufficient for a client to render the same information the UI shows — no UI-privileged data channel.
AP-06List operations paginate (cursor or offset) with a documented maximum page size; /lo/query responses cap at a documented cell limit and say so explicitly when capped.

8.3Semantics

AP-07Create/update/delete of entries are synchronous end-to-end: when the response returns, HI and LO are consistent (OV-02).
AP-08POST /batch/run returns immediately with a run id; progress via /batch/current. Exactly one run at a time (DF-09).
AP-09Forecast regeneration is atomic: readers see either the previous or the new complete forecast, never a mixture; on success all entries transition to RequiresDisaggregation (HE-07). Regeneration is rejected (409) while a batch is running.
AP-10Timestamps in responses are UTC ISO-8601. Quantities are integers in SU (fractions only inside the generated forecast, DM §3.4).
AP-11Concurrent writes to one entry: last-write-wins; no locking. (Demonstrator simplification; noted in decisions log.)
AP-12Export streams; it MUST NOT buffer the full result server-side, and it carries the same staleness semantics as /lo/query.

8.4Illustrative exchange

POST /entries
{ "title": "B1 spring campaign",
  "product_scope": { "attribute": "brand", "value": "B1" },
  "location_scope": "ALL", "customer_scope": null,
  "period": {"type":"month","id":"M1"}, "value_su": 1000 }

→ 201
{ "entry_id":"e-0042", "state":"Disaggregated", "error_message":null,
  "lo_row_count": 13, "value_su": 1000, ... }         // matches example E6-A

Equally valid product scopes through the same mechanism: {"attribute":"upc","value":"U2"} · {"attribute":"product_id","value":"P2"}.