diff --git a/VEZA_INTEGRATION_PERFECTION_TODOLIST_TEMPLATE.json b/VEZA_INTEGRATION_PERFECTION_TODOLIST_TEMPLATE.json index 6d71112fc..693f6a9b0 100644 --- a/VEZA_INTEGRATION_PERFECTION_TODOLIST_TEMPLATE.json +++ b/VEZA_INTEGRATION_PERFECTION_TODOLIST_TEMPLATE.json @@ -708,7 +708,8 @@ "description": "Tous les types partagés doivent être dans types/ et non dupliqués dans features/.", "priority": "P2", "priority_rank": 21, - "status": "todo", + "status": "completed", + "completed_at": "2025-01-27T16:45:00Z", "estimated_hours": 2, "side": "frontend_only", "files_to_modify": [ @@ -1102,13 +1103,13 @@ }, "progress_tracking": { "total_tasks": 32, - "completed": 20, + "completed": 21, "in_progress": 0, - "todo": 12, + "todo": 11, "blocked": 0, - "completion_percentage": 63, - "last_updated": "2025-01-27T16:30:00Z", + "completion_percentage": 66, + "last_updated": "2025-01-27T16:45:00Z", "estimated_completion_date": null, - "estimated_hours_remaining": 18.5 + "estimated_hours_remaining": 16.5 } } diff --git a/apps/web/src/features/auth/services/emailVerificationService.ts b/apps/web/src/features/auth/services/emailVerificationService.ts index c92d669be..9150aff1b 100644 --- a/apps/web/src/features/auth/services/emailVerificationService.ts +++ b/apps/web/src/features/auth/services/emailVerificationService.ts @@ -1,17 +1,13 @@ +// INT-CLEANUP-002: Use standardized ApiError from @/types/api instead of duplicating import { apiClient } from '@/services/api/client'; import axios, { AxiosError } from 'axios'; +import type { ApiError } from '@/types/api'; export interface VerifyEmailResponse { message: string; user_id: string; } -export interface ApiError { - message: string; - code?: string; - details?: Record; -} - /** * Vérifie l'email avec un token de vérification * T0185: Appelle l'endpoint GET /api/v1/auth/verify-email?token=... @@ -52,26 +48,32 @@ export async function verifyEmail(token: string): Promise { 'Verification failed'; const apiError: ApiError = { + code: axiosError.response.status, message: errorMessage, - code: axiosError.response.status.toString(), - details: axiosError.response.data as Record, + timestamp: new Date().toISOString(), + details: Array.isArray(axiosError.response.data?.details) + ? axiosError.response.data.details + : undefined, + context: axiosError.response.data as Record, }; throw apiError; } else if (axiosError.request) { // Requête envoyée mais pas de réponse throw { + code: 0, message: 'Network error: Unable to connect to server', - code: 'NETWORK_ERROR', + timestamp: new Date().toISOString(), } as ApiError; } } // Erreur inconnue throw { + code: 0, message: error instanceof Error ? error.message : 'An unexpected error occurred', - code: 'UNKNOWN_ERROR', + timestamp: new Date().toISOString(), } as ApiError; } } @@ -110,26 +112,32 @@ export async function resendVerificationEmail( 'Failed to resend verification email'; const apiError: ApiError = { + code: axiosError.response.status, message: errorMessage, - code: axiosError.response.status.toString(), - details: axiosError.response.data as Record, + timestamp: new Date().toISOString(), + details: Array.isArray(axiosError.response.data?.details) + ? axiosError.response.data.details + : undefined, + context: axiosError.response.data as Record, }; throw apiError; } else if (axiosError.request) { // Requête envoyée mais pas de réponse throw { + code: 0, message: 'Network error: Unable to connect to server', - code: 'NETWORK_ERROR', + timestamp: new Date().toISOString(), } as ApiError; } } // Erreur inconnue throw { + code: 0, message: error instanceof Error ? error.message : 'An unexpected error occurred', - code: 'UNKNOWN_ERROR', + timestamp: new Date().toISOString(), } as ApiError; } } diff --git a/apps/web/src/features/auth/types/index.ts b/apps/web/src/features/auth/types/index.ts index 7ea04d2cc..319bd84e7 100644 --- a/apps/web/src/features/auth/types/index.ts +++ b/apps/web/src/features/auth/types/index.ts @@ -1,10 +1,8 @@ -export interface User { - // UUID from backend - always string - id: string; - email: string; - username?: string; - role?: string; -} +// INT-CLEANUP-002: Import shared types from @/types instead of duplicating +import type { User, AuthTokens } from '@/types'; + +// Re-export for backward compatibility +export type { User, AuthTokens }; export interface LoginCredentials { email: string; @@ -19,14 +17,9 @@ export interface RegisterCredentials { username?: string; } -export interface AuthTokens { - access_token: string; - refresh_token: string; - expires_in: number; -} - // INT-TYPE-008: AuthResponse aligned with backend LoginResponse (dto.LoginResponse) // Backend format: { user: UserResponse, token: TokenResponse, requires_2fa?: boolean } +// INT-CLEANUP-002: Use User and AuthTokens from @/types export interface AuthResponse { user: User; // Matches backend UserResponse (id, email, username) token: AuthTokens; // Matches backend TokenResponse (access_token, refresh_token, expires_in) diff --git a/apps/web/src/features/playlists/types.ts b/apps/web/src/features/playlists/types.ts index 6726fbf3f..74eebe782 100644 --- a/apps/web/src/features/playlists/types.ts +++ b/apps/web/src/features/playlists/types.ts @@ -2,8 +2,15 @@ * Types pour la feature Playlists * T0451: Structure de base pour les playlists * INT-TYPE-005: PlaylistVisibility enum aligned with backend + * INT-CLEANUP-002: Import Track from tracks/types instead of duplicating */ +// INT-CLEANUP-002: Import Track from tracks/types instead of duplicating +import type { Track } from '@/features/tracks/types/track'; + +// Re-export for backward compatibility +export type { Track }; + /** * PlaylistVisibility enum - aligned with backend visibility concept * Backend currently uses is_public (bool), but enum supports future 'unlisted' value @@ -58,19 +65,6 @@ export interface PlaylistTrack { track?: Track; } -/** - * Interface représentant un track (référence depuis player/types) - */ -export interface Track { - id: string; - title: string; - artist: string; - duration: number; - file_path: string; - cover_art_path?: string; - album?: string; -} - /** * Requête pour créer une playlist */ diff --git a/apps/web/src/features/tracks/services/trackListService.ts b/apps/web/src/features/tracks/services/trackListService.ts index 3d344e84b..647077e92 100644 --- a/apps/web/src/features/tracks/services/trackListService.ts +++ b/apps/web/src/features/tracks/services/trackListService.ts @@ -1,5 +1,7 @@ +// INT-CLEANUP-002: Use standardized ApiError from @/types/api instead of duplicating import { apiClient } from '@/services/api/client'; import type { Track } from '../../player/types'; +import type { ApiError } from '@/types/api'; export interface PaginationOptions { page?: number; @@ -42,10 +44,7 @@ export interface TracksResponse { totalPages?: number; } -export interface ApiError { - message: string; - code?: string; -} +// INT-CLEANUP-002: ApiError removed - use @/types/api instead export async function getTracks( options: GetTracksOptions = {},