Files
L-Ami-Fiduciaire/docs/architecture.md
Saad Ibn-Ezzoubayr 35545c2a8f feat: L'Ami Fiduciaire V1.0.0 — full codebase with Story 0.1 complete
Initial commit of the L'Ami Fiduciaire SaaS platform built on Laravel 12,
Vue 3, Inertia.js 2, and Tailwind CSS 4.

Story 0.1 (rename folders to declarations in database) is implemented and
code-reviewed: migration, rollback, and 6 Pest tests all passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 23:33:10 +00:00

9.9 KiB

Architecture — L'Ami Fiduciaire

Generated: 2026-03-08 | Scan Level: Quick

Executive Summary

L'Ami Fiduciaire is a full-stack web application built for fiduciary/accounting firm client management. It provides a multi-tenant workspace system where firms can manage clients, folders (dossiers), and document exchanges with external clients via email-based invitation links.

The application follows a server-driven SPA architecture using Laravel 12 as the backend with Inertia.js v2 bridging to a Vue 3 frontend. This eliminates the need for a separate API layer — controllers render Vue pages directly via Inertia, while Wayfinder generates TypeScript route functions for type-safe navigation.

Architecture Pattern

Pattern: Full-Stack Monolith with Server-Driven SPA (Inertia.js)

┌─────────────────────────────────────────────────────┐
│                    Browser (SPA)                     │
│  Vue 3 + TypeScript + Tailwind CSS 4 + shadcn-vue   │
│         Inertia.js Client → Page Components          │
└──────────────────────┬──────────────────────────────┘
                       │  XHR / Inertia Protocol
┌──────────────────────▼──────────────────────────────┐
│               Laravel 12 (PHP 8.4)                   │
│  ┌─────────────────────────────────────────────┐    │
│  │  Middleware Pipeline                         │    │
│  │  (Auth, Workspace, Admin, Inertia, etc.)     │    │
│  └──────────────────┬──────────────────────────┘    │
│  ┌──────────────────▼──────────────────────────┐    │
│  │  Controllers → Inertia::render('Page', props)│    │
│  └──────────────────┬──────────────────────────┘    │
│  ┌──────────────────▼──────────────────────────┐    │
│  │  Eloquent ORM → Models + Relationships       │    │
│  └──────────────────┬──────────────────────────┘    │
└──────────────────────┼──────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────┐
│              MySQL 8.4 (via Docker/Sail)             │
└─────────────────────────────────────────────────────┘

Technology Stack

Category Technology Version
Backend Framework Laravel 12.x
Backend Language PHP 8.2+ (8.4 runtime)
Frontend Framework Vue.js 3.5+
Frontend Language TypeScript 5.2+
SPA Bridge Inertia.js v2
CSS Framework Tailwind CSS 4.x
UI Components shadcn-vue (reka-ui) 2.4+
Build Tool Vite 7.x
Database MySQL 8.4
Authentication Laravel Fortify v1
Route Generation Laravel Wayfinder 0.1.x
File Management Spatie Media Library 11.x
Activity Logging Spatie Activity Log 4.x
Enums bensampo/laravel-enum 6.x
Testing Pest 4.x
Code Style (PHP) Laravel Pint 1.x
Code Style (JS) ESLint 9 + Prettier 3 -
Containerization Docker / Laravel Sail -
WebSockets Soketi latest
Mail Testing Mailpit latest

Data Architecture

Eloquent Models

Model Table Key Relationships
User users belongsToMany(Workspace), hasMany(Client)
Workspace workspaces belongsToMany(User) via WorkspaceUser
WorkspaceUser workspace_user Pivot: user_id, workspace_id, role
Client clients belongsTo(Workspace), hasMany(Folder)
Folder folders belongsTo(Client), hasMany(Message), hasMany(FolderInvitation), media
FolderInvitation folder_invitations belongsTo(Folder) — token-based access
Message messages belongsTo(Folder)

Business Enums

Enum Purpose
ActorType Distinguishes user types in activity logs
ClientStatus Client lifecycle status
FolderPriority Folder urgency level
FolderStatus Folder workflow status
FolderType Category of folder/dossier
LegalForm Legal entity type for clients
MessageType Type of message in folder
UserGroup User permission group
WorkspaceUserRole Role within a workspace

Database Migrations (16 files)

  • Core: users, cache, jobs tables
  • Auth: two-factor columns on users
  • Multi-tenant: workspaces, workspace_user
  • Business: clients, folders, folder_invitations, messages
  • Packages: activity_log, media tables
  • Extensions: confirmation fields on folders, responsable/suivi fields on clients

