Skip to content

Provenantie als 1-N junction

Eén instrument-Manifestation, n vindplaatsen. Optie B uit de brainstorm 2026-05-12.

Het patroon

instrument.manifestaties              (UNIQUE op content_sha256)
  └── één rij per fysieke bytes-blob

instrument.manifestatie_herkomsten    (1-N op manifestatie_id)
  └── één rij per concrete vindplaats van die blob

Schema-shape

sql
CREATE TABLE instrument.manifestaties (
  id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  versie_id           UUID NOT NULL REFERENCES instrument.versies(id) ON DELETE CASCADE,
  mime_type           TEXT NOT NULL,
  mime_subtype        TEXT,
  content_sha256      TEXT NOT NULL UNIQUE,   -- uniek per blob
  byte_size           BIGINT,
  ingested_at         TIMESTAMPTZ NOT NULL DEFAULT now(),
  extraction_provenance JSONB
);

CREATE TABLE instrument.manifestatie_herkomsten (
  id                  UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  manifestatie_id     UUID NOT NULL REFERENCES instrument.manifestaties(id) ON DELETE CASCADE,
  register            TEXT NOT NULL REFERENCES catalogus.registers(id),
  source_url          TEXT,
  source_authority_id UUID REFERENCES gezag.gezagen(id),
  akn_uri             TEXT,
  discovered_via      TEXT,
  first_seen_at       TIMESTAMPTZ NOT NULL DEFAULT now(),
  last_seen_at        TIMESTAMPTZ,
  status              TEXT NOT NULL DEFAULT 'active'
                      CHECK (status IN ('active','gone_404','superseded','deprecated_by_source')),
  UNIQUE (manifestatie_id, register, source_url)
);

Het alternatief — Optie A

Optie A was: één rij per (blob × vindplaats)-combinatie. Dezelfde PDF op LVBB en op gemeente-website zou twee instrument.manifestaties-rijen geven, beide met identieke content_sha256.

AspectOptie AOptie B (gekozen)
Aantal rijen voor één blob met n vindplaatsenn1 + n
Blob-duplicaten op Manifestation-laagJaNee
Adviseur-presentatie"Hier zijn drie versies van het document" (zelfde inhoud)"Hier is het document, ook te vinden op…"
Uitval van één bronRij stilzetten; andere rij blijft canoniekHerkomst-rij stilzetten; manifestatie blijft canoniek
Bijna-identieke-bytes edge-caseVerschillende SHA256 → verschillende rijen (per definitie)SHA256 unique-clash; mitigatie via normalisatie-functie vóór hash

Edge-case: bijna-identieke bytes

Twee bronnen van dezelfde document kunnen iets verschillende bytes hebben — een PDF met watermerk-pagina, een PDF-creator-header-verschil, een gemeente-eigen briefhoofd. SHA256 over raw bytes geeft dan verschillende hashes voor wat conceptueel "hetzelfde document" is.

Mitigatie: per mime_type een normalisatie-functie die irrelevante metadata uitstript voordat de hash wordt berekend:

  • application/pdf → hash over de geëxtraheerde tekst-content (niet de raw bytes)
  • application/xml → hash over de canonicalized XML (whitespace + namespace-volgorde genormaliseerd)
  • text/html → hash over de getripte textcontent

Voor de pilot-fase: hash over geëxtraheerde tekst per default. Tweede hash-kolom (bytes_sha256 naast content_sha256) toevoegen als de edge-case in praktijk gaat bijten — geen prematuur ontwerp.

Wat een herkomst-rij betekent

Elke instrument.manifestatie_herkomsten-rij zegt: "deze fysieke blob is vindbaar op deze register-vindplaats, gedetecteerd via deze discovery-route, laatst gezien op dat moment."

Het is niet een classificatie van de blob — het is een vindplaats. Dezelfde blob op LVBB en op gemeente-website krijgt twee herkomst-rijen, gelijkwaardig. De register-as in elke rij verklaart wát voor vindplaats het is (zie registers-taxonomie).

Wanneer een nieuwe blob-rij vs. een nieuwe herkomst-rij?

  • Nieuwe blob (content_sha256 verschilt) → nieuwe instrument.manifestaties-rij + minstens één instrument.manifestatie_herkomsten-rij
  • Bestaande blob op nieuwe vindplaats → alleen nieuwe instrument.manifestatie_herkomsten-rij; manifestatie blijft één rij
  • Bestaande blob, bestaande vindplaats, update van last_seen_at → UPDATE op de bestaande herkomst-rij

Onderliggende ADRs

  • ADR-0037 §2-3 — instrument.manifestaties dun + provenantie-junction

Intern handboek — niet voor externe publicatie