# Phase 9 Backend Contract — Tenant Registry, Domain Automation, Publish Model Companion to [PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md](../PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md) Phase 9 (Sprints 9.1–9.3). Covers plan §4.3, §8. **Status: ready to build.** Zero `hostinger` references exist in the codebase today. --- ## 1. Entities ```ts interface Marketplace { id: string; name: string; code: string; type: 'commerce' | 'mall_directory' | 'hybrid' | 'single_brand'; ownerId: string; countries: string[]; locales: string[]; currencies: string[]; timezone: string; lifecycleState: MarketplaceLifecycleState; } type MarketplaceLifecycleState = | 'draft' | 'configured' | 'content_ready' | 'domains_planned' | 'staging_live' | 'qa_passed' | 'production_ready' | 'live' | 'paused' | 'archived'; interface MarketplaceDomain { marketplaceId: string; domain: string; type: 'production' | 'www' | 'staging' | 'preview' | 'api' | 'seller'; status: 'planned' | 'dns_pending' | 'ssl_pending' | 'active' | 'failed'; } interface MarketplaceFeatureSet { marketplaceId: string; features: Record; // e.g. { catalog: true, sellers: true, cart: true, checkout: true, payments: true, orders: true, refunds: true, directory: false, ... } } interface MarketplaceRevision { id: string; marketplaceId: string; status: 'draft' | 'validated' | 'preview' | 'published'; publishedAt?: string; supersedesRevisionId?: string; // rollback creates a NEW revision, never mutates the old one } ``` **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. ## 2. Lifecycle state machine ``` draft -> configured -> content_ready -> domains_planned -> staging_live -> qa_passed -> production_ready -> live -> paused/archived ``` Every state transition endpoint must return the specific blocker preventing the next transition — not just "not ready." ``` GET /api/admin/v2/marketplaces/{id}/lifecycle -> { currentState, nextState, blockers: string[] } POST /api/admin/v2/marketplaces/{id}/lifecycle/advance ``` ## 3. Onboarding wizard (8 steps, plan §4.3) ``` POST /api/admin/v2/marketplaces -- step 1: name/code/type/owner/countries/locales/currencies/timezone PATCH /api/admin/v2/marketplaces/{id}/feature-set -- step 2 POST /api/admin/v2/marketplaces/{id}/domains -- step 3 PATCH /api/admin/v2/marketplaces/{id}/design -- step 4 POST /api/admin/v2/marketplaces/{id}/roles -- step 5 PATCH /api/admin/v2/marketplaces/{id}/integrations -- step 6 POST /api/admin/v2/marketplaces/{id}/staging-launch -- step 7, runs smoke tests POST /api/admin/v2/marketplaces/{id}/production-launch -- step 8, requires all P0 blockers closed + explicit approval ``` ## 4. Domain automation (Hostinger API, per plan §8.2) ``` GET /api/dns/v1/zones/{domain} POST /api/dns/v1/zones/{domain}/validate PUT /api/dns/v1/zones/{domain} DELETE /api/dns/v1/zones/{domain} GET /api/dns/v1/snapshots/{domain} GET /api/dns/v1/snapshots/{domain}/{snapshotId} POST /api/dns/v1/snapshots/{domain}/{snapshotId}/restore ``` Process, strictly in this order: ``` 1. Read current DNS zone. 2. Save a snapshot (rollback payload) BEFORE any change. 3. Build and validate a DNS plan. 4. NEVER touch MX/SPF/DKIM/DMARC/CAA records without a separate, explicitly scoped task. 5. Apply records only after production approval. 6. Verify propagation, SSL issuance, and health checks. 7. Mark the domain 'active' only after all checks in step 6 pass. ``` ## 5. Publish model ``` draft -> validation -> preview -> publish ``` ``` POST /api/admin/v2/marketplaces/{id}/revisions -- create draft POST /api/admin/v2/marketplaces/{id}/revisions/{revId}/validate POST /api/admin/v2/marketplaces/{id}/revisions/{revId}/publish -- becomes immutable POST /api/admin/v2/marketplaces/{id}/revisions/{revId}/rollback -- creates a NEW revision pointing at the prior published content ``` Replaces the current builder's `localStorage`-only draft persistence and the empty `apiEndpoints.builder: {}` placeholder in bootstrap. CMS/static-page content (currently in-memory bootstrap only) gets a real write path through this same revision model. ## 6. Tenant resolution hardening ``` GET /api/v2/storefront/bootstrap -- resolved server-side from verified Host header ``` - Host is normalized and matched against `MarketplaceDomain` server-side — the marketplace ID from the browser is never a trust boundary. - Unknown Host → `404`, with **no fallback to any other tenant**. ## 7. What the frontend will start doing once this ships - Build the backoffice **Marketplaces** section (missing from admin nav today): registry, type, status, domains, currencies, feature set, responsible manager. - Build the **Domains & Releases** section: DNS/SSL status, staging/production, health checks, rollback. - Wire the project editor/builder to real revision persistence instead of `localStorage`. - Marketplace dashboard: GMV, paid orders, conversion, payment failure rate, moderation queue, low stock, unmatched events, integration health, domain/SSL/release status (plan §4.2).