Files
L-Ami-Fiduciaire/_bmad-output/project-context.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

8.0 KiB

project_name, user_name, date, sections_completed, status, rule_count, optimized_for_llm
project_name user_name date sections_completed status rule_count optimized_for_llm
l'ami fiduciaire Saad 2026-03-08
technology_stack
language_rules
framework_rules
testing_rules
code_quality
workflow_rules
critical_rules
complete 52 true

Project Context for AI Agents

This file contains critical rules and patterns that AI agents must follow when implementing code in this project. Focus on unobvious details that agents might otherwise miss.


Technology Stack & Versions

  • Backend: PHP ^8.2, Laravel 12
  • Frontend: Vue 3.5 (<script setup lang="ts">), TypeScript 5.2 (strict mode)
  • Bridge: Inertia.js 2.0 (@inertiajs/vue3 ^2.3.7)
  • Build: Vite 7.0, laravel-vite-plugin 2.0
  • Styling: Tailwind CSS 4.1 (@tailwindcss/vite), shadcn-vue (reka-ui)
  • Auth: Laravel Fortify ^1.30
  • Media: spatie/laravel-medialibrary ^11.21
  • Logging: spatie/laravel-activitylog ^4.12
  • Enums: bensampo/laravel-enum ^6.12
  • Routes: laravel/wayfinder ^0.1.9 (type-safe frontend routes)
  • Icons: lucide-vue-next
  • CSS Utils: clsx + tailwind-merge + CVA via cn() helper
  • Testing: Pest 4.4, Laravel Pint (PHP formatting)
  • JS Tooling: ESLint 9, Prettier 3.4 (with tailwindcss plugin)

Critical Implementation Rules

Language-Specific Rules

TypeScript:

  • Strict mode enabled — never use any implicitly (explicit any allowed per ESLint config)
  • MUST use import type { ... } for type-only imports (separate statements, not inline type specifier)
  • Import order enforced: builtin → external → internal → parent → sibling → index (alphabetical within groups)
  • Path alias @/ maps to resources/js/ — always use it, never relative paths like ../../
  • isolatedModules: true — no const enum, no namespace merging

PHP:

  • Model casts: use protected function casts(): array method, NOT the $casts property
  • Model mass assignment: always use explicit $fillable, never $guarded = []
  • Relationship return types: always add PHPDoc generics /** @return BelongsTo<Model, $this> */
  • Enums: use bensampo/laravel-enum — serialize with ->value, cast in models with Enum class
  • All controller methods must have explicit return type annotations (Response, RedirectResponse)
  • PHP formatting via Laravel Pint — run composer lint before committing

Framework-Specific Rules

Vue 3 + Composition API:

  • Always use <script setup lang="ts"> — never Options API
  • Define props: type Props = { ... } + defineProps<Props>(); use withDefaults() for defaults
  • Export form data types from form components for reuse in page components
  • Composables follow use prefix convention (useCurrentUrl, useInitials)

Inertia.js:

  • ALL URLs must be passed as props from PHP controllers — never hardcode routes in Vue
  • Standard forms: useForm<T>() with form.post(props.storeUrl)
  • File uploads: use <Form> component with enctype="multipart/form-data", NOT useForm
  • Navigation: router.delete(), router.get(), router.post() for programmatic actions
  • Page titles: always use <Head title="..." /> component
  • Shared props accessed via usePage() (e.g., page.props.auth)

Layout System:

  • Pages wrap content in <AppLayout :breadcrumbs="[...]"> — breadcrumbs are required
  • Auth pages use <AuthLayout> wrapper
  • Settings pages use settings/Layout.vue with its own sidebar navigation

Laravel Controllers:

  • Workspace: resolve from session (current_workspace_id), never from URL params
  • Authorization: custom authorizeXxx() protected methods with abort(404), no Gates/Policies
  • Validation: dedicated Form Request classes, never inline $request->validate()
  • Data shaping: manually build arrays in controllers, no API Resources
  • Always pass URLs as props via route() helper (e.g., 'showUrl' => route('clients.show', $client))
  • Single-action controllers use __invoke() method
  • Enum labels: protected methods on controllers returning label arrays

Testing Rules

  • Use Pest syntax (test() closures), never PHPUnit class-based tests
  • Feature tests: RefreshDatabase is auto-applied via Pest.php — don't add it manually
  • Test descriptions: lowercase, descriptive strings ('authenticated users can visit the dashboard')
  • Assertions: prefer Pest's expect() chaining over PHPUnit assert*() methods
  • Use route() helper for URLs in tests, never hardcoded paths
  • Feature tests grouped by domain subdirectory mirroring controller structure
  • Factory states for user roles: User::factory()->admin()->create()
  • Run tests: composer test (clears config, runs Pint lint check, then php artisan test)
  • No frontend JS tests configured — testing is PHP-only

Code Quality & Style Rules

Prettier (enforced):

  • Semicolons, single quotes, 4-space indentation, 80 char print width
  • Tailwind plugin sorts classes in clsx, cn, cva calls
  • YAML files use 2-space indentation (override)

ESLint:

  • vue/multi-word-component-names is OFF — single-word names allowed
  • resources/js/components/ui/* is ignored — never lint or modify shadcn-vue components
  • Run npm run lint to fix, npm run format to format

File Naming:

  • Vue pages/components: PascalCase (ClientForm.vue, Index.vue)
  • Vue page subdirectories: lowercase by domain (clients/, folders/, auth/)
  • UI component subdirectories: kebab-case (dropdown-menu/, input-otp/)
  • TypeScript type files: lowercase (auth.ts, navigation.ts)
  • Composables: use prefix camelCase (useCurrentUrl.ts)
  • Each UI component group has an index.ts barrel file

Code Organization:

  • Pages: resources/js/pages/{domain}/{Action}.vue
  • Components: resources/js/components/ (app-level) and components/ui/ (shadcn-vue)
  • Types: resources/js/types/ with barrel index.ts
  • Composables: resources/js/composables/
  • Lib utilities: resources/js/lib/utils.ts (cn() helper)

Development Workflow Rules

Local Development:

  • Start all services: composer dev (runs server + queue + logs + Vite concurrently)
  • SSR mode: composer dev:ssr
  • Initial setup: composer setup

CI/CD (GitHub Actions):

  • lint workflow: Pint + Prettier + ESLint on push/PR to develop, main, master
  • tests workflow: Pest on PHP 8.4/8.5 matrix with Node 22
  • All code must pass both workflows before merging

Before Committing:

  • PHP: composer lint (Pint)
  • JS/Vue: npm run format then npm run lint
  • Tests: composer test

Critical Don't-Miss Rules

Never Do:

  • Never modify resources/js/components/ui/* — shadcn-vue auto-generated, use npx shadcn-vue to update
  • Never hardcode routes in Vue — all URLs come from PHP controller props
  • Never use $guarded = [] — always explicit $fillable
  • Never use inline $request->validate() — always Form Request classes
  • Never use Gates/Policies — use custom authorizeXxx() protected methods with abort(404)
  • Never add RefreshDatabase in tests — auto-applied via Pest.php

Gotchas:

  • Workspace is session-based (current_workspace_id) — not in URL, not route-model-bound
  • Nullable enums: use $model->field?->value (null-safe) when serializing
  • Authorization returns 404 not 403 for workspace boundary violations (intentional)
  • Client-facing routes (/c/*) use token-based folder.invitation middleware, not auth
  • New business models must add Spatie LogsActivity trait + getActivitylogOptions() returning logFillable()->logOnlyDirty()->dontSubmitEmptyLogs()
  • New models with files must add Spatie InteractsWithMedia trait and implement HasMedia
  • Inertia render paths use lowercase subdirectory: 'clients/Index', not 'Clients/Index'

Usage Guidelines

For AI Agents:

  • Read this file before implementing any code
  • Follow ALL rules exactly as documented
  • When in doubt, prefer the more restrictive option
  • Update this file if new patterns emerge

For Humans:

  • Keep this file lean and focused on agent needs
  • Update when technology stack changes
  • Review quarterly for outdated rules
  • Remove rules that become obvious over time

Last Updated: 2026-03-08