# 📋 Decisiones Técnicas Consolidadas **Fecha:** 2025-01-25 **Versión:** 1.0 --- ## ✅ DECISIONES TOMADAS ### 1. Value Objects (Híbrido) ✅ - **Decisión:** Tipos simples en entidades, Value Objects en servicios - **Implementación:** - Entidades usan `ContentStatusType`, `ContentPriorityType` (strings) - Value Objects (`ContentStatus`, `ContentPriority`) en Application Services - Domain Layer mantiene entidades como POJOs ### 2. Serialización (Mappers) ✅ - **Decisión:** Mappers separados en Infrastructure Layer - **Implementación:** - `infrastructure/mappers/ContentItemMapper.ts` - Métodos `toDomain()` y `toPersistence()` - Domain Layer NO tiene métodos de serialización ### 3. IDs (Application Layer) ✅ - **Decisión:** UUIDs generados en Application Layer - **Implementación:** - Generar con `randomUUID()` en Use Cases - Pasar como parámetro a `create()` de entidades - Permite inyección en tests ### 4. Validación (Híbrido) ✅ - **Decisión:** Validaciones básicas en Domain, complejas en Application - **Implementación:** - Validaciones de formato en `create()` de entidades - Validaciones de negocio (unicidad, dependencias) en Services - Zod en Application Layer para esquemas ### 5. Fechas (ISO 8601 Strings) ✅ - **Decisión:** Strings ISO 8601 en entidades - **Implementación:** - `readonly createdAt: string` (formato: `"2025-01-25T10:00:00Z"`) - Mappers convierten strings ↔ PostgreSQL TIMESTAMPTZ - NO usar `Date` nativo ### 6. Arrays (readonly T[]) ✅ - **Decisión:** `readonly string[]` para arrays inmutables - **Implementación:** - `readonly tags: readonly string[]` - NO usar `ReadonlyArray` ### 7. Opcionales (Híbrido) ✅ - **Decisión:** `?` para opcionales, `| null` cuando null tiene significado - **Implementación:** - `readonly description?: string` (no proporcionado) - `readonly validatedAt: string | null` (explícitamente null) ### 8. Errores (Personalizados) ✅ - **Decisión:** Errores personalizados (`DomainError`, `ValidationError`) - **Implementación:** - `shared/errors/DomainError.ts` - Errores con código y contexto - NO usar errores genéricos ### 9. Versionado (Números Enteros) ✅ - **Decisión:** Números enteros incrementales - **Implementación:** - `readonly version: number` - `readonly latestVersion: number` - NO usar semantic versioning ### 10. JSONB (Union Types) ✅ - **Decisión:** Union types para campo `content` - **Implementación:** - `content: ProtocolContent | GuideContent | ManualContent` - Type safety completo - NO usar `Record` --- ## 📐 IMPACTO EN ARQUITECTURA ### Domain Layer - Entidades con tipos simples - Value Objects como clases separadas - Métodos `create()` con validaciones básicas - IDs recibidos como parámetro ### Application Layer - Generación de UUIDs - Validaciones complejas con repositorios - Uso de Value Objects para lógica - Zod para validación de esquemas ### Infrastructure Layer - Mappers para conversión Domain ↔ Persistence - Conversión de fechas (string ↔ TIMESTAMPTZ) - Conversión de nombres (camelCase ↔ snake_case) --- ## 🔄 FLUJO COMPLETO ### Crear Contenido 1. **Presentation Layer:** Recibe request, valida con Zod 2. **Application Layer:** - Genera UUID - Valida unicidad (repository) - Crea entidad con `ContentItem.create(id, ...)` 3. **Domain Layer:** - Valida formato básico - Retorna entidad inmutable 4. **Application Layer:** - Guarda con repository 5. **Infrastructure Layer:** - Mapper convierte a formato BD - Persiste en PostgreSQL --- **Fin del documento**