Files
Inventory/CLAUDE.md
2026-03-03 10:13:45 +01:00

169 lines
7.0 KiB
Markdown

# 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
```bash
# Docker
make start # Démarrer les containers
make stop # Arrêter
make shell # Shell dans le container PHP
make install # Install complet (composer + npm + build)
# Backend
make test # PHPUnit
docker compose exec php vendor/bin/php-cs-fixer fix # Linter PHP
docker compose exec php 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` — production
- `develop` — 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 page`
- `fix(machines) : prevent null crash on skeleton creation`
### Pre-commit Hook
1. php-cs-fixer sur les fichiers PHP stagés
2. PHPUnit — bloque le commit si tests échouent
### Submodule Workflow
Le frontend est un submodule git. Lors d'un commit frontend :
1. Commit dans `Inventory_frontend/` d'abord
2. Commit dans le repo principal pour mettre à jour le pointeur submodule
3. Push les deux repos
## Architecture Backend
### Entités Principales
`Machine`, `Piece`, `Composant`, `Product`, `Constructeur`, `Site`, `TypeMachine`, `ModelType`, `CustomField`, `CustomFieldValue`, `Document`, `AuditLog`, `Comment`, `Profile`
### Patterns
- **IDs** : CUID-like strings (`'cl' + bin2hex(random_bytes(12))`), pas d'auto-increment
- **ORM** : Attributs PHP 8 (`#[ORM\Column(...)]`, `#[Groups([...])]`)
- **Lifecycle** : `#[ORM\HasLifecycleCallbacks]` avec `PrePersist`/`PreUpdate` pour `createdAt`/`updatedAt`
- **Sécurité** : `security: "is_granted('ROLE_...')"` sur chaque opération API Platform
- **Audit** : Subscribers Doctrine `onFlush` capturent diff + snapshot complet
- **Migrations** : Raw SQL PostgreSQL avec `IF NOT EXISTS`/`IF EXISTS` pour idempotence
### 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 stocke `typepieceid`
- Le SQL brut doit utiliser les noms lowercase
- Tables de jointure many-to-many : colonnes `a` et `b` (ex: `_piececonstructeurs`)
## Architecture Frontend
### Patterns
- **Composables** : `interface Deps { ... }` + `export function useXxx(deps: Deps)`
- **Communication composants** : Props + Events uniquement (pas de provide/inject)
- **API** : `useApi.ts` wraps fetch avec `credentials: 'include'` pour les cookies session
- **Content-Type** : `application/ld+json` pour POST/PUT, `application/merge-patch+json` pour PATCH
- **Auth** : `useProfileSession` + middleware global `profile.global.ts`
- **Permissions** : `usePermissions.ts` miroir 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
### Toujours faire AVANT de modifier du code
1. **Lire le fichier** avant de l'éditer — ne jamais proposer de changements sur du code non lu
2. **Comprendre le pattern existant** — reproduire le style du fichier (noms, indentation, structure)
3. **Vérifier les deux repos** — un changement peut impacter backend ET frontend
### Après chaque modification
1. Backend PHP : `docker compose exec php vendor/bin/php-cs-fixer fix`
2. Frontend : `npm run lint:fix` puis `npx nuxi typecheck` si 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)
## 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)