Files
Florian Wilde 75e99f75c6 feat: make "only the app publishes a port" a binding rule
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
2026-08-09 01:12:06 +02:00

4.0 KiB

name, description, argument-hint, user-invocable
name description argument-hint user-invocable
architecture Design PM-friendly technical architecture for a feature. No code, only high-level decisions. PROJ-X or feature-spec-path 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]