Buscar/Haz que la IA siga el estilo y las reglas de módulos de un gran backend Java

Haz que la IA siga el estilo y las reglas de módulos de un gran backend Java

Úsalo si una IA trabaja en un gran servidor Java de módulos y proveedores. Lee primero los puntos de entrada, sigue el estilo que se comprueba al compilar y la versión mínima de Java, declara cada módulo que usa, comprueba en el código antes de afirmar y prueba en local antes de subir.

Para usar estas reglas de IA
## Antes de editar, entiende cómo encajan los módulos y los proveedores Un servidor grande de este tipo se ensambla a partir de módulos; no se escribe como una sola aplicación. Una declaración de módulo nombra el módulo y las interfaces de servicio que expone; un proveedor implementa esos servicios con una tecnología concreta; los demás módulos consumen únicamente las interfaces declaradas. Los proveedores se descubren mediante el mecanismo de carga de servicios de la plataforma y siguen un ciclo de vida fijo: una fase de preparación que construye objetos y lee la configuración, y luego una fase de arranque que activa los servicios. ### Recorre la canalización antes de tocar una etapa Los recolectores envían telemetría a través de la capa de transporte, los complementos receptores la analizan y la validan, el motor de análisis la agrega mediante los lenguajes de dominio propios del proyecto, los complementos de almacenamiento persisten el resultado y los complementos de consulta lo sirven a la interfaz. Un cambio en una etapa suele necesitar su contraparte en otra. ### Lee primero los puntos de entrada Antes de editar, lee la definición del módulo central, la clase base del sistema de módulos, los archivos de gramática de los lenguajes específicos de dominio, el punto de entrada de la aplicación y la documentación de arquitectura. Un nombre no te dice cómo funciona una funcionalidad. ## Sigue el estilo de código que se comprueba al compilar Aquí el estilo lo verifica la máquina, así que una infracción bloquea la compilación en lugar de abrir un debate. No imprimas en la salida estándar; usa la fachada de registro del proyecto. No añadas anotaciones de autor. No uses caracteres de tabulación, importaciones con asterisco, importaciones no usadas o redundantes, sentencias vacías ni varias líneas en blanco consecutivas. Mantén una sola sentencia por línea, mantén un espacio después de las comas, los puntos y comas y las conversiones de tipo, y mantén espacios alrededor de los operadores. ### Patrones obligatorios Anota los métodos sobrescritos. Sobrescribe la igualdad y el hash juntos. Da una descripción real a cada etiqueta de parámetro, de retorno y de excepción de la documentación. Escribe las constantes de tipo long con la letra de sufijo en mayúscula. Coloca la rama por defecto al final del switch. Respeta la longitud máxima de archivo y divide cualquier archivo que se acerque a ella. ### Nomenclatura Las constantes y las variables estáticas usan mayúsculas con guiones bajos, los parámetros de tipo usan mayúsculas, los tipos usan pascal case y las variables locales, los parámetros y los miembros usan camel case. Prefiere las factorías de colecciones inmutables y el procesador de anotaciones del proyecto frente al código repetitivo escrito a mano, y prefiere las variables locales y los parámetros declarados como final. ### No incrustes nombres de clase completamente cualificados Añade una importación y usa el nombre corto en las declaraciones de campo, las firmas de método, las variables locales y los argumentos genéricos. Las únicas excepciones aceptables son una colisión real de nombres simples entre dos clases importadas y un único enlace de documentación en el que el nombre corto resultaría ambiguo para quien lo lea. ### No escribas métodos delegados de una sola línea Un envoltorio cuyo único cuerpo reenvía a otra clase añade un salto sin valor. Incorpora la llamada en el punto de uso o llama directamente al objeto subyacente, incluso mediante una referencia a método. ### Cabeceras de licencia Los archivos de código fuente, de marcado y de configuración llevan la cabecera de licencia del proyecto. Los formatos que no admiten comentarios quedan excluidos por la configuración de licencias; sigue esa configuración en lugar de añadir cabeceras a mano donde no corresponden. ## Nombra clases y métodos por su función, no con metáforas Las clases y los métodos se nombran por su función, no por una metáfora abstracta. Prefiere verbos concretos como cargar, aplicar, dar de baja, compilar, verificar, confirmar y revertir, en lugar de verbos metafóricos como sembrar, hidratar, arrancar o cebar. ### Deja que el nombre exprese la tarea Una clase que carga reglas estáticas recibe un nombre que habla de cargar reglas estáticas, no una imagen evocadora. Un temporizador que sincroniza el estado de la base de datos de forma programada se nombra por esa sincronización, no por un tic. ### Una metáfora es una señal para dividir Si no puedes nombrar un método sin recurrir a una metáfora, es probable que el método haga demasiadas cosas. Divídelo hasta que cada parte tenga un nombre funcional y llano. ## Comenta solo lo que el código no explica por sí mismo No expliques lo que el código ya dice. Comenta únicamente donde leer el código no basta: un invariante que no es visible en este método, una restricción de orden transversal, por qué existe una rama no obvia, por qué es necesaria una llamada aparentemente redundante. Si el código es claro, no escribas ningún comentario. ### Conecta la lógica que vive separada Una comprobación que existe solo por una garantía dada en otro sitio merece una referencia de una línea a esa garantía. Una solución alternativa para un defecto conocido en otro sitio merece un enlace a él. ### Recorta la documentación que repite el código La documentación de un método describe el contrato, no el cuerpo. Las justificaciones de varios párrafos van en el documento de diseño, no en el archivo de código fuente. ## Usa las aserciones del marco de pruebas y pregunta antes de cambiar una prueba Usa siempre los métodos de aserción del marco de pruebas. Nunca uses la sentencia de aserción incorporada del lenguaje dentro de una prueba. Incluso donde el ejecutor de pruebas habilite esas sentencias, las aserciones del marco son la convención en el resto del código base, sobreviven a cualquier configuración del ejecutor y producen un fallo estructurado que indica el valor real en lugar de un error sin contexto. ### Arregla las pruebas que fallan; no las cambies en silencio Si fallan pruebas unitarias, de integración o de extremo a extremo ya existentes, intenta arreglarlas. Si hay que modificar un caso de prueba o eliminar código de prueba, ese cambio debe ser revisado por una persona antes de aplicarlo: expón la modificación o la eliminación propuesta junto con su razonamiento, y espera una aprobación explícita en lugar de cambiar o quitar la prueba por tu cuenta. ### Ajusta el tipo de prueba al alcance Los alcances unitario y de integración usan patrones distintos y arneses de prueba distintos. Demuestra el comportamiento en el alcance en el que realmente vive, en lugar de duplicar la misma aserción en todos los niveles. ## Escribe código que compile en la versión mínima admitida de Java Un proyecto que admite varias versiones con soporte a largo plazo debe compilar y ejecutarse en la más antigua, incluso cuando la máquina de compilación tenga un compilador más nuevo. Asume el mínimo, no lo que acepte tu editor. ### Construcciones que evitar cuando el mínimo es más antiguo Las expresiones switch con flecha, la operación terminal de stream que devuelve una lista directamente, los bloques de texto, los tipos record, el ajuste de patrones en una comprobación de tipo y los tipos sellados son todos más recientes que una línea base antigua. Usa en su lugar un switch tradicional con cases y breaks explícitos, un colector para construir la lista, concatenación de cadenas, una clase normal con accesores generados, una conversión de tipo explícita después de la comprobación de tipo, y una clase o interfaz normal. ### Construcciones que son seguras Las factorías de colecciones inmutables, los métodos más nuevos de Optional, las expresiones lambda, las referencias a métodos y la propia interfaz de stream están disponibles en una línea base antigua y no necesitan ninguna solución alternativa. ### Verifica buscando, no confiando en la compilación Busca en el árbol de fuentes cada construcción prohibida y confirma que no hay coincidencias antes de afirmar que hay compatibilidad. Una compilación con un compilador más nuevo no las detectará por ti. ## Mantén los submódulos y el código generado al día con la compilación Las definiciones de protocolo y la interfaz web pueden vivir en submódulos. Clona siempre incluyendo los submódulos y actualízalos de forma explícita cuando un cambio de protocolo lo requiera. Un cambio de protocolo que no se refleje en el puntero del submódulo no compilará para nadie más. ### Genera antes de analizar Ejecuta el paso de compilación antes de analizar código generado, e instala el proyecto para que el precompilador y las clases generadas queden exportados antes de ejecutar las pruebas. Nunca edites a mano las clases generadas; cambia la definición que las produce y vuelve a compilar. ### Recompila el proyecto entero tras cambios entre módulos Si has cambiado más de dos módulos, o has hecho pull o rebase desde el remoto, compila el proyecto entero en lugar de seleccionar módulos individuales. Las compilaciones incrementales de un solo módulo pueden dejar archivos obsoletos en el repositorio local o en el directorio de bibliotecas cuando el tamaño del archivo no cambia pero su contenido sí, lo que produce fallos en tiempo de ejecución muy difíciles de rastrear. ## Mantén la documentación y el changelog exactos y bien mostrados La documentación la renderiza un motor de markdown, así que ten en cuenta cómo se verá, no solo cómo se lee el original. Las rutas de archivo relativas son válidas y funcionan tanto en el repositorio como en el sitio de documentación; sigue usándolas en lugar de enlaces absolutos. Actualiza el changelog siempre que cambie el comportamiento. ### Mantén cada viñeta del changelog en una sola línea No partas una frase en varias líneas del archivo dentro de una viñeta; las subviñetas anidadas están bien porque son elementos de lista reales. El changelog se convierte en el cuerpo de la publicación, y el renderizador de publicaciones convierte un simple salto de línea de continuación en un salto visible, de modo que las viñetas partidas muestran cortes irregulares a mitad de frase en la página de la publicación, aunque el sitio de documentación redistribuya el texto y oculte el problema. ### Congela una propuesta de diseño en cuanto se publique Cuando aterriza la implementación de una propuesta de diseño, sincroniza la propuesta una sola vez con lo que realmente se construyó: cada cambio propuesto redactado en pasado, sin que quede ningún texto de trabajo pendiente, de trabajo futuro, de dependencia abierta o de «vacío hasta» para nada que esté dentro de su alcance. Después de esa sincronización, la propuesta queda congelada. Las métricas, los paneles y las mejoras incrementales posteriores van en la documentación viva para operadores. Solo pueden quedar bajo trabajo futuro seguimientos opcionales realmente pequeños; nunca un cambio grande. ### Haz referencias cruzadas con enlaces de anclaje Referencia otra sección con un enlace de anclaje de markdown, nunca con el símbolo de sección ni con un número de sección suelto. Verifica que cada anclaje resuelve a un encabezado real según las reglas de slug del sitio, porque un anclaje roto se renderiza en silencio como texto plano. ## Declara cada módulo que tu código busca Toda búsqueda del servicio de otro módulo debe estar respaldada por una declaración. Si el código pide al gestor de módulos que encuentre un módulo, ya sea directamente o a través de un ayudante, el nombre de ese módulo debe aparecer en la lista de módulos requeridos del proveedor. Una declaración que falta no falla en el arranque; lanza una excepción la primera vez que se ejecuta esa ruta de código. Envolver la llamada en un catch amplio no es un sustituto: declara el módulo y reserva el manejo defensivo solo para caídas transitorias de un proveedor. Al auditar una rama, busca en cada módulo tocado las búsquedas al gestor de módulos y confirma que cada destino está declarado. ### Actualiza todas las implementaciones, no solo la principal Cuando añadas un servicio a la lista de servicios de un módulo central, actualiza todas las implementaciones de proveedor de ese módulo, incluidos los proveedores simulados que usan las herramientas independientes y los arneses de prueba. Busca las subclases en el árbol en lugar de suponer que solo hay una. El servidor principal no es el único empaquetado; las herramientas independientes arrancan con proveedores simulados y un subconjunto de módulos, así que los cambios en los contratos de los módulos centrales también deben llegar hasta ellas, o esas herramientas fallarán al arrancar. ### Prefiere el servicio ya poblado antes que el módulo de coordinación Los módulos receptores y analizadores no suelen declarar el módulo de coordinación del clúster, así que buscarlo directamente lanza una excepción en tiempo de ejecución. Pasa por el servicio de gestión de pares del módulo central, que la capa de coordinación ya rellena y que expone la lista de pares que necesitan la mayoría de los componentes. Si un módulo necesita realmente primitivas de coordinación, declara ese módulo de forma explícita. ### No enrutes la intención por canales laterales de tipo thread-local Pasar la intención de quien llama a través de un thread-local que lee el código posterior crea un acoplamiento invisible entre rutas de código distantes, se filtra en los traspasos asíncronos como los executors y los bucles de eventos, y hace imposible entender el comportamiento a partir de la firma de un método. Extiende la interfaz en su lugar: añade un parámetro, un método o un valor de modo que aparezca en la firma, aunque cueste más líneas. Las raras excepciones son la propagación de contexto en la que toda la industria se ha estandarizado sobre un thread-local, y los principales de seguridad que impone un framework. ## Espera a que el cambio de esquema llegue a todos los nodos antes de escribir datos Cuando los cambios de esquema o de metadatos se difunden a los nodos coordinadores y se propagan de forma asíncrona a los nodos de datos, una llamada de definición retorna en cuanto el coordinador la acepta, llevando consigo un marcador de revisión, sin esperar a los demás nodos. Una escritura de datos cuya definición aún no se ha propagado se descarta en el nodo que la ejecuta, se registra y se omite, así que hace falta una barrera. ### Espera a la marca de agua de revisión Después de emitir un cambio de definición, bloquéate en el observador de esquema del cliente hasta que todos los nodos vivos informen de que han aplicado al menos la revisión devuelta, con un tiempo límite, antes de liberar las escrituras dependientes. Una comprobación de lectura tras escritura contra el registro no demuestra la propagación. ### Gestiona los borrados y los almacenes síncronos Cuando un borrado no devuelve un marcador de revisión utilizable, recurre a la llamada específica de espera de borrado. Los almacenes cuyas sentencias de definición son síncronas en el coordinador no necesitan barrera alguna. No reintroduzcas el modismo antiguo de sondear la llamada de consulta hasta poder leer tu propia escritura; es anterior a la interfaz de barrera y ya ha sido reemplazado. ### Comprueba qué biblioteca cliente estás leyendo Los tipos de barrera y de observador pueden vivir en una bifurcación del cliente dentro del árbol y no en el cliente publicado independiente. Su ausencia en el cliente publicado no es prueba de que la interfaz haya desaparecido. ## Comprueba en el código y la documentación en lugar de adivinar Nunca adivines ni especules. Todo análisis debe estar fundamentado en el código fuente, la documentación o el comportamiento observado. Lee la implementación en lugar de suponer cómo funciona una funcionalidad por su nombre o por convención. Lee la documentación del proyecto, los archivos de directrices que hay dentro de los submódulos y los archivos readme antes de proponer un diseño. ### Verifica la configuración y las banderas Comprueba qué banderas y variables de entorno existen realmente, cuáles son sus valores por defecto y cómo se analizan, incluida cualquier convención de prefijos que vincule automáticamente las banderas con las variables de entorno. ### Lee los proyectos de los que dependes Antes de dar por supuesta una capacidad, lee el código fuente y la documentación de las dependencias y los proyectos acompañantes implicados: los charts de despliegue para los campos admitidos, la infraestructura de pruebas para las opciones admitidas y las bibliotecas cliente para las llamadas disponibles. Si es probable que un proyecto acompañante esté descargado en local, pide la ruta local, porque buscar en un clon local es mucho más rápido que traer los archivos de uno en uno desde una interfaz remota. ## Ejecuta el código y las pruebas en local antes de depender de la integración continua (CI) Ejecuta el código, arranca el contenedor y lanza la prueba en local antes de hacer push. La integración continua no es un entorno de prueba y error. ### Valida las rutas y las estructuras de directorios Comprueba dónde acaban realmente los datos en lugar de deducir el nombre de un directorio a partir del nombre de una bandera; una opción de ruta raíz crea con frecuencia debajo un subdirectorio con un nombre distinto. ### Valida la configuración generada o editada Después de editar archivos de configuración, sobre todo con editores de flujo o scripts, valídalos con un analizador real antes de confirmar los cambios. Una configuración corrupta provoca fallos silenciosos en la automatización. ### Confirma que las imágenes y los binarios existen Verifica que la imagen de contenedor está realmente publicada antes de escribir configuración de pipeline o de extremo a extremo que dependa de ella, y confirma qué binarios, shells y directorios existen dentro de la imagen antes de escribir comandos que los usen. La disponibilidad de una imagen depende de que los flujos de publicación hayan terminado. Ten en cuenta dónde viven las imágenes: las imágenes propias del proyecto pueden estar en un registro del servicio de alojamiento de código con identificadores de commit completos como etiquetas, mientras que las imágenes oficiales y de terceros están en el registro público con etiquetas convencionales. ## Haz push con el flujo de envío del proyecto y la automatización aprobada Usa el flujo de envío específico del proyecto para confirmar los cambios y subirlos a una rama de revisión. Ejecuta comprobaciones previas como la compilación, la verificación de estilo y la verificación de las cabeceras de licencia antes de cada push, y abre la solicitud de revisión si aún no existe ninguna. ### Respeta la lista de permitidos de la automatización La organización puede imponer una lista de permitidos para los pasos de automatización de terceros, exigiendo que cada uno quede fijado a un identificador de revisión aprobado en lugar de a una etiqueta de versión. Si una revisión se bloquea porque un paso no está permitido, consulta la lista aprobada y actualiza los archivos de flujo de trabajo para usar la fijación aprobada. Los pasos que pertenecen al proveedor de la plataforma o a la propia organización suelen estar permitidos sin fijación. ### Di lo que falta en lugar de adivinar Si no encuentras el código fuente, no sabes cómo ejecutar algo o el código no deja clara la respuesta, pregunta en lugar de especular. Cuando investigues el comportamiento en tiempo de ejecución, monta una prueba local con datos reales y observa la salida real en lugar de predecirla.