docs: partner provisioning API contract, routing context, Track P
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
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:
@@ -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
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user