import { clientFetch } from '@/lib/api/client'; import { unwrap, type ApiEnvelope } from '@/lib/api/types'; import { AUTH_API_BASE } from '../constants'; import type { AuthApi, AuthTokens, LogoutRequest, Me, OtpRequest, OtpVerify, RefreshRequest, RequestOtpResult, SelectRoleDto, } from '../types'; /** * Real HTTP implementation of the AuthApi seam. `clientFetch` returns the raw server * envelope, so each call reads its payload via `unwrap`. Routes are the exact snake_case * paths from the published swagger (`[controller]/[action]` transform). */ export const authClientApi: AuthApi = { requestOtp: async (body: OtpRequest) => unwrap( await clientFetch>(`${AUTH_API_BASE}/auth/request_otp`, { method: 'POST', body: JSON.stringify(body), }), ), verifyOtp: async (body: OtpVerify) => unwrap( await clientFetch>(`${AUTH_API_BASE}/auth/verify_otp`, { method: 'POST', body: JSON.stringify(body), }), ), refresh: async (body: RefreshRequest) => unwrap( await clientFetch>(`${AUTH_API_BASE}/auth/refresh`, { method: 'POST', body: JSON.stringify(body), }), ), // Success is an empty envelope (no `data`) — don't unwrap, just await the revocation. logout: async (body?: LogoutRequest) => { await clientFetch>(`${AUTH_API_BASE}/auth/logout`, { method: 'POST', body: JSON.stringify(body ?? {}), }); }, getMe: async () => unwrap(await clientFetch>(`${AUTH_API_BASE}/me`)), selectRole: async (body: SelectRoleDto) => unwrap( await clientFetch>(`${AUTH_API_BASE}/me/select_role`, { method: 'POST', body: JSON.stringify(body), }), ), };