Verified zero remaining callers for each before deleting (grepped
src/app for every method name individually), not assumed from the
earlier commit's dead-code note.
Deleted from api.service.ts:
- createPayment() - legacy direct QR creation (POST {qrBaseUrl}/qr)
- createCartPayment() - legacy /cart payment creation, client-sent amount
- createPaymentIntent() - superseded by @marketplaces/payment's gateway
- checkCartPaymentStatus(), checkCartCardPaymentStatus(), checkPaymentStatus()
- legacy QR/card status polls, superseded by the same gateway
- resolvePaymentQrId/resolvePaymentQrUrl/resolvePaymentLink/
resolveBankPaymentUrl - QrCreateResponse field-normalization helpers,
no longer had a caller once the methods above were gone
- Types: QrCreateRequest, QrCreateResponse, CartPaymentRequest,
PaymentIntentRequest, QrDynamicStatusResponse
- Fields: qrBaseUrl, cartPaymentPartnerId - no longer read by anything
- Imports: HttpHeaders, environment - no longer used in this file
Did NOT touch createOrder() or createCheckoutSession() - both still have
live callers in cart.component.ts, confirmed before deciding what to keep.
cart.component.ts: corrected the createPaymentIntent() comment, which
referenced the deleted method/helper names, to name what actually got
deleted instead of what was merely "dead as of that commit."
docs/backend/FRONTEND-API-SURFACE-COMPLETE.md: moved the 4 now-deleted
QR/card endpoints out of the "still live" legacy table into a dated removal
note - the doc's own premise is "every endpoint this codebase currently
calls," so it was wrong to leave them listed as called once they weren't.
Legacy-undocumented count corrected 15->11, total 97->93.
Verified: production build succeeds (no dangling references), 247/247 unit
tests, arch:check clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
28 KiB
Complete Frontend API Surface — Master Endpoint List
Generated 2026-08-18, updated same day after the frontend backlog (F1–F65) closed, updated again same day to add §0 after a direct question ("everything is there? payment auth?") caught that the first pass only grepped src/app/ — auth moved into the external @marketplaces/auth package this session, and its own HTTP calls (§0) were missing from what this doc called "complete." Fixed by grepping node_modules/@marketplaces/auth/dist/ directly. Directly from source (every this.http.get/post/patch/put/delete call across src/app/core/, src/app/features/admin/, src/app/services/api.service.ts, and now the auth package). This is not a design document — it is a census: every endpoint this codebase currently calls or will call once its gateway swap goes live, in one place, cross-referenced against the contracts that already exist.
This is the final handoff doc for this pass. Frontend work is done except one item that genuinely cannot be finished without a live backend (§19). Everything else — every gateway, every model, every invariant — is written, tested, and pushed. What follows is everything backend needs to make it real.
Why this exists. The individual Phase/Track contracts in this directory each cover one domain well. Nothing until now listed the entire surface in one pass, so a backend dev building against these docs had no way to see what's fully specified, what's inferred-and-needs-confirmation, and what has no contract at all. This closes that gap.
Status legend
| Status | Meaning |
|---|---|
| ✅ Specified | Exact shape exists in a Phase/Track contract doc. Build as written. |
| ⚠️ Inferred | Endpoint follows this codebase's own REST conventions (path pattern, verb) but no contract doc states it explicitly. Flagged in source with a comment at the call site. Confirm or correct before building — do not treat as final. |
| ❌ Undocumented | Legacy endpoint, no contract anywhere, still called by api.service.ts. Will be replaced when the corresponding /api/v2 migration lands (Track N) — do not invest in these long-term, but they are live today. |
0. Auth — lives in @marketplaces/auth, not this repo, and payment authorization runs through it
Two separate, real mechanisms. Both are called from the external package (node_modules/@marketplaces/auth/dist/), which is why §0 didn't exist in the first pass of this doc — that pass only grepped src/app/.
0.1 Telegram QR/session — ✅ Specified, live
Per BACKEND-HANDOFF.md §3 and PACKAGES-USAGE.md. Customer and admin login call the same endpoints — only client-side storage differs, which is exactly why every admin endpoint must independently verify authorization server-side (stated plainly in BACKEND-HANDOFF.md §3 as "the single most serious open issue in the system").
| Method | Path | Purpose |
|---|---|---|
| POST | {authApiUrl}/users/sessions |
create a session from a Telegram login |
| GET | {authApiUrl}/users/sessions/{id} |
poll / check session status |
| DELETE | {authApiUrl}/users/sessions/{id} |
log out |
Expected response: { webSessionID, user: { userId, username, firstName, lastName }, status, expiresAt } — parsed permissively client-side (many key-name variants accepted), but a clean backend implementation should return exactly this shape.
0.2 Ed25519 admin challenge/response — specified, not built
Per BACKEND-HANDOFF.md §3 and the package's own ed25519/models/auth-api.model.ts. This is what backend-authorizes an admin session distinctly from a customer one, and it does not exist server-side yet — every request today shows a backend-unavailable screen once the client reaches for it, nothing is mocked.
| Method | Path |
|---|---|
| GET | /api/admin/auth/challenge |
| POST | /api/admin/auth/verify |
| POST | /api/admin/auth/refresh |
| POST | /api/admin/auth/logout |
0.3 What this has to do with payment
There is no separate "payment login." Authorization for anything payment-adjacent — creating a checkout session, viewing GET /api/admin/v2/orders/{id}'s pricing breakdown (§20), touching a partner credential (§16) — rides on whichever of the two sessions above is active. The partner-provisioning API (§16) has its own, separate signed-request auth (§6 of that contract, public-key based, no session token at all) — that one is unrelated to Telegram/ed25519 and is not a gap, it's a different, already-built mechanism for a different caller (partners, not our own admins or customers).
The actual payment gap is §1 below, not auth: QR/card payment creation and status polling are real, live, and completely undocumented anywhere in docs/backend/.
1. Legacy surface (still called today, no /api/v2 contract)
These come from BACKEND-API-REFERENCE.md, not docs/backend/. Base URL is environment.localhostApiUrl / tenant-resolved; qrBaseUrl is a separate provider base for QR-specific calls.
| Method | Path | Called from | Status |
|---|---|---|---|
| GET | /ping |
api.service.ts |
❌ Undocumented — health check |
| GET | /category |
api.service.ts, api-category.repository.ts |
❌ Undocumented — full category tree |
| GET | /category/{categoryID} |
api.service.ts |
❌ Undocumented — one category + its items |
| GET | /items/{itemID} |
api.service.ts |
❌ Undocumented — single item detail |
| GET | /searchitems |
api.service.ts |
❌ Undocumented — search |
| GET | /items/randomitems |
api.service.ts |
❌ Undocumented — related/random items |
| POST | /websession/{sessionId} |
api.service.ts |
❌ Undocumented — sync cart to a Telegram web session |
| POST | /items/{itemID}/callback |
api.service.ts |
❌ Undocumented — "call me back" request |
| POST | /items/{itemID}/questiion |
api.service.ts |
❌ Undocumented — product Q&A (note: questiion typo is load-bearing, do not silently "fix" without checking the live backend uses the same typo) |
| POST | /items/{itemID}/notify-me |
api.service.ts |
❌ Undocumented — back-in-stock subscription |
| POST | /purchase-email |
api.service.ts |
❌ Undocumented — post-purchase email collection |
| POST | /orders |
api.service.ts |
❌ Undocumented — records a paid cart as a backoffice order, fire-and-forget |
Recommendation: these 11 need their own contract doc if they are staying, or a deprecation timeline if /api/v2/storefront/* replaces them. Right now they are simply undocumented and live — the single biggest gap in docs/backend/.
Removed 2026-08-21, no longer called by this codebase: POST {qrBaseUrl}/qr (direct QR creation), POST /cart (legacy payment creation with client-sent amount), GET {qrBaseUrl}/qr/dynamic/{partnerId}/{qrId} and GET {qrBaseUrl}/card/{partnerId}/{orderId} (status polls). §2's checkout flow made these dead in code (createPaymentIntent) as of the earlier @marketplaces/payment integration commit; confirmed zero remaining callers and deleted the dead ApiService methods, request/response types, and unused fields (qrBaseUrl, cartPaymentPartnerId) in the same pass. If a real backend still serves these endpoints, they are now backend-only surface with no frontend caller — decide their fate independently of this doc.
2. Storefront checkout & cart — ✅ Specified
Contract: PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §5.2, PHASE-6-CART-CHECKOUT-CONTRACT.md §3, §5.
| Method | Path | Called from |
|---|---|---|
| GET | /api/v2/storefront/cart |
server-cart-api.gateway.ts |
| POST | /api/v2/storefront/cart/lines |
server-cart-api.gateway.ts |
| PATCH | /api/v2/storefront/cart/lines/{lineId} |
server-cart-api.gateway.ts |
| DELETE | /api/v2/storefront/cart/lines/{lineId} |
server-cart-api.gateway.ts |
| POST | /api/v2/storefront/checkout |
server-cart-api.gateway.ts, api.service.ts (two different callers, same contract) |
| POST | /api/v2/storefront/payments/intents |
api.service.ts |
3. Pricing — ✅ Specified
Contract: PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §3.1.
| Method | Path | Called from |
|---|---|---|
| GET | /api/v2/pricing/fx-quote?base="e= |
fx-quote-api.gateway.ts |
4. Identity & permissions — ✅ Specified
Contracts: PHASE-8-IDENTITY-MESSAGING-CONTRACT.md §2, TRACK-S-SECURITY-RBAC-CONTRACT.md §2.
| Method | Path | Called from |
|---|---|---|
| GET | /api/identity/v1/vk/authorize |
vk-id-api.gateway.ts |
| POST | /api/identity/v1/vk/callback |
vk-id-api.gateway.ts |
| GET | /api/identity/v1/session/permissions |
permission-api.gateway.ts |
5. Team / RBAC — mixed
Contract: TRACK-S-SECURITY-RBAC-CONTRACT.md §8.
| Method | Path | Called from | Status |
|---|---|---|---|
| GET | /api/admin/v2/audit |
permission-api.gateway.ts, admin-users-api.gateway.ts?actor= |
✅ Specified |
| POST | /api/admin/v2/team/invite |
admin-users-api.gateway.ts |
✅ Specified |
| GET | /api/admin/v2/team?marketplaceId= |
admin-users-api.gateway.ts |
✅ Specified |
| PATCH | /api/admin/v2/team/{userId} |
admin-users-api.gateway.ts |
✅ Specified |
| DELETE | /api/admin/v2/team/{userId} |
(interface exists, not yet called) | ✅ Specified |
| GET | /api/admin/v2/team/roles |
admin-users-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/team/invitations |
admin-users-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/team/{userId}/sessions |
admin-users-api.gateway.ts |
⚠️ Inferred |
| PATCH | /api/admin/v2/team/{userId}/status |
admin-users-api.gateway.ts |
⚠️ Inferred |
| DELETE | /api/admin/v2/team/invitations/{id} |
admin-users-api.gateway.ts |
⚠️ Inferred |
| DELETE | /api/admin/v2/team/sessions/{sessionId} |
admin-users-api.gateway.ts |
⚠️ Inferred |
6. Orders & notifications — ✅ Specified
Contract: PHASE-2-ORDERS-NOTIFICATIONS-CONTRACT.md.
| Method | Path | Called from |
|---|---|---|
| GET | /api/admin/v2/orders?marketplaceId=&status=&source=&page=&pageSize= |
admin-orders-api.gateway.ts |
| GET | /api/admin/v2/orders/{id} |
admin-orders-api.gateway.ts |
| PATCH | /api/admin/v2/orders/{id}/status |
admin-orders-api.gateway.ts |
| POST | /api/admin/v2/orders/{id}/refund-request |
admin-orders-api.gateway.ts (note: gateway calls this refund-request; interface method is named requestRefund — same endpoint) |
| POST | /api/admin/v2/orders/{id}/notes |
admin-orders-api.gateway.ts |
| POST | /api/admin/v2/orders/{id}/archive |
admin-orders-api.gateway.ts |
| POST | /api/admin/v2/orders/{id}/restore |
admin-orders-api.gateway.ts |
| DELETE | /api/admin/v2/orders/{id} |
admin-orders-api.gateway.ts |
| GET | /api/admin/v2/notifications?marketplaceId=&unreadOnly=&eventType= |
admin-notifications-api.gateway.ts |
| PATCH | /api/admin/v2/notifications/{id}/read |
admin-notifications-api.gateway.ts |
| PATCH | /api/admin/v2/notifications/read-all |
admin-notifications-api.gateway.ts |
7. Catalog / offers — ✅ Specified + ⚠️ Inferred
Contract: PHASE-3-CATALOG-OFFER-FULFILLMENT-CONTRACT.md §7.
| Method | Path | Called from | Status |
|---|---|---|---|
| GET | /api/admin/v2/products?marketplaceId=&status=&search=&page=&pageSize= |
admin-products-api.gateway.ts |
✅ Specified |
| GET | /api/admin/v2/products/{id} |
admin-products-api.gateway.ts |
✅ Specified |
| POST | /api/admin/v2/products |
admin-products-api.gateway.ts |
✅ Specified |
| PATCH | /api/admin/v2/products/{id} |
admin-products-api.gateway.ts |
✅ Specified |
| GET | /api/admin/v2/offers?productId=&sellerId=&status= |
offer-api.gateway.ts |
✅ Specified |
| POST | /api/admin/v2/offers/{id}/publish |
offer-api.gateway.ts |
✅ Specified — 422 + details[] on executability failure |
| GET | /api/admin/v2/offers/lookup?sku=&sellerSku=&externalId= |
offer-api.gateway.ts |
✅ Specified |
| GET | /api/admin/v2/products/categories |
admin-products-api.gateway.ts |
⚠️ Inferred |
| DELETE | /api/admin/v2/products/{id} |
admin-products-api.gateway.ts |
⚠️ Inferred |
| POST | /api/admin/v2/products/{id}/duplicate |
admin-products-api.gateway.ts |
⚠️ Inferred |
| POST | /api/admin/v2/products/{id}/archive |
admin-products-api.gateway.ts |
⚠️ Inferred |
| POST | /api/admin/v2/products/{id}/restore |
admin-products-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/offers/{offerId}/inventory |
offer-api.gateway.ts |
⚠️ Inferred |
8. Categories — ✅ Specified (pre-existing, F29 done before this session)
| Method | Path | Called from |
|---|---|---|
| GET | {baseUrl} (categories collection) |
admin-categories-api.gateway.ts |
| GET | {baseUrl}/{id} |
admin-categories-api.gateway.ts |
| POST | {baseUrl} |
admin-categories-api.gateway.ts |
| PUT | {baseUrl}/{id} |
admin-categories-api.gateway.ts |
| DELETE | {baseUrl}/{id} |
admin-categories-api.gateway.ts |
| POST | {baseUrl}/{id}/restore |
admin-categories-api.gateway.ts |
| GET | {baseUrl}/slug-taken |
admin-categories-api.gateway.ts |
9. Seller portal — mixed
Contract: PHASE-5-SELLER-PORTAL-CONTRACT.md §3.
| Method | Path | Called from | Status |
|---|---|---|---|
| GET | /api/seller/v1/finance/settlements |
(contract-only, no current caller) | ✅ Specified |
| GET | /api/admin/v2/sellers |
seller-api.gateway.ts |
⚠️ Inferred — contract only specifies the caller's own GET /api/seller/v1/profile, not an admin list-all |
| GET | /api/admin/v2/sellers/{sellerId}/team |
seller-api.gateway.ts |
⚠️ Inferred — contract's GET /api/seller/v1/team is session-scoped, not parameterized |
10. Payments, refunds, reconciliation, settlements — ✅ Specified
Contract: PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md.
| Method | Path | Called from |
|---|---|---|
| GET | /api/admin/v2/orders/{orderId}/refunds |
finance-api.gateway.ts |
| GET | /api/admin/v2/reconciliation/queue |
finance-api.gateway.ts |
| POST | /api/admin/v2/reconciliation/{id}/resolve |
finance-api.gateway.ts |
| GET | /api/admin/v2/finance/settlements?sellerId= |
finance-api.gateway.ts |
11. Tenant registry — mixed
Contract: PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md.
| Method | Path | Called from | Status |
|---|---|---|---|
| GET | /api/admin/v2/marketplaces/{id}/lifecycle |
marketplace-api.gateway.ts |
✅ Specified |
| GET | /api/admin/v2/marketplaces (list) |
marketplace-api.gateway.ts |
⚠️ Inferred — contract specifies POST for creation, not the list GET |
| GET | /api/admin/v2/marketplaces/{id}/domains |
marketplace-api.gateway.ts |
⚠️ Inferred |
12. Connector framework — mixed
Contract: PHASE-4-CONNECTOR-FRAMEWORK-CONTRACT.md §7-8.
| Method | Path | Called from | Status |
|---|---|---|---|
| GET | /api/admin/v2/integrations |
connector-api.gateway.ts |
✅ Specified |
| PATCH | /api/admin/v2/integrations/{id} |
connector-api.gateway.ts (pause/resume via status field) |
✅ Specified |
| GET | /api/admin/v2/integrations/{connectorId}/dead-letter |
connector-api.gateway.ts |
⚠️ Inferred — contract specifies replay, not the list |
| POST | /api/admin/v2/integrations/{connectorId}/dead-letter/{id}/replay |
connector-api.gateway.ts |
✅ Specified — path corrected 2026-08-18; the gateway initially omitted connectorId, caught while writing this doc, fixed in the same pass |
13. Content modules (Gorbushka-class) — ⚠️ Mostly inferred
Contract: PHASE-10-CONTENT-MODULES-CONTRACT.md §2.
| Method | Path | Called from | Status |
|---|---|---|---|
| POST | /api/admin/v2/content/rent-listings/{id}/leads |
mall-content-api.gateway.ts |
✅ Specified |
| GET | /api/admin/v2/content/shops |
mall-content-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/content/shop-categories |
mall-content-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/content/floors |
mall-content-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/content/floors/{floorId}/pins |
mall-content-api.gateway.ts |
⚠️ Inferred |
| GET | /api/admin/v2/content/rent-listings |
mall-content-api.gateway.ts |
⚠️ Inferred |
14. Analytics — ✅ Specified
Contract: TRACK-A-ANALYTICS-CONTRACT.md §1.
| Method | Path | Called from |
|---|---|---|
| POST | /api/v2/storefront/analytics/events |
analytics-api.gateway.ts |
15. Transactions, monitoring, moderation — ❌ No contract doc exists
These three domains have gateways calling /api/admin/v2/{resource} by convention only. No Phase/Track doc covers any of them.
| Method | Path | Called from |
|---|---|---|
| GET | /api/admin/v2/transactions |
admin-transactions-api.gateway.ts |
| POST | /api/admin/v2/transactions/{id}/retry |
admin-transactions-api.gateway.ts |
| PATCH | /api/admin/v2/transactions/{id} |
admin-transactions-api.gateway.ts |
| GET | /api/admin/v2/monitoring/events |
admin-monitoring-api.gateway.ts |
| GET | /api/admin/v2/monitoring/queues |
admin-monitoring-api.gateway.ts |
| GET | /api/admin/v2/monitoring/webhooks |
admin-monitoring-api.gateway.ts |
| GET | /api/admin/v2/moderation/reviews |
admin-moderation-api.gateway.ts |
| GET | /api/admin/v2/moderation/reviews/{id} |
admin-moderation-api.gateway.ts |
| PATCH | /api/admin/v2/moderation/reviews/{id} |
admin-moderation-api.gateway.ts (status/visible/pinned/featured — 4 different PATCH bodies, same endpoint) |
| POST | /api/admin/v2/moderation/reviews/{id}/notes |
admin-moderation-api.gateway.ts |
| DELETE | /api/admin/v2/moderation/reviews/{id} |
admin-moderation-api.gateway.ts |
| GET | /api/admin/v2/moderation/reports |
admin-moderation-api.gateway.ts |
| PATCH | /api/admin/v2/moderation/reports/{id} |
admin-moderation-api.gateway.ts |
| GET | /api/admin/v2/dashboard/metrics |
admin-dashboard-metrics-api.gateway.ts |
Recommendation: these are the highest-priority gap. Three full admin domains with real UI and real gateways, zero backend contract. Whoever picks up Phase 5/7 next should write these as proper contract docs — the endpoint shapes above are a starting point, not a spec.
16. Partner provisioning API — ✅ Specified
Contract: PARTNER-PROVISIONING-API-CONTRACT.md §4, §6. This is the one domain where the frontend gateway was built from the contract, not the other way around — no drift to reconcile.
| Method | Path | Called from |
|---|---|---|
| GET | /api/partner/v1/companies/{companyId}/hierarchy?environment= |
partner-hierarchy-api.gateway.ts |
| GET | /api/partner/v1/nodes/{nodeId} |
partner-hierarchy-api.gateway.ts |
| GET | /api/partner/v1/nodes/lookup?externalReference=&environment= |
partner-hierarchy-api.gateway.ts |
| POST | /api/partner/v1/companies/{companyId}/projects |
partner-hierarchy-api.gateway.ts |
| POST | /api/partner/v1/projects/{projectId}/stores |
partner-hierarchy-api.gateway.ts |
| POST | /api/partner/v1/stores/{storeId}/payment-points |
partner-hierarchy-api.gateway.ts |
| PATCH | /api/partner/v1/nodes/{nodeId}/status |
partner-hierarchy-api.gateway.ts |
| POST | /api/partner/v1/nodes/{nodeId}/disable |
partner-hierarchy-api.gateway.ts |
| GET | /api/partner/v1/credentials?companyId= |
partner-hierarchy-api.gateway.ts |
| POST | /api/partner/v1/credentials |
partner-hierarchy-api.gateway.ts |
| POST | /api/partner/v1/credentials/{keyId}/rotate |
partner-hierarchy-api.gateway.ts |
| DELETE | /api/partner/v1/credentials/{keyId} |
partner-hierarchy-api.gateway.ts |
17. Backoffice data & bootstrap — ✅ Specified elsewhere (not a Phase/Track doc, but stable)
| Method | Path | Called from |
|---|---|---|
| GET | /api/backoffice/products |
api-backoffice-data.provider.ts |
| GET | /api/backoffice/categories |
api-backoffice-data.provider.ts |
| GET | (tenant bootstrap URL) | api-bootstrap.provider.ts — see BACKEND-HANDOFF.md §1a |
18. Marketplace publish/revision model — ✅ Specified
Contract: PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md §5. Frontend core built (marketplace-revision-*.gateway.ts), not yet wired into the project editor's UI — see §20.
| Method | Path | Called from |
|---|---|---|
| POST | /api/admin/v2/marketplaces/{id}/revisions |
marketplace-revision-api.gateway.ts — create draft |
| POST | /api/admin/v2/marketplaces/{id}/revisions/{revId}/validate |
marketplace-revision-api.gateway.ts |
| POST | /api/admin/v2/marketplaces/{id}/revisions/{revId}/publish |
marketplace-revision-api.gateway.ts |
| POST | /api/admin/v2/marketplaces/{id}/revisions/{revId}/rollback |
marketplace-revision-api.gateway.ts — creates a NEW revision, never mutates the old one |
One real ambiguity in §5 itself, flagged for confirmation, not guessed silently: the pipeline is described as 4 stages (draft → validated → preview → publish) but only 3 write endpoints exist (validate/publish/rollback) — there is no dedicated "move to preview" call. The frontend model assumes POST .../validate moves a revision straight to preview (the state publish requires), treating validated as a value the caller may never observe. Confirm this is correct before implementing — if the real response returns status: 'validated' and requires a separate step to reach preview, the frontend model and this doc both need updating.
19. RoutingContext on payments — carried through, not yet backend-verified
Contract: PARTNER-PROVISIONING-API-CONTRACT.md §7, PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §6.5. Not a separate endpoint — a field addition backend needs to populate on existing responses:
routing?: {
companyId: string;
routingPath: string[];
leafNodeId: string;
environment: 'TEST' | 'LIVE';
merchantReference: string;
providerPaymentId: string;
}
Frontend added this as an optional field on AdminOrder (admin-order.model.ts) and renders it on the order detail page when present. Nothing breaks if it's absent — but nothing shows the payment-point attribution either until backend populates it on GET /api/admin/v2/orders/{id}.
20. Order pricing breakdown — same pattern, different fields
Contract: PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §5.3. Optional fields added to AdminOrderItem and AdminOrder:
// per line
unitPriceMinor?: number;
lineTotalMinor?: number;
priceSnapshotId?: string;
discountMinor?: number;
// per order
fxQuoteId?: string;
deliveryMinor?: number;
Frontend renders a "total formula" panel on the order detail page (order-total-formula.component.ts) reconstructing total = sum(unitPrice*qty) - discounts + delivery, with the FX quote used. It refuses to show a partial breakdown — every line must carry unitPriceMinor or the panel says "not available" instead of a number that's silently wrong. Populate these fields on GET /api/admin/v2/orders/{id} to make it real; until then it correctly shows nothing.
21. Dashboard metrics — 8 new optional fields, no shape confirmed
Contract intent: PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md §7's target metric list — no contract doc defines GET /api/admin/v2/dashboard/metrics's response shape (§15 already flagged this endpoint has no spec at all). Frontend added these as optional fields on AdminDashboardMetrics, each rendering 'unknown' (not a fabricated 'healthy') while absent:
gmvMinor?: number;
currency?: string;
paidOrdersCount?: number;
conversionRate?: number; // 0-1, not a percentage
paymentFailureRate?: number; // 0-1
moderationQueueCount?: number;
lowStockCount?: number;
unmatchedEventsCount?: number;
integrationHealthyCount?: number;
integrationTotalCount?: number;
This is a genuine ask, not a confirmed contract — §15's recommendation to write a real spec for this endpoint still stands. These field names are what the frontend already expects; change them here first if backend needs different ones.
22. Idempotency — frontend now guards, backend enforcement is still required
The frontend added a client-side guard against double-submitting checkout (a real bug: double-clicking used to fire two POST /api/v2/storefront/checkout calls — fixed in cart.component.ts, checkoutInFlight signal). This does not replace backend idempotency and was never meant to. It closes one specific UI race; it does nothing for a retried request from a flaky network, a backgrounded tab resuming, or an actual duplicate webhook delivery. Contract requirements are unchanged and still required:
PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md§6.3 — webhook idempotency key =provider + providerEventIdPHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md§6.4 — order creation idempotency key =checkoutSessionIdPARTNER-PROVISIONING-API-CONTRACT.md§5 —Idempotency-Keyheader semantics for all partner-API creates
Summary counts
| Status | Count |
|---|---|
| ✅ Specified | 54 |
| ⚠️ Inferred (needs confirmation) | 24 |
| ❌ Undocumented (legacy) | 11 |
| Total distinct endpoints called | 93 |
(§0's 3 Telegram endpoints count as Specified+live; its 4 ed25519 endpoints count as Specified+not-built — both are real, named endpoints with a known shape, distinct from §1's "no contract exists anywhere" undocumented status.)
Plus 3 response-shape additions (§19–21) on existing endpoints — not new endpoints, new optional fields on responses those endpoints already return.
What backend needs to do with this
- §0.2 first, ahead of everything else on this list. The 4 ed25519 admin auth endpoints are the single most serious open issue named anywhere in
docs/backend/(BACKEND-HANDOFF.md§3's own words). Every other item below assumes an admin session exists to authorize the request — that session mechanism does not exist server-side yet. - Build the ✅ rows as written — they match an existing contract doc exactly. This includes §18's 4 revision endpoints, pending confirmation on the
validated/previewambiguity called out there. - Confirm or correct every ⚠️ row — each one has a comment at its call site in source explaining the inference. Search the codebase for
Inferredto find all 24 in place, with the reasoning right next to the code. - Populate the 3 optional field sets (§19–21) on the endpoints that already exist —
routingand pricing-breakdown fields onGET /api/admin/v2/orders/{id}, the 8 metric fields onGET /api/admin/v2/dashboard/metrics. Nothing on the frontend breaks while these are absent; nothing shows the real data either. - Write a contract for §15 (transactions, monitoring, moderation) — real UI, real gateways, zero spec. Highest-priority gap in this whole list.
- Decide the fate of §1 — 15 legacy endpoints with no contract at all, still live. Either document them as a stable, permanent surface, or set a Track N migration date.
- Enforce idempotency server-side regardless of §22 — the frontend's double-click guard is a UI nicety, not a substitute for
Idempotency-Key/providerEventIddedup.
One item that stays blocked until a real backend exists
The frontend backlog (F1–F65, tracked this session) is complete except F60: the full acceptance-path E2E — seller → catalog → storefront → cart → checkout → payment → order → notification → fulfillment, in one test, against real infrastructure. Every other item is written, unit-tested, E2E-covered where an E2E test could prove something real, and pushed. This one cannot be honestly finished by mocking harder — it needs an actual backend to run against. Once even a minimal version of Phases 1–4 is live, this is the next thing to build (docs/PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md Track Q, Q3).