- Rewrite DashboardController with cached role-scoped KPI aggregation (Cache::remember, 5-min TTL, Declaration::forUser scope) - Create StatCard.vue component with CVA status variants and a11y - Rewrite Dashboard.vue with 4-column KPI grid + urgent declarations table - Add mise_en_demeure status to DeclarationStatus enum with transitions - Exclude termine, mise_en_demeure, ferme from dashboard queries - Set deadline proximity red threshold to ≤5 days - Add abort(404) for non-member workspace access per architecture - Fix null-safe client access for soft-deleted clients - Fix hardcoded routes with Wayfinder type-safe imports - Fix DashboardProps.stats type to allow null - Add aria-pressed to StatCard for accessibility - Install shadcn-vue table component (11 files) - Add 11 Pest feature tests + 3 mise_en_demeure transition tests - Fix DeclarationFactory eager workspace creation causing slug collisions - 196 tests pass, 836 assertions, zero regressions
L'Ami Fiduciaire
Client management platform for fiduciary and accounting firms — built with Laravel 12, Vue 3, and Inertia.js.
Table of Contents
- Overview
- Tech Stack
- Cold-Start Guide
- Vite and Docker: The HMR Gotcha
- Verification Checklist
- Docker Command Reference
- Testing
- Code Quality
- Project Structure
- Key Services
- License
Overview
L'Ami Fiduciaire is a multi-tenant web platform that provides:
- Client management — CRUD operations, legal forms, status tracking
- Dossier system — folders with priorities, workflows, and document exchange
- Client portal — token-based file uploads for external clients
- In-folder messaging — communication threads within dossiers
- Activity logging — full audit trail via Spatie Activity Log
- Two-factor authentication — TOTP-based 2FA via Laravel Fortify
Tech Stack
| Layer | Technology |
|---|---|
| Backend | Laravel 12, PHP 8.4 |
| Frontend | Vue 3, TypeScript, Inertia.js v2 |
| Styling | Tailwind CSS 4, shadcn-vue |
| Database | SQLite (dev) |
| Cache/Queue/Session | Redis |
| Email (dev) | Mailpit |
| DevOps | Docker Compose via Laravel Sail |
| Testing | Pest PHP 4 |
Cold-Start Guide
Prerequisites
You need only two things installed on your machine:
- Docker Desktop (or Docker Engine + Docker Compose)
- Git
No local PHP, Node, Composer, or npm required. Everything runs inside Docker.
First-Time Setup
1. Clone the repository
git clone <repository-url> "l'ami fiduciaire"
cd "l'ami fiduciaire"
2. Create your environment file
cp .env.example .env
3. Install PHP dependencies (this also builds the Docker image)
docker run --rm \
-u "$(id -u):$(id -g)" \
-v "$(pwd):/var/www/html" \
-w /var/www/html \
laravelsail/php84-composer:latest \
composer install --ignore-platform-reqs
4. Start the containers
./vendor/bin/sail up -d
5. Generate the application key
./vendor/bin/sail artisan key:generate
6. Run database migrations and seeders
./vendor/bin/sail artisan migrate --seed
7. Install frontend dependencies and build assets
./vendor/bin/sail npm install
./vendor/bin/sail npm run build
8. Open the application
Visit http://localhost in your browser.
Daily Development
Start containers and the Vite dev server for hot-reload:
./vendor/bin/sail up -d
./vendor/bin/sail npm run dev
Or use the all-in-one dev command that starts the server, queue worker, log viewer, and Vite simultaneously:
./vendor/bin/sail composer run dev
Stopping the Environment
./vendor/bin/sail down
To stop and remove volumes (resets Redis data):
./vendor/bin/sail down -v
Vite and Docker: The HMR Gotcha
When running Vite inside a Docker container, Hot Module Replacement (HMR) requires port 5173 to be exposed from the container to your host. This is already configured in compose.yaml:
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
Common symptoms when HMR breaks
| Symptom | Cause | Fix |
|---|---|---|
| Page loads but CSS/JS changes require full refresh | Vite dev server is not running | Run ./vendor/bin/sail npm run dev |
| Browser console shows WebSocket connection errors | Port 5173 is not forwarded or is in use | Check no other process uses port 5173, restart Sail |
ERR_CONNECTION_REFUSED on Vite assets |
Vite is running but the container port mapping is missing | Verify compose.yaml has the 5173 port mapping |
Assets load from public/build/ instead of Vite |
A stale production build exists and Vite is not running | Delete public/build/ and run ./vendor/bin/sail npm run dev |
Key rule
Always run
./vendor/bin/sail npm run devas a separate process when developing. The Vite dev server must stay running alongside the Laravel container for HMR to work. If you usesail composer run dev, it handles this for you.
Custom port
If port 5173 conflicts with another service, override it in your .env:
VITE_PORT=5174
Then restart Sail.
Verification Checklist
Run through this checklist after setup to confirm everything works:
Infrastructure
./vendor/bin/sail ps— showslaravel.test,redis, andmailpitrunning- http://localhost — loads the application without errors
- http://localhost:8025 — Mailpit dashboard is accessible
Database
./vendor/bin/sail artisan migrate:status— all migrations showRan./vendor/bin/sail artisan tinker --execute="echo App\Models\User::count();"— returns a number (seeded users)
Frontend
./vendor/bin/sail npm run dev— Vite starts without errors on port 5173- Edit any
.vuefile — changes appear in the browser without full refresh (HMR works) - Browser DevTools console is free of errors
Cache and Queue
./vendor/bin/sail artisan cache:clear— completes without error (Redis is reachable)./vendor/bin/sail artisan queue:work --once— processes a job or reports "No jobs" (queue connection works)
Tests
./vendor/bin/sail test— all tests pass
Docker Command Reference
All commands use ./vendor/bin/sail as the Docker entry point. You can create a shell alias for convenience:
alias sail='./vendor/bin/sail'
Container management
| Command | Description |
|---|---|
sail up -d |
Start all containers in detached mode |
sail down |
Stop and remove containers |
sail down -v |
Stop containers and remove volumes |
sail ps |
List running containers |
sail logs -f |
Follow container logs |
sail restart |
Restart all containers |
Laravel (Artisan)
| Command | Description |
|---|---|
sail artisan migrate |
Run pending migrations |
sail artisan migrate:fresh --seed |
Reset database and seed |
sail artisan db:seed |
Run database seeders |
sail artisan tinker |
Open Laravel REPL |
sail artisan cache:clear |
Clear application cache |
sail artisan queue:work |
Start the queue worker |
sail artisan pail |
Stream application logs |
Frontend (npm)
| Command | Description |
|---|---|
sail npm install |
Install Node dependencies |
sail npm run dev |
Start Vite dev server with HMR |
sail npm run build |
Build production assets |
sail npm run build:ssr |
Build with server-side rendering |
Composer
| Command | Description |
|---|---|
sail composer install |
Install PHP dependencies |
sail composer run dev |
Start all dev services concurrently |
sail composer run test |
Run linter + test suite |
Shell access
sail shell # Enter container as sail user
sail root-shell # Enter container as root
Testing
Run the full test suite (lint + Pest):
./vendor/bin/sail composer run test
Run only tests (skip linting):
./vendor/bin/sail test
Run a specific test file:
./vendor/bin/sail test tests/Feature/Auth/LoginTest.php
Code Quality
| Tool | Command | Purpose |
|---|---|---|
| Pint | sail composer run lint |
PHP code formatting (PSR-12) |
| ESLint | sail npm run lint |
TypeScript/Vue linting + autofix |
| Prettier | sail npm run format |
Frontend code formatting |
| Prettier check | sail npm run format:check |
Verify formatting without changes |
Project Structure
├── app/
│ ├── Actions/ # Single-purpose action classes
│ ├── Enums/ # PHP enums (status, types)
│ ├── Http/ # Controllers, requests, middleware
│ ├── Models/ # Eloquent models
│ └── Observers/ # Model lifecycle hooks
├── database/
│ ├── factories/ # Test data factories
│ ├── migrations/ # Database schema
│ └── seeders/ # Seed data
├── resources/js/
│ ├── pages/ # Inertia page components (Vue)
│ ├── layouts/ # Layout wrappers
│ ├── components/ui/ # shadcn-vue components
│ ├── composables/ # Vue composables
│ └── types/ # TypeScript definitions
├── routes/ # Laravel route definitions
├── tests/
│ ├── Feature/ # Integration tests
│ └── Unit/ # Unit tests
├── compose.yaml # Docker Compose services
├── vite.config.ts # Vite + plugins configuration
└── docs/ # Detailed project documentation
Key Services
| Service | Internal Port | Host URL | Purpose |
|---|---|---|---|
| Laravel | 80 | http://localhost | Application server |
| Vite | 5173 | http://localhost:5173 | HMR dev server |
| Redis | 6379 | — | Cache, sessions, queues |
| Mailpit SMTP | 1025 | — | Catches outbound email |
| Mailpit UI | 8025 | http://localhost:8025 | Email viewer dashboard |
License
Proprietary — All rights reserved.