


Cambia un servicio de autorización basado en grafos escribiendo primero las pruebas
Úsalo al cambiar un servicio de autorización basado en grafos. Sigue la ruta de cada solicitud, usa los objetivos de build y las reglas de lint del repositorio, escribe primero una prueba que falle y no toca a mano los archivos generados.
Para usar estas reglas de IA
## Pon la corrección primero y usa los objetivos de build del repositorio
Aplica las prioridades del proyecto en este orden:
1. Corrección: cada decisión de autorización debe ser exacta.
2. Fiabilidad: el servicio debe permanecer disponible y recuperarse de forma predecible.
3. Rendimiento: minimiza la latencia y las asignaciones de memoria solo después de proteger la corrección y la fiabilidad.
Trata los objetivos de compilación administrados por el repositorio como la fuente de verdad. Prefiérelos a los comandos improvisados porque incorporan la generación, los indicadores, la detección de condiciones de carrera, la cobertura, el linting y la configuración del entorno necesarios.
Los grupos habituales de objetivos deben incluir:
- compilaciones de producción;
- el conjunto completo de pruebas;
- pruebas filtradas para un caso específico;
- pruebas de rendimiento con métricas de memoria;
- pruebas de integración que necesitan contenedores;
- linting con la versión de herramienta configurada por el repositorio;
- dobles de prueba generados;
- desarrollo local con un almacén de datos en memoria o basado en contenedores.
Antes de ejecutar un objetivo, lee su definición y las variables de entorno obligatorias. Si el objetivo canónico no está disponible o no está claro, resuelve esa carencia en lugar de sustituirlo silenciosamente por un comando más débil.
## Sigue el recorrido de una solicitud por la cadena de resolutores antes de cambiarla
Traza la solicitud por toda la ruta de ejecución antes de cambiar el comportamiento. Sigue esta secuencia:
1. recibir la solicitud HTTP o RPC;
2. aplicar el middleware;
3. entrar en el manejador de transporte;
4. invocar el comando o servicio de aplicación;
5. resolver el grafo de autorización;
6. acceder al almacenamiento;
7. devolver la respuesta.
Localiza los módulos responsables del inicio y cierre, los manejadores, los comandos de negocio, la evaluación del grafo, la planificación, las interfaces e implementaciones de almacenamiento, el análisis de modelos, la validación de tuplas, la autenticación y la autorización de la API.
Para las comprobaciones basadas en grafos, inspecciona juntos el constructor y la interfaz del resolutor. Una canalización de resolutores puede añadir caché, limitación de la distribución o comparación en sombra solo cuando la configuración lo habilita.
No supongas que la cadena es lineal. Algunos sistemas de resolución forman una cadena de delegación circular en la que el último resolutor vuelve al primero. Verifica el orden de construcción, las condiciones de terminación y la diferencia entre los envoltorios opcionales y el comprobador local central antes de cambiar el comportamiento de distribución.
Considera el cableado en tiempo de ejecución una evidencia más sólida que los nombres de directorios o las suposiciones de diseño.
## Respeta los nombres que exige lint y mantén identificables los errores envueltos
Lee la configuración activa de lint antes de editar imports o nombres. Conserva:
- los alias obligatorios para API generadas y analizadores;
- los grupos y el orden de imports configurados;
- los nombres de interfaces sin prefixes redundantes;
- los constructores nombrados según el patrón `NewTypeName`;
- las options funcionales nombradas según el patrón `WithPropertyName`;
- los tipos option con la forma `TypeNameOption func(*TypeName)`;
- las constantes exportadas con el estilo de nombres exportados del proyecto;
- las constantes no exportadas y las context keys con el estilo de nombres locales del proyecto.
Define los errores de dominio estables como valores centinela. Añade contexto sin destruir la identidad del error:
- declara un centinela como `var ErrNotFound = errors.New("not found")`;
- envuélvelo con contexto como `fmt.Errorf("load relationship: %w", ErrNotFound)`.
Usa `errors.Is` o `errors.As` para las comprobaciones. No compares directamente errores envueltos ni formatees un error envuelto con un verbo que pierda la cadena.
Mantén la conversión del dominio al transporte en un límite explícito. La lógica del comando debe devolver errores de dominio; un conversor específico debe asignarlos a respuestas HTTP o RPC.
## Escribe primero una prueba que falle y mantén las pruebas de matriz de autorización
Usa desarrollo guiado por pruebas para los cambios de comportamiento:
1. Añade una prueba enfocada que exprese el comportamiento ausente o incorrecto.
2. Ejecútala y confirma que falla por el motivo previsto.
3. Implementa el cambio mínimo que pueda hacerla pasar.
4. Ejecuta la prueba enfocada y después el conjunto directamente afectado.
5. Refactoriza solo cuando las pruebas hayan pasado.
Para los algoritmos de autorización, mantén pruebas matriciales que definan modelos, tuplas de relaciones y resultados esperados para las API de comprobación, listado de objetos y listado de usuarios. Cada etapa de la matriz debe permitir leer juntos el modelo y las aserciones.
Un caso matricial mínimo debe conservar este orden y significado:
1. asignar un nombre a la prueba, por ejemplo `viewer_can_read_document`;
2. definir los tipos `user` y `document` en el modelo de la etapa;
3. definir una relación `viewer` que acepte un usuario;
4. añadir la tupla `document:1`, `viewer`, `user:alice`;
5. afirmar que comprobar el mismo objeto, relación y usuario devuelve `true`.
Mantén los recursos de prueba incrustados registrados con sus ejecutores. Cuando una API tenga varias superficies de listado o comprobación, verifica cada ejecutor pertinente en lugar de suponer que una superficie cubre las demás.
Usa pruebas de rendimiento al cambiar rutas críticas del grafo, la selección de resolutores, el acceso al almacenamiento o código sensible a las asignaciones. Usa pruebas basadas en contenedores para el comportamiento específico de un almacén de datos.
## No edites a mano archivos generados ni esquemas de otro repositorio
No edites directamente mocks generados, bindings de protocolo generados ni otros artefactos generados. Cambia la fuente o el generador y vuelve a generar mediante el objetivo canónico.
No modifiques definiciones de schema administradas externamente en el repositorio de un servicio descendente. Realiza y revisa el cambio de schema en el repositorio propietario y después actualiza la dependencia descendente.
Ten en cuenta estas trampas operativas:
- un objetivo de prueba completo puede regenerar mocks automáticamente, mientras que un comando directo de prueba del lenguaje puede no hacerlo;
- las pruebas de integración para almacenes SQL pueden necesitar un entorno de ejecución de contenedores;
- la recursión del resolutor puede ser intencionada porque la cadena es circular;
- la sintaxis de configuración de lint depende de la versión;
- cambiar una interfaz de almacenamiento exige actualizar conjuntamente todos los backends y sus pruebas de contrato compartidas.
Si no están disponibles un generador, un entorno de contenedores o un schema ascendente necesarios, informa del requisito previo que falta. No edites manualmente artefactos derivados para simular que el trabajo está terminado.
## Completa todos los pasos al añadir un endpoint de API o cambiar el almacenamiento
Para un endpoint de API nuevo:
1. actualiza el schema de API administrado;
2. añade el manejador de transporte;
3. añade la lógica del comando o servicio de aplicación;
4. asigna los errores de dominio en el límite de transporte;
5. añade pruebas enfocadas y matriciales.
Para un cambio en la interfaz de almacenamiento:
1. actualiza la interfaz;
2. actualiza las pruebas compartidas del contrato de almacenamiento;
3. implementa el cambio para cada backend compatible;
4. ejecuta los conjuntos afectados en memoria y basados en contenedores.
Para un cambio en el resolutor del grafo:
1. implementa la interfaz del resolutor;
2. añade o actualiza las options del constructor;
3. verifica la composición condicional y la delegación circular;
4. prueba la corrección, las interacciones con la limitación o la caché y la terminación;
5. ejecuta una prueba de rendimiento si puede cambiar la ruta crítica.
Para un cambio del sistema de tipos, actualiza el análisis, la validación, la lógica de grafos ponderada u optimizada y las pruebas de validación relacionadas como un único cambio coherente.
Antes de declarar que el trabajo está terminado, revisa el diff para detectar ediciones accidentales de archivos generados, confirma que la prueba enfocada pasó de fallo a éxito, ejecuta los objetivos canónicos directamente afectados y registra cualquier clase de prueba que no haya podido ejecutarse junto con su requisito previo exacto.
