- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8 - Actualizaciones de configuracion Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
234 lines
5.3 KiB
Markdown
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
|