Skip to content

Schema Design

The data architecture spans three layers, each with its own storage and query characteristics. The commerce schema is the source of truth for the domain layer. Analytics and measurement data live on R2 as Apache Iceberg tables. Pipeline orchestration is handled by Cloudflare Workflows — no pipeline state tables in PG.

┌─────────────────────────────────────────────────────────────┐
│ Layer 1 — Domain (PlanetScale PostgreSQL) │
│ 153 tables across 25 modules │
│ Transactional OLTP: orders, products, payments, publishers │
│ Source of truth for all domain entities │
└──────────────────────┬──────────────────────────────────────┘
│ events via Worker enrichment
┌─────────────────────────────────────────────────────────────┐
│ Layer 2 — Analytics (Cloudflare Pipelines → R2 Data Catalog) │
│ Three telemetry streams → Iceberg/Parquet on R2 │
│ Sales measurement, performance metrics, classification │
│ Long-term retention, no sampling │
└──────────────────────┬──────────────────────────────────────┘
│ Iceberg REST catalog
┌─────────────────────────────────────────────────────────────┐
│ Layer 3 — Query (DuckDB over R2) │
│ Sliding windows, aggregations, nominal classifications │
│ Deployment: WASM in Workers / CF Container / MotherDuck │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Real-time — Workers Analytics Engine │
│ High-frequency counters: clicks, impressions, page views │
│ 3-month retention, auto-sampling, Grafana integration │
└─────────────────────────────────────────────────────────────┘

See ADR-006 through ADR-009 for the rationale behind this layering.

The commerce schema defines 153 tables across 25 modules, organized into three passes:

PassModulesTablesFocus
Commerce Core01–13, 1577Products, orders, payments, fulfillment, promotions, regions
Creator Commerce16–2552Publishers, ad servers, memberships, ledger, invoices, disputes, leads, identity, governance
Platform24–257Identity + Governance
Links1424Cross-module join tables

Full API specifications for all 153 tables are available in the API Reference.

Key design choices:

  • TEXT primary keys with prefixed UIDs (ord_xxx, pubi_xxx, mda_xxx)
  • K8s-style resource model: status JSONB (phase + conditions), labels JSONB, annotations JSONB
  • _ts suffix on all timestamps (create_ts, update_ts, provision_timer_ts)
  • NUMERIC + raw_* JSONB for monetary amounts (FIBO MonetaryAmount pattern)
  • Explicit link tables, no polymorphic associations
  • CHECK constraints on all enum-like columns
  • No stored procedures, no materialized views — all logic in application code (ADR-003)
  • Foreign keys documented but not enforced (ADR-004)
ModuleTablesWhat it covers
02 — Product10Catalog hierarchy: products, variants, options, categories, tags, images
06 — Order12order_header + line items, shipping, summaries, changes, transactions
09 — Fulfillment10Providers, sets, zones, options, fulfillments, items, labels
16 — Publisher & Ad Server15Publishers, ad servers, publications, telemetry, referrals, conversions, commissions
23 — Macrodata2macrodata_catalog + macrodata_artifact — k8s-style artifact registry

Commerce events are streamed from Workers to Cloudflare Pipelines, which applies lightweight SQL transforms and lands data as Apache Iceberg tables on R2 Data Catalog.

StreamEventsSource
COMMERCE_TELEMETRYorder_created, order_completed, payment_captured, fulfillment_shipped, return_requestedWorkers, after PG write
PUBLICATION_TELEMETRYclick, impression, view, engagement, conversionPlatform worker
SYNC_TELEMETRYprocedure completions, record counts, watermark positionsCF Workflows

Workers perform PG reads/writes (domain operations, enrichment) before pushing enriched events to streams (ADR-007). Events arrive on R2 already denormalized — analytical queries don’t need to join back to PG.

These tables exist as Iceberg tables on R2, not as PG tables. They are queried by DuckDB (or R2 SQL when it matures).

