---
title: Data model
description: The core entities of Enterium — companies, contracts, configs, runs, research facts, articles and published URLs — and the metamodel fields every business entity carries.
locale: en
version: 0.2.0
canonical: https://enterium-developer-docs.pages.dev/developers/platform/data-model/
---

> Documentation index: https://enterium-developer-docs.pages.dev/developers/llms.txt — every page of this portal has a Markdown twin at <route>.md; the frozen API contract is at https://enterium-developer-docs.pages.dev/developers/api/openapi.json.

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.

## The contract hierarchy

```mermaid
erDiagram
    AI_COMPANY ||--o{ SALESCONTRACT : "has"
    SALESCONTRACT ||--|| SCRAPPER_CONFIG : "configured by"
    SALESCONTRACT ||--o{ AUTHOR : "author pool"
    SCRAPPER_CONFIG ||--|| HUGO_INSTANCE : "publishes to"
    SALESCONTRACT ||--o{ RESEARCH_FACT : "corpus"
    SALESCONTRACT ||--o{ GENERATED_ARTICLE : "produces"
    GENERATED_ARTICLE ||--o| PUBLISHED_URL : "published as"
```

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

## Production and evidence

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

## Accounting and observability

- **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](../../guides/reading-errors/)).
- **Search metrics** (analytics tables) — daily search-console time series
  per site, plus topic-level performance used by the feedback loop.

## The metamodel heritage

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.
