trading-platform/docs/90-transversal/inventarios/MIGRACION-SUPABASE-EXPRESS.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
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>
2026-01-07 05:33:35 -06:00

23 KiB

id title type project version updated_date
MIGRACION-SUPABASE-EXPRESS Supabase a Express Backend Documentation trading-platform 1.0.0 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

// 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

// 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
// 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

// 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

// 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

// 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
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

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