Tag: Programación

  • Cómo usar Claude Code para tareas sin ser developer

    Cómo usar Claude Code para tareas sin ser developer

    Es claude code tan solo para developers ? 3 cosas que puedes hacer con claude sin ser developer

    “Tiempo estimado de lectura: 3 min”

    • Claude Code es una herramienta orientada a terminales y repos; Claude (modelo web/API) ofrece razonamiento técnico accesible sin instalar dependencias.
    • Con Claude puedes diseñar y depurar workflows en herramientas como n8n (automatización), transformar y analizar datos, y generar documentación y diagramas (Mermaid, OpenAPI).
    • La diferencia clave no es saber programar, sino estructurar problemas y validar hipótesis técnicas usando el modelo web/API.

    Introducción

    Es claude code tan solo para developers ? Si escuchaste “CLI” y cerraste la puerta, respira: la respuesta técnica es sí —pero la historia completa no es tan simple.

    Claude Code (el agente CLI de Anthropic) está pensado para terminales, repos y tareas que tocan el código. Pero Claude, el modelo, vive en la web, en APIs y en integraciones: te da razonamiento técnico sin obligarte a teclear npm install. Aquí te explico por qué importa y tres cosas concretas que puedes hacer sin ser developer.

    Resumen rápido (lectores con prisa)

    Qué es: Claude Code es un agente CLI; Claude (modelo) se accede vía web/API e integraciones.

    Cuándo usarlo: Usa Claude Code si un agente debe tocar tu repo y ejecutar tests; usa Claude Web/API para razonamiento, diseño de flujos y transformación de datos.

    Por qué importa: Permite a non-devs con criterio diseñar, validar y documentar soluciones técnicas sin convertirse en especialistas en sintaxis.

    Cómo funciona: En vez de escribir sintaxis, describes escenarios, estructuras y reglas; el modelo transforma esa descripción en snippets, esquemas y diagramas reutilizables.

    Es claude code tan solo para developers ? Lo esencial en 60 segundos

    Claude Code = herramienta para desarrolladores. Vive en la terminal. Requiere Git, variables de entorno y un repo que pueda inspeccionar y modificar.

    Claude (3.7 Sonnet y variantes) = modelo razonador accesible por web/API. No necesitas compilar nada, sí necesitas saber explicar problemas con precisión. En vez de escribir sintaxis, planteas escenarios, estructuras de datos y reglas. El peso se traslada del teclado al criterio.

    Traducción práctica: si eres product manager, automation builder o founder, puedes usar Claude como copiloto intelectual. No como quien programa, sino como quien diseña y valida soluciones.

    1) Diseñar y depurar workflows en n8n — sin tocar Node.js

    n8n es el lugar donde los flujos se vuelven reales. Pero cuando un JSON llega sucio o una API no tiene nodo nativo, la fricción aparece.

    Lo que haces con Claude:

    • Pegas el payload del webhook y pides: “Dame el fragmento JS para extraer estos campos y normalizarlos.”
    • Le pides la lógica de reintentos y manejo de errores: condiciones, backoff y notificaciones.
    • Si una API requiere HMAC o firma en cabeceras, Claude te escribe la plantilla para el nodo HTTP.

    Ejemplo (conceptual): le describes el JSON y obtienes el snippet listo para pegar en un Code Node de n8n. No tienes que memorizar async/await; solo validar la salida.

    Referencia: n8n (automatización)

    2) Transformar y analizar datos — sin pelear con hojas de cálculo eternas

    Limpiar datos es un agujero negro. Claude lo hace predecible.

    Casos concretos:

    • Generar regex para extraer emails, IDs o patrones específicos. (“Extrae solo .edu y .org que parezcan institucionales.”)
    • Convertir CSV/XML desordenados a JSON con esquema validado. Pegas 50 filas y pides el JSON-schema.
    • Redactar consultas SQL complejas: joins, ventanas, filtros por fechas. Le das la estructura de tablas y la métrica que quieres; él devuelve la query optimizada para tu caso.

    No es “codificar por ti”. Es convertir trabajo repetitivo y propenso a errores en instrucciones reproducibles.

    3) Documentación y diagramas técnicos que no te roban medio día

    El 70% del valor de una decisión técnica está en cómo se comunica. Claude entiende Mermaid.js y puede producir diagramas desde tu texto.

    Lo que recibes:

    • Código Mermaid listo para pegar en Notion o GitHub y ver el diagrama al instante.
    • Un borrador de OpenAPI a partir de la descripción de un endpoint (paths, parámetros, respuestas).
    • Un mapa de arquitectura cloud con dependencias y puntos de integración (ideal para alinear con ingeniería sin sonar inocente).

    Pequeña ventaja: llegas a la reunión con algo que se puede visualizar y discutir, no con una vaga idea.

    Docu: Mermaid (diagramas) · OpenAPI spec

    ¿Cómo decidir si usar Claude Code o Claude Web/API?

    Regla simple:

    • Si vas a dejar que un agente toque tu repo, ejecuciones y tests: Claude Code (requiere developer).
    • Si necesitas razonamiento, diseño de flujos, transformación de datos o documentación: Claude Web/API o integraciones (ideal para non-devs con criterio).

    El nuevo diferencial no es “saber programar”. Es saber estructurar problemas y validar hipótesis técnicas. Claude amplifica eso.

    Conclusión

    No conviertas la terminal en el test de tu valía. Aprende a describir problemas con precisión y tendrás una herramienta que piensa en arquitectura, no solo en sintaxis. Esto apenas comienza: la próxima ronda será cómo integrar Claude en tus procesos de despliegue y gobernanza sin romper producción.

    Fuentes útiles: Anthropic – Claude, n8n (automatización), Mermaid (diagramas), OpenAPI spec

    Para explorar implementaciones y experimentos relacionados con automatización y agentes, visita Dominicode Labs. Es una continuación lógica para quien quiere pasar del diseño a prototipos reproducibles.

    FAQ

    Respuesta: Claude Code es el agente CLI de Anthropic diseñado para operar en terminales y repos (requiere Git, variables de entorno y permisos de repo). Claude, en cambio, es el modelo accesible por web/API e integraciones y está orientado a razonamiento y generación sin necesidad de ejecutar comandos locales.

    Respuesta: No. Para acceder al razonamiento y generación de soluciones técnicas puedes usar Claude Web/API o integraciones; no necesitas ser developer, pero sí saber describir problemas con precisión.

    Respuesta: Sí. Puedes describir el payload o el problema y pedir snippets o plantillas listos para pegar en un Code Node de n8n, así evitas escribir Node.js desde cero.

    Respuesta: Generación de regex, conversión de CSV/XML a JSON con esquema validado, y redacción de consultas SQL complejas (joins, ventanas y filtros). Claude transforma tareas repetitivas en instrucciones reproducibles.

    Respuesta: Sí. Claude puede producir código Mermaid y borradores de OpenAPI que se pegan directamente en herramientas como Notion o GitHub para visualización inmediata.

    Respuesta: Elige que un agente toque tu repositorio cuando sea necesario ejecutar pruebas, aplicar cambios automáticos o inspeccionar código de forma programática. Si solo necesitas diseño, razonamiento o generación de artefactos técnicos, la web/API suele ser suficiente.

  • Implementando Compound AI para Optimizar la Efectividad en Testing

    Implementando Compound AI para Optimizar la Efectividad en Testing

    ¿Quieres que la IA escriba código… o que lo arruine en silencio mientras nadie sabe por qué?

    Tiempo estimado de lectura: 8 min

    • Ideas clave:
    • Los LLMs no son inherentemente malos; el problema es soltarlos sin reglas ni orquestación.
    • Compound AI es orquestación: múltiples modelos, validadores, RAG y un controlador que decide.
    • Spec, Código y Tests deben mantenerse sincronizados; la trazabilidad y decisiones registradas son críticas.

    Introducción

    Poca gente lo dice claro: no es que los LLMs sean malos. Es que los estamos soltando sin reglas. Y rápido.
    Eso se nota cuando el triángulo Spec — Código — Tests se desincroniza a ritmo algorítmico. Y adivina qué aparece primero: deuda técnica.

    Claire Le Goues en CMU lo adelantó hace años. No es novedad; es evolución. Reparación automática de programas y análisis de cobertura no son juguetes académicos. Son la columna vertebral de cualquier agente que quiera escribir código que aguante en producción.

    Lo que estamos construyendo hoy se llama Compound AI. Y si lo manejas mal, es una mina.

    Resumen rápido (lectores con prisa)

    Compound AI: orquestación de múltiples modelos, validadores, bases de conocimiento (RAG) y un controlador.
    Úsalo cuando necesites código reproducible, verificable y trazable en producción.
    Importa porque reduce deuda técnica y fallos en producción al exigir specs operables, tests automatizados y decisiones registradas.
    Funciona mediante pipelines: inputs tipados, transformaciones, validación automática y decision logging.

    1) Por qué esto ya no es ML-only

    Los investigadores pueden inventar algoritmos bonitos. Pero la ingeniería de verdad exige cosas aburridas: orquestación de estado, reintentos inteligentes, persistencia de memoria, latencias aceptables y observabilidad.
    Necesitas backends robustos. PaaS. Infra que aguante agentes que lanzan 50 tareas concurrentes y esperan consistencia.

    2) DSPy y la estructuración de llamadas

    Frameworks como DSPy (o lo que quieras llamar ese nivel de orquestación) transforman llamadas LLM en flujos compilables.
    Piensa en DSLs para IA: inputs tipados, outputs comprobables, rutas deterministas. Menos “ensayo y error” y más pipelines reproducibles.

    3) Test-Time Inference y RLMs — lo que no es magia

    En vez de quemar ciclos entrenando eternamente, gastas cómputo en inferencia inteligente.
    Modelos de razonamiento (RLMs) exploran caminos, ejecutan validadores, comparan resultados y devuelven la versión que pasa las pruebas.
    Sí: eso cuesta. Sí: merece la pena cuando lo que quieres no es una demo, sino software que no explote a las 2AM.

    4) ¿Por qué necesitas ingenieros backend (con experiencia en PaaS)?

    Porque la solución no es un notebook de investigación. Es operación:

    • Orquestar estado entre modelos.
    • Persistir trazas y decisiones.
    • Manejar reintentos sin duplicar efectos.
    • Escalar validadores y tests en paralelo.
    • Aislar fallos y hacer rollback automáticos.

    Si tu equipo no tiene esto, el agente será como un aprendiz con acceso root: peligroso.

    5) El Triángulo que manda: Spec, Código, Tests

    Si uno se desincroniza, todo se va a la mierda. Punto.

    • La Spec debe ser operable. Markdown no basta. Necesitas specs con semántica, vinculadas a código y tests.
    • El Código debe exponer por qué existe. No solo el “qué”.
    • Los Tests no son opcionales. Deben ser ejecutados por el pipeline de agente antes de cualquier merge automático.

    Implementación ≠ caja negra. Implementación comunica intención. Y esa intención debe quedar como dato.

    6) Trazabilidad: la regla de oro

    Cada decisión que toma un agente necesita un artefacto: quién, cuándo, por qué, y qué alternativas se descartaron.
    Si el agente aplicó un “hack” para pasar un test, eso no puede quedar en un chat efímero. Tiene que vivir en tu repo, indexable. JSONL. PR metadata. Historia forense.

    ¿Por qué? Porque poder buscar “find all shortcuts” salva horas de debugging y evita que el mismo hack mute millón de veces.

    7) Integración práctica: stack mínimo para empezar hoy

    No necesitas toda una nave espacial. Esto es un MVP operativo:

    • Orquestador: un servicio que planifica pasos y guarda estado (puede ser una pequeña cola + DB).
    • Callers LLM: modelos rápidos (OSS) para edición y modelos potentes (RLM) para verificación.
    • RAG vector DB para contexto y specs.
    • Validadores: linters, pruebas unitarias, integración y un sandbox de ejecución.
    • Decision store: archivo versionado (.decisions.jsonl) por PR.
    • CI que no solo ejecuta tests, sino que verifica que la spec y los tests se actualizaron si el código cambió.

    8) Un flujo mínimo (ejemplo)

    1. Dev escribe o actualiza spec en formato operable.
    2. El agente genera código y propone cambios en una rama.
    3. Pipeline ejecuta tests + validadores.
    4. Agente intenta optimizar. Si aplica un atajo, registra una decisión en .jsonl. Commit falla si no hay artefacto.
    5. Reviewer aprueba la decisión o solicita cambio.
    6. Merge + sync spec/tests/código.

    Sí, agrega fricción. Es la fricción que salva producción.

    9) Herramientas y patrones recomendados

    • Esquemas validados: usa Zod o similar para validar outputs LLM cuando tocas boundaries.
    • Captura de decisiones: .jsonl con campos: id, pregunta, decisión, autor (LLM/humano), timestamp, diff link.
    • Umbrales configurables: “strict” para core, “lenient” para experiments.
    • Rollbacks automáticos: si una decisión se revoca, tus pipelines deben poder revertir o marcar la rama como needing-fix.
    • Observabilidad: traces de latencia, éxito de validadores, número de decisiones por PR.

    10) Cultura, no solo stack

    No automatices los valores. Automatiza la disciplina.
    Si el equipo ve la herramienta como un juez en lugar de asistente, la odiarán. Hazla útil. Hazla pequeña. Hazla punitiva solo cuando tenga que serlo.

    • Regla simple: cada cambio que no sea trivial necesita al menos una línea en la spec o una entrada en el decision log.
    • No más “and let it run and we go answer some email and then we come back and now I get a decision and I’m like, that’s insane. Don’t do that.” Si vas a delegar, que quede registrado.

    11) Riesgos reales y cómo mitigarlos

    • Ruido: Demasiadas decisiones pequeñas saturan. Solución: umbrales y agrupación por categoría.
    • Alucinaciones del LLM: Validadores estrictos y esquemas runtime.
    • Duplicidad de specs: Fragmenta specs por dominio y mantén ownership.
    • Ataques o leak de credenciales: todo secreto rotatable y accesible solo a procesos autorizados.

    12) Qué cambiar en GitHub (si tuvieras la varita mágica)

    • Markdown como entidad semántica. No solo texto.
    • Linkar decisiones ↔ specs ↔ tests ↔ diffs en la UI.
    • Búsqueda por “intención” (por ejemplo: “find decisions that relaxed auth checks”).
    • Hooks nativos que prevengan merges sin decision artifacts.

    13) Resultado: ¿qué ganas si lo haces bien?

    • Menos deuda acumulada.
    • Onboarding más rápido. Nuevos devs leen la historia de decisiones.
    • Automatización sin descontrol.
    • Auditoría real para compliance.
    • Velocidad que no se convierte en caos.

    14) No es sexy. Es efectivo.

    Las grandes respuestas técnicas no son flashes de genialidad. Son procesos con disciplina.
    Tenemos herramientas para bajar esa disciplina a la realidad operativa. Compound AI no es excusa para saltarse pasos. Es oportunidad para formalizarlos.

    ¿Quieres que lo vuelva práctico?
    Puedo:
    – Escribir el template de .jsonl para decisiones.
    – Diseñar el flujo de CI (GitHub Actions) que bloquee merges sin sincronía spec↔tests↔code.
    – Crear un checklist para ponerlo en marcha en 2 semanas.

    Respóndeme “Dame el template” o “Quiero la CI” y te lo entrego listo para copiar.
    Y recuerda: velocidad sin registro es solo una forma elegante de cavar tu propia trampa. Esto no acaba aquí.

    Si quieres avanzar en pipelines, validación y decision logging con ejemplos prácticos y plantillas, revisa los recursos y experimentos de Dominicode Labs. Es una continuación lógica para equipos que quieren pasar de prototipos a procesos operables. Encontrarás ejemplos de decision logs y patrones de integración que encajan con lo expuesto arriba.

    FAQ

    ¿Qué es Compound AI?

    Compound AI es la orquestación de múltiples modelos, herramientas de validación, bases de conocimiento (RAG) y un controlador que decide qué modelo o herramienta usar, cuándo y cómo, para producir resultados reproducibles y verificables.

    ¿Cuándo debo usar validadores estrictos?

    Usa validadores estrictos en componentes core que afectan seguridad, integridad de datos o disponibilidad. Para experimentos o prototipos puedes aplicar umbrales más lenient, pero documentándolo en el decision log.

    ¿Qué debe contener un decision log (.jsonl)?

    Campos mínimos: id, pregunta, decisión, autor (LLM/humano), timestamp y diff link. Debe ser indexable y versionado por PR.

    ¿Cómo evito que el agente aplique hacks sin supervisión?

    Bloquea commits sin artefacto de decisión; ejecuta validadores en CI; exige que cualquier atajo quede registrado en .jsonl y sea revisado por un humano antes del merge.

    ¿Qué cambios mínimos implemento en CI?

    1) Ejecutar tests y validadores automáticamente. 2) Comprobar que specs y tests cambien si el código cambia. 3) Fallar merges que no incluyan decision artifacts.

    ¿Cómo balancear fricción y velocidad?

    Define umbrales configurables: “strict” para core y “lenient” para experiments. Agrupa decisiones pequeñas y aplica políticas de batching para reducir ruido sin sacrificar trazabilidad.

  • Cómo evitar memory leaks en aplicaciones Angular

    Cómo evitar memory leaks en aplicaciones Angular

    Frontend Memory Leaks y como evitarlo en Angular

    Tiempo estimado de lectura: 3 min

    • Identifica suscripciones, listeners y timers que sobreviven a componentes.
    • Prefiere async pipe y herramientas integradas (takeUntilDestroyed) para evitar fugas.
    • Diagnostica con Chrome DevTools: heap snapshots y comparación de instancias.
    • Disciplina de equipo: code review, linters y políticas de invalidación en singletons.

    Introducción

    ¿Tu SPA se vuelve lenta sin error en consola? Frontend Memory Leaks y como evitarlo en Angular debería ser parte de tu checklist antes de enviar a producción. Si no controlas referencias, suscripciones y listeners, la app “come” memoria hasta que la pestaña muere.

    Resumen rápido (lectores con prisa)

    Qué es: Objetos no referenciados siguen vivos y el Garbage Collector no los elimina.

    Cuándo usar: Siempre que tu SPA cree y destruya componentes, gestiona suscripciones, listeners y timers.

    Por qué importa: Fugas causan degradación silenciosa de rendimiento en sesiones largas y móviles.

    Cómo funciona: Evita referencias persistentes: async pipe, takeUntilDestroyed, Renderer2 y limpieza en ngOnDestroy.

    Frontend Memory Leaks y como evitarlo en Angular: qué pasa y por qué importa

    Un memory leak ocurre cuando objetos que ya no necesitas siguen referenciados y el Garbage Collector no los elimina. En Angular esto duele más: la app vive sin recargas, los componentes se crean y destruyen, y cualquier referencia residual se acumula en el heap.

    No es magia ni culpa del navegador: es disciplina de código. Y sí, pasa en producción, en móviles y en equipos con pestañas cientos abiertas.

    Fuentes útiles:

    Vectores comunes y cómo cerrarlos

    Suscripciones RxJS sin gestionar

    • Qué pasa: .subscribe() vive más que el componente. El callback mantiene la instancia viva.
    • Soluciones: Async pipe (templates), takeUntilDestroyed() en Angular 16+, o takeUntil con un destroy$ en versiones anteriores.
    • Docs: RxJS takeUntil ; Angular rxjs-interop

    Event listeners globales

    Qué pasa: window.addEventListener('resize', fn) sin removeEventListener mantiene la referencia.

    Solución: usar Renderer2.listen() (retorna un unlisten) o guardar la referencia y llamarla en ngOnDestroy().

    Timers (setInterval, setTimeout)

    Qué pasa: un timer que cierra sobre this impide la recolección.

    Solución: almacenar el id y clearInterval/clearTimeout en ngOnDestroy().

    Servicios singleton con datos retenidos

    Qué pasa: providedIn: 'root' vive toda la sesión; si almacenas grandes estructuras sin limpieza, la memoria crece.

    Solución: políticas explícitas de invalidación / límites / weak references lógicas.

    Patrones prácticos (código)

    Async pipe — la opción más simple

    <!-- template -->
    <div *ngIf="data$ | async as data">{{ data.title }}</div>
    

    El async se suscribe y se desuscribe automáticamente cuando el componente muere.

    takeUntilDestroyed() — Angular 16+ (recomendado para TS)

    import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
    
    this.service.stream()
      .pipe(takeUntilDestroyed())
      .subscribe(x => this.handle(x));
    

    Patrón clásico (Angular <16)

    private destroy$ = new Subject<void>();
    
    ngOnInit() {
      this.service.stream()
        .pipe(takeUntil(this.destroy$))
        .subscribe(...);
    }
    
    ngOnDestroy() {
      this.destroy$.next();
      this.destroy$.complete();
    }
    

    Listeners con Renderer2

    private unlisten: () => void;
    
    ngOnInit() {
      this.unlisten = this.renderer.listen('window', 'scroll', this.onScroll.bind(this));
    }
    
    ngOnDestroy() {
      this.unlisten?.();
    }
    

    Timers

    private intervalId?: ReturnType<typeof setInterval>;
    
    ngOnInit() {
      this.intervalId = setInterval(() => this.poll(), 5000);
    }
    
    ngOnDestroy() {
      clearInterval(this.intervalId);
    }
    

    Cómo diagnosticar fugas — proceso práctico

    1. Abre Chrome DevTools → Memory (Chrome DevTools Memory).
    2. Toma Heap Snapshot.
    3. Navega al componente sospechoso, repite la interacción que crees filtra memoria.
    4. Regresa y toma otro snapshot.
    5. Compara: si ves instancias de tu componente o Detached DOM nodes, hay fuga.

    Allocation timeline te muestra crecimiento en tiempo real: una línea que solo sube y no baja es una mala señal.

    Política de equipo: lo que realmente previene fugas

    Esto no es sólo técnica, es disciplina:

    • Regla: preferir Async Pipe cuando sea posible.
    • Regla: toda suscripción en clase debe documentarse: ¿se cancela? ¿por quién?
    • Code reviews: busca .subscribe( sin takeUntil / takeUntilDestroyed o sin async.
    • Linters y tareas CI: detecta patrones peligrosos (por ejemplo .subscribe( sin unsubscribe en componentes).
    • Tests de rendimiento en CI: integra un paso de e2e que simule navegación repetida y monitorice memoria.

    Cierre: no cures síntomas, cambia hábitos

    Un memory leak no es un bug aislado; es deuda técnica que crece silenciosamente. Angular te da herramientas —async pipe, takeUntilDestroyed, Renderer2— pero depende del equipo usarlas consistentemente.

    Si quieres, en Dominicode podemos publicar una checklist de code-review y un snippet de ESLint que detecte suscripciones peligrosas. No te prometo magia: te prometo menos pestañas explotando. Apúntate y seguimos.

    FAQ

    ¿Qué es un memory leak?

    Un memory leak ocurre cuando objetos que ya no necesitas siguen referenciados y el Garbage Collector no los elimina. En una SPA esto provoca acumulación de memoria en el heap mientras la sesión continúa.

    ¿Cómo detectarlo en Angular?

    Usa Chrome DevTools → Memory: toma heap snapshots antes y después de interacciones repetidas. Busca instancias de componentes o Detached DOM nodes que no desaparecen.

    ¿Cómo manejar suscripciones RxJS?

    Prefiere async en templates, o en código use takeUntilDestroyed() (Angular 16+) o takeUntil con un destroy$ y limpieza en ngOnDestroy().

    ¿Y los listeners globales?

    No uses addEventListener sin remover. Usa Renderer2.listen() y llama al “unlisten” en ngOnDestroy().

    ¿Qué hacer con timers e intervalos?

    Guarda los ids retornados por setInterval/setTimeout y llama a clearInterval/clearTimeout en ngOnDestroy().

    ¿Los servicios singleton pueden filtrar memoria?

    Sí. Los servicios providedIn: 'root' viven toda la sesión; si almacenan grandes estructuras sin limpieza la memoria crece. Define políticas de invalidación y límites.

  • Cómo tipar correctamente una API REST en TypeScript

    Cómo tipar correctamente una API REST en TypeScript

    ¿Te fiarías de un mensaje de WhatsApp para pagar una factura importante? No. Entonces, ¿por qué confías en que la red te devuelva exactamente el JSON que tu UI necesita?

    Poca gente lo dice tan claro: la red es hostil. Los backends cambian, las APIs se versionan mal y los datos llegan raros. TypeScript te da sensaciones de seguridad en el editor. Fuera de la compilación, la realidad es JavaScript indiferente. Tipar una API REST no es cuestión de estética. Es la barrera que separa una app que sobrevive a la producción de un desastre nocturno.

    Voy a contarte cómo tipar correctamente una API REST en TypeScript sin postureo. Con ejemplos prácticos, decisiones arquitectónicas y la única verdad que importa: que tu app no rompa en prod por culpa de un campo faltante.

    Primera regla: el contrato no es el código. Es la promesa. Y debe ser verificable.

    Resumen rápido (lectores con prisa)

    Qué es: Validar y tipar el JSON recibido de la red en tiempo de ejecución usando esquemas (por ejemplo Zod) junto a tipos TypeScript.

    Cuándo usarlo: Siempre en boundaries de red; imprescindible para APIs externas o equipos distintos.

    Por qué importa: Previene errores silenciosos en producción y permite estrategias de error diferenciadas.

    Cómo funciona: Fetch/axios → recibir unknown → parse con Zod (o similar) → mapear a modelos internos.

    ¿Por qué los tipos por sí solos no bastan?

    TypeScript vive en tiempo de compilación. Cuando haces fetch o llamas a Axios, recibes JSON en tiempo de ejecución. TypeScript no inspecciona la red. Usar as T es firmar un cheque sin fondos: le estás diciendo al compilador “confía en mí”, pero nadie te va a confiar cuando el objeto tenga un null donde esperabas string.

    Eso genera errores silenciosos: undefined que se propaga, componentes que se caen sin stack trace claro, tests que pasan porque los mocks también mienten. La alternativa no es renunciar a TypeScript. Es complementarlo con validación runtime donde pinte.

    Paso 1 — Define el contrato: DTO claro y aislado

    Haz DTOs en su propio archivo. Separa lo que viene de la red de tus modelos internos.

    Ejemplo:

    // api/types.ts
    export interface UserResponse {
      id: string;
      email: string;
      full_name: string; // nota: formato snake_case típico de backend
      created_at: string;
    }
    
    export interface ApiError {
      statusCode: number;
      message: string;
      errorCode?: string;
    }
    

    ¿Por qué aislarlo?

    Porque si el backend cambia full_namefullName, no quieres que todo tu frontend explote. Cambias la capa de red y mapping. Punto.

    Paso 2 — Wrappers: encapsula fetch/axios

    No llames fetch o axios.get en mitad del componente. Haz un wrapper que:

    • haga la petición,
    • valide el payload,
    • normalice nombres,
    • lance errores tipados.

    Con fetch:

    async function fetchTyped(url: string, opts?: RequestInit): Promise {
      const res = await fetch(url, opts);
      const text = await res.text();
      let json;
      try {
        json = text ? JSON.parse(text) : {};
      } catch {
        throw new Error(`Invalid JSON from ${url}`);
      }
      if (!res.ok) throw Object.assign(new Error('HTTP error'), { status: res.status, body: json });
      return json as T; // todavía una aserción: complementa con validación runtime
    }
    

    Con Axios es más limpio:

    import axios from 'axios';
    async function get(url: string) {
      const res = await axios.get(url);
      return res.data;
    }
    

    Pero cuidado: Axios con genéricos es cómodo, no mágico. Sigue siendo una promesa de que la red devolverá lo que dijiste.

    Paso 3 — Validación runtime: Zod o similar

    Aquí se separan los novatos de los equipos que sobreviven. Zod no es moda; es la última capa de defensa. Define un esquema, parsea el JSON y obtienes tipado estático y validación a la vez.

    Ejemplo con Zod:

    import { z } from 'zod';
    
    const UserSchema = z.object({
      id: z.string(),
      email: z.string().email(),
      full_name: z.string(),
      created_at: z.string(), // luego puedes transformar a Date si quieres
    });
    
    type UserResponse = z.infer<typeof UserSchema>;
    
    async function fetchUser(id: string) {
      const raw = await fetchTyped<unknown>(`/api/users/${id}`);
      return UserSchema.parse(raw); // lanza un error si no coincide
    }
    

    Ventajas:

    • Detectas inmediatamente datos corruptos.
    • Los errores llegan con contexto (qué llave falló y por qué).
    • Puedes transformar created_at a Date de forma declarativa.

    Paso 4 — Manejo de errores tipados

    No uses catch (e) { console.error(e) }. En TS moderno el error es unknown. Te obliga a respirar antes de leer.

    Con Axios:

    try {
      const u = await get<UserResponse>('/api/users/1');
    } catch (err) {
      if (axios.isAxiosError(err)) {
        const server: ApiError | undefined = err.response?.data;
        console.error('Server:', server?.message ?? err.message);
      } else if (err instanceof z.ZodError) {
        console.error('Validation failed:', err.errors);
      } else if (err instanceof Error) {
        console.error('Network or runtime:', err.message);
      } else {
        console.error('Unknown error', err);
      }
    }
    

    ¿Por qué esto importa?

    Porque no es lo mismo que falles por validación (mal payload) que por HTTP 500 o por timeout. Cada caso requiere una estrategia distinta: retry, fallback UI, mostrar mensaje al usuario, reportar a Sentry con tags distintos.

    Paso 5 — Normaliza y mapea en la capa de red

    No dejes snake_case pululando por la app. Tradúcelo en la capa de consumo.

    function mapUser(api: UserResponse) {
      return {
        id: api.id,
        email: api.email,
        fullName: api.full_name,
        createdAt: new Date(api.created_at),
      };
    }
    

    Así tus modelos internos usan camelCase y Date real, no strings sucios.

    Decisiones arquitectónicas: cuándo validar y cuánto validar

    • Si controlas backend y frontend (monorepo o contrato firme): validación runtime puede ser ligera o incluso obviada en puntos internos. Pero en los boundaries externos, sigue validando.
    • Si consumes APIs públicas o equipos distintos: valida TODO. Sin excusas.
    • Campos opcionales: define qué hacer cuando faltan. ¿Default? ¿Error? No improvises en el handler.

    Performance y coste: ¿La validación runtime es lenta?

    Sí, agrega CPU. No, no es un killer. Para la mayoría de apps es insignificante comparado con network. Si tu app maneja miles de respuestas por segundo, shardea validaciones o valida en capas: sólo validar payloads que entren a la lógica crítica.

    Testing: no te olvides de tests de integración

    Mocks unitarios son útiles, pero añade tests e2e que disparen la API real (o un sandbox) y verifiquen que las validaciones y mappings no rompen. Testear tipado estático no te salva si la red cambia; testear contra endpoint sí.

    Checklist práctico (aplicable hoy)

    1. Centraliza DTOs en src/api/types.ts.
    2. Implementa un http wrapper (fetch/axios) que devuelva unknown.
    3. Define Zod schemas para cada DTO.
    4. Parsea el unknown con los schemas antes de castear a tipos.
    5. Mappea a modelos internos (camelCase, Date).
    6. Trata y tipa errores (Axios ZodError, Error genérico).
    7. Agrega tests e2e para validar contratos.
    8. Logea y reporta fallos con contexto (payload, endpoint, user id).

    Antipatrones que debes romper hoy

    • Usar as T en todo el código. Es la tapa del inodoro para ignorar problemas.
    • Confiar en que “el backend no cambia porque somos amigos”.
    • No versionar tus contratos. Versiona APIs y mantén backwards compatibility.
    • Manejar errores con any. Eso borra información útil para debugging.

    Metáfora que funciona: el contrato es la arquitectura del puente

    Tu frontend es el tráfico. El backend es el río. Si el puente (contrato) no es firme y verificado, los coches caen al agua. Los tipos son el plano; la validación runtime es el inspector que revisa la soldadura antes de poner el primer coche encima.

    Mini-guía de migración si tienes legado

    • Prioriza endpoints críticos: pagos, auth, guardar datos de usuario. Valida primero allí.
    • Añade schemas Zod incrementales; empieza por parse y logea sin bloquear; luego, cuando el tráfico confirme estabilidad, cambia a bloquear y fallar fast.
    • Automatiza alerts: si un endpoint empieza a fallar por validación, dispara una tarea de mesa de ayuda y un PR para el backend. No lo ignores.

    Y ahora, lo que pocas hojas blancas te dirán: la cultura importa

    La técnica sola no arregla nada. Si los desarrolladores creen que validar es “trabajo extra” y no “seguridad mínima”, la herramienta se convertirá en una carpeta más del repo. Hazlo obligatorio en el CI:

    • Test de contractos: correr zod.parse en un job.
    • Rechazar PRs si los contratos no están actualizados.
    • Mantén el mapping y los schemas en la misma PR que cambia el backend si controlas ambos.

    ¿Quieres algo listo para copiar y pegar?

    Tengo un template completo: wrapper http (fetch + manejo de errores), ejemplo de schema Zod, mapping y un job de GitHub Actions que valida contratos en CI. Lo dejo preparado para TypeScript + React (Vite) o Next.js.

    Haz esto ahora:

    1. Crea src/api/
    2. Pega el wrapper y el schema Zod del template.
    3. Añade ci/validate-contracts.yml a tu pipeline.
    4. Corre pnpm test:contracts en tu CI.

    ¿Te lo mando ya?

    Responde “Mándame el template” y te paso:

    • El wrapper http.ts listo.
    • Un user.schema.ts con Zod y z.infer.
    • Un ejemplo de fetchUser + mapping + test e2e.
    • Un workflow de GitHub Actions que bloquea merges si falla la validación.

    No es sexy. Es aburrido. Pero es lo que evita que pases la noche arreglando producción porque un created_at vino null.
    Esto no acaba aquí.

    FAQ

    ¿Por qué no son suficientes los tipos de TypeScript?

    Porque TypeScript opera en tiempo de compilación. Los datos de la red llegan en tiempo de ejecución y pueden diferir del contrato. Validar runtime evita errores silenciosos y fallos en producción.

    ¿Qué es Zod y por qué usarlo?

    Zod es una biblioteca de esquemas para validación y parsing en runtime. Proporciona validación declarativa, errores con contexto y permite inferir tipos TypeScript desde el esquema.

    ¿Dónde debo validar: en backend o frontend?

    Valida en ambos. El backend debe proteger su dominio; el frontend debe validar boundaries externos y usuarios malformados. Si controlas ambos, puedes relajar validaciones internas, pero nunca las boundaries públicas.

    ¿No hará lenta la app la validación runtime?

    Añade CPU, sí, pero para la mayoría de aplicaciones el coste es insignificante frente a la latencia de red. Para sistemas de alto rendimiento, valida selectivamente o en capas.

    ¿Cómo manejar campos opcionales o faltantes?

    Decide una política: default, error o fallback. Documenta la decisión y aplica la política consistentemente en la capa de red. No improvises en handlers dispersos.

    ¿Qué patrones debo evitar hoy mismo?

    Evita usar as T indiscriminadamente, confiar en que el backend no cambiará y manejar errores con any. También evita no versionar contratos y no tener tests contra endpoints reales.

    Tiempo estimado de lectura: 6 min

  • Cómo identificar y gestionar la deuda técnica en proyectos de software

    Cómo identificar y gestionar la deuda técnica en proyectos de software

    ¿Quieres que tu equipo deje de temer los viernes por la noche? Entonces presta atención: la deuda técnica no es un problema técnico, es un problema comercial disfrazado de código.

    Tiempo estimado de lectura: 6 min

    • Ideas clave:
    • La deuda técnica es una decisión con coste futuro; hay que tratarla como deuda comercial: medirla, priorizarla y pagarla en cuotas.
    • Las estrategias prácticas funcionan: Boy Scout, presupuesto técnico en sprints, tickets visibles, patrón Strangler y tests donde más duelen.
    • Detecta síntomas (deploys con miedo, PRs largos, regresiones) y aplica un plan de 90 días con diagnósticos y quick wins.

    Introducción

    Poca gente habla claro sobre esto. Todos hablan de “refactorizar” como si fuera una pócima mágica. Nadie te dice que hay que pagar esas facturas en cuotas, con interés, y con plan.

    Voy a contarte cómo identificarla, cuándo pagarla, cómo priorizarla y, sobre todo, cómo evitar que se convierta en una morgue de proyectos. No es teoría: es un manual de supervivencia para equipos que quieren seguir entregando valor sin enterrarse en yeso.

    Resumen rápido (lectores con prisa)

    Deuda técnica: decisión que acelera hoy y encadena mañana. Mide impacto en negocio, reserva presupuesto en cada sprint, prioriza por ROI y aplica mejoras incrementales (Boy Scout + Strangler).

    ¿Qué es la deuda técnica, de verdad?

    No es solo código feo o tests faltantes. Es cualquier decisión que acelera hoy y te encadena mañana.

    Pedir velocidad a cambio de calidad es pedir un préstamo. Si sabes que lo pides, es deuda deliberada. Si lo hiciste por ignorancia, es otra cosa — y merece formación, no romántica metáfora.

    La deuda tiene un interés: cada cambio posterior será más lento. Cada bug será más caro. Cada onboarding tomará más tiempo. Y cuando llegue la crisis, el interés se come tu ritmo de entrega.

    Cómo suena la deuda en la sala de engineering

    Frases que delatan deuda

    • “No lo toques, no vaya a romper algo” — frase clásica.
    • “Los rollouts se hacen los lunes por la mañana” — signo de miedo.
    • “Necesitamos 3 semanas para entender esto” — onboarding fallando.

    Si tu equipo dice estas frases, tienes deuda. Si además las frases salen con cara de resignación, tienes un problema estratégico.

    Tipos que importan (y cómo tratarlos)

    No todas las deudas se pagan igual.

    1) Deuda deliberada y prudente

    • Lo haces con los ojos abiertos.
    • Ejemplo: lanzar un MVP sin caché óptimo para validar mercado.
    • Cómo pagarlo: ticket en backlog, plazo definido, regla de “no crecer la superficie sin pagar”.

    2) Deuda deliberada y temeraria

    • Se hace por presión sin plan.
    • Ejemplo: copiar-pegar soluciones, no tests, no CI.
    • Cómo pagarlo: es urgente. Priorizar mitigación, pruebas, y quizá revertir la decisión de negocio si falla.

    3) Deuda inadvertida

    • Por falta de conocimiento o negligencia.
    • Ejemplo: código espagueti porque nadie revisa PRs.
    • Cómo pagarlo: formación, pair programming, código con owners claros.

    4) Deuda evolución/tecnológica

    • Dependencias sin actualizar, plataformas obsoletas.
    • Cómo pagarlo: calendarizar upgrades por riesgo, no por fecha bonita.

    Síntomas que deberían encender una alarma

    No lo adivines: mide. Estos son síntomas que indican bancarrota técnica:

    • Deployments con sudor frío y rollback semanal.
    • PRs que duran semanas por complejidad.
    • Reducción dramática de la velocidad del equipo sin razón aparente.
    • Regresiones frecuentes donde arreglas una cosa y rompes tres.
    • Tests que mienten o tardan horas en ejecutarse.

    Si ves dos o más, levanta la bandera y para la próxima feature hasta tener plan de pago.

    Estrategias que funcionan (no cuentos)

    Olvídate de “vamos a parar todo y reescribir”. Eso solo suena bien en presentaciones.

    La estrategia que funciona es incremental y política. Aquí las más efectivas:

    Regla del Boy Scout

    Deja el campamento un poco más limpio. Si tocas un archivo, arréglalo: renombra, añade un test, extrae funciones. Pequeñas mejoras constantes suman.

    Presupuesto técnico en cada sprint

    Reserva un % fijo del capacity (10–25%). Lo ideal depende de tu contexto. Si estás en hypergrowth, sube al 20%. Si estás estable, 10% puede bastar.

    Tickets visibles y priorizados

    La deuda que no está en el backlog no existe. Traduce deuda en tickets claros con impacto de negocio (tiempo de dev, riesgo, seguridad). Prioriza igual que features.

    El patrón Strangler (reconstrucción por partes)

    No reescribas el monolito. Construye nuevo alrededor y estrangula lo viejo. Migración por capas, desvío de tráfico y pruebas A/B hasta que lo antiguo deje de respirar.

    Writer único para datos críticos

    Si la deuda viene de concurrencia en escritura (bases, archivos), centraliza el writer. Evita múltiples procesos escribiendo el mismo artefacto.

    Tests donde duela

    No necesitas 100% coverage. Necesitas tests donde duele: integración crítica, pagos, seguridad y puntos con historial de fallos.

    Checklist para Tech Leads (haz que te obedezcan)

    Un listado que puedes imponer como política sin sermones:

    1. Cada PR > 200 LOC exige refactor simple o tests.
    2. Problema no documentado → no merge.
    3. Sprint: 15% de capacidad para deuda técnica.
    4. Métricas públicas: tiempo de build, tiempo de despliegue, tasa de rollback.
    5. Owners claros: cada módulo con responsable técnico.
    6. Registro de decisiones técnicas (ADR) obligatorio.

    Cómo priorizar: regla del ROI técnico

    No pagues lo que no frena tu negocio. Pregunta: ¿esta deuda impide ventas, seguridad o escalabilidad inmediata?

    Prioriza por:

    • Impacto en cliente (bugs críticos).
    • Riesgo de seguridad o cumplimiento.
    • Tiempo que retrasa nuevas features.
    • Coste de mantenimiento actual (horas/semana).

    Haz una matriz rápida: impacto vs esfuerzo. Ataca primero lo alto-impacto/bajo-esfuerzo.

    Evolución de personajes: el equipo, la feature y el legacy

    Imagina una escena: la feature (entusiasmada) quiere salir al mercado. El legacy (cansado) susurra “no me toques”. El equipo (dividido) corre para lanzar.

    Con el plan correcto, la feature sale, el equipo aprende y el legacy muere por asfixia controlada. Sin plan, la feature se convierte en otro parche que alimenta más deuda. La clave es dirigir la narrativa: que la feature evolucione, no que se enrede.

    Casos prácticos: qué hacer hoy mismo

    No necesitas permiso del CEO para estas acciones:

    1. Haz un sprint de diagnóstico (1 semana).
      • Recolecta métricas: tiempo CI, fallos, PR cycle.
      • Lista top 10 hotspots (archivos o módulos más cambiados/rotos).
    2. Empieza con 3 quick wins.
      • Añade tests en módulos críticos.
      • Elimina imports duplicados y variables globales peligrosas.
      • Automatiza un job de lint/format en CI.
    3. Define owner por módulo.
      • Asigna y documenta quien manda sobre cada componente.
    4. Programa un mes de mejoras
      • Plan de 4 semanas: cada semana 1 objetivo de deuda con entregable claro.

    Herramientas y métricas que realmente importan

    No más dashboards bonitos que no sirven.

    • MTTR (Mean Time To Recovery): si sube, hay deuda.
    • Tiempo medio de PR (days): cuando sube, complejidad.
    • Tasa de rollback: fricción operativa.
    • Coverage en paths críticos: no porcentaje general.
    • Tiempo de build y test: si CI crece, la velocidad muere.

    Cómo vender el pago de deuda al negocio (el argumento que funciona)

    No hables en técnico. Habla en riesgo, dinero y velocidad.

    • “Invertir X horas reduce tiempo de entrega de features en Y% y fallos en Z%”.
    • Muestra casos: “Reducimos rollbacks en 70% y ganamos N horas de dev/mes”.
    • Propón un plan con milestones y rollback: “Si no vemos mejora en 3 sprints, revertimos la política”.

    Cuándo sí reescribir (y cuándo no)

    Reescribir es una opción legítima. Pero sólo cuando:

    • La base de código es inentendible y ralentiza todo por encima del 50%.
    • Hay problemas legales o de seguridad que no se pueden parchear.
    • La plataforma actual impide crear valor competitivo.

    Si no, aplica strangler. Reescribir por ego o miedo es receta de desastre.

    Errores comunes que deberías evitar

    • No documentar la deuda: desaparece y vuelve peor.
    • Pay only when there are fires. (Pagar sólo cuando hay incendios.)
    • Pensar que QA soluciona deuda: QA encuentra errores, no reestructura código.
    • Ignorar la deuda cultural: sin code reviews, la deuda vuelve.

    Metáfora que pega: la deuda como jardín

    La deuda es jardín salvaje. Si lo ignoras, crece maleza y come el césped bonito. Podés dejarlo crecer por un tiempo si sólo querés probar el terreno (MVP). Pero a la larga, o contratas jardineros o el jardín se vuelve intransitable.

    Urgencia y plan de 90 días (si quieres resultados reales)

    Si te sientes valiente, este es el plan que recomiendo:

    • Día 0–7: Diagnóstico y métricas.
    • Día 8–30: Quick wins + políticas (Boy Scout + Sprint budget).
    • Día 31–60: Migraciones pequeñas (Strangler) y tests críticos.
    • Día 61–90: Medir impacto, ajustar presupuesto, presentar resultados al negocio.

    CTA directo (haz algo ahora)

    Haz esto ahora: abre tu tablero de issues, crea un epic llamado “Deuda Técnica — Sprint 0” y añade:

    • 3 métricas que vas a medir.
    • 3 hotspots para arreglar esta sprint.
    • Asignación del 15% de la capacidad.

    Respóndeme con “DEUDA YA” y te mando una plantilla de epic + checklist de 90 días que puedes pegar en tu Jira/Linear. Además te daré el mail corto y convincente para que envíes a Product/CEO y consigas el presupuesto técnico.

    Cierre — por qué esto no acaba aquí

    La deuda técnica no es un monstruo que se elimina de una vez. Es una economía: cobran intereses y cambia con el mercado. La idea no es purismo, es sostenibilidad.

    Si haces lo básico —visibilidad, presupuesto y pequeños pagos constantes— recuperarás velocidad y reducirás noches de pánico. Si no, la deuda comprará una hipoteca sobre tu tiempo de desarrollo.

    No te estoy pidiendo que seas perfecto. Te pido que seas estratégico. ¿Quieres la plantilla? Di “DEUDA YA”. Esto no acaba aquí: esto es el inicio de que tu equipo vuelva a confiar en sus despliegues.

    FAQ

    Respuesta: La deuda técnica es cualquier decisión que acelera hoy y genera coste futuro en forma de mayor complejidad, bugs o tiempo de desarrollo.

    Respuesta: Si observas dos o más síntomas (deploys con miedo, PRs largos, regresiones, subida del MTTR), detén nuevas features hasta tener un plan de pago.

    Respuesta: Reserva entre 10–25% del capacity por sprint. Ajusta según contexto: hypergrowth ≈ 20%, estable ≈ 10%.

    Respuesta: Reescribe solo si la base de código es inentendible y ralentiza más del 50%, hay problemas legales/seguridad o la plataforma impide crear valor competitivo.

    Respuesta: Publica tiempo de build, tiempo de despliegue, tasa de rollback, MTTR y tiempo medio de PR, además de coverage en paths críticos.

    Respuesta: Deuda deliberada se contrata con conocimiento y plan; inadvertida surge por falta de formación o procesos (ej.: PRs sin revisión).

    Respuesta: Traduce problemas técnicos en tickets con impacto de negocio (tiempo de dev, riesgo, seguridad), priorízalos como features y asigna owners claros.

  • Cómo Migrar a TypeScript 6.0 y Evitar Problemas

    Cómo Migrar a TypeScript 6.0 y Evitar Problemas

    ¿Listo para dejar de escribir código como si fuera 2016? TypeScript 6.0 no es un parche: es un ultimátum. Lee rápido. Haz el plan. Y no lo dejes para mañana.

    Tiempo estimado de lectura: 8 min

    • TypeScript 6.0 activa “strict” por defecto y cambia el módulo por defecto a ESM: esto exigirá limpiar deuda técnica y migrar módulos.
    • Trae soporte nativo para APIs modernas (Temporal, getOrInsert en Map) que reducen boilerplate y errores de fechas y caches.
    • Planifica la migración: branch, activar strict, clasificar errores, pruebas y CI, migración gradual a ESM y reemplazo progresivo de Date por Temporal.

    TypeScript 6.0 ya está aquí. Y no viene a hacerte la vida más fácil solo por cortesía: viene a exigir calidad. Si tu repo huele a “any” y a configuraciones por defecto, vas a ver errores. Muchos. Bienvenidos a la criba.

    Resumen rápido (lectores con prisa)

    TypeScript 6.0 activa “strict” por defecto, cambia el módulo por defecto a ESM y trae typings nativos para APIs modernas como Temporal y utilidades como getOrInsert en Map. Migrar requiere rama dedicada, pruebas y una estrategia gradual para modernizar módulos y reemplazar Date por Temporal.

    Qué cambia en TypeScript 6.0

    Primero: el golpe que no puedes ignorar — strict por defecto

    Hasta ahora, muchos iniciaban proyectos con la mínima fricción posible. Eso se acabó. TS 6.0 crea nuevos proyectos con “strict”: true por defecto. Traducción al cristiano:

    • noImplicitAny se vuelve exigente. Si algo no tiene tipo, ahora te lo va a recordar a gritos.
    • strictNullChecks hace que ignorar null y undefined sea una mala idea.
    • strictBindCallApply valida que cuando cambias el contexto de una función, lo hagas correctamente.

    Si tu código vive de aserciones (as any, as unknown, as Tipo), la migración te sacará los esqueletos del armario. Buen momento para limpiar deuda técnica, no para hacer commits de pánico.

    Ejemplo rápido: tsconfig mínimo ahora

    {
      "compilerOptions": {
        "target": "ES2022",
        "module": "esnext",
        "strict": true,
        ...
      }
    }

    Segundo: adiós CommonJS (por defecto), hola esnext

    TS 6.0 asume ESM como estándar. El valor por defecto de module pasa a esnext. Esto es intencional: el mundo ya está usando imports nativos, top-level await y bundlers modernos.

    Impactos prácticos:

    • Si aún exportas con module.exports y require(), tendrás que migrar o añadir compatibilidad.
    • Mejora el tree-shaking en bundlers modernos.
    • Usa Top-Level Await sin trucos.

    ¿Te preocupa Node legacy? Mantén compatibilidad en módulos concretos o transpila a CommonJS solo donde lo necesites. Pero el camino natural ahora es ESM.

    Tercero: nuevas API que facilitan la vida (Temporal, getOrInsert…)

    Temporal: el reemplazo sensato del desastre llamado Date

    Temporal no es una moda. Es la API de fechas que por fin piensa en zonas horarias, mutabilidad y precisión. TS 6.0 trae typings nativos para Temporal, así que puedes usarla sin depender de librerías externas.

    Ejemplo:

    import { Temporal } from '@js-temporal/polyfill'; // en runtime, o nativo en motores que lo implementen
    
    const ahora = Temporal.Now.plainDateTimeISO();
    const proximaSemana = ahora.add({ days: 7 });
    console.log(proximaSemana.toString());

    Temporal hace que calcular intervalos, convertir zonas y sumar días deje de ser una pesadilla llena de bugs.

    getOrInsert en Map: menos boilerplate, menos condiciones de carrera

    La operación de “si existe devuélvelo, si no cálcula/crea e inserta” es un patrón recurrente. Con getOrInsert (o emplace) lo tienes atómico y tipado:

    const cache = new Map();
    const user = await cache.getOrInsert(id, async () => await fetchUsuario(id));

    Esto evita el clásico:

    if (!map.has(key)) map.set(key, factory());
    const val = map.get(key);

    Menos código, menos bugs, menos gente escribiendo race conditions cuando la función es asíncrona.

    Cómo migrar sin incendiar el repo (plan paso a paso)

    Plan práctico

    • 1) No lo hagas en master. Crea un branch de migración y un plan.
    • 2) Activa strict localmente: cambia tsconfig y corre tsc. Déjalo fallar.
    • 3) Clasifica errores por impacto: trivial (añadir tipo), moderado (cambiar firmas), crítico (bibliotecas externas).
    • 4) Prioriza los puntos de entrada: handlers API, parsers de JSON, webhooks, init de app.
    • 5) Añade pruebas y CI que compile en strict. Si falla la compilación en PR, no se mergea.
    • 6) Moderniza módulos a ESM gradualmente. Empieza por paquetes que usen bundlers modernos.
    • 7) Reemplaza Date por Temporal en nuevos módulos. Hazlo con PRs pequeños.
    • 8) Introduce getOrInsert para caches y mapas concurridos.

    Checklist práctico para cada repo

    • – ¿tsconfig tiene “strict”: true? Si no, actívalo en un branch.
    • – ¿Import/Export mixto? Documenta y migra módulos uno por uno.
    • – ¿Tests unitarios? Asegúrate de que cubran la lógica de frontera (parsers, inputs externos).
    • – ¿Variables de entorno y config? Añade validación en startup (Zod o similar).
    • – ¿Dependencias nativas de Node? Verifica compatibilidad con ESM o usa interop wrappers.

    Riesgos reales y cuándo NO actualizar aún

    No es un dogma: hay casos donde deberías esperar.

    • – Repos monolíticos con mil paquetes legacy y dependencias dinámicas de require().
    • – Librerías que exponen CommonJS exclusivamente y no tienen roadmap de ESM.
    • – Pipelines que necesitan latencia ultra-baja y donde cambiar la cadena de build ahora es peligroso.

    Si estás en uno de esos escenarios, planifica una migración progresiva y una ventana de compatibilidad.

    Performance y el futuro del compilador (spoiler: se viene cambio de motor)

    TS 6.0 es la última gran versión mayor que funciona sobre el compilador escrito en JS/TS. El equipo ha dejado claro que la arquitectura actual llegó a su techo en repos masivos, y se ha hablado de explorar compiladores nativos (Go u otras tecnologías). Eso implica:

    • – Cambios en la velocidad de análisis a medio plazo.
    • – Posibles ajustes en la API del tooling.
    • – Mayor exigencia en la calidad del código para aprovechar mejoras de rendimiento.

    No lo tomes como alarma: tómalo como señal para ordenar tu base de código ahora, antes de que el motor cambie.

    Ejemplos rápidos que deberías probar hoy (copia-pega y juega)

    • 1) Activar strict y ver errores:
      npx tsc --init
      # edita tsconfig: "strict": true
      npx tsc --noEmit
    • 2) Probar Temporal (cliente o node con polyfill):
      npm i @js-temporal/polyfill
      node -e "const { Temporal } = require('@js-temporal/polyfill'); console.log(Temporal.Now.plainDateTimeISO().toString());"
    • 3) Migrar módulo a ESM:
      - cambia exports a export default / named exports
      - añade "type": "module" en package.json donde aplique

    Una metáfora rápida

    TS 6.0 es el peaje en la autopista. Si vas en coche viejo sin luces, te obliga a parar y actualizar. Si ya vas con el coche bien afinado, pasas más rápido. Y sí: pagarás por entrar, pero el viaje será más predecible.

    Cierre con plan de ataque corto (haz esto hoy)

    • 1. En un branch, activa strict y corre tsc. Mira la lista de fallos.
    • 2. Arregla los 10 errores más ruidosos. Haz PRs pequeños.
    • 3. Actualiza un paquete a ESM y lanza canary.
    • 4. Reemplaza Date por Temporal en un módulo pequeño.
    • 5. Añade validaciones de entrada (webhooks, APIs) usando Zod o tu validador favorito.

    CTA

    ¿Quieres la checklist automática para tu repo? Respóndeme con “MIGRAR MI REPO” y te envío el script que crea el branch, activa strict y lista los errores más críticos.

    FAQ

    ¿Por qué TS 6.0 activa strict por defecto?

    Porque busca elevar la calidad del código desde el inicio de nuevos proyectos. Activar strict reduce errores silenciosos relacionados con any, null y llamadas mal tipadas.

    ¿Tengo que migrar todo a ESM de inmediato?

    No. La recomendación es migrar gradualmente: empuja módulos que ya usan bundlers modernos, mantén compatibilidad para paquetes legacy y transpila a CommonJS solo donde sea imprescindible.

    ¿Cómo empiezo a usar Temporal sin romper producción?

    Introduce Temporal en módulos nuevos o en PRs pequeños. Usa el polyfill @js-temporal/polyfill en entornos que no lo soporten nativamente y añade pruebas para conversiones de zona horaria e intervalos.

    ¿Qué hago con dependencias que solo expone CommonJS?

    Mantén wrappers de interop o transpila esos paquetes en tu pipeline. Prioriza reemplazos si la dependencia es crítica y no tiene roadmap hacia ESM.

    ¿Qué pruebas debo priorizar durante la migración?

    Prioriza tests sobre parsers de entrada, handlers de API, webhooks y cualquier lógica que deserialice datos externos. Asegura que el CI falle si TypeScript en strict da errores.

    ¿Cómo evitar que un cambio de tsconfig rompa CI?

    Haz la activación de strict en un branch con su propio pipeline, clasifica errores y crea PRs pequeños que corrigen grupos de errores. No merges hasta que el build en strict pase.

  • Versiones maliciosas de Axios despliegan un troyano de acceso remoto

    Versiones maliciosas de Axios despliegan un troyano de acceso remoto

    Versiones maliciosas de Axios (1.14.1 y 0.30.4) despliegan un troyano de acceso remoto mediante un ataque de cadena de suministro

    Tiempo estimado de lectura: 5 min

    Ideas clave

    • Dos releases maliciosos: axios@1.14.1 y axios@0.30.4 publicados en npm el 2026-03-31 que introdujeron un RAT via dependencia secundaria.
    • Dependencia trampa: se añadió plain-crypto-js@4.2.1 con un script postinstall que descarga payloads desde http://sfrclak.com:8000.
    • Vector operacional: publicación manual con credenciales npm comprometidas; installs que usan latest sin lockfile pueden ejecutar código remoto.
    • Mitigación observada: detecciones automáticas (por ejemplo, Socket) y bloqueos de plataformas como Vercel ayudaron a contener la propagación.

    Tabla de contenidos

    Introducción

    El 31 de marzo de 2026 se publicaron en npm dos versiones maliciosas de Axios —1.14.1 y 0.30.4— que desplegaban un troyano de acceso remoto a través de una dependencia secundaria. Este incidente demuestra cómo una falla operacional en el ecosistema de paquetes puede convertir una librería ampliamente descargada en un vector de compromisos masivos.

    Resumen rápido (lectores con prisa)

    Qué: Axios publicó dos releases maliciosos que añadieron plain-crypto-js@4.2.1 con un postinstall que descarga y ejecuta un RAT.

    Cuándo: Publicado en npm el 2026-03-31; la dependencia trampa se subió ~18 horas antes.

    Por qué importa: installs que resuelven latest sin lockfile pueden ejecutar código remoto inmediatamente al correr npm install.

    Cómo funciona: el postinstall contacta a un C2 en http://sfrclak.com:8000 y descarga payloads por plataforma que actúan como RAT.

    Qué ocurrió, técnicamente

    Acceso y publicaciones

    Un atacante obtuvo acceso a las credenciales npm de un mantenedor principal de Axios, cambió el correo de la cuenta y publicó manualmente dos releases fuera del pipeline CI/CD y sin tags en GitHub. Las dos ramas (1.x y 0.x) fueron comprometidas con 39 minutos de diferencia.

    Dependencia trampa

    Previamente se subió la dependencia trampa plain-crypto-js@4.2.1 aproximadamente 18 horas antes de las releases. Esa dependencia definía un script postinstall que se ejecuta durante npm install y actúa como dropper.

    Impacto en installs

    Installs que resolvían latest sin un lockfile podían ejecutar código remoto tan pronto como npm install corría. Resultado: posibilidad de ejecución remota de código en entornos locales, CI y servidores de build.

    Cómo funciona el malware (anatomía técnica)

    1. Vector

    No se modificó el código funcional de Axios; se añadió una dependencia maliciosa en el árbol de dependencias.

    2. Trigger

    plain-crypto-js define un script postinstall. Npm ejecuta por defecto scripts de lifecycle en install, lo que activa la carga maliciosa.

    3. Dropper

    El postinstall contacta al servidor C2 y descarga un payload específico por plataforma (macOS, Windows, Linux). El servidor observado es http://sfrclak.com:8000.

    4. Persistencia y evasión

    El payload ejecuta acciones maliciosas, luego se autoelimina y sobrescribe su propio package.json con contenido “limpio” para dificultar auditorías forenses. Si el script se ejecutó en entornos con secretos (CI, máquinas de build, servidores), la exposición es grave.

    Diagnóstico rápido: cómo saber si te afectó

    Asume compromiso si ejecutaste npm install o instalaciones globales sin lockfile después de 2026-03-31T00:21:58Z. Búsquedas imprescindibles:

    • Revisar lockfiles y dependencias transitivas: package-lock.json / yarn.lock / pnpm-lock.yaml: busca axios@1.14.1 o axios@0.30.4.
    • Buscar en node_modules: busca plain-crypto-js.
    • Logs de red: busca conexiones a http://sfrclak.com:8000 o a sfrclak.com.
    • Sistemas CI: revisa jobs que corrieron npm install sin --ignore-scripts.

    Comandos útiles:

    grep -E "axios.*(1\.14\.1|0\.30\.4)" package-lock.json || true
    grep -r "plain-crypto-js" node_modules || true
    journalctl -u your-ci-agent.service | grep "sfrclak.com" || true

    Remediación inmediata (ordenada y práctica)

    1. Fija la versión segura en tus proyectos: axios@1.14.0 o axios@0.30.3 en package.json.
    2. Purge e instala de nuevo desde estado limpio:
      npm cache clean --force
      rm -rf node_modules
      npm install
    3. Rota TODOS los secretos de entornos que pudieron ejecutar el script: tokens CI, claves API, accesos a bases de datos y claves SSH.
    4. Redespliega desde artefactos construidos en entornos sanos.
    5. En CI, añade por defecto:
      npm ci --ignore-scripts

      Y autoriza scripts de instalación solamente de forma explícita y revisada.

    6. Audita y notifica: si detectas conexiones a http://sfrclak.com:8000, asume exfiltración y sigue el protocolo de respuesta de incidentes de tu organización.

    Medidas arquitectónicas y criterio técnico para evitarlo

    • Denegar por defecto: CI debe ejecutar --ignore-scripts y solo permitir scripts documentados y revisados.
    • Lockfiles en control de versiones: no sólo package.json; el lockfile debe revisarse y aprobarse en PR.
    • Auditoría de transitivas: integra escáneres (por ejemplo, Socket, Snyk, Dependabot) como paso obligatorio en PR y en pipelines.
    • Política de least privilege para cuentas de publish: MFA obligatorio, rotación de accesos, uso de cuentas de bot con límites.
    • Aislamiento de builders: construye artefactos en runners frescos y con secreto mínimo; evita que builders tengan credenciales de producción.
    • Monitorización post-install: alertas en EDR, inspección de conexiones salientes y huellas de procesos anómalos.

    Cierre: esto no acaba aquí

    Un mantenedor comprometido puede provocar daño a escala en minutos. La conclusión operativa es simple: reduce la superficie de ejecución de scripts, exige lockfiles revisados y trata las dependencias como parte del perímetro de seguridad. Implementa --ignore-scripts en CI, audita transitivas y rota secretos hoy mismo. Mañana publicaremos una checklist técnica para automatizar la autorización de scripts en pipelines y ejemplos de políticas IaC para entornos CI/CD.

    Dominicode Labs

    Para equipos que automatizan validaciones de seguridad en pipelines y flujos de trabajo, es recomendable integrar pasos automatizados de autorización y escaneo. Para recursos y pruebas aplicadas a pipelines, vea Dominicode Labs como continuación lógica de las medidas técnicas descritas.

    FAQ

    ¿Cómo sé si ejecuté el script malicioso?

    Asume compromiso si corriste npm install sin lockfile después de 2026-03-31T00:21:58Z. Busca la presencia de plain-crypto-js en node_modules, entradas de axios@1.14.1 o axios@0.30.4 en tus lockfiles y conexiones a http://sfrclak.com:8000 en logs de red.

    ¿Qué versiones de Axios son seguras ahora?

    Fija a axios@1.14.0 o axios@0.30.3 según la rama que uses. No uses las versiones 1.14.1 ni 0.30.4.

    ¿Debo rotar todos los secretos aunque no detecte conexiones al C2?

    Sí. Si un postinstall se ejecutó en un entorno con acceso a secretos, existe riesgo de exposición incluso sin señales evidentes de conexiones; rote tokens CI, claves API y credenciales de acceso como medida cautelar.

    ¿Por qué no basta con eliminar la dependencia maliciosa?

    El payload puede haber ejecutado acciones, creado persistencia o exfiltrado secretos antes de ser removido; además, puede haber sobrescrito artefactos y ocultado rastros. La remediación debe incluir rotación de secretos y reconstrucción desde artefactos sanos.

    ¿Qué configuraciones de CI deben cambiarse inmediatamente?

    Ejecutar por defecto npm ci --ignore-scripts, no almacenar credenciales de producción en runners que ejecutan installs, exigir revisión y aprobación del lockfile en PR y limitar cuentas con permisos de publish mediante MFA y políticas de least privilege.

    ¿Dónde puedo ver la página oficial del paquete afectado?

    La página oficial del paquete Axios en npm está disponible en página del paquete Axios en npm.

  • Implementación de Function Calling en Modelos LLM para Automatización

    Implementación de Function Calling en Modelos LLM para Automatización

    ¿Quieres que un modelo de IA deje de ser un loro elegante y empiece a hacer cosas reales por ti? Bienvenido a las Function calling.

    Tiempo estimado de lectura: 5 min

    Ideas clave

    • Las Function calling permiten a un LLM devolver una estructura (normalmente JSON) indicando intención y parámetros para que el backend ejecute acciones reales.
    • Existen dos estilos principales: JSON Schema (estricto) y formato libre (flexible), cada uno con trade-offs de seguridad y predictibilidad.
    • Diseño seguro requiere validaciones, registros, sandboxes, rollback y, para operaciones críticas, un human-in-the-loop.
    • Arquitectura práctica mínima: catálogo de herramientas, orquestador, executor aislado, auditoría y mecanismos de reversión.

    Tabla de contenidos

    Introducción

    Poca gente habla claro sobre esto: las llamadas a funciones son la diferencia entre un chatbot inútil y un agente que mueve fichas en el mundo real. No es magia. Es arquitectura.

    Resumen rápido (lectores con prisa)

    Las Function calling permiten que un LLM deje de generar solo texto y devuelva una estructura (normalmente JSON) con intención y parámetros para que tu backend ejecute acciones reales. Usa JSON Schema para operaciones críticas y formato libre para prototipos; siempre valida y, para escrituras peligrosas, exige confirmación humana.

    ¿Qué son, en una frase?

    Son el puente que permite a un LLM dejar de generar puro texto y pedirle a tu sistema: “oye, ejecuta esto”. El modelo no ejecuta nada por sí solo. Lo que hace es devolver una estructura (normalmente JSON) con la intención y los parámetros. Tu backend toma ese JSON, ejecuta la función y devuelve el resultado al modelo. Fin.

    ¿Por qué importa más que otra “nueva característica”?

    Porque hasta ayer los LLMs eran como una enciclopedia parlante: óptimos para explicar, pésimos para actuar. Las Function calling rompen ese techo. Ahora el modelo puede:

    • Consultar una base de datos en tiempo real.
    • Lanzar un reembolso en Stripe.
    • Generar y ejecutar una consulta SQL.
    • Enviar un mensaje a Slack o disparar un workflow en n8n.

    Es como si le dieras manos al loro: sigue hablando, pero ahora también abre puertas.

    El ciclo real: cómo funciona sin volverte loco

    No inventes un diagrama mental complejo. Hay cinco pasos claros y repetibles:

    1. Tu app manda el prompt + la descripción de las herramientas disponibles.
    2. El modelo decide: ¿lo puedo responder solo o necesito una herramienta?
    3. Si necesita, devuelve un JSON con el nombre de la función y parámetros.
    4. Tu backend valida y ejecuta la función real (API, DB, script).
    5. Devuelves el resultado al modelo. Él sintetiza y responde al usuario.

    Siempre hay una mano humana posible en el medio, sobre todo en operaciones peligrosas. Más abajo te explico por qué.

    Dos estilos de herramientas: JSON Schema o texto libre

    No todas las herramientas son iguales. Hay dos escuelas y cada una tiene su lugar.

    JSON Schema (estricto)

    Defines la función, tipos, campos obligatorios y enums. El modelo devuelve exactamente lo que espera tu backend. Es predecible, seguro y perfecto para integraciones REST y sistemas críticos. Ejemplo mental: la función crear_ticket exige titulo:string y prioridad:("alta"|"media"|"baja"). Punto y final.

    Formato libre (texto)

    El modelo genera un bloque de texto, código o comando. Ideal para análisis ad-hoc, scripts complejos o cuando necesitas flexibilidad absoluta. Requiere parsing robusto y sandboxes. Es más potente, pero también más peligroso si no controlas la entrada y la ejecución.

    ¿Cuándo usar cada una?

    • Si tu operación cambia estados críticos (pagos, borrados, cambios de permisos): usa JSON Schema y validaciones humanas.
    • Si estás haciendo análisis, prototipos o generación de consultas SQL que luego validarás: el modo libre puede acelerar prototipos, pero añade riesgo.

    Casos de uso que realmente importan (no los anuncios)

    • Customer Success: un agente recibe una queja, consulta el pedido en Shopify y, si procede, crea el reembolso en Stripe. Si la operación implica dinero, envía un checkpoint a un humano antes de ejecutar.
    • DataOps: un usuario pide “ventas por región ayer”. El LLM traduce a SQL, ejecutas, devuelves los resultados y el modelo te da el resumen en lenguaje natural.
    • Automatizaciones internas (n8n): en vez de tener flujos rígidos, el modelo decide qué nodos disparar, en qué orden y con qué parámetros, según la intención del usuario. Eso convierte tu automatización en dinámica, no en una secuencia predefinida.

    Una advertencia sin eufemismos: los modelos mienten (a veces)

    Alucinación de parámetros. Prompt injection. Errores sutiles. No es paranoia, es experiencia. Los LLMs pueden inventarse campos, malinterpretar enums o seguir instrucciones maliciosas ocultas en el prompt.

    Regla de oro

    • Automáticamente ejecuta lecturas (GET) si la operación es inofensiva.
    • Para escrituras (POST/DELETE/PUT) exige validación adicional: reglas en el backend o confirmación humana. Siempre. No, no es opcional.

    Human-in-the-loop: no es una filosofía, es ingeniería

    La idea es simple: deja que el LLM proponga, pero que un humano o una lógica de negocio firme el cheque para operaciones críticas. Dos patrones útiles:

    • Confirmación explícita: el LLM genera el payload, lo guardas y muestras a un humano para aprobar.
    • Validación automática: reglas en el backend que verifican coherencia, límites y permisos antes de ejecutar.

    Si haces esto bien, reduces riesgos drásticamente sin perder automatización.

    Arquitectura práctica: qué componentes necesitas

    No necesitas un stack del otro mundo. Necesitas disciplina.

    1. Registro de herramientas: catálogo con descripciones y esquemas JSON.
    2. Orquestador: recibe el JSON del LLM, valida y ejecuta. Aquí entra n8n, un backend propio o un servidorless.
    3. Sandbox/Executor: si vas a ejecutar scripts generados por el modelo, hazlo en un entorno aislado.
    4. Auditoría: logs de cada llamada, inputs y outputs. Esto no es solo para depurar; es para seguridad y cumplimiento.
    5. Rollback y revocación: especialmente si permites crear o borrar recursos.

    Un ejemplo mental (sin código complicado)

    Usuario: “Reembolsa el pedido 123 si no se ha enviado.”

    El LLM: decide que necesita verificar el estado del pedido → devuelve { action: "checkOrder", orderId: "123" }.

    Tu backend: consulta y devuelve { status: "pending", paid: true }.

    El LLM: con ese dato propone { action: "refund", orderId: "123", reason: "producto no enviado" }.

    Tu backend: valida política de reembolsos y, si todo ok, lo ejecuta o pide OK humano.

    Pistas y errores que nadie te dirá gratis

    • Nunca confíes en que la respuesta del LLM está “bien formateada”. Valida siempre.
    • Evita exponer funciones peligrosas sin restricciones de permiso.
    • Ten límites de tasa para evitar loops: un LLM llamando a una función que regenere prompts puede convertirse en un bucle infinito.
    • Si permites código, ejecútalo en containers efímeros con timeouts rígidos.

    Metáfora que pega y que funciona

    Las Function calling son como darle una tarjeta de crédito a un asistente. Con ella puede comprar lo que necesita, pero tú decides los límites, si necesita aprobación para ciertos tickets y a qué tiendas no puede entrar. Sin límites, te quedas sin dinero. Con límites y reglas, ganas productividad.

    Urgencia realista

    Si estás empezando a usar LLMs para interacción con sistemas reales y no diseñaste estas capas, estás pidiendo problemas. Empezar ahora con patrones sólidos (schemas, validaciones, humanos en la cadena) te ahorra migraciones dolorosas.

    ¿Quieres empezar ya?

    Haz esto en 3 pasos prácticos:

    1. Define las 3 funciones más críticas que quieres exponer (consulta de pedidos, emitir reembolso, crear ticket).
    2. Escribe schemas JSON mínimos para cada una y prueba el loop: prompt → LLM → JSON → backend → resultado.
    3. Añade validación humana para la más peligrosa y logs para todo.

    No te dejo solo: ¿seguimos con la parte técnica?

    Puedo enviarte:

    • Un checklist para diseñar tus schemas JSON.
    • Plantillas de orquestador para n8n con ejemplos de validación humana.
    • Estrategias para sandboxing y rollback.

    Respóndeme este mensaje y te doy la checklist completa y un ejemplo listo para copiar y pegar. Esto no acaba aquí: en la próxima entrega te muestro cómo migrar un flujo rígido de n8n a un agente LLM dinámico sin incendiar producción. ¿Te interesa?

    Dominicode Labs

    Si quieres ejemplos prácticos, plantillas y artículos relacionados con automatización, agentes y workflows, revisa Dominicode Labs. Es una continuación lógica para implementar patrones de Function calling en entornos productivos.

    FAQ

    ¿Qué diferencia hay entre JSON Schema y formato libre?

    JSON Schema es estricto: defines tipos, campos y enums y el modelo debe devolver estructura predecible. Formato libre permite flexibilidad para análisis o scripts complejos, pero requiere parsing y sandboxes adicionales.

    ¿Debo permitir que el modelo ejecute escrituras automáticamente?

    No. Para escrituras (POST/DELETE/PUT) exige validación adicional en backend o confirmación humana. Es la regla de oro indicada en el artículo.

    ¿Cómo prevengo loops entre el LLM y mis funciones?

    Aplica límites de tasa y reglas que detecten y rompan llamadas recursivas. Evita diseños donde una función cause regeneración automática de prompts sin control.

    ¿Qué registros debo guardar?

    Logs de cada llamada, inputs y outputs. Auditoría para depuración, seguridad y cumplimiento. Guarda también decisiones de validación y aprobaciones humanas.

    ¿Cuándo usar validación humana?

    Para operaciones críticas que afecten dinero, permisos o borrados irreversibles. También cuando las reglas automáticas no pueden garantizar seguridad suficiente.

    ¿Es seguro ejecutar código generado por el modelo?

    Solo en sandboxes aislados, con containers efímeros y timeouts rígidos. El artículo recomienda ejecutar código en entornos aislados y con controles estrictos.

  • Cómo crear prompts efectivos para generar código con IA

    Cómo crear prompts efectivos para generar código con IA

    ¿Quieres que tu proyecto salga de un prompt y se convierta en un producto real… o en otro experimento bonito que nadie mantiene?

    Poca gente lo dice así: usar Lovable o Bolt.new no te salva de las malas decisiones. Te da velocidad y una sensación de omnipotencia. Eso es peligroso. Si no pones reglas, estándar y criterio técnico, la IA te entregará un prototipo brillante y un desastre a medio plazo.

    Resumen rápido (lectores con prisa)

    Qué es: Lista de buenas prácticas para usar IA en generación de código de producción.

    Cuándo usarlo: Antes de delegar generación de pantallas, esquemas o integraciones críticas a un LLM.

    Por qué importa: Evita deuda técnica, fugas de seguridad y vendor lock‑in.

    Cómo funciona: Define contrato y plan primero; da contexto reducido al modelo y versiona prompts.

    Tiempo estimado de lectura: 6 min

    Ideas clave

    • Ventana de contexto es tu presupuesto: modulariza y da snippets pequeños.
    • Diseña tus tablas y ERD antes de pedir esquemas a la IA.
    • Plan First: valida el plan antes de generar código.
    • Evita vendor lock‑in y exige código estándar y control de versiones.
    • Seguridad: nunca hardcodees keys en el cliente; usa BFF y Secret Manager.

    1) El Context Window es tu presupuesto real

    La IA no tiene memoria infinita. La ventana de contexto es el límite de atención del modelo. Si tu app es un mamotreto con 20 componentes, 10 rutas y 3 librerías por feature, la IA terminará olvidando piezas críticas.

    Síntoma

    Pides una nueva pantalla y la IA borra imports o rompe tests que estaban bien ayer.

    Solución

    • Modulariza. Divide en microcomponentes. Un componente = una responsabilidad.
    • Un prompt = el componente y sus contratos (props, eventos, estado).
    • Mantén snippets pequeños y referencias externas. No le metabolismes el repo entero en una sola petición.

    Truco

    La ventana de contexto es la mochila del modelo. Pocas cosas, y bien organizadas —no todo el campamento adentro.

    2) Base de datos: tú diseñas las tablas, no la IA

    Lovable y Bolt.new son rápidos para scaffolding. Pero pedirle a la IA que “genere el esquema” suele acabar en redundancias y campos con nombres raros tipo “user_name_2”.

    • Regla dura: escribe el ERD primero. Define relaciones (1:N, N:M), claves foráneas, índices y tipos. Dale ese SQL o ese esquema inicial a la IA como contexto.
    • Si usas Supabase, prepara las migrations y políticas RLS antes de que la IA genere las pantallas.
    • Beneficio: menos prompts, menos correcciones, menos refactors dolorosos.

    3) Plan First, Code Later — no es sugerencia, es mandamiento

    Las herramientas muestran un plan. Léelo como si fuera el contrato que firmarás. Si el plan falla, el código será un remiendo.

    Preguntas que debes hacer al plan

    • ¿Entendió el flujo del usuario?
    • ¿Qué librerías propone y por qué?
    • ¿Qué estrategias de estado (local/global) va a usar?
    • ¿Qué testing planea (unit, e2e)?

    Si la IA propone algo raro, corrígelo en el plan. Luego ejecuta la generación.

    Pro-tip: agrupa requerimientos complejos en un solo prompt largo (Lovable) o en un bloque bien definido con ejemplos (Bolt.new). Gasta menos mensajes y evitas contradicciones.

    4) Vendor lock‑in y exportación: piensa en huir antes de casarte

    ¿Y si dentro de seis meses quieres migrar? ¿Qué pasa si Bolt.new cambia modelo de negocio? No te cases por default.

    • Exige código estándar: React+Vite+Tailwind o lo que tu equipo soporte.
    • Control de versiones: GitHub integrado y commits humanos. Que el repo sea clonable y arranque local.
    • Evita dependencias propietarias: libs que solo funcionan dentro del editor de la plataforma son bombas de tiempo.

    5) Manejo de diffs y errores cíclicos: corta el bucle

    La IA puede entrar en bucles de “arreglar-esto-romper-aquello”. Si ves repetidos fallos en el mismo bloque, deja de pedirle que arregle. Entra y corrige manualmente.

    • Técnica simple: si falla dos veces en el mismo lugar, resetea a un commit estable y arregla a mano. Luego vuelve a la IA.
    • Por qué funciona: rompes el estado de error acumulado y le das a la IA un contexto limpio.

    Tokens vs mensajes: cómo pagar menos sin perder eficacia

    Bolt.new cobra por tokens. Lovable, por mensajes. Eso cambia la estrategia.

    • Bolt.new (tokens): haz micro-prompts, optimiza longitud y reusa templates. Bueno para iteración rápida.
    • Lovable (mensajes): agrupa instrucciones complejas en un solo prompt largo. Menos interacciones, más orden.

    Stack “opinada”: si quieres otra cosa, pelea por ello

    Estas herramientas aman React y Tailwind. Si tu stack es Angular, Laravel o un monolito legacy, prepárate para forzar mucho al modelo.

    • Opción A: adapta tu stack al flujo (si puedes).
    • Opción B: usa una herramienta más abierta (Cursor, Copilot, IDEs asistidos). Menor magia visual, pero mayor control técnico.

    Seguridad: las API keys no son souvenirs

    El error clásico: pedir a la IA que “integre Stripe” y conseguir un .env con la API key pegada en el frontend. Eso pasa. Mucho.

    • Nunca pongas keys en el cliente.
    • Siempre: BFF (Backend-for-Frontend) + Secret Manager (AWS Secrets Manager, Vault).
    • Recomendación: short-lived tokens y rotación automatizada. Kill-switch para revocar keys si algo huele raro.

    Prompt versioning: trata el prompt como código

    Un cambio de prompt puede cambiar comportamiento entero. Versiona tus prompts como si fueran migrations.

    • Estructura mínima: promptId, version, author, changelog, template.
    • Guarda promptId y promptVersion en metadatos de cada request para reproducibilidad y auditoría.

    Moderación y trust & safety: no lo ignores

    Tus usuarios intentarán generar logos, contenido protegido o imágenes que no deberías producir.

    • Filtra y modera en el BFF antes de llamar al modelo.
    • Bloquea términos sensibles. Si hay duda, manda a revisión humana.
    • Log: guarda hashes de prompts, no texto completo si hay PII.

    Observability: métricas que realmente importan

    No solo logs. Métricas que salven tu día.

    • Latencia E2E por prompt.
    • Cost per generation (USD).
    • Cache hit ratio.
    • Rate of regeneration per user.
    • Incidencias de prompt-injection.

    Cache: ahorra dinero y tiempo

    Si dos usuarios piden “perro astronauta”, no generes dos imágenes nuevas.

    • Hash(prompt + constraints) → Redis.
    • TTL adaptativo: prompts comerciales frecuentes TTL largo; prompts únicos TTL corto.
    • Cache hit = ahorro directo.

    Testing y CI: no dejes que la IA improvise tu pipeline

    • Mockea LLM en tests unitarios.
    • Contract tests: respuesta del modelo debe cumplir schema JSON.
    • Canary releases para nuevos prompts: 1% tráfico, luego escalas.

    UX que no traicione la IA

    • Siempre: transparencia. Indica cuando la respuesta es generativa.
    • Si confidence < 0.6: pide confirmación humana antes de acciones sensibles.
    • Muestra el prompt o la interpretación antes de ejecutar (editable).

    Playbook anti-abuso (lo que debes tener listo)

    • Rate limits y quotas por usuario.
    • Circuit breaker y fallback a placeholder.
    • Kill switch global para detener generación masiva.
    • Alertas de gasto (thresholds diarios).

    Plantilla rápida: prompt “Plan First”

    Usa esta plantilla antes de generar código. Pégala como prompt inicial.

    System: “Eres un generador de código que sigue estrictamente el plan. Responde con: 1) Plan de archivos; 2) Librerías y versiones; 3) Tests a crear; 4) Código. El prompt del usuario es: {{user_prompt}}. Las reglas de la marca: {{brand_rules}}. Stack: React 18, Vite, Tailwind 3.2. Output: JSON con campos plan, files[], tests[].”

    Si la IA no responde en ese formato, rechaza y reprompt.

    Checklist mínimo antes de pulsar “deploy”

    • [ ] ERD definido y migrations escritas.
    • [ ] Prompt versionado y almacenado en repo seguro.
    • [ ] BFF implementado con secret manager y rate limiting.
    • [ ] Moderación automática y paths de escalado humano.
    • [ ] Tests con mocks LLM.
    • [ ] Canary rollout para new prompts.
    • [ ] Observability y alertas de coste.

    Errores que acaban con productos bonitos

    • Permitir que la IA toque el schema sin revisión.
    • Dejar keys en el bundle para facilitar “hackeo” por bots.
    • No versionar prompts: si algo falla, no puedes reproducir.
    • Depender de wrappers no oficiales (Midjourney via Discord): buen gusto para hobbies, mal gusto para negocios.

    Qué hacer ahora (acción inmediata)

    1. Si estás probando: agrega promptVersion y un traceId a cada petición.
    2. Si vas a producción: crea el BFF en la próxima semana. No hay atajos.
    3. Si tienes equipo: asigna ownership de prompts a un rol (AI Owner) con procesos de CI.

    Si quieres que te lo entregue listo

    Responde “QUIERO EL KIT” y te doy:

    • Esqueleto BFF Node/Nest con secret manager y rate limiting.
    • Plantilla de prompt versionado y CI para canary prompts.
    • Component React + Vite + Tailwind con patrón Plan First integrado.
    • Tests e2e que simulan LLM.

    Dominicode Labs

    Si quieres explorar workflows y agentes aplicados a producto, puedes ver recursos y experimentos relacionados en Dominicode Labs. Es un complemento lógico si trabajas con automatización y agentes en entornos de producción.

    FAQ

    ¿Qué es la ventana de contexto y por qué debería preocuparme?

    La ventana de contexto es la cantidad de texto que un modelo puede “recordar” en una sola petición. Debes preocuparte porque si le das demasiado contexto, el modelo puede omitir piezas críticas; si le das poco, carecerá de información esencial.

    ¿La IA puede diseñar mi BD por completo?

    No. La IA puede ayudar a generar esquemas iniciales, pero deberías diseñar el ERD, relaciones, índices y tipos primero y proporcionar ese contexto al modelo.

    ¿Cómo evito vendor lock‑in al usar Bolt.new o Lovable?

    Exige código estándar (por ejemplo React+Vite+Tailwind), controla versiones en Git y evita dependencias propietarias que solo funcionen dentro de la plataforma.

    ¿Dónde debo almacenar las API keys?

    En un Secret Manager (AWS Secrets Manager, Vault, etc.) y exponerlas vía un BFF. Nunca las incluyas en el cliente.

    ¿Qué es prompt versioning y cómo se aplica?

    Tratar los prompts como código: asignar promptId, version, author y changelog; guardar metadatos en cada request para trazabilidad y reproducibilidad.

    ¿Qué métricas debo monitorizar para generación IA?

    Latencia E2E por prompt, coste por generación, cache hit ratio, rate of regeneration per user e incidencias de prompt‑injection.

    ¿Cuándo debo usar un canary para nuevos prompts?

    Cuando lances cambios en prompts que afectan lógica crítica o costos. Empieza con ~1% del tráfico y escala según resultados y métricas.

  • Cómo implementar generación de imágenes en tiempo real para e-commerce

    Cómo implementar generación de imágenes en tiempo real para e-commerce

    ¿Quieres que tu e‑commerce deje de vender fotos y empiece a fabricar deseos en tiempo real?

    Tiempo estimado de lectura: 4 min

    Ideas clave

    • Generación de imágenes en tiempo real: es una palanca de conversión que exige arquitectura, cache, moderación y observabilidad.
    • BFF controlado: valida prompts, aplica reglas de marca y evita exponer la cuenta de la empresa al cliente.
    • Cache y coste: hash de prompt → Redis + TTL inteligente y políticas de rate limiting para evitar facturas inesperadas.
    • UX y mock‑ups: mostrar progreso, confirmar cuando la confianza es baja y combinar imágenes generadas con mock‑ups reales.
    • Moderación y legal: bloquear logos/trademarks y guardar metadata (promptId, traceId) para reproducibilidad y cumplimiento.

    Poca gente lo dice tan claro: la generación de imágenes al vuelo no es un capricho estético. Es una palanca de conversión. Si la ejecutas mal, quemas presupuesto y confianza. Si la ejecutas bien, vendes productos que no existían cinco minutos antes.

    Te voy a dar el patrón que usan los equipos que ya están experimentando con esto en producción. Sin rodeos. Con lo técnico que importa. Y con las trampas que nadie te advierte hasta que te llega la factura.

    Resumen rápido (lectores con prisa)

    Qué es: Generación de imágenes en tiempo real integrada en el flujo de e‑commerce para producir mock‑ups o productos personalizados al momento.

    Cuándo usarlo: Cuando el valor de conversión supera el coste por generación y puedes controlar cache, moderación y latencia.

    Por qué importa: Aumenta la conversión y reduce fricción para productos personalizados; mal implementado genera coste y pérdida de confianza.

    Cómo funciona (resumen): Cliente → BFF (validación, prompt‑engineering, moderación, cache) → Modelo generativo → Storage/CDN → cliente con URL y metadata (promptId, traceId).

    1) Arquitectura mínima que funciona (y no te deja expuesto)

    Cliente Angular

    • captura prompt, muestra estado, aplica mock‑up en Canvas/Three.js.

    BFF (Node/Nest)

    • valida prompt, aplica prompt‑engineering de marca, moderación, cache, llama a la API generativa.

    Storage CDN (S3 + Cloudfront)

    • guarda imagen final, sirve al cliente por URL.

    Redis

    • cache de hash(prompt) → URL.

    Observability

    • traces (OpenTelemetry), métricas de latencia y coste.

    Metáfora rápida: el BFF es el taller de estampación. El cliente es la tienda con el maniquí. No mandes clientes a la fábrica con la tarjeta de crédito de la empresa.

    2) ¿DALL‑E 3 o Midjourney? La decisión que define tu stack

    DALL‑E 3: integra, documentado, estable. Latencia predecible. Útil para flujos sin sorpresas.

    Midjourney: estética potente, pero sin API oficial. Inestabilidad + riesgo legal. Úsalo solo para pruebas internas o moodboards.

    Regla: si es negocio y producción, DALL‑E (o alternativa con SLA). Si es inspiración artística, Midjourney en sandbox.

    3) UX que no te mata la tasa de conversión

    • Primera regla: muestra progreso. El usuario debe saber que algo está sucediendo (ondas, barra y texto: “La IA está pintando tu idea”).
    • Segunda regla: siempre confirmación si confidence < 0.6. No ejecutes automáticamente acciones críticas.
    • Tercera: muestra la transcripción/prompt y permite editar antes de generar; reduce re‑generaciones y costes.

    4) Cómo combinar imagen generada con mock‑up realista

    • Si tu IA devuelve fondo blanco: usa mix-blend-mode: multiply para integrar color y sombras.
    • Para recortar a área imprimible: usa mask-image con PNG alfa que delimite el área.
    • Para objetos 3D (tazas, gorras): renderiza textura en Three.js y proyecta. La imagen 2D se vuelve material.

    5) Cache y coste: no es opcional

    • Hash(prompt + constraints) → si existe en Redis, devuelve URL.
    • TTL inteligente: alta prioridad evergreen (best sellers) tiene TTL largo; prompts únicos TTL corto.
    • Rate limiting en BFF y quotas por usuario. Un mal prompt viral = factura.

    6) Moderación y cumplimiento legal

    • Antes de llamar al modelo: pass prompt through a moderation endpoint.
    • Bloquea logos/trademark detectados y solicita versión con licencia o alternativa propuesta.
    • Guarda hashes de audio/texto, no PII completo, salvo consentimiento.

    7) Pipeline de prompts (versión como código)

    No mezcles estilos. Versiona prompts. Cada cambio debe pasar CI.

    Ejemplo de prompt system (simple y efectivo):

    "UserPrompt: {{user}}. BrandRules: fondo blanco, sin texto, colores primarios: #000,#fff,#ff0066, estilo: vector elegante, resolución: 2048x2048. Output: return image url or base64."

    Guarda promptId en la metadata de la imagen (para reproducibilidad).

    8) Snippet Angular (esqueleto, revisa nombres)

    • Usa Signals para estado: isLoading, imageUrl, error.
    • Llama a BFF con debounce en input.
    • Muestra preview inmediatamente si hay cache.

    9) Casos límite y cómo protegerte

    • Input malicioso: sanitize + moderate.
    • Trafico súbito: circuit breaker en BFF con fallback a placeholder.
    • Resultados pobres: ofrecer 3 variantes y un botón “regenerar” que cuente como 1 intento.

    10) Métricas que importan (no te fijes en impresiones)

    • Latencia end-to-end (ms).
    • Cost per generation.
    • Cache hit ratio.
    • Conversion lift por producto con imagen generativa.
    • Tasa de re‑generaciones por usuario.

    Checklist mínimo antes de lanzar

    • [ ] BFF con autenticación y rate limiting.
    • [ ] Cache (Redis) por prompt hash.
    • [ ] Moderación automática en BFF.
    • [ ] Mock‑up pipeline (mask + blend + optional 3D).
    • [ ] Observability y tracing (traceId en metadata).
    • [ ] Tests e2e con fixtures de imágenes.
    • [ ] Política de retención y GDPR (si almacenas diseños con PII).

    Si quieres algo listo para pegar en tu repo Dime exactamente qué prefieres y te lo doy:

    • QUIERO EL REPO”: repo con Angular UI + BFF Node + Redis cache + prompts versionados + tests e2e.
    • QUIERO EL BFF”: solo el BFF con endpoints, moderación, cache y llamadas DALL‑E.
    • QUIERO LA UI”: Angular component con Signals, Canvas mock‑up y Three.js demo.

    Esto no acaba aquí: si implementas mal, perderás dinero; si lo implementas bien, venderás productos que nadie espera. ¿Qué quieres construir primero — la fábrica (BFF) o la vitrina (UI)? Responde “BFF” o “UI” y te paso el plan con código listo para copiar y pegar.

    Si buscas una continuación práctica y orientada a equipos que implementan pipelines, revisión de prompts y workflows de producción, considera explorar Dominicode Labs como recurso complementario. Ofrece experimentos y plantillas que encajan con la arquitectura y las pruebas operativas descritas en este artículo.

    FAQ

    ¿Por qué necesito un BFF en este flujo?

    El BFF valida prompts, aplica reglas de marca, modera contenido, gestiona cache y llama al modelo generativo. Evita exponer credenciales y controla quota y costes.

    ¿Qué modelo debo usar en producción?

    Usa un modelo con SLA y API documentada (por ejemplo, DALL‑E 3 o alternativa con soporte). Midjourney es válido para pruebas internas o moodboards, no para producción.

    ¿Cómo reduzco costes por generación?

    Implementa cache por hash de prompt, TTL por prioridad, limita re‑generaciones y muestra/edita prompts antes de generar.

    ¿Qué hago si aparece un logo o trademark?

    Bloquea la generación, solicita una versión con licencia o propone una alternativa sin marca. Registra acciones en metadata para auditoría.

    ¿Cómo debe integrarse la cache?

    Hash(prompt + constraints) → Redis → devuelve URL si existe. TTL inteligente según prioridad del prompt y políticas por usuario.

    ¿Qué métricas debo vigilar al lanzar?

    Latencia E2E, coste por generación, cache hit ratio, conversion lift por producto y tasa de re‑generaciones.

    ¿Cuándo ofrecer regeneraciones y cómo limitar abusos?

    Ofrece 3 variantes por intento y cuenta cada regeneración. Aplica rate limiting y quotas por usuario para evitar picos de coste.