Skip to content

Architektur

PostGIS + QGIS

QGIS (lokal)  →  TLS 1.3 + Client-Zertifikat  →  PgBouncer (mTLS)  →  PostGIS (nur Compose-Netz)
Browser       →  HTTPS  →  Next.js  →  FastAPI  →  PostGIS
Editor/Field  →  HTTPS  →  FastAPI  →  PostGIS (postgres:5432)
  • SSOT: Postgres/PostGIS — nicht die QGIS-Projektdatei.
  • QGIS: Operatives UI für Erfassung und Karte. Schema anwenden im Plugin (GET /qgis/layers, Views qgis_<kind>, Filter project_id). Stammdaten bleiben im Web-CMS.
  • Geo: PostGIS, SRID 25832.
  • DB-Rollen: Control-Plane linetra_edit / linetra_read nur auf DB linetra. QGIS und Fach-API verbinden als {slug}_edit / {slug}_read auf linetra_<slug> (ADR-0031). Superuser postgres nur Admin/Restore. Cert-CN = Mandanten-Rolle, nicht pro Person.
  • Netz (Soll, live): PostGIS unpublished. QGIS über PgBouncer mTLS (sslmode=verify-full). Production-FastAPI intern postgres:5432. Workstation-Development darf denselben Proxy nutzen (ADR-0013). WireGuard darf für andere NAS-Dienste bleiben, ist keine Voraussetzung für QGIS oder die Apps (ADR-0003).
  • Netz (Ist, abgeschaltet): Traefik TCP :3401 auf wg0 (plain, geteiltes Passwort). docker-compose.override.yml ist nicht mehr der QGIS-Pfad.

Lokal darf Compose Postgres weiter auf localhost:3401 legen — das ist nicht das Server-Soll.

Web-CMS

FastAPI + Next.js auf demselben PostGIS:

Service Rolle
postgres PostGIS SSOT (postgis/postgis:17-3.5), unpublished
pgbouncer mTLS-Auth-Proxy für QGIS (Profil mtls)
backend FastAPI JSON API (/api/v1/…), dual DB engines + app_users
frontend / frontend-prod Next.js Webapp (dev / production) auf linetra-web.nasarek.dev
marketing / marketing-prod Öffentliche Produktseite (Preise, Kontakt, Rechtliches) auf linetra-org.nasarek.dev
redis Broker + Result-Backend
celery Ingest, GIS-Import, Produkt-PDF, .ltp / QGIS-Export
docs Zensical unter /documentation/ (über die Webapp)
Browser → Traefik (linetra-web.nasarek.dev) → Next.js Webapp → /api proxy → FastAPI → PostGIS
Browser → Traefik (linetra-org.nasarek.dev + Basic Auth) → Next.js Marketing
QGIS → PgBouncer :5432 (TLS inside PgBouncer, kein Traefik-TLS) → PostGIS

Zwei getrennte Identitätsebenen:

Ebene Identitäten Zweck
DB-Rollen {slug}_edit / {slug}_read auf der Mandanten-DB; Control: linetra_edit / linetra_read Postgres-Login für QGIS (Cert-CN) und API-Engines
Linetra-Nutzer Tabelle app_users (Control-DB, tenant_id = Organisationskonto) Web-Login; Org-Rollen admin/editor/reader (ADR-0032)
  • Auth: app_users + argon2, signed session cookie + CSRF; erster Admin/Editor per Bootstrap aus LINETRA_BOOTSTRAP_* (nicht aus den DB-Rollen).
  • Admin/Editor → Edit-Engine; Reader → Read-Engine.
  • Stammdaten CRUD in the web app; GIS-Write im Editor (FastAPI) oder QGIS (Proxy). Web /map ist OpenLayers + MVT, nur lesen. Stamm: geo_objects + Schema-CMS; QGIS schreibt qgis_<kind> (ADR-0049, ADR-0050).
  • Redis / Celery / hosted Docs: Compose-Services; Entscheidungen unter ADRs.

Produkt-IA: .cursor/rules/product-ux-contracts.mdc, site-shell.mdc. Editor: linetra-editor/README.md. Entscheidungen: ADRs.

Workflow

DB → QGIS (Geo write) / Web-CMS (Stammdaten + read-only map) → Reports / PDF

Jira-Import und weitere Geo-Layer/Tiles im Web sind bewusst später.