# Reglas obligatorias para páginas de catálogo
Estas reglas complementan `AGENTS.md`, `AGENTS_PAGE_STRUCTURE.md`, `AGENTS_WEBFORMS_PARTIAL_POSTBACKS.md` y `AGENTS_JAVASCRIPT_INITIALIZATION.md`.
## Estructura visual
Toda página de catálogo debe organizarse, en este orden:
1. Título de la página.
2. Barra de navegación ascendente y menú de acciones.
3. Barra o control de filtros.
4. Sección opcional de cabecera con indicadores o resúmenes.
5. Grid o contenido principal.
- El título, breadcrumb y contenedor de acciones pertenecen a `Site.master`; no deben duplicarse en cada ASPX.
- La barra de navegación debe mostrar la jerarquía ascendente hasta la página actual, por ejemplo `Inicio > Desarrolladores > Fraccionamientos`.
- La master debe exponer un `ContentPlaceHolder` de acciones dentro de un `
`; las páginas insertan elementos `- ` o un `UpdatePanel` que produzca esos elementos.
- Las acciones principales del catálogo, como agregar, exportar o imprimir, deben colocarse en ese menú cuando corresponda.
## Filtros
- Los catálogos deben usar el control reutilizable de filtros activos; no construir una barra distinta en cada página.
- El control muestra los filtros aplicados y permite abrir un modal para seleccionarlos o modificarlos.
- Los combos, buscadores y demás campos de selección pertenecen al modal de filtros.
- Todo `asp:DropDownList` nuevo de una página de catálogo debe incluir la clase `select2me`, además de sus clases visuales necesarias.
- Los filtros aplicados deben describirse con texto comprensible y permitir retirarse o limpiarse.
- La búsqueda debe volver a enlazar indicadores y contenido principal con el mismo conjunto de filtros.
- El control reutilizable de filtros debe permanecer como server control de C#, conservar la imagen de chips y toolbar acordada, y exponer un evento `Consultar` para que cada página ejecute su propia búsqueda.
- Los estilos del control de filtros pertenecen a `Styles/Filtros.css` y deben registrarse en el bundle global; no duplicarlos en `Estilos2.css`, en páginas ASPX ni registrarlos desde el control.
- El control debe reconstruir sus hijos con IDs estables y conservar su estado y eventos al trabajar dentro de un `UpdatePanel`; no debe registrar scripts globales ni crear otro `ScriptManager`.
## Presentación de grids
- Todo `asp:GridView` nuevo o modificado debe declarar `GridLines="None"`.
- Su `CssClass` debe incluir la clase exacta `Widthall`.
- No usar la clase `table-bordered` en grids de catálogo o detalle.
- Se pueden conservar `table`, `table-striped` y `table-hover` cuando correspondan al diseño.
## Ordenamiento manual de catálogos
- Cuando una tabla de catálogo tenga el campo `Orden`, no mostrar ese campo en formularios, modales ni columnas del grid.
- En el alta, el procedimiento almacenado asigna `ISNULL(MAX(Orden), 0) + 1`; cuando el orden dependa de una entidad padre, calcular el máximo únicamente dentro de ese padre.
- Las modificaciones ordinarias conservan el orden existente. Si el registro cambia de padre, asignarle el siguiente orden disponible dentro del nuevo padre.
- El procedimiento de listado ordena primero por `Orden` y después por un campo descriptivo estable.
- El grid permite reordenar filas mediante arrastre y muestra únicamente un asa visual; no muestra el valor numérico de `Orden`.
- El reordenamiento usa un procedimiento almacenado dedicado, valida en servidor el registro, la referencia y su pertenencia al mismo padre, y se ejecuta mediante repositorio y servicio.
- Todo cambio de orden se registra mediante `IBitacoraService` dentro de la misma transacción de aplicación que actualiza el catálogo.
- La inicialización del arrastre debe ser idempotente y volver a ejecutarse después de postbacks parciales sin duplicar eventos.
## Indicadores y contenido
- La sección de cabecera es opcional; se usa cuando existen indicadores útiles como totales, activos, pendientes, etapas o avances.
- No agregar tarjetas decorativas sin información funcional.
- El grid o contenido principal siempre aparece después de filtros e indicadores.
- Los estados vacíos deben explicar que no existen registros para los filtros actuales.
## Mensajes originados en modales
- Los labels dentro del modal se reservan para validaciones de captura conocidas, como campos requeridos, formatos inválidos o valores que el usuario puede corregir directamente.
- Las reglas de negocio, resultados de servicios, errores técnicos, confirmaciones y mensajes de éxito deben mostrarse mediante el sistema central de alertas, aunque la acción se haya iniciado dentro del modal.
- Cuando guardar falle, el modal debe conservar los valores y permanecer abierto o volver a abrirse; la alerta debe mostrarse por encima del overlay.
- Un guardado exitoso puede cerrar el modal y mostrar un toast. Las alertas deben encolarse para no sobreponerse.
- La misma regla aplica durante postbacks completos y parciales con `UpdatePanel`.
## Navegación a páginas de detalle
- Cuando una fila abre una página de detalle, usar `asp:HyperLink` con `NavigateUrl` o un enlace HTML real.
- No usar `LinkButton`, `CommandName`, `RowCommand` ni postback únicamente para navegar al detalle.
- Los nombres de controles, métodos y variables deben identificar la entidad de la fila, por ejemplo `LnkFraccionamientoDetalle`, `cveFraccionamiento` y `fraccionamientoDetalleUrl`.
- Reservar los comandos con postback para operaciones de servidor como guardar, eliminar, activar o ejecutar una acción de negocio.
## Pestañas y estado de página
- AjaxControlToolkit debe registrarse globalmente en `Web.config` con el prefijo exacto `ajax`; no agregar directivas `<%@ Register ... %>` en cada página.
- Las pestañas de catálogos y páginas de detalle deben implementarse con `ajax:TabContainer` y `ajax:TabPanel`.
- No crear pestañas funcionales mediante `nav-tabs` de Bootstrap, paneles ocultos manualmente o navegación JavaScript independiente del ciclo de vida de WebForms.
- Las claves y modos internos que deban sobrevivir postback se conservan en propiedades tipadas de `ViewState`.
- No usar `asp:HiddenField` para estado exclusivamente del servidor. Reservarlo para valores que JavaScript necesite leer o modificar y validarlos nuevamente en el servidor.
- Los nombres de las propiedades ViewState deben describir la entidad, por ejemplo `CveFraccionamientoActual` y `CveFraccionamientoEtapaActual`.
## Alta rápida y detalle
- Antes de implementar un catálogo se debe definir si agregar y editar usarán modal, página de detalle o ambas modalidades.
- La captura rápida se realiza en modal y contiene únicamente los campos necesarios para crear el registro.
- Cuando el alta tenga modalidad básica y avanzada, el modal debe incluir un botón `Avanzado` que navegue a la página completa.
- Cuando editar requiera relaciones, historial, etapas, documentos, trámites o estados, debe abrir una página de detalle en lugar de sobrecargar el modal.
- La página de detalle puede editar la información principal y administrar sus relaciones en secciones o pestañas claramente identificadas.
- No asumir automáticamente que alta y edición usan la misma interfaz.
## Bitácora de catálogos
- Toda alta, modificación, activación, desactivación o eliminación de un catálogo debe registrarse mediante `IBitacoraService` dentro de la misma transacción de aplicación que la operación principal.
- El servicio confirma la transacción únicamente después de guardar correctamente la operación y toda su bitácora. Un fallo del encabezado, relaciones o campos revierte también la operación principal.
- No registrar consultas, búsquedas, filtros, paginación ni visualizaciones de detalle sin cambios.
- El servicio del catálogo construye el evento; el ASPX, su code-behind y los repositorios de negocio no deben registrar la bitácora directamente.
- `Bit_Bitacora` guarda el encabezado del movimiento. Cada evento debe enviar una lista genérica de relaciones formada por tabla, campo y valor; el procedimiento resuelve `CveTabla`, `CveCampo` y si el valor se almacena como número entero o texto.
- Los catálogos ligados a un cliente deben incluir una relación para la entidad afectada y otra para `Clientes.CveCliente`. Cada relación declara explícitamente `VisibleDesarrollador`.
- Las altas envían todos los campos auditables y establecen `DiscriminarCamposSinCambios = false`.
- Las modificaciones envían valor anterior y nuevo de los campos candidatos; `DiscriminarCamposSinCambios = true` es el valor predeterminado y guarda únicamente los campos que realmente cambiaron, distinguiendo correctamente entre `NULL` y texto vacío.
- Las eliminaciones registran encabezado y relaciones, pero no requieren registros en `Bit_BitacoraCampos`.
- Nunca registrar contraseñas, hashes, tokens, secretos ni otros valores sensibles en los campos de bitácora.
- Para consultar la bitácora, `SuperUsuario` y `Administrador` pueden ver todos los registros. El rol `Empresa` se considera desarrollador y sólo puede ver eventos con una relación `Clientes.CveCliente` visible que coincida con cualquiera de sus clientes activos en `Sis_UsuariosClientes`.
- Antes de liberar un catálogo nuevo, sus tablas y campos auditables deben estar registrados y activos en `Bit_Tablas` y `Bit_Campos`, junto con el script de configuración correspondiente.
## Regla actual para fraccionamientos
- `Agregar fraccionamiento` usa captura rápida en modal.
- `Editar` o `Ver detalle` navega a una página dedicada.
- El detalle muestra la información del fraccionamiento, sus etapas, los trámites asociados a cada etapa y el último estado disponible, incluyendo estados finales como cancelado o terminado cuando existan.
## Legibilidad del código
- El ASPX, C#, CSS y JavaScript del catálogo debe conservar sangría y saltos de línea legibles.
- No colocar grids, columnas, modales, controles anidados, validaciones ni varios statements C# en una sola línea.
- Los archivos deben quedar preparados para que otro programador pueda localizar y modificar una sección sin tener que reformatearla primero.
## WebForms
- Los modales permanecen dentro del único formulario de `Site.master`; ninguna página declara un formulario adicional.
- Los eventos de botones dentro de acciones o modales siguen pasando por code-behind delgado, servicios, contratos, repositorios y procedimientos almacenados.
- Después de un postback parcial, Select2 y los modales deben reinicializarse de manera idempotente según `AGENTS_JAVASCRIPT_INITIALIZATION.md`.
- No copiar VB del sistema anterior; sólo usarlo como referencia funcional y reconstruir la solución en C#.