Template
A published database port puts the data on the public internet, and Docker's own iptables rules bypass ufw — the server looks firewalled while the port is open. Previously this was only a comment in compose.yaml, which an agent adding a db service later is free to ignore. Anchored at every point where a service could be added or shipped: - rules/security.md: the rule, the reasoning, and the audit commands - rules/backend.md + architecture SKILL: constraint when picking the data layer - agents/backend-dev.md: non-negotiable for any service it adds - agents/qa-engineer.md: a published port is a Critical finding - skills/deploy: blocking pre-flight audit - compose.yaml: db example now uses expose:, with depends_on healthcheck - docs/DEPLOYMENT.md + README: SSH tunnel instead of publishing for debugging
137 lines
4.0 KiB
Markdown
137 lines
4.0 KiB
Markdown
---
|
|
name: architecture
|
|
description: Design PM-friendly technical architecture for a feature. No code, only high-level decisions.
|
|
argument-hint: "PROJ-X or feature-spec-path"
|
|
user-invocable: true
|
|
---
|
|
|
|
# Architecture
|
|
|
|
You translate a feature spec into a design a non-technical stakeholder can follow —
|
|
and you make the binding technical decisions the developers will implement.
|
|
|
|
## Hard rule: no code
|
|
|
|
No SQL, no TypeScript, no API snippets. Describe **what** gets built and **why**,
|
|
never **how** in detail. Structure and plain language only.
|
|
|
|
## 1. Load context
|
|
|
|
1. Read `features/INDEX.md`
|
|
2. Read `docs/PRD.md`
|
|
3. Read the feature spec
|
|
4. `git ls-files src/components/ src/app/api/` — what already exists
|
|
|
|
**If the status is "Roadmap" or no spec file exists:**
|
|
> "PROJ-X hat noch keine Spec. Führe erst `/write-spec PROJ-X` aus — ohne User Stories
|
|
> und Acceptance Criteria kann ich das Design nicht entwerfen."
|
|
→ Stop.
|
|
|
|
## 2. Resolve the open decisions
|
|
|
|
One question at a time, each with a recommendation.
|
|
|
|
### Data layer (decide this first — it shapes everything else)
|
|
|
|
This template deliberately ships **no** database or ORM. Decide per feature:
|
|
|
|
> "Wo sollen die Daten liegen?"
|
|
> Empfehlung: Ohne Nutzerkonten und ohne Gerätewechsel reicht localStorage. Sobald
|
|
> Daten einen Neustart überleben oder zwischen Nutzern geteilt werden müssen, braucht
|
|
> es eine Datenbank im Compose-Stack.
|
|
|
|
If a database is needed, also settle the ORM/driver, and record both in the
|
|
Technical Decisions table. Two constraints: it must be self-hostable in the Docker
|
|
Compose stack (no managed-only services), and it runs **without a published port** —
|
|
only the app is reachable from outside, everything else talks over the internal
|
|
compose network.
|
|
|
|
### Authentication
|
|
|
|
> "Braucht dieses Feature angemeldete Nutzer?"
|
|
|
|
If yes, the stack is fixed: **Better Auth with the passkey plugin**, passkey as the
|
|
primary method, password only as a fallback. Do not re-open that choice — note it
|
|
as a dependency and move on.
|
|
|
|
### Remaining questions
|
|
|
|
- Multiple user roles with different permissions?
|
|
- Third-party integrations?
|
|
- Anything with unusual performance or volume characteristics?
|
|
|
|
## 3. Write the design
|
|
|
|
Add a **Tech Design** section to the spec containing:
|
|
|
|
**A) Component structure** — a plain tree of the UI parts:
|
|
```
|
|
Board-Seite
|
|
├── Eingabefeld (neue Aufgabe)
|
|
├── Spalte "Offen"
|
|
│ └── Aufgabenkarte (verschiebbar)
|
|
├── Spalte "Erledigt"
|
|
└── Leerzustand
|
|
```
|
|
|
|
**B) Data model** — in words, no schema:
|
|
```
|
|
Eine Aufgabe hat:
|
|
- eindeutige ID
|
|
- Titel (max. 200 Zeichen)
|
|
- Status (offen / erledigt)
|
|
- Erstellzeitpunkt
|
|
|
|
Gespeichert in: Browser-localStorage (kein Server nötig)
|
|
```
|
|
|
|
**C) Tech decisions** — each justified in language a PM understands
|
|
|
|
**D) Dependencies** — package names with a one-line purpose each
|
|
|
|
## 4. Log the decisions
|
|
|
|
Every meaningful choice goes into the spec's **Technical Decisions** table:
|
|
|
|
```
|
|
| Entscheidung | Begründung | Datum |
|
|
| localStorage statt Datenbank | Keine Nutzerkonten, Daten bleiben gerätelokal | 2026-08-09 |
|
|
```
|
|
|
|
Log at minimum: storage approach, ORM/driver if any, auth yes/no, package choices,
|
|
and anything a future developer would otherwise question.
|
|
|
|
Anything unresolved goes to **Open Questions** as `- [ ]`.
|
|
|
|
## 5. Review
|
|
|
|
Present the design and ask:
|
|
> "Ergibt das Design so Sinn? Irgendwo Fragen oder Bauchschmerzen?"
|
|
|
|
Wait for approval.
|
|
|
|
## 6. Wrap up
|
|
|
|
- [ ] Existing components and APIs checked
|
|
- [ ] Component structure documented, PM-readable
|
|
- [ ] Data model in plain language, no code
|
|
- [ ] Data layer decided and justified
|
|
- [ ] Auth need clarified (Better Auth + passkey if yes)
|
|
- [ ] Dependencies listed
|
|
- [ ] Technical Decisions table filled
|
|
- [ ] Open Questions recorded
|
|
- [ ] Design written into the spec and re-read to verify
|
|
- [ ] `features/INDEX.md` → **Architected**
|
|
- [ ] User approved
|
|
|
|
## Handoff
|
|
|
|
> "Design steht. Nächster Schritt: `/frontend` für die UI-Komponenten."
|
|
> Braucht das Feature einen Server-Teil, folgt `/backend` danach.
|
|
|
|
## Commit
|
|
|
|
```
|
|
docs(PROJ-X): Add technical design for [feature name]
|
|
```
|