ATLAS + GOTCHA -- Parte 7

Patrones Avanzados y los 10 Anti-Gotchas Más Comunes

#ai #atlas #gotcha #patterns #prompts #architecture

El Problema

Llevas unas semanas usando ATLAS (el checklist de arquitectura en 5 fases) y GOTCHA (el formato de prompt con 6 capas para IA). El flujo de trabajo es más rápido. El output de la IA es mejor. Pasas menos tiempo arreglando código generado y más tiempo revisándolo.

Pero a medida que los proyectos crecen y los equipos se amplían, aparecen nuevos problemas. Problemas que estos frameworks pueden prevenir — si sabes dónde se esconden.

Los llamo anti-gotchas. No son bugs en tu código. No son features que faltan. Son errores en cómo usas el enfoque estructurado. Patrones que parecen bien en proyectos pequeños pero se rompen a escala. Formas de escribir prompts que parecen completos pero dejan huecos que la IA rellena con suposiciones.

A lo largo de seis artículos, has visto los frameworks aplicados a una sola API y un solo pipeline. Los proyectos reales no son servicios únicos. Son plataformas SaaS multi-tenant. Son operadores de K8s que gestionan estado complejo. Son funciones serverless reemplazando monolitos legacy. Los frameworks escalan — pero solo si evitas las trampas.

La Solución

Diez anti-gotchas. Después tres patrones avanzados con prompts. Y finalmente una librería de 20 prompts listos para usar que puedes adaptar a tu propio trabajo.

Los 10 Anti-Gotchas Más Comunes

1. Saltarse la Fase Architect Porque “Es Obvio”

El error más común. Sabes lo que vas a construir, así que te saltas ATLAS Architect y pasas directo a Trace. Dos días después descubres que el sistema necesita manejar dos casos de uso que no definiste, el alcance se ha duplicado, y tu código generado por IA está estructurado para el caso A, no para el B.

La solución: escribe siempre “fuera de alcance” de forma explícita. La IA construirá lo que describas. Si no dices lo que NO estás construyendo, adivina — y normalmente adivina de más.

2. Goals Que Describen Implementación, No Resultados

# Bad: this is implementation, not a goal
GOALS: Use the repository pattern with async/await,
       return DTOs from controllers, validate with FluentValidation.

# Good: this is a goal
GOALS: Build a REST API that registers users, authenticates with JWT,
       and returns RFC 7807 error responses. Handles 500 concurrent requests.

Los Goals responden “¿cómo se ve terminado?” El repository pattern es una heurística. El tiempo de expiración del JWT es un arg. Mantén los Goals limpios.

3. Context Sin Tus Restricciones Reales

Los desarrolladores escriben Context que suena detallado pero no contiene restricciones reales:

# Vague context (useless)
CONTEXT: This is a microservices architecture deployed to the cloud.
         We follow standard patterns and best practices.

# Real context (useful)
CONTEXT: 10 services, all on AKS West Europe. Database per service.
         Service Bus for async. Managed identities — no connection strings.
         All logs to Azure Monitor via Serilog. EU data residency required.

“Standard patterns and best practices” no significa nada para la IA. “EU data residency required” significa que ningún dato sale de la región West Europe — y la IA respetará eso en cada decisión de almacenamiento e integración.

4. Heuristics Demasiado Vagas para Verificar

# Vague (the AI can't verify this)
DON'T: Write bad code.

# Specific (the AI can check each one)
DON'T:
- No synchronous calls to external services (no .Result or .Wait())
- No secrets in code — all from environment variables
- No catching Exception base class — catch specific exceptions only

Cada heurística debería ser una comprobación de sí/no: “¿Hice esto?” Si no puedes verificarlo, reescríbelo.

5. Args Que Faltan para Todo lo Que Tiene un Número

Si hay un número en tu sistema — un timeout, un número de reintentos, un número de réplicas, un tamaño máximo de request, una expiración de token — va en Args. Si no lo pones ahí, la IA inventa un valor. A veces inventa uno razonable. A veces inventa 2 reintentos cuando necesitas 5, o 30 minutos cuando el JWT debería expirar en 1 hora.

