288 lines
12 KiB
Markdown
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)
|
|
|
|
|
|
|