28 lines
3.9 KiB
Markdown
28 lines
3.9 KiB
Markdown
# Phase 1C commerce API
|
||
|
||
All routes use /api/v1. Protected routes require a bearer session and current permissions. Organization and user scope come from the session. PUT replaces editable input fields. Module schemas define the field contracts.
|
||
|
||
| Routes | Permission |
|
||
| ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
||
| GET /products, /products/:id, /catalog-groups | catalog.read |
|
||
| POST /products, PUT /products/:id, POST /products/:id/variants, PUT /products/:id/variants/:variantId | catalog.manage |
|
||
| POST /catalog-groups, PUT /catalog-groups/:id | catalog.manage |
|
||
| PATCH /products/:id/status | catalog.publish |
|
||
| GET /storefront/:organizationId/products and /:id | Public, throttled |
|
||
| GET/POST /addresses, PUT/DELETE /addresses/:id | Authenticated, own addresses |
|
||
| GET /inventory/warehouses, /inventory/stock-items, /inventory/stock-items/:id, /inventory/stock-items/:id/ledger | inventory.read |
|
||
| POST /inventory/warehouses, /inventory/stock-items | inventory.manage |
|
||
| POST /inventory/adjustments | inventory.adjust |
|
||
| POST /inventory/reservations, GET /inventory/reservations/:id, POST /inventory/reservations/:id/release | inventory.reserve; reads/releases belong to creator |
|
||
| POST /inventory/reservations/:id/commit | inventory.commit, same organization |
|
||
|
||
Products begin as drafts. Publishing requires an active variant; archived products cannot be edited. Groups are categories or collections. Public lists contain summaries; details expose published products and active variants. Price input is a positive decimal string with two fractional digits, stored as exact Decimal(12,2) with explicit currency. Output may omit trailing zeroes. Lists and nested inputs are bounded.
|
||
|
||
Addresses are private, limited to 20 per user and have one default enforced by a partial unique index. Deleting the default selects a replacement when possible. Private address values are excluded from audits.
|
||
|
||
Stock quantities are integers. Opening stock is an adjustment. Adjustments require stockItemId, nonzero delta, reason and UUID idempotencyKey. Reservations require stockItemId, positive quantity, UUID idempotencyKey and optional ttlMinutes (1–60, default 15). Matching retries return the original result; changed input conflicts.
|
||
|
||
Availability equals on-hand stock minus unexpired active reservations. Stock row locks serialize changes. Expired holds stop consuming availability and cannot be committed. Release and commit are idempotent. Commit decrements stock and appends one ledger entry in the same transaction. A database trigger rejects ledger updates/deletes.
|
||
|
||
Existing system roles receive permissions through migration; custom roles require explicit grants. This phase covers finished goods. Checkout/orders and pricing snapshots follow in Phase 1D; procurement and production in Phase 2.
|