[BE-SEC-001] security: Fix ownership verification for user profile updates
- Verified RequireOwnershipOrAdmin middleware is correctly applied to PUT /users/:id - Added integration tests for ownership verification - Test: user cannot update another user's profile (403 Forbidden) - Test: admin can update any profile (200 OK) - Test: user can update own profile (200 OK) - All tests pass Phase: PHASE-1 Priority: P0 Progress: 1/267 (0.4%)
This commit is contained in:
parent
37120e8dd1
commit
b9821db707
7 changed files with 12301 additions and 0 deletions
628
VEZA_COMPLETE_AUDIT_PROMPT.md
Normal file
628
VEZA_COMPLETE_AUDIT_PROMPT.md
Normal file
|
|
@ -0,0 +1,628 @@
|
||||||
|
# VEZA Complete MVP Audit & Todolist Generator
|
||||||
|
|
||||||
|
## 🎯 Mission
|
||||||
|
|
||||||
|
Tu es un agent d'audit exhaustif. Ta mission est de scanner **l'intégralité** du codebase Veza et générer une **todolist de 200+ tâches** couvrant tout ce qui est nécessaire pour atteindre un **MVP stable prêt pour la production à petite échelle**.
|
||||||
|
|
||||||
|
**RÈGLE ABSOLUE** : Ne JAMAIS ignorer, skipper ou supprimer une feature/route/fonction. Si quelque chose existe côté frontend mais pas backend (ou inversement), **AJOUTE UNE TÂCHE** pour l'implémenter. L'objectif est la **progression**, pas la régression ni la stagnation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Répertoires à Scanner
|
||||||
|
|
||||||
|
```
|
||||||
|
veza/
|
||||||
|
├── apps/web/ # Frontend React/TypeScript (SCAN COMPLET)
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── components/ # Composants UI
|
||||||
|
│ │ ├── features/ # Features par domaine
|
||||||
|
│ │ ├── hooks/ # Custom hooks
|
||||||
|
│ │ ├── pages/ # Pages/routes
|
||||||
|
│ │ ├── services/ # Services API
|
||||||
|
│ │ ├── stores/ # State management
|
||||||
|
│ │ ├── types/ # Types TypeScript
|
||||||
|
│ │ ├── utils/ # Utilitaires
|
||||||
|
│ │ └── schemas/ # Validation Zod
|
||||||
|
│ ├── public/
|
||||||
|
│ └── tests/
|
||||||
|
│
|
||||||
|
├── veza-backend-api/ # Backend Go/Gin (SCAN COMPLET)
|
||||||
|
│ ├── cmd/ # Entry points
|
||||||
|
│ ├── internal/
|
||||||
|
│ │ ├── api/ # Routes & handlers
|
||||||
|
│ │ ├── config/ # Configuration
|
||||||
|
│ │ ├── dto/ # Data Transfer Objects
|
||||||
|
│ │ ├── middleware/ # Middlewares
|
||||||
|
│ │ ├── models/ # Database models
|
||||||
|
│ │ ├── repository/ # Data access
|
||||||
|
│ │ ├── services/ # Business logic
|
||||||
|
│ │ └── errors/ # Error handling
|
||||||
|
│ └── migrations/
|
||||||
|
│
|
||||||
|
├── veza-common/ # Shared code (SI EXISTE)
|
||||||
|
├── veza-chat-server/ # Chat server Rust (SI EXISTE)
|
||||||
|
├── veza-stream-server/ # Streaming server (SI EXISTE)
|
||||||
|
├── docker-compose*.yml # Infrastructure
|
||||||
|
└── docs/ # Documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 Protocole d'Audit Exhaustif
|
||||||
|
|
||||||
|
### ÉTAPE 1 : Cartographie du Frontend (apps/web/)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1.1 Lister TOUTES les routes/pages
|
||||||
|
find apps/web/src/pages apps/web/src/features/*/pages -name "*.tsx" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.2 Lister TOUS les services API
|
||||||
|
find apps/web/src/services apps/web/src/features/*/services -name "*.ts" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.3 Lister TOUS les appels API
|
||||||
|
grep -rn "apiClient\.\|axios\.\|fetch(" apps/web/src/ --include="*.ts" --include="*.tsx"
|
||||||
|
|
||||||
|
# 1.4 Lister TOUS les types/interfaces
|
||||||
|
find apps/web/src/types apps/web/src/features/*/types -name "*.ts" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.5 Lister TOUS les stores (state management)
|
||||||
|
find apps/web/src/stores apps/web/src/features/*/stores -name "*.ts" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.6 Lister TOUS les hooks custom
|
||||||
|
find apps/web/src/hooks apps/web/src/features/*/hooks -name "*.ts" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.7 Lister TOUS les composants
|
||||||
|
find apps/web/src/components apps/web/src/features/*/components -name "*.tsx" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.8 Lister TOUS les schemas de validation
|
||||||
|
find apps/web/src/schemas apps/web/src/features/*/schemas -name "*.ts" 2>/dev/null
|
||||||
|
|
||||||
|
# 1.9 Lister les tests existants
|
||||||
|
find apps/web/src -name "*.test.ts" -o -name "*.test.tsx" -o -name "*.spec.ts" 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### ÉTAPE 2 : Cartographie du Backend (veza-backend-api/)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 2.1 Lister TOUTES les routes définies
|
||||||
|
grep -rn "router\.\(GET\|POST\|PUT\|DELETE\|PATCH\)" veza-backend-api/internal/api/
|
||||||
|
|
||||||
|
# 2.2 Lister TOUS les handlers
|
||||||
|
find veza-backend-api/internal/handlers veza-backend-api/internal/api -name "*.go" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.3 Lister TOUS les models
|
||||||
|
find veza-backend-api/internal/models -name "*.go" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.4 Lister TOUS les DTOs
|
||||||
|
find veza-backend-api/internal/dto -name "*.go" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.5 Lister TOUS les services
|
||||||
|
find veza-backend-api/internal/services -name "*.go" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.6 Lister TOUS les repositories
|
||||||
|
find veza-backend-api/internal/repository -name "*.go" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.7 Lister TOUS les middlewares
|
||||||
|
find veza-backend-api/internal/middleware -name "*.go" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.8 Lister les migrations
|
||||||
|
find veza-backend-api/migrations -name "*.sql" 2>/dev/null
|
||||||
|
|
||||||
|
# 2.9 Lister les tests existants
|
||||||
|
find veza-backend-api -name "*_test.go" 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### ÉTAPE 3 : Analyse de l'Intégration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 3.1 Extraire TOUS les endpoints appelés par le frontend
|
||||||
|
grep -rohn "apiClient\.[a-z]*\s*(\s*['\"\`][^'\"\`]*" apps/web/src/ | sort | uniq
|
||||||
|
|
||||||
|
# 3.2 Extraire TOUTES les routes backend
|
||||||
|
grep -rn "router\.\(GET\|POST\|PUT\|DELETE\|PATCH\)" veza-backend-api/internal/api/ | grep -o '"[^"]*"' | sort | uniq
|
||||||
|
|
||||||
|
# 3.3 Comparer les deux listes pour trouver les gaps
|
||||||
|
|
||||||
|
# 3.4 Vérifier la cohérence des types
|
||||||
|
# Frontend types vs Backend DTOs
|
||||||
|
|
||||||
|
# 3.5 Vérifier les variables d'environnement
|
||||||
|
grep -rn "VITE_" apps/web/src/
|
||||||
|
grep -rn "os.Getenv" veza-backend-api/
|
||||||
|
```
|
||||||
|
|
||||||
|
### ÉTAPE 4 : Scanner les Autres Services (si présents)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# veza-common
|
||||||
|
ls -la veza-common/ 2>/dev/null
|
||||||
|
|
||||||
|
# veza-chat-server
|
||||||
|
ls -la veza-chat-server/ 2>/dev/null
|
||||||
|
grep -rn "route\|endpoint\|handler" veza-chat-server/src/ 2>/dev/null
|
||||||
|
|
||||||
|
# veza-stream-server
|
||||||
|
ls -la veza-stream-server/ 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Catégories de Tâches à Générer
|
||||||
|
|
||||||
|
Pour chaque élément trouvé, génère des tâches dans ces catégories :
|
||||||
|
|
||||||
|
### 1. BACKEND - Routes API (BE-API-XXX)
|
||||||
|
- Routes manquantes appelées par le frontend
|
||||||
|
- Routes existantes mais incomplètes
|
||||||
|
- Validation des inputs manquante
|
||||||
|
- Gestion des erreurs insuffisante
|
||||||
|
- Documentation OpenAPI manquante
|
||||||
|
|
||||||
|
### 2. BACKEND - Models & Database (BE-DB-XXX)
|
||||||
|
- Models manquants ou incomplets
|
||||||
|
- Migrations manquantes
|
||||||
|
- Index manquants
|
||||||
|
- Relations mal définies
|
||||||
|
- Soft delete non implémenté
|
||||||
|
|
||||||
|
### 3. BACKEND - Services & Logic (BE-SVC-XXX)
|
||||||
|
- Business logic manquante
|
||||||
|
- Validation métier manquante
|
||||||
|
- Transactions non gérées
|
||||||
|
- Caching non implémenté
|
||||||
|
|
||||||
|
### 4. BACKEND - Security (BE-SEC-XXX)
|
||||||
|
- Authentication gaps
|
||||||
|
- Authorization gaps
|
||||||
|
- Rate limiting manquant
|
||||||
|
- Input sanitization
|
||||||
|
- CORS issues
|
||||||
|
|
||||||
|
### 5. BACKEND - Tests (BE-TEST-XXX)
|
||||||
|
- Tests unitaires manquants
|
||||||
|
- Tests d'intégration manquants
|
||||||
|
- Coverage insuffisante
|
||||||
|
|
||||||
|
### 6. FRONTEND - Pages & Routes (FE-PAGE-XXX)
|
||||||
|
- Pages incomplètes
|
||||||
|
- Routes mal configurées
|
||||||
|
- Layouts manquants
|
||||||
|
- Navigation broken
|
||||||
|
|
||||||
|
### 7. FRONTEND - Components (FE-COMP-XXX)
|
||||||
|
- Composants manquants
|
||||||
|
- Props non typées
|
||||||
|
- Accessibilité (a11y)
|
||||||
|
- Responsive design
|
||||||
|
- Error boundaries
|
||||||
|
|
||||||
|
### 8. FRONTEND - Services & API (FE-API-XXX)
|
||||||
|
- Services API incomplets
|
||||||
|
- Error handling manquant
|
||||||
|
- Loading states manquants
|
||||||
|
- Retry logic manquant
|
||||||
|
|
||||||
|
### 9. FRONTEND - State Management (FE-STATE-XXX)
|
||||||
|
- Stores incomplets
|
||||||
|
- State sync issues
|
||||||
|
- Cache invalidation
|
||||||
|
- Optimistic updates
|
||||||
|
|
||||||
|
### 10. FRONTEND - Types & Validation (FE-TYPE-XXX)
|
||||||
|
- Types manquants ou incorrects
|
||||||
|
- Zod schemas manquants
|
||||||
|
- Runtime validation
|
||||||
|
|
||||||
|
### 11. FRONTEND - Tests (FE-TEST-XXX)
|
||||||
|
- Tests unitaires manquants
|
||||||
|
- Tests de composants manquants
|
||||||
|
- Tests E2E manquants
|
||||||
|
|
||||||
|
### 12. INTEGRATION (INT-XXX)
|
||||||
|
- Contract mismatches
|
||||||
|
- Type inconsistencies
|
||||||
|
- Missing endpoints
|
||||||
|
- Response format issues
|
||||||
|
|
||||||
|
### 13. INFRASTRUCTURE (INFRA-XXX)
|
||||||
|
- Docker configuration
|
||||||
|
- Environment variables
|
||||||
|
- CI/CD pipeline
|
||||||
|
- Monitoring/Logging
|
||||||
|
|
||||||
|
### 14. DOCUMENTATION (DOC-XXX)
|
||||||
|
- API documentation
|
||||||
|
- README updates
|
||||||
|
- Architecture docs
|
||||||
|
- Deployment guide
|
||||||
|
|
||||||
|
### 15. SECURITY (SEC-XXX)
|
||||||
|
- Authentication issues
|
||||||
|
- Authorization issues
|
||||||
|
- Data exposure risks
|
||||||
|
- Dependency vulnerabilities
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Format de Sortie JSON
|
||||||
|
|
||||||
|
Génère le fichier `VEZA_COMPLETE_MVP_TODOLIST.json` avec cette structure :
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"title": "Veza Complete MVP Todolist",
|
||||||
|
"description": "Exhaustive todolist for production-ready MVP",
|
||||||
|
"generated_at": "ISO_TIMESTAMP",
|
||||||
|
"total_tasks": 200,
|
||||||
|
"target": "Production-ready MVP at small scale",
|
||||||
|
"scanned_directories": [
|
||||||
|
"apps/web/",
|
||||||
|
"veza-backend-api/",
|
||||||
|
"veza-common/",
|
||||||
|
"..."
|
||||||
|
],
|
||||||
|
"audit_methodology": "Full codebase scan + integration analysis"
|
||||||
|
},
|
||||||
|
"summary": {
|
||||||
|
"by_priority": {
|
||||||
|
"P0_critical": 0,
|
||||||
|
"P1_high": 0,
|
||||||
|
"P2_medium": 0,
|
||||||
|
"P3_low": 0
|
||||||
|
},
|
||||||
|
"by_category": {
|
||||||
|
"BE-API": 0,
|
||||||
|
"BE-DB": 0,
|
||||||
|
"BE-SVC": 0,
|
||||||
|
"BE-SEC": 0,
|
||||||
|
"BE-TEST": 0,
|
||||||
|
"FE-PAGE": 0,
|
||||||
|
"FE-COMP": 0,
|
||||||
|
"FE-API": 0,
|
||||||
|
"FE-STATE": 0,
|
||||||
|
"FE-TYPE": 0,
|
||||||
|
"FE-TEST": 0,
|
||||||
|
"INT": 0,
|
||||||
|
"INFRA": 0,
|
||||||
|
"DOC": 0,
|
||||||
|
"SEC": 0
|
||||||
|
},
|
||||||
|
"by_owner": {
|
||||||
|
"backend": 0,
|
||||||
|
"frontend": 0,
|
||||||
|
"fullstack": 0,
|
||||||
|
"devops": 0
|
||||||
|
},
|
||||||
|
"estimated_total_hours": 0
|
||||||
|
},
|
||||||
|
"phases": [
|
||||||
|
{
|
||||||
|
"id": "PHASE-1",
|
||||||
|
"name": "Critical Foundation",
|
||||||
|
"description": "Must fix before any other work",
|
||||||
|
"priority": "P0",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-2",
|
||||||
|
"name": "Core Features Completion",
|
||||||
|
"description": "Complete essential user-facing features",
|
||||||
|
"priority": "P1",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-3",
|
||||||
|
"name": "Integration & Consistency",
|
||||||
|
"description": "Ensure frontend/backend work seamlessly",
|
||||||
|
"priority": "P1",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-4",
|
||||||
|
"name": "Security Hardening",
|
||||||
|
"description": "Security measures for production",
|
||||||
|
"priority": "P1",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-5",
|
||||||
|
"name": "Testing & Quality",
|
||||||
|
"description": "Test coverage and code quality",
|
||||||
|
"priority": "P2",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-6",
|
||||||
|
"name": "Performance & Optimization",
|
||||||
|
"description": "Optimize for production load",
|
||||||
|
"priority": "P2",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-7",
|
||||||
|
"name": "Documentation & DevOps",
|
||||||
|
"description": "Documentation and deployment readiness",
|
||||||
|
"priority": "P2",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-8",
|
||||||
|
"name": "Polish & UX",
|
||||||
|
"description": "UI/UX improvements and polish",
|
||||||
|
"priority": "P3",
|
||||||
|
"estimated_days": 0,
|
||||||
|
"tasks": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "BE-API-001",
|
||||||
|
"phase": "PHASE-2",
|
||||||
|
"priority": "P1",
|
||||||
|
"priority_rank": 1,
|
||||||
|
"category": "backend-api",
|
||||||
|
"title": "Task title",
|
||||||
|
"description": "Detailed description",
|
||||||
|
"owner": "backend",
|
||||||
|
"estimated_hours": 2,
|
||||||
|
"status": "todo",
|
||||||
|
"files_involved": [
|
||||||
|
{
|
||||||
|
"path": "veza-backend-api/internal/...",
|
||||||
|
"action": "create|modify|delete",
|
||||||
|
"reason": "Why this file"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"implementation_steps": [
|
||||||
|
{
|
||||||
|
"step": 1,
|
||||||
|
"action": "What to do",
|
||||||
|
"details": "How to do it"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"acceptance_criteria": [
|
||||||
|
"Criterion 1",
|
||||||
|
"Criterion 2"
|
||||||
|
],
|
||||||
|
"dependencies": ["OTHER-TASK-ID"],
|
||||||
|
"related_frontend": "FE-XXX-YYY",
|
||||||
|
"related_backend": "BE-XXX-YYY",
|
||||||
|
"test_requirements": [
|
||||||
|
"Unit test for...",
|
||||||
|
"Integration test for..."
|
||||||
|
],
|
||||||
|
"notes": "Additional context"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"gap_analysis": {
|
||||||
|
"frontend_calls_without_backend": [
|
||||||
|
{
|
||||||
|
"frontend_location": "apps/web/src/services/xxx.ts:42",
|
||||||
|
"endpoint_called": "GET /api/v1/something",
|
||||||
|
"backend_status": "NOT_FOUND",
|
||||||
|
"task_created": "BE-API-XXX"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"backend_routes_without_frontend": [
|
||||||
|
{
|
||||||
|
"backend_location": "veza-backend-api/internal/api/router.go:123",
|
||||||
|
"endpoint_defined": "POST /api/v1/something-else",
|
||||||
|
"frontend_usage": "NOT_FOUND",
|
||||||
|
"task_created": "FE-API-XXX"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type_mismatches": [
|
||||||
|
{
|
||||||
|
"frontend_type": "apps/web/src/types/user.ts - id: number",
|
||||||
|
"backend_type": "veza-backend-api/internal/dto/user.go - ID: uuid.UUID",
|
||||||
|
"task_created": "INT-XXX"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"risk_register": [
|
||||||
|
{
|
||||||
|
"risk": "Description of risk",
|
||||||
|
"severity": "high|medium|low",
|
||||||
|
"mitigation_tasks": ["TASK-ID-1", "TASK-ID-2"],
|
||||||
|
"owner": "backend|frontend|devops"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mvp_definition": {
|
||||||
|
"must_have_features": [
|
||||||
|
{
|
||||||
|
"feature": "User Authentication",
|
||||||
|
"status": "complete|partial|missing",
|
||||||
|
"tasks_required": ["BE-API-001", "FE-PAGE-001"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nice_to_have": [
|
||||||
|
{
|
||||||
|
"feature": "Advanced Search",
|
||||||
|
"tasks_if_included": ["BE-API-050", "FE-COMP-030"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"out_of_scope": [
|
||||||
|
"Feature X - reason"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"progress_tracking": {
|
||||||
|
"completed": 0,
|
||||||
|
"in_progress": 0,
|
||||||
|
"todo": 200,
|
||||||
|
"blocked": 0,
|
||||||
|
"last_updated": null,
|
||||||
|
"completion_percentage": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔢 Règles de Priorisation
|
||||||
|
|
||||||
|
### P0 - Critical (Blocker)
|
||||||
|
- L'app ne démarre pas
|
||||||
|
- Crash systématique
|
||||||
|
- Faille de sécurité majeure
|
||||||
|
- Perte de données possible
|
||||||
|
- Authentication cassée
|
||||||
|
|
||||||
|
### P1 - High (Core Feature)
|
||||||
|
- Feature essentielle non fonctionnelle
|
||||||
|
- Intégration frontend/backend cassée
|
||||||
|
- UX bloquante pour l'utilisateur
|
||||||
|
- Performance inacceptable
|
||||||
|
|
||||||
|
### P2 - Medium (Important)
|
||||||
|
- Feature secondaire non fonctionnelle
|
||||||
|
- Inconsistances visuelles
|
||||||
|
- Tests manquants pour code critique
|
||||||
|
- Documentation manquante
|
||||||
|
|
||||||
|
### P3 - Low (Nice to Have)
|
||||||
|
- Améliorations UX mineures
|
||||||
|
- Refactoring non urgent
|
||||||
|
- Tests pour code non critique
|
||||||
|
- Optimisations mineures
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Règles Absolues
|
||||||
|
|
||||||
|
### NE JAMAIS :
|
||||||
|
- ❌ Ignorer une route/feature parce qu'elle n'est pas implémentée
|
||||||
|
- ❌ Recommander de supprimer du code qui appelle des endpoints manquants
|
||||||
|
- ❌ Sauter des fichiers "parce qu'ils semblent obsolètes"
|
||||||
|
- ❌ Limiter l'audit à certains dossiers seulement
|
||||||
|
- ❌ Générer moins de 200 tâches
|
||||||
|
|
||||||
|
### TOUJOURS :
|
||||||
|
- ✅ Créer une tâche pour implémenter ce qui manque
|
||||||
|
- ✅ Documenter les deux côtés (frontend + backend) pour chaque gap
|
||||||
|
- ✅ Lier les tâches entre elles (dependencies, related_*)
|
||||||
|
- ✅ Inclure des critères d'acceptation testables
|
||||||
|
- ✅ Estimer les heures de travail
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Séquence d'Exécution
|
||||||
|
|
||||||
|
```
|
||||||
|
1. SCAN FRONTEND
|
||||||
|
└── Lister tous les fichiers
|
||||||
|
└── Extraire tous les appels API
|
||||||
|
└── Identifier tous les types
|
||||||
|
└── Trouver tous les composants/pages
|
||||||
|
└── Détecter les tests manquants
|
||||||
|
|
||||||
|
2. SCAN BACKEND
|
||||||
|
└── Lister toutes les routes
|
||||||
|
└── Extraire tous les handlers
|
||||||
|
└── Identifier tous les models/DTOs
|
||||||
|
└── Trouver tous les services
|
||||||
|
└── Détecter les tests manquants
|
||||||
|
|
||||||
|
3. ANALYSE D'INTÉGRATION
|
||||||
|
└── Comparer endpoints frontend vs backend
|
||||||
|
└── Comparer types frontend vs DTOs backend
|
||||||
|
└── Identifier TOUS les gaps
|
||||||
|
└── Créer tâches pour chaque gap
|
||||||
|
|
||||||
|
4. SCAN SERVICES ANNEXES
|
||||||
|
└── veza-common
|
||||||
|
└── veza-chat-server
|
||||||
|
└── veza-stream-server
|
||||||
|
└── Autres...
|
||||||
|
|
||||||
|
5. ANALYSE SÉCURITÉ
|
||||||
|
└── Auth/AuthZ gaps
|
||||||
|
└── Input validation
|
||||||
|
└── CORS/CSRF
|
||||||
|
└── Secrets exposure
|
||||||
|
|
||||||
|
6. ANALYSE INFRA
|
||||||
|
└── Docker configs
|
||||||
|
└── Environment vars
|
||||||
|
└── CI/CD gaps
|
||||||
|
|
||||||
|
7. GÉNÉRATION TODOLIST
|
||||||
|
└── Créer toutes les tâches
|
||||||
|
└── Assigner les priorités
|
||||||
|
└── Calculer les estimations
|
||||||
|
└── Organiser en phases
|
||||||
|
└── Générer le JSON final
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📤 Output Attendu
|
||||||
|
|
||||||
|
À la fin de l'audit, tu dois produire :
|
||||||
|
|
||||||
|
1. **`VEZA_COMPLETE_MVP_TODOLIST.json`** — Le fichier JSON avec 200+ tâches
|
||||||
|
2. **Résumé dans la conversation** :
|
||||||
|
```
|
||||||
|
══════════════════════════════════════════════════════
|
||||||
|
📊 AUDIT COMPLET VEZA - RÉSUMÉ
|
||||||
|
══════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
Total tâches générées: XXX
|
||||||
|
|
||||||
|
Par priorité:
|
||||||
|
• P0 (Critical): XX tâches
|
||||||
|
• P1 (High): XX tâches
|
||||||
|
• P2 (Medium): XX tâches
|
||||||
|
• P3 (Low): XX tâches
|
||||||
|
|
||||||
|
Par catégorie:
|
||||||
|
• Backend API: XX
|
||||||
|
• Backend DB: XX
|
||||||
|
• Backend Services: XX
|
||||||
|
• Frontend Pages: XX
|
||||||
|
• Frontend Components: XX
|
||||||
|
• Integration: XX
|
||||||
|
• Security: XX
|
||||||
|
• Tests: XX
|
||||||
|
• Infrastructure: XX
|
||||||
|
• Documentation: XX
|
||||||
|
|
||||||
|
Gaps critiques détectés:
|
||||||
|
• XX endpoints appelés par frontend mais non implémentés
|
||||||
|
• XX routes backend sans utilisation frontend
|
||||||
|
• XX type mismatches
|
||||||
|
|
||||||
|
Estimation totale: XXX heures (~XX semaines)
|
||||||
|
|
||||||
|
Fichier généré: VEZA_COMPLETE_MVP_TODOLIST.json
|
||||||
|
══════════════════════════════════════════════════════
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 COMMENCE MAINTENANT
|
||||||
|
|
||||||
|
1. **Lis la structure du projet** :
|
||||||
|
```bash
|
||||||
|
ls -la
|
||||||
|
find . -type d -name "src" | head -20
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Scanne le frontend** (apps/web/)
|
||||||
|
|
||||||
|
3. **Scanne le backend** (veza-backend-api/)
|
||||||
|
|
||||||
|
4. **Identifie les gaps d'intégration**
|
||||||
|
|
||||||
|
5. **Génère les 200+ tâches**
|
||||||
|
|
||||||
|
6. **Produis le fichier JSON final**
|
||||||
|
|
||||||
|
**Première action** : Lister la structure racine du projet et identifier tous les répertoires à scanner.
|
||||||
9831
VEZA_COMPLETE_MVP_TODOLIST.json
Normal file
9831
VEZA_COMPLETE_MVP_TODOLIST.json
Normal file
File diff suppressed because it is too large
Load diff
406
VEZA_MVP_INFINITE_AGENT.md
Normal file
406
VEZA_MVP_INFINITE_AGENT.md
Normal file
|
|
@ -0,0 +1,406 @@
|
||||||
|
# VEZA MVP Implementation Agent — Infinite Loop Protocol
|
||||||
|
|
||||||
|
## 🎯 Mission
|
||||||
|
|
||||||
|
Tu es un agent d'implémentation autonome. Ta mission est d'implémenter **toutes les 267 tâches** du fichier `VEZA_COMPLETE_MVP_TODOLIST.json` jusqu'à atteindre un MVP stable prêt pour la production.
|
||||||
|
|
||||||
|
Tu travailles sur une **branche dédiée** et tu **commits après chaque tâche**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Fichier Source de Vérité
|
||||||
|
|
||||||
|
```
|
||||||
|
VEZA_COMPLETE_MVP_TODOLIST.json ← Todolist complète (267 tâches)
|
||||||
|
```
|
||||||
|
|
||||||
|
Ce fichier DOIT être maintenu à jour après chaque tâche terminée.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌿 Gestion de Branche Git
|
||||||
|
|
||||||
|
### Au Début de la Première Session
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier la branche actuelle
|
||||||
|
git branch --show-current
|
||||||
|
|
||||||
|
# Si pas sur la branche MVP, la créer ou y aller
|
||||||
|
git checkout -b feature/mvp-complete 2>/dev/null || git checkout feature/mvp-complete
|
||||||
|
|
||||||
|
# S'assurer d'être à jour
|
||||||
|
git pull origin feature/mvp-complete 2>/dev/null || echo "Nouvelle branche"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Au Début de Chaque Session Suivante
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Revenir sur la branche MVP
|
||||||
|
git checkout feature/mvp-complete
|
||||||
|
|
||||||
|
# Récupérer les derniers changements
|
||||||
|
git pull origin feature/mvp-complete 2>/dev/null || echo "OK"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Cycle d'Implémentation (Boucle Infinie)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ 1. LOAD & FIND │
|
||||||
|
│ → Lire VEZA_COMPLETE_MVP_TODOLIST.json │
|
||||||
|
│ → Trouver la tâche avec: │
|
||||||
|
│ • status = "todo" │
|
||||||
|
│ • Le plus petit priority_rank │
|
||||||
|
│ → Si toutes complétées → MISSION ACCOMPLIE 🎉 │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ 2. ANNOUNCE │
|
||||||
|
│ → Afficher: "🚀 [X/267] Tâche ID: TITRE" │
|
||||||
|
│ → Lister les fichiers à modifier │
|
||||||
|
│ → Vérifier les dépendances │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ 3. IMPLEMENT │
|
||||||
|
│ → Suivre les implementation_steps │
|
||||||
|
│ → Modifier/créer les fichiers listés │
|
||||||
|
│ → Respecter les acceptance_criteria │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ 4. VALIDATE │
|
||||||
|
│ → Compiler: TypeScript (npx tsc --noEmit) │
|
||||||
|
│ → Compiler: Go (go build ./...) │
|
||||||
|
│ → Vérifier les acceptance_criteria │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ 5. UPDATE JSON │
|
||||||
|
│ → Mettre status = "completed" │
|
||||||
|
│ → Ajouter bloc "completion" avec détails │
|
||||||
|
│ → Mettre à jour progress_tracking │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ 6. COMMIT │
|
||||||
|
│ → git add -A │
|
||||||
|
│ → git commit avec message formaté │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ 7. REPORT & CONTINUE │
|
||||||
|
│ → Afficher le résumé │
|
||||||
|
│ → Retour à l'étape 1 │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Format de Mise à Jour du JSON
|
||||||
|
|
||||||
|
### Quand une Tâche est Complétée
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "BE-SEC-001",
|
||||||
|
"status": "completed",
|
||||||
|
"completion": {
|
||||||
|
"completed_at": "2025-01-28T14:30:00Z",
|
||||||
|
"actual_hours": 2.5,
|
||||||
|
"commits": ["abc1234"],
|
||||||
|
"files_changed": [
|
||||||
|
"veza-backend-api/internal/api/router.go",
|
||||||
|
"veza-backend-api/internal/handlers/profile_handler.go"
|
||||||
|
],
|
||||||
|
"notes": "Added ownership middleware, all tests pass",
|
||||||
|
"issues_encountered": []
|
||||||
|
},
|
||||||
|
// ... reste inchangé
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mise à Jour de progress_tracking
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"progress_tracking": {
|
||||||
|
"completed": 1,
|
||||||
|
"in_progress": 0,
|
||||||
|
"todo": 266,
|
||||||
|
"blocked": 0,
|
||||||
|
"last_updated": "2025-01-28T14:30:00Z",
|
||||||
|
"completion_percentage": 0.37
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Format de Commit
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "[TASK-ID] CATEGORY: Title
|
||||||
|
|
||||||
|
- Change 1
|
||||||
|
- Change 2
|
||||||
|
- Change 3
|
||||||
|
|
||||||
|
Phase: PHASE-X
|
||||||
|
Priority: PX
|
||||||
|
Progress: Y/267 (Z%)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Exemples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "[BE-SEC-001] security: Fix ownership verification for user profile updates
|
||||||
|
|
||||||
|
- Added userOwnerResolver function in router.go
|
||||||
|
- Applied RequireOwnershipOrAdmin middleware to PUT /users/:id
|
||||||
|
- Added unit tests for ownership verification
|
||||||
|
|
||||||
|
Phase: PHASE-1
|
||||||
|
Priority: P0
|
||||||
|
Progress: 1/267 (0.4%)"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit -m "[FE-COMP-015] component: Add loading skeleton for track list
|
||||||
|
|
||||||
|
- Created TrackListSkeleton component
|
||||||
|
- Integrated with useTrackList hook
|
||||||
|
- Added storybook story
|
||||||
|
|
||||||
|
Phase: PHASE-2
|
||||||
|
Priority: P1
|
||||||
|
Progress: 45/267 (16.9%)"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Séquence de Démarrage (À Chaque Session)
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## DÉMARRAGE SESSION
|
||||||
|
|
||||||
|
1. [ ] Vérifier/créer la branche
|
||||||
|
git checkout feature/mvp-complete 2>/dev/null || git checkout -b feature/mvp-complete
|
||||||
|
|
||||||
|
2. [ ] Lire VEZA_COMPLETE_MVP_TODOLIST.json
|
||||||
|
→ Noter progress_tracking.completed
|
||||||
|
→ Calculer: X tâches restantes
|
||||||
|
|
||||||
|
3. [ ] Trouver la prochaine tâche
|
||||||
|
→ status = "todo"
|
||||||
|
→ Plus petit priority_rank
|
||||||
|
|
||||||
|
4. [ ] Annoncer:
|
||||||
|
"📍 Session démarrée
|
||||||
|
Progression: X/267 (Y%)
|
||||||
|
Prochaine tâche: [ID] - [TITLE]
|
||||||
|
Phase: PHASE-Z (Priority: PW)"
|
||||||
|
|
||||||
|
5. [ ] Commencer l'implémentation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Format de Rapport Après Chaque Tâche
|
||||||
|
|
||||||
|
```
|
||||||
|
═══════════════════════════════════════════════════════════════
|
||||||
|
✅ COMPLÉTÉ: [TASK-ID] — [Title]
|
||||||
|
═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
Phase: PHASE-X | Priorité: PY | Durée: Zh XXmin
|
||||||
|
|
||||||
|
Fichiers modifiés:
|
||||||
|
✓ path/to/file1.go
|
||||||
|
✓ path/to/file2.ts
|
||||||
|
|
||||||
|
Validation:
|
||||||
|
✓ TypeScript compile
|
||||||
|
✓ Go build OK
|
||||||
|
✓ Critères d'acceptation respectés
|
||||||
|
|
||||||
|
Commit: abc1234
|
||||||
|
|
||||||
|
───────────────────────────────────────────────────────────────
|
||||||
|
📊 PROGRESSION
|
||||||
|
───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
Complétées: X/267 (Y%)
|
||||||
|
[████████░░░░░░░░░░░░░░░░░░░░░░] Y%
|
||||||
|
|
||||||
|
Par phase:
|
||||||
|
PHASE-1 (P0): X/12
|
||||||
|
PHASE-2 (P1): X/XX
|
||||||
|
PHASE-3 (P1): X/XX
|
||||||
|
...
|
||||||
|
|
||||||
|
Prochaine tâche: [NEXT-ID] — [Next Title]
|
||||||
|
|
||||||
|
═══════════════════════════════════════════════════════════════
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ Gestion des Blocages
|
||||||
|
|
||||||
|
### Si une Dépendance n'est pas Satisfaite
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "TASK-ID",
|
||||||
|
"status": "blocked",
|
||||||
|
"blocked_info": {
|
||||||
|
"blocked_at": "2025-01-28T14:30:00Z",
|
||||||
|
"blocked_by": ["DEPENDENCY-ID"],
|
||||||
|
"reason": "Dependency task not completed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
→ Passer à la tâche suivante avec priority_rank le plus bas qui n'est pas bloquée.
|
||||||
|
|
||||||
|
### Si l'Implémentation Échoue
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Annuler les changements
|
||||||
|
git checkout -- .
|
||||||
|
|
||||||
|
# Marquer comme bloquée avec raison
|
||||||
|
# Passer à la tâche suivante
|
||||||
|
```
|
||||||
|
|
||||||
|
### Si TypeScript/Go ne Compile Pas
|
||||||
|
|
||||||
|
1. Identifier l'erreur
|
||||||
|
2. Corriger si possible
|
||||||
|
3. Si non corrigeable immédiatement → marquer comme blocked avec la raison
|
||||||
|
4. Passer à la tâche suivante
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Commandes Utiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# === GIT ===
|
||||||
|
git checkout feature/mvp-complete
|
||||||
|
git add -A
|
||||||
|
git commit -m "MESSAGE"
|
||||||
|
git push origin feature/mvp-complete
|
||||||
|
|
||||||
|
# === VALIDATION ===
|
||||||
|
cd apps/web && npx tsc --noEmit
|
||||||
|
cd veza-backend-api && go build ./...
|
||||||
|
cd apps/web && npm test -- --watchAll=false
|
||||||
|
cd veza-backend-api && go test ./...
|
||||||
|
|
||||||
|
# === RECHERCHE ===
|
||||||
|
grep -rn "PATTERN" apps/web/src/
|
||||||
|
grep -rn "PATTERN" veza-backend-api/
|
||||||
|
|
||||||
|
# === STRUCTURE ===
|
||||||
|
find apps/web/src -name "*.ts" -o -name "*.tsx" | head -20
|
||||||
|
find veza-backend-api/internal -name "*.go" | head -20
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Règles d'Implémentation
|
||||||
|
|
||||||
|
### DO ✅
|
||||||
|
- Suivre exactement les `implementation_steps`
|
||||||
|
- Modifier uniquement les fichiers listés dans `files_involved`
|
||||||
|
- Respecter tous les `acceptance_criteria`
|
||||||
|
- Compiler après chaque modification
|
||||||
|
- Committer après chaque tâche complète
|
||||||
|
- Mettre à jour le JSON immédiatement
|
||||||
|
|
||||||
|
### DON'T ❌
|
||||||
|
- Sauter des étapes d'implémentation
|
||||||
|
- Modifier des fichiers non listés
|
||||||
|
- Ignorer les erreurs de compilation
|
||||||
|
- Oublier de committer
|
||||||
|
- Oublier de mettre à jour le JSON
|
||||||
|
- Changer de branche sans committer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📈 Milestones
|
||||||
|
|
||||||
|
```
|
||||||
|
PHASE-1 (P0): 12 tâches → Fondation sécurisée
|
||||||
|
PHASE-2 (P1): ~64 tâches → Features core complètes
|
||||||
|
PHASE-3 (P1): ~35 tâches → Intégration parfaite
|
||||||
|
PHASE-4 (P1): 15 tâches → Sécurité renforcée
|
||||||
|
PHASE-5 (P2): ~43 tâches → Tests complets
|
||||||
|
PHASE-6 (P2): ~34 tâches → Services optimisés
|
||||||
|
PHASE-7 (P2): 19 tâches → Docs & DevOps
|
||||||
|
PHASE-8 (P3): ~17 tâches → Polish final
|
||||||
|
|
||||||
|
TOTAL: 267 tâches → MVP Production-Ready 🚀
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏁 Condition de Fin
|
||||||
|
|
||||||
|
La mission est terminée quand:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"progress_tracking": {
|
||||||
|
"completed": 267,
|
||||||
|
"in_progress": 0,
|
||||||
|
"todo": 0,
|
||||||
|
"blocked": 0,
|
||||||
|
"completion_percentage": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
À ce moment, afficher:
|
||||||
|
|
||||||
|
```
|
||||||
|
╔═══════════════════════════════════════════════════════════════╗
|
||||||
|
║ ║
|
||||||
|
║ 🎉 MISSION ACCOMPLIE — MVP VEZA STABLE 🎉 ║
|
||||||
|
║ ║
|
||||||
|
║ 267/267 tâches complétées (100%) ║
|
||||||
|
║ ║
|
||||||
|
║ Prochaines étapes: ║
|
||||||
|
║ 1. Merge feature/mvp-complete → main ║
|
||||||
|
║ 2. Tag version v1.0.0-mvp ║
|
||||||
|
║ 3. Déploiement production ║
|
||||||
|
║ ║
|
||||||
|
╚═══════════════════════════════════════════════════════════════╝
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 COMMENCE MAINTENANT
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Créer/checkout la branche
|
||||||
|
git checkout -b feature/mvp-complete 2>/dev/null || git checkout feature/mvp-complete
|
||||||
|
|
||||||
|
# 2. Lire le JSON et trouver la première tâche todo
|
||||||
|
```
|
||||||
|
|
||||||
|
**Première action**:
|
||||||
|
1. Lis `VEZA_COMPLETE_MVP_TODOLIST.json`
|
||||||
|
2. Trouve la tâche avec `status: "todo"` et le plus petit `priority_rank`
|
||||||
|
3. Annonce-la et commence l'implémentation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 PROMPT ULTRA-COURT (réutilisable)
|
||||||
|
|
||||||
|
Si tu veux relancer l'agent rapidement, utilise ce prompt minimal:
|
||||||
|
|
||||||
|
```
|
||||||
|
Continue l'implémentation du MVP Veza.
|
||||||
|
|
||||||
|
Fichier: @VEZA_COMPLETE_MVP_TODOLIST.json
|
||||||
|
Branche: feature/mvp-complete
|
||||||
|
|
||||||
|
Trouve la prochaine tâche (status: todo, plus petit priority_rank).
|
||||||
|
Implémente-la.
|
||||||
|
Mets à jour le JSON.
|
||||||
|
Commit.
|
||||||
|
Continue.
|
||||||
|
```
|
||||||
674
VEZA_MVP_VALIDATION_TODOLIST.json
Normal file
674
VEZA_MVP_VALIDATION_TODOLIST.json
Normal file
|
|
@ -0,0 +1,674 @@
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"title": "Veza MVP Validation & Final Audit",
|
||||||
|
"description": "Complete validation of 15 MVP fixes + final audit to reach stable state",
|
||||||
|
"created_at": "2025-01-28T00:00:00Z",
|
||||||
|
"previous_phase": "MVP Stability Fixes (15/15 completed)",
|
||||||
|
"current_phase": "Validation & Final Audit",
|
||||||
|
"target": "Confirmed stable MVP with no regressions",
|
||||||
|
"estimated_effort": "3-5 hours"
|
||||||
|
},
|
||||||
|
"phases": [
|
||||||
|
{
|
||||||
|
"id": "PHASE-V1",
|
||||||
|
"name": "Technical Validation",
|
||||||
|
"description": "Verify all 15 MVP fixes compile and pass tests",
|
||||||
|
"priority": "CRITICAL",
|
||||||
|
"estimated_effort": "30 min",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "VAL-001",
|
||||||
|
"title": "TypeScript Compilation Check",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "cd apps/web && npx tsc --noEmit",
|
||||||
|
"expected_result": "Exit code 0, no errors",
|
||||||
|
"failure_action": "List all errors, categorize by MVP fix that may have caused them",
|
||||||
|
"related_mvp_fixes": ["MVP-003", "MVP-004", "MVP-010", "MVP-011", "MVP-015"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-002",
|
||||||
|
"title": "Go Compilation Check",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "cd veza-backend-api && go build ./...",
|
||||||
|
"expected_result": "Exit code 0, no errors",
|
||||||
|
"failure_action": "List all errors, identify which MVP fix caused them",
|
||||||
|
"related_mvp_fixes": ["MVP-001", "MVP-005", "MVP-009", "MVP-014"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-003",
|
||||||
|
"title": "Frontend Unit Tests",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "cd apps/web && npm test -- --passWithNoTests --watchAll=false",
|
||||||
|
"expected_result": "All tests pass",
|
||||||
|
"failure_action": "List failing tests, identify regression source",
|
||||||
|
"related_mvp_fixes": ["MVP-002", "MVP-003", "MVP-004", "MVP-015"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-004",
|
||||||
|
"title": "Backend Unit Tests",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "cd veza-backend-api && go test ./... -v",
|
||||||
|
"expected_result": "All tests pass",
|
||||||
|
"failure_action": "List failing tests, identify regression source",
|
||||||
|
"related_mvp_fixes": ["MVP-001", "MVP-009", "MVP-014"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-005",
|
||||||
|
"title": "CORS Production Validation",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "cd veza-backend-api && APP_ENV=production CORS_ALLOWED_ORIGINS='' timeout 5 go run ./cmd/api || echo 'Expected failure'",
|
||||||
|
"expected_result": "Server fails to start with clear CORS error message",
|
||||||
|
"failure_action": "MVP-001 fix incomplete - server should not start without CORS in prod",
|
||||||
|
"related_mvp_fixes": ["MVP-001"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-006",
|
||||||
|
"title": "Legacy Code Removal - ApiService",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "grep -r 'ApiService' apps/web/src/ || echo 'PASS: No ApiService found'",
|
||||||
|
"expected_result": "0 results (no ApiService references)",
|
||||||
|
"failure_action": "MVP-004 incomplete - remove remaining ApiService references",
|
||||||
|
"related_mvp_fixes": ["MVP-004"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-007",
|
||||||
|
"title": "Legacy Code Removal - Token Storage Fragmentation",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "grep -r 'auth-storage' apps/web/src/services/ || echo 'PASS: No auth-storage in services'",
|
||||||
|
"expected_result": "0 results in services directory",
|
||||||
|
"failure_action": "MVP-002 incomplete - remove Zustand token storage fallback",
|
||||||
|
"related_mvp_fixes": ["MVP-002"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-008",
|
||||||
|
"title": "Environment Variable Consistency",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "grep -r 'VITE_API_BASE_URL' apps/web/ || echo 'PASS: No VITE_API_BASE_URL found'",
|
||||||
|
"expected_result": "0 results (only VITE_API_URL should be used)",
|
||||||
|
"failure_action": "MVP-006 incomplete - standardize env var names",
|
||||||
|
"related_mvp_fixes": ["MVP-006"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-009",
|
||||||
|
"title": "User.id Type Consistency",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "grep -rn 'id:\\s*number' apps/web/src/types/ apps/web/src/features/auth/types/ 2>/dev/null || echo 'PASS: No number id types'",
|
||||||
|
"expected_result": "0 results for User-related id: number",
|
||||||
|
"failure_action": "MVP-003 incomplete - fix remaining number types",
|
||||||
|
"related_mvp_fixes": ["MVP-003"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "VAL-010",
|
||||||
|
"title": "Remember Me Field Consistency",
|
||||||
|
"type": "automated",
|
||||||
|
"status": "todo",
|
||||||
|
"command": "grep -rn 'rememberMe' apps/web/src/ --include='*.ts' --include='*.tsx' | grep -v node_modules || echo 'PASS: No camelCase rememberMe'",
|
||||||
|
"expected_result": "0 results (should be remember_me everywhere)",
|
||||||
|
"failure_action": "MVP-015 incomplete - standardize to snake_case",
|
||||||
|
"related_mvp_fixes": ["MVP-015"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-V2",
|
||||||
|
"name": "Functional E2E Validation",
|
||||||
|
"description": "Manual testing of critical user flows",
|
||||||
|
"priority": "HIGH",
|
||||||
|
"estimated_effort": "1 hour",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "E2E-001",
|
||||||
|
"title": "Authentication Flow - Registration",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Navigate to /register",
|
||||||
|
"Fill form with valid data (email, username, password)",
|
||||||
|
"Submit form",
|
||||||
|
"Verify redirect to dashboard or confirmation page",
|
||||||
|
"Verify user data in localStorage (TokenStorage)",
|
||||||
|
"Verify no 'auth-storage' key in localStorage"
|
||||||
|
],
|
||||||
|
"expected_result": "User registered, tokens stored via TokenStorage only",
|
||||||
|
"failure_indicators": [
|
||||||
|
"Registration form error",
|
||||||
|
"API 4xx/5xx response",
|
||||||
|
"Tokens not stored",
|
||||||
|
"Multiple storage mechanisms detected"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-002", "MVP-003"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-002",
|
||||||
|
"title": "Authentication Flow - Login",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Logout if logged in",
|
||||||
|
"Navigate to /login",
|
||||||
|
"Enter valid credentials",
|
||||||
|
"Check 'Remember me' checkbox",
|
||||||
|
"Submit form",
|
||||||
|
"Verify login success",
|
||||||
|
"Check localStorage for veza_access_token and veza_refresh_token",
|
||||||
|
"Verify remember_me was sent correctly (check Network tab)"
|
||||||
|
],
|
||||||
|
"expected_result": "Login succeeds, tokens stored, remember_me sent as snake_case",
|
||||||
|
"failure_indicators": [
|
||||||
|
"Login rejected",
|
||||||
|
"Token not stored",
|
||||||
|
"rememberMe sent instead of remember_me"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-002", "MVP-015"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-003",
|
||||||
|
"title": "Authentication Flow - Persistence",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Ensure logged in",
|
||||||
|
"Hard refresh the page (Ctrl+Shift+R / Cmd+Shift+R)",
|
||||||
|
"Verify still logged in",
|
||||||
|
"Open new tab, navigate to app",
|
||||||
|
"Verify logged in in new tab",
|
||||||
|
"Close all tabs, reopen app",
|
||||||
|
"Verify still logged in (if remember_me was checked)"
|
||||||
|
],
|
||||||
|
"expected_result": "Session persists across refresh, tabs, and browser restart",
|
||||||
|
"failure_indicators": [
|
||||||
|
"Logged out after refresh",
|
||||||
|
"Different auth state across tabs",
|
||||||
|
"Token lost"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-002", "MVP-011"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-004",
|
||||||
|
"title": "Authentication Flow - Token Refresh",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Login with short-lived token (or manually expire token in localStorage)",
|
||||||
|
"Make API request (e.g., load profile)",
|
||||||
|
"Check Network tab for refresh token request",
|
||||||
|
"Verify new tokens stored",
|
||||||
|
"Verify original request succeeded after refresh"
|
||||||
|
],
|
||||||
|
"expected_result": "Token auto-refreshes, request succeeds transparently",
|
||||||
|
"failure_indicators": [
|
||||||
|
"401 error shown to user",
|
||||||
|
"Logged out unexpectedly",
|
||||||
|
"Multiple refresh requests (race condition)"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-002", "MVP-011"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-005",
|
||||||
|
"title": "Authentication Flow - Logout",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Ensure logged in",
|
||||||
|
"Click logout",
|
||||||
|
"Verify redirect to login page",
|
||||||
|
"Check localStorage - tokens should be cleared",
|
||||||
|
"Try to access protected route",
|
||||||
|
"Verify redirected to login"
|
||||||
|
],
|
||||||
|
"expected_result": "Clean logout, all tokens cleared, protected routes inaccessible",
|
||||||
|
"failure_indicators": [
|
||||||
|
"Tokens remain in localStorage",
|
||||||
|
"Can still access protected routes",
|
||||||
|
"Partial state remains"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-002"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-006",
|
||||||
|
"title": "Profile - View and Edit",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Navigate to profile page",
|
||||||
|
"Verify all user fields displayed (id, email, username, avatar, etc.)",
|
||||||
|
"Edit a field (e.g., username)",
|
||||||
|
"Save changes",
|
||||||
|
"Refresh page",
|
||||||
|
"Verify changes persisted"
|
||||||
|
],
|
||||||
|
"expected_result": "Profile loads with full user data, edits persist",
|
||||||
|
"failure_indicators": [
|
||||||
|
"Missing fields (only id, email, role)",
|
||||||
|
"404 on profile endpoint",
|
||||||
|
"Edits not saved"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-007", "MVP-009"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-007",
|
||||||
|
"title": "API Error Handling - Request ID Correlation",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Open browser DevTools Console",
|
||||||
|
"Trigger an API error (e.g., invalid request, 404)",
|
||||||
|
"Check console for error log",
|
||||||
|
"Verify request_id is included in log",
|
||||||
|
"Check Network tab for same request_id in response"
|
||||||
|
],
|
||||||
|
"expected_result": "Error logs include request_id matching backend response",
|
||||||
|
"failure_indicators": [
|
||||||
|
"No request_id in console",
|
||||||
|
"request_id mismatch",
|
||||||
|
"Error not logged"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-013"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-008",
|
||||||
|
"title": "API Error Handling - Retry Logic",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"If possible: Stop backend temporarily",
|
||||||
|
"Or: Use browser DevTools to throttle/block requests",
|
||||||
|
"Trigger API request",
|
||||||
|
"Check Network tab for retry attempts",
|
||||||
|
"Verify exponential backoff timing (1s, 2s, 4s)",
|
||||||
|
"Restart backend / remove throttle",
|
||||||
|
"Verify request eventually succeeds or fails gracefully after max retries"
|
||||||
|
],
|
||||||
|
"expected_result": "Transient errors (502/503) are retried with backoff",
|
||||||
|
"failure_indicators": [
|
||||||
|
"No retry attempts",
|
||||||
|
"Immediate failure on first error",
|
||||||
|
"No backoff between retries"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-012"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-009",
|
||||||
|
"title": "CORS - Cross-Origin Request",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Run frontend on localhost:3000",
|
||||||
|
"Run backend on localhost:8080",
|
||||||
|
"Make API request from frontend",
|
||||||
|
"Check Network tab for CORS headers",
|
||||||
|
"Verify Access-Control-Allow-Origin matches frontend origin",
|
||||||
|
"Verify Access-Control-Allow-Credentials: true"
|
||||||
|
],
|
||||||
|
"expected_result": "CORS headers present and correct, requests succeed",
|
||||||
|
"failure_indicators": [
|
||||||
|
"CORS error in console",
|
||||||
|
"Missing Access-Control headers",
|
||||||
|
"Preflight (OPTIONS) fails"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-001", "MVP-014"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "E2E-010",
|
||||||
|
"title": "Console Error Check",
|
||||||
|
"type": "manual",
|
||||||
|
"status": "todo",
|
||||||
|
"steps": [
|
||||||
|
"Open DevTools Console",
|
||||||
|
"Clear console",
|
||||||
|
"Navigate through: Login → Dashboard → Profile → Tracks → Playlists → Logout",
|
||||||
|
"Note any errors or warnings",
|
||||||
|
"Specifically check for: 404 errors, CORS errors, TypeScript runtime errors"
|
||||||
|
],
|
||||||
|
"expected_result": "No unexpected errors in console during normal navigation",
|
||||||
|
"failure_indicators": [
|
||||||
|
"404 errors (missing endpoints)",
|
||||||
|
"CORS errors",
|
||||||
|
"Uncaught exceptions",
|
||||||
|
"Type errors"
|
||||||
|
],
|
||||||
|
"related_mvp_fixes": ["MVP-008"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-V3",
|
||||||
|
"name": "Remaining Issues Audit",
|
||||||
|
"description": "Review issues INT-000016 to INT-000030 from original audit",
|
||||||
|
"priority": "MEDIUM",
|
||||||
|
"estimated_effort": "1 hour",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "AUDIT-001",
|
||||||
|
"title": "Review P2 Issues (INT-000016 to INT-000023)",
|
||||||
|
"type": "audit",
|
||||||
|
"status": "todo",
|
||||||
|
"issues_to_review": [
|
||||||
|
{
|
||||||
|
"id": "INT-000016",
|
||||||
|
"title": "Field Name Mismatch: cover_art_path vs cover_art_url",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify if cover_art naming is consistent",
|
||||||
|
"action_if_found": "Add to next sprint backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000017",
|
||||||
|
"title": "Inconsistent Pagination Response Format",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify pagination format across list endpoints",
|
||||||
|
"action_if_found": "Document and add to backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000018",
|
||||||
|
"title": "Missing Rate Limit Feedback to User",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify 429 responses show user-friendly message",
|
||||||
|
"action_if_found": "Add to backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000019",
|
||||||
|
"title": "WebSocket Connection Error Handling",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify chat/real-time features handle disconnects",
|
||||||
|
"action_if_found": "Add to backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000020",
|
||||||
|
"title": "File Upload Progress Accuracy",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify upload progress is accurate",
|
||||||
|
"action_if_found": "Add to backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000021",
|
||||||
|
"title": "Search Debounce Missing",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify search inputs have debounce",
|
||||||
|
"action_if_found": "Add to backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000022",
|
||||||
|
"title": "Optimistic UI Updates Not Rolled Back on Error",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify failed mutations roll back UI state",
|
||||||
|
"action_if_found": "Add to backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000023",
|
||||||
|
"title": "Date/Time Timezone Handling",
|
||||||
|
"severity": "P2",
|
||||||
|
"check": "Verify dates display in user's timezone",
|
||||||
|
"action_if_found": "Add to backlog"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "List of P2 issues still present with severity assessment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "AUDIT-002",
|
||||||
|
"title": "Review P3 Issues (INT-000024 to INT-000030)",
|
||||||
|
"type": "audit",
|
||||||
|
"status": "todo",
|
||||||
|
"issues_to_review": [
|
||||||
|
{
|
||||||
|
"id": "INT-000024",
|
||||||
|
"title": "No API Versioning Strategy",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Verify /api/v1 is used consistently",
|
||||||
|
"action_if_found": "Document for future"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000025",
|
||||||
|
"title": "Missing OpenAPI/Swagger Documentation",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Check if API docs exist",
|
||||||
|
"action_if_found": "Add to tech debt backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000026",
|
||||||
|
"title": "Inconsistent Error Message Formatting",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Spot check error responses for consistency",
|
||||||
|
"action_if_found": "Add to tech debt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000027",
|
||||||
|
"title": "No Rate Limit Headers in Responses",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Check for X-RateLimit-* headers",
|
||||||
|
"action_if_found": "Add to tech debt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000028",
|
||||||
|
"title": "Missing API Documentation Updates",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Verify FRONTEND_INTEGRATION.md is current",
|
||||||
|
"action_if_found": "Update docs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000029",
|
||||||
|
"title": "No Vite Proxy Configuration for Development",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Verify dev setup works without proxy",
|
||||||
|
"action_if_found": "Optional improvement"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "INT-000030",
|
||||||
|
"title": "Missing HLS Endpoints",
|
||||||
|
"severity": "P3",
|
||||||
|
"check": "Verify HLS features are disabled or stubbed",
|
||||||
|
"action_if_found": "Already handled in MVP-008"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "List of P3 issues with tech debt assessment"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "AUDIT-003",
|
||||||
|
"title": "Regression Detection Scan",
|
||||||
|
"type": "audit",
|
||||||
|
"status": "todo",
|
||||||
|
"checks": [
|
||||||
|
{
|
||||||
|
"name": "New TypeScript Errors",
|
||||||
|
"command": "cd apps/web && npx tsc --noEmit 2>&1 | head -50",
|
||||||
|
"check": "Any errors introduced by MVP fixes?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "New Console Warnings",
|
||||||
|
"command": "Manual: Check browser console during app usage",
|
||||||
|
"check": "Any new React warnings, deprecation notices?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "New Go Lint Issues",
|
||||||
|
"command": "cd veza-backend-api && golangci-lint run 2>&1 | head -50",
|
||||||
|
"check": "Any new lint issues from MVP fixes?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Dead Code Detection",
|
||||||
|
"command": "grep -r 'TODO.*MVP\\|FIXME.*MVP' apps/web/src/ veza-backend-api/",
|
||||||
|
"check": "Any incomplete TODOs from MVP work?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Duplicate Code",
|
||||||
|
"command": "Manual: Review for copy-paste code in MVP fixes",
|
||||||
|
"check": "Any obvious duplication introduced?"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "List of regressions or new issues introduced"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "AUDIT-004",
|
||||||
|
"title": "Security Quick Scan",
|
||||||
|
"type": "audit",
|
||||||
|
"status": "todo",
|
||||||
|
"checks": [
|
||||||
|
{
|
||||||
|
"name": "CSRF Token Implementation",
|
||||||
|
"check": "Is CSRF actually preventing attacks? (was deferred in MVP-005)",
|
||||||
|
"status": "Review if MVP-005 was fully implemented or stubbed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Token Storage Security",
|
||||||
|
"check": "Tokens in localStorage are XSS-vulnerable",
|
||||||
|
"status": "Accepted risk for MVP, document for future httpOnly cookie migration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CORS Wildcard Check",
|
||||||
|
"check": "No wildcards in production CORS origins",
|
||||||
|
"command": "grep -r 'AllowOrigins.*\\*' veza-backend-api/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Sensitive Data in Logs",
|
||||||
|
"check": "Tokens/passwords not logged",
|
||||||
|
"command": "grep -rn 'console.log.*token\\|console.log.*password' apps/web/src/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Security assessment with accepted risks documented"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PHASE-V4",
|
||||||
|
"name": "Final Report Generation",
|
||||||
|
"description": "Generate comprehensive integration health report",
|
||||||
|
"priority": "HIGH",
|
||||||
|
"estimated_effort": "30 min",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"id": "REPORT-001",
|
||||||
|
"title": "Calculate New Health Score",
|
||||||
|
"type": "analysis",
|
||||||
|
"status": "todo",
|
||||||
|
"scoring_criteria": {
|
||||||
|
"compilation": {
|
||||||
|
"weight": 20,
|
||||||
|
"checks": ["TypeScript compiles", "Go compiles"],
|
||||||
|
"score_if_pass": 20,
|
||||||
|
"score_if_fail": 0
|
||||||
|
},
|
||||||
|
"tests": {
|
||||||
|
"weight": 15,
|
||||||
|
"checks": ["Frontend tests pass", "Backend tests pass"],
|
||||||
|
"score_if_pass": 15,
|
||||||
|
"score_if_fail": 0
|
||||||
|
},
|
||||||
|
"auth_flow": {
|
||||||
|
"weight": 20,
|
||||||
|
"checks": ["Login", "Logout", "Token refresh", "Persistence"],
|
||||||
|
"score_if_pass": 20,
|
||||||
|
"score_if_fail": 5
|
||||||
|
},
|
||||||
|
"api_contract": {
|
||||||
|
"weight": 15,
|
||||||
|
"checks": ["No 404s", "Consistent response format", "Type safety"],
|
||||||
|
"score_if_pass": 15,
|
||||||
|
"score_if_fail": 5
|
||||||
|
},
|
||||||
|
"error_handling": {
|
||||||
|
"weight": 10,
|
||||||
|
"checks": ["Retry logic", "Error correlation", "User feedback"],
|
||||||
|
"score_if_pass": 10,
|
||||||
|
"score_if_fail": 3
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"weight": 10,
|
||||||
|
"checks": ["CORS configured", "No wildcards in prod", "CSRF exists"],
|
||||||
|
"score_if_pass": 10,
|
||||||
|
"score_if_fail": 2
|
||||||
|
},
|
||||||
|
"code_quality": {
|
||||||
|
"weight": 10,
|
||||||
|
"checks": ["No legacy code", "Consistent naming", "No dead code"],
|
||||||
|
"score_if_pass": 10,
|
||||||
|
"score_if_fail": 5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"output": "Health score X/100 (converted to X/10)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "REPORT-002",
|
||||||
|
"title": "Generate Final Integration Report",
|
||||||
|
"type": "documentation",
|
||||||
|
"status": "todo",
|
||||||
|
"sections": [
|
||||||
|
"Executive Summary",
|
||||||
|
"Health Score Breakdown",
|
||||||
|
"MVP Fixes Verification (15/15)",
|
||||||
|
"E2E Test Results",
|
||||||
|
"Remaining Issues (P2/P3)",
|
||||||
|
"Security Assessment",
|
||||||
|
"Regressions Detected",
|
||||||
|
"Recommendations for Next Phase",
|
||||||
|
"Deployment Readiness Checklist"
|
||||||
|
],
|
||||||
|
"output_file": "VEZA_INTEGRATION_FINAL_REPORT.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "REPORT-003",
|
||||||
|
"title": "Generate Next Phase Todolist (if needed)",
|
||||||
|
"type": "planning",
|
||||||
|
"status": "todo",
|
||||||
|
"condition": "If health score < 8/10 or critical issues found",
|
||||||
|
"output_file": "VEZA_POST_MVP_TODOLIST.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summary": {
|
||||||
|
"total_tasks": 27,
|
||||||
|
"by_phase": {
|
||||||
|
"PHASE-V1 (Technical)": 10,
|
||||||
|
"PHASE-V2 (E2E)": 10,
|
||||||
|
"PHASE-V3 (Audit)": 4,
|
||||||
|
"PHASE-V4 (Report)": 3
|
||||||
|
},
|
||||||
|
"by_type": {
|
||||||
|
"automated": 10,
|
||||||
|
"manual": 10,
|
||||||
|
"audit": 4,
|
||||||
|
"analysis": 1,
|
||||||
|
"documentation": 1,
|
||||||
|
"planning": 1
|
||||||
|
},
|
||||||
|
"estimated_total_hours": "3-5 hours"
|
||||||
|
},
|
||||||
|
"progress_tracking": {
|
||||||
|
"completed": 0,
|
||||||
|
"in_progress": 0,
|
||||||
|
"todo": 27,
|
||||||
|
"failed": 0,
|
||||||
|
"last_updated": null,
|
||||||
|
"completion_percentage": 0
|
||||||
|
},
|
||||||
|
"validation_results": {
|
||||||
|
"technical": {
|
||||||
|
"typescript_compiles": null,
|
||||||
|
"go_compiles": null,
|
||||||
|
"frontend_tests_pass": null,
|
||||||
|
"backend_tests_pass": null,
|
||||||
|
"legacy_code_removed": null
|
||||||
|
},
|
||||||
|
"functional": {
|
||||||
|
"auth_flow_works": null,
|
||||||
|
"profile_works": null,
|
||||||
|
"error_handling_works": null,
|
||||||
|
"cors_works": null
|
||||||
|
},
|
||||||
|
"audit": {
|
||||||
|
"p2_issues_remaining": null,
|
||||||
|
"p3_issues_remaining": null,
|
||||||
|
"regressions_found": null,
|
||||||
|
"security_issues": null
|
||||||
|
},
|
||||||
|
"final_health_score": null,
|
||||||
|
"mvp_stable": null
|
||||||
|
}
|
||||||
|
}
|
||||||
495
VEZA_VALIDATION_AGENT_PROMPT.md
Normal file
495
VEZA_VALIDATION_AGENT_PROMPT.md
Normal file
|
|
@ -0,0 +1,495 @@
|
||||||
|
# VEZA MVP Validation & Final Audit Agent
|
||||||
|
|
||||||
|
## 🎯 Mission
|
||||||
|
|
||||||
|
Tu es un agent de validation et d'audit. Les 15 tâches MVP ont été implémentées. Ta mission est de :
|
||||||
|
|
||||||
|
1. **VALIDER** que les 15 fixes fonctionnent réellement
|
||||||
|
2. **TESTER** les flows critiques E2E
|
||||||
|
3. **AUDITER** les problèmes restants
|
||||||
|
4. **GÉNÉRER** un rapport final avec score de santé
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Fichiers de Référence
|
||||||
|
|
||||||
|
```
|
||||||
|
VEZA_MVP_VALIDATION_TODOLIST.json ← Source de vérité pour cette phase
|
||||||
|
VEZA_MVP_STABILITY_TODOLIST.json ← Référence des 15 fixes implémentés
|
||||||
|
VEZA_MVP_TODOLIST_TRACKING.md ← Journal des implémentations
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Cycle d'Exécution
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ PHASE-V1: VALIDATION TECHNIQUE (10 checks automatiques) │
|
||||||
|
│ → Exécuter chaque commande │
|
||||||
|
│ → Noter PASS/FAIL │
|
||||||
|
│ → Si FAIL: identifier la cause et documenter │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ PHASE-V2: TESTS E2E (10 tests manuels) │
|
||||||
|
│ → Guider l'utilisateur à travers chaque test │
|
||||||
|
│ → Collecter les résultats │
|
||||||
|
│ → Documenter les échecs │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ PHASE-V3: AUDIT DES ISSUES RESTANTES │
|
||||||
|
│ → Vérifier INT-000016 à INT-000030 │
|
||||||
|
│ → Détecter les régressions │
|
||||||
|
│ → Scan de sécurité │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ PHASE-V4: RAPPORT FINAL │
|
||||||
|
│ → Calculer le score de santé │
|
||||||
|
│ → Générer VEZA_INTEGRATION_FINAL_REPORT.md │
|
||||||
|
│ → Décider si MVP est stable │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 PHASE-V1 : Validation Technique
|
||||||
|
|
||||||
|
Exécute ces 10 commandes et enregistre les résultats :
|
||||||
|
|
||||||
|
### VAL-001: TypeScript Compilation
|
||||||
|
```bash
|
||||||
|
cd apps/web && npx tsc --noEmit
|
||||||
|
```
|
||||||
|
**Attendu**: Exit 0, aucune erreur
|
||||||
|
**Si échec**: Lister les erreurs, identifier le MVP fix responsable
|
||||||
|
|
||||||
|
### VAL-002: Go Compilation
|
||||||
|
```bash
|
||||||
|
cd veza-backend-api && go build ./...
|
||||||
|
```
|
||||||
|
**Attendu**: Exit 0, aucune erreur
|
||||||
|
**Si échec**: Lister les erreurs, identifier le MVP fix responsable
|
||||||
|
|
||||||
|
### VAL-003: Frontend Tests
|
||||||
|
```bash
|
||||||
|
cd apps/web && npm test -- --passWithNoTests --watchAll=false
|
||||||
|
```
|
||||||
|
**Attendu**: Tous les tests passent
|
||||||
|
**Si échec**: Noter les tests qui échouent
|
||||||
|
|
||||||
|
### VAL-004: Backend Tests
|
||||||
|
```bash
|
||||||
|
cd veza-backend-api && go test ./... -v
|
||||||
|
```
|
||||||
|
**Attendu**: Tous les tests passent
|
||||||
|
**Si échec**: Noter les tests qui échouent
|
||||||
|
|
||||||
|
### VAL-005: CORS Production Check
|
||||||
|
```bash
|
||||||
|
cd veza-backend-api && APP_ENV=production CORS_ALLOWED_ORIGINS='' timeout 5 go run ./cmd/api 2>&1 || echo "Expected failure - check output above"
|
||||||
|
```
|
||||||
|
**Attendu**: Serveur refuse de démarrer avec message d'erreur CORS clair
|
||||||
|
**Si échec**: MVP-001 incomplet
|
||||||
|
|
||||||
|
### VAL-006: ApiService Removed
|
||||||
|
```bash
|
||||||
|
grep -r 'ApiService' apps/web/src/ 2>/dev/null || echo "PASS: No ApiService found"
|
||||||
|
```
|
||||||
|
**Attendu**: 0 résultats
|
||||||
|
**Si échec**: MVP-004 incomplet, lister les fichiers
|
||||||
|
|
||||||
|
### VAL-007: Token Storage Unified
|
||||||
|
```bash
|
||||||
|
grep -r 'auth-storage' apps/web/src/services/ 2>/dev/null || echo "PASS: No auth-storage in services"
|
||||||
|
```
|
||||||
|
**Attendu**: 0 résultats dans services/
|
||||||
|
**Si échec**: MVP-002 incomplet
|
||||||
|
|
||||||
|
### VAL-008: Env Vars Standardized
|
||||||
|
```bash
|
||||||
|
grep -r 'VITE_API_BASE_URL' apps/web/ 2>/dev/null || echo "PASS: No VITE_API_BASE_URL"
|
||||||
|
```
|
||||||
|
**Attendu**: 0 résultats
|
||||||
|
**Si échec**: MVP-006 incomplet
|
||||||
|
|
||||||
|
### VAL-009: User.id Type Fixed
|
||||||
|
```bash
|
||||||
|
grep -rn 'id:\s*number' apps/web/src/types/ apps/web/src/features/auth/types/ 2>/dev/null || echo "PASS: No number id types"
|
||||||
|
```
|
||||||
|
**Attendu**: 0 résultats pour User id
|
||||||
|
**Si échec**: MVP-003 incomplet
|
||||||
|
|
||||||
|
### VAL-010: remember_me Standardized
|
||||||
|
```bash
|
||||||
|
grep -rn 'rememberMe' apps/web/src/ --include='*.ts' --include='*.tsx' 2>/dev/null | grep -v node_modules || echo "PASS: No camelCase rememberMe"
|
||||||
|
```
|
||||||
|
**Attendu**: 0 résultats
|
||||||
|
**Si échec**: MVP-015 incomplet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 PHASE-V2 : Tests E2E
|
||||||
|
|
||||||
|
Guide l'utilisateur à travers ces tests. Demande confirmation après chaque test.
|
||||||
|
|
||||||
|
### E2E-001: Registration Flow
|
||||||
|
```
|
||||||
|
Instructions pour l'utilisateur:
|
||||||
|
1. Navigue vers /register
|
||||||
|
2. Remplis le formulaire (email, username, password)
|
||||||
|
3. Soumets
|
||||||
|
4. Vérifie la redirection
|
||||||
|
5. Ouvre DevTools > Application > localStorage
|
||||||
|
6. Vérifie que veza_access_token existe
|
||||||
|
7. Vérifie qu'il n'y a PAS de clé 'auth-storage'
|
||||||
|
|
||||||
|
Questions à poser:
|
||||||
|
- Registration réussie? (oui/non)
|
||||||
|
- Tokens dans localStorage? (oui/non)
|
||||||
|
- Clé 'auth-storage' absente? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-002: Login Flow
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Déconnecte-toi si connecté
|
||||||
|
2. Va sur /login
|
||||||
|
3. Entre des credentials valides
|
||||||
|
4. Coche "Remember me"
|
||||||
|
5. Soumets
|
||||||
|
6. Ouvre DevTools > Network
|
||||||
|
7. Trouve la requête POST /auth/login
|
||||||
|
8. Vérifie le body: remember_me (snake_case) et non rememberMe
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Login réussi? (oui/non)
|
||||||
|
- remember_me envoyé en snake_case? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-003: Session Persistence
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Assure-toi d'être connecté
|
||||||
|
2. Fais un hard refresh (Ctrl+Shift+R)
|
||||||
|
3. Es-tu toujours connecté?
|
||||||
|
4. Ouvre un nouvel onglet sur l'app
|
||||||
|
5. Es-tu connecté dans le nouvel onglet?
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Session persiste après refresh? (oui/non)
|
||||||
|
- Session partagée entre onglets? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-004: Token Refresh
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Connecte-toi
|
||||||
|
2. Dans DevTools > Application > localStorage
|
||||||
|
3. Modifie veza_access_token (ajoute des caractères pour l'invalider)
|
||||||
|
4. Fais une action qui appelle l'API (ex: charger le profil)
|
||||||
|
5. Observe Network tab
|
||||||
|
6. Y a-t-il une requête vers /auth/refresh?
|
||||||
|
7. Le token a-t-il été renouvelé dans localStorage?
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Token refresh automatique? (oui/non)
|
||||||
|
- Nouveaux tokens stockés? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-005: Logout Flow
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Assure-toi d'être connecté
|
||||||
|
2. Clique sur Logout
|
||||||
|
3. Vérifie la redirection vers /login
|
||||||
|
4. Vérifie localStorage - tokens effacés?
|
||||||
|
5. Essaie d'accéder à une route protégée
|
||||||
|
6. Es-tu redirigé vers login?
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Logout réussi? (oui/non)
|
||||||
|
- Tokens effacés de localStorage? (oui/non)
|
||||||
|
- Routes protégées inaccessibles? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-006: Profile View/Edit
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Va sur la page profil
|
||||||
|
2. Tous les champs sont-ils affichés? (id, email, username, avatar, etc.)
|
||||||
|
3. Modifie un champ (ex: username)
|
||||||
|
4. Sauvegarde
|
||||||
|
5. Refresh la page
|
||||||
|
6. Le changement est-il persisté?
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Tous les champs user affichés? (oui/non)
|
||||||
|
- Modifications sauvegardées? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-007: Error Request ID
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Ouvre DevTools > Console
|
||||||
|
2. Provoque une erreur API (ex: accède à une ressource inexistante)
|
||||||
|
3. Regarde le log d'erreur dans la console
|
||||||
|
4. Contient-il un request_id?
|
||||||
|
5. Vérifie dans Network si le même request_id est dans la réponse
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- request_id présent dans les logs? (oui/non)
|
||||||
|
- request_id correspond à la réponse backend? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-008: Retry Logic (si testable)
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Si possible: arrête le backend temporairement
|
||||||
|
2. Ou: utilise DevTools > Network > Throttling > Offline
|
||||||
|
3. Déclenche une requête API
|
||||||
|
4. Observe Network - y a-t-il des retry?
|
||||||
|
5. Remets la connexion
|
||||||
|
6. La requête finit-elle par réussir?
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Retry automatique observé? (oui/non/non testable)
|
||||||
|
- Backoff exponentiel? (oui/non/non testable)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-009: CORS Headers
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Frontend sur localhost:3000, Backend sur localhost:8080
|
||||||
|
2. Fais une requête API
|
||||||
|
3. Ouvre Network > trouve la requête
|
||||||
|
4. Regarde les Response Headers
|
||||||
|
5. Access-Control-Allow-Origin présent?
|
||||||
|
6. Access-Control-Allow-Credentials: true?
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Headers CORS présents? (oui/non)
|
||||||
|
- Pas d'erreur CORS dans console? (oui/non)
|
||||||
|
```
|
||||||
|
|
||||||
|
### E2E-010: Console Error Scan
|
||||||
|
```
|
||||||
|
Instructions:
|
||||||
|
1. Ouvre DevTools > Console
|
||||||
|
2. Clear console
|
||||||
|
3. Navigue: Login → Dashboard → Profile → Tracks → Playlists → Logout
|
||||||
|
4. Note toutes les erreurs/warnings
|
||||||
|
|
||||||
|
Questions:
|
||||||
|
- Erreurs 404? (oui/non, lesquelles?)
|
||||||
|
- Erreurs CORS? (oui/non)
|
||||||
|
- Exceptions JavaScript? (oui/non, lesquelles?)
|
||||||
|
- Warnings React? (oui/non, lesquels?)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 PHASE-V3 : Audit Issues Restantes
|
||||||
|
|
||||||
|
### Vérifier les issues P2 (INT-000016 à INT-000023)
|
||||||
|
|
||||||
|
Pour chaque issue, vérifie si elle existe encore et note la sévérité actuelle:
|
||||||
|
|
||||||
|
| ID | Issue | Commande/Check | Statut |
|
||||||
|
|----|-------|----------------|--------|
|
||||||
|
| INT-000016 | cover_art_path vs cover_art_url | `grep -rn 'cover_art' apps/web/src/types/` | |
|
||||||
|
| INT-000017 | Pagination inconsistante | Spot check des endpoints de liste | |
|
||||||
|
| INT-000018 | Rate limit feedback | Vérifier gestion du 429 | |
|
||||||
|
| INT-000019 | WebSocket error handling | Si chat existe, tester déconnexion | |
|
||||||
|
| INT-000020 | Upload progress accuracy | Tester upload de fichier | |
|
||||||
|
| INT-000021 | Search debounce | Tester champs de recherche | |
|
||||||
|
| INT-000022 | Optimistic UI rollback | Tester échec de mutation | |
|
||||||
|
| INT-000023 | Timezone handling | Vérifier affichage des dates | |
|
||||||
|
|
||||||
|
### Vérifier les issues P3 (INT-000024 à INT-000030)
|
||||||
|
|
||||||
|
| ID | Issue | Statut |
|
||||||
|
|----|-------|--------|
|
||||||
|
| INT-000024 | API versioning | /api/v1 utilisé partout? |
|
||||||
|
| INT-000025 | OpenAPI docs | Swagger existe? |
|
||||||
|
| INT-000026 | Error message format | Cohérent? |
|
||||||
|
| INT-000027 | Rate limit headers | X-RateLimit-* présents? |
|
||||||
|
| INT-000028 | API docs à jour | FRONTEND_INTEGRATION.md actuel? |
|
||||||
|
| INT-000029 | Vite proxy | Fonctionne sans? |
|
||||||
|
| INT-000030 | HLS endpoints | Désactivés dans MVP-008? |
|
||||||
|
|
||||||
|
### Détection de Régressions
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# TODOs/FIXMEs liés au MVP
|
||||||
|
grep -rn 'TODO.*MVP\|FIXME.*MVP' apps/web/src/ veza-backend-api/
|
||||||
|
|
||||||
|
# Code mort potentiel
|
||||||
|
grep -rn 'ApiService\|apiService' apps/web/src/
|
||||||
|
|
||||||
|
# Sensitive data in logs
|
||||||
|
grep -rn 'console.log.*token\|console.log.*password' apps/web/src/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 PHASE-V4 : Rapport Final
|
||||||
|
|
||||||
|
### Calcul du Score de Santé
|
||||||
|
|
||||||
|
```
|
||||||
|
SCORING (sur 100 points, converti en /10):
|
||||||
|
|
||||||
|
Compilation (20 pts)
|
||||||
|
├── TypeScript compile: 10 pts
|
||||||
|
└── Go compile: 10 pts
|
||||||
|
|
||||||
|
Tests (15 pts)
|
||||||
|
├── Frontend tests pass: 7 pts
|
||||||
|
└── Backend tests pass: 8 pts
|
||||||
|
|
||||||
|
Auth Flow (20 pts)
|
||||||
|
├── Login works: 5 pts
|
||||||
|
├── Logout works: 5 pts
|
||||||
|
├── Token refresh works: 5 pts
|
||||||
|
└── Session persists: 5 pts
|
||||||
|
|
||||||
|
API Contract (15 pts)
|
||||||
|
├── No 404 errors: 5 pts
|
||||||
|
├── Consistent format: 5 pts
|
||||||
|
└── Type safety: 5 pts
|
||||||
|
|
||||||
|
Error Handling (10 pts)
|
||||||
|
├── Retry logic: 4 pts
|
||||||
|
├── Error correlation: 3 pts
|
||||||
|
└── User feedback: 3 pts
|
||||||
|
|
||||||
|
Security (10 pts)
|
||||||
|
├── CORS configured: 4 pts
|
||||||
|
├── No wildcards prod: 3 pts
|
||||||
|
└── CSRF exists: 3 pts
|
||||||
|
|
||||||
|
Code Quality (10 pts)
|
||||||
|
├── No legacy code: 4 pts
|
||||||
|
├── Consistent naming: 3 pts
|
||||||
|
└── No dead code: 3 pts
|
||||||
|
|
||||||
|
TOTAL: ___ / 100 = ___ / 10
|
||||||
|
```
|
||||||
|
|
||||||
|
### Template du Rapport Final
|
||||||
|
|
||||||
|
Génère ce fichier: `VEZA_INTEGRATION_FINAL_REPORT.md`
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Veza Integration Final Report
|
||||||
|
|
||||||
|
**Date**: [DATE]
|
||||||
|
**Auditeur**: [Agent]
|
||||||
|
**Phase précédente**: MVP Stability Fixes (15/15)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
**Health Score**: X/10 (était 4/10 avant MVP fixes)
|
||||||
|
**MVP Stable**: OUI/NON
|
||||||
|
**Prêt pour Production**: OUI/NON/AVEC RÉSERVES
|
||||||
|
|
||||||
|
[Résumé en 3-4 phrases]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MVP Fixes Verification
|
||||||
|
|
||||||
|
| ID | Fix | Validation | Statut |
|
||||||
|
|----|-----|------------|--------|
|
||||||
|
| MVP-001 | CORS Config | VAL-005 | ✅/❌ |
|
||||||
|
| MVP-002 | Token Storage | VAL-007 | ✅/❌ |
|
||||||
|
| ... | ... | ... | ... |
|
||||||
|
|
||||||
|
**Résultat**: X/15 fixes vérifiés fonctionnels
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## E2E Test Results
|
||||||
|
|
||||||
|
| Test | Résultat | Notes |
|
||||||
|
|------|----------|-------|
|
||||||
|
| E2E-001 Registration | ✅/❌ | |
|
||||||
|
| E2E-002 Login | ✅/❌ | |
|
||||||
|
| ... | ... | ... |
|
||||||
|
|
||||||
|
**Résultat**: X/10 tests passent
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Issues Restantes
|
||||||
|
|
||||||
|
### P2 (Medium - à traiter prochainement)
|
||||||
|
- [ ] INT-000016: ...
|
||||||
|
- [ ] INT-000017: ...
|
||||||
|
|
||||||
|
### P3 (Low - tech debt)
|
||||||
|
- [ ] INT-000024: ...
|
||||||
|
- [ ] INT-000025: ...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Régressions Détectées
|
||||||
|
|
||||||
|
[Liste des régressions trouvées, ou "Aucune régression détectée"]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Assessment
|
||||||
|
|
||||||
|
| Check | Statut | Risque Accepté? |
|
||||||
|
|-------|--------|-----------------|
|
||||||
|
| CORS configuré | ✅/❌ | |
|
||||||
|
| Pas de wildcards | ✅/❌ | |
|
||||||
|
| CSRF implémenté | ✅/❌ | |
|
||||||
|
| Tokens en localStorage | ⚠️ | Oui (MVP) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommandations
|
||||||
|
|
||||||
|
### Immédiat (avant déploiement)
|
||||||
|
1. ...
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
### Court terme (sprint suivant)
|
||||||
|
1. ...
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
### Moyen terme (backlog)
|
||||||
|
1. ...
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Readiness Checklist
|
||||||
|
|
||||||
|
- [ ] Tous les tests passent
|
||||||
|
- [ ] CORS_ALLOWED_ORIGINS configuré pour prod
|
||||||
|
- [ ] Variables d'environnement documentées
|
||||||
|
- [ ] Pas de secrets dans le code
|
||||||
|
- [ ] Docker build fonctionne
|
||||||
|
- [ ] Rollback plan en place
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
[Score final, décision MVP stable ou non, prochaines étapes]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 COMMENCE
|
||||||
|
|
||||||
|
1. Lis `VEZA_MVP_VALIDATION_TODOLIST.json`
|
||||||
|
2. Annonce: "🔍 Démarrage de la validation MVP Veza"
|
||||||
|
3. Exécute PHASE-V1 (commandes automatiques)
|
||||||
|
4. Guide l'utilisateur pour PHASE-V2 (tests manuels)
|
||||||
|
5. Effectue PHASE-V3 (audit)
|
||||||
|
6. Génère PHASE-V4 (rapport final)
|
||||||
|
|
||||||
|
**Première action**: Exécuter VAL-001 (TypeScript compilation)
|
||||||
|
|
@ -108,3 +108,4 @@ export default globalSetup;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
//go:build integration
|
||||||
|
// +build integration
|
||||||
|
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"veza-backend-api/internal/models"
|
||||||
|
"veza-backend-api/internal/repositories"
|
||||||
|
"veza-backend-api/internal/services"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"gorm.io/driver/sqlite"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setupProfileIntegrationTestRouter crée un router de test pour les tests de profile
|
||||||
|
// BE-SEC-001: Tests d'intégration pour vérification ownership
|
||||||
|
func setupProfileIntegrationTestRouter(t *testing.T) (*gin.Engine, *gorm.DB, func()) {
|
||||||
|
gin.SetMode(gin.TestMode)
|
||||||
|
|
||||||
|
// Setup in-memory SQLite database
|
||||||
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Enable foreign keys for SQLite
|
||||||
|
db.Exec("PRAGMA foreign_keys = ON")
|
||||||
|
|
||||||
|
// Auto-migrate - include all models needed for PermissionService
|
||||||
|
err = db.AutoMigrate(
|
||||||
|
&models.User{},
|
||||||
|
&models.Role{},
|
||||||
|
&models.Permission{},
|
||||||
|
&models.UserRole{},
|
||||||
|
&models.RolePermission{},
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Setup logger
|
||||||
|
logger := zap.NewNop()
|
||||||
|
|
||||||
|
// Setup services
|
||||||
|
userRepo := repositories.NewGormUserRepository(db)
|
||||||
|
userService := services.NewUserServiceWithDB(userRepo, db)
|
||||||
|
profileHandler := NewProfileHandler(userService, logger)
|
||||||
|
|
||||||
|
// Setup PermissionService for admin checks
|
||||||
|
permissionService := services.NewPermissionService(db)
|
||||||
|
profileHandler.SetPermissionService(permissionService)
|
||||||
|
|
||||||
|
// Create router
|
||||||
|
router := gin.New()
|
||||||
|
v1 := router.Group("/api/v1")
|
||||||
|
{
|
||||||
|
// Protected routes with mock auth middleware
|
||||||
|
protected := v1.Group("/users")
|
||||||
|
protected.Use(func(c *gin.Context) {
|
||||||
|
// Mock auth middleware - set user_id from header
|
||||||
|
// This simulates RequireAuth() middleware
|
||||||
|
userIDStr := c.GetHeader("X-User-ID")
|
||||||
|
if userIDStr == "" {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uid, err := uuid.Parse(userIDStr)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid user id"})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Set("user_id", uid)
|
||||||
|
c.Next()
|
||||||
|
})
|
||||||
|
{
|
||||||
|
// Note: In real router, RequireOwnershipOrAdmin middleware would be here
|
||||||
|
// For this test, we're testing the handler's ownership check directly
|
||||||
|
protected.PUT("/:id", profileHandler.UpdateProfile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup := func() {
|
||||||
|
// Database will be closed automatically
|
||||||
|
}
|
||||||
|
|
||||||
|
return router, db, cleanup
|
||||||
|
}
|
||||||
|
|
||||||
|
// createTestUser crée un utilisateur de test
|
||||||
|
func createTestUserForProfile(t *testing.T, db *gorm.DB, userID uuid.UUID, username string, isAdmin bool) *models.User {
|
||||||
|
user := &models.User{
|
||||||
|
ID: userID,
|
||||||
|
Username: username,
|
||||||
|
Slug: username,
|
||||||
|
Email: username + "@example.com",
|
||||||
|
PasswordHash: "hashed_password",
|
||||||
|
IsActive: true,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
if isAdmin {
|
||||||
|
user.Role = "admin"
|
||||||
|
user.IsAdmin = true
|
||||||
|
} else {
|
||||||
|
user.Role = "user"
|
||||||
|
}
|
||||||
|
// Create user first
|
||||||
|
err := db.Create(user).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Then create admin role and assign it if admin
|
||||||
|
if isAdmin {
|
||||||
|
// Create admin role and assign it to user
|
||||||
|
adminRole := &models.Role{
|
||||||
|
Name: "admin",
|
||||||
|
DisplayName: "Administrator",
|
||||||
|
IsSystem: true,
|
||||||
|
IsActive: true,
|
||||||
|
}
|
||||||
|
err = db.FirstOrCreate(adminRole, models.Role{Name: "admin"}).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
userRole := &models.UserRole{
|
||||||
|
UserID: userID,
|
||||||
|
RoleID: adminRole.ID,
|
||||||
|
RoleName: "admin",
|
||||||
|
IsActive: true,
|
||||||
|
}
|
||||||
|
err = db.Create(userRole).Error
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
// BE-SEC-001: Test that user cannot update another user's profile
|
||||||
|
func TestUpdateProfile_UserCannotUpdateOtherUserProfile(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping integration test in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
router, db, cleanup := setupProfileIntegrationTestRouter(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
// Create two users
|
||||||
|
ownerID := uuid.New()
|
||||||
|
otherUserID := uuid.New()
|
||||||
|
createTestUserForProfile(t, db, ownerID, "owner", false)
|
||||||
|
createTestUserForProfile(t, db, otherUserID, "otheruser", false)
|
||||||
|
|
||||||
|
// Try to update owner's profile as otherUser
|
||||||
|
updateReq := UpdateProfileRequest{
|
||||||
|
FirstName: "Hacked",
|
||||||
|
Bio: "I shouldn't be able to do this",
|
||||||
|
}
|
||||||
|
body, _ := json.Marshal(updateReq)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+ownerID.String(), bytes.NewBuffer(body))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("X-User-ID", otherUserID.String()) // otherUser is authenticated
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
|
// Should return 403 Forbidden
|
||||||
|
assert.Equal(t, http.StatusForbidden, w.Code)
|
||||||
|
|
||||||
|
var response map[string]interface{}
|
||||||
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
// Error can be a string or a map, check both
|
||||||
|
if errorStr, ok := response["error"].(string); ok {
|
||||||
|
assert.Contains(t, errorStr, "cannot update other user's profile")
|
||||||
|
} else if errorMap, ok := response["error"].(map[string]interface{}); ok {
|
||||||
|
if message, ok := errorMap["message"].(string); ok {
|
||||||
|
assert.Contains(t, message, "cannot update other user's profile")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BE-SEC-001: Test that admin can update any profile
|
||||||
|
func TestUpdateProfile_AdminCanUpdateAnyProfile(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping integration test in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
router, db, cleanup := setupProfileIntegrationTestRouter(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
// Create two users: owner and admin
|
||||||
|
ownerID := uuid.New()
|
||||||
|
adminID := uuid.New()
|
||||||
|
createTestUserForProfile(t, db, ownerID, "owner", false)
|
||||||
|
createTestUserForProfile(t, db, adminID, "admin", true)
|
||||||
|
|
||||||
|
// Admin tries to update owner's profile
|
||||||
|
updateReq := UpdateProfileRequest{
|
||||||
|
FirstName: "Updated by Admin",
|
||||||
|
Bio: "Admin updated this profile",
|
||||||
|
}
|
||||||
|
body, _ := json.Marshal(updateReq)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+ownerID.String(), bytes.NewBuffer(body))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("X-User-ID", adminID.String()) // admin is authenticated
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
|
// Admin should be able to update
|
||||||
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
|
|
||||||
|
var response map[string]interface{}
|
||||||
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, response["data"])
|
||||||
|
}
|
||||||
|
|
||||||
|
// BE-SEC-001: Test that user can update their own profile
|
||||||
|
func TestUpdateProfile_UserCanUpdateOwnProfile(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("Skipping integration test in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
router, db, cleanup := setupProfileIntegrationTestRouter(t)
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
// Create a user
|
||||||
|
userID := uuid.New()
|
||||||
|
createTestUserForProfile(t, db, userID, "testuser", false)
|
||||||
|
|
||||||
|
// User tries to update their own profile
|
||||||
|
updateReq := UpdateProfileRequest{
|
||||||
|
FirstName: "Updated First Name",
|
||||||
|
Bio: "Updated bio",
|
||||||
|
}
|
||||||
|
body, _ := json.Marshal(updateReq)
|
||||||
|
|
||||||
|
req := httptest.NewRequest(http.MethodPut, "/api/v1/users/"+userID.String(), bytes.NewBuffer(body))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("X-User-ID", userID.String()) // user is authenticated
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
router.ServeHTTP(w, req)
|
||||||
|
|
||||||
|
// User should be able to update their own profile
|
||||||
|
assert.Equal(t, http.StatusOK, w.Code)
|
||||||
|
|
||||||
|
var response map[string]interface{}
|
||||||
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, response["data"])
|
||||||
|
|
||||||
|
// Verify the profile was actually updated
|
||||||
|
profileData := response["data"].(map[string]interface{})
|
||||||
|
profile := profileData["profile"].(map[string]interface{})
|
||||||
|
assert.Equal(t, "Updated First Name", profile["first_name"])
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue