Files
Gardomatic/AGENTS.md
T
kleiax 904d14b64c
CI / test (push) Canceled after 0s
Initial commit
2026-09-12 22:22:17 +02:00

166 lines
8.2 KiB
Markdown

# AGENTS.md
Diese Anweisungen gelten für das gesamte Repository. Benutzeranweisungen haben
Vorrang. Spezifischere `AGENTS.md`- oder `AGENTS.override.md`-Dateien in
Unterverzeichnissen dürfen diese Regeln für ihren Bereich ergänzen oder
überschreiben.
## Projektüberblick
Gardomatic ist eine mobile, mehrbenutzerfähige Gartenverwaltung in Go. Das
Repository enthält drei Programme:
- `cmd/api`: JSON-API; besitzt Authentifizierung, Autorisierung und Fachlogik.
- `cmd/web`: serverseitig gerenderte Webanwendung; greift ausschließlich über
`lib/client` auf die API zu.
- `cmd/cli`: Administration über direkten PostgreSQL-Zugriff.
PostgreSQL ist die einzige unterstützte Datenbank. Das Web-Frontend soll in den
wesentlichen Abläufen ohne JavaScript funktionieren; htmx ergänzt diese Abläufe.
## Arbeitsweise
- Vor Änderungen zuerst den betroffenen Ablauf über alle Schichten verfolgen.
Relevante Implementierungen, Helfer und Tests mit `rg` suchen.
- Änderungen klein und auf den Auftrag begrenzt halten. Keine beiläufigen
Umbenennungen, Formatierungen oder Refactorings außerhalb des betroffenen
Bereichs durchführen.
- Bestehende, nicht zum Auftrag gehörende Änderungen im Arbeitsverzeichnis
erhalten und nicht überschreiben.
- Fachliche Änderungen als vollständigen Vertical Slice umsetzen, soweit
betroffen: Migration, Storage-Vertrag, PostgreSQL-Adapter, API, Client, Web und
Tests.
- Öffentliche Schnittstellen und persistierte Daten nur bewusst und
rückwärtskompatibel ändern. Unvermeidbare Brüche klar dokumentieren.
## Struktur und Schichtengrenzen
- `cmd/*` bleibt schlank und enthält nur Konfiguration, Verdrahtung und Startcode.
- Datenbankzugriffe gehören hinter die Verträge in `internal/storage`; konkrete
PostgreSQL-Implementierungen liegen in `internal/storage/postgres`.
- HTTP- und Berechtigungslogik der JSON-API gehört in `internal/api`.
- Wiederverwendbare API-Aufrufe des Web-Clients gehören in `lib/client`.
- `internal/web` greift nicht direkt auf PostgreSQL oder Storage-Modelle zu.
- Browserpfade werden zentral in `internal/web/paths.go` gepflegt; keine
verstreuten Pfad-Literale einführen.
- Templates, statische Dateien und Mailvorlagen in ihren bestehenden Verzeichnissen
ablegen und die vorhandenen Einbettungsmechanismen beibehalten.
- Neue Pakete nur bilden, wenn sie eine klare Verantwortung besitzen. Keine
Sammelpakete wie `utils`, `common` oder `helpers` neu einführen.
## Idiomatischer Go-Code
- Die in `go.mod` festgelegte Go-Version und Standardbibliothek bevorzugen.
- Geänderte Go-Dateien mit `gofmt` formatieren. Code muss `go vet` und
`staticcheck` bestehen.
- Kleine, fokussierte Funktionen, frühe Rückgaben und verständliche Namen
bevorzugen. Kommentare erklären das Warum, nicht den offensichtlichen Ablauf.
- Fehler mit hilfreichem Kontext und `%w` weiterreichen, wenn Aufrufer die Ursache
noch untersuchen sollen. Erwartbare Domänenfehler mit `errors.Is`/`errors.As`
behandeln.
- `context.Context` entlang bestehender Request- und Storage-Grenzen weitergeben;
keine neuen Hintergrundkontexte mitten in einem Request-Ablauf erzeugen.
- Abhängigkeiten explizit verdrahten. Globale veränderliche Zustände vermeiden.
- Neue Produktionsabhängigkeiten nur bei klarem Mehrwert einführen. Vorhandene
Standardbibliotheks- oder Projektlösungen bevorzugen und neue Abhängigkeiten in
der Übergabe begründen.
## Keine Codeduplizierung
- Vor dem Anlegen neuer Typen, Validatoren, Abfragen, Handler-Helfer, Clientmethoden
oder Template-Teile nach gleichartigem Code suchen.
- Gemeinsame fachliche Regeln an einer Stelle implementieren und von den
aufrufenden Schichten wiederverwenden. API und Web dürfen dieselbe Fachregel
nicht unabhängig voneinander nachbilden.
- Wiederholte SQL-Fragmente, Filter- und Paginglogik über die bereits vorhandenen
Storage-Helfer konsolidieren, sofern Semantik und Sicherheitsgrenzen identisch
sind.
- Ähnliche, aber fachlich unterschiedliche Abläufe nicht vorschnell abstrahieren.
Eine Abstraktion muss Namen, Verantwortung und Fehlerverhalten klarer machen.
- Beim Entfernen einer Duplikation alle Aufrufer migrieren und das alte Konstrukt
löschen, sobald es nicht mehr benötigt wird.
## Fachliche und sicherheitsrelevante Regeln
- Ein Garten ist eine abgeschlossene Daten- und Berechtigungsgrenze. Jede
gartenbezogene Abfrage muss die Garten-ID berücksichtigen.
- Fremde oder nicht sichtbare Garten-IDs liefern `404`; verbotene Aktionen in einem
sichtbaren Garten liefern `403`.
- Authentifizierung und Autorisierung verbleiben in der API. Das Web leitet das
Session-Cookie über einen request-spezifischen API-Client weiter.
- Rollen und Berechtigungen nicht durch reine UI-Prüfungen absichern.
- Artenstammdaten und konkrete Pflanzen getrennt halten; Pflanzen dürfen ohne Art
existieren.
- Automatisch erzeugte Aufgaben müssen idempotent bleiben. Fälligkeitsfenster und
Zeiträume über Jahresgrenzen hinweg korrekt behandeln.
- Nutzereingaben an der zuständigen Systemgrenze validieren. HTML-Ausgabe über
`html/template` escapen und bestehende CSRF-, Cookie- und Security-Header-
Mechanismen nicht umgehen.
- Keine Zugangsdaten, Tokens, echte personenbezogene Daten oder lokale `.env`- und
`.envrc`-Inhalte committen oder in Logs und Tests ausgeben.
## Datenbank und Migrationen
- Schemaänderungen ausschließlich als neues, fortlaufend nummeriertes Paar aus
`.up.sql` und `.down.sql` in `internal/storage/postgres/migrations` hinzufügen.
- Bereits eingecheckte Migrationen nicht nachträglich ändern, außer der Benutzer
fordert dies ausdrücklich und die Migration wurde nachweislich noch nirgends
angewendet.
- Migrationen müssen auf einer leeren Datenbank vorwärts laufen. Die Down-Migration
muss die Änderung soweit sinnvoll und sicher rückgängig machen.
- SQL parametrieren, Transaktionsgrenzen bewusst wählen und konkurrierende
Zugriffe berücksichtigen.
- Neue oder geänderte Abfragen durch PostgreSQL-Integrationstests abdecken, wenn
Verhalten nicht sinnvoll mit einem Unit-Test geprüft werden kann.
## Tests
- Jede Verhaltensänderung erhält passende Tests, sofern technisch möglich. Fehler-
und Berechtigungspfade gehören ebenso dazu wie der Erfolgsfall.
- Fehlerbehebungen möglichst zuerst mit einem Regressionstest reproduzieren.
- Tests nahe am getesteten Paket ablegen und vorhandene Testhelfer wiederverwenden.
Tabellengetriebene Tests nutzen, wenn mehrere gleichartige Fälle dadurch klarer
werden.
- Tests müssen deterministisch und voneinander unabhängig sein. Keine echten
Netzwerkdienste, Uhrzeit oder Zufallswerte unkontrolliert voraussetzen.
- Bestehende Tests nicht löschen, abschwächen oder überspringen, nur um einen Build
grün zu bekommen.
- Zuerst die direkt betroffenen Pakete testen, anschließend standardmäßig:
```sh
go test ./...
```
- Vor Abschluss einer größeren oder sicherheitsrelevanten Änderung zusätzlich
ausführen:
```sh
make audit
```
- PostgreSQL-Integrationstests nur mit einer ausdrücklich dafür vorgesehenen
Datenbank ausführen:
```sh
GARDOMATIC_TEST_DB_DSN="$TEST_DATABASE_URL" go test -count=1 ./internal/storage/postgres
```
`make test/integration` migriert die in `GARDOMATIC_DB_DSN` konfigurierte
Datenbank. Niemals versehentlich gegen Produktion ausführen.
## Dokumentation und Abschluss
- README, Konfigurationsbeispiele und weiterführende Dokumentation aktualisieren,
wenn sich Setup, Befehle, Umgebungsvariablen oder Nutzerverhalten ändern.
- Für Beiträge Dritter gelten `CONTRIBUTING.md` und `CLA.md`. Die CLA-Checkbox oder
Zustimmung niemals stellvertretend für eine beitragende Person setzen.
- Den CLA-Workflow nicht umgehen, abschwächen oder auf einen grünen Status setzen,
wenn die nachweisbare Zustimmung der beitragenden Person fehlt.
- Kein Fremdmaterial übernehmen, dessen Herkunft, Lizenz oder Vereinbarkeit mit
der Projektlizenz und der CLA unklar ist.
- Rechtstexte (`LICENSE` und `CLA.md`) nur auf ausdrücklichen Auftrag ändern.
- Vor der Übergabe den Diff auf unnötige Änderungen, Duplikationen, Geheimnisse und
fehlende Tests prüfen.
- In der Übergabe geänderte Bereiche, ausgeführte Prüfungen und verbleibende Risiken
knapp nennen. Übersprungene Prüfungen mit Grund aufführen.