Files
arbeitszeit/CLAUDE.md
T
admin cb168fbd18 Reisezeit aus Start/Ende, Pause pro Eintrag in Minuten
- Reisezeit wird aus Reise-Beginn/-Ende zur Laufzeit berechnet (Spalte reisezeit entfernt),
  Anzeige in Vorschau und Liste wie Mehrarbeit
- Pause pro Eintrag in Minuten (Feld zwischen Beginn und Ende), Default aus globaler Einstellung
- Eingabefelder werden nach dem Speichern eines neuen Eintrags geleert
- DB-Migrationen für reise_beginn/reise_ende/pause-Spalten
- Version 0.1.2

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 17:00:57 +02:00

64 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
Hinweise für Claude Code (claude.ai/code) zur Arbeit in diesem Repository.
## Commands
```bash
npm run dev # Entwicklungsserver
npm run build # Produktions-Build (nach jeder Änderung zur Prüfung ausführen)
npm run lint # ESLint
```
Kein Test-Setup. Deploy via `./deploy.sh [tag]` — baut ein Multiplatform-Docker-Image
(amd64 + arm64) und pusht es nach `docker.citysensor.de`.
## Architektur
Next.js 16 App-Router-Anwendung. Seiten sind Server-Komponenten; interaktive Teile sind
Client-Komponenten in `app/MainClient.tsx` und `components/`. Layout und Design sind dem
Schwesterprojekt `~/Projekte/logbuch` nachempfunden, jedoch mit **grüner** Grundfarbe.
**Auth**: Single-User. Benutzername und Passwort sind fest in `.env` hinterlegt
(`APP_USERNAME` default `Birgit`, `APP_PASSWORD`). Login über `app/login/actions.ts`
`lib/auth.ts` (Plaintext-Vergleich, kein bcrypt). Sessions sind JWT-Cookies via `jose`
(`lib/session.ts`, 8 h Gültigkeit, Cookie `arbeitszeit_session`). Middleware liegt in
`proxy.ts` (Next.js-16-Konvention) und exportiert `middleware`.
**Passkeys (WebAuthn)**: Zusätzlich zum Passwort (das als Fallback bleibt). `lib/webauthn.ts`
kapselt `@simplewebauthn/server` (RP-Config aus `RP_ID`/`RP_ORIGIN`/`RP_NAME`, Default
`localhost`); Credentials liegen in Tabelle `passkeys` (`lib/passkeys.ts`). Die Challenge wird
kurzlebig in einem httpOnly-Cookie zwischengespeichert. API unter `app/api/passkey/`:
`register` (GET Options / POST Verify, Session nötig), `authenticate` (GET/POST, **öffentlich**
in `proxy.ts` von der Session-Pflicht ausgenommen, setzt bei Erfolg die Session), sowie
`GET`/`DELETE` auf `app/api/passkey/route.ts` zum Verwalten. Registrierung im Einstellungen-Tab
(`components/Passkeys.tsx`), Anmeldung per Button auf `app/login/page.tsx`. **WebAuthn braucht
HTTPS** (Prod via Traefik) bzw. `localhost` in der Entwicklung.
**Datenbank**: SQLite3 via `better-sqlite3`. `lib/db.ts` ist ein Singleton, legt Schema und
die `settings`-Tabelle beim ersten Zugriff an. Datei unter `DB_PATH`
(default `./data/arbeitszeit.db`, in Produktion `/app/data/arbeitszeit.db` auf einem Volume).
`better-sqlite3` ist nativ → `serverExternalPackages` in `next.config.ts` und im Dockerfile
`python3 make g++` in der `deps`-Stage.
**Datenzugriff**: `lib/repo.ts` (CRUD + Pause-Setting), `lib/calc.ts` (Zeit-/Wochentag-Helfer),
`lib/validate.ts` (Body-Validierung). API-Routen unter `app/api/` prüfen alle `getSession()`
und liefern 401 ohne Session.
## Datenmodell & Berechnungen
Tabelle `arbeitszeit`: `datum`, `ort` (Kunde FFM | Homeoffice | Andrena), `beginn`, `ende`
(je HH:MM), `reise_beginn`, `reise_ende` (je HH:MM, optional), `pause` (dezimale Stunden),
`vertriebsunterstuetzung` (default 2), `kommentar` (max. 500).
- `Arbeitszeit = Ende Beginn` (dezimale Stunden)
- `Reisezeit = Reise-Ende Reise-Beginn`: im Formular werden Start/Ende eingegeben, die
Reisezeit wird wie Mehrarbeit zur Laufzeit berechnet (nicht gespeichert) und in Vorschau
und Liste angezeigt. Beim Speichern koppelt sie nur die Vertriebsunterstützung.
- `Mehrarbeit = Arbeitszeit 8 Pause`
- Die Spalte „Arbeitszeit Kunde" ist fix 8 h (`ARBEITSZEIT_KUNDE_FIX`).
- Die **Pause** wird pro Eintrag gespeichert (Spalte `pause`, dezimale Stunden; Eingabe im
Formular in Minuten zwischen Beginn und Ende). Standard ist die globale Pause-Einstellung
in der `settings`-Tabelle (Tab „Einstellungen"). Mehrarbeit wird je Eintrag aus dieser
Pause zur Laufzeit berechnet, nicht gespeichert.