Selecting a company returns current detail, source history, and relationship history¶
Status: accepted Date: 2026-08-14 Deciders: Chris (solo founder) Depends on: ADR-0011, ADR-0005, ADR-0006, and ADR-0007
Context¶
The current read contract supports population filters, latest financial figures, current web presence, and current web contacts. It does not define the product action "select a company." It also does not expose CVR source history or ended relationships. A consumer must know private table shapes and still cannot reconstruct data that the current mappers discard.
The CVR source already contains effective-dated arrays for names, addresses, industries, legal forms, contact points, employment, lifecycle, roles, and ownership. The current mappers use only the latest metadata projection. They also omit important current facts. The confirmed gaps include advertising protection, phone, fax, email, website, and secondary industries.
Raw run snapshots are not a read model. They show what one source response contained during one run. They do not give a stable, indexed query for the effective history of one entity.
Decision¶
One collection-owned detail contract¶
The collection service exposes one company-detail operation keyed by CVR. Its transport can be HTTP or database RPC, but its response has three required parts:
current_detail— the current company projection, current production units, current participants and roles, current registry contact points, current web signals, and retained financial publications and metrics.source_history— effective-dated source facts for the company and its production units and participants.relationship_history— effective-dated registry and discovered relationships that touch the selected company. ADR-0013 defines this model.
Every part carries source, source update time, collection time, and raw snapshot or evidence references where applicable. The response also states the freshness of each source slice. A missing slice has an explicit reason; it does not mean that the source reported an empty value.
Consumers call this operation when a user selects a company. They do not join base tables or call CVR, Regnskabsdata, or web adapters directly.
Current CVR field coverage¶
The current projection and its source history must cover the product-relevant CVR facts below. The upstream names are shown to make mapper gaps visible.
| Area | Required source facts |
|---|---|
| Identity and lifecycle | cvrNummer, pNummer, enhedsNummer, names, lifecycle, status |
| Classification | legal form, primary industry, secondary industries |
| Location | business address, postal address, municipality, country, address-protection markers when published |
| Compliance | reklamebeskyttet / Datafordeler CVR_Reklamebeskyttelse |
| Registry contacts | telefonNummer / CVR_Telefonnummer, telefaxNummer / CVR_Telefaxnummer, elektroniskPost / CVR_e_mailadresse, hjemmeside, and their effective periods |
| Employment | annual, quarterly, and monthly employment observations that the source publishes |
| Company attributes | registered capital and other typed attributes that are shown in company detail |
| Participants | participant kind and name, role, function, ownership, voting rights, and validity |
Registry contacts are source facts. Web contacts are observed signals. The detail response keeps the sources separate and does not merge them into one unqualified value.
ADR-0006 still applies. Participant residential addresses and other non-role personal data do not enter history or raw retained participant data. For natural-person participants, queryable history covers business roles and ownership. It does not add historical names or other personal fields that ADR-0006 does not allow.
Queryable source history¶
PostgreSQL stores one row per effective-dated fact version. The logical shape is:
entity identity
source and source record identity
fact type and typed value
valid from and valid to
source updated at and collected at
raw snapshot URI
The physical schema can use typed tables or a common fact-history table. It must support these queries without reading GCS:
- all versions of one fact for one entity;
- the state of one entity at a specified date;
- all changes for a selected company and its production units;
- the source record and raw artifact behind a fact.
The current tables are projections from the effective-dated facts. An ingester must not overwrite the only stored copy of an ended value. Ingestion snapshots remain separate from effective history.
Freshness and financial scope¶
The interface first serves stored data. When a source slice is missing or stale and the source supports a safe per-entity refresh, collection can refresh it behind this boundary. Stale data can be returned with its freshness state while revalidation runs. Consumers do not control adapter calls.
Financial publications and XBRL documents stay bounded to the latest five accounting years, as ADR-0007 defines. "Full source history" does not expand that financial retention window. The detail response states the cutoff.
Contract replacement¶
The new detail and history contracts replace the incomplete shape. The project does not keep old views or payload fields only for backward compatibility. Consumers and collection change together before release.
Options considered¶
| Option | Benefit | Cost | Decision |
|---|---|---|---|
| Let each consumer join current tables | No new interface | Leaks storage shape; no history; repeats freshness logic | Rejected |
| Read history from GCS on each selection | No history schema | Slow batch-object scans; unstable payload; poor query support | Rejected |
| Store current projections plus queryable effective history and expose one detail operation | Simple consumer contract; fast detail and history queries; full provenance | More rows and mapping work | Chosen |
Consequences¶
- CVR mappers and fixtures need wider field coverage before the first full backfill.
- Current-only participant-role replacement and production-unit parent overwrite are not sufficient. They must preserve ended relationships.
- Read-contract migrations need current, fact-history, and relationship-history surfaces plus the composed detail operation.
- The five-year financial implementation stays unchanged.
- A field exposed in
current_detailmust have a declared source, absence meaning, and history rule.
Open questions¶
- Select the detail transport during implementation. This choice must not change the three-part response.
- Measure the history-row volume with a representative CVR extract before the first backfill and set indexes from the measured query plans.