Se duplica el patrón de fetch con manejo de URL, auth y errores en varios services del mobile.
Problema
Actualmente hay 14 llamadas fetch directo distribuidas en 3 services que repiten el mismo boilerplate:
1. venture.service.ts — 7 llamadas raw
// Cada método hace lo mismo
const response = await fetch(`${env.API_URL}/ventures`);
return handleResponse<Venture[]>(response, "errors.venture.fetch_failed");
No inyecta token de auth, usa env.API_URL a mano, repite try/catch + mapNetworkError.
2. project.service.ts — 5 llamadas raw
// Más boilerplate: auth manual + headers
const token = useAuthStore.getState().accessToken;
const response = await fetch(`${env.API_URL}/projects`, {
headers: { Authorization: `Bearer ${token}` },
});
if (!response.ok) return handleResponse(response, "errors.project.fetch_failed");
return response.json();
Inyecta Bearer manualmente en CADA método. Código duplicado 5 veces.
3. auth.service.ts — 2 llamadas raw (login + create tourist)
const response = await fetch(`${env.API_URL}/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(input),
});
return handleResponse<AuthResponse>(response, "errors.auth.invalid_credentials");
No necesita auth token (login es pre-auth), pero igual duplica headers + manejo.
Solución propuesta
Migrar los 3 services a usar apiClient (ya existente en apps/mobile/src/services/api-client.ts):
| Service |
Métodos |
Reemplazo |
venture.service.ts |
7 (getVentures, getVentureById, createVenture, updateVenture, deleteVenture, getVenturesByUserId, getVentureByUserId) |
apiClient.get<Venture[]>("/ventures"), etc. |
project.service.ts |
5 (getProjects, getProjectById, createProject, updateProject, deleteProject) |
apiClient.get<Project[]>("/projects"), etc. |
auth.service.ts |
2 (login, createTourist) |
apiClient.post<AuthResponse>("/auth/login", input), etc. |
apiClient ya maneja:
- ✅ Base URL (
env.API_URL)
- ✅ Auth token injection automática (Bearer header)
- ✅
Content-Type: application/json
- ✅ Error mapping (
handleResponse + mapNetworkError)
No migrar: status.service.ts — pega a /health (no /v1/...), manejo de errores es silencioso (return []), URL usa env.API_URL.replace("/v1", "/health").
Archivos afectados
apps/mobile/src/services/venture.service.ts — reemplazar 7 fetch por apiClient
apps/mobile/src/services/project.service.ts — reemplazar 5 fetch por apiClient, eliminar import de useAuthStore
apps/mobile/src/services/auth.service.ts — reemplazar 2 fetch por apiClient
apps/mobile/src/services/__tests__/venture.service.test.ts — mock apiClient en vez de globalThis.fetch
apps/mobile/src/services/__tests__/project.service.test.ts — mock apiClient en vez de globalThis.fetch
apps/mobile/src/services/__tests__/auth.service.test.ts — mock apiClient en vez de globalThis.fetch
Notas
apiClient.delete ya existe para el DELETE de venture
apiClient.get maneja null/404 correctamente (no hay que checkear response.status === 404)
- Los tests existentes mockean
globalThis.fetch — habría que migrarlos a mockear apiClient (o globalThis.fetch sigue funcionando porque apiClient usa fetch internamente)
auth.service.ts login no tiene token aún → apiClient chequea if (token) antes de inyectar Bearer, así que funciona sin token
Se duplica el patrón de
fetchcon manejo de URL, auth y errores en varios services del mobile.Problema
Actualmente hay 14 llamadas
fetchdirecto distribuidas en 3 services que repiten el mismo boilerplate:1.
venture.service.ts— 7 llamadas rawNo inyecta token de auth, usa
env.API_URLa mano, repitetry/catch+mapNetworkError.2.
project.service.ts— 5 llamadas rawInyecta Bearer manualmente en CADA método. Código duplicado 5 veces.
3.
auth.service.ts— 2 llamadas raw (login + create tourist)No necesita auth token (login es pre-auth), pero igual duplica headers + manejo.
Solución propuesta
Migrar los 3 services a usar
apiClient(ya existente enapps/mobile/src/services/api-client.ts):venture.service.tsgetVentures,getVentureById,createVenture,updateVenture,deleteVenture,getVenturesByUserId,getVentureByUserId)apiClient.get<Venture[]>("/ventures"), etc.project.service.tsgetProjects,getProjectById,createProject,updateProject,deleteProject)apiClient.get<Project[]>("/projects"), etc.auth.service.tslogin,createTourist)apiClient.post<AuthResponse>("/auth/login", input), etc.apiClientya maneja:env.API_URL)Content-Type: application/jsonhandleResponse+mapNetworkError)No migrar:
status.service.ts— pega a/health(no/v1/...), manejo de errores es silencioso (return[]), URL usaenv.API_URL.replace("/v1", "/health").Archivos afectados
apps/mobile/src/services/venture.service.ts— reemplazar 7 fetch por apiClientapps/mobile/src/services/project.service.ts— reemplazar 5 fetch por apiClient, eliminar import deuseAuthStoreapps/mobile/src/services/auth.service.ts— reemplazar 2 fetch por apiClientapps/mobile/src/services/__tests__/venture.service.test.ts— mockapiClienten vez deglobalThis.fetchapps/mobile/src/services/__tests__/project.service.test.ts— mockapiClienten vez deglobalThis.fetchapps/mobile/src/services/__tests__/auth.service.test.ts— mockapiClienten vez deglobalThis.fetchNotas
apiClient.deleteya existe para el DELETE de ventureapiClient.getmaneja null/404 correctamente (no hay que checkearresponse.status === 404)globalThis.fetch— habría que migrarlos a mockearapiClient(oglobalThis.fetchsigue funcionando porqueapiClientusafetchinternamente)auth.service.tslogin no tiene token aún →apiClientchequeaif (token)antes de inyectar Bearer, así que funciona sin token