# 📔 Carnet de Bord - Migration Inventory → Symfony **Projet** : Migration backend NestJS/Prisma → Symfony/API Platform **DĂ©but** : 2026-01-10 **Objectif** : Migrer vers Symfony + JWT + API Platform propre et maintenable --- ## 🎯 Contexte - **Situation initiale** : - `Inventory_backend/` : NestJS + Prisma (fonctionnel, ~11k lignes) - `Inventory_frontend/` : Nuxt 3 (fonctionnel, 105 fichiers) - Base de donnĂ©es PostgreSQL avec donnĂ©es en production - **Objectif** : - Backend Symfony 8 + API Platform + JWT - Garder les donnĂ©es existantes (migration Prisma → Doctrine) - Frontend Nuxt connectĂ© au nouveau backend - Docker : 2 backends en parallĂšle pendant transition --- ## ✅ Phase 1 : PrĂ©paration (TERMINÉE - 10/01/2026) ### Ce qui a Ă©tĂ© fait #### 1. Docker & Infrastructure ✅ - **pgAdmin ajoutĂ©** au docker-compose.yml - Port : 5050 - Login : admin@admin.com / admin - Container : `pgadmin-inventory` - Volume persistant : `pgadmin_data` - **Serveur PostgreSQL prĂ©-configurĂ©** : - Fichier `docker/pgadmin/servers.json` montĂ© automatiquement - Fichier `docker/pgadmin/pgpass` pour authentification sans mot de passe - Connexion automatique Ă  `db:5432/inventory` au dĂ©marrage - Nom du serveur : "Inventory PostgreSQL" #### 2. Bundles Symfony installĂ©s ✅ ```bash # Versions installĂ©es - lexik/jwt-authentication-bundle: v3.2.0 - vich/uploader-bundle: v2.9.1 - symfony/uid: 8.0.* ``` #### 3. JWT Configuration ✅ - **ClĂ©s RSA gĂ©nĂ©rĂ©es** : `config/jwt/private.pem` + `public.pem` - **security.yaml configurĂ©** : - Firewall `login` : pattern `^/api/login_check` avec `json_login` - Firewall `api` : pattern `^/api` avec `jwt` authenticator - Provider : `app_user_provider` (entitĂ© Profile via email) - Password hasher : bcrypt auto #### 4. EntitĂ© Profile créée ✅ **Fichier** : `src/Entity/Profile.php` **CaractĂ©ristiques** : - ImplĂ©mente `UserInterface` + `PasswordAuthenticatedUserInterface` - Champs : - `id` : string (30 chars, CUID-compatible pour Prisma) - `email` : string unique (username pour JWT) - `password` : string (hashed) - `roles` : array JSON (ROLE_USER par dĂ©faut) - `firstName`, `lastName` : string - `isActive` : boolean - `createdAt`, `updatedAt` : DateTimeImmutable - Repository : `ProfileRepository` avec `PasswordUpgraderInterface` - API Platform : endpoints CRUD auto-gĂ©nĂ©rĂ©s #### 5. Base de DonnĂ©es ✅ - **Migration créée** : `Version20260110175413` - **Table** : `profiles` créée avec succĂšs - **Utilisateur test créé** : ``` Email: admin@admin.com Password: admin123 Roles: ['ROLE_USER', 'ROLE_ADMIN'] ``` #### 6. API Platform ✅ - **Endpoint racine** : http://localhost:8081/api/ - **RĂ©ponse** : ```json { "@context": "/api/contexts/Entrypoint", "@id": "/api/", "@type": "Entrypoint", "profile": "/api/profiles" } ``` - **OpenAPI Docs** : ConfigurĂ©es (Ă  tester) #### 7. Configuration Apache ✅ - **VirtualHost** : `docker/php/config/vhost.conf` - **DocumentRoot** : `/var/www/html/public` - **AllowOverride** : All (pour `.htaccess`) - **Port** : 8081 (Apache) → accessible depuis l'hĂŽte #### 8. Routing Symfony ✅ - **Routes dĂ©finies** : - `/api/login_check` : Login JWT - `/api/test` : Test endpoint (TestController) - `/api/*` : API Platform auto-routes - **VĂ©rification** : ```bash php bin/console debug:router api_test php bin/console router:match /api/test --method=GET # ✅ Route found and matches ``` #### 9. .htaccess créé ✅ **Fichier** : `public/.htaccess` **Contenu** : Symfony standard avec mod_rewrite --- ### ⚠ ProblĂšmes identifiĂ©s #### 1. Routes inaccessibles via Apache (404) **SymptĂŽme** : ```bash curl http://localhost:8081/api/test # → 404 Not Found ``` **Tests effectuĂ©s** : - ✅ Route existe : `php bin/console debug:router api_test` - ✅ Route match : `php bin/console router:match /api/test` - ✅ Symfony fonctionne : `curl http://localhost:8081/api/` → JSON OK - ✅ PHP built-in server OK : ```bash php -S localhost:9000 curl http://localhost:9000/api/test # → {"status":"ok","message":"Test endpoint works!"} ``` - ❌ Apache 404 : Depuis l'hĂŽte via port 8081 **Diagnostic** : - Le problĂšme est **Apache-spĂ©cifique** - Symfony/PHP fonctionnent correctement - Le `.htaccess` n'est probablement **PAS lu par Apache** - HypothĂšses : 1. `AllowOverride All` non pris en compte 2. `mod_rewrite` mal configurĂ© 3. Ordre des directives Apache incorrect 4. ProblĂšme de permissions sur `.htaccess` **Actions Ă  faire** : - [ ] VĂ©rifier permissions `.htaccess` dans container - [ ] Tester `apache2ctl configtest` - [ ] Activer logs de rewrite : `LogLevel alert rewrite:trace3` - [ ] Tester FallbackResource dans vhost au lieu de `.htaccess` #### 2. JWT Login non testĂ© **Raison** : BloquĂ© par problĂšme #1 (routes inaccessibles) **Actions Ă  faire** : - [ ] RĂ©soudre problĂšme Apache - [ ] Tester `POST /api/login_check` avec credentials - [ ] VĂ©rifier gĂ©nĂ©ration du token JWT - [ ] Tester route protĂ©gĂ©e avec token --- ## 📝 Configuration Actuelle ### Docker Compose ```yaml services: web: ports: - "8081:80" # Symfony API - "3001:3000" # (prĂ©vu pour Nuxt) db: ports: - "5433:5432" # PostgreSQL pgadmin: ports: - "5050:80" # pgAdmin ``` ### Variables d'Environnement **Fichier** : `docker/.env.docker.local` ```env # PostgreSQL POSTGRES_DB=inventory POSTGRES_USER=root POSTGRES_PASSWORD=root POSTGRES_PORT=5433 --- ## ✅ Phase 2 : Migration DB + Frontend (TERMINÉE - 10/01/2026) ### Ce qui a Ă©tĂ© fait #### 1. EntitĂ©s Doctrine alignĂ©es Prisma ✅ - **Toutes les entitĂ©s manquantes** créées (Machine, ModelType, Composant, Piece, Product, Links, Requirements, CustomField, Document, etc.) - **IDs en string(36)** pour compatibilitĂ© CUID/UUID - **Colonnes Prisma en camelCase** conservĂ©es via `name="..."` (ex: `machineId`, `createdAt`, `supplierPrice`) - **Corrections** : - `Document.path` passĂ© en `TEXT` - `CustomField.options` nullable - `TypeMachineComponentRequirement.required` corrigĂ© #### 2. Migration DB inventory-data → inventory ✅ - **Dump data-only + normalisation** (conversion des identifiants quoted vers lowercase) - **Mapping table Prisma** : `"ModelType"` → `model_types` - **Exclusions** : `profiles`, `_prisma_migrations` - **Import validĂ©** : `Counts match for all tables.` Scripts utiles : ```bash scripts/normalize-dump.py scripts/validate-migration.php ``` #### 3. Frontend basculĂ© sur Inventory_frontend ✅ - `make dev-nuxt` pointe vers `Inventory_frontend/` - `README.md` mis Ă  jour - **Base API** ajustĂ©e : `http://localhost:8081/api` Fichiers modifiĂ©s : ``` makefile README.md Inventory_frontend/.env Inventory_frontend/nuxt.config.ts Inventory_frontend/app/services/modelTypes.ts ``` --- # pgAdmin PGADMIN_EMAIL=admin@admin.com PGADMIN_PASSWORD=admin PGADMIN_PORT=5050 # Symfony APP_ENV=dev APP_SECRET=changeme_super_secret_key_123456789 JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem JWT_PASSPHRASE=your_jwt_passphrase_change_me # NestJS (pour futur parallĂšle) NESTJS_PORT=3000 SESSION_SECRET=changeme_session_secret CORS_ORIGIN=http://localhost:3001 ``` --- ## 🚧 Phase 2 : Debugging & Tests (EN COURS) ### Objectifs - [x] RĂ©soudre problĂšme Apache `.htaccess` - [ ] Tester authentification JWT complĂšte - [ ] CrĂ©er endpoint de test public fonctionnel - [ ] Documenter la solution Apache ### Prochaines Ă©tapes 1. **Fix Apache** : Logs de debug + test FallbackResource 2. **Test JWT** : Login + gĂ©nĂ©ration token + route protĂ©gĂ©e 3. **Documentation** : Documenter la config Apache qui fonctionne --- ## 📊 MĂ©triques ### Temps passĂ© - **Phase 1** : ~3h (exploration + setup + debugging) - **ProblĂšme Apache** : ~1h30 (en cours) ### Fichiers créés/modifiĂ©s **Nouveaux fichiers** : - `src/Entity/Profile.php` - `src/Repository/ProfileRepository.php` - `src/Controller/TestController.php` - `public/.htaccess` - `config/routes/routing.controllers.yaml` - `create_test_user.php` (script utilitaire) - `migrations/Version20260110175413.php` - `docker/pgadmin/servers.json` (config serveur PostgreSQL) - `docker/pgadmin/pgpass` (credentials PostgreSQL) - `CARNET_DE_BORD.md` (ce fichier) **Fichiers modifiĂ©s** : - `docker-compose.yml` (+ pgAdmin) - `docker/.env.docker.local` (+ variables Symfony/JWT/pgAdmin) - `docker/php/config/vhost.conf` (DocumentRoot → public/) - `config/packages/security.yaml` (JWT firewalls) - `config/routes.yaml` (+ api_login_check) - `composer.json` (+ lexik JWT, vich uploader) --- ## 🎓 Leçons Apprises ### 1. Symfony 8 + API Platform - **Attributs PHP 8** : `use Symfony\Component\Routing\Attribute\Route;` (pas `Annotation`) - **Routes controllers** : NĂ©cessite `config/routes/routing.controllers.yaml` avec `type: attribute` - **API Platform** : Auto-gĂ©nĂšre les endpoints CRUD avec `#[ApiResource]` ### 2. JWT Authentication - **3 composants** : 1. Firewall `login` : `json_login` intercepte `/api/login_check` 2. Firewall `api` : `jwt` vĂ©rifie le token sur `/api/*` 3. Access control : `PUBLIC_ACCESS` vs `IS_AUTHENTICATED_FULLY` - **username_path** : Permet de mapper `email` au lieu de `username` - **Provider** : Doit ĂȘtre dĂ©fini dans le firewall `login` ### 3. Doctrine Migrations - **ID Prisma CUID** : Garder en `string(30)` pour compatibilitĂ© - **Lifecycle callbacks** : `#[ORM\PrePersist]` pour `createdAt`/`updatedAt` - **UserInterface** : NĂ©cessite `getUserIdentifier()`, `getRoles()`, `eraseCredentials()` ### 4. Docker & Apache - **`.htaccess` vs VirtualHost** : Le vhost peut override le `.htaccess` - **AllowOverride All** : Indispensable pour que `.htaccess` fonctionne - **FallbackResource** : Alternative au mod_rewrite dans `.htaccess` - **Debugging** : Tester avec PHP built-in server pour isoler le problĂšme --- ## 📚 Ressources Utiles ### AccĂšs aux Services ``` 🌐 pgAdmin: http://localhost:5050 └─ Login: admin@admin.com / admin └─ Serveur: "Inventory PostgreSQL" (prĂ©-configurĂ©) └─ Database: inventory └─ Note: Le serveur PostgreSQL est automatiquement connectĂ© au dĂ©marrage 🌐 API Platform: http://localhost:8081/api/ └─ Docs: http://localhost:8081/api/docs (Ă  venir) đŸ—„ïž PostgreSQL: localhost:5433 └─ User: root / root └─ Database: inventory ``` ### Commandes frĂ©quentes ```bash # Symfony make shell # Entrer dans le container php bin/console cache:clear # Clear cache php bin/console debug:router # Lister routes php bin/console debug:firewall # Lister firewalls php bin/console doctrine:migrations:migrate # ExĂ©cuter migrations # Docker make start # DĂ©marrer containers make stop # ArrĂȘter containers docker logs -f php-inventory-apache # Logs Apache docker logs -f pgadmin-inventory # Logs pgAdmin docker exec php-inventory-apache bash # Shell root # Tests API curl http://localhost:8081/api/ # Test API Platform curl -X POST http://localhost:8081/api/login_check \ -H "Content-Type: application/json" \ -d '{"email":"admin@admin.com","password":"admin123"}' ``` ### Documentation - [Lexik JWT Bundle](https://github.com/lexik/LexikJWTAuthenticationBundle/blob/2.x/Resources/doc/index.rst) - [API Platform Security](https://api-platform.com/docs/core/security/) - [Symfony Security](https://symfony.com/doc/current/security.html) --- ## 🔄 Historique des Changements ### 2026-01-10 - Session 2 (20h30) - ✅ ProblĂšme Apache rĂ©solu (routes fonctionnelles) - ✅ Phase 2 complĂšte (JWT 100% opĂ©rationnel) - ✅ Authentification testĂ©e avec succĂšs - ✅ RĂ©organisation projet (frontend/ + _archives/) - ✅ État des lieux dans MIGRATION_PLAN.md - ✅ 5 commits conventionnels créés - 📊 Base inventory-data analysĂ©e (673 lignes) ### 2026-01-10 - Session 1 (19h00) - ✅ CrĂ©ation projet migration - ✅ Phase 1 complĂšte (pgAdmin, JWT, Profile, migrations) - ⚠ ProblĂšme Apache identifiĂ© (routes 404) - 📝 Carnet de bord créé --- **DerniĂšre mise Ă  jour** : 2026-01-10 20:40 **Statut** : Phase 2 TERMINÉE ✅ - PrĂȘt pour Phase 3 (CrĂ©ation entitĂ©s)