Commit Graph
30 Commits
Author SHA1 Message Date
msolarczekandClaude Opus 5 2f312a7835 Zeiterfassung: Backoffice erfasst Zeiten für Mitarbeiter
- Backoffice-Rolle erhält field:correct_time (User-Entscheidung): Zeiten für
  Monteure/Teamleiter direkt freigegeben anlegen und korrigieren
- Eigene Zeiten erfordern weiterhin field:record_own_time (Backoffice erfasst
  keine eigenen Zeiten)
- Auftragsdetail › Zeiten: Formular „Zeit für Mitarbeiter erfassen“ (Mitarbeiter,
  Art, Datum, von–bis oder Dauer, Begründung; Mandanten-Zeitzone)
- Server Action recordTimeForUserAction (moduleGuard work_orders)
- Test test-backoffice-time (Backoffice, fremdes Team, Monteur, Mandantentrennung)

Demo-Daten lokal bereinigt: je Monteur nur noch eine aktive Uhr.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:54:06 +02:00
msolarczekandClaude Opus 5 fe3eba6e44 L12 Zeiterfassung: Mobile Uhr-Leiste, Meine Zeiten, Freigaben und Backoffice-Liste
Laufende-Uhr-Leiste auf allen /m-Seiten, Start/Pause direkt auf den Auftragskarten,
Auto-Wechsel-Dialog, Auftragsdetail mit Pause / Für heute beenden / Abschließen-Link
und Segmentwechseln, /m/time (Tagesübersicht, Nachtragen, Korrektur vorschlagen),
/m/approvals für Teamleiter, /work-orders/time-approvals mit Sammelfreigabe,
Zeiten-Tab mit Badges und Inline-Freigabe, Dashboard-Kachel, Texte de/en.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:29:38 +02:00
msolarczekandClaude Opus 5 29c80a0e73 L11 Kundenversand: Bericht-PDF an Kunden senden (Service, Action, API, Berichtsseite)
- sendReportToCustomer: report:approve, Scope, nur approved mit PDF, Empfänger
  Ansprechpartner -> Kunde, Dedupe je Adresse+Version, Audit export
- Server Action + POST /api/v1/reports/{id}/send inkl. OpenAPI-Eintrag
- /reports/[id]: Abschnitt „An Kunden senden" mit bisherigen Versänden, Texte de/en

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:48:57 +02:00
msolarczekandClaude Opus 5 21d6dc016a L10b Betrieb & Aufräumen: einklappbare Backoffice-Sidebar, Berichtseditor mit Offline-Entwurf
- Aufräumpunkt g (L1 offener Punkt 10): components/backoffice-frame.tsx – unter 1024 px ist die
  Sidebar ein Drawer hinter einem Menü-Button (44 px, aria-expanded, schließt bei Navigation,
  Hintergrund, Escape); ab 1024 px statisch wie bisher. Header kompakter auf schmalen Screens.
- Aufräumpunkt i (L7 offener Punkt 7): mobiler Berichtseditor speichert ungesicherte Eingaben
  über useOfflineDraft (IndexedDB je Mandant/Nutzer). Ein Entwurf wird nur wiederhergestellt,
  solange die Servertexte unverändert sind (sonst gewinnt der Server, z. B. nach Übernahme eines
  Lotse-Vorschlags); nach Speichern/Absenden gelöscht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 b0aedb5d23 L10b Betrieb & Aufräumen: Lotse-Betrieb – Aufbewahrung KI-Protokoll und Token-Kontingent
Aufräumpunkt k (Spec §31):
- Aufbewahrung: services/lotse/retention.ts leert input/output und createdById von
  AiGeneration-Einträgen älter als AI_GENERATION_RETENTION_DAYS (Default 180), Metadaten bleiben,
  Audit je Mandant. Queue/Processor ai-retention, täglicher BullMQ-Job-Scheduler beim Start des
  craftvia-worker.
- Kontingent: services/lotse/budget.ts (Tokens ein+aus je Kalendermonat, TenantSettings-Wert vor
  Env AI_MONTHLY_TOKEN_LIMIT, 0 = unbegrenzt). Lotse-Entwurf und Sprachnotiz-Zusammenfassung
  → blocked budget_exceeded mit Klartext; Import-Extraktion fällt auf manuelle Erfassung zurück
  (Hinweis ai_budget_exceeded). /settings/lotse: Kontingent setzen, Verbrauch anzeigen.
