DEV Community

Cover image for 🚀 Cómo Usé IA, FRDs, Claude Sonnet, Windsurf y Antigravity para Orquestar un Backend Completo Sin Caos
Jorge Gomez
Jorge Gomez

Posted on

🚀 Cómo Usé IA, FRDs, Claude Sonnet, Windsurf y Antigravity para Orquestar un Backend Completo Sin Caos

Una metodología reproducible para generar software real, limpio y escalable usando agentes LLM orquestados por documentos FRD formales.

`

Introducción

En estas últimas semanas he estado aplicando un enfoque de desarrollo basado en FRDs (Functional Requirements Documents) orquestados con apoyo de Inteligencia Artificial para construir backends modernos, limpios y escalables. Este método me permitió crear un backend completo —con CRUD, base de datos, autenticación JWT, migraciones y pruebas unitarias— sin caos, sin improvisación y con código limpio desde el primer commit.

Aunque los FRDs son un estándar tradicional ampliamente usado en ingeniería de software, lo verdaderamente interesante aquí no es el concepto del FRD en sí, sino cómo se combinan con agentes LLM para crear un proceso determinístico de construcción.

Este enfoque se alinea con técnicas modernas de LLM Orchestration, Task Graphs y Agentic Pipelines, que están siendo adoptadas en herramientas como Windsurf, Cursor, Claude Sonnet y VSCode Agents.

Algo que noté durante este proceso es que comencé usando un FRD gigante, un documento único donde describía todas las fases (boilerplate, base de datos, autenticación, pruebas, etc.). Aunque el documento era muy detallado, pronto aparecieron dos problemas reales:

  1. Los modelos de IA tenían que analizar demasiada información en una sola ventana de contexto, lo cual aumentaba la carga de razonamiento y hacía que el agente se desviara, olvidara pasos o repitiera preguntas innecesarias.
  2. El proceso se volvía lento porque la IA entraba en ciclos de “confirmación”, dudas, ambigüedades y revalidaciones constantes.

Esto me llevó a investigar un enfoque más escalable: separar el proyecto en múltiples FRDs pequeños, cada uno responsable de una fase específica, y crear un FRD-00 Maestro que los orquestara en el orden correcto.

Con esa estructura:

  • La IA ya no necesita analizar un documento gigantesco.
  • Cada fase tiene un FRD corto y preciso.
  • El FRD Maestro controla el flujo completo como un pipeline.
  • El agente deja de preguntar “qué sigue” y simplemente ejecuta.
  • Agregar nuevas features en el futuro es más sencillo y seguro, porque cada una vive en su propio FRD sin interferir con las demás.

¿Qué es la Orquestación por FRDs?

Los FRDs definen:

  • Qué debe hacerse
  • En qué orden
  • Qué criterios deben cumplirse
  • Qué pasos son obligatorios
  • Qué comportamientos debe validar la IA
  • Qué condiciones de aceptación debe pasar cada fase

La clave está en que no solo describes la funcionalidad, sino que defines el proceso de construcción, asegurando precisión, repetibilidad y cero improvisación.


📘 Relación con prácticas existentes

La orquestación por FRDs no pretende reinventar metodologías: más bien integra prácticas formales ya conocidas con la nueva ola de desarrollo asistido por IA.

Este método toma elementos de:

  • LLM-driven Development Workflows
  • Prompt Chaining
  • Task Graph Execution
  • Reproducible Pipelines
  • Specification-Driven Engineering

La contribución aquí es cómo se estructura el proceso, no el concepto del FRD en sí.


FRD-00: El "Controlador de Orquestación"

Este documento maestro dicta:

  • Fases obligatorias
  • Dependencias claras
  • Comportamiento del agente
  • Validaciones en cada etapa
  • Reglas estrictas para avanzar o detenerse
  • Criterios de éxito por fase

Es el pipeline lógico que permite que el proyecto sea ejecutado por IA sin desviaciones.

🔗 Ruta


🚀 ¿Cómo inicia realmente la orquestación?

Antes de empezar las fases, ejecuto esta instrucción inicial para que la IA cargue todos los FRDs y comprenda el orden de ejecución:

`

@FRD-00-master-orchestration.md
@FRD-01-boilerplate-core-products.md
@FRD-02-products-database.md
@FRD-03-auth-security.md
@FRD-04-unit-testing.md

nombre de carpeta: api-products

FRD-00-master-orchestration.md
FRD-01-boilerplate-core-products.md
FRD-02-products-persistence-typeorm.md
FRD-03-unit-testing.md

Inicia la orquestación.

Enter fullscreen mode Exit fullscreen mode


