ADR-0049: Schreibbare QGIS-Views pro Blatt-Layer
- Status: accepted
- Datum: 2026-09-02
- Phase: Web Schema-CMS / QGIS Plugin
- Bezug: ADR-0010, ADR-0025, ADR-0030, ADR-0033, ADR-0045
Kontext
QGIS lädt einen Vektorlayer als eine Geometrieart + Attributtabelle (getypte Spalten, Primärschlüssel, Filter). Schema-CMS speichert Features in geo_objects (geometry(Geometry, 25832) + attrs JSONB). Ohne Projektion sieht das Plugin nur einen JSON-Blob — keine native Attributtabelle, keine Digitize-Defaults, kein Value-Relation auf Fachfeldern. fiber_routes ist genau diese Projektion, aber nur für eine Kind.
Entscheidung
- Eine View pro veröffentlichtem Blatt-Layer:
public.qgis_<kind_code>(bei langen IDs gekürzt + Hash). Eltern mit Kindern bekommen keine View. - Systemspalten (stabil fürs Plugin):
object_id(Key),project_id(Subset-Filter),label,status,geomgetyptPoint/LineString/PolygonSRID 25832,created_at,updated_at. - Fachfelder aus dem effektiven Katalog (inkl. Vererbung) als flache Spalten. Kardinalität
1→ Skalar;n/2–99→ Array;group→jsonb. Kollision mit Systemnamen → Spaltef_<code>(Attrs-Key bleibt der Feldcode). - INSTEAD OF INSERT/UPDATE/DELETE schreiben zurück nach
geo_objects(kind/geom_kindfest,stageungesetzt,attrsgemerged). Bestehende JSONB-Keys außerhalb der View bleiben erhalten. - Rebuild beim Veröffentlichen des Checkouts und bei Live-Writes auf den veröffentlichten Katalog.
GET /qgis/layers?project_id=ist der Plugin-Apply-Vertrag (Gruppen + Blatt-Layer + View-Name + Spaltenmap). Draft-Views gibt es nicht. - Rechte: GRANT an Login-Rollen, die schon
geo_objectslesen bzw. schreiben (decktlinetra_edit/linetra_readund{slug}_edit/{slug}_read).
| Gate | Recommendation | Why it fits here | Rejected alternative and why |
|---|---|---|---|
| Projektion | View + INSTEAD OF, eine Hot-Tabelle | QGIS-Provider; ADR-0010 bleibt SSOT | Tabelle pro Layer — Drift, GIST×N |
| Zeitpunkt | Apply + Live-Write; GET heilt Drift | Plugin lädt nach Migrate ohne Extra-Schritt | Nur Alembic-Snapshot — Felder danach tot |
| Vertrag | GET /qgis/layers |
Plugin braucht View, Typ, Key, Gruppen, Spaltenmap | Plugin rät qgis_<code> und JSONB |
| n-Felder | Postgres-Array | Daten bleiben editierbar | Nur JSONB — Attributtabelle bleibt Blob |
Begründung (für dieses Setup)
Branchenüblich ist eine schreibbare PostGIS-View (oder Wrapper) pro QGIS-Ebene über einem generischen Feature-Stamm. Views skalieren mit der Kataloggröße, nicht mit der Feature-Zahl. Das Plugin setzt project_id auf der View und Formulare aus der Spaltenmap.
Verworfene Alternativen
| Alternative | Warum verworfen |
|---|---|
Plugin schreibt JSONB direkt auf geo_objects |
Keine native Attributtabelle; Digitize bricht |
DDL-Spalten an geo_objects |
Mega-Tabelle; widerspricht ADR-0010 |
Eine View qgis_geo_objects mit kind-Filter nur im Plugin |
Generic Geometry; QGIS editiert kein mixed |
fiber_routes ersetzen |
Erledigt in ADR-0050; Vertrag ist qgis_* |
Folgen
- Alembic public
0027/ tenant0015: Hilfsfunktionen, Registryqgis_layer_views. - API:
GET /api/v1/qgis/layers. - Plugin-Apply liest den Katalog und hängt
qgis_*mitkey=object_id,typeausgeom_kind, Filterproject_id. fiber_routesist entfernt (ADR-0050).