Some checks failed
CI/CD Pipeline / 🧪 Tests (push) Has been cancelled
CI/CD Pipeline / 🏗️ Build (push) Has been cancelled
CI/CD Pipeline / 🚀 Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / 🚀 Deploy to Production (push) Has been cancelled
CI/CD Pipeline / 🏷️ Create Release (push) Has been cancelled
CI/CD Pipeline / 🧹 Cleanup (push) Has been cancelled
Implementados 4 módulos con agent swarm: 1. TESTING FUNCIONAL (Jest) - Configuración Jest + ts-jest - Tests unitarios: auth, booking, court (55 tests) - Tests integración: routes (56 tests) - Factories y utilidades de testing - Coverage configurado (70% servicios) - Scripts: test, test:watch, test:coverage 2. TESTING DE USUARIO (Beta) - Sistema de beta testers - Feedback con categorías y severidad - Beta issues tracking - 8 testers de prueba creados - API completa para gestión de feedback 3. DOCUMENTACIÓN COMPLETA - API.md - 150+ endpoints documentados - SETUP.md - Guía de instalación - DEPLOY.md - Deploy en VPS - ARCHITECTURE.md - Arquitectura del sistema - APP_STORE.md - Material para stores - Postman Collection completa - PM2 ecosystem config - Nginx config con SSL 4. GO LIVE Y PRODUCCIÓN - Sistema de monitoreo (logs, health checks) - Servicio de alertas multi-canal - Pre-deploy check script - Docker + docker-compose producción - Backup automatizado - CI/CD GitHub Actions - Launch checklist completo ESTADÍSTICAS FINALES: - Fases completadas: 7/7 - Archivos creados: 250+ - Líneas de código: 60,000+ - Endpoints API: 150+ - Tests: 110+ - Documentación: 5,000+ líneas PROYECTO COMPLETO Y LISTO PARA PRODUCCIÓN
452 lines
25 KiB
Markdown
452 lines
25 KiB
Markdown
# 🏗️ Arquitectura del Sistema - App Canchas de Pádel
|
|
|
|
Documentación de la arquitectura técnica del proyecto.
|
|
|
|
---
|
|
|
|
## 📐 Diagrama de Arquitectura
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ CLIENTES │
|
|
├─────────────┬─────────────┬─────────────┬───────────────────────┤
|
|
│ Web App │ Mobile App │ Admin │ Terceros │
|
|
│ (React) │ (React │ Dashboard │ (MercadoPago) │
|
|
│ │ Native) │ (React) │ │
|
|
└──────┬──────┴──────┬──────┴──────┬──────┴───────────┬───────────┘
|
|
│ │ │ │
|
|
└─────────────┴──────┬──────┴──────────────────┘
|
|
│
|
|
┌───────────────────────────▼────────────────────────────────────┐
|
|
│ API GATEWAY (Nginx) │
|
|
│ • SSL/TLS Termination • Rate Limiting • Load Balancing │
|
|
└───────────────────────────┬────────────────────────────────────┘
|
|
│
|
|
┌───────────────────────────▼────────────────────────────────────┐
|
|
│ BACKEND API (Node.js) │
|
|
│ Express + TypeScript + Prisma │
|
|
├─────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
|
|
│ │ Auth │ │ Core │ │ Modules │ │
|
|
│ │ Module │ │ Services │ │ │ │
|
|
│ │ │ │ │ │ • Bookings │ │
|
|
│ │ • JWT Auth │ │ • Database │ │ • Tournaments │ │
|
|
│ │ • OAuth │ │ • Email │ │ • Leagues │ │
|
|
│ │ • RBAC │ │ • Logger │ │ • Payments │ │
|
|
│ │ │ │ • Queue │ │ • Subscriptions │ │
|
|
│ └─────────────┘ └─────────────┘ │ • Analytics │ │
|
|
│ │ • Notifications │ │
|
|
│ ┌─────────────┐ ┌─────────────┐ │ • Social │ │
|
|
│ │ Middleware │ │ Validators │ │ • Extras │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ • Auth │ │ • Zod │ │ │ │
|
|
│ │ • RateLimit │ │ • Sanitize │ │ │ │
|
|
│ │ • Errors │ │ • Transform │ │ │ │
|
|
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
|
|
│ │
|
|
└───────────────────────────┬────────────────────────────────────┘
|
|
│
|
|
┌───────────────────────────▼────────────────────────────────────┐
|
|
│ DATA LAYER │
|
|
├─────────────────────┬───────────────────┬──────────────────────┤
|
|
│ PostgreSQL │ Redis │ File Storage │
|
|
│ (Primary DB) │ (Cache/Queue) │ (Uploads/Logs) │
|
|
├─────────────────────┼───────────────────┼──────────────────────┤
|
|
│ • Users │ • Sessions │ • Avatars │
|
|
│ • Bookings │ • Cache │ • Tournament Images │
|
|
│ • Tournaments │ • Rate Limit │ • Documents │
|
|
│ • Payments │ • Pub/Sub │ • Backups │
|
|
│ • Analytics │ │ │
|
|
└─────────────────────┴───────────────────┴──────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 🗂️ Estructura de Directorios
|
|
|
|
```
|
|
app-padel/
|
|
├── backend/ # API REST Backend
|
|
│ ├── src/
|
|
│ │ ├── config/ # Configuraciones
|
|
│ │ │ ├── database.ts # Prisma/DB config
|
|
│ │ │ ├── logger.ts # Winston logger
|
|
│ │ │ └── mercadopago.ts # MP config
|
|
│ │ ├── controllers/ # Controladores HTTP
|
|
│ │ │ ├── auth.controller.ts
|
|
│ │ │ ├── booking.controller.ts
|
|
│ │ │ └── ...
|
|
│ │ ├── middleware/ # Middlewares Express
|
|
│ │ │ ├── auth.ts # JWT auth
|
|
│ │ │ ├── errorHandler.ts
|
|
│ │ │ └── validate.ts # Zod validation
|
|
│ │ ├── routes/ # Definición de rutas
|
|
│ │ │ ├── index.ts # Router principal
|
|
│ │ │ ├── auth.routes.ts
|
|
│ │ │ └── ...
|
|
│ │ ├── services/ # Lógica de negocio
|
|
│ │ │ ├── auth.service.ts
|
|
│ │ │ ├── booking.service.ts
|
|
│ │ │ └── ...
|
|
│ │ ├── validators/ # Esquemas Zod
|
|
│ │ │ ├── auth.validator.ts
|
|
│ │ │ └── ...
|
|
│ │ └── utils/ # Utilidades
|
|
│ │ ├── constants.ts # Constantes/enums
|
|
│ │ ├── jwt.ts # JWT utils
|
|
│ │ └── ...
|
|
│ ├── prisma/
|
|
│ │ └── schema.prisma # Esquema de BD
|
|
│ ├── logs/ # Archivos de log
|
|
│ └── ecosystem.config.js # PM2 config
|
|
│
|
|
├── frontend/ # Web App (React)
|
|
│ ├── src/
|
|
│ │ ├── components/
|
|
│ │ ├── pages/
|
|
│ │ ├── hooks/
|
|
│ │ ├── services/
|
|
│ │ └── store/
|
|
│ └── public/
|
|
│
|
|
├── mobile/ # Mobile App (React Native)
|
|
│ ├── src/
|
|
│ │ ├── components/
|
|
│ │ ├── screens/
|
|
│ │ ├── navigation/
|
|
│ │ └── services/
|
|
│ └── assets/
|
|
│
|
|
├── database/ # Scripts de base de datos
|
|
│ ├── migrations/
|
|
│ └── seeds/
|
|
│
|
|
├── docs/ # Documentación
|
|
│ ├── API.md
|
|
│ ├── SETUP.md
|
|
│ ├── DEPLOY.md
|
|
│ └── ...
|
|
│
|
|
└── scripts/ # Scripts de utilidad
|
|
└── deploy.sh
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 Flujo de Datos
|
|
|
|
### Flujo de Autenticación
|
|
|
|
```
|
|
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
│ Client │────▶│ Login │────▶│ Auth │────▶│ JWT │
|
|
│ │ │ Route │ │ Service │ │ Utils │
|
|
└──────────┘ └──────────┘ └──────────┘ └────┬─────┘
|
|
▲ │
|
|
│ ▼
|
|
│ ┌──────────┐
|
|
│ │ Database │
|
|
│ │ (User) │
|
|
│ └────┬─────┘
|
|
│ │
|
|
│ ┌────────────────────────────────────────────┘
|
|
│ │
|
|
│ ▼
|
|
│┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
└┤ Response │◀────┤ Generate │◀────┤ Validate │
|
|
│ Tokens │ │ Tokens │ │ User │
|
|
└──────────┘ └──────────┘ └──────────┘
|
|
```
|
|
|
|
### Flujo de Reserva
|
|
|
|
```
|
|
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
│ Client │────▶│ Create │────▶│ Validate │────▶│ Check │
|
|
│ │ │ Booking │ │ Input │ │Conflict │
|
|
└──────────┘ └──────────┘ └──────────┘ └────┬─────┘
|
|
▲ │
|
|
│ ▼
|
|
│ ┌────────────────────────────────────────────┐
|
|
│ │ ┌──────────┐ ┌──────────┐ │
|
|
└─────┼─────────┤ Save │◀────┤ Calculate│◀─────┤
|
|
│ │ Booking │ │ Price │ │
|
|
│ └────┬─────┘ └──────────┘ │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ ┌──────────┐ ┌──────────┐ │
|
|
└─────────┤ Response │ │ Notify │◀─────┘
|
|
│ Success │ │ User │
|
|
└──────────┘ └──────────┘
|
|
```
|
|
|
|
### Flujo de Pago
|
|
|
|
```
|
|
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
│ Client │────▶│ Create │────▶│ Mercado │────▶│ Preference│
|
|
│ │ │Preference│ │ Pago │ │ Created │
|
|
└──────────┘ └──────────┘ └──────────┘ └────┬─────┘
|
|
▲ │
|
|
│ │
|
|
│ ┌────────────────────────────────────────────┘
|
|
│ │
|
|
│ ▼
|
|
│┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
└┤ Redirect │────▶│ User │────▶│ Mercado │
|
|
│ MP │ │ Pays │ │ Pago │
|
|
└──────────┘ └──────────┘ └────┬─────┘
|
|
│
|
|
│ Webhook
|
|
▼
|
|
┌──────────┐
|
|
│ Update │
|
|
│ Status │
|
|
└──────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 🛡️ Patrones de Diseño
|
|
|
|
### MVC (Model-View-Controller)
|
|
|
|
```
|
|
Request ──▶ Routes ──▶ Controllers ──▶ Services ──▶ Database
|
|
│
|
|
▼
|
|
Validators (Zod)
|
|
```
|
|
|
|
### Repository Pattern (via Prisma)
|
|
|
|
```typescript
|
|
// services/user.service.ts
|
|
export class UserService {
|
|
async findById(id: string) {
|
|
return prisma.user.findUnique({
|
|
where: { id },
|
|
include: { profile: true }
|
|
});
|
|
}
|
|
|
|
async create(data: CreateUserDTO) {
|
|
return prisma.user.create({ data });
|
|
}
|
|
}
|
|
```
|
|
|
|
### Middleware Pattern
|
|
|
|
```typescript
|
|
// middleware/auth.ts
|
|
export const authenticate = async (req, res, next) => {
|
|
const token = extractToken(req);
|
|
const user = await verifyToken(token);
|
|
req.user = user;
|
|
next();
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Modelo de Datos (Simplificado)
|
|
|
|
```
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ User │ │ Booking │ │ Court │
|
|
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
|
|
│ id (PK) │◀────│ userId (FK) │────▶│ id (PK) │
|
|
│ email │ │ courtId (FK) │────▶│ name │
|
|
│ password │ │ date │ │ type │
|
|
│ role │ │ startTime │ │ pricePerHour │
|
|
│ level │ │ endTime │ │ isActive │
|
|
│ createdAt │ │ status │ └─────────────────┘
|
|
└─────────────────┘ │ totalPrice │
|
|
│ └─────────────────┘
|
|
│
|
|
│ ┌─────────────────┐ ┌─────────────────┐
|
|
│ │ Tournament │ │ Participant │
|
|
│ ├─────────────────┤ ├─────────────────┤
|
|
│─────────────▶│ id (PK) │◀────│ tournamentId(FK)│
|
|
│ │ name │ │ userId (FK) │
|
|
│ │ type │ │ status │
|
|
│ │ status │ │ paymentStatus │
|
|
│ │ maxParticipants │ └─────────────────┘
|
|
│ └─────────────────┘
|
|
│
|
|
│ ┌─────────────────┐ ┌─────────────────┐
|
|
└─────────────▶│ League │ │ LeagueTeam │
|
|
├─────────────────┤ ├─────────────────┤
|
|
│ id (PK) │◀────│ leagueId (FK) │
|
|
│ name │ │ name │
|
|
│ format │ │ members[] │
|
|
│ status │ │ points │
|
|
└─────────────────┘ └─────────────────┘
|
|
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ Payment │ │ Subscription │ │ SubscriptionPlan│
|
|
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
|
|
│ id (PK) │◀────│ userId (FK) │────▶│ id (PK) │
|
|
│ userId (FK) │ │ planId (FK) │────▶│ name │
|
|
│ type │ │ status │ │ type │
|
|
│ amount │ │ startDate │ │ price │
|
|
│ status │ │ endDate │ │ features[] │
|
|
│ provider │ │ autoRenew │ └─────────────────┘
|
|
└─────────────────┘ └─────────────────┘
|
|
|
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
│ Match │ │ Ranking │ │ Achievement │
|
|
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
|
|
│ id (PK) │ │ id (PK) │ │ id (PK) │
|
|
│ bookingId (FK) │ │ userId (FK) │◀────│ code │
|
|
│ team1Players[] │ │ points │ │ name │
|
|
│ team2Players[] │ │ level │ │ category │
|
|
│ score │ │ period │ │ requirement │
|
|
│ winner │ │ position │ └─────────────────┘
|
|
└─────────────────┘ └─────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 🔒 Seguridad
|
|
|
|
### Autenticación
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ AUTHENTICATION FLOW │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ 1. Client envía credenciales │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 2. Server valida con bcrypt │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 3. Genera Access Token (JWT, 7d) │
|
|
│ Genera Refresh Token (JWT, 30d) │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 4. Client almacena tokens │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 5. Requests incluyen: Authorization: Bearer <token> │
|
|
│ │ │
|
|
│ ▼ │
|
|
│ 6. Middleware verifica JWT │
|
|
│ Verifica usuario en DB │
|
|
│ Añade req.user │
|
|
│ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Autorización (RBAC)
|
|
|
|
```typescript
|
|
// Roles hierarchy
|
|
SUPERADMIN > ADMIN > PLAYER
|
|
|
|
// Permission matrix
|
|
Resource │ Create │ Read │ Update │ Delete
|
|
────────────┼────────┼──────┼────────┼───────
|
|
Users │ S │ S │ SA │ S
|
|
Courts │ A │ All │ A │ A
|
|
Bookings │ P │ P/Own│ P/Own │ P/Own
|
|
Tournaments │ A │ All │ A │ A
|
|
Payments │ P │ P/Own│ A │ S
|
|
Analytics │ - │ A │ - │ -
|
|
|
|
S = SuperAdmin, A = Admin, P = Player, Own = Own records
|
|
```
|
|
|
|
---
|
|
|
|
## ⚡ Performance
|
|
|
|
### Optimizaciones Implementadas
|
|
|
|
| Técnica | Implementación | Beneficio |
|
|
|---------|---------------|-----------|
|
|
| Connection Pooling | Prisma default | Reutiliza conexiones DB |
|
|
| Rate Limiting | express-rate-limit | Previene abuso |
|
|
| Response Compression | gzip | Reduce tamaño respuesta |
|
|
| Query Optimization | Prisma selects | Solo datos necesarios |
|
|
| Indexing | DB indexes | Búsquedas rápidas |
|
|
| Caching | Redis ready | Datos frecuentes en memoria |
|
|
|
|
### Escalabilidad
|
|
|
|
```
|
|
┌─────────────────────────────────────────┐
|
|
│ LOAD BALANCER │
|
|
│ (Nginx/CloudFlare) │
|
|
└──────────────┬──────────────────────────┘
|
|
│
|
|
┌───────┴───────┐
|
|
│ │
|
|
┌──────▼──────┐ ┌──────▼──────┐
|
|
│ API Node 1 │ │ API Node 2 │ ... (scale horizontally)
|
|
│ (PM2 inst) │ │ (PM2 inst) │
|
|
└──────┬──────┘ └──────┬──────┘
|
|
│ │
|
|
└───────┬───────┘
|
|
│
|
|
┌──────────────▼──────────────────────────┐
|
|
│ SHARED RESOURCES │
|
|
│ ┌──────────┐ ┌──────────┐ ┌────────┐ │
|
|
│ │PostgreSQL│ │ Redis │ │Storage │ │
|
|
│ └──────────┘ └──────────┘ └────────┘ │
|
|
└─────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Convenciones de Código
|
|
|
|
### Nomenclatura
|
|
|
|
| Elemento | Convención | Ejemplo |
|
|
|----------|-----------|---------|
|
|
| Archivos | kebab-case | `auth.controller.ts` |
|
|
| Clases | PascalCase | `AuthController` |
|
|
| Funciones | camelCase | `createBooking` |
|
|
| Variables | camelCase | `userId` |
|
|
| Constantes | UPPER_SNAKE | `JWT_SECRET` |
|
|
| Enums | PascalCase | `UserRole` |
|
|
| Interfaces | PascalCase | `BookingDTO` |
|
|
|
|
### Estructura de Endpoint
|
|
|
|
```typescript
|
|
// routes/example.routes.ts
|
|
import { Router } from 'express';
|
|
import { ExampleController } from '../controllers/example.controller';
|
|
import { authenticate } from '../middleware/auth';
|
|
import { validate } from '../middleware/validate';
|
|
import { exampleSchema } from '../validators/example.validator';
|
|
|
|
const router = Router();
|
|
|
|
// GET /examples - Listar
|
|
router.get('/', ExampleController.getAll);
|
|
|
|
// GET /examples/:id - Obtener uno
|
|
router.get('/:id', ExampleController.getById);
|
|
|
|
// POST /examples - Crear (protegido + validado)
|
|
router.post(
|
|
'/',
|
|
authenticate,
|
|
validate(exampleSchema),
|
|
ExampleController.create
|
|
);
|
|
|
|
export default router;
|
|
```
|
|
|
|
---
|
|
|
|
*Última actualización: Enero 2026*
|