# 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**. - Es gibt derzeit **nur die Entwicklungsumgebung**, keinen getrennten Produktionsserver. `scripts/update.sh` zieht deshalb aus dem **Fork** (`origin`, Branch `main`); der Upstream dient als Backup und zur Veröffentlichung. Kommt später eine isolierte Produktion (kein Zugriff von außen, kein Zugriff durch Claude Code), zieht sie aus dem Upstream: `UPDATE_REMOTE=upstream ./scripts/update.sh`. ```bash 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 aus dem Fork ./scripts/backup.sh # Backup mit Rotation ``` ## Coding-Regeln - Kein `var_dump`, kein `die()` 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. ```php $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. ```bash 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.php` erledigt das beim Containerstart - Jede Migration idempotent (`IF NOT EXISTS`, `ON DUPLICATE KEY`) ```bash 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 ```