16 KiB
HausPilot-Fachmodule
MVP-Abschluss 2026-07
Neue Migration und Datenmodelle
1720000005000-AddMentionsAndReminders.ts ergänzt task_comment_mentions, reminder_deliveries und applied_project_templates. Eindeutige Constraints deduplizieren Benutzer pro Kommentar, Reminder-Schlüssel sowie Vorlagen je Projekt und Ziel. Die Tabellen referenzieren weiterhin ausschließlich bestehende Benutzer- und Projekt-UUIDs.
Listen-API
Räume, Aufgaben, Meilensteine, Ausgaben, Dokumente, Kommentare und Aktivitäten liefern serverseitig { items, page, pageSize, totalItems, totalPages }. pageSize ist auf 100 begrenzt. Filter enthalten stets projectId. Sortierfelder sind DTO-Whitelists und werden nie als frei übergebener SQL-Ausdruck ausgeführt. Aufgaben unterstützen Suchtext, mehrere Statuswerte, Priorität, Raum, Verantwortlichen, Kategorie, Datumsbereiche, überfällig, blockiert, nicht zugewiesen und „nur meine“. Ausgaben und Dokumente besitzen Zuordnungs- und Datumsfilter.
Neue gezielte Leseendpunkte sind GET /projects/:projectId/tasks/:taskId und GET /projects/:projectId/calendar?from=YYYY-MM-DD&to=YYYY-MM-DD. Die stabile Angular-Route /projekte/:projectId/aufgaben/:taskId enthält Stammdaten, Schnellstatus, Checkliste, Vorgänger und Nachfolger, Kommentare, Erwähnungen, Dokumente und den Aktivitätsauszug. Der Zeitplan bietet eine responsive Monats- und Agendaansicht ohne neue UI-Bibliothek und lädt nur den benötigten Zeitraum.
Vorlagen
Die unveränderlichen Systemvorlagen „Reihenhaus-Renovierung“, „Schlüsselübergabe“, „Renovierung eines Raums“ und „Umzug“ werden transaktional kopiert. Die Reihenhausvorlage enthält fünf Bereiche, 15 Räume, 13 Budgetkategorien, Meilensteine und allgemeine Aufgaben. Die Raumvorlage erzeugt 14 Aufgaben samt Abhängigkeitskette. applied_project_templates erkennt Wiederholungen je Projekt und Zielraum; erneute Anwendung verlangt confirmDuplicate. Fehler rollen alle Kopien und die Aktivität gemeinsam zurück.
Strukturierte Erwähnungen
Kommentare übertragen neben sichtbarem @Anzeigename eine validierte Liste stabiler Benutzer-UUIDs. Nur aktive Mitglieder desselben Projekts werden akzeptiert. Mehrfachnennungen werden dedupliziert, Selbst-Erwähnungen erzeugen keine Nachricht und beim Bearbeiten werden nur neu hinzugekommene Benutzer benachrichtigt. Die In-App-Nachricht verweist direkt auf Aufgabe und Kommentar.
Scheduler und Reminder
Der offizielle Nest-Scheduler führt den ReminderService standardmäßig alle 15 Minuten aus. Er erfasst bald fällige und überfällige Aufgaben, Meilensteine, überfällige offene Ausgaben sowie bald ablaufende Einladungen mit bekanntem Benutzer. Entfernte oder global deaktivierte Mitglieder erhalten nichts. reminder_deliveries.dedupe_key enthält Reminder-Art, Entität, Empfänger und Bezugsdatum; der Unique Constraint schützt auch parallele Läufe. Eine Datumsänderung erzeugt einen neuen fachlich relevanten Schlüssel.
REMINDER_INTERVAL_MS: mindestens 60.000, Standard 900.000REMINDER_DUE_SOON_DAYS: Standard 3
Development-Seed
Nach Migrationen und mindestens einem vorhandenen aktiven SSO-Benutzer wird der ausschließlich explizite Seed gestartet:
npm run seed:development
Er erzeugt idempotent „Umzug Reihenhaus“ mit fünf Etagen, 15 Räumen, 30 Aufgaben, zehn Abhängigkeiten, 20 Checklistenpunkten, zehn Kommentaren, acht Meilensteinen, 13 Budgetkategorien, 15 Ausgaben, vier Dokumentmetadaten, 20 Aktivitäten, In-App-Benachrichtigungen und – sofern vorhanden – bis zu vier bestehende Benutzer in unterschiedlichen Rollen. Er legt weder Benutzer noch Passwörter an. In NODE_ENV=production verweigert er Ausführung und Reset. Der gezielte Reset entfernt nur das eindeutig markierte Seed-Projekt:
npm run seed:development -- --reset
Seed-Dokumente enthalten absichtlich nur Metadaten, keine fingierten Binärdateien.
Abhängigkeitssicherheit und Grenzen
Die produktiven Advisories wurden ohne Major-Upgrade geschlossen: @nestjs/swagger 11.4.6 und TypeORM 0.3.31 beheben die gemeldeten transitiven Risiken in js-yaml, lodash, path-to-regexp und TypeORM. npm audit --omit=dev meldet danach keine bekannte Schwachstelle. @nestjs/schedule 6.1.3 (MIT, Nest-10/11-kompatibel) ist die einzige neue Laufzeitabhängigkeit.
Der Scheduler läuft pro Backend-Instanz; der Datenbank-Constraint macht die Auslieferung mehrfach laufender Instanzen idempotent, ersetzt bei sehr großen Installationen jedoch kein verteiltes Job-Leasing. Komplexe Gantt-, Offline-, E-Mail- und externe Kalenderfunktionen bleiben außerhalb des MVP.
Ausgangsarchitektur und Wiederverwendung
Die Umsetzung erweitert die bestehende Angular-/NestJS-Anwendung. Globale Anmeldung, OIDC, serverseitige MySQL-Session, CSRF, PermissionsGuard, ProjectAccessService, ProjectMembershipEntity, NotificationsService und ProjectActivityEntity bleiben die einzigen Mechanismen für Identität, Projektzugriff, Benachrichtigungen und Aktivitäten. Es gibt keine zweite Benutzer-, Login-, Session- oder Projektverwaltung.
Die fachlichen Controller tragen weiterhin @RequirePermissions(Permission.ProjectsUse). Danach prüft ProjectAccessService die aktive Mitgliedschaft und die Projektrolle. Jede Unterentität wird zusätzlich mit der Kombination aus id und projectId geladen. Dadurch reicht weder eine gültige Anmeldung noch eine fremde Entitäts-ID zum Zugriff.
Datenmodell und Module
RenovationModule bündelt die eng zusammenhängende Renovierungsdomäne und besteht aus Controller, Service, Persistence-Repository, Dokumentablage und DTO-Validierung. Die Migration 1720000004000-AddRenovationDomain.ts ergänzt:
- Gebäude, Etagen und Räume
- Renovierungsaufgaben, Checklisten, Abhängigkeiten und Kommentare
- Meilensteine
- Budgetkategorien und Ausgaben
- projektbezogene Dokumentmetadaten
- Projektstatus, Währung und Gesamtbudget-Grundlage
Historische Benutzerbeziehungen verwenden die bestehende interne User-UUID. Beim Entfernen eines Mitglieds werden offene Zuweisungen in derselben Transaktion geleert; abgeschlossene und historische Beziehungen bleiben erhalten.
API
Die API liegt unter /api/projects/:projectId und stellt Listen sowie Create-/Patch-/Delete-Endpunkte für buildings, floors, rooms, tasks, milestones, budget-categories, expenses und documents bereit. Aufgaben besitzen zusätzlich checklist, dependencies und comments. Weitere gezielte Endpunkte sind:
GET /projects/:projectId/dashboardGET /projects/:projectId/activitiesGET /templatesPOST /projects/:projectId/apply-template/:templateIdGET /projects/:projectId/documents/:id/download
Request-DTOs enthalten weder Ersteller noch handelnde Benutzer. Diese IDs stammen ausschließlich aus dem bestehenden Sessionkontext.
Rollen
- Eigentümer und Projektadministratoren verwalten die gesamte Struktur, Budgets und Vorlagen.
- Bearbeiter verwalten Räume, Aufgaben, Checklisten, Kommentare, Ausgaben und Dokumente.
- Leser können ausschließlich lesen.
Budgetkategorien sind bewusst Eigentümern und Projektadministratoren vorbehalten, weil ihre Änderung den finanziellen Projektrahmen verändert. Globale SSO-Rollen erzeugen weiterhin keine Projektmitgliedschaft.
Fortschritt und Abhängigkeiten
Die einzige Fortschrittsberechnung liegt in renovation/progress.ts: Idee 0, geplant 10, beauftragt 25, in Arbeit 50, blockiert 25, Abnahme 90 und erledigt 100 Prozent. Entfallene Aufgaben werden ausgeschlossen. Das optionale positive Gewicht bildet einen gewichteten Mittelwert; ohne fachliches Gewicht wird 1 verwendet.
Die zentrale Zykluserkennung erweitert den gerichteten Graphen probeweise um die neue Kante und führt eine Tiefensuche mit visiting-/visited-Mengen aus. Selbstbezüge sowie direkte und indirekte Zyklen werden mit HTTP 409 abgewiesen. Eine Aufgabe ist blockiert, sobald ein zwingender Vorgänger nicht erledigt ist; der Start wird dann serverseitig verhindert.
Dashboard und Budget
Der Dashboard-Endpunkt berechnet aggregiert Gesamtfortschritt, offene, überfällige, blockierte, kritische, eigene und nicht zugewiesene Aufgaben, Raumstatus, nächste/gefährdete Meilensteine, aktive Mitglieder sowie geplante, tatsächliche, offene und bezahlte Kosten. Handlungsorientierte Hinweise werden serverseitig aus denselben Daten erzeugt.
Geldbeträge werden in MySQL als DECIMAL gespeichert und erst für Aggregationen explizit in Zahlen überführt. Stornierte Ausgaben fließen nicht in tatsächliche Kosten ein.
Optimistische Nebenläufigkeit
Gebäude, Etagen, Räume, Aufgaben, Meilensteine, Budgetkategorien, Ausgaben und Dokumentmetadaten besitzen eine Versionsnummer. Updates verwenden atomar WHERE id = ? AND project_id = ? AND version = ? und erhöhen die Version in derselben SQL-Anweisung. Ein veralteter Stand überschreibt daher keine neueren Daten und liefert HTTP 409. Angular zeigt dafür einen konkreten Konflikthinweis und führt keine verlustbehaftete automatische Zusammenführung durch.
Dokumentablage
Dateien werden nicht öffentlich ausgeliefert. Upload und Download laufen nach Projektzugriffsprüfung über das Backend. Erlaubt sind PDF, JPEG, PNG und WebP bis zum konfigurierten Limit. Endung, MIME-Typ und Dateisignatur müssen zusammenpassen; der Speichername ist eine zufällige UUID und Pfadbestandteile aus dem Client werden nie übernommen. Metadaten liegen in MySQL, Inhalte unter DOCUMENT_STORAGE_PATH.
Konfiguration:
DOCUMENT_STORAGE_PATH(Standardstorage/documents)DOCUMENT_MAX_FILE_SIZE_BYTES(Standard 10 MiB)
Für mehrere Backend-Instanzen muss der Pfad als gemeinsames, geschütztes Volume bereitgestellt werden. Virenscanning und objektbasierter Cloud-Speicher sind sinnvolle Produktionsausbaustufen.
Frontend
Der responsive Projektarbeitsbereich nutzt ausschließlich bestehende Design-Tokens und UI-Komponenten. Die horizontale, tastaturbedienbare Projektnavigation umfasst Übersicht, Räume, Aufgaben, Zeitplan, Budget, Dokumente, Aktivitäten und die bestehende Mitgliederseite. Listen wechseln auf kleinen Displays in Karten; Hauptaktionen benötigen kein Hover.
Vorlagen und Erweiterbarkeit
Systemvorlagen werden als unveränderliche Definitionen angeboten. Die Raumrenovierung kopiert Aufgaben und Abhängigkeiten; ein vorhandener Aufgabenbestand verlangt eine explizite Duplikatbestätigung. Die Servicegrenze ist für weitere transaktionale Vorlagen vorbereitet.
Spätere Module für Kartons/QR-Codes, Inventar, Lieferanten/Angebote, Materialmengen, Rechnungserkennung, KI-Planung, E-Mail-Erinnerungen und Kalenderintegration können über projectId, bestehende Mitgliedschaften, Dokumentreferenzen, Aktivitäten und Benachrichtigungen angebunden werden, ohne Authentifizierung oder Projektzugriff zu duplizieren.
Tests
Die Verhaltenstests decken insbesondere die gewichtete Fortschrittsberechnung, ausgeschlossene Aufgaben, direkte/indirekte Abhängigkeitszyklen, kombinierte Aufgabenfilter und den Concurrency-Hinweis ab. Bestehende Tests sichern SSO, Projektzugriff, Einladungen, Sessions und Benachrichtigungen weiterhin ab.
Frühere MVP-Grenzen
Die zuvor fehlenden Vorlagen, strukturierten Erwähnungen und deduplizierten Reminder wurden mit dem oben dokumentierten MVP-Abschluss umgesetzt. Eine Queue wurde dafür bewusst nicht eingeführt.
Möbel- und Einrichtungsplanung
AG-Grid-Arbeitsoberfläche
Die Möbelverwaltung nutzt ag-grid-angular und ag-grid-community 36.0.1 (MIT, Community
Edition). Registriert wird ausschließlich AllCommunityModule. Enterprise-Funktionen wie Row
Grouping und Master/Detail werden weder importiert noch vorausgesetzt. Bedarfe, Alternativen,
Bestellungen und Szenarien sind getrennte Grid-Ansichten; die vorhandenen Formulare bleiben für
die vollständige Detailbearbeitung zuständig.
Listen verwenden die bestehende Page-Antwort (items, page, pageSize, totalItems,
totalPages). Bedarfe unterstützen zusätzlich openDecision und overBudget; die projektweite
Alternativenliste unterstützt roomId, requirementId, status, availability, favorite,
selected, ordered und delayed. Sortierfelder werden im Service gegen Positivlisten geprüft.
Bedarfsantworten enthalten aggregierte Optionen, Preise, Budgetabweichung, Bestellstatus und
Lieferdatum. Die Repository-Abfragen laden Optionen gebündelt für die aktuelle Seite.
Inline-Änderungen senden die vorhandene Versionsnummer. Bei Fehlern wird der alte Zellwert wiederhergestellt; bei HTTP 409 wird der Serverstand neu geladen und der Konflikt sichtbar gemeldet. Favorit und Auswahl verwenden die bestehenden Fachendpunkte. Leser erhalten keine Editoren; die serverseitige Projektberechtigung bleibt verbindlich.
Spaltenzustand wird ohne Fachdaten lokal unter Benutzer-, Projekt- und Ansichtsschlüssel gespeichert. Die Suche wird um 300 ms entprellt, Row-IDs sind stabile Datenbank-IDs und CSV-Export nutzt die Community-Funktion. Auf kleinen Displays gelten eine reduzierte Höhe und die vorhandene Dialogbearbeitung für komplexe Eingaben.
Die Möbelplanung ist Bestandteil des vorhandenen RenovationModule und verwendet dessen
ProjectAccessService, Dokumentablage, Ausgaben, Aktivitäten und Benachrichtigungen. Ein
FurnitureRequirement beschreibt den Bedarf eines Raums; konkrete Produkte werden als
FurnitureOption gespeichert. FurnitureScenario und FurnitureScenarioSelection
kombinieren höchstens eine Alternative je Bedarf zu vergleichbaren Einrichtungsvarianten.
Preis- und Kostenregeln
Der geplante Gesamtpreis lautet Einzelpreis × Menge + Versand + Zusatzkosten − Rabatt.
Bei vorhandenem Mobiliar entfallen Anschaffungskosten; Umzug und Aufbereitung werden dennoch
berücksichtigt. Alle persistierten Geldwerte sind DECIMAL(13,2) und werden im Backend als
Strings verarbeitet; die zentrale Berechnung in furniture-pricing.ts rechnet in Cent.
Planwerte stammen aus der ausgewählten Alternative bzw. einem Szenario. Ist-Kosten stammen
ausschließlich aus nicht stornierten, über furniture_option_id verknüpften Ausgaben. Damit
wird eine Bestellung nicht zugleich als Produktpreis und Ausgabe doppelt gezählt.
API und Listenmodell
Die Endpunkte liegen unter /projects/:projectId/furniture-requirements,
/furniture-options, /furniture-scenarios, /furniture-summary sowie
/rooms/:roomId/furniture-summary. Bedarfslisten unterstützen page, pageSize (maximal
100), search, Raum, Kategorie, Status, Priorität, Verantwortlichen, Favorit, Auswahl,
Bestell-/Lieferstatus und Lieferverzug. Erlaubte Sortierungen sind Name, Raum, Kategorie,
Preis, Priorität, Status, Lieferdatum, Änderungsdatum und Sortierreihenfolge.
Auswahl, Szenarien und Nebenläufigkeit
Das Auswählen eines Produkts sperrt die betroffene Alternative und deren Bedarf transaktional, prüft die Version, entfernt die bisherige Auswahl und erzeugt eine Aktivität. Damit bleibt auch bei parallelen Anforderungen höchstens eine aktive Auswahl bestehen. Bedarfe, Alternativen und Szenarien besitzen Versionsnummern; veraltete Änderungen liefern HTTP 409. Automatische Szenarien wählen günstigste, bevorzugte (Auswahl, Favorit, günstigste), teuerste oder vorhandene Alternativen und können danach manuell verändert werden.
Dokumente, Ausgaben, Status und Sicherheit
furniture_option_documents referenziert ausschließlich geschützte Projektdokumente; es
existiert keine zweite Dateiablage. Ausgaben können Bedarf und Alternative referenzieren.
Sämtliche Unterentitäten werden zusätzlich zur authentifizierten Projektmitgliedschaft gegen
die Pfad-projectId geprüft. Leser dürfen lesen und vergleichen; Eigentümer,
Administratoren und Bearbeiter verwenden die bestehende Projektaktion edit.
Bestellungen speichern Besteller, Nummer und Liefertermin. Teil- und Komplettlieferung sowie
Verspätung werden ausgewertet. Liefererinnerungen laufen über den vorhandenen Scheduler und
die bestehende ReminderDelivery-Deduplizierung; eine Terminänderung erzeugt durch das Datum
im Schlüssel eine neue, wiederholte Jobläufe dagegen keine weitere Benachrichtigung.
Migration und Development-Seed
Migration 1720000007000-AddFurniturePlanning erstellt die Möbel- und Szenariotabellen und
ergänzt optionale Expense-Referenzen. Der Development-Seed bleibt produktionsgesperrt und
legt 16 Bedarfe, 48 Alternativen, drei Szenarien, Favoriten, Auswahlen, Bestellungen, eine
Lieferung, einen Lieferverzug, sichere Dokumentmetadaten und verknüpfte Ausgaben an. Die
Etagen des Seeds sind Keller, Erdgeschoss, 1. Stock und Dachboden.