Files
Inventory/CARNET_DE_BORD.md

13 KiB

📔 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


🔗 Convention de liaison des commits (INV)

  • Format : [INV-YYYYMMDD-XX]
  • Usage : même code dans les commits du backend et du frontend + ajout ici pour retrouver le duo rapidement.

🧾 Journal des liaisons INV

  • INV-20260111-01 : ajout du lien submodule Inventory_frontend (commit backend : 987aa5c, commit frontend : 936a73f)
  • INV-20260111-02 : alignement front API Platform + sessions (commit backend : f7fc1bd, commit frontend : e99f053)

🎯 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

# 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 :
    {
      "@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 :
    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 :

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 :
    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

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

# 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


🔄 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)