# 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.