- scripts/test-betrieb-audit.ts: Audit nach Commit/Rollback/verschachtelt, Merge atomar und in
  äußerer Transaktion, Audit „read", Aufbewahrung (Frist, Metadaten, Idempotenz, Mandant B),
  Kontingent (Mandant/Env/Vormonat/unbegrenzt, Rollen, Audit).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 8aedc642ca L10b Betrieb & Aufräumen: Audit nach Commit, mergeCustomers atomar, Audit-Aktion read
- Aufräumpunkt h: writeAuditLog puffert innerhalb von inTransaction (AsyncLocalStorage) und
  schreibt nach dem Commit; bei Rollback werden die Einträge verworfen, nur „denied" bleibt.
  Verschachtelte Transaktionen nutzen den äußeren Puffer.
- Aufräumpunkt d: mergeCustomers läuft über inTransaction (sequenziell, geschützter Statuswechsel)
  statt ctx.db.$transaction([...]) und ist damit auch bei RLS_ENFORCED=true atomar und in äußere
  Transaktionen einbettbar.
- Aufräumpunkt e: AuditAction „read" (+ Label im Audit-Viewer de/en); Notdienst-Kunden- und
  Objektsuche protokollieren als „read" statt „export".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 85bae832d0 L10b Betrieb & Aufräumen: Sync – Berichts-Ops, Konflikt-Übernahme, eigene Session im Bundle
- Aufräumpunkt j: report.save_draft und report.submit mit Zod-Schemas (lib/sync/ops.ts) und
  Registry-Einträgen → services/reports/sync-ops.ts. report.submit reicht baseVersion als
  expectedWorkOrderVersion und aiReviewed an submitReport durch; Lotse-Entwürfe ohne Bestätigung →
  rejected invalid. signature.capture bleibt unregistriert (Upload-Art für Unterschriftsbild fehlt).
