Skip to content

Data model

This page describes the logical data model — what the core entities mean and how they relate. It deliberately omits DDL detail; the authoritative schema lives in the platform’s migrations.

hasconfigured byauthor poolpublishes tocorpusproducespublished asAI_COMPANYSALESCONTRACTSCRAPPER_CONFIGAUTHORHUGO_INSTANCERESEARCH_FACTGENERATED_ARTICLEPUBLISHED_URL
  • Company (ai_company) — the top of the hierarchy; a simple entity.
  • Contract (salescontracts) — the central unit of work: one niche, one brand, one content program. An active contract drives the whole Collect → Generate → Publish cycle.
  • Config (scrapper_config) — 1:1 with a contract; everything that parameterizes its pipeline: the topic ontology, the brand description (which also feeds brand defense), source feeds, per-contract pipeline version pin, the publishing endpoint and the destination-site mark.
  • Author pool (scrapper_lc_authors) — the byline roster for the contract’s site.
  • Site (hugo_instance) — one deployed destination site; linked to a contract through the config’s instance mark.
  • Run (pipeline_run / run_step) — the record of one pipeline execution and its per-step progress. Infrastructure records, not business entities: this is where you look to see what actually happened.
  • Research fact (research_fact) — one extracted, source-attributed fact in a contract’s corpus; carries the claim value used to ground numbers in articles. Facts have statuses, including quarantine for corpus hygiene.
  • Article (generated_articles) — the produced piece. The article field holds the final rendered HTML that gets published; a separate enriched-text field holds the unformatted editing form. A large JSON extra field accumulates per-article signals (dedup scores, grounding results, source class) — by convention it is merge-only.
  • Published URL (published_url and the external-URL check) — the registry mapping sources to live slugs. A publication only counts once the live URL has been verified reachable; this is the platform’s proof-of-publication.
  • Usage event (usage_event) — token-accurate cost metering for every LLM call, attributable to a run and a contract.
  • Error event (error_event) — the single error sink for the whole platform, queryable via the API (see How to read errors).
  • Search metrics (analytics tables) — weekly search-console time series per site, plus topic-level performance used by the feedback loop.

Business entities share a set of system fields inherited from the platform’s metamodel: a global numeric id (guid), an optimistic-locking revision (rsid), a lifecycle pointer (lcid / lcstep — which state machine the entity follows and where it stands), and audit fields (owner, updated-by, timestamps). Two practical consequences:

  1. Lifecycle state is data. “This contract is active” is a lifecycle step value, not a boolean column — the lifecycle engine advances entities through their state machines.
  2. References are application-level. Relations in the diagram above are maintained by the application rather than database foreign keys, so integrity checks live in code and verifiers, not constraints.