Commit Graph
100 Commits
Author SHA1 Message Date
msolarczekandClaude Opus 5 f665999d81 Impressum mit den Anbieterdaten der GEFIM UG
Daten aus gefim.de/impressum als zentrale Konstante (src/lib/marketing/imprint.ts), Seite
/impressum öffentlich und in der Fußzeile verlinkt. Der dort abgeschnittene Satz zur
Verbraucherstreitbeilegung ist mit der Standardformulierung vervollständigt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 09:02:30 +02:00
msolarczekandClaude Opus 5 4815a957b0 Produktseite ausgebaut: Unterseiten und Bildschirmfotos aus der App
Neue öffentliche Routen unter src/app/(marketing): Übersicht /funktionen, sechs Detailseiten
(planung, baustelle, zeiterfassung, berichte, abrechnung, lotse), /sicherheit und /preise,
gemeinsames Gerüst mit Kopf- und Fußzeile.

scripts/marketing-shots.ts nimmt die Bilder direkt aus der laufenden App auf (Playwright über
den installierten Chrome, Session wie im Smoke-Test, ohne Passworteingabe); 14 Aufnahmen in
public/marketing ersetzen die gezeichneten Vorschauen.

Plantafel: „Vorschläge" hängt jetzt als Fußzeile in der Auftragskarte statt frei zwischen zwei
Karten zu stehen (neue Prop footer an OrderCard, Schlüssel unplanned.suggestionsFor).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 13:35:04 +02:00
msolarczekandClaude Opus 5 31343d329a Öffentliche Startseite: Produktseite unter /
Aufbau: Hero mit Plantafel-Vorschau, Leitgedanken, 12 Funktionen, vertiefte Abschnitte zu
Planung, Baustelle und Lotse, Ablauf, Gewerke, Sicherheit, Testphase, häufige Fragen und
Fußzeile. Texte auf Deutsch und Englisch, Vorschauen als Markup statt Screenshots.
Angemeldete Nutzer leitet die Route weiterhin auf Dashboard bzw. mobile Ansicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 11:40:19 +02:00
msolarczekandClaude Opus 5 a4a61dc31f Ereignisse erst nach dem Commit ausliefern
Benachrichtigungs- und Mailversand lief im Handler noch in der offenen Transaktion und
zählte gegen deren Zeitlimit; unter Volllast brachen dadurch wechselnde Tests ab
(test-einsatz-field 31 s, test-planung-recommend). withDeferredEvents puffert Ereignisse
innerhalb von inTransaction und stellt sie nach dem Commit zu, bei Rollback gar nicht —
analog zu withDeferredAudit und passend zum dokumentierten Vertrag in events.ts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 11:05:49 +02:00
msolarczekandClaude Opus 5 1e1c154a8a Plantafel: Beispielwoche relativ zu heute; Live-Lage mit Kachelansicht
Neues Skript scripts/planning-demo.ts plant über createWorkOrder + scheduleWorkOrder eine
Woche für beide Kolonnen (Auslastung, Überbuchung, Überschneidung, Mehrtagesauftrag,
ungeplante Aufträge); die Demo-Termine aus dem Seed liegen relativ zum Seed-Tag und wandern
sonst aus dem Standardzeitraum.

Live-Lage: Umschalter Karte · Kacheln · Liste, Kachelansicht mit Status, Auftrag und Ort;
LiveMap meldet nicht erreichbare Kartenkacheln und die Ansicht wechselt automatisch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 09:44:24 +02:00
msolarczekandClaude Opus 5 dd6a67d329 Offline: Fotos bei abgelaufener Testphase nicht mehr verwerfen
Upload-Antwort 422 trial_expired gilt als vorübergehend: Datei bleibt auf dem Gerät,
wartende Op bleibt in der Warteschlange, der Sync-Durchlauf stoppt mit Backoff.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:23:14 +02:00
msolarczek a8fedc390f Merge lane/testphase in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

# Conflicts:
#	prisma/schema.prisma
#	scripts/test-e2e-tenant-isolation.ts
#	src/server/backup/topology.ts
#	src/server/db.ts
#	src/server/dsgvo/pii-fields.ts
2026-09-15 19:16:19 +02:00
msolarczekandClaude Opus 5 c3712598c1 Transaktionen: Wartezeit 10 s und Zeitlimit 20 s statt Prisma-Standard
Unter paralleler Last scheiterten Tests sporadisch mit „Unable to start a transaction in the given time“.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:14:31 +02:00
msolarczekandClaude Opus 5 df18ff9077 L15 Testphase & Onboarding: Lane-Bericht, Smoke prüft mobilen Scope
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:13:49 +02:00
msolarczekandClaude Opus 5 273a4535e3 L15 Testphase & Onboarding: Lese-Modus am moduleGuard für Seitenkontexte, Sperre für Auftragsdokument-Upload
Der HTTP-Smoke zeigte 500 auf /m für abgelaufene Testmandanten: mobile Seitenkontexte (field,
emergency) und der Import-Datei-Download nutzen moduleGuard zum Lesen. moduleGuard(key, { read: true })
überspringt dort die Schreibsperre; der Guard-Check verbietet den Lese-Modus in Server-Actions.
POST /api/v1/work-orders/[id]/documents läuft nicht über withApi und prüft die Sperre jetzt explizit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:07:20 +02:00
msolarczekandClaude Opus 5 969bc4e12c Merge lane/lotse-chat in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:04:40 +02:00
msolarczekandClaude Opus 5 eec23efa7e L16 Lotse-Chat für Monteure: optionaler Live-Test und Lane-Bericht
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:03:59 +02:00
msolarczekandClaude Opus 5 d9290a187c L15 Testphase & Onboarding: Selbstanmeldung mit Double-Opt-in, Plattform-Wizard, Nur-Lesen-Sperre, Export, Lebenszyklus-Job
- Datenmodell: Testphasen-Lebenszyklus am Mandanten (plan, trialEndsAt, readOnlySince, deletionDueAt,
  Versandmarker), TrialSignup (Plattform, Hashes statt Klartext), TenantExport (RLS), Onboarding-Status
