gateway/docs/real-estate-feature-integration-guide/03-interfaces.md

288 lines
12 KiB
Markdown

# Schritt 2: Interface erstellen
[← Zurück: Datenmodell erstellen](02-datamodels.md) | [Weiter: Feature-Logik implementieren →](04-feature-logic.md)
## Übersicht: Was sind Interfaces?
**Interfaces** sind aktive Klassen, die den **Datenbankzugriff** implementieren. Sie unterscheiden sich von **Datamodels** (die nur die Datenstruktur definieren):
| **Aspekt** | **Datamodels** | **Interfaces** |
|------------|----------------|----------------|
| **Zweck** | Definiert **WAS** (Datenstruktur) | Implementiert **WIE** (Datenzugriff) |
| **Inhalt** | Pydantic-Modelle mit Feldern und Validierung | Klassen mit CRUD-Methoden (`create`, `get`, `update`, `delete`) |
| **Beispiel** | `class Projekt(BaseModel): ...` | `def createProjekt(...) -> Projekt: ...` |
| **Aktivität** | Passiv (nur Struktur) | Aktiv (führt Operationen aus) |
**Analogie:**
- **Datamodel** = Bauplan (beschreibt das Haus)
- **Interface** = Bauunternehmer (baut das Haus)
---
## Struktur: Real Estate CRUD-Interface
Da das Feature **stateless** arbeitet, benötigen wir nur **ein Interface** für CRUD-Operationen auf Real Estate-Entitäten:
### Real Estate-Datenmodelle → Real Estate CRUD-Interface
**Datamodel:** `datamodelRealEstate.py`
- `Projekt`
- `Parzelle`
- `Dokument`
- `Kanton`, `Gemeinde`, `Land`
- `GeoPolylinie`, `GeoPunkt`
- `Kontext`
- etc.
**Interface:** `interfaceDbRealEstateObjects.py`
- `RealEstateObjects` (Haupt-Interface)
- `RealEstateAccess` (Zugriffskontrolle)
- Methoden: `createProjekt()`, `getParzelle()`, `updateDokument()`, etc.
**Hinweis:** Das Haupt-Interface enthält auch `executeQuery()` für direkte SQL-Queries (stateless)
---
## Warum nur ein Haupt-Interface?
1. **Stateless Design**:
- Keine Session-Verwaltung notwendig
- Direkte CRUD-Operationen auf Real Estate-Modellen
2. **Einfache Architektur**:
- Ein Interface für alle CRUD-Operationen
- Weniger Komplexität, bessere Wartbarkeit
3. **Query-Funktionalität**:
- `executeQuery()` ist direkt im Haupt-Interface verfügbar
- Für direkte SQL-Queries (stateless)
- Keine Session-Management-Funktionen
---
## Zu erstellende Dateien
### Schritt 2a: Real Estate CRUD-Interface (ERFORDERLICH)
**Zwei separate Dateien** (wie bei anderen Features):
#### Datei 1: `modules/interfaces/interfaceDbRealEstateAccess.py`
**Enthält:**
- `RealEstateAccess` - Zugriffskontrolle für Real Estate-Entitäten
- Methoden: `uam()`, `canModify()`
**Zweck:** Prüft Zugriffsrechte und filtert Daten basierend auf Benutzerprivilegien
#### Datei 2: `modules/interfaces/interfaceDbRealEstateObjects.py`
**Enthält:**
- `RealEstateObjects` - Haupt-Interface für CRUD-Operationen
- `getInterface()` - Factory-Funktion
- Nutzt `RealEstateAccess` aus der Access-Datei
**Zweck:** Verwaltet Real Estate-Entitäten (Projekt, Parzelle, Dokument, etc.)
**Nutzt:**
- `datamodelRealEstate.py` (Projekt, Parzelle, Dokument, etc.)
- `interfaceDbRealEstateAccess.py` (für Zugriffskontrolle)
**Wann benötigt:** Für alle CRUD-Operationen auf Real Estate-Entitäten (z.B. Projekte erstellen/bearbeiten, Parzellen verwalten). Dies ist das Haupt-Interface für das Feature.
---
## Übersicht: Dateien und ihre Beziehungen
```
┌─────────────────────────────────────────────────────────────┐
│ DATAMODELS (Struktur) │
├─────────────────────────────────────────────────────────────┤
│ datamodelRealEstate.py │
│ ├── Projekt │
│ ├── Parzelle │
│ ├── Dokument │
│ ├── Kanton, Gemeinde, Land │
│ ├── GeoPolylinie, GeoPunkt │
│ ├── Kontext │
│ └── ... │
└─────────────────────────────────────────────────────────────┘
│ nutzt
┌─────────────────────────────────────────────────────────────┐
│ INTERFACES (Zugriff) │
├─────────────────────────────────────────────────────────────┤
│ REAL ESTATE CRUD-INTERFACE (ERFORDERLICH) │
│ │
│ interfaceDbRealEstateAccess.py │
│ └── RealEstateAccess │
│ ├── uam() │
│ └── canModify() │
│ │
│ interfaceDbRealEstateObjects.py │
│ ├── RealEstateObjects │
│ │ ├── createProjekt() │
│ │ ├── getProjekt() │
│ │ ├── updateProjekt() │
│ │ ├── deleteProjekt() │
│ │ ├── createParzelle() │
│ │ ├── getParzelle() │
│ │ └── ... (CRUD für alle Entitäten) │
│ └── getInterface() │
│ └── nutzt RealEstateAccess │
│ │
│ │
│ HINWEIS: executeQuery() ist im Haupt-Interface verfügbar │
│ (kein separates Chat-Interface notwendig) │
└─────────────────────────────────────────────────────────────┘
```
---
## Interface-Struktur: Access vs. Objects
Jedes Interface besteht aus **zwei Klassen**:
### 1. `*Access` Klasse (Zugriffskontrolle)
**Zweck:** Prüft, wer was sehen/dürfen darf
**Methoden:**
- `uam()` - Filtert Daten basierend auf Benutzerprivilegien
- `canModify()` - Prüft, ob Benutzer ändern darf
**Beispiel:** `RealEstateAccess`
### 2. `*Objects` Klasse (Haupt-Interface)
**Zweck:** Führt CRUD-Operationen aus
**Methoden:**
- `create*()` - Erstellt neue Einträge
- `get*()` - Lädt einzelne Einträge nach ID
- `get*()` (Plural) - Lädt Listen von Einträgen mit optionalen Filtern
- `update*()` - Aktualisiert Einträge
- `delete*()` - Löscht Einträge
- `executeQuery()` - Führt direkte SQL-Queries aus (stateless)
**Nutzt:** `*Access` für Zugriffskontrolle
**Beispiel:** `RealEstateObjects`
**Warum getrennt?**
- Separation of Concerns: Zugriffskontrolle ist separate Verantwortlichkeit
- Wiederverwendbarkeit: Access-Klasse kann von mehreren Interfaces genutzt werden
- Testbarkeit: Zugriffskontrolle kann unabhängig getestet werden
---
## Implementierung: Real Estate CRUD-Interface
Das Real Estate CRUD-Interface besteht aus **zwei separaten Dateien**, genau wie bei anderen Features (`interfaceDbAppObjects.py` + `interfaceDbAppAccess.py`).
### Datei 1: Access-Implementierung
**Datei:** `modules/interfaces/interfaceDbRealEstateAccess.py`
**Enthält:**
- `RealEstateAccess` Klasse
- Methoden: `uam()`, `canModify()`
**Funktionalität:**
- **`uam()`**: Filtert Datensätze basierend auf Benutzerprivilegien (SYSADMIN sieht alles, ADMIN sieht Mandat, User sieht nur eigene)
- **`canModify()`**: Prüft, ob Benutzer Datensätze ändern/löschen darf
- Fügt Zugriffskontroll-Attribute hinzu: `_hideView`, `_hideEdit`, `_hideDelete`
---
### Datei 2: Objects-Implementierung
**Datei:** `modules/interfaces/interfaceDbRealEstateObjects.py`
**Enthält:**
- `RealEstateObjects` Klasse (Haupt-Interface)
- `getInterface()` Factory-Funktion (Singleton-Pattern)
**Datenbank-Konfiguration:**
- Verwendet `DB_REALESTATE_*` Umgebungsvariablen (nicht `DB_APP_*`)
- Variablen: `DB_REALESTATE_HOST`, `DB_REALESTATE_DATABASE`, `DB_REALESTATE_USER`, `DB_REALESTATE_PASSWORD_SECRET`, `DB_REALESTATE_PORT`
**CRUD-Methoden für alle Entitäten:**
- **Projekt**: `createProjekt()`, `getProjekt()`, `getProjekte()`, `updateProjekt()`, `deleteProjekt()`
- **Parzelle**: `createParzelle()`, `getParzelle()`, `getParzellen()`, `updateParzelle()`, `deleteParzelle()`
- **Dokument**: `createDokument()`, `getDokument()`, `getDokumente()`, `updateDokument()`, `deleteDokument()`
- **Gemeinde**: `createGemeinde()`, `getGemeinde()`, `getGemeinden()`, `updateGemeinde()`, `deleteGemeinde()`
- **Kanton**: `createKanton()`, `getKanton()`, `getKantone()`, `updateKanton()`, `deleteKanton()`
- **Land**: `createLand()`, `getLand()`, `getLaender()`, `updateLand()`, `deleteLand()`
**Zusätzliche Funktionalität:**
- **List-Methoden**: Alle Entitäten haben `get*()` (Plural) Methoden für Listen mit optionalen Filtern
- **Location-Resolution**: `getParzellen()` löst automatisch Gemeinde-Namen zu IDs auf
- **Query-Ausführung**: `executeQuery()` für direkte SQL-Queries (stateless)
- **Supporting Tables**: Automatische Erstellung von Land, Kanton, Gemeinde, Dokument Tabellen bei Initialisierung
## Wichtige Punkte:
1. **DatabaseConnector**: Nutzt `connectorDbPostgre.DatabaseConnector` für Datenbankzugriff
2. **Access Control**: `RealEstateAccess` implementiert Benutzer- und Mandaten-Filterung
3. **Singleton Pattern**: `getInterface()` erstellt pro User eine Instanz
4. **CRUD-Operationen**: `recordCreate`, `recordModify`, `recordDelete`, `getRecordset` vom Connector
5. **MandateId**: Wird automatisch gesetzt, wenn nicht vorhanden
6. **List-Methoden**: Alle Entitäten haben `get*()` (Plural) Methoden für Listen mit optionalen Filtern
7. **Location-Resolution**: Parzelle-Filter können Gemeinde-Namen enthalten, die automatisch zu IDs aufgelöst werden
8. **Query-Ausführung**: `executeQuery()` ist direkt im Haupt-Interface verfügbar (kein separates Chat-Interface notwendig)
9. **Datenbank-Initialisierung**: Unterstützende Tabellen (Land, Kanton, Gemeinde, Dokument) werden automatisch erstellt
---
## Query-Ausführung: executeQuery()
Das Haupt-Interface `RealEstateObjects` enthält die Methode `executeQuery()` für direkte SQL-Queries. **Kein separates Chat-Interface ist notwendig.**
### Verwendung
**Für CRUD-Operationen (EMPFOHLEN):**
- Verwenden Sie die strukturierten CRUD-Methoden (`createProjekt()`, `getProjekte()`, etc.)
- Vorteile: Validierung, Zugriffskontrolle, Typsicherheit, keine SQL-Injection-Risiken
**Für komplexe SELECT-Queries (OPTIONAL):**
- Verwenden Sie `executeQuery()` direkt im Haupt-Interface
- **Warnung**: Nur für SELECT-Queries, immer Parameterisierung verwenden, Queries validieren
### Hinweise zur Query-Ausführung
1. **Stateless**: Keine Session-Management-Funktionen
2. **Nur für Queries**: Primär für SELECT-Queries gedacht
3. **Sicherheit**: Immer Parameterisierung verwenden
4. **Validierung**: Queries sollten validiert werden (z.B. nur SELECT erlauben)
---
## Zusammenfassung: Benötigte Dateien
### Erforderlich (für CRUD-Operationen):
1.`modules/datamodels/datamodelRealEstate.py`
- Real Estate-Datenmodelle (Projekt, Parzelle, Dokument, etc.)
2.`modules/interfaces/interfaceDbRealEstateAccess.py`
- Zugriffskontrolle für Real Estate-Entitäten (RealEstateAccess)
3.`modules/interfaces/interfaceDbRealEstateObjects.py`
- Real Estate CRUD-Interface (RealEstateObjects)
- Nutzt `interfaceDbRealEstateAccess.py`
- Haupt-Interface für alle CRUD-Operationen
### Hinweis zu Query-Ausführung:
4.`executeQuery()` ist bereits im Haupt-Interface verfügbar
- Kein separates Chat-Interface notwendig
- Direkt in `RealEstateObjects` verfügbar
- Stateless, keine Session-Management
---
[← Zurück: Datenmodell erstellen](02-datamodels.md) | [Weiter: Feature-Logik implementieren →](04-feature-logic.md)