`

¿Por qué esto es crítico?

  • Garantiza que el agente siga el orden correcto
  • Asegura que el FRD-00 actúe como director maestro
  • Reduce carga de contexto
  • Evita loops o preguntas innecesarias
  • Permite reproducibilidad en cualquier editor IA: Windsurf, Antigravity, Cursor, Sonnet, VSCode Agents, etc.

Arquitectura General del Proyecto

El resultado final fue un backend NestJS con:

🧩 Módulos incluidos

  • Auth (JWT + bcrypt + Passport)
  • Users (registro, login, hashing)
  • Products (CRUD con validación)
  • Config centralizado
  • SQLite + TypeORM + migraciones
  • Pruebas unitarias (33 tests)

📁 Estructura final

`

api-products/
├── src/
│   ├── auth/
│   ├── products/
│   ├── users/
│   ├── config/
│   └── main.ts
├── migrations/
├── README.md
└── package.json
Enter fullscreen mode Exit fullscreen mode


`


🔥 Fase 1 — Boilerplate + CRUD en memoria

  • Proyecto creado con nest new
  • Swagger activado
  • Validaciones globales
  • CRUD in-memory
  • DTOs con class-validator
  • JSDoc obligatorio

`

export class CreateProductDto {
  @IsString()
  name: string;

  @IsBoolean()
  isPremium: boolean;

  @IsNumber()
  price: number;
}
Enter fullscreen mode Exit fullscreen mode


`
🔗 Ruta


🗄️ Fase 2 — Base de Datos + TypeORM

  • Integración TypeORM
  • Migraciones
  • ProductRepository
  • Persistencia real con SQLite

`

@Entity()
export class Product {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column()
  isPremium: boolean;

  @Column('float')
  price: number;
}
Enter fullscreen mode Exit fullscreen mode


`
🔗 Ruta


🔐 Fase 3 — Autenticación JWT

  • UsersService + repositorio
  • Hashing con bcrypt
  • LocalStrategy + JwtStrategy
  • JwtAuthGuard
  • Swagger BearerAuth

`

  async login(loginDto: LoginDto): Promise<{ accessToken: string }> {
    const user = await this.usersService.validateCredentials(loginDto.email, loginDto.password);

    if (!user) {
      throw new UnauthorizedException('Invalid credentials');
    }

    const payload = { email: user.email, sub: user.id };
    const accessToken = this.jwtService.sign(payload);

    return { accessToken };
  }
Enter fullscreen mode Exit fullscreen mode

🔗 Ruta


🧪 Fase 4 — Pruebas Unitarias

  • 6 test suites
  • 33 pruebas
  • Mocks limpios
  • Sin BD real
  describe('login', () => {
    it('should login successfully and return access token', async () => {
      const loginDto: LoginDto = {
        email: 'test@example.com',
        password: 'password123',
      };
      const accessToken = 'jwt-token';
      mockUsersService.validateCredentials.mockResolvedValue(mockUser);
      mockJwtService.sign.mockReturnValue(accessToken);

      const result = await service.login(loginDto);

      expect(result).toEqual({ accessToken });
      expect(usersService.validateCredentials).toHaveBeenCalledWith(loginDto.email, loginDto.password);
      expect(jwtService.sign).toHaveBeenCalledWith({ email: mockUser.email, sub: mockUser.id });
    });

    it('should throw UnauthorizedException for invalid credentials', async () => {
      const loginDto: LoginDto = {
        email: 'test@example.com',
        password: 'wrongpassword',
      };
      mockUsersService.validateCredentials.mockResolvedValue(null);

      await expect(service.login(loginDto)).rejects.toThrow(UnauthorizedException);
      expect(usersService.validateCredentials).toHaveBeenCalledWith(loginDto.email, loginDto.password);
    });
  });

Enter fullscreen mode Exit fullscreen mode

🔗 Ruta


📊 Resultados Finales

  • 33 pruebas exitosas
  • Migraciones correctas
  • JWT funcionando
  • CRUD operativo
  • Arquitectura consistente

🖼️ Visual Evidence

(Gallery with screenshots from Windsurf, Antigravity, and Claude Sonnet)


🧠 Importancia en la era de la IA

  1. La IA necesita estructura
  2. Permite la ejecución de proyectos de extremo a extremo
  3. Refuerza buenas prácticas en flujos asistidos por modelos LLM
  4. Es reproducible, escalable y modular

🧭 Conclusión

La Orquestación por FRDs no es simplemente una técnica operativa: es una forma de estructurar la colaboración entre humanos y modelos de IA para producir software reproducible, estable y escalable.

Este método potencia —no reemplaza— al desarrollador.

📂 Repositorio oficial con FRDs + Backend completo


`

Top comments (0)