gateway/docs/PEK_datamodel_desc.md

418 lines
17 KiB
Markdown

# Datenmodell Architektur-Planungs-App
## Übersicht
Dieses Datenmodell bildet die Grundlage für eine Schweizer Architektur-Planungs-App zur Verwaltung von Bauprojekten, Parzellen, Dokumenten und regulatorischen Kontextinformationen.
## Wichtige Hinweise zum Datenmodell
**Objektmodell vs. Datenbank-Repräsentation:**
Dieses Dokument beschreibt ein **Objektmodell** für die Arbeit im Code. Es handelt sich **NICHT** um ein relationales Datenbankmodell mit Junction Tables.
- **Im Code-Modell**: Alle Beziehungen werden als Objektreferenzen oder Listen von Objekten dargestellt (z.B. `dokumente: list[Dokument]`, `parzellen: list[Parzelle]`).
- **Für die Datenbank-Serialisierung**: Bei der Persistierung können Junction Tables verwendet werden, um n:m-Beziehungen in der Datenbank abzubilden. Dies ist jedoch ein Implementierungsdetail der Datenbank-Schicht und gehört nicht zum Hauptmodell.
**Systemattribute:**
Alle Datenobjekte haben automatisch die folgenden Systemattribute:
- `_createdAt`: Float (Timestamp UTC)
- `_createdBy`: String (User-ID)
- `_modifiedAt`: Float (Timestamp UTC)
- `_modifiedBy`: String (User-ID)
**Timestamps:**
- Alle Timestamps sind im Float-Format UTC im Datenmodell gespeichert.
- Die Darstellung im UI erfolgt mit der lokalen Zeitzone des Benutzers.
## Datenfluss-Diagramm
```mermaid
---
title: Hauptflüsse - Architektur-Planungs-App
---
flowchart LR
subgraph Admin[Administrative Ebene]
Land[Land<br/>Schweiz]
Kanton[Kanton<br/>z.B. Zürich]
Gemeinde[Gemeinde<br/>z.B. Zürich Stadt]
Land --> Kanton
Kanton --> Gemeinde
end
subgraph Geo[Geografische Daten]
GeoPolylinie[GeoPolylinie<br/>Linie/Polygon]
GeoPunkt[GeoPunkt<br/>Koordinaten]
GeoPolylinie --> GeoPunkt
end
subgraph Core[Kern-Business-Logik]
Projekt[Projekt<br/>Bauprojekt]
Parzelle[Parzelle<br/>Grundstück mit<br/>Bauparametern]
Gemeinde --> Parzelle
Projekt --> Parzelle
Projekt --> GeoPolylinie
Parzelle --> GeoPolylinie
end
subgraph Support[Unterstützende Daten]
Dokument[Dokument<br/>Dateien & URLs]
Kontext[Kontext<br/>Zusatzinfos]
end
style Land fill:#50C878,stroke:#2D7A4A,stroke-width:2px,color:#fff
style Kanton fill:#50C878,stroke:#2D7A4A,stroke-width:2px,color:#fff
style Gemeinde fill:#50C878,stroke:#2D7A4A,stroke-width:2px,color:#fff
style Parzelle fill:#FF6B6B,stroke:#C92A2A,stroke-width:4px,color:#fff
style Projekt fill:#FF6B6B,stroke:#C92A2A,stroke-width:4px,color:#fff
style Dokument fill:#F5A623,stroke:#C17D11,stroke-width:2px,color:#fff
style GeoPolylinie fill:#F5A623,stroke:#C17D11,stroke-width:2px,color:#fff
style GeoPunkt fill:#F5A623,stroke:#C17D11,stroke-width:2px,color:#fff
style Kontext fill:#F5A623,stroke:#C17D11,stroke-width:2px,color:#fff
```
---
## Alle Datenobjekte als Tabellen
### Übersichtstabelle
| Objekt | Typ | Beschreibung | Hauptfelder |
|--------|-----|--------------|-------------|
| **Projekt** | Kernentität | Bauprojekt mit Status und Perimeter | id, label, statusProzess, perimeter, baulinie, parzellen |
| **Parzelle** | Hauptentität | Grundstück mit Bauparametern | id, label, plz, bauzone, AZ, BZ, perimeter, baulinie, laermschutzzone, hochwasserschutzzone, grundwasserschutzzone |
| **Dokument** | Unterstützend | Dateien und URLs mit Versionierung | id, label, dokumentTyp, quelle, mimeType, kategorienTags |
| **Kontext** | Unterstützend | Flexible Zusatzinformationen | id, thema, inhalt |
| **GeoPolylinie** | Hilfsobjekt | Geometrische Linie/Polygon | id, closed, punkte |
| **Land** | Admin | Nationale Ebene | id, label, abk |
| **Kanton** | Admin | Kantonale Ebene mit Baurecht | id, label, abk, Baureglement |
| **Gemeinde** | Admin | Gemeinde-Ebene mit BZO | id, label, plz, BZO |
| **GeoPunkt** | Hilfsobjekt | 3D-Koordinate | koordinatensystem, x, y, z, referenz |
| **GeoTag** | Enum | Geopunkt-Kategorien | - |
| **JaNein** | Enum | Drei-wertiger Status | "", "Ja", "Nein" |
| **StatusProzess** | Enum | Projektstatus | 7 Werte |
| **DokumentTyp** | Enum | Dokumenttyp | 6 Werte |
---
## Zentrale Entitäten
### 1. Projekt
**Das Kernobjekt, das ein Bauprojekt repräsentiert.**
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `label` | String | ✓ | Projektbezeichnung |
| `statusProzess` | Enum[StatusProzess] | - | Projektstatus: Eingang, Analyse, Studie, Planung, Baurechtsverfahren, Umsetzung, Archiv |
| `perimeter` | GeoPolylinie | - | Umhüllende aller Parzellen des Projektes |
| `baulinie` | GeoPolylinie | - | Baulinie des Projektes |
| `parzellen` | list[Parzelle] | - | Alle Parzellen des Projektes |
| `dokumente` | list[Dokument] | - | Projektspezifische Dokumente |
| `kontextInformationen` | list[Kontext] | - | Projektspezifische Kontextinfos |
---
### 2. Parzelle
**Repräsentiert ein Grundstück mit allen baurechtlichen Eigenschaften als ein einheitliches Objekt.**
#### Grunddaten
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `label` | String | ✓ | Parzellenbezeichnung |
| `parzellenAliasTags` | list[String] | - | Weitere Parzellennamen oder Flurnamen |
| `eigentuemerschaft` | String | - | Eigentümer der Parzelle |
| `strasseNr` | String | - | Straße und Hausnummer |
| `plz` | String | - | Postleitzahl der Parzelle (insbesondere bei Gemeinden mit mehreren PLZ) |
#### Geografischer Kontext
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `perimeter` | GeoPolylinie | - | Parzellengrenze als geschlossene GeoPolylinie |
| `baulinie` | GeoPolylinie | - | Baulinie der Parzelle |
| `kontextGemeinde` | Gemeinde | - | Gemeinde der Parzelle |
#### Bebauungsparameter
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `bauzone` | String | - | Bauzonenbezeichnung (z.B. W3, WG2, etc.) |
| `az` | Float | - | Ausnützungsziffer |
| `bz` | Float | - | Bebauungsziffer |
| `vollgeschossZahl` | Integer | - | Anzahl zulässiger Vollgeschosse |
| `anrechenbarDachgeschoss` | Float | - | Anrechenbarer Anteil Dachgeschoss (0.0 - 1.0) |
| `anrechenbarUntergeschoss` | Float | - | Anrechenbarer Anteil Untergeschoss (0.0 - 1.0) |
| `gebaeudehoeheMax` | Float | - | Maximale Gebäudehöhe in Metern |
#### Abstandsregelungen
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `regelnGrenzabstand` | list[String] | - | Regelungen zum Grenzabstand |
| `regelnMehrlaengenzuschlag` | list[String] | - | Regelungen zum Mehrlängenzuschlag |
| `regelnMehrhoehenzuschlag` | list[String] | - | Regelungen zum Mehrhöhenzuschlag |
#### Eigenschaften (Ja/Nein)
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `parzelleBebaut` | JaNein | - | Ist die Parzelle bebaut? ("", "Ja", "Nein") |
| `parzelleErschlossen` | JaNein | - | Ist die Parzelle erschlossen? ("", "Ja", "Nein") |
| `parzelleHanglage` | JaNein | - | Liegt die Parzelle in Hanglage? ("", "Ja", "Nein") |
#### Schutzzonen
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `laermschutzzone` | String | - | Lärmschutzzone (z.B. "II") |
| `hochwasserschutzzone` | String | - | Hochwasserschutzzone (z.B. "tief") |
| `grundwasserschutzzone` | String | - | Grundwasserschutzzone |
#### Beziehungen
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `parzellenNachbarschaft` | list[Parzelle] | - | Nachbarparzellen |
| `dokumente` | list[Dokument] | - | Parzellenspezifische Dokumente |
| `kontextInformationen` | list[Kontext] | - | Parzellenspezifische Kontextinfos |
---
### 3. Dokument
**Unterstützendes Datenobjekt zur Verwaltung von Dateien und URLs mit Versionierung.**
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `label` | String | ✓ | Dokumentbezeichnung |
| `versionsbezeichnung` | String | - | Versionsnummer oder -bezeichnung (z.B. "v1.0", "Rev. A") |
| `dokumentTyp` | Enum[DokumentTyp] | - | Typ des Dokuments (siehe DokumentTyp-Enum) |
| `dokumentReferenz` | String | ✓ | Dateipfad oder URL |
| `quelle` | String | - | Quelle des Dokuments |
| `mimeType` | String | - | MIME-Type des Dokuments (z.B. "application/pdf", "image/png") |
| `kategorienTags` | list[String] | - | Kategorisierung des Dokuments |
**Hinweis:**
Aktuelle Dokumente (z.B. aktuelle Baureglemente, BZO) können anhand des `dokumentTyp`-Attributs identifiziert werden. Die entsprechenden Dokumente finden sich in der `dokumente`-Liste der jeweiligen Entität (Kanton, Gemeinde).
#### Beispiel-Kategorien (nicht abschliessend)
| Kategorie | Beschreibung |
|-----------|--------------|
| `Kataster Objekte` | Amtliche Vermessung |
| `Kataster Werkeleitungen` | Leitungskataster |
| `Kataster Belastete Standorte` | Altlasten |
| `Kataster Bäume` | Baumkataster |
| `Zonenplan` | Zonenpläne |
| `Planungs- und Baugesetz (PGB)` | Kantonale Baugesetze |
| `Bau- und Zonenordnung (BZO)` | Gemeinde BZO |
| `Parkplatzverordnung` | Parkplatzregelungen |
| `Eigentümerauskunft` | Grundbuch-Auszüge Eigentümer |
| `Grundbuchauszug` | Vollständige Grundbuch-Auszüge |
| `Bauherrschaft` | Dokumente von der Bauherrschaft |
| `Planung` | Planungsdokumente |
---
### 4. Geografische Entitäten
#### GeoPolylinie
**Repräsentiert eine Linie oder ein Polygon aus mehreren GeoPunkten.**
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `closed` | Boolean | ✓ | Ist die GeoPolylinie geschlossen (Polygon)? |
| `punkte` | list[GeoPunkt] | ✓ | Liste der GeoPunkte, die die GeoPolylinie bilden |
**Verwendung:**
- Parzellenperimeter (geschlossene GeoPolylinie)
- Baulinie (offene oder geschlossene GeoPolylinie)
- Projektperimeter (geschlossene GeoPolylinie)
#### GeoPunkt
**Repräsentiert einen 3D-Punkt mit Referenzangabe.**
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `koordinatensystem` | String | ✓ | Koordinatensystem (z.B. "LV95", "EPSG:2056") |
| `x` | Float | ✓ | Ostwert (E) [m], typisch 2'480'000 - 2'840'000 |
| `y` | Float | ✓ | Nordwert (N) [m], typisch 1'070'000 - 1'300'000 |
| `z` | Float | - | Höhe über Meer [m] |
| `referenz` | Enum[GeoTag] | - | Kategorisierung des Punktes |
**Verwendung:**
- Als Teil einer GeoPolylinie (Parzellenperimeter, Baulinie)
- Einzelne Referenzpunkte
#### GeoTag (Enum)
| Kategorie | Beschreibung |
|-----------|--------------|
| `K1` | Fixpunkt höchster Genauigkeit |
| `K2` | Fixpunkt mittlerer Genauigkeit |
| `K3` | Fixpunkt niedriger Genauigkeit |
| `Geometer` | Vom Geometer vermessener Punkt |
**Beispiel (Zürich Hauptbahnhof):**
- `koordinatensystem`: "LV95" oder "EPSG:2056"
- `x`: 2'683'140 [m]
- `y`: 1'247'850 [m]
- `z`: 408 [m]
- `referenz`: "K1" (oder ein anderer GeoTag-Wert)
---
### 5. Administrative Hierarchie
#### Land
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `label` | String | ✓ | Landesname (z.B. "Schweiz") |
| `abk` | String | - | Abkürzung (z.B. "CH") |
| `dokumente` | list[Dokument] | - | Nationale Gesetze |
| `kontextInformationen` | list[Kontext] | - | Nationale Kontextinformationen |
---
#### Kanton
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `label` | String | ✓ | Kantonsname (z.B. "Zürich") |
| `id_land` | [land] | eindeutiger Link zum land, also in welchem land kanton liegt |
| `abk` | String | - | Abkürzung (z.B. "ZH") |
| `dokumente` | list[Dokument] | - | Kantonale Dokumente |
| `kontextInformationen` | list[Kontext] | - | Kantonsspezifische Kontextinfos |
---
#### Gemeinde
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `label` | String | ✓ | Gemeindename (z.B. "Zürich") |
| `id_kanton` | [kanton] | eindeutiger Link zur gemeinde, also im welchem kanton gemeinde liegt |
| `plz` | String | - | Postleitzahl (bei Gemeinden mit mehreren PLZ kann dies eine Haupt-PLZ sein) |
| `dokumente` | list[Dokument] | - | Gemeindedokumente |
| `kontextInformationen` | list[Kontext] | - | Gemeindespezifische Kontextinfos |
**Hinweis:**
Bei Gemeinden mit mehreren Postleitzahlen (z.B. Zürich, Bern) wird die konkrete PLZ der Parzelle im Attribut `plz` der Parzelle erfasst.
---
### 6. Kontext
**Unterstützendes Datenobjekt für flexible Zusatzinformationen und Hinweise.**
| Feld | Datentyp | Pflicht | Beschreibung |
|------|----------|---------|--------------|
| `id` | UUID | ✓ | Eindeutiger Identifier |
| `thema` | String | ✓ | Bezeichnung des Themas |
| `inhalt` | String | ✓ | Detaillierte Information (Text) |
**Verwendung:**
Kontext-Objekte werden als Listen in den jeweiligen Entitäten gespeichert:
- `projekt.kontextInformationen: list[Kontext]`
- `parzelle.kontextInformationen: list[Kontext]`
- `land.kontextInformationen: list[Kontext]`
- `kanton.kontextInformationen: list[Kontext]`
- `gemeinde.kontextInformationen: list[Kontext]`
#### Beispielthemen (nicht abschliessend)
| Themenbereich | Beispiele |
|---------------|-----------|
| **Nutzung** | Vorgaben zur Erdgeschossnutzung (Wohnen erlaubt oder Pflicht für Gewerbe) |
| **Rechte** | Dienstbarkeiten (Wegrechte, Nähebaurechte, etc.) |
| **Parkierung** | Anforderung Parkplätze (Berechnung / Reduktionsfaktoren) |
| **Ausnützung** | Ausnützungsübertragungen |
| **Umwelt** | Schadstoffbelastungen auf Parzellen |
| **Planung** | Aktive Gestaltungspläne |
| **Lärm** | Lärmempfindlichkeitsstufen |
| **Energie** | Mögliche Wärmenutzung (Wärmeverbundnetze; Fernwärme, Anergie) |
| **Natur** | Baumbestand auf privaten Grundstücken |
| **Schutz** | Isos (Ortsbild, Schutzstatus, Denkmalschutz, Weilergebiet, etc.) |
| **Gefahren** | Naturgefahren (z.B. Objektschutzmassnahmen (Hochwasser)) |
| **Revision** | Verweis auf aktuell in oder zukünftig in Revision befindlichen Normen/Gesetze (z.B. Revision PBG mit aktuell negativer Vorwirkung) |
**Design-Rationale:**
Das Kontext-Objekt ermöglicht flexibles Hinzufügen von projektspezifischen, parzellen-spezifischen oder regionalen Informationen ohne Schemaänderungen.
---
### 7. Hilfsentitäten & Enumerationen
#### JaNein (Enum)
**Drei-wertiger Zustand für optionale Ja/Nein-Fragen.**
| Wert | Bedeutung |
|------|-----------|
| `""` (leer) | Unbekannt / Nicht erfasst |
| `"Ja"` | Ja / Zutreffend |
| `"Nein"` | Nein / Nicht zutreffend |
**Verwendung:**
- `parzelleBebaut`: Ist die Parzelle bebaut?
- `parzelleErschlossen`: Ist die Parzelle erschlossen?
- `parzelleHanglage`: Liegt die Parzelle in Hanglage?
---
#### StatusProzess (Enum)
**Projektstatus zur Nachverfolgung des Projektfortschritts.**
| Wert | Beschreibung |
|------|--------------|
| `Eingang` | Projekt wurde eingereicht |
| `Analyse` | Projekt wird analysiert |
| `Studie` | Machbarkeitsstudie läuft |
| `Planung` | Planungsphase |
| `Baurechtsverfahren` | Baubewilligung läuft |
| `Umsetzung` | Bauprojekt in Umsetzung |
| `Archiv` | Projekt abgeschlossen |
---
#### DokumentTyp (Enum)
**Dokumenttyp zur Kategorisierung von Dokumenten, insbesondere für kantonale und kommunale Dokumente.**
| Wert | Beschreibung |
|------|--------------|
| `kantonBaureglementAktuell` | Aktuelles Baureglement (Kanton) |
| `kantonBaureglementRevision` | Baureglement in Revision (Kanton) |
| `kantonBauverordnungAktuell` | Aktuelle Bauverordnung (Kanton) |
| `kantonBauverordnungRevision` | Bauverordnung in Revision (Kanton) |
| `gemeindeBzoAktuell` | Aktuelle Bau- und Zonenordnung (BZO) (Gemeinde) |
| `gemeindeBzoRevision` | BZO in Revision (Gemeinde) |
**Verwendung:**
- Dokumente in der `dokumente`-Liste von Kanton oder Gemeinde können über `dokumentTyp` identifiziert werden
- Ermöglicht die Suche nach aktuellen oder in Revision befindlichen Dokumenten
---
## Q & A
1. **Versionierung**: Sollen Änderungen an Parzellen historisiert werden? --> Vorerst nicht
2. **Mehrsprachigkeit**: Labels in DE/FR/IT? --> Wir im Pydantic Model später umgesetzt
3. **Benutzer & Rollen**: Wer darf was bearbeiten? --> In der App über Roles und Permissions gesteuert
4. **Workflow-Engine**: Für Statusübergänge und Genehmigungen? --> In der App über Workflow-Engine gesteuert
5. **Integration**: Anbindung an amtliche Geodaten (z.B. Swisstopo API)? --> In der App über Integrationen gesteuert
6. **Berechnungen**: Sollen Ausnützungsberechnungen automatisiert werden? --> In der App über Berechnungen gesteuert
---
## Nächste Schritte
1. **Validierung**: Review mit PEK
2. **Prototyp**: Implementierung der Datenmodell-Klassen
3. **GIS-Integration**: PostGIS aufsetzen, Test-Geodaten importieren
4. **API-Design**: RESTful API (FastAPI) mit OpenAPI-Dokumentation