- Aufräumpunkt b: „Übernehmen" in der Konfliktliste delegiert an den Sync-Dispatcher
  (apply.ts#reapplyOperation, ohne baseVersion) statt des L2-Stubs; unterstützt
  work_order.transition und report.submit. Hinweistext der Konfliktliste angepasst.
- Aufräumpunkt c: getFieldBundle liefert je Auftrag mySession (eigene aktive WorkSession); die
  Offline-Ansicht leitet den Zeitstatus daraus ab (alte Bundles: Näherung über Auftragsstatus).
- scripts/test-betrieb-sync.ts (Bundle, clientId je Mandant, Berichts-Ops, Konflikt-Übernahme,
  Mandant B, Monteur ohne Zuweisung); test-einsatz-sync.ts prüft „nicht verfügbare Op" jetzt mit
  signature.capture, weil report.save_draft registriert ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 a7d4b02a13 Merge lane/lotse in feature/craftvia-mvp
Konflikt gelöst: nav.ts Icon-Imports (Siren aus L8, Compass aus L9).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:44:06 +02:00
msolarczekandClaude Opus 5 2a30ee1919 Merge lane/offline in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:28:04 +02:00
msolarczekandClaude Opus 5 8ebf3c0685 L7 Offline & PWA: E2E-Test (20 Ops offline → ein Batch → applied/duplicate, Mandanten-/Scope-Trennung), Message-Keys ohne Punkt
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:21:41 +02:00
msolarczekandClaude Opus 5 f0620f9c3b L7 Offline & PWA: Sync-Seite, Offline-Ansicht, Sync-Badge, Installationshinweis, Logout-Schutz
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:20:44 +02:00
msolarczekandClaude Opus 5 9a3d472682 L9 Lotse – KI-Assistent: UI im Berichtseditor, Auftragsdetail, Sprachnotizen und Einstellungen
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:19:38 +02:00
msolarczekandClaude Opus 5 ff5c57f276 L9 Lotse – KI-Assistent: Transkription, Berichtsentwurf, Vollständigkeitsprüfung, Freigabeprinzip (Services)
- OpenAI-kompatible Transkription + Processor transcription (done/failed/disabled, AiGeneration, Notiz aus Sprachnotiz)
- Claude-Lotse (strukturierte Ausgabe, Refusal/Fallback), Datenminimierung, Vorschläge in content.lotse
- Vollständigkeitsprüfung (Regeln + KI-Hinweise mit Deep-Link), Einstellungen, KI-Protokoll
- Freigabeprinzip: Submit eines Lotse-Entwurfs nur mit Prüfbestätigung (serverseitig)
- Migration lotse_address_form (TenantSettings)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:19:38 +02:00
msolarczekandClaude Opus 5 dece70c129 L8 Notdienst: Backoffice-Nachbearbeitung /work-orders/emergency-review
Liste und Detail mit fünf Prüfschritten (Kunde, Objekt, Auftrag, Bericht,
Abrechnung), Navigationseintrag, Dashboard-Kachel verlinkt auf die Prüfung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 13:12:33 +02:00
msolarczekandClaude Opus 5 ef61754a0a L8 Notdienst: mobile Erfassung /m/emergency in drei Schritten
Kunde suchen oder vorläufig anlegen, Einsatzort mit Ansprechpartner,
Grund mit optionaler Sprachnotiz, Beginn und Team; Start über die Sync-Op.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 13:12:33 +02:00
msolarczekandClaude Opus 5 d5c1221ab5 UI: veraltete Stub-Hinweise in Auftragsdetail und Konfliktliste bereinigt
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:49:46 +02:00
msolarczekandClaude Opus 5 2984cc18d3 Merge lane/stammdaten in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:38:34 +02:00
msolarczekandClaude Opus 5 d9476d324b Merge lane/auftraege in feature/craftvia-mvp
Konflikte gelöst: Header mit Suche (L2) und Glocke (L6), Audit-Labels vereinigt
(ohne doppeltes sync_operation), Navigation mit Benachrichtigungen und Auftragsvorlagen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:36:21 +02:00
msolarczekandClaude Opus 5 024ec5e3ab Merge lane/einsatz in feature/craftvia-mvp
Konflikte gelöst: processors/index.ts (report-pdf + image-derivatives),
(app)/layout.tsx (Logo, Glocke, AccountInactiveNotice). L5-Mobilseiten
report/sign nach src/app/(field)/m/(core)/orders/[id]/ verschoben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:32:35 +02:00
msolarczekandClaude Opus 5 b49d14bab3 L2 Aufträge & Backoffice: Einzeiler Navigation, Header-Suche, Audit-Entity-Labels
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:30:44 +02:00
msolarczekandClaude Opus 5 b96016d593 L2 Aufträge & Backoffice: Backoffice-UI (Liste, Detail, Konflikte, Dashboard, Suche, Einstellungen) + Texte de/en
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:30:32 +02:00
msolarczekandClaude Opus 5 95f41b29f5 L4 Einsatz mobil: Mobile Shell und Einsatz-Oberfläche
- /m in eigene Route-Group (field)/m verschoben (emergency-Platzhalter mit),
  Zugriffsprüfungen aus (app)/layout.tsx nach server/app-access.ts extrahiert
  und von Backoffice- und Mobile-Shell gemeinsam genutzt
- Mobile Shell mit Bottom-Nav (Heute · Aufträge · Notdienst · Sync · Profil)
  und Online/Offline-Badge; Startseite rollenabhängig (Feldrollen → /m),
  Login-Default-Redirect auf /
- Heute, Auftragsliste mit Tabs, Auftragsdetail mit einer Primäraktion je
  Zustand, Unterseiten Fotos (Kamera, Kompression, Upload-Fortschritt),
  Notizen + Sprachaufnahme, Material mit Stepper, Checkliste, Zeiten mit
  Korrektur, Profil; Sync-Platzhalter für L7
- Client-Wrapper submitOp (lib/field/client-ops.ts), Upload mit Fortschritt,
  Bildkompression, Formatierung; Texte in messages/{de,en}/field.json

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:30:03 +02:00
msolarczekandClaude Opus 5 d18f4fe431 L1 Stammdaten: Backoffice-Seiten Kunden, Objekte, Teams und Dokumente
Listen mit Suche/Filter/Paginierung, Popups für Anlage und Bearbeitung,
Kundendetail mit Tabs, Dublettenhinweis und Zusammenführen, Objektdetail mit
Kartenlink, Dokumenten-Tab und Historie, Teamverwaltung mit Mitgliedern,
Dokumentenübersicht. Texte in messages de/en, Audit-Label Ansprechpartner.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:26:27 +02:00
msolarczekandClaude Opus 5 3e16689b2f Merge lane/berichte in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:23:34 +02:00
msolarczekandClaude Opus 5 94092ade3f L5 Berichte & Unterschrift: Backoffice- und Mobil-Oberflächen
/reports mit Filtern (zur Prüfung zuerst), /reports/[id] mit Aktionen, Versionen und PDF-Link;
mobile Komponenten für Bericht, Prüfung und Unterschrift inkl. Signature-Pad; Texte de/en.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:22:40 +02:00
msolarczekandClaude Opus 5 f532ba9a96 Merge lane/import in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:22:07 +02:00
msolarczekandClaude Opus 5 cf012d40c2 L3 Auftragsimport: Prüfmaske, Upload, API und Lane-Bericht
- /imports: Upload per Drag & Drop/Dateiauswahl mit Fortschritt, Liste mit Status, Neu verarbeiten
- /imports/[id]: Originaldokument + Prüfmaske (Kunde, Objekt, Ansprechpartner, Auftrag, Positionen),
  unsichere Felder markiert, Kunden-/Objektentscheidung, Bestätigen/Verwerfen
- Datei-Route für die Vorschau, Server Actions (moduleGuard("imports"))
- API: POST /api/v1/work-orders/import, GET /api/v1/imports/[id], POST /api/v1/imports/[id]/confirm
- Texte messages/{de,en}/imports.json, Bericht docs/craftvia/lanes/import.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:21:15 +02:00
msolarczekandClaude Opus 5 879012415e L6 Benachrichtigungen & Audit: Glocke, Posteingang, Nutzer-Einstellungen, Mailkonfiguration
- Glocke im Backoffice-Header (ungelesen-Zähler, letzte 10, alle gelesen), mobil
  einbindbar über variant="mobile".
- /notifications mit Filter gelesen/ungelesen/Art, Öffnen markiert gelesen (nur
  relative Links), Pagination.
- /account Abschnitt Benachrichtigungen: E-Mail-Opt-out je Typ, Notdienst Pflicht.
- /settings/email (tenant:manage): Absendername, Antwortadresse, Empfänger Notdienst
  und Abrechnung; Validierung gegen Header-Injection, max. 20 Adressen, Audit.
- Actions unter actions/notifications mit moduleGuard + guard; Navigation ergänzt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:12:21 +02:00
msolarczekandClaude Opus 5 7b37c41a83 L6 Benachrichtigungen & Audit: Empfängerregeln, In-App-Benachrichtigungen und Craftvia-Mails
- handleEvent (Signatur unverändert) löst alle 17 Domain-Events auf: Team/Assignees,
  Backoffice (read_all + report:approve), Teamleiter-Freigaben, Ersteller, Abrechnung,
  Notdienst, Import, Sync; Akteur ausgenommen, alle IDs über ctx.db neu aufgelöst.
- In-App-Notification über ctx.db (ungelesene gleiche Meldung wird aufgefrischt),
  E-Mail über enqueueMail mit dedupeKey event:entity:user (+ optional occurrenceId),
  Opt-out je Typ, Notdienst als Pflichtmail, feste Empfänger ohne Doppelmail.
- Mail-Templates craftvia_* (de/en) inkl. Notdienst-Format Spec §19.4 und Craftvia-Fußzeile.
- Migration tenant_mail_settings: mailFromName, mailReplyTo, emergencyRecipients,
  billingRecipients an tenant_settings (keine neue Tabelle).
- Texte aus messages/{de,en}/notifications.json.
- Test scripts/test-benachrichtigungen-events.ts (63 Prüfungen).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:11:53 +02:00
msolarczekandClaude Opus 5 8491c7f173 Fundament: ISMS-Module entfernt; Craftvia-Rollen, Module, Navigation, i18n-Split
- ISMS-Routen, Actions, Server-/Lib-Code, Komponenten, Prisma-Modelle, Seeds,
  Importer, Skripte und ISMS-Tests entfernt (Fundament bleibt: Auth, Identity,
  MFA/WebAuthn, RBAC, Audit, Mail, Storage, Backup/DSGVO, Plattform-Admin)
- Schema auf Fundament-Modelle reduziert; TenantSettings generisch (+phone/email)
- TENANT_MODELS (db.ts, backup/topology.ts) und PII-Felder ausgedünnt
- RBAC: Rollen tenant-admin/backoffice/team-lead/technician + Craftvia-Permissions
- Modul-Katalog (customers, sites, teams, work_orders, imports, field, reports,
  emergency, documents, notifications, lotse) + Navigation aus src/lib/nav.ts
- Modul-Routen mit requireModule-Layout und Platzhalterseite
- Message-Katalog je Namespace (messages/<locale>/<namespace>.json), fs-Loader
- check-module-guards: Modul-Key aus src/server/actions/<moduleKey>/
- Provisionierung, Admin-Konsole, Einstellungen, Files-Route, Mail entkoppelt
- Seed minimal (demo/demo2, Nutzer je Rolle); Fundament-Tests auf Role/
  NotificationPreference-Fixtures umgestellt

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 11:35:44 +02:00