Contributing & Architektur
Dieser Leitfaden richtet sich an Entwickler, die zu Gäld beitragen oder dessen Interna verstehen möchten.
Entwicklungsumgebung
Docker (empfohlen)
git clone https://github.com/Scanix/Gaeld.git
cd Gaeld/api
cp .env.example .env
docker compose up -d
docker compose exec laravel.test php artisan gaeld:install --demo
Die App ist unter http://localhost:8080 verfügbar. Das Flag --demo erstellt Beispieldaten (Rechnungen, Ausgaben, Kontakte) für die Entwicklung.
Von Docker Compose gestartete Dienste:
| Dienst | Container | Port |
|---|---|---|
| Laravel (PHP + Nginx) | laravel.test | 8080 |
| PostgreSQL 16 | pgsql | 5432 |
| Redis 7 | redis | 6379 |
| MeiliSearch | meilisearch | 7700 |
| Mailpit (Dev-E-Mail) | mailpit | 8025 (Dashboard), 1025 (SMTP) |
Befehle ausführen
Alle PHP-Befehle sollten innerhalb des Docker-Containers ausgeführt werden:
# Artisan-Befehle
docker compose exec laravel.test php artisan <command>
# Composer
docker compose exec laravel.test composer <command>
# PHPStan
docker compose exec laravel.test ./vendor/bin/phpstan analyse
# Tests
docker compose exec laravel.test php artisan test
Frontend
Das API-Projekt verwendet Inertia.js + Vue 3 für seine Admin-Oberfläche:
pnpm install
pnpm dev # Vite Dev Server mit HMR
pnpm build # Produktions-Build
Architekturübersicht
Tech Stack
| Schicht | Technologie |
|---|---|
| Backend | Laravel 12, PHP 8.4 |
| Frontend | Vue 3 + Inertia.js |
| Datenbank | PostgreSQL 16 |
| Cache/Queue/Session | Redis 7 |
| Suche | MeiliSearch (Fallback: Datenbank) |
| Währungsberechnung | BCMath (Strings, niemals Floats) |
Domain-Driven Struktur
Die Codebase ist in Domains unter app/Domains/ organisiert, die jeweils eine Geschäftsfähigkeit kapseln:
app/Domains/
├── Accounting/ # Kontenplan, Hauptbuch, Buchungssätze, MWST, Budget
├── Api/ # REST-API-Controller, Ressourcen, Webhook-System
├── Assets/ # Anlagenvermögen und Abschreibungen
├── Banking/ # Bankkonten, CAMT-Import, Abstimmung
├── Contacts/ # Kunden, Lieferanten, Kontaktpersonen
├── Expenses/ # Ausgabenerfassung, Kategorien, Genehmigungsworkflow
├── Invoicing/ # Rechnungen, Gutschriften, Dauerrechnungen, Zahlungen
├── Migration/ # Datenimport aus externer Buchhaltungssoftware
├── Organizations/ # Multi-Tenancy, Org-Einstellungen, Onboarding
├── Payroll/ # Mitarbeiter, Gehaltsabrechnungen, Schweizer Abzüge
├── Reporting/ # Finanzberichte, Exporte
└── Users/ # Authentifizierung, Profile, 2FA, Passkeys
Jede Domain enthält typischerweise:
Domains/Invoicing/
├── Controllers/ # HTTP-Controller
├── Models/ # Eloquent-Modelle
├── Services/ # Geschäftslogik
├── Queries/ # Query Builder (Filterung, Sortierung, Suche)
├── Requests/ # Form-Request-Validierung
├── Resources/ # Inertia/API-Ressourcentransformer
├── Events/ # Domain Events
├── Enums/ # Status-Enums, Typen
└── Policies/ # Autorisierungsrichtlinien
Multi-Tenancy
Gäld verwendet ein Shared-Database-Modell mit zeilenbasierter Isolation:
- Jede Datentabelle hat einen
organization_id-Fremdschlüssel - Das Trait
BelongsToOrganizationfügt einen globalen Scope hinzu, der Abfragen automatisch filtert und die Org bei der Erstellung automatisch zuweist - Der Service
CurrentOrganizationhält die aktive Org für die aktuelle Anfrage - Die Middleware
EnsureHasOrganizationlöst die Org aus der Session (Web) oder dem Token (API) auf
Wichtige Traits
| Trait | Zweck |
|---|---|
BelongsToOrganization | Scopt automatisch alle Abfragen auf die aktuelle Org, weist organization_id bei Erstellung zu |
Auditable | Protokolliert Modelländerungen im Aktivitätsprotokoll |
HasUuids | Verwendet UUIDs als Primärschlüssel |
Feature Flags
Funktionen werden über FEATURE_*-Umgebungsvariablen gesteuert:
| Flag | Standard | Beschreibung |
|---|---|---|
FEATURE_BANK_SYNC | false | Bankverbindung und automatische Synchronisation |
FEATURE_AUTO_RECONCILIATION | false | Automatische Zahlungszuordnung |
FEATURE_AUTOMATION | false | Regel-Engine und Automatisierung |
FEATURE_MULTI_CURRENCY | false | Multi-Währungs-Unterstützung |
FEATURE_API_ACCESS | false | REST-API-Zugang |
FEATURE_RULE_ENGINE | false | Geschäftsregel-Engine |
FEATURE_SAAS | false | SaaS-Funktionen (privates Plugin) |
Plugin-System
Plugins erweitern Gäld ohne den Kerncode zu verändern. Siehe den Plugin-Entwicklungsleitfaden für Details.
Testing
Gäld hat drei Test-Suiten:
# Alle Tests ausführen
docker compose exec laravel.test php artisan test
# Eine bestimmte Suite ausführen
docker compose exec laravel.test php artisan test --testsuite=Feature
docker compose exec laravel.test php artisan test --testsuite=Unit
docker compose exec laravel.test php artisan test --testsuite=Security
# Eine bestimmte Testdatei ausführen
docker compose exec laravel.test php artisan test --filter=InvoiceTest
| Suite | Ort | Zweck |
|---|---|---|
Feature | tests/Feature/ | Integrationstests — HTTP-Anfragen, Datenbank, Full Stack |
Unit | tests/Unit/ | Isolierte Unit-Tests — Services, Modelle, Hilfsfunktionen |
Security | tests/Security/ | Sicherheitstests — Auth, Berechtigungen, CSRF, Injection |
Test-Konventionen
- Verwenden Sie das Attribut
#[DataProvider('name')](nicht die Annotation@dataProvider) - Web-Formularvalidierung gibt 302-Weiterleitungen zurück — prüfen Sie mit
assertSessionHasErrors() - Alle Tests verwenden eine In-Memory-Testdatenbank (konfiguriert in
phpunit.xml) - Test-Hilfsprogramme und gemeinsame Traits befinden sich in
tests/Traits/ - Fixture-Dateien (Beispiel-CAMT-XMLs, CSVs) befinden sich in
tests/fixtures/
Statische Analyse
docker compose exec laravel.test ./vendor/bin/phpstan analyse
PHPStan ist auf Level 5 konfiguriert mit einer Baseline in phpstan-baseline.neon.
Code-Stil
docker compose exec laravel.test ./vendor/bin/pint
Verwendet Laravel Pint zur Codeformatierung (basierend auf PSR-12).
Beitrags-Workflow
- Forken Sie das Repository und erstellen Sie einen Branch von
main - Richten Sie die Entwicklungsumgebung wie oben beschrieben ein
- Nehmen Sie Ihre Änderungen vor — halten Sie jeden PR auf ein einzelnes Thema fokussiert
- Fügen Sie Tests hinzu für jedes neue Verhalten
- Führen Sie Checks aus vor dem Pushen:
docker compose exec laravel.test php artisan test
docker compose exec laravel.test ./vendor/bin/phpstan analyse
docker compose exec laravel.test ./vendor/bin/pint --test - Öffnen Sie einen Pull Request mit einer klaren Beschreibung des Was und Warum
Für grössere Änderungen eröffnen Sie bitte zuerst ein Issue, um den Ansatz zu diskutieren.
Commit-Nachrichten
Verwenden Sie klare, beschreibende Commit-Nachrichten. Stellen Sie den Domänennamen voran, wenn relevant:
invoicing: add recurring invoice frequency validation
banking: fix CAMT.053 duplicate detection
docs: update API reference with webhook events
Issues melden
Eröffnen Sie ein Issue auf GitHub mit:
- Einem klaren Titel und Beschreibung
- Schritten zur Reproduktion (bei einem Bug)
- Erwartetem vs. tatsächlichem Verhalten
- Ihrer Umgebung (PHP-Version, OS, Browser)