Docker Compose mit drei Services (nginx auf Port 8000), Migrationsmechanik, Update- und Backup-Skript. Anwendung: Router mit CSRF-Prüfung, Anmeldung und Ersteinrichtung, zentraler Einstellungsdialog mit Reitern, ein- und ausschaltbares Debug-Log mit Maskierung von Zugangsdaten. Layout nach Vorbild des FinanzManagers: feste Navigation links, Werkzeugleiste oben, Tab-Leiste; Farbschema hell/dunkel/System. Tests: 51 PHP-Prüfungen und 7 Playwright-Tests, alle grün.
4.6 KiB
Finanzmanager – Entwicklungsregeln
Tech Stack
PHP 8.3+, MariaDB, PSR-4 (Namespace Finanzmanager\), Composer, kein Framework.
MVC: src/Controllers/, src/Models/, src/Services/, src/Views/.
Webserver: nginx + php-fpm, alles in Docker Compose.
Betriebsregeln
- Keine lokale Installation ohne Rückfrage. Kein PHP, kein Composer, kein MariaDB auf dem Host – alles läuft in Containern.
- Lokal erreichbar unter http://localhost:8000.
- Der Produktionsserver zieht den Code aus dem Upstream-Repository und läuft
isoliert: kein Zugriff von außen, kein Zugriff durch Claude Code. Deployment dort
ausschließlich über
scripts/update.sh.
docker compose up -d # starten
docker compose exec -u www-data php php tests/run.php # Tests
./scripts/run-tests.sh # dasselbe, kürzer
./scripts/update.sh # Update (Produktion)
./scripts/backup.sh # Backup mit Rotation
Coding-Regeln
- Kein
var_dump, keindie()in Produktionscode. - Neue Libraries nur nach expliziter Rückfrage. Wenn eine Bibliothek wirklich Arbeit spart, wird sie auf Codeberg geforkt und über ein VCS-Repository eingebunden – keine Abhängigkeit von fremden Update-Zyklen.
declare(strict_types=1), 4 Leerzeichen Einrückung.- SQL ausschließlich über
Database::fetchAll/fetchOne/fetchValue/execute()mit Prepared Statements. - Bezeichner und Oberflächentexte auf Deutsch.
Begrifflichkeiten – nicht abweichen
Die Partnerin nutzt weiterhin den Lexware FinanzManager. Alle fachlichen Begriffe bleiben deshalb identisch:
Kategorie · Klasse · Splitbuchung · Umbuchung · Kontengruppe · Kontoblatt · Budgetplaner · Monatsabschluss · Auswertung · Buchungsvorlage · Regelmäßige Buchung · Zahlungsverkehr · Cockpit · Kontenübersicht · Umbuchungskonto
Keine eigenen Wortschöpfungen, keine englischen Entsprechungen.
Tests
Regel: Jedes neue Feature bekommt einen eigenen Test.
Tests liegen in tests/ nach dem Schema NN_NameTest.php, jede Klasse erweitert
TestCase und implementiert run(). Transaktions-Isolation ist automatisch.
$this->assert(bool, 'Beschreibung');
$this->assertEquals($erwartet, $ist, 'Beschreibung');
$this->assertNotEmpty($wert, 'Beschreibung');
$this->assertNull($wert, 'Beschreibung');
$this->assertGreaterThan($minimum, $wert, 'Beschreibung');
Dateien und Verzeichnisse immer über $this->tempPfad() bzw.
$this->registriereTempPfad() anlegen – der Rollback greift nur in der Datenbank.
Immer -u www-data: sonst laufen die Tests als root und legen unter data/
Dateien an, die php-fpm später nicht mehr beschreiben kann.
E2E-Tests
Browser-Abläufe gehören nach tests/e2e/ (Playwright über das Projekt e2e-runner,
läuft im Container – auf dem Host wird nichts installiert). Rechen- und Model-Logik
gehört in die PHP-Suite: schneller und isoliert.
tests/e2e/run.sh
Datenbankmigrationen
Schemaänderungen kommen ausschließlich als nummerierte Datei nach migrations/:
NNN_kurze_beschreibung.sql(nächste freie dreistellige Nummer)- Nie manuell einspielen –
scripts/migrate.phperledigt das beim Containerstart - Jede Migration idempotent (
IF NOT EXISTS,ON DUPLICATE KEY)
ls migrations/ | tail -1 # nächste freie Nummer
docker compose exec php php scripts/migrate.php # manuell testen
Diagnose
Das Debug-Log wird im Einstellungsdialog unter Diagnose eingeschaltet (oder über
DEBUG_LOG=1). Es schreibt nach data/logs/debug-JJJJ-MM-TT.log und maskiert PINs,
Passwörter, TANs und API-Keys. Im Normalbetrieb ausgeschaltet lassen.
Neue Einstellungen gehören in den zentralen Einstellungsdialog (ein Reiter je
Bereich aus Einstellung::BEREICHE), nicht in eigene Dialoge.
Dokumentation aktuell halten
| Datei | Wann aktualisieren |
|---|---|
Changes.md |
Bei jedem Feature, Bugfix oder strukturellen Änderung |
PLAN.md |
Wenn sich Phasenzuschnitt oder Grundentscheidungen ändern |
README.md |
Bei Änderungen an Funktionsumfang oder Tech Stack |
docs/ |
Wenn ein Modul hinzukommt oder sich wesentlich ändert |
Git
Codeberg, nicht GitHub. Upstream = persönlicher Account, Fork = BOT-Account
(CODEBERG_BOT_TOKEN). Keine Feature-Branches, direkt auf main im Fork.
Ein Feature = ein PR. Vor jedem Commit prüfen, ob upstream noch ein offener PR
vom Fork existiert – sonst vermischen sich Features.
Fix #NR: Kurze Beschreibung der Änderung