Commit Graph
126 Commits
Author SHA1 Message Date
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