Skip to content

ADR-0046: Catalog checkout (lock, draft, apply)

  • Status: accepted
  • Datum: 2026-09-02
  • Phase: Web Schema-CMS
  • Bezug: ADR-0033, ADR-0038

Kontext

Schema-CMS schrieb sofort in die veröffentlichten Katalogtabellen. Mehrere Org-Admins konnten parallel draften; QGIS las geo_object_kinds live. Halbfertige Änderungen und Last-Write-Wins erzeugten broken oder unsync Zustände. Isolation bleibt die Org-DB — kein CREATE DATABASE pro Projekt.

Entscheidung

  1. Zentrum ist catalog_checkouts (eine Sitzung pro Org, höchstens eine Zeile). Overlay-Tabellen halten den Entwurf; Kind-code und field_id bleiben gleich.
  2. Gesperrt (Default): Katalog-Writes 409. QGIS, Datensätze, Layer-Tree, instantiate_base_schema und Pull lesen nur die veröffentlichten Tabellen.
  3. Entsperren: ein can_edit-User wird Holder. Overlay = Kopie des veröffentlichten Katalogs. Andere Writes 409.
  4. Anwenden (confirm: true): eine Transaktion merged Overlay → Live, dann Hybrid/geo_object_kinds. Bindings bestehender Projekte werden nicht additiv für neue Basis-Definitionen erweitert (Pull bleibt). Neue projektbezogene Kinds/Felder binden an ihr Pack-Projekt. Checkout bleibt offen, is_dirty=false. Die UI zeigt vorher GET /catalog-checkout/diff (pro Entität von → zu).
  5. Sperren ist immer erlaubt. Ohne Änderungen wird die Zeile gelöscht. Mit unveröffentlichten Änderungen bleibt das Overlay (is_parked); die Ansicht zeigt den veröffentlichten Katalog, bis derselbe Holder entsperrt. Verwerfen kopiert Live zurück ins Overlay (Checkout bleibt offen, is_dirty=false). Org-Admin darf force-lock (Verwerfen + Freigabe, auch geparkter Entwurf).
  6. Rollen unverändert: Base/Standard nur Org-Admin; Projektschemata Editor. Datensätze brauchen keinen Checkout.
Gate Recommendation Why it fits here Rejected alternative and why
Sperre eine Zeile in der Org-DB, FOR UPDATE Haltbar, tenant-scoped; analog ESRI Schema Lock Redis; Lock pro named schema
Entwurf Overlay-Tabellen Live-Tabellen bleiben QGIS-SSOT edition_id an Live-Zeilen; JSON-Snapshot
Apply Request-Transaktion, publish-only Katalog ist klein; Celery unnötig Push auf alle project_schema_*
Steal Org-Admin force-lock Hängende Sitzung ohne stilles Löschen Auto-Expire

Begründung (für dieses Setup)

QGIS und Validierung dürfen den Entwurf nicht sehen (create_kind upsertet sonst sofort geo_object_kinds). Ein Overlay mit stabilen IDs lässt Apply Bindings stehen. Publish-only vermeidet Überraschungs-Layer in laufenden Projekten; Pull bleibt der bewusste Add.

Verworfene Alternativen

Alternative Warum verworfen
Nur exklusiver Lock auf Live-Tabellen Halbfertige Writes bleiben sofort sichtbar
Apply bindet neue Basis-Kinds in alle Projekte Unsync-Schutz ja, aber laufende QGIS-Projekte wachsen ungefragt
edition_id auf entity_kinds Jeder Consumer muss filtern; leicht zu vergessen
Auto-Expire des Checkouts Verwirft Arbeit während Nachdenken

Folgen

  • Alembic 0022_catalog_checkout (Tenant 0010), is_parked in 0026 (Tenant 0014).
  • API /catalog-checkout; Schema-Writes nur als unparked Holder; ?working=1 für Schema-Reads des Holders. GET /diff nur als Holder.
  • Hybrid-Upsert nur bei Apply.