[FE-TYPE-008] fe-type: Add type definitions for route params
- Created comprehensive route parameter types (routes.ts): * Detail pages: TrackDetailParams, PlaylistDetailParams, UserProfileParams * Chat: ConversationDetailParams, MessageDetailParams * Settings: SessionDetailParams, SettingsParams * Admin: RoleDetailParams, AuditLogDetailParams, AdminParams * Auth: ResetPasswordParams, VerifyEmailParams, OAuthCallbackParams * Search/Filter: SearchParams, LibraryParams, MarketplaceParams * Generic: IdRouteParams, SlugRouteParams, PaginationParams, FilterParams - Added type guards: hasIdParam, hasUsernameParam - Added helper functions: extractRouteParams, extractQueryParams - Ensures type safety for all route navigation and params
This commit is contained in:
parent
729a4435be
commit
9627153921
2 changed files with 265 additions and 2 deletions
|
|
@ -9360,7 +9360,7 @@
|
|||
"description": "Add types for all route parameters",
|
||||
"owner": "frontend",
|
||||
"estimated_hours": 2,
|
||||
"status": "todo",
|
||||
"status": "completed",
|
||||
"files_involved": [],
|
||||
"implementation_steps": [
|
||||
{
|
||||
|
|
@ -9381,7 +9381,8 @@
|
|||
"Unit tests",
|
||||
"Integration tests"
|
||||
],
|
||||
"notes": ""
|
||||
"notes": "Created comprehensive route parameter type definitions. Added types for TrackDetailParams, PlaylistDetailParams, UserProfileParams, ConversationDetailParams, MessageDetailParams, SessionDetailParams, RoleDetailParams, WebhookDetailParams, AuditLogDetailParams, ResetPasswordParams, VerifyEmailParams, OAuthCallbackParams, SearchParams, LibraryParams, MarketplaceParams, AdminParams, SettingsParams, and generic types (IdRouteParams, SlugRouteParams, PaginationParams, FilterParams, DateRangeParams). Added type guards and helper functions for extracting and validating route params.",
|
||||
"completed_at": "2025-12-25T14:45:09.832417Z"
|
||||
},
|
||||
{
|
||||
"id": "FE-TYPE-009",
|
||||
|
|
|
|||
262
apps/web/src/types/routes.ts
Normal file
262
apps/web/src/types/routes.ts
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/**
|
||||
* Route Parameter Types
|
||||
* FE-TYPE-008: Add type definitions for all route parameters
|
||||
*
|
||||
* Comprehensive type definitions for all route parameters used throughout
|
||||
* the application, ensuring type safety for route navigation and params.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Track Detail Route Params
|
||||
* Route: /tracks/:id
|
||||
*/
|
||||
export interface TrackDetailParams {
|
||||
id: string; // Track ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Playlist Detail Route Params
|
||||
* Route: /playlists/:id
|
||||
*/
|
||||
export interface PlaylistDetailParams {
|
||||
id: string; // Playlist ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* User Profile Route Params
|
||||
* Route: /u/:username
|
||||
*/
|
||||
export interface UserProfileParams {
|
||||
username: string; // Username or slug
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversation Detail Route Params
|
||||
* Route: /chat/:id
|
||||
*/
|
||||
export interface ConversationDetailParams {
|
||||
id: string; // Conversation ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Message Detail Route Params
|
||||
* Route: /messages/:id
|
||||
*/
|
||||
export interface MessageDetailParams {
|
||||
id: string; // Message ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Session Detail Route Params
|
||||
* Route: /settings/sessions/:id
|
||||
*/
|
||||
export interface SessionDetailParams {
|
||||
id: string; // Session ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Role Detail Route Params
|
||||
* Route: /admin/roles/:id
|
||||
*/
|
||||
export interface RoleDetailParams {
|
||||
id: string; // Role ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Webhook Detail Route Params
|
||||
* Route: /webhooks/:id
|
||||
*/
|
||||
export interface WebhookDetailParams {
|
||||
id: string; // Webhook ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Audit Log Detail Route Params
|
||||
* Route: /admin/audit/:id
|
||||
*/
|
||||
export interface AuditLogDetailParams {
|
||||
id: string; // Audit Log ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset Password Route Params
|
||||
* Route: /reset-password
|
||||
* Query params: ?token=...
|
||||
*/
|
||||
export interface ResetPasswordParams {
|
||||
token?: string; // Reset token from query string
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify Email Route Params
|
||||
* Route: /verify-email
|
||||
* Query params: ?token=...
|
||||
*/
|
||||
export interface VerifyEmailParams {
|
||||
token?: string; // Verification token from query string
|
||||
}
|
||||
|
||||
/**
|
||||
* OAuth Callback Route Params
|
||||
* Route: /auth/callback
|
||||
* Query params: ?code=...&state=...
|
||||
*/
|
||||
export interface OAuthCallbackParams {
|
||||
code?: string; // OAuth authorization code
|
||||
state?: string; // OAuth state parameter
|
||||
error?: string; // OAuth error code
|
||||
error_description?: string; // OAuth error description
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Route Params
|
||||
* Route: /search
|
||||
* Query params: ?q=...&type=...
|
||||
*/
|
||||
export interface SearchParams {
|
||||
q?: string; // Search query
|
||||
type?: 'track' | 'playlist' | 'user' | 'all'; // Search type
|
||||
page?: string; // Page number
|
||||
limit?: string; // Results per page
|
||||
}
|
||||
|
||||
/**
|
||||
* Library Route Params
|
||||
* Route: /library
|
||||
* Query params: ?filter=...&sort=...
|
||||
*/
|
||||
export interface LibraryParams {
|
||||
filter?: 'all' | 'tracks' | 'playlists' | 'favorites';
|
||||
sort?: 'recent' | 'name' | 'artist' | 'date';
|
||||
page?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marketplace Route Params
|
||||
* Route: /marketplace
|
||||
* Query params: ?category=...&price_min=...&price_max=...
|
||||
*/
|
||||
export interface MarketplaceParams {
|
||||
category?: string;
|
||||
price_min?: string;
|
||||
price_max?: string;
|
||||
sort?: 'price' | 'date' | 'popularity';
|
||||
page?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin Route Params
|
||||
* Route: /admin/*
|
||||
*/
|
||||
export interface AdminParams {
|
||||
section?: 'users' | 'roles' | 'audit' | 'settings';
|
||||
id?: string; // Resource ID
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings Route Params
|
||||
* Route: /settings/*
|
||||
*/
|
||||
export interface SettingsParams {
|
||||
tab?: 'profile' | 'security' | 'notifications' | 'privacy' | 'sessions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Route Params with ID
|
||||
*/
|
||||
export interface IdRouteParams {
|
||||
id: string; // Generic ID (UUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Route Params with Slug
|
||||
*/
|
||||
export interface SlugRouteParams {
|
||||
slug: string; // Generic slug
|
||||
}
|
||||
|
||||
/**
|
||||
* Pagination Route Params (query string)
|
||||
*/
|
||||
export interface PaginationParams {
|
||||
page?: string; // Page number
|
||||
limit?: string; // Items per page
|
||||
cursor?: string; // Cursor for pagination
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter Route Params (query string)
|
||||
*/
|
||||
export interface FilterParams {
|
||||
filter?: string; // Filter value
|
||||
sort?: string; // Sort field
|
||||
order?: 'asc' | 'desc'; // Sort order
|
||||
}
|
||||
|
||||
/**
|
||||
* Date Range Route Params (query string)
|
||||
*/
|
||||
export interface DateRangeParams {
|
||||
start_date?: string; // Start date (ISO8601)
|
||||
end_date?: string; // End date (ISO8601)
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard for route params with ID
|
||||
*/
|
||||
export function hasIdParam(params: unknown): params is IdRouteParams {
|
||||
return (
|
||||
typeof params === 'object' &&
|
||||
params !== null &&
|
||||
'id' in params &&
|
||||
typeof (params as any).id === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard for route params with username
|
||||
*/
|
||||
export function hasUsernameParam(params: unknown): params is UserProfileParams {
|
||||
return (
|
||||
typeof params === 'object' &&
|
||||
params !== null &&
|
||||
'username' in params &&
|
||||
typeof (params as any).username === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to extract and validate route params
|
||||
*/
|
||||
export function extractRouteParams<T extends Record<string, string>>(
|
||||
params: Record<string, string | undefined>,
|
||||
required: (keyof T)[],
|
||||
): T | null {
|
||||
const extracted: Partial<T> = {};
|
||||
|
||||
for (const key of required) {
|
||||
const value = params[key as string];
|
||||
if (!value) {
|
||||
return null; // Required param missing
|
||||
}
|
||||
extracted[key] = value as T[keyof T];
|
||||
}
|
||||
|
||||
return extracted as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to extract query params
|
||||
*/
|
||||
export function extractQueryParams<T extends Record<string, string | undefined>>(
|
||||
searchParams: URLSearchParams,
|
||||
): Partial<T> {
|
||||
const extracted: Partial<T> = {};
|
||||
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
extracted[key as keyof T] = value as T[keyof T];
|
||||
}
|
||||
|
||||
return extracted;
|
||||
}
|
||||
|
||||
Loading…
Reference in a new issue