Iceberg tableOntological typeWhat it holds
commerce.telemetryProcess Boundary (BFO)Commerce lifecycle events, partitioned by day
publication.telemetryProcess Boundary (BFO)Engagement events, partitioned by day
sync.telemetryProcess Record (IAO)Pipeline execution audit trail
measurement.salesMeasurement Datum (IAO)Daily sales aggregates by product × day (ratio scale)
measurement.performanceDataset (IAO)Aggregated metrics with sliding windows + nominal classification
configuration.objective_specObjective Specification (IAO)Classification thresholds (macrodata_artifact with kind classification_spec)

The measurement.sales and measurement.performance tables replace the former PG tables sales_measurement_dataset and performance_measurement_dataset. Classification thresholds (objective_specification) are stored as a macrodata_artifact in PG and replicated to R2 for query co-location.

Per ADR-009, pipeline orchestration state (watermarks, run history, step tracking) is handled by Cloudflare Workflows — not PG tables. The former procedure_execution_state and procedure_execution_record tables are replaced by:

  • Workflow execution state — managed by CF Workflows (automatic retries, replay, step tracking)
  • Watermark/cursor state — stored in Durable Object persistent storage
  • Execution audit trail — captured by the SYNC_TELEMETRY stream and landed on R2 for long-term retention

The original 18-table schema has been absorbed into the commerce schema and analytics layer:

Old tableNew homeLayer
procedure_execution_stateCF Workflows / Durable ObjectsRuntime
procedure_execution_recordCF Workflows + sync.telemetry on R2Runtime + Analytics
commercial_transaction_recordorder_header (Module 06)Domain
transaction_participation_recordorder_line_item (Module 06)Domain
material_artifactproduct (Module 02)Domain
sales_measurement_datasetmeasurement.sales on R2Analytics
performance_measurement_datasetmeasurement.performance on R2Analytics
objective_specificationmacrodata_artifact (kind: classification_spec)Domain + Analytics
creative_act_reportmacrodata_artifact (kind: combo_report)Domain
suggestion_content_entitymacrodata_artifact (kind: combo_suggestion)Domain
plan_specificationmacrodata_artifact (kind: combo_template)Domain
tag_content_entityproduct_tag (Module 02)Domain
information_entity_collectionproduct_category (Module 02)Domain
agent_role_assignmentmacrodata_artifact (kind: agent_assignment)Domain
information_content_entitymacrodata_artifact (kind: design_asset)Domain
denotation_relationlink_product_macrodata_artifact (Module 14)Domain
document_artifactmacrodata_artifact (kind: document_export)Domain

For engineers migrating from the original Supabase table names:

Supabase tableOntology name (v1)Commerce schema (v2)
raw_ingest_stateprocedure_execution_stateCF Workflows
raw_ingest_runsprocedure_execution_recordCF Workflows + R2
raw_shopify_orderscommercial_transaction_recordorder_header
raw_shopify_line_itemstransaction_participation_recordorder_line_item
dim_productsmaterial_artifactproduct
fact_sales_dailysales_measurement_datasetR2: measurement.sales
mart_performance_metricsperformance_measurement_datasetR2: measurement.performance
classification_settingsobjective_specificationmacrodata_artifact
combo_logscreative_act_reportmacrodata_artifact
combo_suggestionssuggestion_content_entitymacrodata_artifact
combo_templatesplan_specificationmacrodata_artifact
tag_classificationstag_content_entityproduct_tag
tag_groupsinformation_entity_collectionproduct_category
designer_assignmentsagent_role_assignmentmacrodata_artifact
assetsinformation_content_entitymacrodata_artifact
product_asset_mappingsdenotation_relationlink_product_macrodata_artifact
csv_exportsdocument_artifactmacrodata_artifact
casestry_order_jobs(not ontologized)CF Workflows
casestry_order_job_items(not ontologized)CF Workflows