workspace/projects/gamilit/apps/frontend/src/config/api.config.ts
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- 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>
2025-12-08 10:44:23 -06:00

657 lines
23 KiB
TypeScript

/**
* API Configuration - Single Source of Truth
*
* IMPORTANTE: Este es el ÚNICO lugar donde se configuran las URLs del API.
* Todos los demás archivos DEBEN importar desde aquí.
*
* @author Architecture-Analyst Agent
* @date 2025-11-24
* @version 1.0.0
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
// ============================================================================
// ENVIRONMENT VARIABLES
// ============================================================================
const API_HOST = import.meta.env.VITE_API_HOST;
const API_PROTOCOL = import.meta.env.VITE_API_PROTOCOL || 'http';
const API_VERSION = import.meta.env.VITE_API_VERSION || 'v1';
const WS_HOST = import.meta.env.VITE_WS_HOST || API_HOST;
const WS_PROTOCOL = import.meta.env.VITE_WS_PROTOCOL || 'ws';
const API_TIMEOUT = parseInt(import.meta.env.VITE_API_TIMEOUT || '30000');
// Validación
if (!API_HOST) {
throw new Error('VITE_API_HOST is required in .env file');
}
// ============================================================================
// API CONFIGURATION
// ============================================================================
/**
* Base API URL
* Construido desde: PROTOCOL://HOST/api/VERSION
* Ejemplo: http://localhost:3006/api/v1
*/
export const API_BASE_URL = `${API_PROTOCOL}://${API_HOST}/api/${API_VERSION}`;
/**
* WebSocket URL
* Construido desde: WS_PROTOCOL://WS_HOST
* Ejemplo: ws://localhost:3006
*/
export const WS_BASE_URL = `${WS_PROTOCOL}://${WS_HOST}`;
/**
* API Configuration Object
*/
export const API_CONFIG = {
baseURL: API_BASE_URL,
wsURL: WS_BASE_URL,
timeout: API_TIMEOUT,
version: API_VERSION,
host: API_HOST,
protocol: API_PROTOCOL,
} as const;
// ============================================================================
// API ENDPOINTS
// ============================================================================
/**
* API Endpoints - Todas las rutas relativas (sin /v1, ya está en baseURL)
*/
export const API_ENDPOINTS = {
/**
* Authentication endpoints
*/
auth: {
login: '/auth/login',
register: '/auth/register',
logout: '/auth/logout',
refresh: '/auth/refresh',
profile: '/auth/profile',
validateToken: '/auth/validate-token',
resetPassword: '/auth/reset-password',
changePassword: '/auth/change-password',
verifyEmail: '/auth/verify-email',
requestPasswordReset: '/auth/request-password-reset',
getCurrentUser: '/auth/me',
updateProfile: '/auth/profile',
getSessions: '/auth/sessions',
revokeSession: (sessionId: string) => `/auth/sessions/${sessionId}`,
},
/**
* Gamification endpoints
*/
gamification: {
userSummary: (userId: string) => `/gamification/users/${userId}/summary`,
userStats: (userId: string) => `/gamification/users/${userId}/stats`,
userRankProgress: (userId: string) => `/gamification/ranks/users/${userId}/rank-progress`,
achievements: '/gamification/achievements',
achievement: (achievementId: string) => `/gamification/achievements/${achievementId}`,
userAchievements: (userId: string) => `/gamification/users/${userId}/achievements`,
leaderboard: '/gamification/leaderboard',
rewards: '/gamification/rewards',
badges: '/gamification/badges',
mlCoins: (userId: string) => `/gamification/users/${userId}/ml-coins`,
},
/**
* Educational endpoints
*/
educational: {
// Modules
modules: '/educational/modules',
module: (id: string) => `/educational/modules/${id}`,
userModules: (userId: string) => `/educational/modules/user/${userId}`,
moduleAccess: (moduleId: string) => `/educational/modules/${moduleId}/access`,
moduleExercises: (moduleId: string) => `/educational/modules/${moduleId}/exercises`,
// Exercises
exercises: '/educational/exercises',
exercise: (id: string) => `/educational/exercises/${id}`,
// Lessons
lessons: '/educational/lessons',
lesson: (id: string) => `/educational/lessons/${id}`,
// User Progress & Analytics (legacy - these should use progress namespace)
userProgress: (userId: string) => `/progress/users/${userId}`,
moduleProgress: (userId: string, moduleId: string) =>
`/progress/users/${userId}/modules/${moduleId}`,
userDashboard: (userId: string) => `/educational/users/${userId}/dashboard`,
exerciseAttempts: (userId: string) => `/progress/attempts/users/${userId}`,
userAnalytics: (userId: string) => `/educational/users/${userId}/analytics`,
activityStats: (userId: string) => `/educational/users/${userId}/activity-stats`,
activitiesByType: (userId: string, type: string) =>
`/educational/users/${userId}/activities/${type}`,
userActivities: (userId: string) => `/educational/users/${userId}/activities`,
},
/**
* Progress endpoints
*/
progress: {
userProgress: (userId: string) => `/progress/users/${userId}`,
moduleProgress: (userId: string, moduleId: string) =>
`/progress/users/${userId}/modules/${moduleId}`,
exerciseProgress: (userId: string, exerciseId: string) =>
`/progress/users/${userId}/exercises/${exerciseId}`,
recentActivities: (userId: string) => `/progress/users/${userId}/recent-activities`,
statistics: (userId: string) => `/progress/users/${userId}/statistics`,
},
/**
* Economy endpoints
*/
economy: {
balance: (userId: string) => `/economy/users/${userId}/balance`,
transactions: (userId: string) => `/economy/users/${userId}/transactions`,
shop: '/economy/shop',
purchase: '/economy/purchase',
earn: '/economy/earn',
spend: '/economy/spend',
shopItems: '/economy/shop/items',
shopItem: (itemId: string) => `/economy/shop/items/${itemId}`,
inventory: (userId: string) => `/economy/users/${userId}/inventory`,
inventoryItem: (userId: string, itemId: string) =>
`/economy/users/${userId}/inventory/${itemId}`,
},
/**
* Social endpoints
*/
social: {
guilds: '/social/guilds',
guild: (id: string) => `/social/guilds/${id}`,
userGuilds: (userId: string) => `/social/users/${userId}/guilds`,
friends: (userId: string) => `/social/users/${userId}/friends`,
messages: (userId: string) => `/social/users/${userId}/messages`,
},
/**
* Notifications endpoints
*/
notifications: {
all: (userId: string) => `/notifications/users/${userId}`,
unread: (userId: string) => `/notifications/users/${userId}/unread`,
markRead: (notificationId: string) => `/notifications/${notificationId}/read`,
markAllRead: (userId: string) => `/notifications/users/${userId}/mark-all-read`,
},
/**
* Admin endpoints
*/
admin: {
// Dashboard
dashboard: '/admin/dashboard',
analytics: {
overview: '/admin/analytics/overview',
engagement: '/admin/analytics/engagement',
gamification: '/admin/analytics/gamification',
activityTimeline: '/admin/analytics/activity-timeline',
topUsers: '/admin/analytics/top-users',
retention: '/admin/analytics/retention',
export: '/admin/analytics/export',
},
settings: '/admin/settings',
// Organizations (nested structure for adminAPI.ts compatibility)
organizations: {
list: '/admin/organizations',
get: (id: string) => `/admin/organizations/${id}`,
create: '/admin/organizations',
update: (id: string) => `/admin/organizations/${id}`,
delete: (id: string) => `/admin/organizations/${id}`,
users: (id: string) => `/admin/organizations/${id}/users`,
updateSubscription: (id: string) => `/admin/organizations/${id}/subscription`,
updateFeatures: (id: string) => `/admin/organizations/${id}/features`,
},
// Backwards compatibility (flat structure)
organization: (id: string) => `/admin/organizations/${id}`,
organizationFeatures: (id: string) => `/admin/organizations/${id}/features`,
organizationSubscription: (id: string) => `/admin/organizations/${id}/subscription`,
organizationUsers: (id: string) => `/admin/organizations/${id}/users`,
// Content Management (includes approvals workflow)
content: {
// Content approval workflow
pending: '/admin/content/pending',
approve: (id: string) => `/admin/content/${id}/approve`,
reject: (id: string) => `/admin/content/${id}/reject`,
history: '/admin/content/history',
list: '/admin/content',
get: (id: string) => `/admin/content/${id}`,
// Media library
mediaLibrary: '/admin/content/media',
deleteMedia: (id: string) => `/admin/content/media/${id}`,
createVersion: '/admin/content/versions',
},
// Users Management (nested structure)
users: {
list: '/admin/users',
get: (id: string) => `/admin/users/${id}`,
update: (id: string) => `/admin/users/${id}`,
delete: (id: string) => `/admin/users/${id}`,
activate: (id: string) => `/admin/users/${id}/activate`,
deactivate: (id: string) => `/admin/users/${id}/deactivate`,
suspend: (id: string) => `/admin/users/${id}/suspend`,
unsuspend: (id: string) => `/admin/users/${id}/unsuspend`,
},
// Backwards compatibility (flat structure)
user: (id: string) => `/admin/users/${id}`,
// Roles & Permissions
roles: {
list: '/admin/roles',
permissions: (roleId: string) => `/admin/roles/${roleId}/permissions`,
updatePermissions: (roleId: string) => `/admin/roles/${roleId}/permissions`,
availablePermissions: '/admin/roles/permissions',
},
// Classrooms
classrooms: '/admin/classrooms',
classroom: (id: string) => `/admin/classrooms/${id}`,
classroomTeachersById: (classroomId: string) => `/admin/classrooms/${classroomId}/teachers`,
// Gamification Configuration
gamificationConfig: '/admin/gamification/config',
gamification: {
settings: '/admin/gamification/settings',
updateSettings: '/admin/gamification/settings',
previewChanges: '/admin/gamification/preview-changes',
restoreDefaults: '/admin/gamification/restore-defaults',
},
// System Monitoring & Configuration
system: {
health: '/admin/system/health',
metrics: '/admin/system/metrics',
logs: '/admin/system/logs',
maintenance: '/admin/system/maintenance',
config: '/admin/system/config',
configCategories: '/admin/system/config/categories',
categoryConfig: (category: string) => `/admin/system/config/${category}`,
validateConfig: '/admin/system/config/validate',
},
// Reports
reports: {
generate: '/admin/reports/generate',
list: '/admin/reports',
download: (reportId: string) => `/admin/reports/${reportId}/download`,
delete: (reportId: string) => `/admin/reports/${reportId}`,
schedule: (reportId: string) => `/admin/reports/${reportId}/schedule`,
},
// Alerts (used as string concatenation in adminAPI.ts)
alerts: '/admin/alerts',
// Monitoring
monitoring: {
metrics: '/admin/monitoring/metrics',
metricsHistory: '/admin/monitoring/metrics/history',
errorStats: '/admin/monitoring/errors/stats',
recentErrors: '/admin/monitoring/errors/recent',
errorTrends: '/admin/monitoring/errors/trends',
},
// Progress
progress: {
overview: '/admin/progress/overview',
classroom: (id: string) => `/admin/progress/classrooms/${id}`,
student: (id: string) => `/admin/progress/students/${id}`,
module: (id: string) => `/admin/progress/modules/${id}`,
exercise: (id: string) => `/admin/progress/exercises/${id}`,
export: '/admin/progress/export',
},
// Classroom Teachers
classroomTeachers: {
list: '/admin/classroom-teachers',
bulk: '/admin/classroom-teachers/bulk',
byClassroom: (id: string) => `/admin/classrooms/${id}/teachers`,
byTeacher: (id: string) => `/admin/teachers/${id}/classrooms`,
classroomsList: '/admin/classrooms/list',
teachersList: '/admin/teachers/list',
},
// Bulk Operations
bulk: {
suspendUsers: '/admin/users/bulk/suspend',
deleteUsers: '/admin/users/bulk/delete',
updateRole: '/admin/users/bulk/update-role',
},
},
/**
* Teacher endpoints
*/
teacher: {
// Dashboard (nested structure for teacherApi.ts compatibility)
dashboard: {
stats: '/teacher/dashboard/stats',
activities: '/teacher/dashboard/activities',
alerts: '/teacher/dashboard/alerts',
topPerformers: '/teacher/dashboard/top-performers',
moduleProgress: '/teacher/dashboard/module-progress',
},
// Classrooms
classrooms: '/teacher/classrooms',
classroom: (id: string) => `/teacher/classrooms/${id}`,
classroomTeachers: (classroomId: string) => `/teacher/classrooms/${classroomId}/teachers`,
classroomStudents: (classroomId: string) => `/teacher/classrooms/${classroomId}/students`,
classroomStats: (classroomId: string) => `/teacher/classrooms/${classroomId}/stats`,
createClassroom: '/teacher/classrooms',
updateClassroom: (id: string) => `/teacher/classrooms/${id}`,
deleteClassroom: (id: string) => `/teacher/classrooms/${id}`,
// Backwards compatibility
students: (classroomId: string) => `/teacher/classrooms/${classroomId}/students`,
// Assignments
assignments: '/teacher/assignments',
assignment: (assignmentId: string) => `/teacher/assignments/${assignmentId}`,
createAssignment: '/teacher/assignments',
updateAssignment: (assignmentId: string) => `/teacher/assignments/${assignmentId}`,
deleteAssignment: (assignmentId: string) => `/teacher/assignments/${assignmentId}`,
assignmentSubmissions: (assignmentId: string) =>
`/teacher/assignments/${assignmentId}/submissions`,
submission: (submissionId: string) => `/teacher/submissions/${submissionId}`,
gradeSubmission: (submissionId: string) => `/teacher/submissions/${submissionId}/feedback`,
// Analytics
analytics: '/teacher/analytics',
engagementMetrics: '/teacher/analytics/engagement',
economyAnalytics: '/teacher/analytics/economy', // GAP-ST-005
studentsEconomy: '/teacher/analytics/students-economy', // GAP-ST-006
achievementsStats: '/teacher/analytics/achievements', // GAP-ST-007
generateReport: '/teacher/reports/generate',
reportStatus: (reportId: string) => `/teacher/reports/${reportId}/status`,
studentInsights: (studentId: string) => `/teacher/students/${studentId}/insights`,
// Grades & Reports
grades: '/teacher/grades',
reports: {
list: '/teacher/reports',
recent: '/teacher/reports/recent',
stats: '/teacher/reports/stats',
download: (reportId: string) => `/teacher/reports/${reportId}/download`,
generate: '/teacher/reports/generate',
},
// Communications
communications: '/teacher/communications',
sendCommunication: '/teacher/communications',
// Alerts
alerts: {
list: '/teacher/alerts',
byClassroom: (classroomId: string) => `/teacher/alerts?classroomId=${classroomId}`,
get: (alertId: string) => `/teacher/alerts/${alertId}`,
resolve: (alertId: string) => `/teacher/alerts/${alertId}/resolve`,
dismiss: (alertId: string) => `/teacher/alerts/${alertId}/dismiss`,
},
// Content Management
content: {
list: '/teacher/content',
get: (contentId: string) => `/teacher/content/${contentId}`,
create: '/teacher/content',
update: (contentId: string) => `/teacher/content/${contentId}`,
delete: (contentId: string) => `/teacher/content/${contentId}`,
clone: (contentId: string) => `/teacher/content/${contentId}/clone`,
publish: (contentId: string) => `/teacher/content/${contentId}/publish`,
},
// Manual Review (for modules 4 and 5)
reviews: {
pending: '/teacher/reviews/pending',
get: (id: string) => `/teacher/reviews/${id}`,
start: (submissionId: string) => `/teacher/reviews/${submissionId}/start`,
update: (id: string) => `/teacher/reviews/${id}`,
complete: (id: string) => `/teacher/reviews/${id}/complete`,
},
},
/**
* Educational Media endpoints
*/
media: {
upload: '/educational/media/upload',
get: (id: string) => `/educational/media/${id}`,
delete: (id: string) => `/educational/media/${id}`,
validate: '/educational/media/validate',
},
/**
* Ranks API endpoints
*/
ranks: {
current: '/gamification/ranks/current',
rankProgress: (userId: string) => `/gamification/ranks/users/${userId}/progress`,
promote: (userId: string) => `/gamification/ranks/users/${userId}/promote`,
history: (userId: string) => `/gamification/ranks/users/${userId}/history`,
multipliers: (userId: string) => `/gamification/ranks/users/${userId}/multipliers`,
},
/**
* Achievements API endpoints
*/
achievements: {
list: '/gamification/achievements',
get: (achievementId: string) => `/gamification/achievements/${achievementId}`,
unlockSpecific: (achievementId: string) => `/gamification/achievements/${achievementId}/unlock`,
updateProgress: (achievementId: string) =>
`/gamification/achievements/${achievementId}/progress`,
stats: '/gamification/achievements/stats',
},
/**
* Powerups (Comodines) API endpoints
* ARCH-015: Aligned with backend comodines.controller.ts routes
*/
powerups: {
list: '/gamification/comodines',
purchase: '/gamification/comodines/purchase',
use: '/gamification/comodines/use',
inventory: (userId: string) => `/gamification/comodines/users/${userId}/inventory`,
history: (userId: string) => `/gamification/comodines/users/${userId}/history`,
stats: (userId: string) => `/gamification/comodines/users/${userId}/stats`,
},
/**
* Leaderboards API endpoints
*/
leaderboards: {
byTypeAndPeriod: (type: string, period: string) =>
`/gamification/leaderboards/${type}/${period}`,
userRank: '/gamification/leaderboards/user-rank',
xp: '/gamification/leaderboards/xp',
coins: '/gamification/leaderboards/coins',
streaks: '/gamification/leaderboards/streaks',
globalView: '/gamification/leaderboards/global',
myRank: (type: string) => `/gamification/leaderboards/${type}/my-rank`,
classroom: (classroomId: string) => `/gamification/leaderboard/classrooms/${classroomId}`,
},
/**
* Guilds API endpoints
*/
guilds: {
list: '/gamification/guilds',
get: (guildId: string) => `/gamification/guilds/${guildId}`,
create: '/gamification/guilds',
join: (guildId: string) => `/gamification/guilds/${guildId}/join`,
leave: (guildId: string) => `/gamification/guilds/${guildId}/leave`,
members: (guildId: string) => `/gamification/guilds/${guildId}/members`,
updateMemberRole: (guildId: string, memberId: string) =>
`/gamification/guilds/${guildId}/members/${memberId}/role`,
challenges: (guildId: string) => `/gamification/guilds/${guildId}/challenges`,
},
/**
* Friends API endpoints
*/
friends: {
list: '/gamification/friends',
request: '/gamification/friends/request',
requests: '/gamification/friends/requests',
accept: (requestId: string) => `/gamification/friends/requests/${requestId}/accept`,
decline: (requestId: string) => `/gamification/friends/requests/${requestId}/decline`,
remove: (userId: string) => `/gamification/friends/${userId}`,
recommendations: '/gamification/friends/recommendations',
activities: '/gamification/friends/activities',
},
/**
* Mechanics API endpoints
*/
mechanics: {
list: '/mechanics',
get: (mechanicId: string) => `/mechanics/${mechanicId}`,
progress: '/mechanics/progress',
hints: (mechanicId: string) => `/mechanics/${mechanicId}/hints`,
scoring: '/mechanics/scoring',
validate: '/mechanics/validate',
},
/**
* AI Service endpoints
*/
ai: {
analyzeText: '/ai/analyze-text',
generateResponse: '/ai/generate-response',
checkFact: '/ai/check-fact',
validateHypothesis: '/ai/validate-hypothesis',
improveReading: '/ai/improve-reading',
getSuggestions: '/ai/suggestions',
},
/**
* Users endpoints (general)
*/
users: {
list: '/users',
get: (userId: string) => `/users/${userId}`,
create: '/users',
update: (userId: string) => `/users/${userId}`,
delete: (userId: string) => `/users/${userId}`,
},
/**
* Student endpoints
*/
student: {
dashboard: '/student/dashboard',
profile: (userId: string) => `/student/users/${userId}/profile`,
courses: '/student/courses',
assignments: '/student/assignments',
grades: '/student/grades',
},
/**
* Health check
*/
health: {
check: '/health',
status: '/health/status',
},
} as const;
// ============================================================================
// HELPER FUNCTIONS
// ============================================================================
/**
* Construye URL completa para un endpoint
* @param path - Ruta relativa (puede ser string o función)
* @returns URL completa
*/
export function buildApiUrl(path: string | ((...args: any[]) => string), ...args: any[]): string {
const relativePath = typeof path === 'function' ? path(...args) : path;
return `${API_BASE_URL}${relativePath}`;
}
/**
* Construye WebSocket URL
* @param path - Ruta relativa para WebSocket
* @returns WebSocket URL completa
*/
export function buildWsUrl(path: string = ''): string {
return `${WS_BASE_URL}${path}`;
}
// ============================================================================
// FEATURE FLAGS
// ============================================================================
export const FEATURE_FLAGS = {
USE_MOCK_DATA: import.meta.env.VITE_USE_MOCK_DATA === 'true',
MOCK_API: import.meta.env.VITE_MOCK_API === 'true',
ENABLE_WEBSOCKET: import.meta.env.VITE_ENABLE_WEBSOCKET !== 'false',
DEBUG_API: import.meta.env.VITE_DEBUG_API === 'true',
ENABLE_AI: import.meta.env.VITE_ENABLE_AI !== 'false',
ENABLE_ANALYTICS: import.meta.env.VITE_ENABLE_ANALYTICS === 'true',
ENABLE_GAMIFICATION: import.meta.env.VITE_ENABLE_GAMIFICATION === 'true',
ENABLE_SOCIAL_FEATURES: import.meta.env.VITE_ENABLE_SOCIAL_FEATURES === 'true',
ENABLE_DEBUG: import.meta.env.VITE_ENABLE_DEBUG === 'true',
} as const;
// ============================================================================
// HTTP STATUS CODES
// ============================================================================
export const HTTP_STATUS = {
OK: 200,
CREATED: 201,
NO_CONTENT: 204,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
CONFLICT: 409,
UNPROCESSABLE_ENTITY: 422,
TOO_MANY_REQUESTS: 429,
INTERNAL_SERVER_ERROR: 500,
SERVICE_UNAVAILABLE: 503,
} as const;
// ============================================================================
// VALIDATION & LOGGING
// ============================================================================
if (import.meta.env.MODE === 'development') {
console.log('[API Config] Configuration loaded:', {
baseURL: API_BASE_URL,
wsURL: WS_BASE_URL,
version: API_VERSION,
host: API_HOST,
protocol: API_PROTOCOL,
});
}
// ============================================================================
// DEFAULT EXPORT
// ============================================================================
export default {
API_CONFIG,
API_ENDPOINTS,
FEATURE_FLAGS,
HTTP_STATUS,
buildApiUrl,
buildWsUrl,
};