147 lines
9.1 KiB
Markdown
147 lines
9.1 KiB
Markdown
# CLAUDE.md — Inventory Project
|
|
|
|
Application de gestion d'inventaire industriel (machines, pièces, composants, produits).
|
|
**Monorepo** : backend Symfony + frontend Nuxt (`frontend/`) dans le **même dépôt git** (plus de submodule). Un seul commit/push couvre backend + frontend.
|
|
|
|
## 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 | |
|
|
|
|
## Documentation détaillée (lire à la demande, ne pas dupliquer ici)
|
|
|
|
Vu la complexité du projet, le détail vit dans `docs/` — y aller plutôt que de deviner :
|
|
|
|
- **`docs/FONCTIONNEMENT.md`** — le métier : à quoi sert l'app, entités, ModelType/skeleton, cycle de vie, rôles, fonctionnalités clés.
|
|
- **`docs/GLOSSAIRE_METIER.md`** — glossaire complet, correspondance métier ↔ code (le « pourquoi »).
|
|
- **`docs/BACKEND.md`** — catalogue backend complet : toutes les entités, **tous les controllers** (routes), audit, services, migrations, auth, rôles.
|
|
- **`docs/FRONTEND.md`** — catalogue frontend : composables, composants, useApi, IRIs, content-types, auth, style.
|
|
- **`docs/REVIEW_ARCHITECTURE.md`** — top 10 des sources de complexité et effets de bord (God controllers, canaux cachés, doubles flush…). **À consulter avant tout refacto.**
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
Inventory/ # Backend Symfony (repo principal)
|
|
├── src/Entity/ (+ Trait/) # Entités Doctrine (attributs PHP 8), CuidEntityTrait
|
|
├── src/Controller/ # Controllers custom (session, comments, audit, structure…)
|
|
├── src/EventSubscriber/ # Audit (onFlush) + sync/contraintes
|
|
├── src/Service/ (+ Sync/) # Services métier (sync, conversion, storage, versions…)
|
|
├── src/Enum/ src/DTO/ src/Filter/ src/Command/
|
|
├── config/ migrations/ docker/ scripts/ fixtures/ tests/
|
|
├── makefile VERSION # VERSION = source unique de version (semver)
|
|
└── frontend/ # ← Frontend Nuxt (MÊME repo, pas un submodule)
|
|
└── app/{pages,components,composables,shared,middleware,services}/
|
|
```
|
|
|
|
## Key Commands
|
|
|
|
```bash
|
|
# Docker
|
|
make start / make stop # Démarrer / arrêter les containers
|
|
make shell # Shell interactif (nécessite un TTY)
|
|
make install # Install complet (composer + npm + build)
|
|
|
|
# Backend
|
|
make test # PHPUnit (tous)
|
|
make test FILES=tests/Api/Entity/MachineTest.php # Un test
|
|
make test-setup # Créer/MAJ le schéma de test
|
|
make php-cs-fixer-allow-risky # Linter PHP
|
|
docker exec -u www-data php-inventory-apache php bin/console doctrine:migrations:migrate
|
|
|
|
# Frontend (dans frontend/)
|
|
npm run dev # Dev server (port 3001)
|
|
npm run lint:fix # ESLint fix
|
|
npx nuxi typecheck # TypeScript check (0 erreur attendu)
|
|
|
|
# Database / Fixtures
|
|
make db-reset # Reset DB (drop + recreate schema)
|
|
make fixtures-reset # Reset DB + recharger fixtures SQL
|
|
make import-data # Importer les dumps SQL normalisés
|
|
make cache-clear
|
|
|
|
# Import fournisseurs (non destructif : find-or-create par nom normalisé)
|
|
docker exec -u www-data php-inventory-apache php bin/console app:import-fournisseurs # dry-run
|
|
docker exec -u www-data php-inventory-apache php bin/console app:import-fournisseurs --force # applique
|
|
|
|
# Release
|
|
./scripts/release.sh patch # Bump version (patch/minor/major)
|
|
```
|
|
|
|
## Git Conventions
|
|
|
|
- **Branches** : `master` (prod), `develop` (cible des PR), `feat/* fix/* refactor/*`.
|
|
- **Commit** (enforced par hook) : `<type>(<scope>) : <message>` — **espace obligatoire autour du `:`**. Types : `build chore ci docs feat fix perf refactor revert style test wip`.
|
|
- Ex : `feat(auth) : add login page`, `fix(machines) : prevent null crash`
|
|
- **Pre-commit hook** : php-cs-fixer + PHPUnit (bloque si échec).
|
|
- **Workflow commit** : backend + frontend = **un seul commit/push** depuis la racine (pas de submodule). Le hook étant lent, committer avec `git commit --no-verify`. Push rejeté → `git pull --rebase` puis `git push`.
|
|
- **Sync master ↔ develop** : `git checkout master && git merge develop && git push` puis revenir sur `develop`.
|
|
|
|
## Pièges & patterns non-évidents
|
|
|
|
> Le catalogue complet est dans `docs/BACKEND.md` / `docs/FRONTEND.md`. Ci-dessous **uniquement** ce qui n'est pas évident en lisant le code.
|
|
|
|
### Backend
|
|
- **IDs CUID** : strings `'cl' + bin2hex(random_bytes(12))`, **pas** d'auto-increment.
|
|
- **Lifecycle** : `#[ORM\HasLifecycleCallbacks]` + `PrePersist`/`PreUpdate` pour `createdAt`/`updatedAt`.
|
|
- **Sécurité** : `security: "is_granted('ROLE_...')"` sur chaque opération API Platform. Hiérarchie : `ROLE_ADMIN → ROLE_GESTIONNAIRE → ROLE_VIEWER → ROLE_USER`.
|
|
- **Audit** : subscribers Doctrine `onFlush` (diff + snapshot complet).
|
|
- **Migrations** : raw SQL PostgreSQL avec `IF NOT EXISTS`/`IF EXISTS` (idempotence).
|
|
- **Constructeur (Fournisseur)** : collection `telephones` (1-N, cascade/orphanRemoval) + `categories` (M2M, table `constructeur_categories`). ⚠️ L'adder M2M est `addCategory()`/`removeCategory()` (l'inflector singularise `categories` → `category`), **pas** `addCategorie`. Groupes API `constructeur:read` / `constructeur:write`.
|
|
- **Normalisation slots/skeleton** : les anciennes colonnes JSON `structure`/`productIds` sont remplacées par des tables relationnelles — slots réels (`ComposantPieceSlot`, `ComposantSubcomponentSlot`, `ComposantProductSlot`, `PieceProductSlot`) vs définitions ModelType (`SkeletonPieceRequirement`, `SkeletonProductRequirement`, `SkeletonSubcomponentRequirement`).
|
|
- **Custom Fields** : Composants/Pièces/Produits → définitions dans les `Skeleton*Requirement` du ModelType (clé `customFields` JSON) ; Machines → entités `CustomField` liées par `machineId` FK (pas de ModelType). Les deux partagent l'entité `CustomFieldValue` pour les valeurs.
|
|
- **`MachineStructureController`** (`/api/machines/{id}/structure`, `/clone`) : source principale de données de la page détail machine (normalisation JSON manuelle). Cf. `REVIEW_ARCHITECTURE.md` (God controller).
|
|
|
|
### PostgreSQL — ATTENTION
|
|
- Noms de colonnes **TOUJOURS EN MINUSCULES** en PG. Doctrine camelCase (`typePieceId`) → PG `typepieceid`. Le **SQL brut doit être lowercase**.
|
|
- Tables de jointure M2M : colonnes `a` et `b` (ex : `_piececonstructeurs`).
|
|
|
|
### Frontend
|
|
- **Composables** : `interface Deps { ... }` + `export function useXxx(deps: Deps)`.
|
|
- **Communication composants** : Props + Events uniquement (**pas** de provide/inject).
|
|
- **API** : `useApi.ts` wrappe fetch avec `credentials: 'include'`. ⚠️ `useApi()` **préfixe déjà** `/api` → appeler **sans** `/api` au début. Ex : `api.get('/custom-fields/names')` **et PAS** `'/api/custom-fields/names'` (sinon 404 sur `/api/api/...`).
|
|
- **Content-Type** : `application/ld+json` (POST/PUT), `application/merge-patch+json` (PATCH).
|
|
- **Auth** : `useProfileSession` + middleware global `profile.global.ts`. Permissions : `usePermissions.ts` (miroir de la hiérarchie backend).
|
|
- **Classes DaisyUI** : `input input-bordered input-sm md:input-md` (idem textarea/select/btn, `btn-primary`).
|
|
|
|
## Règles Importantes
|
|
|
|
### Avant de modifier du code
|
|
1. **Lire le fichier** avant de l'éditer.
|
|
2. **Reproduire le pattern existant** (noms, indentation, structure).
|
|
3. **Vérifier backend ET frontend** — un changement peut impacter les deux (même repo).
|
|
|
|
### Après chaque modification
|
|
1. Backend PHP : `make php-cs-fixer-allow-risky`
|
|
2. Frontend TS : `npm run lint:fix` puis `npx nuxi typecheck`
|
|
|
|
### Ne jamais faire
|
|
- Features non demandées, code mort, abstractions prématurées
|
|
- `provide/inject` (le code utilise Props + Events) · JWT/tokens (auth session-based)
|
|
- SQL en camelCase (PG = lowercase)
|
|
- Committer sans demande explicite · force push sans confirmation · modifier la config git
|
|
|
|
### Maintenir ce fichier
|
|
Mettre à jour quand une nouvelle convention/pattern/décision archi est établie. Source de vérité pour commandes, pièges et règles ; le **détail** descriptif va dans `docs/`.
|
|
|
|
## Tests
|
|
|
|
- **PHPUnit 12** + **API Platform Test** (`ApiTestCase`), env `test`, même PG.
|
|
- **DAMA DoctrineTestBundle** : chaque test wrappé en transaction + rollback auto → **ne PAS** faire de TRUNCATE/cleanup en `tearDown`.
|
|
- Hériter de `AbstractApiTestCase` (helpers auth + factories `create*()`).
|
|
- Auth : `createViewerClient()`, `createGestionnaireClient()`, `createAdminClient()`, `createUnauthenticatedClient()`.
|
|
|
|
## URLs Locales
|
|
- API Symfony : `http://localhost:8081/api` · Nuxt dev : `http://localhost:3001`
|
|
- Adminer : `http://localhost:5050` · PG direct : `localhost:5433` (user/pass `root`, db `inventory`)
|
|
|
|
## Délégation Codex
|
|
Pour les tâches mécaniques (tests, boilerplate, renommages, refacto répétitif), déléguer à Codex via le plugin `codex` (junior rapide/pas cher). Garder Claude pour la réflexion, l'architecture et la vérification (senior). Meilleur ratio qualité/crédits.
|