Repasa tus escenarios de Stress-test. Cada número en esos escenarios es un Arg.

6. Un Solo Prompt para Todo el Sistema

GOTCHA funciona mejor a nivel de servicio, no a nivel de sistema. Un prompt para toda una plataforma de e-commerce producirá algo genérico. Un prompt por servicio — Order Service, Notification Service, Users API — produce algo específico.

Usa ATLAS para diseñar todo el sistema. Después escribe un prompt GOTCHA por componente. Cada prompt es enfocado, completo y con alcance definido.

7. No Actualizar GOTCHA Cuando Cambian los Requisitos

Escribes un prompt GOTCHA. La IA genera código. Tres semanas después los requisitos cambian — añades refresh tokens, cambias de PostgreSQL a Cosmos DB, añades un nuevo tipo de evento. Actualizas el código directamente y te olvidas de actualizar el prompt GOTCHA.

La siguiente vez que le pides a la IA que extienda el sistema, trabaja desde el prompt antiguo. Reintroduce los patrones antiguos. Usa la base de datos antigua.

Guarda tus prompts GOTCHA en el repositorio. Trátalos como documentación — porque eso es lo que son.

8. Ignorar el Paso “Lo Que Ajustamos”

En los Artículos 5 y 6, mostré tres cosas que la IA hizo mal en cada proyecto. Esa sección no es opcional. Después de cada output generado por IA, dedica 10 minutos a revisar contra cada capa de GOTCHA:

  • ¿El código cumple los Goals?
  • ¿El orden de construcción en el código es consistente con Orchestration?
  • ¿Están todos los Tools presentes y con las versiones correctas?
  • ¿El código refleja el Context (convenciones, managed identities, etc.)?
  • ¿El código sigue todas las Heuristics?
  • ¿Se usan todos los Args correctamente?

La mayoría de los errores de la IA son pequeños y se arreglan en minutos. Pero solo los pillas si los buscas.

9. Usar GOTCHA Como Atajo, No Como Framework

“Solo voy a escribir un prompt largo y llamarlo GOTCHA.” Esto no tiene sentido. El valor de GOTCHA es la separación de responsabilidades entre capas. Goals separados de Heuristics. Tools separados de Context. Cuando los mezclas, la IA también los mezcla — y obtienes código que intenta ser un goal, una restricción y una herramienta al mismo tiempo.

Si no puedes asignar fácilmente una frase a exactamente una capa de GOTCHA, reescríbela.

10. Saltarse ATLAS para Tareas “Pequeñas”

“Esto es solo una feature pequeña — no necesito ATLAS.” Las features pequeñas en sistemas grandes no son pequeñas. Añadir un nuevo campo a un esquema de base de datos puede requerir una migración, un cambio en la API, una actualización de contrato, una actualización del frontend y un re-deploy de tres servicios. Eso son cinco fases de ATLAS de pensamiento.

No necesitas un documento ATLAS completo para cada tarea. Pero deberías hacerte las cinco preguntas, aunque sea de forma informal: ¿Cuáles son los límites? ¿Cuál es el flujo? ¿Qué se conecta con qué? ¿Cuál es el orden de construcción? ¿Cómo lo valido?

Dos minutos pensando. Horas de debugging ahorradas.

Patrones Avanzados

Patrón 1: SaaS Multi-Tenant

Multi-tenancy es donde la mayoría del código generado por IA falla. La IA genera código single-tenant por defecto. Tienes que ser explícito.

Adiciones clave a tu prompt GOTCHA:

=== CONTEXT ===
Multi-tenant SaaS. TenantId on every database entity.
All queries must include WHERE tenant_id = @tenantId.
TenantId extracted from JWT claim 'tid' in middleware.
Never return data from one tenant to another — this is a security boundary.
EF Core global query filter: .HasQueryFilter(e => e.TenantId == _tenantContext.TenantId)

=== HEURISTICS ===
DO:
- Inject ITenantContext into every repository
- Set TenantId from ITenantContext in every entity before saving
- Test cross-tenant data isolation explicitly (Scenario: TenantA token accessing TenantB data → 404)

DON'T:
- Don't accept TenantId from the request body — always from JWT
- Don't write any query without the tenant filter

