Files
craftvia/AGENTS.md
T
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

92 lines
5.3 KiB
Markdown

<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
# Craftvia — Projektregeln
Mandantenfähige Einsatz-PWA für Handwerks- und Montagebetriebe: Kunden, Objekte, Teams,
Aufträge (inkl. PDF-Import), mobile Einsatzbearbeitung, Berichte, Notdienst, Dokumente,
KI-Assistent „Lotse".
**Maßgebliche Spezifikation: [docs/craftvia/SPEC-CRAFTVIA.md](docs/craftvia/SPEC-CRAFTVIA.md)**
(Rollen, Module, Abläufe, Akzeptanzkriterien) und
**[docs/craftvia/ARCHITEKTUR.md](docs/craftvia/ARCHITEKTUR.md)** (Datenmodell, Schnitte; wird
separat geliefert). Marke: [docs/craftvia/BRANDBOOK.md](docs/craftvia/BRANDBOOK.md), Umsetzung
im Code: [docs/craftvia/BRANDING.md](docs/craftvia/BRANDING.md).
## Eiserne Regeln
1. **Mandanten-Isolation:** Kein DB-Zugriff an Prisma vorbei, kein Query ohne Tenant-Kontext.
Fachliche Tabellen tragen `tenant_id`; Zugriff nur über `dbForTenant(tenantId)`
(`src/server/db.ts`), zusätzlich Postgres RLS. Neue Tenant-Tabelle ⇒
`SELECT enable_tenant_rls('<tabelle>');` in der Migration **und** Eintrag in beiden
`TENANT_MODELS`-Listen (`src/server/db.ts`, `src/server/backup/topology.ts`) — siehe
[docs/craftvia/MIGRATIONS.md](docs/craftvia/MIGRATIONS.md).
2. **RBAC serverseitig:** Jede Mutation/Query prüft Permissions am Server
(`customer:write`, `work_order:assign`, …; Katalog in `src/server/rbac.ts`). UI-Ausblenden
ist nur Komfort, nie Sicherheit.
3. **Modul-Gating:** Routen eines Moduls haben ein `layout.tsx` mit
`await requireModule("<moduleKey>")`; Server-Actions liegen in
`src/server/actions/<moduleKey>/*.ts` und laufen über `moduleGuard("<moduleKey>")` +
`await guard(...)`. `scripts/check-module-guards.ts` erzwingt das (prebuild).
4. **Audit-Log:** Jede schreibende Aktion erzeugt einen `AuditLog`-Eintrag (before/after,
`writeAuditLog` in `src/server/audit.ts`).
5. **i18n:** Keine hartkodierten UI-Texte — alle Strings über den Message-Katalog
(`de` default, `en` gepflegt). Ein File je Namespace: `messages/<locale>/<namespace>.json`.
6. **DSGVO:** Felder, die Personen referenzieren (`User.id`), in
`src/server/dsgvo/pii-fields.ts` eintragen.
## Andockpunkte für Fachmodule
| Was | Wo |
|---|---|
| Modul-Keys | `src/lib/modules.ts` (`customers`, `sites`, `teams`, `work_orders`, `imports`, `field`, `reports`, `emergency`, `documents`, `notifications`, `lotse`) |
| Sidebar (Backoffice) | `src/lib/nav.ts` (Modul + Permission-Filter) |
| Routen-Platzhalter | `src/app/(app)/<route>/{layout,page}.tsx` — Lane ersetzt `page.tsx` |
| Server-Actions | `src/server/actions/<moduleKey>/*.ts` |
| Rollen/Permissions | `src/server/rbac.ts` (danach `scripts/sync-role-permissions.ts`) |
| Texte | `messages/de/<namespace>.json` + `messages/en/<namespace>.json` |
| Benachrichtigungen | `notifyUser()` in `src/server/mail/notifications.ts` |
| Dateien | `src/server/storage/*` (Keys mit Präfix `<tenantId>/`), Download `/files/<key>` |
| KI | `src/server/ai/client.ts` |
| Provisionierung neuer Mandanten | `src/server/provision.ts` |
## Stack & Konventionen
- Next.js 16 (App Router, `src/proxy.ts` statt Middleware) + TypeScript, Tailwind CSS 4,
shadcn/ui (Base UI), lucide-react, next-intl.
- Prisma 7 (`prisma.config.ts`, Adapter `@prisma/adapter-pg`) + PostgreSQL 16 (pgvector),
BullMQ + Redis (Mail-/Backup-Worker), **Garage** (S3-kompatibel) als Objektspeicher,
Auth.js v5 (Credentials, Argon2id + Pepper, TOTP/WebAuthn, getrennte Plattform-Auth).
- Tests: tsx-Skripte `scripts/test-*.ts` gegen die lokale Infra; Runner `npm run test`.
- Qualitäts-Gate vor jedem Commit: `npm run gate`
(= `prisma generate && tsc --noEmit && lint && build && test`).
- Sprache: UI und Fachbegriffe Deutsch; Code (Bezeichner) Englisch, Kommentare Deutsch
oder Englisch.
## Rollen (Spec §4)
`tenant-admin` (Mandantenadministrator), `backoffice`, `team-lead` (Teamleiter),
`technician` (Monteur). Plattform-Administratoren sind ein getrennter Store
(`/platform/login`) ohne Zugriff auf Mandanten-Fachdaten. Rechte liegen im JWT und wirken
für Lesepfade nach erneutem Login; Mutationen prüfen autoritativ gegen die DB (`moduleGuard`).
## Entwicklung
```bash
docker compose up -d postgres redis garage # Infrastruktur (+ --profile dev für mailhog)
GARAGE_ADMIN_URL=http://localhost:3903 npx tsx scripts/garage-provision.ts # Bucket/Key (einmalig)
npx prisma migrate deploy && npx prisma db seed # Schema + Demo-Daten
npx tsx scripts/geocode-backfill.ts --tenant=demo # Koordinaten der Objekte (Karte, Empfehlungen)
npx tsx scripts/planning-demo.ts # Beispielbelegung der Plantafel (relativ zu heute)
npm run dev # App auf :3000
npm run gate # vollständiges Qualitäts-Gate
```
Demo-Logins (Passwort `Demo1234!` bzw. `SEED_PASSWORD`): `admin@demo.example`,
`backoffice@demo.example`, `teamleiter@demo.example`, `monteur@demo.example`
(Mandant „Musterbau Haustechnik GmbH"), `admin2@demo.example` (`demo2`),
`multi@demo.example` (beide Mandanten), Plattform: `platform@demo.example`.