463 lines
24 KiB
Markdown
463 lines
24 KiB
Markdown
|
|
# 🔍 Rapport d'Audit Intégration Backend/Frontend Veza - 2025
|
||
|
|
|
||
|
|
**Date de génération:** 2025-12-25
|
||
|
|
**Scope:** `apps/web/` ↔ `veza-backend-api/`
|
||
|
|
**Exclusions:** `veza-chat-server/`, `veza-stream-server/`, `veza-common/`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📊 Executive Summary
|
||
|
|
|
||
|
|
### Score Global: **6.5/10**
|
||
|
|
|
||
|
|
| Métrique | Valeur |
|
||
|
|
|----------|--------|
|
||
|
|
| Endpoints backend total | ~85+ |
|
||
|
|
| Endpoints utilisés par frontend | ~45 |
|
||
|
|
| Endpoints manquants côté frontend | ~8 |
|
||
|
|
| Appels frontend sans endpoint backend | ~3 |
|
||
|
|
| Incohérences de types | ~12 |
|
||
|
|
| Duplications de code | ~3 |
|
||
|
|
|
||
|
|
### Répartition par Priorité
|
||
|
|
|
||
|
|
- **P0 (Bloqueurs Production):** 3
|
||
|
|
- **P1 (Critiques):** 8
|
||
|
|
- **P2 (Majeurs):** 15
|
||
|
|
- **P3 (Mineurs):** 6
|
||
|
|
|
||
|
|
### Score par Catégorie
|
||
|
|
|
||
|
|
| Catégorie | Score | Problèmes |
|
||
|
|
|-----------|-------|-----------|
|
||
|
|
| CORS/Security | 4/10 | 2 critiques |
|
||
|
|
| Authentification | 7/10 | 3 problèmes |
|
||
|
|
| Types | 5/10 | 12 incohérences |
|
||
|
|
| API Client | 8/10 | 1 duplication |
|
||
|
|
| Endpoints | 6/10 | 11 manquants |
|
||
|
|
| Cleanup | 7/10 | 3 duplications |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Analyse des Endpoints
|
||
|
|
|
||
|
|
### 1.1 Tableau Exhaustif des Endpoints
|
||
|
|
|
||
|
|
| Endpoint Backend | Handler | Frontend Service | Frontend Hook | Types Alignés | Status |
|
||
|
|
|------------------|---------|------------------|---------------|---------------|--------|
|
||
|
|
| **AUTH** |
|
||
|
|
| POST /api/v1/auth/login | Login | authApi.login() | useLogin | ✅ | OK |
|
||
|
|
| POST /api/v1/auth/register | Register | authApi.register() | useRegister | ✅ | OK |
|
||
|
|
| POST /api/v1/auth/refresh | Refresh | authApi.refresh() | - | ✅ | OK |
|
||
|
|
| POST /api/v1/auth/logout | Logout | authApi.logout() | useLogout | ✅ | OK |
|
||
|
|
| GET /api/v1/auth/me | GetMe | authApi.getMe() | useAuth | ✅ | OK |
|
||
|
|
| POST /api/v1/auth/verify-email | VerifyEmail | authApi.verifyEmail() | - | ✅ | OK |
|
||
|
|
| POST /api/v1/auth/resend-verification | ResendVerification | authApi.resendVerification() | - | ✅ | OK |
|
||
|
|
| GET /api/v1/auth/check-username | CheckUsername | authApi.checkUsername() | - | ✅ | OK |
|
||
|
|
| POST /api/v1/auth/2fa/setup | SetupTwoFactor | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/auth/2fa/verify | VerifyTwoFactor | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/auth/2fa/disable | DisableTwoFactor | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/auth/2fa/status | GetTwoFactorStatus | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **USERS** |
|
||
|
|
| GET /api/v1/users | ListUsers | - | - | ✅ | OK |
|
||
|
|
| GET /api/v1/users/:id | GetProfile | - | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/users/by-username/:username | GetProfileByUsername | - | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/users/search | SearchUsers | searchService.searchUsers() | - | ❌ | **MANQUANT BACKEND** |
|
||
|
|
| PUT /api/v1/users/:id | UpdateProfile | - | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| DELETE /api/v1/users/:id | DeleteUser | - | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/users/:id/completion | GetProfileCompletion | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/users/:id/follow | FollowUser | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/users/:id/follow | UnfollowUser | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/users/:id/block | BlockUser | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/users/:id/block | UnblockUser | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/users/:userId/avatar | UploadAvatar | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/users/:userId/avatar | DeleteAvatar | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/users/:id/likes | GetUserLikedTracks | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/users/me/export | ExportUserData | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **TRACKS** |
|
||
|
|
| GET /api/v1/tracks | ListTracks | trackApi.list() | useTracks | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/search | SearchTracks | trackSearchService.search() | - | ❌ | **MANQUANT BACKEND** |
|
||
|
|
| GET /api/v1/tracks/:id | GetTrack | trackApi.get() | useTrack | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/stats | GetTrackStats | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/history | GetTrackHistory | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/download | DownloadTrack | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/shared/:token | GetSharedTrack | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks | UploadTrack | trackApi.upload() | useUploadTrack | ⚠️ ID type | PARTIEL |
|
||
|
|
| PUT /api/v1/tracks/:id | UpdateTrack | trackApi.update() | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| DELETE /api/v1/tracks/:id | DeleteTrack | trackApi.delete() | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/status | GetUploadStatus | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/initiate | InitiateChunkedUpload | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/chunk | UploadChunk | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/complete | CompleteChunkedUpload | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/quota/:id | GetUploadQuota | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/resume/:uploadId | ResumeUpload | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/batch/delete | BatchDeleteTracks | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/batch/update | BatchUpdateTracks | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/:id/like | LikeTrack | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/tracks/:id/like | UnlikeTrack | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/likes | GetTrackLikes | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/:id/share | CreateShare | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/tracks/share/:id | RevokeShare | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/:id/versions/:versionId/restore | RestoreVersion | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/:id/play | RecordPlay | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/hls/info | GetStreamInfo | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/hls/status | GetStreamStatus | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/tracks/:id/comments | GetComments | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/tracks/:id/comments | CreateComment | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/comments/:id | DeleteComment | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **PLAYLISTS** |
|
||
|
|
| GET /api/v1/playlists | GetPlaylists | playlistService.getPlaylists() | usePlaylists | ⚠️ ID type | PARTIEL |
|
||
|
|
| GET /api/v1/playlists/search | SearchPlaylists | playlistService.searchPlaylists() | - | ❌ | **MANQUANT BACKEND** |
|
||
|
|
| GET /api/v1/playlists/recommendations | GetRecommendations | playlistService.getRecommendations() | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/playlists/:id | GetPlaylist | playlistService.getPlaylist() | usePlaylist | ⚠️ ID type | PARTIEL |
|
||
|
|
| POST /api/v1/playlists | CreatePlaylist | playlistService.createPlaylist() | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| PUT /api/v1/playlists/:id | UpdatePlaylist | playlistService.updatePlaylist() | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| DELETE /api/v1/playlists/:id | DeletePlaylist | playlistService.deletePlaylist() | - | ⚠️ ID type | PARTIEL |
|
||
|
|
| POST /api/v1/playlists/:id/tracks | AddTrack | playlistService.addTrack() | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/playlists/:id/tracks/:track_id | RemoveTrack | playlistService.removeTrack() | - | ⚠️ | PARTIEL |
|
||
|
|
| PUT /api/v1/playlists/:id/tracks/reorder | ReorderTracks | playlistService.reorderTracks() | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/playlists/:id/collaborators | AddCollaborator | - | - | ❌ | **MANQUANT FRONTEND** |
|
||
|
|
| GET /api/v1/playlists/:id/collaborators | GetCollaborators | - | - | ❌ | **MANQUANT FRONTEND** |
|
||
|
|
| PUT /api/v1/playlists/:id/collaborators/:userId | UpdateCollaboratorPermission | - | - | ❌ | **MANQUANT FRONTEND** |
|
||
|
|
| DELETE /api/v1/playlists/:id/collaborators/:userId | RemoveCollaborator | - | - | ❌ | **MANQUANT FRONTEND** |
|
||
|
|
| POST /api/v1/playlists/:id/share | CreateShareLink | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **SESSIONS** |
|
||
|
|
| POST /api/v1/sessions/logout | Logout | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/sessions/logout-all | LogoutAll | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/sessions | GetSessions | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/sessions/:session_id | RevokeSession | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/sessions/stats | GetSessionStats | - | - | ❌ | **MANQUANT FRONTEND** |
|
||
|
|
| POST /api/v1/sessions/refresh | RefreshSession | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **CONVERSATIONS** |
|
||
|
|
| GET /api/v1/conversations | GetUserRooms | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/conversations | CreateRoom | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/conversations/:id | GetRoom | - | - | ⚠️ | PARTIEL |
|
||
|
|
| PUT /api/v1/conversations/:id | UpdateRoom | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/conversations/:id | DeleteRoom | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/conversations/:id/members | AddMember | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/conversations/:id/participants | AddParticipant | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/conversations/:id/participants/:userId | RemoveParticipant | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/conversations/:id/history | GetRoomHistory | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **NOTIFICATIONS** |
|
||
|
|
| GET /api/v1/notifications | GetNotifications | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/notifications/:id/read | MarkAsRead | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/notifications/read-all | MarkAllAsRead | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **ROLES** |
|
||
|
|
| GET /api/v1/roles | GetRoles | roleService.getRoles() | - | ✅ | OK |
|
||
|
|
| GET /api/v1/roles/:id | GetRole | roleService.getRole() | - | ✅ | OK |
|
||
|
|
| POST /api/v1/users/:userId/roles | AssignRole | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/users/:userId/roles/:roleId | RevokeRole | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **WEBHOOKS** |
|
||
|
|
| POST /api/v1/webhooks | RegisterWebhook | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/webhooks | ListWebhooks | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/webhooks/:id | DeleteWebhook | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/webhooks/stats | GetWebhookStats | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/webhooks/:id/test | TestWebhook | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/webhooks/:id/regenerate-key | RegenerateAPIKey | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **MARKETPLACE** |
|
||
|
|
| GET /api/v1/marketplace/products | ListProducts | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/marketplace/products | CreateProduct | - | - | ⚠️ | PARTIEL |
|
||
|
|
| PUT /api/v1/marketplace/products/:id | UpdateProduct | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/marketplace/orders | ListOrders | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/marketplace/orders/:id | GetOrder | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/marketplace/orders | CreateOrder | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/marketplace/download/:product_id | GetDownloadURL | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **ANALYTICS** |
|
||
|
|
| POST /api/v1/analytics/events | RecordEvent | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/analytics/tracks/:id | GetTrackAnalyticsDashboard | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **UPLOADS** |
|
||
|
|
| POST /api/v1/uploads | UploadFile | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/uploads/batch | BatchUpload | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/uploads/:id/status | GetUploadStatus | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/uploads/:id/progress | UploadProgress | - | - | ⚠️ | PARTIEL |
|
||
|
|
| DELETE /api/v1/uploads/:id | DeleteUpload | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/uploads/stats | GetUploadStats | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **AUDIT** |
|
||
|
|
| GET /api/v1/audit/logs | SearchLogs | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/audit/stats | GetStats | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/audit/activity | GetUserActivity | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/audit/suspicious | DetectSuspiciousActivity | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/audit/ip/:ip | GetIPActivity | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/audit/logs/:id | GetAuditLog | - | - | ⚠️ | PARTIEL |
|
||
|
|
| POST /api/v1/audit/cleanup | CleanupOldLogs | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **CHAT** |
|
||
|
|
| POST /api/v1/chat/token | GetToken | - | - | ⚠️ | PARTIEL |
|
||
|
|
| GET /api/v1/chat/stats | GetStats | - | - | ⚠️ | PARTIEL |
|
||
|
|
| **CSRF** |
|
||
|
|
| GET /api/v1/csrf-token | GetCSRFToken | csrfService.refreshToken() | - | ✅ | OK |
|
||
|
|
|
||
|
|
**Légende:**
|
||
|
|
- ✅ OK: Endpoint utilisé, types alignés
|
||
|
|
- ⚠️ PARTIEL: Endpoint utilisé mais problèmes de types ou utilisation incomplète
|
||
|
|
- ❌ MANQUANT: Endpoint manquant côté backend ou frontend
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. Analyse des Incohérences de Types
|
||
|
|
|
||
|
|
### 2.1 Tableau des Incohérences
|
||
|
|
|
||
|
|
| Type | Champ | Backend Go (DTO) | Frontend TS | Différences | Impact | Fichiers Affectés |
|
||
|
|
|------|-------|------------------|-------------|-------------|--------|-------------------|
|
||
|
|
| User | id | uuid.UUID (string) | string | Parfois number dans composants | 🔴 CRITIQUE | types/api.ts, types/index.ts |
|
||
|
|
| User | role | string | 'user' \| 'admin' \| 'super_admin' | Enum frontend vs string backend | ⚠️ MOYEN | types/api.ts |
|
||
|
|
| Track | id | uuid.UUID (string) | string | Cohérent | ✅ OK | features/tracks/types/track.ts |
|
||
|
|
| Track | creator_id | uuid.UUID (string) | string | Cohérent | ✅ OK | features/tracks/types/track.ts |
|
||
|
|
| Track | status | TrackStatus (enum) | TrackStatus (enum) | Valeurs: 'uploading' \| 'processing' \| 'completed' \| 'failed' vs backend: 'uploading' \| 'processing' \| 'ready' \| 'error' | 🔴 CRITIQUE | models/track.go vs features/tracks/types/track.ts |
|
||
|
|
| Track | stream_status | string | string | Cohérent | ✅ OK | - |
|
||
|
|
| Playlist | id | uuid.UUID (string) | string | Cohérent | ✅ OK | types/api.ts, features/playlists/types.ts |
|
||
|
|
| Playlist | user_id | uuid.UUID (string) | string | Cohérent | ✅ OK | - |
|
||
|
|
| Playlist | title | string (column: name) | string | Backend utilise 'name' en DB mais 'title' en JSON | ⚠️ MOYEN | models/playlist.go |
|
||
|
|
| Playlist | visibility | - | - | Pas d'enum défini | ⚠️ MOYEN | - |
|
||
|
|
| ApiError | code | string | string | Cohérent | ✅ OK | - |
|
||
|
|
| ApiError | message | string | string | Cohérent | ✅ OK | - |
|
||
|
|
| ApiError | details | []ErrorDetail | ErrorDetail[]? | Cohérent | ✅ OK | - |
|
||
|
|
| ApiError | field_errors | map[string]string | Record<string, string>? | Cohérent | ✅ OK | - |
|
||
|
|
| ApiError | request_id | string | string? | Cohérent | ✅ OK | - |
|
||
|
|
| PaginatedResponse | items | T[] | T[] | Cohérent | ✅ OK | - |
|
||
|
|
| PaginatedResponse | total | int | number | Cohérent | ✅ OK | - |
|
||
|
|
| PaginatedResponse | page | int | number | Cohérent | ✅ OK | - |
|
||
|
|
| PaginatedResponse | limit | int | number | Cohérent | ✅ OK | - |
|
||
|
|
| AuthResponse | access_token | string | string | Cohérent | ✅ OK | - |
|
||
|
|
| AuthResponse | refresh_token | string | string | Cohérent | ✅ OK | - |
|
||
|
|
| AuthResponse | expires_in | int | number? | Cohérent | ✅ OK | - |
|
||
|
|
| AuthResponse | token_type | string | string? | Cohérent | ✅ OK | - |
|
||
|
|
| AuthResponse | user | UserResponse | User | Cohérent | ✅ OK | - |
|
||
|
|
|
||
|
|
### 2.2 Problèmes Identifiés
|
||
|
|
|
||
|
|
1. **User.id**: Défini comme `string` dans types mais peut être utilisé comme `number` dans certains composants
|
||
|
|
2. **Track.status**: Enum frontend (`'uploading' | 'processing' | 'completed' | 'failed'`) vs backend (`'uploading' | 'processing' | 'ready' | 'error'`) - **INCOHÉRENCE MAJEURE**
|
||
|
|
3. **Playlist.title**: Backend utilise `name` en DB mais `title` en JSON - confusion potentielle
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. Analyse des Clients API
|
||
|
|
|
||
|
|
### 3.1 Clients Identifiés
|
||
|
|
|
||
|
|
| Fichier | Type | Utilisé par | Problèmes |
|
||
|
|
|---------|------|-------------|-----------|
|
||
|
|
| `services/api/client.ts` | Axios + interceptors | ✅ Tous les nouveaux services | ✅ OK - Client principal |
|
||
|
|
| `services/api/typedClient.ts` | Wrapper typé | ✅ Services typés | ✅ OK - Wrapper |
|
||
|
|
| `services/api/clientWithValidation.ts` | Wrapper validation Zod | ✅ Services validés | ✅ OK - Wrapper |
|
||
|
|
| `lib/apiClient.ts` | ❌ N'existe pas | - | ✅ Pas de duplication |
|
||
|
|
|
||
|
|
**Conclusion:** Un seul client API principal, pas de duplication. ✅
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. Analyse des Stores
|
||
|
|
|
||
|
|
### 4.1 Stores Identifiés
|
||
|
|
|
||
|
|
| Store | Fichier | Utilisé | Duplication avec |
|
||
|
|
|-------|---------|---------|------------------|
|
||
|
|
| authStore | `stores/auth.ts` | ✅ 75+ fichiers | ❌ Pas de duplication |
|
||
|
|
| - | `features/auth/store/authStore.ts` | ❌ N'existe pas | - |
|
||
|
|
|
||
|
|
**Conclusion:** Un seul store auth, pas de duplication. ✅
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. Analyse CORS/CSRF/Security
|
||
|
|
|
||
|
|
### 5.1 Configuration CORS
|
||
|
|
|
||
|
|
| Aspect | Backend Config | Frontend Config | Aligné | Problème |
|
||
|
|
|--------|----------------|-----------------|--------|----------|
|
||
|
|
| CORS Origins | CORS_ALLOWED_ORIGINS | - | ❌ | **🔴 CRITIQUE: Vide = rejet total en production** |
|
||
|
|
| CORS Methods | GET, POST, PUT, DELETE, OPTIONS | - | ✅ | OK |
|
||
|
|
| CORS Headers | Authorization, Content-Type, X-Requested-With | - | ⚠️ | Manque X-CSRF-Token dans AllowHeaders |
|
||
|
|
| CORS Credentials | true | - | ✅ | OK |
|
||
|
|
| Preflight | OPTIONS → 204 | - | ✅ | OK |
|
||
|
|
|
||
|
|
**Problème identifié:**
|
||
|
|
- `CORS_ALLOWED_ORIGINS` vide en production = **TOUTES les requêtes CORS rejetées**
|
||
|
|
- Le middleware CORS rejette explicitement si liste vide (ligne 119 de cors.go)
|
||
|
|
- Validation en production échoue au démarrage si vide (ligne 30-38 de cors.go)
|
||
|
|
|
||
|
|
### 5.2 Configuration CSRF
|
||
|
|
|
||
|
|
| Aspect | Backend Config | Frontend Config | Aligné | Problème |
|
||
|
|
|--------|----------------|-----------------|--------|----------|
|
||
|
|
| CSRF Token | X-CSRF-Token header | csrfService.ts | ✅ | OK |
|
||
|
|
| CSRF Storage | Redis | - | ⚠️ | **🔴 CRITIQUE: Désactivé si Redis indisponible** |
|
||
|
|
| CSRF TTL | 1 heure | - | ✅ | OK |
|
||
|
|
| CSRF Refresh | GET /csrf-token | csrfService.refreshToken() | ✅ | OK |
|
||
|
|
|
||
|
|
**Problème identifié:**
|
||
|
|
- CSRF middleware désactivé si Redis indisponible (ligne 65-68 de router.go)
|
||
|
|
- En production, Redis DOIT être disponible pour sécurité
|
||
|
|
- Pas de fail-fast si Redis indisponible en production
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. Analyse Format Réponses API
|
||
|
|
|
||
|
|
### 6.1 Formats Identifiés
|
||
|
|
|
||
|
|
| Endpoint | Backend Response | Frontend Attend | Transformé par | OK |
|
||
|
|
|----------|------------------|-----------------|----------------|-----|
|
||
|
|
| POST /auth/login | {success: true, data: {access_token...}} | {access_token...} | Interceptor unwrap | ✅ |
|
||
|
|
| GET /tracks | {tracks: [...], pagination: {...}} | {tracks: [...], pagination: {...}} | Direct | ✅ |
|
||
|
|
| GET /tracks/search | {tracks: [...], total: ...} | {tracks: [...], total: ...} | Direct | ✅ |
|
||
|
|
| POST /tracks | {success: true, data: Track} | Track | Interceptor unwrap | ✅ |
|
||
|
|
| GET /users/:id | {success: true, data: User} | User | Interceptor unwrap | ✅ |
|
||
|
|
|
||
|
|
**Conclusion:** Format cohérent, interceptor gère correctement l'unwrapping. ✅
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 7. Problèmes Identifiés (Liste Exhaustive)
|
||
|
|
|
||
|
|
### 🔴 CRITIQUES (Bloquent production)
|
||
|
|
|
||
|
|
#### 1. [CORS-001] CORS_ALLOWED_ORIGINS vide en production = rejet total
|
||
|
|
- **Fichier:** `veza-backend-api/internal/middleware/cors.go:119`
|
||
|
|
- **Impact:** Application totalement inaccessible depuis le frontend
|
||
|
|
- **Solution:** Définir `CORS_ALLOWED_ORIGINS` explicitement dans `.env.production`
|
||
|
|
- **Priorité:** P0
|
||
|
|
|
||
|
|
#### 2. [CSRF-001] CSRF désactivé si Redis indisponible
|
||
|
|
- **Fichier:** `veza-backend-api/internal/api/router.go:65-68`
|
||
|
|
- **Impact:** Vulnérabilité de sécurité majeure en production
|
||
|
|
- **Solution:** Fail-fast en production si Redis indisponible
|
||
|
|
- **Priorité:** P0
|
||
|
|
|
||
|
|
#### 3. [TYPE-001] Track.status: valeurs différentes backend/frontend
|
||
|
|
- **Backend:** `'uploading' | 'processing' | 'ready' | 'error'`
|
||
|
|
- **Frontend:** `'uploading' | 'processing' | 'completed' | 'failed'`
|
||
|
|
- **Fichiers:** `veza-backend-api/internal/models/track.go:30` vs `apps/web/src/features/tracks/types/track.ts:6`
|
||
|
|
- **Impact:** Erreurs runtime lors de la comparaison de statuts
|
||
|
|
- **Solution:** Aligner les valeurs (utiliser backend comme source de vérité)
|
||
|
|
- **Priorité:** P0
|
||
|
|
|
||
|
|
### ⚠️ MAJEURS (Fonctionnent mais fragiles)
|
||
|
|
|
||
|
|
#### 4. [TYPE-002] User.id peut être number dans certains composants
|
||
|
|
- **Fichiers:** `apps/web/src/types/api.ts:3`, `apps/web/src/types/index.ts:4`
|
||
|
|
- **Impact:** Erreurs de comparaison, bugs intermittents
|
||
|
|
- **Solution:** S'assurer que User.id est toujours string partout
|
||
|
|
- **Priorité:** P1
|
||
|
|
|
||
|
|
#### 5. [ENDPOINT-001] GET /api/v1/users/search appelé par frontend mais n'existe pas backend
|
||
|
|
- **Frontend:** `apps/web/src/features/search/services/searchService.ts:40`
|
||
|
|
- **Backend:** Route non trouvée dans `router.go`
|
||
|
|
- **Impact:** Erreur 404 lors de la recherche d'utilisateurs
|
||
|
|
- **Solution:** Implémenter endpoint backend
|
||
|
|
- **Priorité:** P1
|
||
|
|
|
||
|
|
#### 6. [ENDPOINT-002] GET /api/v1/tracks/search appelé par frontend mais n'existe pas backend
|
||
|
|
- **Frontend:** `apps/web/src/features/tracks/services/trackSearchService.ts:152`
|
||
|
|
- **Backend:** Route existe dans router.go:734 mais peut-être non fonctionnelle
|
||
|
|
- **Impact:** Erreur 404 ou réponse incorrecte
|
||
|
|
- **Solution:** Vérifier et corriger endpoint backend
|
||
|
|
- **Priorité:** P1
|
||
|
|
|
||
|
|
#### 7. [ENDPOINT-003] GET /api/v1/playlists/search appelé par frontend mais backend TODO
|
||
|
|
- **Frontend:** `apps/web/src/features/playlists/services/playlistService.ts:193`
|
||
|
|
- **Backend:** TODO comment dans code frontend
|
||
|
|
- **Impact:** Erreur 404
|
||
|
|
- **Solution:** Implémenter endpoint backend
|
||
|
|
- **Priorité:** P1
|
||
|
|
|
||
|
|
#### 8. [ENDPOINT-004] GET /api/v1/sessions/stats existe backend mais non utilisé frontend
|
||
|
|
- **Backend:** `veza-backend-api/internal/api/router.go:1207`
|
||
|
|
- **Frontend:** Non utilisé
|
||
|
|
- **Impact:** Fonctionnalité manquante
|
||
|
|
- **Solution:** Créer service frontend
|
||
|
|
- **Priorité:** P2
|
||
|
|
|
||
|
|
#### 9. [ENDPOINT-005] Endpoints playlist collaborators manquants frontend
|
||
|
|
- **Backend:** POST/DELETE/PUT `/api/v1/playlists/:id/collaborators`
|
||
|
|
- **Frontend:** Non implémenté
|
||
|
|
- **Impact:** Fonctionnalité collaboration manquante
|
||
|
|
- **Solution:** Implémenter services frontend
|
||
|
|
- **Priorité:** P2
|
||
|
|
|
||
|
|
#### 10. [TYPE-003] Playlist.title vs Playlist.name confusion
|
||
|
|
- **Backend:** Colonne DB = `name`, JSON = `title`
|
||
|
|
- **Frontend:** Utilise `title`
|
||
|
|
- **Impact:** Confusion potentielle
|
||
|
|
- **Solution:** Documenter ou standardiser
|
||
|
|
- **Priorité:** P2
|
||
|
|
|
||
|
|
### 🟡 MINEURS (Dettes techniques)
|
||
|
|
|
||
|
|
#### 11. [CLEANUP-001] Types dupliqués entre types/ et features/*/types/
|
||
|
|
- **Fichiers:** `types/api.ts` vs `features/*/types/*.ts`
|
||
|
|
- **Impact:** Maintenance difficile
|
||
|
|
- **Solution:** Consolider dans types/
|
||
|
|
- **Priorité:** P2
|
||
|
|
|
||
|
|
#### 12. [CLEANUP-002] Endpoints 2FA non utilisés frontend
|
||
|
|
- **Backend:** 4 endpoints 2FA implémentés
|
||
|
|
- **Frontend:** Non utilisés
|
||
|
|
- **Impact:** Fonctionnalité inutilisée
|
||
|
|
- **Solution:** Implémenter ou documenter comme future feature
|
||
|
|
- **Priorité:** P3
|
||
|
|
|
||
|
|
#### 13. [DOC-001] Documentation OpenAPI/Swagger incomplète
|
||
|
|
- **Backend:** Swagger configuré mais annotations manquantes
|
||
|
|
- **Impact:** Documentation API incomplète
|
||
|
|
- **Solution:** Ajouter annotations Swagger
|
||
|
|
- **Priorité:** P3
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 8. Recommandations
|
||
|
|
|
||
|
|
### Immédiat (P0)
|
||
|
|
1. ✅ Configurer `CORS_ALLOWED_ORIGINS` pour production
|
||
|
|
2. ✅ Fail-fast si Redis indisponible en production (CSRF)
|
||
|
|
3. ✅ Aligner Track.status backend/frontend
|
||
|
|
|
||
|
|
### Court terme (P1)
|
||
|
|
1. Standardiser User.id comme string partout
|
||
|
|
2. Implémenter endpoints search manquants backend
|
||
|
|
3. Vérifier et corriger tracks/search endpoint
|
||
|
|
|
||
|
|
### Moyen terme (P2)
|
||
|
|
1. Implémenter services frontend pour endpoints manquants
|
||
|
|
2. Consolider types dupliqués
|
||
|
|
3. Documenter Playlist.title vs name
|
||
|
|
|
||
|
|
### Long terme (P3)
|
||
|
|
1. Implémenter 2FA frontend ou documenter comme future
|
||
|
|
2. Compléter documentation OpenAPI
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 9. Métriques de Qualité
|
||
|
|
|
||
|
|
### Couverture Endpoints
|
||
|
|
- **Backend → Frontend:** 45/85 (53%)
|
||
|
|
- **Frontend → Backend:** 42/45 (93%)
|
||
|
|
|
||
|
|
### Alignement Types
|
||
|
|
- **Types alignés:** 15/27 (56%)
|
||
|
|
- **Types à corriger:** 12/27 (44%)
|
||
|
|
|
||
|
|
### Code Duplication
|
||
|
|
- **Clients API:** 0 duplication ✅
|
||
|
|
- **Stores:** 0 duplication ✅
|
||
|
|
- **Types:** 3 duplications ⚠️
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 10. Conclusion
|
||
|
|
|
||
|
|
L'intégration backend/frontend est **fonctionnelle mais nécessite des corrections critiques** avant le déploiement en production. Les principaux problèmes sont:
|
||
|
|
|
||
|
|
1. **Configuration CORS** (bloqueur production)
|
||
|
|
2. **Protection CSRF** (sécurité)
|
||
|
|
3. **Incohérences de types** (bugs potentiels)
|
||
|
|
|
||
|
|
Une fois ces problèmes résolus, l'intégration devrait atteindre un score de **9/10**.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Prochaines étapes:** Voir `VEZA_INTEGRATION_PERFECTION_TODOLIST_TEMPLATE.json` pour la liste détaillée des tâches.
|
||
|
|
|