9.2 KiB
9.2 KiB
CLAUDE.md — Inventory Project
Project Overview
Application de gestion d'inventaire industriel (machines, pièces, composants, produits). Mono-repo avec backend Symfony et frontend Nuxt en submodule git.
Stack
| Layer | Tech | Version |
|---|---|---|
| Backend | Symfony + API Platform | 8.0 / ^4.2 |
| PHP | PHP | >=8.4 |
| Database | PostgreSQL | 16 |
| Frontend | Nuxt (SPA, SSR off) | 4 |
| UI | Vue 3 Composition API + TypeScript | 3.5 / 5.7 |
| CSS | TailwindCSS 4 + DaisyUI 5 | |
| Auth | Session-based (cookies, pas JWT) | |
| Containers | Docker Compose |
Project Structure
Inventory/ # Backend Symfony (repo principal)
├── src/Entity/ # Entités Doctrine (annotations PHP 8 attributes)
├── src/Controller/ # Controllers custom (session, comments, audit…)
├── src/EventSubscriber/ # Audit subscribers (onFlush)
├── config/ # Config Symfony
├── migrations/ # Migrations Doctrine (raw SQL PostgreSQL)
├── docker/ # Dockerfile + .env.docker
├── scripts/ # release.sh, normalize-dump.py
├── fixtures/ # SQL fixtures
├── tests/ # PHPUnit
├── pre-commit, commit-msg # Git hooks
├── makefile # Commandes Docker/dev
├── VERSION # Source unique de version (semver)
├── Inventory_frontend/ # ← SUBMODULE GIT (repo séparé)
│ ├── app/pages/ # Pages Nuxt (file-based routing)
│ ├── app/components/ # Composants Vue (auto-imported)
│ ├── app/composables/ # Composables Vue
│ ├── app/shared/ # Types, utils, validation
│ ├── app/middleware/ # Auth middleware global
│ └── app/services/ # Service layer (wrappers useApi)
Key Commands
# Docker
make start # Démarrer les containers
make stop # Arrêter
make shell # Shell interactif (nécessite un TTY)
make install # Install complet (composer + npm + build)
# Backend
make test # PHPUnit (tous les tests)
make test FILES=tests/Api/Entity/MachineTest.php # Un test spécifique
make php-cs-fixer-allow-risky # Linter PHP (cs-fixer)
docker exec -u www-data php-inventory-apache php bin/console doctrine:migrations:migrate
# Frontend (dans Inventory_frontend/)
npm run dev # Dev server (port 3001)
npm run build # Build production
npm run lint:fix # ESLint fix
npx nuxi typecheck # TypeScript check (0 errors attendu)
# Release
./scripts/release.sh patch # Bump patch version (ou minor/major)
Git Conventions
Branches
master— productiondevelop— branche principale de dev (cible des PR)feat/xxx,fix/xxx,refactor/xxx— branches de travail
Commit Message Format (enforced by hook)
<type>(<scope optionnel>) : <message>
Espace obligatoire autour du :. Types autorisés (minuscules) :
build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test, wip
Exemples :
feat(auth) : add login pagefix(machines) : prevent null crash on skeleton creation
Pre-commit Hook
- php-cs-fixer sur les fichiers PHP stagés
- PHPUnit — bloque le commit si tests échouent
Submodule Workflow
Le frontend est un submodule git. Lors d'un commit frontend :
- Commit dans
Inventory_frontend/d'abord - Commit dans le repo principal pour mettre à jour le pointeur submodule
- Push les deux repos
Architecture Backend
Entités Principales
Machine, Piece, Composant, Product, Constructeur, Site, ModelType, CustomField, CustomFieldValue, Document, AuditLog, Comment, Profile, MachineComponentLink, MachinePieceLink, MachineProductLink
Patterns
- IDs : CUID-like strings (
'cl' + bin2hex(random_bytes(12))), pas d'auto-increment - ORM : Attributs PHP 8 (
#[ORM\Column(...)],#[Groups([...])]) - Lifecycle :
#[ORM\HasLifecycleCallbacks]avecPrePersist/PreUpdatepourcreatedAt/updatedAt - Sécurité :
security: "is_granted('ROLE_...')"sur chaque opération API Platform - Audit : Subscribers Doctrine
onFlushcapturent diff + snapshot complet - Migrations : Raw SQL PostgreSQL avec
IF NOT EXISTS/IF EXISTSpour idempotence
Custom Controllers (pas API Platform)
MachineStructureController—/api/machines/{id}/structure(GET/PATCH) : hiérarchie complète machine avec normalisation JSON manuelle (pas Symfony Serializer). Source principale de données pour la page détail machine.MachineCustomFieldsController—/api/machines/{id}/add-custom-fields(POST) : initialise les CustomFieldValue manquants pour une machine.CustomFieldValueController—/api/custom-fields/values/*: CRUD + upsert pour les valeurs de champs perso.
Custom Fields — Architecture
- Composants/Pièces/Produits : définitions dans le JSON
structuredu ModelType - Machines : définitions = entités
CustomFieldliées directement viamachineIdFK (pas de ModelType) - Les deux partagent la même entité
CustomFieldValuepour stocker les valeurs
Rôles (hiérarchie)
ROLE_ADMIN → ROLE_GESTIONNAIRE → ROLE_VIEWER → ROLE_USER
PostgreSQL — ATTENTION
- Les noms de colonnes sont TOUJOURS EN MINUSCULES dans PG
- Doctrine utilise camelCase (
typePieceId) mais PG stocketypepieceid - Le SQL brut doit utiliser les noms lowercase
- Tables de jointure many-to-many : colonnes
aetb(ex:_piececonstructeurs)
Architecture Frontend
Patterns
- Composables :
interface Deps { ... }+export function useXxx(deps: Deps) - Communication composants : Props + Events uniquement (pas de provide/inject)
- API :
useApi.tswraps fetch aveccredentials: 'include'pour les cookies session - Content-Type :
application/ld+jsonpour POST/PUT,application/merge-patch+jsonpour PATCH - Auth :
useProfileSession+ middleware globalprofile.global.ts - Permissions :
usePermissions.tsmiroir de la hiérarchie backend côté client - Auto-imports : Nuxt auto-importe composants (
components/) et composables (composables/)
DaisyUI Classes
- Input :
input input-bordered input-sm md:input-md - Textarea :
textarea textarea-bordered textarea-sm md:textarea-md - Select :
select select-bordered select-sm md:select-md - Button :
btn btn-sm md:btn-md btn-primary
Règles Importantes
CLAUDE.md — Maintenance obligatoire
- Toujours consulter ce fichier en début de conversation pour respecter les conventions
- Mettre à jour ce fichier quand une nouvelle convention, pattern ou décision architecturale est établie
- Utiliser comme source de vérité pour les commandes, patterns et règles du projet
Toujours faire AVANT de modifier du code
- Lire le fichier avant de l'éditer — ne jamais proposer de changements sur du code non lu
- Comprendre le pattern existant — reproduire le style du fichier (noms, indentation, structure)
- Vérifier les deux repos — un changement peut impacter backend ET frontend
Après chaque modification
- Backend PHP :
make php-cs-fixer-allow-risky - Frontend :
npm run lint:fixpuisnpx nuxi typechecksi fichiers TS modifiés
Ne jamais faire
- Ajouter des features non demandées, du code mort, ou des abstractions prématurées
- Utiliser
provide/inject— le codebase utilise Props + Events - Utiliser JWT/tokens — l'auth est session-based
- Écrire du SQL avec des noms camelCase — PostgreSQL = lowercase
- Committer sans que l'utilisateur le demande explicitement
- Force push sans confirmation explicite
- Modifier la config git
Submodule — Synchronisation
Quand les branches master et develop divergent sur l'un des deux repos, toujours les synchroniser :
- Main repo :
git checkout master && git merge develop && git push - Frontend :
git checkout develop && git merge master && git push(ou l'inverse selon le cas)
Tests
Stack de test
- PHPUnit 12 + API Platform Test (
ApiTestCase) - DAMA DoctrineTestBundle — wrappe chaque test dans une transaction avec rollback automatique (pas de TRUNCATE)
- Base de test : même PG, env
test
Commandes
Voir section "Key Commands". Commande additionnelle :
make test-setup # Créer/mettre à jour le schéma test
Pattern de test
- Hériter de
AbstractApiTestCase(helpers auth + factories) - Ne PAS faire de TRUNCATE/cleanup dans tearDown — DAMA s'en occupe par rollback
- Factories :
createProfile(),createMachine(),createSite(),createComposant(),createPiece(),createProduct(),createCustomField(),createCustomFieldValue(),createModelType(),createMachineComponentLink(),createMachinePieceLink(),createMachineProductLink() - Auth :
createViewerClient(),createGestionnaireClient(),createAdminClient()
URLs Locales
- API Symfony :
http://localhost:8081/api - Nuxt dev :
http://localhost:3001 - Adminer (PG) :
http://localhost:5050 - PG direct :
localhost:5433(user: root, pass: root, db: inventory)