@battle-racing/br-common-lib
Version:
Common library for all Battle Racing Repositorios
88 lines (55 loc) • 6.06 kB
Markdown
# Battle Racing Common Library (`br-common-lib`)
Este repositorio contiene los esquemas de validación Zod, los tipos TypeScript, y las constantes compartidas de domino que actúan como la **fuente única de verdad (Single Source of Truth)** para los microservicios y clientes del ecosistema de Battle Racing (POS, Game Manager Backend, y Web Apps).
Para asegurar la coherencia arquitectónica y facilitar la integración con futuras herramientas de IA (agentes), **todas las modificaciones al ecosistema deben respetar las siguientes convenciones y flujos**.
---
## 🏗️ 1. Modelo de Dominio Crítico: `User` vs `Player`
La decisión arquitectónica más importante del sistema es la inyección de **cero fricción** en el entorno físico de la pista. Para ello, se ha separado estrictamente el concepto de "Cuenta" (quien paga y se loguea) del concepto de "Corredor" (quien sale en la pantalla y maneja el Kart).
### `User` (La Cuenta / El Pagador)
- **Propósito:** Representa a la persona física que se registra en la app, gestiona un método de pago, y posee un historial transaccional.
- **Autenticación (Email o Teléfono):** En lugar de utilizar un `username` de foros antiguos, **la autenticación se realiza estrictamente a través de `email` o `phoneNumber`**. Esto asegura un proceso de on-boarding sin fricción y previene cuellos de botella en los puntos de venta (POS) donde un cajero o totém no puede adivinar qué `username` no está registrado.
- **Propiedades Clave:** `password`, `role` (SUPER_ADMIN, CASHIER, PLAYER), `type`.
- **Relación:** Un `User` siempre tiene asignado automáticamente un `defaultPlayerId` (su perfil de corredor). Sin embargo, un `User` (tutor o papá) puede administrar y poseer múltiples `Players` hijos (`MINOR`).
### `Player` (El Corredor)
- **Propósito:** Es la entidad gamificada. Representa los datos que ven los espectadores en la pantalla del líder, en la pista, y lo que se le asigna físicamente a un Kart.
- **Identificador (`nickname`):** Los jugadores se identifican por su `nickname` (ej. "Maverick 🏎️💨").
- **Regla de Oro (No Unicidad):** **Los `nicknames` NO son únicos en la base de datos**. Diferentes jugadores pueden llamarse "Juan" para evitar fricción en un sábado por la noche lleno de clientes registrándose. El sistema interno los diferencia mediante su `UUID` o vinculándolos temporalmente al número de Kart en la carrera activa.
- **Waivers:** Los `Players` deben firmar (o sus tutores deben firmar por ellos) un documento de exención de responsabilidad (`waiver`).
---
## 🛡️ 2. Práctica de Validación (Zod First)
Nuestra arquitectura delega TODA la validación de negocio y seguridad a **Zod**. En lugar de duplicar lógicas de validación en frontend, backend, y bases de datos, los moldes residen aquí en `br-common-lib`.
### Organización de Archivos (Arquitectura de Dominio)
Dentro de `src/domains/{domainName}/`:
- `*.schema.ts`: Aquí residen todos los objetos Zod (ej. `userSchema`, `userLoginInputSchema`).
- `*.types.ts`: Tipos estáticos autogenerados mediante `z.infer<typeof schema>`. Nunca se debe escribir un `interface` manualmente si ya existe un esquema de validación.
- `*.const.ts`: Enums, literales y variables constantes.
### DTOs en NestJS (`nestjs-zod`)
En el ecosistema Backend (`game-manager-backend`), está **estrictamente prohibido** usar decoradores de `class-validator` (como `@IsString()`).
En su lugar, los DTOs heredan del esquema Zod importado de esta librería utilizando la función `createZodDto`:
```typescript
// En game-manager-backend: src/modules/auth/dto/login.dto.ts
import { createZodDto } from 'nestjs-zod';
import { userLoginInputSchema } from '@battle-racing/br-common-lib';
export class LoginInputDto extends createZodDto(userLoginInputSchema) {}
```
Cualquier cambio a los endpoints o al pipeline de registro DEBE comenzar por actualizar el `.schema.ts` dentro de `br-common-lib` y recompilar la librería (`npm run build`).
---
## 🎟️ 3. Flujo Transaccional: Compras y Turnos de Juego (Ticketing)
### The `Purchase` (Compra)
- Agrupa múltiples "Items" de juegos bajo una misma transacción de pago con un `buyerUserId` (que puede ser Null si la compra se hace 100% anónima como Guest en el POS).
- La creación de compras asíncronas es un proceso validado por Webhooks (ej. una vez liquidado el pago en el gateway, se genera legalmente la compra).
### The `GameTicket` (El Boleto individual)
- Una compra de "3 Carreras" se desfragmenta en 3 `GameTicket` separados en la base de datos.
- Los Boletos nacen en estado `CREATED`.
- Un boleto es asignado a un corredor físico mediante el `playerId`. **Ya no se usa `ownerUsername`**.
### The `GameTurn` (El Turno Físico en Pista)
- Cuando un grupo de amigos se acerca a la fila, el operador (o el sistema automático) los agrupa en un `GameTurn`.
- El `GameTurn` toma un conjunto de `GameTickets` válidos (de cualquier compra anterior) y un conjunto de `playerIds` participantes.
- Enlaza la lógica del hardware, controlando qué `Kart` se le asigna a cada integrante para la carrera real y las misiones/tareas (`tasks`) escaneadas por QR.
---
## 🔄 4. Flujo de Trabajo para Inteligencias Múltiples (Agentes)
Si eres un modelo de IA leyendo este archivo para continuar con el desarrollo de Battle Racing:
1. **Nunca añadas `username`** ni regreses a prácticas de validación por foros.
2. Si un endpoint o componente frontend necesita una regla de UI o validación nueva, módificala **primero** en los schemas de `br-common-lib` y recompila con `npm run build`.
3. Evita las dependencias circulares usando los archivos de mapeo de barril (`index.ts`) y organizando siempre el código en `/domains`.
4. Todos los identificadores (ID's) a través del sistema están diseñados con `z.uuidv4()`. Mantén ese estándar para migraciones futuras a bases de datos escalables.
5. Emplea variables `emailOrPhone` cuando realices un flujo de acceso. No dupliques ni requieras ambas salvo expresamente configurado.