Authentication & Authorization

  • Laravel Fortify provides headless auth: login, registration, password reset, email verification, two-factor authentication (TOTP)
  • Custom Middleware:
    • EnsureUserIsAdmin — Admin-only route protection (users, workspaces management)
    • EnsureUserHasWorkspace — Workspace context enforcement
    • ValidateFolderInvitation — Token-based access for external client portal
    • HandleInertiaRequests — Shares auth/workspace data with frontend
    • HandleAppearance — Theme/appearance persistence

Route Architecture

Authenticated Routes (auth + verified)

  • GET /dashboard — DashboardController (invokable)
  • POST /workspace/switch — WorkspaceSwitchController (invokable)

Workspace-Scoped Routes (auth + verified + workspace)

  • CRUD /clients — ClientController (resource)
  • CRUD /folders — FolderController (resource)
  • POST /folders/{folder}/messages — FolderMessageController
  • POST /folders/{folder}/media — FolderMediaController (upload)
  • GET /folders/{folder}/media/{mediaId} — FolderMediaController (download)

Admin Routes (auth + verified + admin)

  • CRUD /users — UserController (resource)
  • CRUD /workspaces — WorkspaceController (resource)

Public Client Portal (/c/ prefix, folder.invitation middleware)

  • GET|POST /c/upload/{token} — Client file upload
  • GET|POST /c/confirm/{token} — Client folder confirmation
  • GET|POST /c/refuse/{token} — Client folder refusal

Settings Routes (auth / auth+verified)

  • GET|PATCH /settings/profile — Profile management
  • DELETE /settings/profile — Account deletion
  • GET|PUT /settings/password — Password change (throttled)
  • GET /settings/appearance — Appearance/theme settings
  • GET /settings/two-factor — Two-factor authentication management

Email System

5 folder-related mailables handle client communication:

  • FolderInviteMail — Invitation to access a folder
  • FolderFileRequestMail — Request for file upload
  • FolderConfirmationMail — Folder confirmation notification
  • FolderSituationMail — Folder status update
  • FolderTextMessageMail — Text message notification

Frontend Architecture

Component Organization

  • Pages (31 Vue components): Mapped to routes via Inertia, organized by domain (auth, clients, folders, users, workspaces, settings, client portal)
  • Layouts (8 components): AppLayout (sidebar/header variants), AuthLayout (card/simple/split variants), SettingsLayout
  • UI Components: shadcn-vue design system with 20+ component groups (Button, Card, Dialog, Dropdown, Input, Select, Table, Tabs, Tooltip, etc.)
  • Business Components: ClientForm, FolderForm, UserForm, WorkspaceForm, WorkspaceSwitcher, Pagination
  • Composables (4): useAppearance, useCurrentUrl, useInitials, useTwoFactorAuth

State Management

  • No client-side store (Redux/Pinia) — state is server-driven via Inertia props
  • useForm() from Inertia handles form state and submission
  • Composables for shared client-side logic

Type System

  • TypeScript strict mode across all frontend code
  • Type definitions in resources/js/types/ (auth, navigation, UI types)
  • Wayfinder generates typed route functions

Testing Strategy

  • Framework: Pest 4 (PHPUnit 12 compatible)
  • Test Suites: Feature (13 test files) + Unit
  • Coverage Areas: Authentication, settings, dashboard, user groups
  • Factories: Model factories for test data generation
  • CI Matrix: PHP 8.4 and 8.5

CI/CD Pipeline

Lint Workflow (lint.yml)

  • Triggers: push/PR to develop, main, master, workos
  • Steps: PHP setup → Composer install → npm install → Pint → Prettier → ESLint

Test Workflow (tests.yml)

  • Triggers: push/PR to develop, main, master, workos
  • Matrix: PHP 8.4, 8.5
  • Steps: PHP setup → Node 22 → Composer install → npm install → env setup → key generation → Vite build → Pest

Deployment Configuration

Docker Compose (Laravel Sail)

  • laravel.test — PHP 8.5 application container (port 80, Vite 5173)
  • mysql — MySQL 8.4 database (port 3306)
  • mailpit — Email testing UI (ports 1025, 8025)
  • soketi — WebSocket server / Pusher-compatible (port 6001)

SSR Support

  • Inertia SSR is enabled (inertia.phpssr.enabled = true)
  • SSR entry point: resources/js/ssr.ts
  • SSR server URL: http://127.0.0.1:13714