Template
585 lines
23 KiB
Markdown
585 lines
23 KiB
Markdown
# AI Coding Starter Kit
|
|
|
|
Next.js-Vorlage mit einem durchgängigen KI-Workflow für [Claude Code](https://docs.anthropic.com/en/docs/claude-code).
|
|
Neun Skills führen von der Idee bis zum laufenden Deployment. Jede Phase schreibt ihr
|
|
Ergebnis in die Feature-Spec — der Projektstand liegt in Dateien, nicht im Chatverlauf.
|
|
|
|
Genau das macht die Vorlage fürs Vibe-Coden brauchbar: Du musst dich nicht erinnern,
|
|
wo du stehst. `/help` liest es aus den Dateien ab, und nach einem Kontextverlust
|
|
liest sich jede Skill selbst wieder ein.
|
|
|
|
---
|
|
|
|
## Inhalt
|
|
|
|
- [Schnellstart](#schnellstart)
|
|
- [Der Workflow im Überblick](#der-workflow-im-überblick)
|
|
- [Die neun Skills](#die-neun-skills)
|
|
- [Die drei Sub-Agents](#die-drei-sub-agents)
|
|
- [Die vier Rules](#die-vier-rules)
|
|
- [Kontext-Ebenen](#kontext-ebenen)
|
|
- [Das Feature-System](#das-feature-system)
|
|
- [Tech-Stack](#tech-stack)
|
|
- [Authentifizierung: Passkeys](#authentifizierung-passkeys)
|
|
- [Tests](#tests)
|
|
- [Deployment](#deployment)
|
|
- [Kommandos](#kommandos)
|
|
- [Dateibaum](#dateibaum)
|
|
- [Stolperfallen](#stolperfallen)
|
|
- [Anpassen](#anpassen)
|
|
|
|
---
|
|
|
|
## Schnellstart
|
|
|
|
```bash
|
|
git clone <repo-url> mein-projekt
|
|
cd mein-projekt
|
|
npm install
|
|
cp .env.example .env
|
|
npx playwright install chromium # einmalig pro Rechner, für E2E-Tests
|
|
npm run dev
|
|
```
|
|
|
|
Dann in Claude Code:
|
|
|
|
```
|
|
/init Ich will eine Aufgabenverwaltung für kleine Teams bauen
|
|
```
|
|
|
|
---
|
|
|
|
## Der Workflow im Überblick
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
subgraph P["Planung — inline mit dir im Gespräch"]
|
|
direction LR
|
|
INIT["/init<br/><i>PRD + Feature-Map</i>"]
|
|
SPEC["/write-spec<br/><i>User Stories, AC</i>"]
|
|
ARCH["/architecture<br/><i>Tech Design</i>"]
|
|
end
|
|
|
|
subgraph B["Bauen — delegiert an Sub-Agents"]
|
|
direction LR
|
|
FE["/frontend<br/><i>UI</i>"]
|
|
BE["/backend<br/><i>API + Daten</i>"]
|
|
QA["/qa<br/><i>Tests + Audit</i>"]
|
|
end
|
|
|
|
DEP["/deploy<br/><i>Docker-Stack</i>"]
|
|
|
|
INIT --> SPEC --> ARCH --> FE
|
|
FE -->|"braucht Server"| BE --> QA
|
|
FE -->|"nur Frontend"| QA
|
|
QA -->|"keine Critical/High"| DEP
|
|
QA -.->|"Bugs gefunden"| FE
|
|
QA -.->|"Bugs gefunden"| BE
|
|
|
|
REF["/refine PROJ-X"] -.->|"Spec überarbeiten"| SPEC
|
|
HELP["/help"] -.->|"Wo stehe ich?"| P
|
|
```
|
|
|
|
Übergaben sind **immer** von dir ausgelöst. Keine Skill springt selbstständig weiter,
|
|
jede endet mit einem Freigabe-Checkpoint.
|
|
|
|
### Das Grill-Me-Prinzip
|
|
|
|
`/init`, `/write-spec` und `/refine` interviewen nach denselben Regeln:
|
|
|
|
- Eine Frage pro Runde, niemals eine Liste
|
|
- Immer mit einer Empfehlung — du bestätigst oder korrigierst
|
|
- Dem Gespräch folgen statt einem Skript
|
|
- Erst im Code nachsehen, dann fragen
|
|
- Kein Fragenlimit: Schluss ist, wenn es verstanden ist
|
|
|
|
---
|
|
|
|
## Die neun Skills
|
|
|
|
| # | Skill | Argument | Liest | Schreibt | Ausführung |
|
|
|---|-------|----------|-------|----------|------------|
|
|
| 1 | **`/init`** | Beschreibung der Idee | PRD, INDEX | `docs/PRD.md`, `features/INDEX.md`, ggf. `docs/design-system.md` | inline |
|
|
| 2 | **`/write-spec`** | Feature-Name oder `PROJ-X` | PRD, INDEX, Code | `features/PROJ-X-name.md`, INDEX, PRD | inline |
|
|
| 3 | **`/refine`** | `PROJ-X` | Spec, INDEX, PRD | Spec, INDEX, PRD | inline |
|
|
| 4 | **`/architecture`** | `PROJ-X` | Spec, PRD, Code | Tech Design + Entscheidungslog in der Spec | inline |
|
|
| 5 | **`/frontend`** | `PROJ-X` | Spec, `components/ui/`, Design-System | Komponenten, Seiten, Spec-Notizen | → Sub-Agent |
|
|
| 6 | **`/backend`** | `PROJ-X` | Spec, `app/api/`, `lib/` | Route Handler, Schema, Tests, `.env.example` | → Sub-Agent |
|
|
| 7 | **`/qa`** | `PROJ-X` | Spec, INDEX, Git-Log | QA-Abschnitt in der Spec, Unit- und E2E-Tests | → Sub-Agent |
|
|
| 8 | **`/deploy`** | `PROJ-X` | Spec (QA-Teil), INDEX | Deployment-Abschnitt, Git-Tag | inline |
|
|
| 9 | **`/help`** | optionale Frage | PRD, INDEX, Specs, Code | nichts | inline |
|
|
|
|
### Was jede Skill konkret tut
|
|
|
|
<table>
|
|
<tr><td width="140"><b><code>/init</code></b></td><td>
|
|
Einmalig pro Projekt. Interviewt dich zu Problem, Zielgruppe, MVP-Umfang, Alternativen,
|
|
Rahmenbedingungen, Erfolgsmetriken und Nicht-Zielen. Klärt <b>verbindlich</b> drei Dinge,
|
|
bevor die Feature-Map entsteht: Braucht es dauerhafte Speicherung? Braucht es Nutzerkonten
|
|
(dann wird „Auth-Grundlage" automatisch PROJ-1)? Gibt es ein Design-System? Legt danach
|
|
PRD und priorisierte Feature-Map an — aber <i>keine</i> Spec-Dateien.
|
|
</td></tr>
|
|
<tr><td><b><code>/write-spec</code></b></td><td>
|
|
Macht aus einer Feature-Idee eine testbare Spec. Drei Einstiege: Feature steht schon als
|
|
„Roadmap" im INDEX, Feature fehlt dort noch (wird ergänzt), oder es hat bereits eine Spec
|
|
(verweist auf <code>/refine</code>). Füllt neben User Stories und Acceptance Criteria auch
|
|
Out of Scope, Produkt-Entscheidungen und Offene Fragen.
|
|
</td></tr>
|
|
<tr><td><b><code>/refine</code></b></td><td>
|
|
Öffnet eine bestehende Spec. Fragt zuerst „Was bringt dich zurück zu dieser Spec?" und
|
|
wählt danach den Pfad: <b>1)</b> Scope hat sich geändert, <b>2)</b> die Umsetzung hat eine
|
|
Lücke aufgedeckt, <b>3)</b> das Feature gehört grundsätzlich hinterfragt — bis hin zum
|
|
Aufsplitten in zwei Specs. Schließt erledigte Offene Fragen mit Datum.
|
|
</td></tr>
|
|
<tr><td><b><code>/architecture</code></b></td><td>
|
|
Übersetzt die Spec in ein Design, das auch ohne Technikhintergrund lesbar ist:
|
|
Komponentenbaum, Datenmodell in Worten, begründete Tech-Entscheidungen, Paketliste.
|
|
<b>Schreibt bewusst keinen Code</b> — kein SQL, kein TypeScript. Trifft hier die
|
|
Datenbank-Entscheidung, die die Vorlage offenlässt.
|
|
</td></tr>
|
|
<tr><td><b><code>/frontend</code></b></td><td>
|
|
Klärt Designfragen mit dir (oder liest <code>docs/design-system.md</code>), setzt den Status
|
|
auf „In Progress" und übergibt an den Frontend-Sub-Agent. Präsentiert dessen Bericht,
|
|
holt dein Urteil im Browser ein und iteriert im selben Sub-Agent-Kontext weiter.
|
|
</td></tr>
|
|
<tr><td><b><code>/backend</code></b></td><td>
|
|
Klärt Rechte, Nebenläufigkeit, Validierung und Rate-Limiting, dann Übergabe an den
|
|
Backend-Sub-Agent. Stoppt, wenn im Tech Design noch kein Daten-Layer steht — die
|
|
Entscheidung gehört zu <code>/architecture</code>, nicht hierher.
|
|
</td></tr>
|
|
<tr><td><b><code>/qa</code></b></td><td>
|
|
Setzt „In Review", übergibt an den QA-Sub-Agent, schreibt dessen Ergebnis als
|
|
QA-Abschnitt in die Spec und priorisiert die Bugs mit dir. Setzt bei sauberem Lauf
|
|
„Approved", sonst bleibt „In Review".
|
|
</td></tr>
|
|
<tr><td><b><code>/deploy</code></b></td><td>
|
|
Blockiert ohne QA-Abschnitt oder bei offenen Critical/High-Bugs. Fährt Lint, Typecheck,
|
|
Test und Build als Pre-Flight, führt beim ersten Mal durch die Servereinrichtung und
|
|
danach durch <code>./scripts/update.sh</code>. Setzt Status, Tag und Deployment-Notiz.
|
|
</td></tr>
|
|
<tr><td><b><code>/help</code></b></td><td>
|
|
Liest PRD, INDEX und Spec-Abschnitte und sagt dir, wo das Projekt steht und was als
|
|
Nächstes dran ist — mit dem exakten Kommando. Widersprechen sich Dateien und
|
|
Status-Spalte, gewinnen die Dateien und es sagt dir das.
|
|
</td></tr>
|
|
</table>
|
|
|
|
---
|
|
|
|
## Die drei Sub-Agents
|
|
|
|
`/frontend`, `/backend` und `/qa` führen Interview und Review mit dir im Hauptgespräch
|
|
und geben die eigentliche Dateiarbeit ab. Der Sub-Agent arbeitet in eigenem Kontext und
|
|
liefert einen kompakten Bericht zurück statt der vollen Erzählung.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
actor Du
|
|
participant S as Skill<br/>(Hauptgespräch)
|
|
participant A as Sub-Agent<br/>(eigener Kontext)
|
|
participant F as Dateien
|
|
|
|
Du->>S: /frontend PROJ-3
|
|
S->>F: Spec + INDEX lesen
|
|
S->>Du: Designfragen, je eine mit Empfehlung
|
|
Du-->>S: Antworten
|
|
S->>F: Status → In Progress
|
|
S->>A: Auftrag: Spec, Designentscheidungen,<br/>Komponentenliste
|
|
A->>F: Komponenten schreiben,<br/>lint / typecheck / build
|
|
A-->>S: Bericht: Dateien, Abweichungen,<br/>offene Fragen
|
|
S->>Du: Bericht + "Schau es dir an"
|
|
Du-->>S: Feedback
|
|
S->>A: Nachbesserung (gleicher Kontext)
|
|
S->>F: Spec-Notizen + Status
|
|
S->>Du: Handoff → /backend oder /qa
|
|
```
|
|
|
|
| Agent | Datei | Werkzeuge | Aufgabe | Hard Rule |
|
|
|-------|-------|-----------|---------|-----------|
|
|
| **Frontend Developer** | `.claude/agents/frontend-dev.md` | Read, Write, Edit, Bash, Glob, Grep | UI umsetzen | shadcn vor Eigenbau; Lint, Typecheck und Build müssen grün sein |
|
|
| **Backend Developer** | `.claude/agents/backend-dev.md` | Read, Write, Edit, Bash, Glob, Grep | Routen, Daten, Auth | **Stoppt und meldet zurück**, wenn der Daten-Layer noch nicht entschieden ist |
|
|
| **QA Engineer** | `.claude/agents/qa-engineer.md` | Read, Write, Edit, Bash, Glob, Grep | Testen, Security-Audit | **Behebt niemals selbst einen Bug** — nur finden, dokumentieren, priorisieren |
|
|
|
|
Keiner der drei fasst `features/INDEX.md` an. Tracking gehört der aufrufenden Skill —
|
|
so kann es keine zwei Wahrheiten über den Status geben.
|
|
|
|
---
|
|
|
|
## Die vier Rules
|
|
|
|
Rules laden sich automatisch, sobald passende Dateien bearbeitet werden. Du musst sie
|
|
nie manuell erwähnen.
|
|
|
|
| Datei | Greift bei | Inhalt |
|
|
|-------|-----------|--------|
|
|
| **`general.md`** | immer aktiv | Feature-Tracking, Status-Flow, Commit-Format, „erst lesen, dann ändern", Write-then-Verify, Human-in-the-Loop, Sprachregel |
|
|
| **`frontend.md`** | `src/components/**`<br/>`src/app/**/page.tsx`<br/>`src/app/**/layout.tsx`<br/>`src/hooks/**` | shadcn-Pflicht, Tailwind-v4-Eigenheiten, semantische Tokens, Server Components, Loading/Error/Empty, Formulare |
|
|
| **`backend.md`** | `src/app/api/**`<br/>`src/lib/**`<br/>`src/server/**`<br/>`drizzle/**`, `prisma/**` | Kein vorgewählter Daten-Layer, Zod-Validierung, Statuscodes, Ownership im Query statt danach, Indizes, Migrationen, Secrets |
|
|
| **`security.md`** | API-Routen, `src/lib/auth*`<br/>`.env*`, `next.config.*`<br/>`Dockerfile`, `compose.yaml` | Passkey-Standard, Autorisierung pro Ressource, Secrets, Security-Header, genehmigungspflichtige Änderungen |
|
|
|
|
---
|
|
|
|
## Kontext-Ebenen
|
|
|
|
Nicht alles wird gleichzeitig geladen — das ist der Grund, warum lange Sessions nicht
|
|
zerfasern.
|
|
|
|
```mermaid
|
|
flowchart TB
|
|
subgraph AUTO["Automatisch"]
|
|
CM["<b>CLAUDE.md</b><br/>jede Session"]
|
|
RU["<b>.claude/rules/</b><br/>sobald passende Dateien<br/>bearbeitet werden"]
|
|
end
|
|
|
|
subgraph DEMAND["Auf Abruf"]
|
|
SK["<b>.claude/skills/</b><br/>beim /kommando"]
|
|
AG["<b>.claude/agents/</b><br/>wenn eine Skill delegiert"]
|
|
SP["<b>features/PROJ-X.md</b><br/>wenn die Skill sie liest"]
|
|
DOC["<b>docs/DEPLOYMENT.md</b><br/>nur wenn referenziert"]
|
|
end
|
|
|
|
CM --> SK
|
|
RU --> SK
|
|
SK --> AG
|
|
SK --> SP
|
|
AG --> SP
|
|
```
|
|
|
|
**Zustand liegt in Dateien, nicht im Gespräch.** Wird der Kontext komprimiert, liest die
|
|
Skill Spec und `git diff` neu ein und macht weiter — ohne Arbeit zu wiederholen oder
|
|
doppelt zu bauen.
|
|
|
|
---
|
|
|
|
## Das Feature-System
|
|
|
|
Alles läuft über `features/INDEX.md` und eine Spec-Datei pro Feature
|
|
(`features/PROJ-X-name.md`). Ein Feature = eine testbare, deploybare Einheit.
|
|
|
|
```mermaid
|
|
stateDiagram-v2
|
|
[*] --> Roadmap: /init
|
|
Roadmap --> Planned: /write-spec
|
|
Planned --> Architected: /architecture
|
|
Architected --> InProgress: /frontend<br/>/backend
|
|
InProgress --> InReview: /qa startet
|
|
InReview --> Approved: keine Critical/High
|
|
InReview --> InProgress: Bugs beheben
|
|
Approved --> Deployed: /deploy
|
|
Deployed --> [*]
|
|
|
|
Planned --> Planned: /refine
|
|
Architected --> Architected: /refine
|
|
```
|
|
|
|
### Aufbau einer Spec
|
|
|
|
Eine Spec wächst über die Phasen hinweg. Vorlage:
|
|
`.claude/skills/write-spec/template.md`
|
|
|
|
| Abschnitt | Gefüllt von | Wozu |
|
|
|-----------|-------------|------|
|
|
| Abhängigkeiten | `/write-spec` | Welche PROJ-X vorher fertig sein müssen |
|
|
| User Stories | `/write-spec` | Als [Rolle] möchte ich [Aktion], um [Ziel] |
|
|
| **Out of Scope** | `/write-spec` | Was bewusst *nicht* gebaut wird — sonst baut es der nächste Durchlauf nach |
|
|
| Acceptance Criteria | `/write-spec` | Angenommen / Wenn / Dann, direkt abtestbar |
|
|
| Edge Cases | `/write-spec` | Nebenläufigkeit, Netzfehler, leere Eingabe, Rechtegrenzen |
|
|
| **Offene Fragen** | `/write-spec` | `- [ ]`, geschlossen in `/refine` mit Datum |
|
|
| **Entscheidungslog** | `/write-spec` + `/architecture` | Produkt- und Tech-Entscheidungen mit Begründung |
|
|
| Tech Design | `/architecture` | Komponentenbaum, Datenmodell, Abhängigkeiten |
|
|
| QA Test Results | `/qa` | Kriterium für Kriterium, Bugs, Security, Urteil |
|
|
| Deployment | `/deploy` | URL, Datum, Commit |
|
|
|
|
Out of Scope und Entscheidungslog sind das Gedächtnis der Vorlage.
|
|
|
|
### Format der Acceptance Criteria
|
|
|
|
```
|
|
- [ ] Angenommen der Nutzer ist angemeldet, wenn er ein leeres Formular abschickt,
|
|
dann erscheint pro Pflichtfeld eine Validierungsmeldung
|
|
```
|
|
|
|
**Sprache:** PRD, Specs und Acceptance Criteria auf Deutsch. Code, Kommentare,
|
|
Commit-Messages und die Skill-Anweisungen selbst auf Englisch.
|
|
|
|
---
|
|
|
|
## Tech-Stack
|
|
|
|
| Ebene | Wahl | Anmerkung |
|
|
|-------|------|-----------|
|
|
| Framework | Next.js 16, App Router | React 19, Server Components als Standard |
|
|
| Sprache | TypeScript `strict` | `@/*` → `src/*` |
|
|
| Styling | Tailwind CSS v4 | CSS-first, **keine `tailwind.config.ts`** |
|
|
| Komponenten | shadcn/ui, Stil `new-york` | 6 vorinstalliert, Rest per CLI |
|
|
| Icons | lucide-react | |
|
|
| Formulare | react-hook-form + Zod | Zod-Schema gilt auch serverseitig |
|
|
| Toasts | sonner | in `layout.tsx` gemountet |
|
|
| Theming | next-themes | Dark Mode über `.dark` |
|
|
| Auth | Better Auth + Passkey-Plugin | nur wenn das Projekt Anmeldung braucht |
|
|
| Daten-Layer | **pro Projekt entschieden** | Vorlage bringt keinen mit |
|
|
| Tests | Vitest + Playwright | strikt getrennte Scopes |
|
|
| Betrieb | Docker Compose, selbst gehostet | App-Container, Proxy extern |
|
|
|
|
### Bewusst nicht enthalten
|
|
|
|
- **Keine Datenbank, kein ORM.** `/architecture` entscheidet pro Projekt. Einzige
|
|
Auflage: muss im Compose-Stack selbst hostbar sein.
|
|
- **Kein Supabase, kein Vercel.** Nicht vergessen, sondern absichtlich ausgebaut.
|
|
In `CLAUDE.md` steht das explizit, damit es nicht durch die Hintertür zurückkommt.
|
|
- **Keine Content-Security-Policy vorkonfiguriert.** Geraten bricht sie Apps; pro
|
|
Projekt mit `Report-Only` anfangen.
|
|
- **Kein Error-Tracking vorinstalliert.** Sentry-Anleitung in `docs/DEPLOYMENT.md`.
|
|
|
|
### UI-Komponenten
|
|
|
|
Sechs sind vorinstalliert:
|
|
|
|
| Komponente | Wofür |
|
|
|------------|-------|
|
|
| `button` | Aktionen, Varianten über CVA |
|
|
| `card` | Container mit Header/Content/Footer |
|
|
| `input` | Textfelder |
|
|
| `label` | Beschriftungen, barrierefrei verknüpft |
|
|
| `form` | react-hook-form-Anbindung inkl. Fehlermeldungen |
|
|
| `sonner` | Toaster, bereits in `layout.tsx` gemountet |
|
|
|
|
Alles Weitere ist ein Kommando entfernt:
|
|
|
|
```bash
|
|
npx shadcn@latest add dialog table tabs --yes
|
|
```
|
|
|
|
**Tailwind v4 ist CSS-first: es gibt keine `tailwind.config.ts`.** Theme-Tokens leben
|
|
in `src/app/globals.css` unter `@theme inline`. Wer aus Gewohnheit eine Config-Datei
|
|
anlegt, wundert sich, warum nichts greift.
|
|
|
|
Nutze semantische Tokens (`bg-background`, `text-muted-foreground`) statt roher
|
|
Palettenwerte (`bg-slate-900`) — sonst bricht der Dark Mode.
|
|
|
|
---
|
|
|
|
## Authentifizierung: Passkeys
|
|
|
|
Sobald ein Projekt Anmeldung braucht, ist der Stack festgelegt: **Better Auth mit
|
|
Passkey-Plugin**. Passkey ist der primäre Weg und wird zuerst angeboten; ein
|
|
Passwort-Flow ist nur der Fallback für Geräte ohne WebAuthn.
|
|
|
|
`/init` legt dafür automatisch „Auth-Grundlage" als **PROJ-1, P0** an. Jedes Feature,
|
|
das angemeldete Nutzer braucht, hängt davon ab.
|
|
|
|
Verbindlich, sobald Auth im Spiel ist:
|
|
|
|
- Passkey-Registrierung wird bei der Anmeldung angeboten, nicht in den Einstellungen versteckt
|
|
- Bestehende Passwort-Nutzer werden nach dem Login zum Passkey eingeladen
|
|
- Passwort-Fallback ist rate-limited und verrät nie, ob ein Konto existiert
|
|
- Produktion braucht HTTPS — localhost ist die einzige Ausnahme
|
|
|
|
> **Die eine Sache, die dich sonst Stunden kostet:** Die WebAuthn-Relying-Party-ID
|
|
> wird aus dem Hostnamen in `NEXT_PUBLIC_APP_URL` abgeleitet. Stimmt der nicht exakt
|
|
> mit der ausgelieferten Domain überein, scheitern *alle* Passkeys — ohne verwertbare
|
|
> Fehlermeldung.
|
|
|
|
`/qa` prüft aktiv, dass der Passkey-Weg der primäre ist. Ein aufgeweichter oder
|
|
fehlender Passkey-Flow gilt als **High**-Befund.
|
|
|
|
---
|
|
|
|
## Tests
|
|
|
|
| Art | Ort | Kommando | Geschrieben von |
|
|
|-----|-----|----------|-----------------|
|
|
| Unit / Integration (Vitest) | neben der Quelle: `useThing.test.ts` neben `useThing.ts` | `npm test` | `/backend`, `/qa` |
|
|
| E2E (Playwright) | `tests/PROJ-X-name.spec.ts` | `npm run test:e2e` | `/qa` |
|
|
|
|
Die Läufe sind strikt getrennt: Vitest scannt ausschließlich `src/`, Playwright
|
|
ausschließlich `tests/`. Zwei Smoke-Tests liegen als Muster bei und belegen, dass die
|
|
Trennung greift.
|
|
|
|
`/qa` schreibt für jedes bestandene Acceptance Criterion einen E2E-Test — daraus wächst
|
|
die Regressions-Suite von selbst.
|
|
|
|
**Port belegt?** `E2E_PORT=3177 npm run test:e2e`. Ohne das testet Playwright
|
|
stillschweigend gegen einen fremden Server, der zufällig auf :3000 läuft.
|
|
|
|
---
|
|
|
|
## Deployment
|
|
|
|
Selbst gehostet über Docker Compose. Der Stack veröffentlicht die App auf Loopback;
|
|
ein Reverse Proxy auf dem Host terminiert TLS.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
U["Nutzer"] -->|HTTPS| P["Reverse Proxy<br/><i>nginx / Caddy</i><br/>auf dem Host"]
|
|
P -->|"127.0.0.1:3000"| C["app-Container<br/><i>Next.js standalone</i>"]
|
|
C --> H["/api/health"]
|
|
|
|
subgraph SRV["Server"]
|
|
P
|
|
subgraph CMP["docker compose"]
|
|
C
|
|
H
|
|
DB[("Datenbank<br/><i>optional, pro Projekt</i>")]
|
|
end
|
|
end
|
|
|
|
C -.->|"nur wenn gewählt"| DB
|
|
G["git repo"] -->|"./scripts/update.sh"| CMP
|
|
|
|
style DB stroke-dasharray: 5 5
|
|
```
|
|
|
|
```bash
|
|
docker compose up -d --build # Erststart
|
|
./scripts/update.sh # neuen Stand ausrollen
|
|
```
|
|
|
|
### Was `update.sh` macht
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["Start"] --> B{"Arbeitsverzeichnis<br/>sauber?"}
|
|
B -->|nein| X["Abbruch"]
|
|
B -->|ja| C["git fetch + fast-forward"]
|
|
C --> D{"Neuer Commit<br/>oder --force?"}
|
|
D -->|nein| Y["Nichts zu tun"]
|
|
D -->|ja| E["docker compose build"]
|
|
E --> F["docker compose up -d"]
|
|
F --> G{"Healthcheck<br/>innerhalb 120s?"}
|
|
G -->|ja| H["Alte Images aufräumen<br/>✓ Deployed"]
|
|
G -->|nein| I["Letzte 50 Logzeilen ausgeben"]
|
|
I --> J["git reset auf Vorgänger-Commit"]
|
|
J --> K["Neu bauen + starten"]
|
|
K --> L["✓ Rollback"]
|
|
```
|
|
|
|
Ein kaputtes Deployment heilt sich selbst, statt die Seite liegen zu lassen.
|
|
|
|
```bash
|
|
./scripts/update.sh --force # neu bauen ohne neuen Commit
|
|
./scripts/update.sh --branch dev # anderen Branch ausrollen
|
|
```
|
|
|
|
Der Reverse Proxy muss `X-Forwarded-Proto` und `X-Forwarded-Host` durchreichen, sonst
|
|
brechen Redirects und WebAuthn-Origin-Prüfungen. Fertige nginx- und Caddy-Blöcke sowie
|
|
die Anleitung zum Nachrüsten einer Datenbank stehen in
|
|
[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md).
|
|
|
|
Security-Header (`X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, `HSTS`)
|
|
sind in `next.config.ts` gesetzt und nach dem Deploy im Browser gegenzuprüfen.
|
|
|
|
---
|
|
|
|
## Kommandos
|
|
|
|
```bash
|
|
npm run dev # Dev-Server auf :3000
|
|
npm run build # Produktions-Build (standalone)
|
|
npm run start # Produktions-Server lokal
|
|
npm run lint # ESLint
|
|
npm run typecheck # tsc --noEmit
|
|
npm test # Vitest
|
|
npm run test:watch # Vitest im Watch-Modus
|
|
npm run test:e2e # Playwright
|
|
npm run test:all # beide Suites
|
|
npm run docker:up # Stack bauen und starten
|
|
npm run docker:down # Stack stoppen
|
|
npm run docker:logs # Logs folgen
|
|
```
|
|
|
|
---
|
|
|
|
## Dateibaum
|
|
|
|
```
|
|
CLAUDE.md Wird jede Session geladen: Stack, Struktur, Konventionen
|
|
README.md Dieses Dokument
|
|
.claude/
|
|
settings.json Permissions: Deny für Secrets, Allow für Routine
|
|
rules/
|
|
general.md Immer aktiv: Tracking, Status, Git, Human-in-the-Loop
|
|
frontend.md Bei UI-Dateien
|
|
backend.md Bei API-, lib- und Schema-Dateien
|
|
security.md Bei API-, Auth-, Env- und Deploy-Dateien
|
|
skills/
|
|
init/SKILL.md /init
|
|
write-spec/SKILL.md /write-spec (+ template.md für neue Specs)
|
|
refine/SKILL.md /refine
|
|
architecture/SKILL.md /architecture
|
|
frontend/SKILL.md /frontend
|
|
backend/SKILL.md /backend
|
|
qa/SKILL.md /qa
|
|
deploy/SKILL.md /deploy
|
|
help/SKILL.md /help
|
|
agents/
|
|
frontend-dev.md Sub-Agent für UI
|
|
backend-dev.md Sub-Agent für Server
|
|
qa-engineer.md Sub-Agent für Tests und Audit
|
|
docs/
|
|
PRD.md Füllt /init im Interview
|
|
DEPLOYMENT.md Docker-Betrieb, Proxy, DB nachrüsten, Troubleshooting
|
|
features/
|
|
INDEX.md Zentrales Status-Tracking
|
|
src/
|
|
app/
|
|
layout.tsx ThemeProvider + Toaster verdrahtet
|
|
page.tsx Startseite mit Workflow-Übersicht
|
|
globals.css Tailwind v4: Theme-Tokens in @theme inline
|
|
api/health/route.ts Liveness-Probe für Docker und update.sh
|
|
components/
|
|
theme-provider.tsx
|
|
ui/ button, card, input, label, form, sonner
|
|
lib/
|
|
utils.ts cn()
|
|
utils.test.ts Vitest-Muster
|
|
test/setup.ts
|
|
tests/smoke.spec.ts Playwright-Muster
|
|
scripts/update.sh Pull, Rebuild, Restart, Rollback
|
|
Dockerfile Dreistufig → standalone, unprivilegierter User
|
|
compose.yaml App-Service, Healthcheck, Log-Rotation
|
|
.env.example Jede benötigte Variable mit Dummy-Wert
|
|
.gitattributes Erzwingt LF — sonst scheitert update.sh auf dem Server
|
|
.dockerignore .gitignore eslint.config.mjs next.config.ts
|
|
playwright.config.ts postcss.config.mjs vitest.config.mts
|
|
components.json tsconfig.json package.json
|
|
```
|
|
|
|
55 Dateien im Repo.
|
|
|
|
---
|
|
|
|
## Stolperfallen
|
|
|
|
Vier Dinge, die nicht offensichtlich sind und je einmal wehtun:
|
|
|
|
| Fall | Was passiert |
|
|
|------|--------------|
|
|
| `NEXT_PUBLIC_APP_URL` weicht von der Domain ab | Alle Passkeys scheitern, ohne verwertbare Fehlermeldung |
|
|
| Port 3000 ist von einem anderen Projekt belegt | Playwright testet still gegen den fremden Server — `E2E_PORT` setzen |
|
|
| Jemand legt eine `tailwind.config.ts` an | Wird in v4 ignoriert; Tokens gehören in `globals.css` |
|
|
| Checkout auf Windows ohne `.gitattributes` | `update.sh` bekommt CRLF und stirbt auf dem Server mit `bad interpreter` |
|
|
|
|
---
|
|
|
|
## Anpassen
|
|
|
|
| Was | Wo |
|
|
|-----|-----|
|
|
| Stack, Konventionen, Kommandos | `CLAUDE.md` |
|
|
| Coding-Standards | `.claude/rules/` |
|
|
| Workflow-Schritte selbst | `.claude/skills/*/SKILL.md` |
|
|
| Aufgabenteilung der Sub-Agents | `.claude/agents/` |
|
|
| Permissions | `.claude/settings.json` |
|
|
| Spec-Aufbau | `.claude/skills/write-spec/template.md` |
|
|
|
|
Ein neues Kommando ist ein neuer Ordner unter `.claude/skills/` mit einer `SKILL.md`
|
|
und `user-invocable: true` im Frontmatter. Ein neuer Sub-Agent ist eine Markdown-Datei
|
|
in `.claude/agents/` mit `name`, `description`, `tools` im Frontmatter.
|
|
|
|
---
|
|
|
|
## Lizenz
|
|
|
|
MIT
|