Unify commercial runtime ownership across backend and frontend so platform, experience, and hospitality modules use the shared commercial source of truth. Co-authored-by: Cursor <cursoragent@cursor.com>
158 lines
6.2 KiB
Markdown
158 lines
6.2 KiB
Markdown
# Commercial Runtime Backend — Final Report
|
||
|
||
> **Date:** 2026-07-28
|
||
> **Phase:** `commercial-runtime-backend`
|
||
> **Domain:** Core Platform → Commercial Runtime (`backend/core-service/app/commercial`)
|
||
> **Architecture status:** **COMMERCIAL_RUNTIME_BACKEND_COMPLETE**
|
||
> **Contract family:** `commercial.v1.2`
|
||
> **ADR:** [ADR-023](architecture/adr/ADR-023.md) · ownership boundary [ADR-022](architecture/adr/ADR-022.md)
|
||
|
||
---
|
||
|
||
## Verdict
|
||
|
||
Commercial Runtime Backend is the **single Source of Truth** for commercial metadata on TorbatYar Platform.
|
||
|
||
- Universal `CommercialRegistryObject` + meta-registry `CommercialRegistryKind`
|
||
- Unlimited future kinds via `POST /api/v1/commercial/admin/kinds` (zero code change for CRUD)
|
||
- Discovery catalog so the frontend never hardcodes registry names
|
||
- Recommendation, assessment, bundle, plan, license, and policy engines
|
||
- Outbox events, OpenAPI paths, Alembic migration `0007_commercial_runtime`, seed from docs catalogs
|
||
- **9/9** `test_commercial_runtime.py` green
|
||
|
||
Commercial owns **definitions only**. Orders, invoices ledgers, payments, and vertical data remain owned by their services.
|
||
|
||
---
|
||
|
||
## Placement
|
||
|
||
| Choice | Path |
|
||
| --- | --- |
|
||
| Service | `backend/core-service` (Core Platform) |
|
||
| Package | `app/commercial/` |
|
||
| API | `/api/v1/commercial/*` |
|
||
| DB | `core_platform_db` · tables `commercial_*` |
|
||
| Migration | `alembic/versions/0007_commercial_runtime.py` |
|
||
| Seed | `scripts/seed_commercial_runtime.py` |
|
||
|
||
Compatible with existing Core Platform ownership of tenants, plans, entitlements, and outbox.
|
||
|
||
---
|
||
|
||
## Universal Registry Model
|
||
|
||
Every registry object exposes:
|
||
|
||
| Field | Notes |
|
||
| --- | --- |
|
||
| `registry_object_id` | UUID primary key (= `id`) |
|
||
| `slug` | URL-safe identity |
|
||
| `stable_code` | Business code (product_code, bundle_code, …) |
|
||
| `version` / `version_code` | Versioning |
|
||
| `status` | `draft` · `published` · `archived` · `deleted` |
|
||
| `visibility` | `public` · `authenticated` · `admin` · `hidden` |
|
||
| `payload` + `metadata` | Open JSON — no service-specific ID columns |
|
||
| `created_by` / `updated_by` | Audit actors |
|
||
| timestamps | created/updated + published/archived/deleted |
|
||
| soft delete | `is_deleted` + restore |
|
||
|
||
Lifecycle actions: **publish · draft · archive · delete · restore · clone**.
|
||
|
||
List APIs: **search (`q`) · filters · pagination · sorting · tenant-safe**.
|
||
|
||
---
|
||
|
||
## Built-in registries (CRUD + discovery)
|
||
|
||
Products · Bundles · Pricing · Plans · Trials · Capabilities · Policies · Assets · Extensions · Automation Packs · Metadata · Recommendation Rules · Assessment Schemas · Notifications · Usage Plans · Coupons · Promotions · Taxes · Currencies · Regions · Industries · Business Types · Announcements · Languages
|
||
|
||
Plus **generic** `/api/v1/commercial/registries/{kind}` for any future kind.
|
||
|
||
Discovery: `GET /api/v1/commercial/catalog` returns every enabled kind with `href` + `generic_href`.
|
||
|
||
---
|
||
|
||
## Engines
|
||
|
||
| Engine | Endpoint / behavior |
|
||
| --- | --- |
|
||
| Recommendation | `POST /recommendations` — input business type/industry/size/goals/country/features → products, bundles, plans, capabilities, automations, assets + `rule_trace` |
|
||
| Assessment | `GET /assessment/schema` — questions from `assessment_schemas` registry only |
|
||
| Bundle resolver | `GET /bundles/{code}/resolve` — products, capabilities, policies, pricing, extensions, assets, automation |
|
||
| Plan resolver | `GET /plans/{code}/resolve` — trial, limits, price, renewal, visibility |
|
||
| License / entitlements | `POST /entitlements/check` + tenant licenses |
|
||
| Policy evaluate | `POST /policies/evaluate` |
|
||
| Notifications | `notifications` registry (email / SMS / push / in-app templates) |
|
||
|
||
Honest empty: `GET /invoices` and `GET /transactions` return empty collections — **Payment** owns money ledgers.
|
||
|
||
---
|
||
|
||
## Events (outbox)
|
||
|
||
`commercial.registry.created` · `updated` · `published` · `archived` · `deleted` · `commercial.subscription.activated` (and related activation paths).
|
||
|
||
---
|
||
|
||
## Quality gates
|
||
|
||
| Gate | Result |
|
||
| --- | --- |
|
||
| No TODO / fake / placeholder registries | **PASS** |
|
||
| No hardcoded product/bundle/capability catalogs in engines | **PASS** |
|
||
| Unlimited future kinds | **PASS** (`admin/kinds` + generic routes) |
|
||
| Tenant isolation fields + platform catalogs (`tenant_id` NULL) | **PASS** |
|
||
| Permissions (auth deps on mutating routes) | **PASS** |
|
||
| Audit + versioning + soft delete | **PASS** |
|
||
| OpenAPI includes `/commercial/*` | **PASS** |
|
||
| Tests | **9 passed** |
|
||
|
||
---
|
||
|
||
## Deployment readiness
|
||
|
||
| Area | Status |
|
||
| --- | --- |
|
||
| Backend code | **READY** |
|
||
| Migration `0007` | **READY** (apply on Core deploy) |
|
||
| Seed catalogs | **READY** (`seed_commercial_runtime.py`) |
|
||
| OpenAPI | **READY** (Core `/openapi.json`) |
|
||
| Tests | **GREEN** |
|
||
| FE adapters | Already wired; live after Core deploy + seed |
|
||
| Production | Deploy Core with commercial migration + seed; restart frontend BFF if needed |
|
||
|
||
---
|
||
|
||
## Remaining roadmap (NOT this phase)
|
||
|
||
Do **not** implement in Commercial Runtime:
|
||
|
||
- Marketplace / QR / Booking / Payment `14.6+` / Experience FE `11.6+` product engines
|
||
- Those products activate later by **registry rows only** (zero Commercial Runtime code changes)
|
||
|
||
Separate tracks (see `project-status.yaml`):
|
||
|
||
1. Payment Backend MVP `14.6–14.10`
|
||
2. Hospitality `12.9` / `12.10`
|
||
3. Experience FE `11.6+`
|
||
4. Delivery production, booking, short links, QR, …
|
||
|
||
Optional follow-ups (non-blocking): FE catalog codegen from YAML; Payment connector for live invoices/transactions.
|
||
|
||
---
|
||
|
||
## Artifacts
|
||
|
||
| Artifact | Path |
|
||
| --- | --- |
|
||
| Architecture report | [commercial-runtime-backend-architecture-report.md](commercial-runtime-backend-architecture-report.md) |
|
||
| Snapshot | [service-snapshots/commercial-runtime-backend.yaml](service-snapshots/commercial-runtime-backend.yaml) |
|
||
| Handover | [phase-handover/phase-commercial-runtime-backend.md](phase-handover/phase-commercial-runtime-backend.md) |
|
||
| Foundation ADR | [ADR-023](architecture/adr/ADR-023.md) |
|
||
|
||
---
|
||
|
||
## STOP
|
||
|
||
Commercial Runtime Backend is complete. Do not continue into Marketplace, QR, Booking, Payment 14.6+, CRM, or vertical modules from this phase.
|