Changes include: - Updated architecture documentation - Enhanced module definitions (OQI-001 to OQI-008) - ML integration documentation updates - Trading strategies documentation - Orchestration and inventory updates - Docker configuration updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
711 lines
23 KiB
Markdown
711 lines
23 KiB
Markdown
---
|
|
id: "MIGRACION-SUPABASE-EXPRESS"
|
|
title: "Supabase a Express Backend"
|
|
type: "Documentation"
|
|
project: "trading-platform"
|
|
version: "1.0.0"
|
|
updated_date: "2026-01-04"
|
|
---
|
|
|
|
# Plan de Migracion: Supabase a Express Backend
|
|
|
|
**Ultima actualizacion:** 2025-12-05
|
|
**Proyecto origen:** stc-platform-web (Supabase)
|
|
**Proyecto destino:** trading-platform (Express + pg + PostgreSQL)
|
|
**Patrones base:** `shared/catalog/auth/` *(inspiración arquitectónica de patrones auth y estructura)*
|
|
|
|
---
|
|
|
|
## Resumen Ejecutivo
|
|
|
|
Este documento detalla el plan de migracion del frontend existente en `stc-platform-web` que usa Supabase como backend hacia una arquitectura con Express.js como backend propio.
|
|
|
|
**Estado Actual del Backend:**
|
|
El backend de trading-platform (`/home/isem/workspace/projects/trading-platform/apps/backend/`) ya tiene implementacion funcional con:
|
|
- Express.js + TypeScript
|
|
- Autenticacion JWT completa (registro, login, refresh tokens, sesiones)
|
|
- OAuth multi-proveedor (Google, Facebook, Twitter, Apple, GitHub)
|
|
- 2FA con TOTP (speakeasy)
|
|
- Autenticacion por telefono (Twilio SMS/WhatsApp)
|
|
- PostgreSQL con pg driver nativo
|
|
- Estructura modular escalable
|
|
- Guards, interceptors, filters adaptados de patrones NestJS
|
|
|
|
**Patrones de Gamilit Adaptados:**
|
|
Se tomaron patrones del proyecto Gamilit y se adaptaron para Express:
|
|
- Constantes compartidas (DB_SCHEMAS, enums)
|
|
- Estructura de servicios modulares
|
|
- Manejo de errores unificado
|
|
- Guards de autenticacion y autorizacion
|
|
|
|
---
|
|
|
|
## 1. Arquitectura Objetivo
|
|
|
|
### Antes (Supabase)
|
|
```
|
|
Frontend (React) ──> Supabase Client ──> Supabase (Auth + DB + Storage)
|
|
│
|
|
├── Auth (Built-in)
|
|
├── PostgreSQL
|
|
├── Realtime
|
|
└── Storage
|
|
```
|
|
|
|
### Despues (Express Backend Propio)
|
|
```
|
|
Frontend (React) ──> API Client ──> Express Backend ──> PostgreSQL
|
|
│ │
|
|
│ ├── JWT Auth (jsonwebtoken + Passport)
|
|
│ ├── pg driver (Multi-schema)
|
|
│ ├── Redis (Sessions/Cache)
|
|
│ ├── S3/MinIO (Storage)
|
|
│ └── Socket.io (Realtime)
|
|
│
|
|
└── WebSocket ──> Realtime Updates
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Estructura Backend Actual (Express)
|
|
|
|
```
|
|
apps/backend/src/
|
|
├── index.ts # Entry point Express server
|
|
├── config/
|
|
│ └── index.ts # Configuracion centralizada
|
|
├── core/
|
|
│ ├── decorators/
|
|
│ ├── filters/
|
|
│ │ ├── http-exception.filter.ts # Excepciones HTTP unificadas
|
|
│ │ └── index.ts
|
|
│ ├── guards/
|
|
│ │ ├── auth.guard.ts # Guards de autenticacion
|
|
│ │ └── index.ts
|
|
│ ├── interceptors/
|
|
│ │ ├── transform-response.interceptor.ts
|
|
│ │ └── index.ts
|
|
│ └── middleware/
|
|
│ ├── auth.middleware.ts # Middleware JWT
|
|
│ ├── error-handler.ts # Manejador de errores
|
|
│ ├── not-found.ts # 404 handler
|
|
│ └── rate-limiter.ts # Rate limiting
|
|
├── modules/
|
|
│ ├── auth/
|
|
│ │ ├── auth.routes.ts # Rutas de auth
|
|
│ │ ├── controllers/
|
|
│ │ │ └── auth.controller.ts # Controller principal
|
|
│ │ ├── services/
|
|
│ │ │ ├── email.service.ts # Auth email/password
|
|
│ │ │ ├── oauth.service.ts # OAuth multi-provider
|
|
│ │ │ ├── phone.service.ts # SMS/WhatsApp (Twilio)
|
|
│ │ │ ├── token.service.ts # JWT tokens
|
|
│ │ │ └── twofa.service.ts # 2FA TOTP
|
|
│ │ ├── strategies/ # Passport strategies
|
|
│ │ ├── types/
|
|
│ │ │ └── auth.types.ts # Tipos de auth
|
|
│ │ └── validators/
|
|
│ │ └── auth.validators.ts # Validacion Zod
|
|
│ ├── users/
|
|
│ │ └── users.routes.ts
|
|
│ ├── education/
|
|
│ │ └── education.routes.ts
|
|
│ ├── trading/
|
|
│ │ └── trading.routes.ts
|
|
│ ├── investment/
|
|
│ │ └── investment.routes.ts
|
|
│ ├── payments/
|
|
│ │ └── payments.routes.ts
|
|
│ └── admin/
|
|
│ └── admin.routes.ts
|
|
└── shared/
|
|
├── constants/
|
|
│ ├── database.constants.ts # DB_SCHEMAS, DB_TABLES
|
|
│ ├── enums.constants.ts # UserStatusEnum, etc
|
|
│ ├── routes.constants.ts # API_ROUTES
|
|
│ └── index.ts
|
|
├── database/
|
|
│ └── index.ts # Pool de conexiones pg
|
|
├── dto/
|
|
├── types/
|
|
│ ├── common.types.ts # ApiResponse, PaginatedResult
|
|
│ └── index.ts
|
|
└── utils/
|
|
└── logger.ts # Winston logger
|
|
```
|
|
|
|
### Servicios de Auth Implementados
|
|
|
|
| Servicio | Archivo | Funcionalidades |
|
|
|----------|---------|-----------------|
|
|
| **EmailService** | `email.service.ts` | Registro, login, verificacion email, reset password |
|
|
| **OAuthService** | `oauth.service.ts` | Google, Facebook, Twitter, Apple, GitHub |
|
|
| **PhoneService** | `phone.service.ts` | SMS OTP, WhatsApp OTP (Twilio) |
|
|
| **TokenService** | `token.service.ts` | JWT access/refresh, sesiones |
|
|
| **TwoFAService** | `twofa.service.ts` | TOTP setup, verify, backup codes |
|
|
|
|
---
|
|
|
|
## 3. Estructura Backend Gamilit (Referencia)
|
|
|
|
```
|
|
gamilit/apps/backend/src/
|
|
├── main.ts # Bootstrap con Swagger, CORS, ValidationPipe
|
|
├── app.module.ts # Root module con multi-schema TypeORM
|
|
├── config/
|
|
│ ├── app.config.ts # Configuracion de aplicacion
|
|
│ ├── database.config.ts # Configuracion PostgreSQL
|
|
│ ├── jwt.config.ts # Configuracion JWT
|
|
│ └── env.config.ts # Variables de entorno
|
|
├── modules/
|
|
│ ├── auth/ # ✅ REUTILIZAR PATRON
|
|
│ │ ├── auth.module.ts # Module definition
|
|
│ │ ├── controllers/
|
|
│ │ │ ├── auth.controller.ts # Login, Register, Refresh
|
|
│ │ │ ├── password.controller.ts # Forgot/Reset password
|
|
│ │ │ └── users.controller.ts # User CRUD
|
|
│ │ ├── services/
|
|
│ │ │ ├── auth.service.ts # Core auth logic (25KB)
|
|
│ │ │ ├── session-management.service.ts
|
|
│ │ │ ├── security.service.ts
|
|
│ │ │ ├── password-recovery.service.ts
|
|
│ │ │ └── email-verification.service.ts
|
|
│ │ ├── entities/
|
|
│ │ │ ├── user.entity.ts
|
|
│ │ │ ├── profile.entity.ts
|
|
│ │ │ ├── user-session.entity.ts
|
|
│ │ │ ├── auth-attempt.entity.ts
|
|
│ │ │ ├── auth-provider.entity.ts # OAuth providers
|
|
│ │ │ └── ...
|
|
│ │ ├── strategies/
|
|
│ │ │ └── jwt.strategy.ts # Passport JWT strategy
|
|
│ │ ├── guards/
|
|
│ │ │ └── jwt-auth.guard.ts
|
|
│ │ ├── dto/
|
|
│ │ │ ├── register-user.dto.ts
|
|
│ │ │ ├── login.dto.ts
|
|
│ │ │ └── ...
|
|
│ │ └── decorators/
|
|
│ │ └── current-user.decorator.ts
|
|
│ ├── educational/ # → Adaptar para courses
|
|
│ ├── progress/ # → Adaptar para course progress
|
|
│ ├── gamification/ # → Adaptar para trading stats
|
|
│ ├── notifications/ # ✅ REUTILIZAR
|
|
│ ├── websocket/ # ✅ REUTILIZAR para signals realtime
|
|
│ └── health/ # ✅ REUTILIZAR
|
|
└── shared/
|
|
├── constants/
|
|
│ ├── database.constants.ts # DB_SCHEMAS, DB_TABLES
|
|
│ ├── routes.constants.ts # API_PREFIX, API_VERSION
|
|
│ └── enums.constants.ts # Shared enums
|
|
├── decorators/
|
|
├── dto/
|
|
├── filters/
|
|
│ └── http-exception.filter.ts # Global exception handler
|
|
├── guards/
|
|
├── interceptors/
|
|
│ ├── transform-response.interceptor.ts
|
|
│ └── rls.interceptor.ts # Row Level Security
|
|
├── middleware/
|
|
├── pipes/
|
|
└── utils/
|
|
```
|
|
|
|
### Archivos Clave a Copiar/Adaptar
|
|
|
|
| Archivo Gamilit | Destino Trading Platform | Adaptaciones |
|
|
|-----------------|-------------------------|--------------|
|
|
| `main.ts` | `apps/backend/src/main.ts` | Cambiar nombre app, tags Swagger |
|
|
| `app.module.ts` | `apps/backend/src/app.module.ts` | Cambiar schemas y modules |
|
|
| `auth/` (completo) | `modules/auth/` | Agregar OAuth providers adicionales |
|
|
| `shared/` (completo) | `shared/` | Adaptar constantes y enums |
|
|
| `websocket/` | `modules/websocket/` | Adaptar eventos para trading signals |
|
|
| `health/` | `modules/health/` | Sin cambios |
|
|
|
|
---
|
|
|
|
## 4. Mapeo de Supabase a Express
|
|
|
|
### 4.1 Autenticacion
|
|
|
|
| Supabase Method | Express Equivalent | Endpoint |
|
|
|-----------------|-------------------|----------|
|
|
| `supabase.auth.signInWithPassword()` | POST `/api/v1/auth/login` | JWT + Refresh Token |
|
|
| `supabase.auth.signUp()` | POST `/api/v1/auth/register` | Validacion + Email verification |
|
|
| `supabase.auth.signInWithOAuth()` | GET `/api/v1/auth/oauth/:provider/url` | Passport OAuth strategies |
|
|
| `supabase.auth.signOut()` | POST `/api/v1/auth/logout` | Invalidar tokens |
|
|
| `supabase.auth.resetPasswordForEmail()` | POST `/api/v1/auth/forgot-password` | Nodemailer |
|
|
| `supabase.auth.updateUser()` | PATCH `/api/v1/auth/password` | Validacion + bcrypt |
|
|
| `supabase.auth.verifyOtp()` | POST `/api/v1/auth/verify-email` | Token validation |
|
|
| `supabase.auth.refreshSession()` | POST `/api/v1/auth/refresh` | JWT refresh rotation |
|
|
| `supabase.auth.getUser()` | GET `/api/v1/auth/me` | JWT middleware |
|
|
| `supabase.auth.getSession()` | (Client-side localStorage) | JWT decode |
|
|
| `supabase.auth.onAuthStateChange()` | (Client-side event) | Estado local |
|
|
|
|
### 4.2 Queries de Base de Datos
|
|
|
|
| Supabase Query | Express/TypeORM Equivalent |
|
|
|----------------|---------------------------|
|
|
| `.from('table').select()` | `repository.find()` |
|
|
| `.from('table').select('*', { count: 'exact' })` | `repository.findAndCount()` |
|
|
| `.from('table').insert()` | `repository.save()` |
|
|
| `.from('table').update()` | `repository.update()` |
|
|
| `.from('table').delete()` | `repository.delete()` |
|
|
| `.eq('column', value)` | `{ where: { column: value } }` |
|
|
| `.in('column', [values])` | `{ where: { column: In([values]) } }` |
|
|
| `.order('column', { ascending: true })` | `{ order: { column: 'ASC' } }` |
|
|
| `.range(0, 10)` | `{ skip: 0, take: 10 }` |
|
|
| `.single()` | `repository.findOne()` |
|
|
| `.rpc('function_name', params)` | Service method / Raw query |
|
|
|
|
### 4.3 Realtime
|
|
|
|
| Supabase Realtime | Express Equivalent |
|
|
|-------------------|-------------------|
|
|
| `.channel()` | Socket.io room |
|
|
| `.on('postgres_changes', ...)` | Socket.io events + DB triggers |
|
|
| `.subscribe()` | `socket.join(room)` |
|
|
| `supabase.removeChannel()` | `socket.leave(room)` |
|
|
|
|
### 4.4 Storage
|
|
|
|
| Supabase Storage | Express Equivalent |
|
|
|------------------|-------------------|
|
|
| `supabase.storage.from('bucket').upload()` | Multer + S3/MinIO |
|
|
| `supabase.storage.from('bucket').download()` | S3 signed URLs |
|
|
| `supabase.storage.from('bucket').getPublicUrl()` | CDN URL generation |
|
|
|
|
---
|
|
|
|
## 5. Servicios a Migrar (Frontend)
|
|
|
|
### 5.1 AuthService Migration
|
|
|
|
**Archivo origen:** `src/features/auth/services/authService.ts`
|
|
**Archivo destino:** `apps/frontend/src/services/auth.service.ts`
|
|
|
|
```typescript
|
|
// ANTES (Supabase)
|
|
async signInWithEmail(email: string, password: string) {
|
|
const { data, error } = await supabase.auth.signInWithPassword({
|
|
email,
|
|
password
|
|
});
|
|
// ...
|
|
}
|
|
|
|
// DESPUES (Express API)
|
|
async signInWithEmail(email: string, password: string) {
|
|
const response = await api.post('/auth/login', { email, password });
|
|
if (response.data.accessToken) {
|
|
tokenService.setTokens(
|
|
response.data.accessToken,
|
|
response.data.refreshToken
|
|
);
|
|
}
|
|
return response.data;
|
|
}
|
|
```
|
|
|
|
### 5.2 CourseService Migration
|
|
|
|
**Archivo origen:** `src/features/courses/services/courseService.ts`
|
|
**Archivo destino:** `apps/frontend/src/services/course.service.ts`
|
|
|
|
```typescript
|
|
// ANTES (Supabase)
|
|
async getCourses(filters, sort, page, perPage) {
|
|
let query = supabase
|
|
.from('education.courses')
|
|
.select(`*, instructor:profiles!instructor_id(...)`)
|
|
// ...
|
|
}
|
|
|
|
// DESPUES (Express API)
|
|
async getCourses(filters, sort, page, perPage) {
|
|
const params = new URLSearchParams({
|
|
page: String(page),
|
|
per_page: String(perPage),
|
|
sort_field: sort.field,
|
|
sort_dir: sort.direction,
|
|
...filters
|
|
});
|
|
return api.get(`/courses?${params}`);
|
|
}
|
|
```
|
|
|
|
### 5.3 SignalService Migration
|
|
|
|
**Archivo origen:** `src/features/trading/services/signalService.ts`
|
|
|
|
**Cambios principales:**
|
|
1. Queries → API calls
|
|
2. Realtime subscriptions → WebSocket
|
|
|
|
```typescript
|
|
// DESPUES (WebSocket)
|
|
subscribeToSignals(botIds: string[], callback: (signal) => void) {
|
|
socket.emit('subscribe:signals', { botIds });
|
|
socket.on('signal:new', callback);
|
|
return () => socket.off('signal:new', callback);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Estructura de Carpetas Destino
|
|
|
|
> **Nota:** La estructura del backend ya está implementada. Ver Sección 2 para el estado actual.
|
|
> La siguiente es la estructura objetivo del frontend.
|
|
|
|
### 6.1 Frontend (React)
|
|
|
|
```
|
|
apps/frontend/src/
|
|
├── services/
|
|
│ ├── api.ts # Axios instance con interceptores
|
|
│ ├── auth.service.ts # Migrado de authService.ts
|
|
│ ├── course.service.ts # Migrado de courseService.ts
|
|
│ ├── trading.service.ts # Consolidado de trading services
|
|
│ ├── payment.service.ts # Migrado de stripeService.ts
|
|
│ └── socket.service.ts # NUEVO: WebSocket client
|
|
├── stores/
|
|
│ └── auth.store.ts # Migrar con cambios de API
|
|
├── hooks/
|
|
│ ├── useAuth.ts # Mantener logica, cambiar imports
|
|
│ └── ...
|
|
└── lib/
|
|
└── socket.ts # Socket.io client config
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Backend Endpoints a Implementar
|
|
|
|
### 7.1 Auth Module (Prioridad 1) - ✅ IMPLEMENTADO
|
|
|
|
```
|
|
POST /api/v1/auth/register
|
|
POST /api/v1/auth/login
|
|
POST /api/v1/auth/logout
|
|
POST /api/v1/auth/refresh
|
|
GET /api/v1/auth/me
|
|
GET /api/v1/auth/oauth/:provider/url
|
|
POST /api/v1/auth/oauth/:provider
|
|
DELETE /api/v1/auth/oauth/:provider
|
|
POST /api/v1/auth/phone/send
|
|
POST /api/v1/auth/phone/verify
|
|
POST /api/v1/auth/2fa/setup
|
|
POST /api/v1/auth/2fa/enable
|
|
POST /api/v1/auth/2fa/verify
|
|
POST /api/v1/auth/2fa/disable
|
|
POST /api/v1/auth/forgot-password
|
|
POST /api/v1/auth/reset-password
|
|
POST /api/v1/auth/verify-email
|
|
POST /api/v1/auth/resend-verification
|
|
GET /api/v1/auth/sessions
|
|
DELETE /api/v1/auth/sessions/:id
|
|
DELETE /api/v1/auth/sessions
|
|
```
|
|
|
|
### 7.2 Users Module
|
|
|
|
```
|
|
GET /api/v1/users
|
|
GET /api/v1/users/:id
|
|
PATCH /api/v1/users/:id
|
|
DELETE /api/v1/users/:id
|
|
GET /api/v1/users/:id/profile
|
|
PATCH /api/v1/users/:id/profile
|
|
POST /api/v1/users/:id/avatar
|
|
```
|
|
|
|
### 7.3 Courses Module (Prioridad 2)
|
|
|
|
```
|
|
GET /api/v1/courses
|
|
GET /api/v1/courses/featured
|
|
GET /api/v1/courses/search
|
|
GET /api/v1/courses/:id
|
|
GET /api/v1/courses/:slug
|
|
POST /api/v1/courses
|
|
PATCH /api/v1/courses/:id
|
|
DELETE /api/v1/courses/:id
|
|
POST /api/v1/courses/:id/publish
|
|
POST /api/v1/courses/:id/archive
|
|
GET /api/v1/courses/:id/modules
|
|
POST /api/v1/courses/:id/modules
|
|
GET /api/v1/courses/:id/modules/:mid/lessons
|
|
POST /api/v1/courses/:id/enroll
|
|
GET /api/v1/courses/:id/progress
|
|
POST /api/v1/courses/:id/lessons/:lid/complete
|
|
GET /api/v1/courses/:id/certificate
|
|
```
|
|
|
|
### 7.4 Trading Module (Prioridad 3)
|
|
|
|
```
|
|
GET /api/v1/trading/bots
|
|
GET /api/v1/trading/bots/featured
|
|
GET /api/v1/trading/bots/:id
|
|
POST /api/v1/trading/bots/:id/subscribe
|
|
DELETE /api/v1/trading/bots/:id/subscribe
|
|
GET /api/v1/trading/bots/:id/reviews
|
|
POST /api/v1/trading/bots/:id/reviews
|
|
GET /api/v1/trading/signals
|
|
GET /api/v1/trading/signals/:id
|
|
POST /api/v1/trading/signals/:id/execute
|
|
GET /api/v1/trading/portfolio
|
|
GET /api/v1/trading/positions
|
|
GET /api/v1/trading/history
|
|
```
|
|
|
|
### 7.5 Payments Module (Prioridad 4)
|
|
|
|
```
|
|
GET /api/v1/payments
|
|
GET /api/v1/payments/:id
|
|
POST /api/v1/payments/checkout
|
|
GET /api/v1/payments/credits
|
|
POST /api/v1/payments/credits/purchase
|
|
GET /api/v1/subscriptions
|
|
POST /api/v1/subscriptions
|
|
DELETE /api/v1/subscriptions/:id
|
|
GET /api/v1/invoices
|
|
GET /api/v1/invoices/:id/download
|
|
POST /api/v1/webhooks/stripe
|
|
```
|
|
|
|
---
|
|
|
|
## 8. API Client Configuration
|
|
|
|
### 8.1 Axios Instance
|
|
|
|
```typescript
|
|
// apps/frontend/src/services/api.ts
|
|
import axios from 'axios';
|
|
import { tokenService } from './token.service';
|
|
|
|
const api = axios.create({
|
|
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3001/api/v1',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
}
|
|
});
|
|
|
|
// Request interceptor - Add auth header
|
|
api.interceptors.request.use((config) => {
|
|
const token = tokenService.getAccessToken();
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
}
|
|
return config;
|
|
});
|
|
|
|
// Response interceptor - Handle 401, refresh token
|
|
api.interceptors.response.use(
|
|
(response) => response,
|
|
async (error) => {
|
|
const originalRequest = error.config;
|
|
|
|
if (error.response?.status === 401 && !originalRequest._retry) {
|
|
originalRequest._retry = true;
|
|
|
|
try {
|
|
const refreshToken = tokenService.getRefreshToken();
|
|
const response = await axios.post('/auth/refresh', { refreshToken });
|
|
|
|
tokenService.setTokens(
|
|
response.data.accessToken,
|
|
response.data.refreshToken
|
|
);
|
|
|
|
originalRequest.headers.Authorization = `Bearer ${response.data.accessToken}`;
|
|
return api(originalRequest);
|
|
} catch (refreshError) {
|
|
tokenService.clearTokens();
|
|
window.location.href = '/login';
|
|
return Promise.reject(refreshError);
|
|
}
|
|
}
|
|
|
|
return Promise.reject(error);
|
|
}
|
|
);
|
|
|
|
export { api };
|
|
```
|
|
|
|
### 8.2 Socket.io Client
|
|
|
|
```typescript
|
|
// apps/frontend/src/lib/socket.ts
|
|
import { io, Socket } from 'socket.io-client';
|
|
import { tokenService } from '@/services/token.service';
|
|
|
|
let socket: Socket | null = null;
|
|
|
|
export function getSocket(): Socket {
|
|
if (!socket) {
|
|
socket = io(import.meta.env.VITE_WS_URL || 'ws://localhost:3001', {
|
|
auth: {
|
|
token: tokenService.getAccessToken()
|
|
},
|
|
autoConnect: false
|
|
});
|
|
}
|
|
return socket;
|
|
}
|
|
|
|
export function connectSocket(): void {
|
|
const s = getSocket();
|
|
if (!s.connected) {
|
|
s.connect();
|
|
}
|
|
}
|
|
|
|
export function disconnectSocket(): void {
|
|
if (socket?.connected) {
|
|
socket.disconnect();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Orden de Migracion
|
|
|
|
### Fase 1: Autenticacion (Semana 1-2)
|
|
1. Backend: Implementar auth endpoints
|
|
2. Frontend: Migrar authService.ts
|
|
3. Frontend: Migrar tokenService.ts
|
|
4. Frontend: Actualizar auth.store.ts
|
|
5. Frontend: Actualizar hooks de auth
|
|
6. Testing: Flujos completos de auth
|
|
|
|
### Fase 2: Usuarios y Perfiles (Semana 2)
|
|
1. Backend: Implementar users endpoints
|
|
2. Frontend: Crear user.service.ts
|
|
3. Frontend: Actualizar profileService.ts
|
|
4. Testing: CRUD de usuarios
|
|
|
|
### Fase 3: Cursos/Educacion (Semana 3-4)
|
|
1. Backend: Implementar courses endpoints
|
|
2. Frontend: Migrar courseService.ts
|
|
3. Frontend: Migrar enrollment/progress services
|
|
4. Frontend: Migrar quiz/certificate services
|
|
5. Testing: Flujos de cursos
|
|
|
|
### Fase 4: Trading (Semana 4-5)
|
|
1. Backend: Implementar trading endpoints
|
|
2. Backend: Implementar WebSocket para signals
|
|
3. Frontend: Migrar signalService.ts
|
|
4. Frontend: Migrar botService.ts
|
|
5. Frontend: Crear socket.service.ts
|
|
6. Testing: Trading flows + realtime
|
|
|
|
### Fase 5: Pagos (Semana 5-6)
|
|
1. Backend: Implementar payment endpoints
|
|
2. Backend: Stripe webhooks
|
|
3. Frontend: Migrar stripeService.ts
|
|
4. Frontend: Migrar webhookService.ts
|
|
5. Testing: Payment flows
|
|
|
|
---
|
|
|
|
## 10. Consideraciones Especiales
|
|
|
|
### 10.1 Manejo de Errores
|
|
|
|
```typescript
|
|
// Error response standard
|
|
interface ApiError {
|
|
code: string;
|
|
message: string;
|
|
field?: string;
|
|
details?: any;
|
|
}
|
|
|
|
// En frontend, mapear a mensajes amigables
|
|
const errorMessages: Record<string, string> = {
|
|
'AUTH_INVALID_CREDENTIALS': 'Email o contrasena incorrectos',
|
|
'AUTH_EMAIL_NOT_VERIFIED': 'Debes verificar tu email',
|
|
'AUTH_TOKEN_EXPIRED': 'Tu sesion ha expirado',
|
|
// ...
|
|
};
|
|
```
|
|
|
|
### 10.2 Rate Limiting
|
|
|
|
El backend implementara rate limiting:
|
|
- Auth endpoints: 5 requests/15min
|
|
- General API: 100 requests/min
|
|
- Heavy endpoints: 10 requests/min
|
|
|
|
### 10.3 Cache
|
|
|
|
- Redis para sessions y tokens
|
|
- Redis para cache de queries frecuentes
|
|
- Frontend: TanStack Query cache
|
|
|
|
### 10.4 Variables de Entorno Frontend
|
|
|
|
```env
|
|
# .env
|
|
VITE_API_URL=http://localhost:3001/api/v1
|
|
VITE_WS_URL=ws://localhost:3001
|
|
VITE_STRIPE_PUBLIC_KEY=pk_test_xxx
|
|
VITE_GOOGLE_CLIENT_ID=xxx
|
|
VITE_FACEBOOK_APP_ID=xxx
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Testing Strategy
|
|
|
|
### 11.1 Backend Tests
|
|
- Unit tests para services
|
|
- Integration tests para endpoints
|
|
- E2E tests para flujos criticos
|
|
|
|
### 11.2 Frontend Tests
|
|
- Unit tests para services migrados
|
|
- Integration tests con MSW (mocks)
|
|
- E2E tests con Playwright
|
|
|
|
---
|
|
|
|
## 12. Rollback Plan
|
|
|
|
En caso de problemas:
|
|
1. Mantener Supabase operativo durante migracion
|
|
2. Feature flags para cambiar entre backends
|
|
3. Logs detallados para debugging
|
|
4. Snapshots de base de datos
|
|
|
|
---
|
|
|
|
## 13. Referencias
|
|
|
|
### Documentacion Interna
|
|
- [ADR-001: Stack Tecnologico](../../97-adr/ADR-001-stack-tecnologico.md)
|
|
- [ADR-003: Autenticacion Multi-proveedor](../../97-adr/ADR-003-autenticacion-multiproveedor.md)
|
|
- [INVENTARIO-STC-PLATFORM-WEB.md](./INVENTARIO-STC-PLATFORM-WEB.md)
|
|
- [OQI-001: Fundamentos y Auth](../../01-fase-mvp/OQI-001-fundamentos-auth/_MAP.md)
|
|
|
|
### Catálogo de Patrones Reutilizables
|
|
> **Nota:** Los patrones de autenticación fueron inspirados en arquitecturas previas y están
|
|
> documentados en el catálogo central para reutilización.
|
|
|
|
- **Catálogo Auth:** `shared/catalog/auth/` *(patrones de autenticación JWT, OAuth, 2FA)*
|
|
- **Catálogo Session:** `shared/catalog/session-management/` *(gestión de sesiones)*
|
|
- **Patrones Backend:** `shared/catalog/backend-patterns/` *(interceptors, filters, guards)*
|
|
|
|
### Documentacion Externa
|
|
- [Express.js Documentation](https://expressjs.com/)
|
|
- [node-postgres (pg) Documentation](https://node-postgres.com/)
|
|
- [Passport.js Strategies](http://www.passportjs.org/)
|
|
- [jsonwebtoken Documentation](https://github.com/auth0/node-jsonwebtoken)
|
|
- [Zod Validation](https://zod.dev/)
|