diff --git a/apps/web/src/features/auth/services/authService.test.ts b/apps/web/src/features/auth/services/authService.test.ts index a18a844fe..f0ef30f45 100644 --- a/apps/web/src/features/auth/services/authService.test.ts +++ b/apps/web/src/features/auth/services/authService.test.ts @@ -33,6 +33,32 @@ const mockedApiClient = apiClient as { get: ReturnType; }; +// v1.0.8 B6 — login / logout / resendVerificationEmail / +// checkUsernameAvailability migrated to orval. Tests still mock +// `apiClient.post/get` for legacy ergonomics; the orval module's +// functions are stubbed to delegate back to those mocks so existing +// `toHaveBeenCalledWith('/auth/...', ...)` assertions keep working. +vi.mock('@/services/generated/auth/auth', () => ({ + postAuthLogin: vi.fn(async (body: unknown) => + mockedApiClient.post('/auth/login', body).then((r: { data?: unknown }) => r?.data), + ), + postAuthLogout: vi.fn(async () => + mockedApiClient.post('/auth/logout').then((r: { data?: unknown }) => r?.data), + ), + postAuthResendVerification: vi.fn(async (body: unknown) => + mockedApiClient + .post('/auth/resend-verification', body) + .then((r: { data?: unknown }) => r?.data), + ), + getAuthCheckUsername: vi.fn(async (params: { username: string }) => + mockedApiClient + .get( + `/auth/check-username?username=${encodeURIComponent(params.username)}`, + ) + .then((r: { data?: unknown }) => r?.data), + ), +})); + describe('authService', () => { beforeEach(() => { vi.clearAllMocks(); diff --git a/apps/web/src/features/auth/services/authService.ts b/apps/web/src/features/auth/services/authService.ts index 1a0a6c474..c16bdbf6d 100644 --- a/apps/web/src/features/auth/services/authService.ts +++ b/apps/web/src/features/auth/services/authService.ts @@ -1,4 +1,32 @@ +/** + * Auth service — orval-backed (partial v1.0.8 B6). + * + * Migrated to orval generated client: + * login, logout, resendVerificationEmail, checkUsernameAvailability. + * + * Still on raw apiClient (deferred v1.0.9 — backend annotation gaps or + * field-name drift would risk breaking auth): + * - register → backend DTO says `password_confirmation` while the + * frontend currently sends `password_confirm` + * (register_request.go:8). Renaming via orval would + * change wire shape; needs explicit verification on + * prod first. + * - refreshToken → same pattern, backend expects `refresh_token` but + * current frontend sends `refreshToken`. + * - requestPasswordReset / resetPassword → endpoints not yet annotated + * in swaggo (no /auth/password/* in openapi.yaml). + * - verifyEmail → frontend uses GET /auth/verify-email?token= but + * orval-generated spec says POST. Verb drift + the + * query→header migration parked in FUNCTIONAL_AUDIT + * §4#7 should land together in v1.0.9. + */ import { apiClient } from '@/services/api/client'; +import { + postAuthLogin, + postAuthLogout, + postAuthResendVerification, + getAuthCheckUsername, +} from '@/services/generated/auth/auth'; import { handleApiServiceError } from '@/utils/serviceErrorHandler'; import type { LoginFormData, @@ -32,8 +60,10 @@ export interface AuthResponse { // INT-API-003: Standardized error handling using handleApiServiceError export async function login(data: LoginFormData): Promise { try { - const response = await apiClient.post('/auth/login', data); - return response.data; + const response = await postAuthLogin( + data as Parameters[0], + ); + return response as unknown as AuthResponse; } catch (error) { handleApiServiceError(error, { context: 'auth', @@ -79,7 +109,9 @@ export async function register(data: RegisterFormData): Promise { // INT-API-003: Standardized error handling using handleApiServiceError export async function logout(): Promise { try { - await apiClient.post('/auth/logout'); + // PostAuthLogoutBody.refresh_token is optional; the cookie-based session + // tear-down doesn't need a body. + await postAuthLogout({}); } catch (error) { handleApiServiceError(error, { context: 'auth' }); } @@ -162,7 +194,7 @@ export async function verifyEmail(token: string): Promise { // INT-API-003: Standardized error handling using handleApiServiceError export async function resendVerificationEmail(email: string): Promise { try { - await apiClient.post('/auth/resend-verification', { email }); + await postAuthResendVerification({ email }); } catch (error) { handleApiServiceError(error, { context: 'auth' }); } @@ -179,10 +211,14 @@ export async function checkUsernameAvailability( username: string, ): Promise { try { - const response = await apiClient.get<{ available: boolean }>( - `/auth/check-username?username=${encodeURIComponent(username)}`, - ); - return response.data.available; + const response = await getAuthCheckUsername({ username }); + const payload = response as unknown as + | { available: boolean } + | { data?: { available?: boolean } }; + if ('available' in payload) { + return payload.available; + } + return payload.data?.available ?? false; } catch (error) { handleApiServiceError(error, { context: 'auth' }); }