El global query filter de EF Core es la pieza más importante. Sin él, dependes de que cada desarrollador recuerde añadir el filtro de tenant a cada query. Con él, es automático e imposible de olvidar.

Patrón 2: Kubernetes Operators

Los Kubernetes operators son complejos — gestionan custom resources y reconcilian estado de forma continua. ATLAS + GOTCHA es especialmente útil aquí porque el alcance es difícil de definir sin ellos.

Adiciones clave a ATLAS:

[T] TRACE (reconciliation loop)
  1. Controller watches MyResource CRD for create/update/delete events
  2. On event: fetch current state from cluster
  3. Compare with desired state (spec)
  4. If drift: apply corrective actions (create/update/delete child resources)
  5. Update status subresource with current phase + conditions
  6. Requeue after N minutes for periodic drift check

[A] ASSEMBLE
  Phase 1: CRD definition (schema + validation)
  Phase 2: Reconciler skeleton (kubebuilder scaffolding)
  Phase 3: Reconcile logic (desired vs actual state comparison)
  Phase 4: Status conditions (ready, degraded, progressing)
  Phase 5: Error handling (permanent vs transient errors, max retries)

La Heuristic clave para operators:

=== HEURISTICS ===
DO:
- Make reconcile idempotent (running it twice must produce the same result)
- Use status conditions to communicate state to users (not just logs)
- Distinguish permanent errors (don't retry) from transient errors (requeue with backoff)
- Always update status before returning an error from Reconcile

La idempotencia es lo más importante. Un operator que no es idempotente creará recursos duplicados, se romperá al reintentar y será imposible de debuggear.

Patrón 3: Migración a Serverless

Migrar un monolito a serverless (Azure Functions, por ejemplo) es un proyecto común donde ATLAS Trace es esencial y muchas veces se salta.

El monolito tiene dependencias implícitas — un método que llama a otro método que escribe en una base de datos que lee de una caché. Cuando los separas en funciones independientes, cada dependencia implícita se convierte en una integración explícita. Si te saltas una, tienes un bug silencioso de consistencia de datos.

Adiciones clave a ATLAS para migración serverless:

[A] ARCHITECT
  Out of scope: Don't migrate everything at once. This iteration:
  only the order processing path. Leave payments and notifications in the monolith.

[T] TRACE
  For each function to migrate, trace:
    - What triggers it? (HTTP, queue message, timer, event)
    - What data does it read? Where from?
    - What does it write? Where?
    - What does it call? (other functions, external APIs, databases)
    - What happens on failure?

[L] LINK
  (Map each implicit monolith call to an explicit Azure service)
  | Was implicit call | Becomes |
  | Direct DB call    | Durable Function with retry |
  | In-process event  | Service Bus message |
  | Shared cache      | Azure Cache for Redis (shared) |

La Librería de 20 Prompts

Aquí tienes 20 prompts GOTCHA listos para usar en tareas comunes. Cada uno es una plantilla — rellena las secciones [YOUR VALUES].

1. CRUD REST API (.NET)

GOALS: Build a .NET 10 REST API for [ENTITY] management. CRUD + JWT auth. RFC 7807 errors.
ORCHESTRATION: Entity → Repository → Service → Controller → Validators → Middleware
TOOLS: .NET 10, EF Core 10, Npgsql, BCrypt.Net-Next, FluentValidation, Serilog
CONTEXT: Part of [SYSTEM]. Deploys to AKS. Managed identities. Soft delete via DeletedAt.
HEURISTICS: Repository pattern. Return DTOs not entities. Async everywhere. No logic in controllers.
ARGS: DB_CONNECTION env var. JWT_SECRET env var. Port 8080. K8s replicas: [N].

2. Event-Driven Worker (.NET + Service Bus)

GOALS: .NET 10 worker service. Consumes [EVENT] from Service Bus. Processes and writes to [DESTINATION].
ORCHESTRATION: Consumer → Deserialize → Validate → Process → Persist → Acknowledge
TOOLS: .NET 10, Azure.Messaging.ServiceBus, EF Core, Serilog, Polly
CONTEXT: [SYSTEM]. Messages are idempotent — deduplicate by [FIELD]. At-least-once delivery.
HEURISTICS: Acknowledge only after successful processing. Retry transient errors with backoff. Log correlation ID.
ARGS: SERVICEBUS_CONNECTION env var. Topic: [TOPIC]. Subscription: [SUB]. Max concurrent: [N].

3. Azure DevOps CI/CD Pipeline

GOALS: Azure DevOps pipeline for [SERVICE]. Build → test → scan → push to ACR → deploy to AKS.
ORCHESTRATION: 5 stages: build, scan (Trivy HIGH/CRITICAL), image push, deploy, smoketest.
TOOLS: Azure DevOps YAML, dotnet 10 SDK, Docker, Trivy, kubectl, kubelogin.
CONTEXT: ACR: [NAME]. AKS: [CLUSTER], namespace [NS]. Secrets from variable group.
HEURISTICS: Deploy only on main. Use dependsOn. Never use latest tag. rollout status before smoketest.
ARGS: Pool: ubuntu-latest. Image tag: BuildId+gitsha. Trivy: HIGH,CRITICAL. Rollout timeout: 5m.

4. PostgreSQL Schema Migration

GOALS: EF Core migration to add [FEATURE] to [TABLE]. Zero downtime. Backward compatible.
ORCHESTRATION: New nullable column → deploy new code → backfill data → add NOT NULL constraint.
TOOLS: EF Core 10, Npgsql, dotnet ef migrations.
CONTEXT: [SERVICE]. Production table has [N] million rows. Migration runs during rolling deploy.
HEURISTICS: Never drop columns in this migration. New columns nullable until backfill. Index on [FIELD].
ARGS: Migration name: Add[Feature]To[Table]. Backfill batch size: 1000. DB_CONNECTION env var.

5. JWT Authentication Middleware

GOALS: ASP.NET Core JWT middleware. Validate HS256 tokens. Extract sub, email, [CLAIMS] as user context.
ORCHESTRATION: Register → configure validation → inject ICurrentUser into DI.
TOOLS: .NET 10, System.IdentityModel.Tokens.Jwt, Microsoft.AspNetCore.Authentication.JwtBearer.
CONTEXT: Tokens issued by [SERVICE]. Must validate issuer, audience, expiry, and signature.
HEURISTICS: Never trust claims without signature validation. Return 401 (not 403) on invalid token.
ARGS: JWT_SECRET env var. Issuer: [ISSUER]. Audience: [AUDIENCE]. Clock skew: 30s.

6. React Form with Validation

GOALS: React form for [ACTION]. Client-side validation + server error display. Accessible.
ORCHESTRATION: Form state → validate on submit → POST to [ENDPOINT] → handle success/error.
TOOLS: React 19, React Hook Form, Zod, fetch API, Tailwind CSS.
CONTEXT: Part of [APP]. API returns RFC 7807 errors. Auth via Bearer token in localStorage.
HEURISTICS: Field-level errors from server mapped to form fields. No double submit. ARIA labels.
ARGS: API endpoint: [URL]. Token: localStorage.getItem('token'). Redirect on success: [PATH].

7. Kubernetes Deployment Manifest

GOALS: K8s manifests for [SERVICE]. Deployment + Service + Ingress. Production-ready.
ORCHESTRATION: Namespace → Secret → ConfigMap → Deployment → Service → Ingress.
TOOLS: Kubernetes 1.29+, NGINX Ingress Controller, cert-manager (TLS).
CONTEXT: AKS West Europe. Image in ACR. Secrets from K8s Secret. Azure managed identity via workload identity.
HEURISTICS: runAsNonRoot. allowPrivilegeEscalation: false. Liveness + readiness probes. Resource limits.
ARGS: Image: [ACR]/[SERVICE]:[TAG]. Namespace: [NS]. Replicas: [N]. CPU: [REQ]/[LIM]. Memory: [REQ]/[LIM].

8. Azure Function HTTP Trigger

GOALS: Azure Function v4 (Node/TypeScript or .NET) for [PURPOSE]. HTTP trigger. Returns [RESPONSE].
ORCHESTRATION: Validate input → [BUSINESS LOGIC] → return result.
TOOLS: Azure Functions v4, [SDK FOR DEPENDENCIES], Application Insights.
CONTEXT: Part of [SYSTEM]. Consumes [INPUT]. Connects to [SERVICES].
HEURISTICS: Anonymous auth level. CORS from [ALLOWED_ORIGIN]. Structured logging. No secrets in code.
ARGS: PORT: 7071 local. Env vars: [LIST]. CORS: [ORIGIN].

9. Integration Test Suite

GOALS: Integration test suite for [SERVICE] using Testcontainers. Real PostgreSQL, no mocks for DB.
ORCHESTRATION: Spin up PostgreSQL → run migrations → seed data → execute tests → teardown.
TOOLS: xUnit, Testcontainers.PostgreSql, Microsoft.AspNetCore.Mvc.Testing, Bogus (fake data).
CONTEXT: Tests run in CI (Azure DevOps, Ubuntu agent). Must complete in under 2 minutes.
HEURISTICS: One container per test collection (not per test). Reset DB between test classes. Test happy + sad paths.
ARGS: PostgreSQL image: postgres:16. Test DB name: [SERVICE]_test. Parallel: false.

10. OpenAPI Specification

GOALS: OpenAPI 3.0 spec for [SERVICE]. All endpoints, request/response schemas, auth, error responses.
ORCHESTRATION: Info → servers → security schemes → paths → components.
TOOLS: OpenAPI 3.0 YAML. Validated against [openapi-generator or similar].
CONTEXT: [SERVICE] endpoints: [LIST]. JWT Bearer auth on all except [PUBLIC ENDPOINTS].
HEURISTICS: All 4xx/5xx responses include RFC 7807 schema. Response schemas never include passwords or secrets.
ARGS: API version: [VERSION]. Server: [URL]. Security scheme: Bearer JWT.

11-20 (Referencia Rápida)

11. Dockerfile (multi-stage, .NET): FROM sdk → restore → build → FROM runtime → copy → runAsUser 1000
12. Helm Chart (K8s): deployment + service + ingress + values.yaml — parameterized for dev/prod
13. Terraform module (Azure Storage + Function): idempotent, parameterized, managed identity via azurerm provider
14. GitHub Actions workflow: same structure as Azure DevOps article — adapt trigger syntax
15. Rate limiting middleware (.NET): per-IP + per-user limits, return 429 with Retry-After header
16. Distributed cache (Redis): cache-aside pattern, TTL per entity type, invalidation on update
17. Audit log table: append-only, records who changed what when, EF Core interceptor
18. Health check endpoint: DB ping + downstream services + disk space — detailed for /health, simple for /healthz
19. Multi-tenant EF Core: global query filter + TenantId on all entities + ITenantContext
20. CORS policy (.NET): allow specific origins from config, handle OPTIONS preflight, credentials support

Para los prompts 11-20, el patrón es el mismo: Goals (qué + resultado medible), Orchestration (orden), Tools (específicos), Context (tu entorno), Heuristics (lo que sí/lo que no), Args (valores concretos). Las plantillas de arriba te dan la estructura — rellena con tus datos específicos.

Plantilla

La meta-plantilla: cómo escribir cualquier nuevo prompt GOTCHA desde cero.

Before writing the prompt, answer these five questions:

1. What does "done" look like? (→ Goals)
2. What gets built first, second, third? (→ Orchestration)
3. What technologies are we using? (→ Tools)
4. What does the AI need to know about our environment? (→ Context)
5. What rules must the AI follow? What must it never do? (→ Heuristics)
6. What are the concrete values — numbers, names, connection strings? (→ Args)

If you can't answer all six, you're not ready to prompt yet. Go back to ATLAS.

Reto

Antes del Artículo 8, haz una auditoría rápida de la última tarea que completaste con IA. Repasa los diez anti-gotchas. ¿Cuántos aplicaban? ¿Cuáles te costaron tiempo?

En el Artículo 8, cerraremos la serie con una autoevaluación, un roadmap de 90 días para convertir esto en un hábito, y un vistazo a dónde pueden llevarte ATLAS + GOTCHA.

Si esta serie te ayuda, considera invitarme a un café.

Comments

Loading comments...