Files
MarcWieland 411ede36ef init
2026-07-26 23:58:12 +02:00

125 lines
6.7 KiB
Markdown

# Handwerksfreund - Datenstruktur & Domänenmodell
Dieses Dokument beschreibt die grundlegende Datenstruktur für das Projekt **Handwerksfreund**. Es dient als Diskussionsgrundlage für die Datenbankmodellierung in Supabase/PostgreSQL.
---
## 1. Entitäten-Übersicht
```mermaid
erDiagram
KUNDE ||--o{ VERBAUTES_TEIL : "besitzt"
KUNDE ||--o{ AUFTRAG : "beauftragt"
AUFTRAG ||--o{ VERBAUTES_TEIL : "installiert im Rahmen von"
AUFTRAG ||--o{ AUFTRAGS_ANHANG : "enthält n Dokumente/Baupläne"
KUNDE ||--o{ TERMIN_EINTRAG : "bezieht sich auf"
AUFTRAG ||--o{ TERMIN_EINTRAG : "eingeplant als"
```
---
## 2. Detaillierte Felddefinitionen
### 2.1 Kunde (`customers`)
Stammdaten der Kunden inklusive Geokoordinaten für die Kartendarstellung und Vor-Ort-Notizen.
| Feld | Datentyp | Pflichtfeld | Beschreibung / Beispiel |
| :--- | :--- | :---: | :--- |
| `id` | UUID | Ja | Eindeutige ID (Primärschlüssel) |
| `customer_number` | Text | Ja | Eindeutige Kundennummer (z.B. `K-10025`) |
| `name` | Text | Ja | Vollständiger Name / Firmenname (z.B. `Max Mustermann`) |
| `street` | Text | Ja | Straße & Hausnummer (z.B. `Musterweg 12`) |
| `zip_code` | Text | Ja | Postleitzahl (z.B. `12345`) |
| `city` | Text | Ja | Stadt (z.B. `Musterstadt`) |
| `latitude` | Float (Double) | Ja | Geografische Breite für Karten-Pin |
| `longitude` | Float (Double) | Ja | Geografische Länge für Karten-Pin |
| `distance_km` | Float (Double) | Nein | Berechnete Entfernung zum Techniker-Standort |
| `phone` | Text | Nein | Telefonnummer (z.B. `0171 1234567`) |
| `email` | Text | Nein | E-Mail-Adresse (z.B. `max.mustermann@email.de`) |
| `notes` | Text | Nein | Vor-Ort-Hinweise (z.B. `Schlüsselbox an der Garage`) |
| `first_contact_date` | Datum | Nein | Erstkontakt-Datum (z.B. `10.03.2022`) |
| `open_orders_count` | Ganzzahl | Nein | Anzahl offener Aufträge (berechnet oder gecached) |
| `last_order_date` | Datum | Nein | Datum des letzten ausgeführten Auftrags |
| `created_at` | Zeitstempel | Ja | Erstellungszeitpunkt des Datensatzes |
---
### 2.2 Verbaute Teile / Gerätekartei (`installed_parts`)
Alle beim Kunden installierten Geräte, Heizungsanlagen, Thermostate, Filter und Ersatzteile mit Seriennummern.
| Feld | Datentyp | Pflichtfeld | Beschreibung / Beispiel |
| :--- | :--- | :---: | :--- |
| `id` | UUID | Ja | Eindeutige ID (Primärschlüssel) |
| `customer_id` | UUID | Ja | Referenz auf den Besitzer (`customers.id`) |
| `order_id` | UUID | Nein | Referenz auf den Auftrag, bei dem das Teil verbaut wurde |
| `name` | Text | Ja | Produktbezeichnung (z.B. `Buderus Logamax plus GB172-24`) |
| `category` | Text | Ja | Geräte-Kategorie (z.B. `Gas-Brennwertgerät`, `Raumthermostat`) |
| `serial_number` | Text | Nein | Eindeutige Seriennummer (z.B. `8374747383`) |
| `quantity` | Ganzzahl | Ja | Anzahl verbauter Einheiten (Standard: `1`) |
| `installed_at` | Datum | Nein | Einbaudatum |
| `created_at` | Zeitstempel | Ja | Erstellungszeitpunkt des Datensatzes |
---
### 2.3 Auftrag (`work_orders`)
Aufträge und Wartungsarbeiten, die für Kunden angelegt und ausgeführt werden.
| Feld | Datentyp | Pflichtfeld | Beschreibung / Beispiel |
| :--- | :--- | :---: | :--- |
| `id` | UUID | Ja | Eindeutige ID (Primärschlüssel) |
| `customer_id` | UUID | Ja | Referenz auf den Kunden (`customers.id`) |
| `title` | Text | Ja | Titel des Auftrags (z.B. `Wartung Heizungsanlage`) |
| `description` | Text | Nein | Beschreibung & Aufgabenstellung |
| `status` | Enum | Ja | Status: `offen`, `inBearbeitung`, `abgeschlossen`, `storniert` |
| `scheduled_date` | Datum | Nein | Geplantes Ausführungsdatum |
| `completed_at` | Zeitstempel | Nein | Zeitpunkt der Fertigstellung |
| `created_at` | Zeitstempel | Ja | Erstellungszeitpunkt |
---
### 2.4 Auftrags-Anhänge & Dokumente (`order_attachments`) 📄📍
Baupläne, CAD-Zeichnungen, Fotos vor Ort, Schaltpläne und Misc-Dateien zu einem Auftrag.
> **Speicherung in Supabase**: Die eigentliche Datei (z.B. PDF, PNG) liegt im **Supabase Storage Bucket** (`order-files`). In dieser DB-Tabelle speichern wir die Metadaten & den Storage-Pfad.
| Feld | Datentyp | Pflichtfeld | Beschreibung / Beispiel |
| :--- | :--- | :---: | :--- |
| `id` | UUID | Ja | Eindeutige ID (Primärschlüssel) |
| `order_id` | UUID | Ja | Referenz auf den Auftrag (`work_orders.id`) |
| `title` | Text | Ja | Name der Datei / Anzeige-Titel (z.B. `Bauplan EG - Sanitär.pdf`) |
| `category` | Enum / Text | Ja | Kategorie: `bauplan`, `schaltplan`, `foto_vor_ort`, `abnahmeprotokoll`, `sonstiges` |
| `file_path` | Text | Ja | Pfad im Supabase Storage Bucket (z.B. `orders/ord-123/bauplan_eg.pdf`) |
| `file_size_bytes` | Ganzzahl | Nein | Dateigröße in Bytes (z.B. `2458120` für ~2.4 MB) |
| `mime_type` | Text | Nein | Dateityp (z.B. `application/pdf`, `image/png`) |
| `uploaded_at` | Zeitstempel | Ja | Upload-Zeitpunkt |
---
### 2.5 Termin-Eintrag / Tagesplan (`schedule_items`)
Zeitleisten-Einträge für die Tages- und Wochenansicht (Aufträge, Besprechungen, Mittagspause, Feierabend).
| Feld | Datentyp | Pflichtfeld | Beschreibung / Beispiel |
| :--- | :--- | :---: | :--- |
| `id` | UUID | Ja | Eindeutige ID (Primärschlüssel) |
| `order_id` | UUID | Nein | Verknüpfung zum Auftrag (falls vorhanden) |
| `customer_id` | UUID | Nein | Verknüpfung zum Kunden (falls vorhanden) |
| `title` | Text | Ja | Titel (z.B. `Max Mustermann - Heizungswartung` oder `Mittagspause`) |
| `customer_name` | Text | Nein | Kundenname für Schnellanzeige |
| `address` | Text | Nein | Einsatzadresse |
| `task_description` | Text | Nein | Spezifische Aufgabe |
| `start_time` | Uhrzeit / Text | Ja | Startzeit (z.B. `10:30`) |
| `end_time` | Uhrzeit / Text | Ja | Endzeit (z.B. `13:00`) |
| `type` | Enum | Ja | Typ: `job`, `routine`, `lunchBreak`, `feierabend` |
| `is_completed` | Boolean | Ja | Flag: Auftrag abgeschlossen |
| `is_in_progress` | Boolean | Ja | Flag: Anfahrt gestartet / in Bearbeitung |
| `scheduled_date` | Datum | Ja | Datum des Tagesplans |
| `created_at` | Zeitstempel | Ja | Erstellungszeitpunkt |
---
## 3. Offene Fragen & Diskussionspunkte
1. **Entfernung (`distance_km`)**: Sollen wir die Distanz dynamisch via Geo-Abfrage (PostGIS) zur aktuellen Handwerker-Position berechnen lassen, oder als festes Feld im Kunden speichern?
2. **Kombination `work_orders` & `schedule_items`**: Reicht ein einziges Feld `work_orders` mit Uhrzeit, oder gefällt dir die Trennung von *Auftrag* (Fachlicher Arbeitsauftrag) und *Termin-Eintrag* (Konkreter Kalendereintrag in der Zeitleiste)?
3. **Baupläne / Anhänge**: Gefällt dir die Aufteilung mit `order_attachments`? So kann ein Techniker vor Ort in Flutter auf *"Baupläne"* tippen, bekommt eine Liste aller PDFs/Fotos des Auftrags und kann per Klick direkt neue Fotos vom Handy hochladen!