[INT-CLEANUP-002] Consolidate type definitions in single location

This commit is contained in:
senke 2025-12-26 09:21:54 +01:00
parent 6d1e3cea3d
commit 0ba99548c0
5 changed files with 45 additions and 50 deletions

View file

@ -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
}
}

View file

@ -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<string, unknown>;
}
/**
* 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<VerifyEmailResponse> {
'Verification failed';
const apiError: ApiError = {
code: axiosError.response.status,
message: errorMessage,
code: axiosError.response.status.toString(),
details: axiosError.response.data as Record<string, unknown>,
timestamp: new Date().toISOString(),
details: Array.isArray(axiosError.response.data?.details)
? axiosError.response.data.details
: undefined,
context: axiosError.response.data as Record<string, unknown>,
};
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<string, unknown>,
timestamp: new Date().toISOString(),
details: Array.isArray(axiosError.response.data?.details)
? axiosError.response.data.details
: undefined,
context: axiosError.response.data as Record<string, unknown>,
};
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;
}
}

View file

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

View file

@ -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
*/

View file

@ -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 = {},