- /testen: 5-Schritte-Wizard (Betrieb, Admin-Konto, Enddatum, Einrichtung, Zusammenfassung),
  Bestätigung per POST, direkte Anmeldung über login-ticket; Rate-Limit je IP/E-Mail, Honeypot,
  Enumeration-Schutz, Slug-Kollisionen
- Plattform: Wizard „Testmandant anlegen“ mit Einladung, Badges/Filter, Enddatum ändern,
  umwandeln, beenden, Löschung vormerken/abbrechen (Bestätigung + Audit)
- Schreibsperre nach Ablauf zentral in moduleGuard und requireApiContext (non-GET über withApi),
  Upload-Routen, Einstellungen/Nutzerverwaltung, Worker-Jobs; Banner Backoffice + mobil
- Datenexport (ZIP mit CSV/JSON + Dateien) als Worker-Job, auch im Nur-Lesen-Zustand
- Täglicher Job trial-lifecycle: Erinnerungen 7/3/1, Ablauf, Löschhinweis, Löschung über das Offboarding
- Erste-Schritte-Checkliste im Dashboard, Mail-Vorlagen de/en, Tests + Smoke, Betriebsdoku

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 19:01:47 +02:00
msolarczekandClaude Opus 5 2f46552970 L16 Lotse-Chat für Monteure: Tests für Chat-Schleife und Bestätigen, Isolation und Smoke
Fake-Provider mit geskripteten Tool-Aufrufen: Zuordnung, Vorschlag ohne Schreibzugriff,
Ausführung über Services, Blocker, Einmaligkeit/Ablauf/fremder Nutzer, Scope,
Mandantentrennung, Datenminimierung, Einstellung aus, Budget- und Rundengrenze.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 18:57:20 +02:00
msolarczekandClaude Opus 5 63baaf29df L16 Lotse-Chat für Monteure: mobile Chat-Seite, Aktionskarten, Mikrofon, Einstieg und Einstellung
/m/lotse mit Verlauf, Chips, Sprungzielen, Aktionskarten (Bestätigen/Bearbeiten/Verwerfen),
Spracheingabe mit editierbarem Transkript und Offline-Hinweis; Navigationseintrag, Button
„Lotse fragen“ im Auftragsdetail, Schalter und Datenfluss in /settings/lotse, Audit-Labels.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 18:57:20 +02:00
msolarczekandClaude Opus 5 68f4eb32dc L16 Lotse-Chat für Monteure: Datenmodell, Provider mit Tool-Schleife, Vorschläge und Bestätigen über bestehende Services
Chatverlauf (LotseConversation/-Message) und Aktionskarten (LotseActionProposal) als
Mandantentabellen mit RLS; Schalter lotseChatEnabled. Tool-Use-Schleife mit Runden- und
Tokengrenze, Datenminimierung per Platzhalter, Auftragszuordnung im Sichtbarkeits-Scope,
Bestätigen/Verwerfen/Alle bestätigen mit Hash, Ablauf und Idempotenz, Transkriptions-API.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 18:57:20 +02:00
msolarczekandClaude Opus 5 6b8cdf543b Abrechnen nur über die Abrechnungsübersicht, solange das Modul aktiv ist
Direkter Übergang nach billed → invalid use_billing_overview (nach der Rechteprüfung),
Button im Auftragsdetail ausgeblendet, markBilled läuft über den Abrechnungseintrag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:53:16 +02:00
msolarczekandClaude Opus 5 8324c48178 Merge lane/abrechnung in feature/craftvia-mvp
Konflikte gelöst (additiv): Benachrichtigungstexte (Planung + Meilensteine), Event-Typen,
Navigation, Job-Queues/Prozessoren (geocode-site, planning-watch, billing-pdf), OpenAPI-Tags,
Smoke-Prüfungen (zweiter Mandant: Planung + Abrechnung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:37:52 +02:00
msolarczekandClaude Opus 5 2df785dd14 L14 Abrechnungsübersicht: Tests, Backfill, Smoke und Lane-Bericht
test-abrechnung-service (118 Prüfungen inkl. Mandantentrennung und PDF-Render-Smoke), test-abrechnung-sync (21), Fixture-Zeilen für die neuen Tenant-Modelle, Rollen-Matrix billing:*, smoke-auth um /billing, Detail, Druckansicht, Auftrags-Tab und mobile Meilensteine erweitert, scripts/billing-backfill.ts, docs/craftvia/lanes/abrechnung.md, ABNAHME §3 „Abrechnungsübersicht“ (keine Buchhaltung). Gate 69/69, RLS 69/69.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:36:10 +02:00
msolarczekandClaude Opus 5 b76c1bdbfd L14 Abrechnungsübersicht: Backoffice-Übersicht, Detail, Druckansicht, Meilensteine im Auftrag und mobil, API
/billing mit Tabs Offen/Abgerechnet/Storniert, Filtern und Mehrfachdruck; /billing/[id] mit Abrechnungsblatt und Aktionen (abgerechnet mit Rechnungsnummer, PDF, Rechnungsnummer ändern, stornieren); /billing/print; Auftrags-Tab „Meilensteine & Abrechnung“; mobiler Abschnitt „Erreicht melden“ (offline); Dashboard-Kachel „Bereit zur Abrechnung“; /api/v1/billing*, Meilenstein-Endpunkte und OpenAPI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:35:56 +02:00
msolarczekandClaude Opus 5 ac2d857e26 L14 Abrechnungsübersicht: Services für Einträge, Aufstellung, Abrechnen/Stornieren, Meilensteine und PDF
syncBillingCandidates (idempotent, Event-Hook für work_order.released_for_billing und report.approved), Aufstellung ohne Preise (nur freigegebene Zeiten, Fahrzeit getrennt, Pausen informativ, Anfahrten-Zählung, Material), markBilled mit eingefrorenem Snapshot und Positionszuordnung, voidBilling mit Grund und neuem offenen Eintrag (billed → released_for_billing nur über applyTransition-Option billingVoid), Meilenstein-Flow mit Events, Job billing-pdf (Dokument other/backoffice_only), Sync-Op milestone.reach.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:35:38 +02:00
msolarczekandClaude Opus 5 6358d5762c L14 Abrechnungsübersicht: Datenmodell, Migration, Rechte und Modul
Neue Tenant-Tabellen work_order_milestones und billing_records (RLS, TENANT_MODELS, PII-Felder), Partial-Unique-Indizes je Quelle, billing_record_id an time_entries/material_usages. Rechte billing:read/billing:write (Backoffice, Mandantenadmin), Modul billing, Events milestone.*.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:35:20 +02:00
msolarczekandClaude Opus 5 9b087168d1 L14 Abrechnungsübersicht: Demo-Seed auf frischer Datenbank lauffähig
Seit L12 darf ein Nutzer nur eine laufende Uhr haben. DEMO-06/DEMO-07 (laufende Uhren) werden deshalb nach den vergangenen Einsätzen derselben Monteure angelegt; Inhalte unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:35:07 +02:00
msolarczekandClaude Opus 5 bf92100661 Merge lane/planung in feature/craftvia-mvp
Konflikte gelöst (additiv): Benachrichtigungstexte (Zeiterfassung + Planung, JSON zusammengeführt),
Event-Typen, Navigation, Empfänger-Felder, handle-event (reason inkl. rejectionReason + Planungsfelder),
Smoke-Prüfungen (Teamleiter: Zeiten + Planung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:15:47 +02:00
msolarczekandClaude Opus 5 edee395b2e L13 Planung: Lane-Bericht und Abnahme-Matrix (Kalender, Live-Lage, Verzug, Standortdaten)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:13:57 +02:00
msolarczekandClaude Opus 5 ee17134863 L13 Planung: Menüpunkt Planung mit Plantafel und Live-Lage
Plantafel: Standard heute + nächste 4 Werktage (Kolonnen als Zeilen, heutige Spalte mit Live-Status), Heute mit Kolonnen als parallelen Spalten (6–20 Uhr), Woche/nächste Woche, Auslastung, Konflikte/Hinweise, Verzugs- und Gefährdungs-Badges, Drag & Drop (@dnd-kit/core) mit Bestätigungs-Popover und Tastatur-Alternative, ungeplante Aufträge mit Vorschlägen, früher fertig mit Vorziehen, Kolonnenkapazität-Popup. Live-Lage: Leaflet/OSM-Karte mit einem Marker je Kolonne, Liste, Polling 30 s, Hinweis keine GPS-Ortung; CSP img-src für Kacheln. Dashboard-Kacheln Planung heute und Konflikte diese Woche, Einsatz-Vorschläge im Auftragsdetail, Navigation mit Unterpunkten, Smoke-Prüfungen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:13:50 +02:00
msolarczekandClaude Opus 5 5e10523df6 L13 Planung: Plantafel-, Einplan-, Empfehlungs-, Live- und Verzugsdienste mit API und Meldungen
Services board/schedule (L2 assign+update in inTransaction, Versionskonflikt, Audit), recommend (Luftlinie + freie Kolonnenzeit), live (Kolonnen, ohne Geräte-Koordinaten), watch (Verzug ab 80 %, Überschreitung, gefährdete Folgeaufträge, früher fertig mit Vorschlägen), Kolonnenkapazität. Job planning-watch alle 5 min, Events planning.capacity_freed/overrun/followup_at_risk (In-App an Backoffice + Teamleiter, Dedupe im Audit-Log), L12-Adapter für source/approvalStatus/manual. API /api/v1/planning/{board,schedule,recommendations,live} + OpenAPI. Tests core, recommend, live, watch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:13:39 +02:00
msolarczekandClaude Opus 5 213bcca3a1 L13 Planung: Geocoding der Objekte über OpenStreetMap Nominatim
Provider-Interface (nominatim|none), strukturierte Suche mit User-Agent und Accept-Language, Drosselung 1/s je Prozess, Job geocode-site (Worker: Concurrency 1 + Limiter), Cache am Objekt, manuelle Koordinaten bleiben, Auslöser Anlage/Adressänderung/Import-Bestätigung nur per Queue, Backfill-Skript, Env-Beispiele. Tests mit Fake-Provider, Nominatim nie aufgerufen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:13:26 +02:00
msolarczekandClaude Opus 5 604f2bfdc5 L13 Planung: Datenmodell (Kolonnenkapazität, Dauer, Geocoding-Cache) und Planungsregeln
Migration 20260915120000_planung (nur Spalten): Team.dailyCapacityMinutes/workingDays, OrderType.defaultDurationMinutes (+ Backfill Standardarten), WorkOrder.plannedDurationMinutes, Site.geocodedAt/geocodeStatus/geocodeQuery. Client-sichere Regeln: Haversine, Tage/Werktage, Dauer, Kolonnenkapazität, Konflikte inkl. Hinweis crew_incomplete, Vereinigung von Arbeitssegmenten, Fahrzeitschätzung.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:13:18 +02:00
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 5ea23a179d Merge lane/zeiterfassung in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:35:16 +02:00
msolarczekandClaude Opus 5 ceab79b7f8 L12 Zeiterfassung: Lane-Bericht und Abnahme-Entscheidung Arbeitszeitkorrektur
docs/craftvia/lanes/zeiterfassung.md (Umfang, Dateien, Tests, Gate/RLS, Lücken),
ABNAHME §4 „Arbeitszeitkorrektur“ auf die Freigaberegel aktualisiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:31:29 +02:00
msolarczekandClaude Opus 5 9f4eecf6e2 L12 Zeiterfassung: Tests und authentifizierter Smoke
test-zeiterfassung-service (78 Prüfungen) und test-zeiterfassung-sync (29 Prüfungen),
Rollen-Matrix um field:record_own_time und time:approve ergänzt, smoke-auth um
/m/time, /m/time/new, /m/approvals, Uhr-Leiste und /work-orders/time-approvals.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:29:46 +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 0e94eb0d9d L12 Zeiterfassung: Services für Nachtrag, Freigabe, Auto-Wechsel und Für heute beenden
time-entries.ts (manuelle Einträge, Korrekturvorschläge, Freigabe/Ablehnung mit
Team-Scope), Sessions in inTransaction mit switchFromOther, stopForToday,
Segmentwechsel und getMyActiveSession. Sync-Ops time.add_manual,
time.propose_correction, session.stop_day, session.segment inkl. optimistischer
Offline-Ansicht. Bericht, Zeiten-Tab, Dashboard und Lotse zählen nur freigegebene
Zeiten; Abrechnungsfreigabe blockiert bei offenen Zeiten. Empfänger und Links der
Zeit-Events. Notdienst-Start pausiert eine laufende Uhr automatisch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:29:30 +02:00
msolarczekandClaude Opus 5 03a2ccab4f L12 Zeiterfassung: Datenmodell, Rechte und Events für die Zeitfreigabe
Migration zeiterfassung_freigabe (TimeEntry source/approvalStatus/pendingChange,
WorkSession.manual), Rechte field:record_own_time und time:approve,
PII approvedById, Events time.approval_requested/approved/rejected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 09:29:20 +02:00
msolarczekandClaude Opus 5 d3bc7f2d29 Doku: Abnahme-Matrix Craftvia MVP (Spec §40, US-001–012, §44)
17 Abnahmekriterien und 12 User Stories mit Status und Nachweis (Testskript, Route,
Lane-Bericht); Soll-/Kann-Funktionen; getroffene MVP-Annahmen zu den offenen
fachlichen Entscheidungen; bekannte Einschränkungen und nicht verifizierte Punkte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:59:47 +02:00
msolarczekandClaude Opus 5 ef2f3f16c6 Härtung: Login-Drosselung je IP/Konto, Mail-Anhangfehler ohne Retry, doppeltes Upload-Audit
- rate-limit: neuer Scope login (20/15 min, LOGIN_RATE_LIMIT_PER_15_MIN) je IP und
  je Konto; geprüft in verifyIdentityPassword (Login-Seite + Credentials-Provider),
  gedrosselt verhält sich wie Fehlanmeldung (generisch, konstante Laufzeit) – L10a
- mail/worker: MailAttachmentError wie MailNotConfiguredError unrecoverable
  (fremder Mandant/Prüfsumme/Größe ändern sich nicht durch Warten) – L11
- field/uploads: Dokument-Audit nur noch in storeFile (vorher doppelt) – L10a
- Test test-login-rate-limit

Gate 65/65 grün; komplette Suite mit RLS_ENFORCED=true 65/65 grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:59:47 +02:00
msolarczekandClaude Opus 5 40c3e8e46b Merge lane/qualitaet in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:52:19 +02:00
msolarczekandClaude Opus 5 3769312bfb L10a Qualität & Abnahmetests: Lane-Bericht
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:49:54 +02:00
msolarczekandClaude Opus 5 fcd1dca971 Merge lane/kundenversand in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:49:42 +02:00
msolarczekandClaude Opus 5 fe891b1b79 L11 Kundenversand: Tests und Lane-Bericht
- scripts/test-report-customer-mail.ts: 41 Prüfungen (Rechte/Scope, Mandantentrennung
  beim Zustellen, Prüfsumme, Größenlimit, Dedupe, Fake-Provider, Mailhog-Durchstich)
- docs/craftvia/lanes/kundenversand.md: Umfang, Gate 53/53, HTTP-Smoke 13/13, offene Punkte

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:49:06 +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 e0106b8f8e L11 Kundenversand: Mail-Anhänge per Dokument-Referenz und Template craftvia_report_customer
- MailJob/EnqueueInput: attachments als { documentId } (keine Bytes in Redis, nur mit tenantId)
- deliverMail: Anhänge mandantengebunden aus MailLog.tenantId laden, SHA-256 prüfen,
  Größenlimit MAIL_MAX_ATTACHMENT_BYTES (Default 10 MB); Fehler -> failed ohne Versand
- SMTP-Provider reicht Anhänge an nodemailer durch; optionaler Provider für Tests
- Template craftvia_report_customer (de/en) ohne App-Link, eigene CUSTOMER_TEMPLATE_KEYS

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:48:45 +02:00
msolarczekandClaude Opus 5 565cd4ef5c L10a Qualität & Abnahmetests: Authentifizierter Durchstich aller Kernseiten je Rolle, Last-Seed (5 000 Aufträge) mit Performance-Messung, Demo-Import für die Prüfmaske
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:43:47 +02:00
msolarczekandClaude Opus 5 388ca85f54 L10a Qualität & Abnahmetests: HTTP-Sicherheitstest (manipulierte IDs aller /api/v1-Routen, Datei-Routen, Uploads, CSRF, Sessions, Login-Sperre, Header) gegen next start
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:34:29 +02:00
msolarczekandClaude Opus 5 6687ef2e03 Tests: vollständige Suite auch mit RLS_ENFORCED=true grün
- test-tenant-isolation: Compound-Key mit fremdem Mandanten – im Owner-Betrieb Throw
  (Tenant-Guard), unter scharfer RLS liefert die DB null; beides = kein Datenabfluss
- run-tests.ts: lädt .env und leitet RLS_DATABASE_URL (Rolle craftvia_app) aus
  DATABASE_URL ab, wenn RLS_ENFORCED=true und keine URL gesetzt ist

Nachweis: RLS_ENFORCED=true npm run test → 52/52; npm run gate → 52/52.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:33:22 +02:00
msolarczekandClaude Opus 5 bc58738129 Merge lane/betrieb in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:26:36 +02:00
msolarczekandClaude Opus 5 c297cfbe83 L10a Qualität & Abnahmetests: Sicherheitstests (Rollen-Matrix, schädliche Uploads, Login-Sperre/Rate-Limit/Sessions) und Audit-Log append-only für craftvia_app
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:25:55 +02:00
msolarczekandClaude Opus 5 5343174136 L10b Betrieb & Aufräumen: Lane-Bericht und HTTP-Smoke
- docs/craftvia/lanes/betrieb.md: Umfang a–k, Entscheidungen (b: report.submit übernehmbar, h: Audit nach Commit umgesetzt), Verhaltensänderungen (Fehlerformat, 422), Dateien, Tests (api 150, sync 36, audit 48), Gate 52/52, RLS_ENFORCED-Lauf 50/52 (zwei Owner-Modus-Tests unverändert), Docker-Build, offene Punkte.
- scripts/smoke-betrieb.ts: HTTP-Smoke gegen den Dev-Server (Session-Cookies ohne Passworteingabe) für Fehlerformat, OpenAPI, Sync-Ops, Bundle, Lotse-Kontingent, Sidebar; 18/18 grün auf :3111.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:25:36 +02:00
msolarczekandClaude Opus 5 cadaedc6cc L10b Betrieb & Aufräumen: Deploy – craftvia-worker, CI-Testjob, DEPLOY.md, Certvia-Doku archiviert
- docker-compose.coolify(.prebuilt).yml: Service craftvia-worker (Target worker, Chromium,
  shm_size 1gb, gleiche Härtung), Craftvia-Variablen für app und worker.
- Dockerfile: worker-Stage mit HOME=/home/app (Chromium-Profil für non-root); lokaler
  docker build der Targets runner und worker erfolgreich, PDF-Erzeugung im Image geprüft.
- .env.example/.env.prod.example/.env.coolify.example: alle Craftvia-Variablen inkl. RLS,
  KI-Provider, PDF_CHROMIUM_PATH, OFFLINE_MAX_DAYS, API_RATE_LIMIT_*, AI_GENERATION_RETENTION_DAYS,
  AI_MONTHLY_TOKEN_LIMIT.
- CI (.github, .gitea): Job gate mit Postgres (pgvector) und Redis als Service: migrate deploy,
  seed, Passwort für craftvia_app, tsc, lint, build, npm run test.
- docs/craftvia/DEPLOY.md (aus den Certvia-Deploy-Docs abgeleitet): Architektur, Domains, Secrets,
  Worker, Migrationen, RLS-Aktivierung, Backup/Restore, KI, Rate Limits, Aufbewahrung, Smoke,
  Update/Rollback. build-and-push-images.sh baut craftvia-worker.
- Certvia-/ISMS-Dokumente aus docs/ nach docs/_certvia-archiv/ (mit README); Verweise in README.md
  und Skript-Kommentaren angepasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +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 5f08df324f L10b Betrieb & Aufräumen: Migrationen clientId je Mandant und KI-Token-Kontingent
- 20260915090000_betrieb_client_id_per_tenant (Aufräumpunkt f, L8 offener Punkt 6): globale
  Unique-Indizes auf client_id (material_usages, work_sessions, time_entries, activity_notes,
  photos, voice_notes, reports, signatures) → @@unique([tenantId, clientId]). Offline-IDs sind nur
  je Mandant eindeutig; ein Replay derselben ID in einem anderen Mandanten scheiterte bisher mit
  internem Fehler. Keine neuen Tabellen.
- 20260915091000_betrieb_ai_token_limit (Aufräumpunkt k): tenant_settings.ai_monthly_token_limit
  (NULL = Plattform-Vorgabe AI_MONTHLY_TOKEN_LIMIT, 0 = unbegrenzt). Keine neue Tabelle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 49f05c8db3 L10b Betrieb & Aufräumen: OpenAPI 3.1 unter /api/v1/openapi.json, API-Doku und API-Test
- src/lib/api/openapi.ts: statisch gepflegte Spezifikation aller v1-Routen inkl. Fehlerformat,
  Pagination, Idempotenz (clientOpId/clientId), Konflikte, Rate Limits, Rechte je Operation.
- GET /api/v1/openapi.json liefert das Dokument (angemeldete Nutzer).
- docs/craftvia/API.md: Kurzdoku mit Endpunkt-Tabelle.
- scripts/test-betrieb-api.ts: jede Route nutzt requireApiContext/respond.ts, 401 ohne Sitzung
  im einheitlichen Format, 403 bei fremdem Origin/Sec-Fetch-Site, Fehler-Mapping, Rate Limit je
  Nutzer (Standard/Einsatz getrennt), OpenAPI deckt jede route.ts ab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 fb993a7730 L10b Betrieb & Aufräumen: /api/v1 über gemeinsamen Adapter, einheitliches Fehlerformat, Rate Limiting
Aufräumpunkt a: Die lane-lokalen API-Kontexte (imports/_context.ts, sync/api-context.ts,
reports/http.ts, work-orders/_http.ts mit moduleGuard) sind entfernt. Alle v1-Routen laufen über
requireApiContext (DB-autoritative Rechte, 401/403) und withApi/toErrorResponse (respond.ts):
- Fehlerformat überall { error: { code, message, details? } }; invalid und blocked → 422,
  conflict → 409, payload_too_large → 413, rate_limited → 429 + Retry-After.
- Same-Origin-Prüfung in withApi für jede Mutation vor der Anmeldung (vorher fehlte sie bei
  imports, reports und work-orders).
- Rate Limiting je Nutzer mit rate-limit.ts: api (API_RATE_LIMIT_PER_MINUTE, 300/min) und
  apiField für sync/uploads/field (API_FIELD_RATE_LIMIT_PER_MINUTE, 1200/min).
- Clients angepasst: Import-Uploader liest das neue Fehlerformat, Upload/Outbox werten 422 als
  endgültig ungültig (429 bleibt transient mit Backoff).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:19:19 +02:00
msolarczekandClaude Opus 5 4507862375 L10a Qualität & Abnahmetests: E2E-Prozesstests (regulärer Auftrag, mehrtägig, Notdienst, Offline-Sync, Pflichtfotos/Unterschrift, Dubletten, Mandantentrennung systematisch)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 18:16:11 +02:00
msolarczekandClaude Opus 5 1a75c28bb4 L10a Qualität & Abnahmetests: Demo-Seed (Teams, Kunden, Objekte, 20 Aufträge, Berichte, Notdienst, demo2)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:58:22 +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 1796869e05 PWA: Service Worker ohne Session erreichbar, nie HTTP-gecacht; authentifizierter Smoke
- proxy: /sw.js vom Session-Gate ausgenommen (Update-Prüfung auch bei abgelaufener
  Sitzung; enthält keine Mandantendaten) – gemeldet von L7
- next.config: /sw.js mit Cache-Control no-cache/no-store, Service-Worker-Allowed /
- scripts/smoke-auth.ts: Session-Cookie über finalizeIdentityLogin + next-auth/jwt
  encode (ohne Passworteingabe), prüft Backoffice- und Monteur-Seiten

Nachweis: /sw.js anonym 200 + no-cache; Smoke 19/19 Seiten grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:43:29 +02:00
msolarczekandClaude Opus 5 ffd2f02632 L9 Lotse – KI-Assistent: Lane-Bericht
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:31:16 +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 7825245901 Fix: /dashboard 500 – buttonCls aus Client-Modul herausgelöst
Server-Komponenten (Dashboard, Aufträge, Suche, Checklisten, Auftragsdetail) riefen
buttonCls() aus einem "use client"-Modul auf; das bricht zur Laufzeit (gemeldet von L8).
Neu: src/components/work-orders/button-cls.ts (server-sicher), action-form re-exportiert.

Nachweis: authentifizierter HTTP-Smoke (Backoffice 13 Seiten, Monteur 6 Seiten) alle 200,
/dashboard vorher 500. tsc/lint grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:27:46 +02:00
msolarczekandClaude Opus 5 e5d5ccad6f L7 Offline & PWA: Lane-Bericht
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:26:20 +02:00
msolarczekandClaude Opus 5 5f6e70fdf3 L9 Lotse – KI-Assistent: Gate-Fixes (EXEMPT-Auth-Prüfung, Sprachnotiz ohne Transkriptionsanbieter nicht einreihen)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:25:50 +02:00
msolarczekandClaude Opus 5 0757f212f5 Merge lane/notdienst in feature/craftvia-mvp
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:23:13 +02:00
msolarczekandClaude Opus 5 519bd2a303 L8 Notdienst: Lane-Bericht
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:22:26 +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 9b3c50923f L7 Offline & PWA: submitOp über Outbox, Foto/Sprachnotiz über Upload-Warteschlange, Entwürfe in IndexedDB
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:21:14 +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 4dd330b9fd L7 Offline & PWA: Service Worker (Static/Seiten/Dokument-Cache) und Manifest start_url /m
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:20:20 +02:00
msolarczekandClaude Opus 5 9f73cdae49 L7 Offline & PWA: Outbox-Kern, IndexedDB-Store, Sync-Engine und Bundle-Logik
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:19:43 +02:00
msolarczekandClaude Opus 5 f42ead3ced L9 Lotse – KI-Assistent: Tests (Entwurf, Datenminimierung, Rechte/Mandant, Transkription, Live)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 17:19:38 +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 8e08156e55 L8 Notdienst: Tests für Erfassung, Mandantentrennung, Sync und Prüfung
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 13:12:33 +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 f173563424 L8 Notdienst: Services für Erfassung, Suche, Abschluss-Event und Sync-Op
createEmergencyOrder in einer Transaktion (vorläufiger Kunde/Objekt, Auftrag N-…
in_progress, Team/Zuweisung, WorkSession), searchCustomersForEmergency mit
minimalem Feldumfang + Audit, emergency.completed nach Abschlussbericht,
Sync-Op emergency.create (Registry + Zod-Schema), Review-Services.

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 3883296300 Integration: Stubs von L2/L3/L4/L5 gegen echte Services getauscht
- Aufträge: createWorkOrder/transitionWorkOrder/getCompletionBlockers aus L2
- Dokumente: storeFile aus L1; neu services/documents/read.ts (readStoredBytes,
  readDocumentBytes mit Prüfsummenprüfung); L2-Upload nutzt zentrale Ablage
- Dubletten aus L1 (findDuplicateCustomers(ctx)); Objekt-Kandidaten als
  imports/site-candidates.ts; Dateityp-Erkennung mobil als field/mime.ts
- Objekt-Historie mobil als Adapter auf L1 getSiteHistory, PDF über /api/v1/reports/:id/pdf
- L4-Upload-Idempotenz: fester Upload-Lineage nach storeFile, Race → Soft-Delete + Replay
- PDF-Worker-Kontext: document:write zum Ablegen des Berichts-PDF
- Import: doppeltes Work-Order-Audit entfernt; bestätigte Aufträge starten planned
- Dateilinks in Auftragsdetail auf /files/[documentId]
- proxy: /api/v1 ohne Session → 401 JSON statt Login-Redirect
- ARCHITEKTUR §2: Objekt-Historie für Feldrollen (freigegebene Einsätze aller Teams)

Gate: tsc, lint, build, 42/42 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:49:19 +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 f17eeaf47b L1 Stammdaten: Lane-Bericht und mobile Suchfelder
Bericht docs/craftvia/lanes/stammdaten.md (Umfang, Dateien, Tests, Smoke,
offene Punkte) sowie umbrechende Suchfelder der Kunden- und Objektliste bei
schmalen Viewports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:37:07 +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 da2afb79e3 Fix: BullMQ-Job-IDs ohne Doppelpunkt
BullMQ lehnt benutzerdefinierte Job-IDs mit ':' ab; dispatchJob fiel dadurch
mit Redis immer auf die Inline-Verarbeitung zurück (gemeldet von L4).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:35:24 +02:00
msolarczekandClaude Opus 5 e0f5e13e1c Fix: doppelte Audit-Entity-Labels nach Merge lane/einsatz
Gate: tsc, lint, build, 33/33 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:35:14 +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 a9530f2513 L2 Aufträge & Backoffice: Lane-Bericht docs/craftvia/lanes/auftraege.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:30:54 +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 edded26b21 L4 Einsatz mobil: Lane-Bericht
docs/craftvia/lanes/einsatz.md: Umfang, Routen, Dateien, Tests, Stubs und
Abhängigkeiten, bekannte Lücken, Gate- und Smoke-Ergebnis.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:30:03 +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 4a25f2cc3b Fundament: atomare Mandanten-Transaktionen, iframe-Vorschau, Uploads bis 25 MB, DSGVO-Felder
- db.ts: tenantTransaction() – atomar auch bei RLS_ENFORCED=true (AsyncLocalStorage
  bindet Operationen an eine craftvia_app-Transaktion, Kontext einmal gesetzt,
  verschachtelte Aufrufe treten bei, fremder Mandant wird abgewiesen)
- services/context.ts: inTransaction(ctx, fn); imports/confirm.ts umgestellt
- next.config.ts: EMBEDDABLE_FILE_ROUTES mit frame-ancestors 'self'/SAMEORIGIN
  (PDF-Vorschau Prüfmaske), proxyClientMaxBodySize 26mb (Import bis 25 MB)
- test-rls-enforcement: RLS-URL-Default aus DATABASE_URL (Lane-DBs)
- dsgvo/pii-fields: 26 Personenreferenzen des Craftvia-Domänenmodells
- ARCHITEKTUR §4.8: Transaktions-, Header-, Upload-, Versions- und PII-Regeln
- Test test-tenant-transaction (Commit/Rollback/Fremdmandant/Verschachtelung),
  grün im Owner- und im RLS-Modus

Gate: tsc, lint, build, 31/31 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:29:57 +02:00
msolarczekandClaude Opus 5 952e74cddd L4 Einsatz mobil: Field-Services, Sync-API, Uploads und Tests
- services/field: Einsatz-Sessions (Anfahrt/Arbeit/Pause als TimeEntry-Segmente,
  eine aktive Session je User+Auftrag), Zeitkorrektur mit Recht + Grund + Audit,
  Checkliste, Material (Abweichung nur mit Begründung, Zusatzmaterial), Notizen,
  Fotos, Sprachnotizen (ohne Transkriptions-Processor Status disabled), Uploads
  (idempotent je Mandant), autorisierte Dokument-Auslieferung, Lesemodelle + Bundle
- services/sync: applyOperations mit Idempotenz, baseVersion-Konfliktprüfung,
  Registry für Ops anderer Lanes, lane-lokaler requireApiContext
- /api/v1/sync, /api/v1/uploads, /api/v1/field/bundle, /api/v1/field/documents/[id]
- lib/sync/ops.ts (Zod-Payloads je opType), lib/field/material-rules.ts
- Stubs mit Vertragssignatur: transitionWorkOrder (L2), storeFile (§4.3),
  getSiteHistory (L1)
- Processor image-derivatives + Registrierung, Audit-Entity-Labels
- Tests: test-einsatz-field (48 Prüfungen), test-einsatz-sync (38 Prüfungen)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:29:48 +02:00
msolarczekandClaude Opus 5 a962fa8be9 L2 Aufträge & Backoffice: Server Actions und /api/v1/work-orders
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:29:42 +02:00
msolarczekandClaude Opus 5 2311b35d8c L2 Aufträge & Backoffice: Service-Schicht Aufträge + Tests
Statusmaschine (transitionWorkOrder inkl. eventData), Zuweisung, Completion-Guards,
Materialvorgabe, Checklisten/Pflichtfotos, Liste/Dashboard-Presets, Suche,
Sync-Konflikte, Einstellungen (Auftragsarten, Vorlagen, Nummernkreise).
Tests: Übergangsmatrix je Rolle, Kernlogik, Scope/Mandantentrennung, Nummernkreis-Parallelität.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:29:15 +02:00
msolarczekandClaude Opus 5 6423351035 L1 Stammdaten: Tests für Dubletten, Kunden, Objekte, Teams und Dokumente
Kernlogik, Mandantentrennung (Mandant B liest/ändert nichts von A) und
Rollen/Scope (Monteur ohne Zuweisung → not_found/forbidden).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-14 12:26:27 +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