Developer Onboarding
Welcome! This guide gets you from zero to a running Gäld development environment.
Prerequisites
| Tool | Version | Purpose |
|---|---|---|
| Docker & Docker Compose | Latest | Runs PostgreSQL, Redis, and the Laravel app via Sail |
| PHP | 8.4+ | Only needed if running tools outside Sail |
| Node.js | 24+ | Frontend asset compilation |
| pnpm | Latest | Package manager for JS dependencies |
| Composer | 2.x | Installed inside Sail, but useful locally too |
1. Clone & Install
git clone git@github.com:Scanix/Gaeld.git
cd Gaeld
# Install PHP dependencies
composer install
# Install JS dependencies
pnpm install
# Copy environment file and generate app key
cp .env.example .env
php artisan key:generate
All PHP commands (artisan, composer, phpstan, phpunit) should be run through Laravel Sail. After composer install, Sail is available at ./vendor/bin/sail. You can alias it:
alias sail='./vendor/bin/sail'
2. Start the Development Stack
sail up -d
This starts:
- PostgreSQL 16 on port 5432
- Redis 7 on port 6379
- Laravel app on port 80 (http://localhost)
Run the first-time setup:
sail artisan migrate
sail artisan db:seed # optional — loads demo data
sail artisan gaeld:install # interactive setup wizard
3. Build Frontend Assets
pnpm build # one-time build
pnpm dev # Vite dev server with HMR
The frontend uses Vue 3 + Inertia.js. Components live in resources/js/.
4. Running Quality Tools
Tests (PHPUnit)
sail artisan test # run all tests
sail artisan test --filter=InvoiceTest # run specific test
sail artisan test --testsuite=Unit # run only unit tests
sail artisan test --coverage # with coverage report
There are three test suites: Unit, Feature, and Security.
Static Analysis (PHPStan)
sail bin phpstan analyse --memory-limit=512M
# or via composer script:
sail composer stan
PHPStan runs at level 7 with a baseline file (phpstan-baseline.neon). New code must not introduce new errors. Existing baseline entries should be reduced over time.
Code Style (Pint)
sail composer format # auto-fix code style
sail composer lint # check without fixing (CI mode)
Pint uses the laravel preset. A pre-commit hook enforces style on staged PHP files.
All checks at once
sail composer check # runs lint → stan → test
5. Domain Structure
The codebase uses Domain-Driven Design. All business logic lives under app/Domains/:
| Domain | Purpose |
|---|---|
Accounting | Chart of accounts, journal entries, fiscal years, ledger, VAT rates |
Api | REST API controllers, resources, Sanctum tokens, webhooks |
Assets | Fixed assets and depreciation |
Banking | Bank accounts, imports (CAMT.053), transactions, reconciliation |
Contacts | Customers, suppliers, contact persons |
Expenses | Expense tracking, categories, approval workflow |
Invoicing | Invoices, credit notes, payments, recurring invoices, QR-Bill |
Migration | Data import from other accounting systems |
Organizations | Multi-tenancy, org settings, invitations, onboarding |
Payroll | Salary processing and social charges |
Reporting | Dashboard, financial reports, aging, cash flow, VAT report |
Users | Authentication, registration, 2FA, passkeys, profile |
Each domain contains: Actions/, Controllers/, DTOs/, Models/, Services/, Requests/, Policies/, and more. See Coding Standards for the full breakdown.
6. Key Conventions
- Monetary math: BCMath only (strings, never floats) — e.g.
bcadd('100.00', '8.10', 2) - Models: Generic type annotations on all relationships,
preventLazyLoading()active in non-production - Invoices: Use UUIDs (
HasUuidstrait) - Expenses:
categoryis required (not null), field isdate(notexpense_date),vat_amountdefaults to0 - Validation: Web forms return 302 redirect-back with errors (not 422 JSON)
- Tests: PHPUnit 13 — use
#[DataProvider('name')]attribute (not@dataProviderannotation) - Queues: 4 queues (
default,webhooks,exports,notifications) routed viaQueue::route()
7. Useful Commands
sail artisan gaeld:install # first-run wizard
sail artisan gaeld:demo # seed demo data for development
sail artisan gaeld:sync-permissions # sync RBAC permissions after changes
sail artisan scout:sync-index-settings # sync Meilisearch indexes
sail artisan scribe:generate # regenerate API docs
8. Contributing
- Fork the repo and create a feature branch from
develop - Follow the coding standards (Pint + PHPStan must pass)
- Write tests for new features
- Submit a PR against
develop
See Contributing Guide for the full process.