Steuerkram/CLAUDE.md
fds2610-bot 7cea573ffc Fix #e2e: E2E-Tests ergänzt, /accounts/new und /assets/new lieferten HTTP 500
Steuerkram an den e2e-runner angebunden (tests/e2e/, 44 Playwright-Tests).
Der erste Smoke-Lauf fand zwei Seiten mit HTTP 500: AccountController::create
las $_GET['from'] ungeprüft, assets/form.php nutzte $testMode und
$defaultKontoId außerhalb des Bearbeiten-Zweigs. Beides war bis zur
Fehler-Härtung (#142) nur eine stille Warning.

Test 67 räumt sein Belegverzeichnis jetzt mit ab - es blieb als root-eigenes
Verzeichnis liegen und blockierte spätere echte Uploads mit HTTP 500.

Test 77 (neu) sichert die Löschsperre von Beleg::delete() ab.
2026-08-02 11:58:33 +02:00

4.2 KiB
Raw Blame History

Steuerkram – Entwicklungsregeln

Tech Stack

PHP 8.3+, MySQL, PSR-4 (Namespace Steuerkram\), Composer, kein Framework. MVC: src/Controllers/, src/Models/, src/Services/, src/Views/.

Coding-Regeln

  • Kein var_dump, kein die() in Produktionscode.
  • Neue Libraries nur nach expliziter Rückfrage einbinden.
  • Bestehenden Code-Stil beibehalten (declare strict_types, 4 Spaces).
  • SQL ausschließlich über Database::fetchAll/fetchOne/execute() mit Prepared Statements.

Tests

Regel: Jedes neue Feature bekommt einen eigenen Test.

Tests liegen in tests/ und folgen dem Namensschema NN_FunktionsnameTest.php. Jede Testklasse erweitert TestCase und implementiert run().

php tests/run.php           # alle Tests ausführen
./scripts/run-tests.sh      # Tests + automatische Issue-Erstellung bei Fehlern
./scripts/run-tests.sh 42   # Tests; bei Fehlern Kommentar in Issue #42

Neuen Test erstellen

  1. Datei tests/NN_MeinFeatureTest.php anlegen (NN = nächste freie Nummer)
  2. Klasse MeinFeatureTest extends TestCase
  3. protected string $testName = 'Test NN: Beschreibung';
  4. Methode public function run(): void mit Assertions implementieren
  5. Transaktions-Isolation ist automatisch (setUp/tearDown in TestCase)

Assertion-Methoden

$this->assert(bool, 'Beschreibung');
$this->assertEquals($erwartet, $ist, 'Beschreibung');
$this->assertGreaterThan($min, $wert, 'Beschreibung');
$this->assertNotEmpty($wert, 'Beschreibung');

E2E-Tests (Browser)

Die PHP-Tests erreichen Routing, Views und Formular-JavaScript nicht. Dafür gibt es Playwright-Tests in tests/e2e/, die im Container des e2e-runner laufen (auf dem Host wird nichts installiert). Details: tests/e2e/README.md.

docker compose exec web php scripts/e2e-user.php   # einmalig: Testnutzer anlegen
tests/e2e/run.sh                                   # alle E2E-Tests
docker compose exec web php scripts/e2e-cleanup.php --force   # Reste entfernen

Fehlt Docker, der Runner oder das Image, wird mit Exit 0 übersprungen.

Welche Ebene wofür: Rechen- und Model-Logik gehört in die PHP-Suite (schneller, isoliert). In tests/e2e/ gehört nur, was einen Browser braucht: Formularabläufe, Redirects, gerenderte Views, JavaScript-Umrechnungen, DOM-XSS.

Dokumentation aktuell halten

Datei Wann aktualisieren
Changes.md Bei jedem Feature, Bugfix oder strukturellen Änderung (nicht bei reinen Test- oder Doku-Commits)
README.md Wenn sich der Funktionsumfang oder der Tech Stack grundlegend ändert
docs/funktionen.md Wenn ein neues Feature hinzukommt oder ein bestehendes wesentlich geändert wird
docs/berechnungslogik.md Bei jeder Änderung an EuerCalculator.php oder UstvaCalculator.php (Zuordnungsregeln, neue Kennzahlen, geänderte Bedingungen)
docs/anlagevermögen.md Bei Änderungen am Anlagevermögens-Workflow oder den Asset-Modellen

Datenbankmigrationen

Schemaänderungen (neue Spalten, Tabellen, Kontenanpassungen) kommen ausschließlich als nummerierte Migrations-Datei in migrations/:

  • Schema: NNN_kurze_beschreibung.sql (NNN = nächste freie dreistellige Nummer, z.B. 011_...)
  • Migrationen werden nie manuell eingespielt – scripts/migrate.php erledigt das automatisch beim Container-Start
  • Jede Migration muss idempotent sein oder mit IF NOT EXISTS / ON DUPLICATE KEY abgesichert werden
# Nächste freie Nummer ermitteln:
ls migrations/ | tail -1

# Migration manuell testen (ohne Neustart):
docker compose exec web php scripts/migrate.php

Geplante Aufgaben (Cron)

Alle planmäßigen Aufgaben (z.B. Ideenagent, Automatisierungen) laufen lokal über die System-Crontab des Nutzers. Für außerplanmäßige Ausführung das jeweilige Skript direkt aufrufen:

crontab -l                                              # alle geplanten Jobs anzeigen
/home/fds/projects/Steuerkram/.claude/ideenagent-run.sh # Ideenagent manuell starten
/home/fds/projects/Steuerkram/.claude/automate-run.sh   # Automatisierung manuell starten

Remote Triggers (claude.ai) oder Claude Code Cron-Jobs werden nicht verwendet.

Commits

Fix #NR: Kurze Beschreibung der Änderung

Keine Co-Authored-By-Zeile. Keine langen Commit-Messages.