# 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.