ARQUITECTURA · DDD · CLEAN CODE · BASE DE DATOS
Cómo trabajo por dentro: menos humo, más invariantes y tests
Mis reglas de arquitectura aplican igual en Python (Django / FastAPI), TypeScript (NestJS / Prisma / TypeORM) y Go: el dominio no depende del framework, los listados no tienen N+1 y la base de datos es la última línea de defensa.
01 · DDD & CLEAN ARCHITECTURE
Dominio puro, sin sobre-ingeniería y desacoplado del framework
La solución más simple que resuelva el problema, pero lo más ordenada posible. Las reglas de negocio nunca viven en serializers de DRF ni en DTOs de NestJS: viven en el dominio y se testean sin levantar el servidor.
Cero lógica de negocio en Serializers, Schemas (Pydantic/Zod) o Controllers: solo validación y transformación de entrada/salida.
Patrón Repository con interfaces en la capa de aplicación: permite correr suites enteras de casos de uso con FakeRepositories en memoria en milisegundos.
Límite estricto de ~400 líneas por archivo y una responsabilidad por módulo. Nada de monolitos inmanejables.
Fronteras de arquitectura garantizadas por ESLint / tests: domain/ jamás importa NestJS, Prisma ni Django.
Frontera de Capas & Caso de Uso con Repository Patterntypescript
// ✅ domain/quote-calculator.ts — Puro, determinístico, dinero en centavos (Int)
export function calculateOrderTotalCents(
items: ReadonlyArray<{ unitPriceCents: number; qty: number }>,
discountBps: number // 10000 = 100%
): number {
const subtotal = items.reduce((acc, item) => acc + item.unitPriceCents * item.qty, 0);
const discount = Math.round((subtotal * discountBps) / 10_000);
return Math.max(0, subtotal - discount);
}
// ✅ application/approve-budget.use-case.ts — Depende del puerto, no del ORM
export class ApproveBudgetUseCase {
constructor(
private readonly budgets: BudgetRepositoryPort,
private readonly workOrders: WorkOrderRepositoryPort,
) {}
async execute(budgetId: string): Promise<{ createdOrders: number }> {
const budget = await this.budgets.findByIdOrThrow(budgetId);
const groups = budget.partitionByBusinessUnitAndWorkType();
await this.workOrders.saveBatch(groups);
return { createdOrders: groups.length };
}
}CAJA DE HERRAMIENTAS EN PRODUCCIÓN
Stack Técnico Dominado
Sin dependencias innecesarias · Cada elección justificada por ADR
Núcleo transaccional y APIs
Backend & Arquitectura
Python · Django 5 & DRF
ERPs complejos, Signals, Channels (WebSockets), Celery
FastAPI
APIs async de alta velocidad, SQLAlchemy Async, Pydantic v2
TypeScript · NestJS
Monolitos modulares y microservicios con DDD estricto
Go (Golang)
Binarios seguros, concurrencia, proxies y custodios criptográficos
Modelado relacional y tiempo real
Datos, Caché & Mensajería
PostgreSQL
Modelado relacional, locks, índices estratégicos, RLS, constraints UNIQUE
Prisma & TypeORM
Repositorios desacoplados, migraciones reversibles (down.sql), conteo 1 vs N
Redis
Caché de baja latencia, broker de WebSockets (Daphne/Channels) y colas
RabbitMQ
Eventos de dominio, Saga Pattern y Outbox transaccional
De punta a punta hasta producción
IA Aplicada, DevOps & Front
MCP Servers & RAG
Protocolo MCP, pipelines de ingesta, Ollama local, Text-to-SQL seguro
Docker & Linux
Docker Compose, sandboxes aislados, Cloudflare Tunnels, CI/CD
Next.js & React Native
Interfaces operativas (Refine, Tailwind, Zod) y apps de campo (Expo)
Observabilidad & Testing
Sentry, TDD en dominio, repositorios Fake en memoria, Testcontainers
¿Querés ver las herramientas de código abierto que construí con este enfoque?
Sandboxes Docker para auditar MCP servers, pipelines RAG en NestJS y más.