template-saas/docs/01-modulos/SAAS-012-crud-base.md
rckrdmrd 50a821a415
Some checks failed
CI / Backend CI (push) Has been cancelled
CI / Frontend CI (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / CI Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones de configuracion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:08 -06:00

234 lines
5.3 KiB
Markdown

---
id: "SAAS-012"
title: "Patrones Base CRUD"
type: "Module"
status: "Published"
priority: "P2"
module: "crud-base"
version: "1.0.0"
created_date: "2026-01-07"
updated_date: "2026-01-10"
---
# SAAS-012: Patrones Base CRUD
## Metadata
| Campo | Valor |
|-------|-------|
| Codigo | SAAS-012 |
| Modulo | crud-base |
| Prioridad | P2 |
| Estado | Documentacion |
| Tipo | Guia de Patrones |
| Ultima Actualizacion | 2026-01-10 |
---
## Descripcion
Este documento describe los patrones CRUD utilizados en el proyecto template-saas.
Actualmente cada modulo implementa su propia logica CRUD de forma independiente,
siguiendo las convenciones descritas aqui.
**Nota importante:** Las clases base documentadas (BaseCrudService, BaseCrudController)
son patrones recomendados, no clases implementadas. Cada modulo implementa su propia
logica siguiendo estos patrones.
---
## Patron Arquitectonico Actual
### Estructura por Modulo
Cada modulo backend sigue esta estructura:
```
modules/[nombre]/
├── [nombre].controller.ts # Endpoints REST
├── [nombre].module.ts # Configuracion NestJS
├── [nombre].service.ts # Logica de negocio (o services/*.service.ts)
├── dto/
│ ├── create-[nombre].dto.ts
│ ├── update-[nombre].dto.ts
│ └── [nombre]-response.dto.ts
├── entities/
│ └── [nombre].entity.ts # Entidad TypeORM
└── __tests__/
└── [nombre].service.spec.ts
```
### Ejemplo de Modulos que Siguen el Patron
- `modules/storage/` - Patron mas limpio y recomendado
- `modules/webhooks/` - Implementacion completa
- `modules/tenants/` - Implementacion simple
---
## Campos Base Comunes
Todas las entidades incluyen estos campos base:
| Campo | Tipo | Descripcion |
|-------|------|-------------|
| id | UUID | Primary key, auto-generado |
| tenant_id | UUID | Foreign key a tenants (RLS) |
| created_at | TIMESTAMP | Fecha de creacion |
| updated_at | TIMESTAMP | Fecha ultima modificacion |
| deleted_at | TIMESTAMP | Soft delete (nullable) |
| created_by | UUID | Usuario que creo (opcional) |
| updated_by | UUID | Usuario que modifico (opcional) |
---
## Patron de Paginacion
Todos los endpoints de listado soportan paginacion:
### Query Parameters
```typescript
interface PaginationQuery {
page?: number; // default: 1
limit?: number; // default: 10, max: 100
sort?: string; // campo a ordenar
order?: 'ASC' | 'DESC'; // default: 'DESC'
}
```
### Respuesta Paginada
```typescript
interface PaginatedResponse<T> {
data: T[];
meta: {
page: number;
limit: number;
total: number;
totalPages: number;
};
}
```
---
## Patron de Filtros
```typescript
interface FilterQuery {
search?: string; // busqueda full-text
status?: string; // filtro por estado
from?: string; // fecha inicio (ISO)
to?: string; // fecha fin (ISO)
}
```
---
## Endpoints REST Estandar
Cada modulo CRUD expone estos endpoints:
| Metodo | Ruta | Descripcion |
|--------|------|-------------|
| GET | /[recurso] | Listar con paginacion |
| GET | /[recurso]/:id | Obtener por ID |
| POST | /[recurso] | Crear nuevo |
| PATCH | /[recurso]/:id | Actualizar parcial |
| DELETE | /[recurso]/:id | Eliminar (soft delete) |
---
## SQL Base para Tablas
Template recomendado para nuevas tablas:
```sql
CREATE TABLE schema_name.table_name (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id),
-- Campos especificos aqui --
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ,
deleted_at TIMESTAMPTZ
);
-- Indices estandar
CREATE INDEX idx_table_tenant ON schema_name.table_name(tenant_id);
CREATE INDEX idx_table_deleted ON schema_name.table_name(deleted_at)
WHERE deleted_at IS NULL;
-- RLS
ALTER TABLE schema_name.table_name ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON schema_name.table_name
USING (tenant_id = auth.get_current_tenant());
-- Trigger updated_at
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON schema_name.table_name
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
```
---
## Decoradores y Validacion
### Decoradores Utiles
```typescript
// Excluir de respuesta
@Exclude()
deleted_at: Date;
// Transformar fecha
@Transform(({ value }) => value?.toISOString())
created_at: Date;
// Validacion condicional
@ValidateIf(o => o.type === 'special')
@IsNotEmpty()
specialField: string;
```
### Interceptores
```typescript
// Transformar respuesta
@UseInterceptors(ClassSerializerInterceptor)
// Log de audit
@UseInterceptors(AuditInterceptor)
```
---
## Roadmap: Clases Base Genericas
### Implementacion Futura Planificada
Se planea implementar clases base reutilizables para reducir duplicacion:
1. **BaseEntity** - Campos comunes (id, timestamps, tenant_id)
2. **BaseCrudService<T>** - Operaciones CRUD genericas con TypeORM
3. **BaseCrudController<T>** - Endpoints REST estandar
4. **BaseDto** - Validaciones comunes
**Estado:** Pendiente de implementacion
**Prioridad:** Baja (cada modulo funciona correctamente de forma independiente)
**Ubicacion propuesta:** `apps/backend/src/shared/`
---
## Referencias
- Implementaciones en: `apps/backend/src/modules/*/`
- Ejemplo recomendado: `modules/storage/`
- DDL templates: `apps/database/ddl/schemas/`
---
**Ultima actualizacion:** 2026-01-10