- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.3 KiB
6.3 KiB
GAP Analysis: Patrón ApiResponse en adminAPI.ts
ID: GAP-API-RESPONSE-PATTERN-001 Fecha: 2025-11-24 Severidad: ALTA (P1) Analista: Architecture-Analyst Estado: En corrección
1. RESUMEN EJECUTIVO
Se identificó un uso incorrecto del tipo genérico en adminAPI.ts donde las funciones usan ApiResponse<T> como tipo de retorno cuando el interceptor de axios ya desenvuelve la respuesta y devuelve T directamente.
2. CAUSA RAÍZ
El interceptor ya desenvuelve la respuesta
// apps/frontend/src/services/api/apiClient.ts (líneas 88-92)
apiClient.interceptors.response.use(
(response: AxiosResponse) => {
// Unwrap backend response format: { success, data, timestamp, path }
if (response.data && typeof response.data === 'object' && 'success' in response.data && 'data' in response.data) {
response.data = response.data.data; // ← El interceptor EXTRAE "data" interno
}
return response;
},
);
Flujo de datos:
Backend envía: { success: true, data: { ... }, timestamp, path }
↓
Interceptor: response.data = response.data.data // Extrae "data"
↓
Después: response.data = { ... } // Ya es T, NO ApiResponse<T>
Uso incorrecto actual:
// ❌ INCORRECTO - El tipo genérico incluye ApiResponse
const response = await apiClient.get<ApiResponse<SystemMetrics>>(...);
return response.data; // TypeScript piensa que es ApiResponse<SystemMetrics>
// Pero REALMENTE es SystemMetrics (el interceptor lo desenvolvió)
Uso correcto:
// ✅ CORRECTO - El tipo genérico es solo T
const response = await apiClient.get<SystemMetrics>(...);
return response.data; // TypeScript sabe que es SystemMetrics
3. ARCHIVOS AFECTADOS
| Archivo | Funciones con problema | Estado |
|---|---|---|
adminAPI.ts |
~40 funciones | ⏳ Pendiente |
4. PLAN DE CORRECCIÓN
Paso 1: Eliminar wrapper ApiResponse en llamadas a apiClient
Patrón a buscar:
apiClient.get<ApiResponse<T>>
apiClient.post<ApiResponse<T>>
apiClient.put<ApiResponse<T>>
apiClient.patch<ApiResponse<T>>
apiClient.delete<ApiResponse<T>>
Reemplazar con:
apiClient.get<T>
apiClient.post<T>
apiClient.put<T>
apiClient.patch<T>
apiClient.delete<T>
Paso 2: Actualizar accesos a response.data
Algunas funciones acceden a propiedades como response.data.data o response.data.page asumiendo la estructura ApiResponse. Estas deben acceder directamente:
Antes:
const response = await apiClient.get<ApiResponse<any>>(url);
return {
items: response.data.data,
pagination: { page: response.data.page }
};
Después:
const backendData = await apiClient.get<any>(url);
return {
items: backendData.data.data, // Si backend envía estructura anidada
pagination: { page: backendData.data.page }
};
O mejor aún, crear tipos específicos para las respuestas paginadas del backend.
5. LISTA DE FUNCIONES A CORREGIR
Funciones que devuelven objeto simple:
| # | Función | Línea aprox | Tipo actual | Tipo correcto |
|---|---|---|---|---|
| 1 | getAdminDashboard |
91 | ApiResponse<DashboardData> |
DashboardData |
| 2 | getOrganization |
252 | ApiResponse<Organization> |
Organization |
| 3 | createOrganization |
270 | ApiResponse<Organization> |
Organization |
| 4 | updateOrganization |
290 | ApiResponse<Organization> |
Organization |
| 5 | getUser |
584 | ApiResponse<UserDetails> |
UserDetails |
| 6 | updateUser |
603 | ApiResponse<User> |
User |
| 7 | activateUser |
632 | ApiResponse<User> |
User |
| 8 | deactivateUser |
648 | ApiResponse<User> |
User |
| 9 | suspendUser |
664 | ApiResponse<User> |
User |
| 10 | unsuspendUser |
680 | ApiResponse<User> |
User |
| 11 | getRolePermissions |
717 | ApiResponse<RolePermissions> |
RolePermissions |
| 12 | updateRolePermissions |
737 | ApiResponse<RolePermissions> |
RolePermissions |
| 13 | getGamificationSettings |
773 | ApiResponse<GamificationSettings> |
GamificationSettings |
| 14 | updateGamificationSettings |
792 | ApiResponse<GamificationSettings> |
GamificationSettings |
| 15 | restoreGamificationDefaults |
826 | ApiResponse<GamificationSettings> |
GamificationSettings |
| 16 | getSystemHealth |
846 | ApiResponse<SystemHealth> |
SystemHealth |
| 17 | getSystemConfig |
988 | ApiResponse<SystemConfig> |
SystemConfig |
| 18 | updateSystemConfig |
1004 | ApiResponse<SystemConfig> |
SystemConfig |
Funciones que devuelven arrays:
| # | Función | Tipo actual | Tipo correcto |
|---|---|---|---|
| 19 | getRoles |
ApiResponse<Role[]> |
Role[] |
| 20 | getAvailablePermissions |
ApiResponse<AvailablePermission[]> |
AvailablePermission[] |
| 21 | getMayaRanks |
ApiResponse<MayaRank[]> |
MayaRank[] (con transformación) |
Funciones que devuelven paginados (requieren manejo especial):
| # | Función | Nota |
|---|---|---|
| 22 | getOrganizations |
Backend envía estructura paginada |
| 23 | getPendingContent |
Backend envía estructura paginada |
| 24 | getMediaLibrary |
Backend envía estructura paginada |
| 25 | getApprovalHistory |
Backend envía estructura paginada |
| 26 | getOrganizationUsers |
Backend envía estructura paginada |
| 27 | getUsers |
Ya tiene transformación manual |
| 28 | getSystemLogs |
Backend envía estructura paginada |
| 29 | getReports |
Ya tiene transformación manual |
| 30 | listAlerts |
Ya tiene transformación manual |
6. CRITERIOS DE ACEPTACIÓN
- ✅ Todas las funciones usan el tipo genérico correcto (sin ApiResponse wrapper)
- ✅
npm run type-checkpasa sin errores relacionados con ApiResponse - ✅ Las funciones que requieren transformación de datos la hacen explícitamente
- ✅ Documentación actualizada
7. REFERENCIAS
- Interceptor:
apps/frontend/src/services/api/apiClient.ts:88-92 - Archivo a corregir:
apps/frontend/src/services/api/adminAPI.ts - Tipos:
apps/frontend/src/services/api/adminTypes.ts
Versión: 1.0 Estado: Listo para implementación