docs: partner provisioning API contract, routing context, Track P
Some checks failed
Architecture Governance / architecture (push) Has been cancelled

A partner integration request landed for programmatic merchant-hierarchy
management (Company/Project/Store/PaymentPoint). Built the answer generically:
partner-specific behaviour is a PartnerProfile config row, and no partner name
appears in any entity, field, endpoint or status value.

New:
- docs/backend/PARTNER-PROVISIONING-API-CONTRACT.md - hierarchy, idempotency,
  node-scoped public-key credentials, TEST/LIVE partition, routing context
- docs/context/adrs/ADR-0003-generic-partner-provisioning-api.md

Amended, because the schema impact must land before Phase 1 is implemented:
- Phase 1 gains RoutingContext on CheckoutSession/PaymentIntent/Payment,
  frozen at checkout-session creation and immutable after
- Phase 7 gains routing on Refund/ReconciliationRecord, plus the rule that
  seller settlement splits happen after routing, never as a hierarchy level
- Phase 9 gains Company/Project above Marketplace and PaymentPoint below it,
  with a backfill sequence for existing marketplaces
- Track S gains partner credentials: public key only, node-scoped authority,
  rotation with overlap, immediate revoke, audit coverage

Also: Track P (P1-P10) in the delivery plan, and backend ownership closed as
answered across the contract set.

Card payment was checked, not added - qr and card both already ship in
cart.component.ts with separate create paths and status pollers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
sdarbinyan
2026-08-18 11:22:24 +04:00
parent 551a22a245
commit 71da5a8d80
11 changed files with 560 additions and 10 deletions

View File

@@ -8,9 +8,39 @@ Companion to [PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md](../PRODUCT-PLAN-v3.1-DELIVERY-
## 1. Entities
Added 2026-08-18: two levels now sit **above** `Marketplace`, introduced by [PARTNER-PROVISIONING-API-CONTRACT.md §10](PARTNER-PROVISIONING-API-CONTRACT.md).
```ts
interface Company {
id: string;
name: string;
externalReference?: string; // partner's own id, when provisioned via the partner API
status: 'active' | 'suspended' | 'disabled';
createdAt: string;
updatedAt: string;
}
interface Project {
id: string;
companyId: string;
name: string; // a product line, e.g. "marketplaces"
externalReference?: string;
status: 'active' | 'suspended' | 'disabled';
createdAt: string;
updatedAt: string;
}
```
Both are deliberately thin — they exist to scope ownership, credentials, and payment routing, not to hold configuration. All marketplace configuration stays on `Marketplace` below.
A `Marketplace` **is** the partner hierarchy's `store` level. One project holds many marketplaces; one marketplace holds many sellers (Phase 5), and sellers are not part of that hierarchy.
```ts
interface Marketplace {
id: string;
companyId: string; // added 2026-08-18
projectId: string; // added 2026-08-18
externalReference?: string; // added 2026-08-18, partner's own id for this store
name: string;
code: string;
type: 'commerce' | 'mall_directory' | 'hybrid' | 'single_brand';
@@ -49,6 +79,42 @@ interface MarketplaceRevision {
**Hard invariant:** `Order`, `Payment`, `InventoryRecord`, and every financial ledger row are **not part of a `MarketplaceRevision`**. Rolling back a storefront design revision must never touch commerce data.
### 1.1 PaymentPoint
Added 2026-08-18. The leaf of the partner hierarchy: one payment method accepted at one marketplace. A marketplace taking both QR and card has two payment points.
```ts
interface PaymentPoint {
id: string;
marketplaceId: string;
method: 'qr' | 'card'; // extensible; both ship today
currencies: string[]; // ISO 4217 subset this channel accepts
externalReference?: string;
status: 'active' | 'suspended' | 'disabled';
providerAccountRef?: string; // set only by financial enablement, never by provisioning
createdAt: string;
updatedAt: string;
}
```
- Creating a payment point registers the channel. It does **not** enable real money — that requires `providerAccountRef`, set through a separate approved flow.
- A payment point is what `RoutingContext.leafNodeId` points at (Phase 1 §6.5).
- `MarketplaceFeatureSet.features.payments` gates whether the marketplace may have enabled payment points at all; the payment point gates which method.
### 1.2 Backfill
Existing marketplaces predate `Company` and `Project`. Migration, in this order:
```
1. Create one Company for the current owning entity.
2. Create one Project ("marketplaces") under it.
3. Set companyId + projectId on every existing Marketplace.
4. Create PaymentPoints for the methods each marketplace already accepts (qr, card).
5. Make companyId and projectId non-nullable only after 3 completes.
```
`externalReference` stays null for backfilled rows — it is only meaningful for partner-provisioned nodes.
## 2. Lifecycle state machine
```