Formulario «Nuevo / Editar documento»
Carpeta: app/src/app/dashboard/documentos/administrativos/nuevo/. Estado (2026-10-09): el formulario es el compacto de Ccirhack (main/ccirhack): tarjetas pequeñas en dos columnas (texto de 10–12 px, campos de 28 px, field-styles.ts) con Destinatarios a todo el ancho, que cabe en una vista; la cabecera usa botones propios (BASE_BTN) en una fila.
Se revirtieron, a petición del equipo, los rediseños propuestos por Frontend para este formulario (cabecera con
StatusBar, campos subrayados con etiqueta flotante, tarjetas por fila conSortableCardRow, secciones contraíbles, panel único). Siguen disponibles en el historial de Git (commits1f552d6dy8ca006d9) si se retoma la discusión. No se aplica a este formulario la regla deapp/AGENTS.mdsobre campos subrayados (FloatingUnderline*): queda pendiente de decidir con el equipo si se unifica.
Funcionalidad (de Ccirhack)
- Nuevo (
NewDocumentFormsindocumentId): «Grabar» crea el documento y navega a…/[id]/editar. Editar (condocumentId): carga el documento, «Grabar» solo se habilita si hay cambios (isDirty) y el documento es borrador. - Emisión personal (
NewDocumentForm isPersonal, rutasdocumentos/personales): el remitente muestra Dependencia, Local/Sede/Agencia y «Firmado por» (uno mismo, sin jefe), se crea conisPersonalEmissiony vuelve al listado de personales. «Responder» desde Recepción abre «Nuevo» con?refId=y precarga esa referencia. Firmar solo se habilita al firmante del documento (currentUserId); si no lo eres, el botón explica «Solo el jefe de la oficina puede firmar este documento». - Remitente: en «Nuevo», la oficina activa y el usuario de la sesión; en «Editar», el autor y la oficina grabados del documento (
documentAuthorName/documentOfficeName). - Cabecera (20-oct-2026, solo interfaz; la lógica no cambió): el estado es un recorrido de cuatro píldoras «En proyecto | Para despacho | Firmado | Emitido» («Para despacho» es cuando el documento espera la firma del jefe y los vistos buenos, y hasta que se firma todavía puede regresar a proyecto; los estados posteriores de recepción reemplazan a «Emitido»). Mientras el documento está en proyecto el conjunto de botones es fijo y en el mismo lugar —Grabar, Generar, Cargar, Abrir, Cargar anexos y «Enviar a despacho»— y los que aún no aplican se ven apagados (borde discontinuo,
aria-disabled) sin texto debajo: el motivo sale en el tooltip compartido (al instante con foco de teclado) y se anuncia como descripción; el botón de color es el paso que toca (grabar → generar → cargar el PDF → enviar a firma). Una vez generado el documento, «Generar» pasa a ser «Editar» (abre el Word) y su flecha solo ofrece «Regenerar» (un botón del mismo ancho que «Editar» con su flecha; el aviso de confirmación sigue diciendo «Volver a generar»), con confirmación porque reemplaza el Word editado. «Volver» es una flecha sin texto a la izquierda del título («Volver a documentos administrativos» o «…personales», que llevan al listado de la tabla). La primera fila reúne la flecha, el título y las píldoras (a la derecha); los botones van en la fila siguiente y solo suben a la primera cuando el ancho del contenedor supera 1750 px. «Anular» está en el menú «Más». «Regresar a proyecto» es un botón (antes, la píldora «En proyecto»). Fuera de borrador: «Firmar» (con candado y el motivo si falta algo, p. ej. vistos buenos pendientes), «Ver documento», «Ver anexos» (apagado si el documento no tiene anexos). Vistos buenos (20-oct-2026): lista de texto —nombre y dependencia, estado «Pendiente»— con asa y flechas para reordenar; el lápiz abre la fila para cambiar dependencia y personal («Listo» / «Cancelar»); «Agregar visador», «Uno a uno» y «Agregar grupo» (panel con selector de grupo); estado vacío con explicación; interruptor «Con orden». Comportamiento completo endocs/manual-usuario/documento-administrativo.md. Referencias y observación interna (20-oct-2026): Referencias pasa de una tabla de 10 a 11 px a una lista (tipo y número, fecha, etiqueta Emitido o Recibido, y las acciones ver documento, ver anexos y quitar) con estado vacío explicativo y la nota de que el expediente se hereda del primer documento; Observación interna lleva el aviso «Solo tu oficina la ve» en el encabezado y el contador de caracteres (máximo 2000). Destinatarios (20-oct-2026): el tipo es un control segmentado «Oficinas | Persona jurídica | Ciudadano | Otros» (equivale a «Institución» en el manual v5.1); «Agregar grupo» (panel con selector) y «Agregar destinatario» arriba a la derecha, sin el botón del pie de la tabla; bloque «Aplicar a todos los destinatarios» con un solo botón; tabla con texto de 12 px, número en círculo y estado vacío explicativo; ayudas breves. Comportamiento endocs/manual-usuario/documento-administrativo.md. Remitente (21-oct-2026): datos de solo lectura con icono e iniciales (no campos deshabilitados), candado «Datos de tu sesión y de la oficina»; en el administrativo se agrega Firmado por (quien dirige la oficina, con su cargo; «Sin encargado asignado» si no hay), con la misma consulta de encargatura vigente de Destinatarios; en el personal, Dependencia, Local/sede/agencia y Firmado por («Tú»). Expediente, N.º de emisión y Documento (21-oct-2026): campos de 36 px y texto de 13 px; obligatorios con asterisco rojo en la etiqueta (no en el título de la tarjeta);ReadOnlyData(nuevo/readonly-data.tsx) muestra los datos de solo lectura con icono, etiqueta pequeña y valor (Remitente, Fecha, expediente heredado y número de emisión), con candado y motivo en el encabezado cuando no se pueden cambiar; aviso de «sin series asignadas» con icono; «Elige primero la serie» en el expediente; «Atender en» con el sufijo «días». Opciones del documento (21-oct-2026): «Documento reservado» pasa a «Acceso restringido» (casilla con una línea de ayuda: solo quienes participan ven el detalle en el seguimiento) y «Con orden» de Vistos buenos también es casilla: ambas son opciones que se guardan con el documento y se muestran como casillas, para que se lean igual que el resto de las opciones del formulario (el Design System admite también el interruptor al guardar). Espaciado del formulario (21-oct-2026, Design System): una sola medida de 16 px para todo el espacio exterior del formulario (arriba, a los costados y abajo, entre tarjetas en vertical, entre las dos columnas y entre la cabecera y la primera tarjeta; el contenedor de la página aporta 16 px arriba y abajo y el margen lateral se fija a 16 px), y el contenido de cada tarjeta con un margen interno de 12 px, el mismo del título, de modo que iconos, etiquetas y campos queden alineados con el encabezado; 12 px entre campos de la tarjeta Documento y 10 px en Expediente y Remitente. No añadir márgenes laterales propios a los textos de ayuda dentro de una tarjeta. Cabecera en tarjeta (21-oct-2026): en una tarjeta (sgd-panel, como las demás, con el margen del contenido y no de borde a borde) que se desplaza con el contenido, con dos zonas separadas por una línea —arriba la identidad con el estado en flechas a la derecha, debajo las acciones— con flechas de estado finas (28 px de alto y texto de 13 px); el espacio superior es el de los costados (24 px): fila de ruta (botón «Nuevo» solo con el documento grabado, con confirmación si hay cambios sin grabar; enlace al listado; título con el número del documento y menú ⋮ con «Anular») y fila de acciones con el recorrido de estado en flechas a la derecha (reemplaza las píldoras). Sustituye a la flecha «Volver» y al menú «Más» de la fila de botones. Pendiente: «Solicitar vistos buenos» desde «Para firma» (el servidor solo permite aprobar, observar y anotar un visado ya pedido), fila de ruta con contador de anexos y paso al documento anterior o siguiente. - Acciones de la cabecera (anterior): Generar Doc. (con «Editar Docx» en su menú ▾), Cargar Doc., Abrir Doc., Cargar Anexos / Ver (modal
anexos/attachments-modal.tsx) y Anular (no implementado). Con el documento ya fuera de borrador (en despacho, trámite "Para Despacho"): desaparece «Grabar», el cuerpo queda inerte y atenuado, y aparece «Firmar Doc.» (abreSignDocumentDialogcon el PDF final,onEmitvalida/sube/emite -- verapp/docs/components/firma-digital.md; es un botón simple, sin menú ▾; «Ver documento» abre el PDF y no hay «Abrir Docx»: en despacho no se edita, para editar se usa «Regresar a proyecto»). Con el documento ya Emitido (trámite "Emitido"), la cabecera se reduce a solo «Ver Documento» y «Cargar Anexos / Ver» -- ni «Firmar Doc.» ni «Anular» tienen sentido sobre un documento ya firmado y emitido; el estado EN PROYECTO/EMITIDO sigue igual. - Etiquetas del botón de anexos (23-oct-2026): «Cargar anexos» en proyecto y «Ver anexos» (ícono de ojo) fuera de borrador;
AttachmentsModalrecibetitle(«Cargar anexos» / «Anexos del documento»). El tooltip dice «Clic para cargar anexos» o «Clic para ver los anexos» y, sin anexos en proyecto, «Aún no hay anexos…». - Lote del 23-oct-2026: sin tarjeta «N.º de emisión» (la cabecera dice «El N.º de emisión se asigna al grabar» hasta grabar);
SectionCardadmiterequired(asterisco + «(obligatorio)» oculto) y Destinatarios lo usa;EntityPickerDialogusa un alto de listaclamp(20rem, 100dvh − 18rem, 36rem); «Ver anexos» queda activo con referencias aunque no haya anexos propios; la cabecera lleva un botón «Copiar número del documento» junto al número. - Ventana de anexos: especificación completa (estructura, acciones, selección y eliminación de varios, casuísticas, pendientes) en
anexos.md. - Firma de anexos por el jefe (25-oct-2026): con anexos «Requiere firma» sin resolver, «Firmar»/«Emitir» del documento se bloquea con «Faltan N anexos por firmar» y «Ver anexos» se resalta con «N por firmar»; el firmante resuelve cada uno en la ventana de anexos (
signerMode). Detalle endocs/components/anexos.mdy en el manual. - Anexos fuera de borrador:
AttachmentsModalrecibereadOnly(!isDraftacá; en la bandeja de Emisión,doc.status !== "draft"; en Recepción, siempre) -- el modal sigue abriéndose para consultar los anexos ya cargados, pero oculta «Agregar archivo(s)» en vez del botón. El backend también lo exige (UploadAttachmentsdevuelveErrDocumentReasonForbiddensi el documento no está endraft): la UI no es la única barrera. - Estado del trámite (
tramitStatusName): «EN PROYECTO» | «PARA DESPACHO» (pasa a despacho condispatchDocument) | «EMITIDO» | otros estados de recepción como paso único. El autor puede regresar a «En proyecto» desde «Para despacho» o «Emitido» (revertDocument, con confirmación: limpia vistos buenos y firma). La firma emite el documento (emitDocument,onEmitdeSignDocumentDialog). - Secciones: Expediente (solo lectura, se hereda de la primera referencia), Emisión (número), Remitente, Documento (tipo filtrado por oficina, asunto, fecha, plazo, reservado), Vistos Buenos, Referencias, Observación Interna y Destinatario (tablas con selectores en diálogo).
- Los datos que se envían (
createDocument/updateDocument) no dependen del diseño.
Documento en solo lectura (24-oct-2026; datos como texto desde el 25-oct-2026)
Fuera de «En proyecto» el formulario no se edita, pero tampoco se bloquea con inert (ocultaba los datos a los lectores de pantalla y no dejaba seleccionarlos ni copiarlos). Regla (25-oct-2026): una caja de entrada promete que se puede escribir; si no se puede, no debe parecer caja. Por eso los datos de las tarjetas se muestran como texto (icono, etiqueta y valor, ReadOnlyData, el mismo patrón de «Documento recibido»), y los controles que quedan (tablas de destinatarios y vistos buenos) pierden borde y fondo. El cuerpo se envuelve en FormReadOnlyProvider (ui/form-read-only.tsx):
| Elemento | En solo lectura |
|---|---|
| Tarjeta «Documento» | ReadOnlyData: Tipo de documento, Asunto (completo, respeta los saltos de línea), Fecha (la de emisión o creación, no la de hoy), «Atender en» («5 días» o «Sin plazo» atenuado) y «Acceso restringido» («Sí…» o «No»). Sin asteriscos, contador, flecha ni casilla. Insignia «Solo lectura» con candado en la cabecera. El nombre del tipo lo pide useReadOnlyDocumentType, que también avisa al formulario del tipo resuelto (encabezado y barra de acciones). |
| «Observación interna» | La nota como texto, o «Sin observación interna» atenuado. |
| «Con orden» (vistos buenos) | «Con orden: sí» o «Con orden: no». |
Input, Textarea | readOnly automático (enfocables, legibles, copiables) y, por CSS ([data-form-readonly]), sin borde, sin fondo y sin sangría: se leen como texto. Una propiedad readOnly explícita manda sobre el contexto. |
Checkbox | aria-readonly="true" y no cambia; se anuncia con su estado. |
SearchableCombobox (listas de opciones) | Campo readOnly con la selección, sin abrir la lista y sin chevron. |
EntityPickerDialog (dependencia, personal, trámite, prioridad en destinatarios) | Se muestra como campo de texto de solo lectura, sin diálogo de búsqueda. |
| Acciones de las secciones | Se ocultan con useFormReadOnly(): «Agregar visador/grupo», «Uno a uno», «Limpiar», asa y flechas de orden, editar y quitar visador; «Agregar» y «Quitar» referencia; «Agregar destinatario/grupo», «Aplicar a todos», eliminar fila y las pestañas de tipo (queda «Tipo: Oficinas»). |
| «Indicaciones» de un destinatario | Al hacer clic abre la ventana para leer el texto completo (campo de solo lectura, botón «Cerrar», sin «Guardar»). |
| Aviso | Una línea al inicio del cuerpo: «Este documento ya no está «En proyecto», por eso solo se puede consultar.» |
Reglas:
DialogContentreinicia el contexto: una ventana abierta desde la zona (anexos, indicaciones) conserva sus propios controles. Quien necesite el valor dentro del diálogo lo lee fuera de él conuseFormReadOnly().- La barra de acciones, el motivo de «Observado» y el botón «Regresar a proyecto» quedan fuera del proveedor y siguen activos.
- Sin atenuar el cuerpo (antes 90 % de opacidad): el texto conserva su contraste pleno y las etiquetas van en el gris secundario. El contenedor se anuncia como grupo «Datos del documento (solo lectura)».
- Foco: los campos de solo lectura (
data-form-readonly) conservan un foco visible con teclado (2.4.7), pero neutro: borde de 2 px en el color del texto, sin el azul ni el halo de los campos editables; tras un clic o toque (data-input-modality="pointer") no se dibuja, y el cursor es normal (las «Indicaciones», que abren una ventana de lectura, conservan la mano). Así un campo enfocado no parece editable. - Un control nuevo que se edite en este formulario debe leer el contexto (o usar
Input,Textarea,Checkboxo los selectores compartidos); si no, quedaría editable.
Documento recibido (revisión de Recepción, 24-oct-2026)
La pantalla recepcion/[id]/recepcion-review-content.tsx usa el mismo lenguaje visual que el formulario de emisión (antes tenía cabecera y campos de otra época: botones de 13 px, cajas grises y texto de 12 px).
- Cabecera: tarjeta
sgd-panel, igual que la del formulario de emisión. Arriba a la izquierda, la ruta «Recepción de documentos › Documento recibido» (el primer tramo vuelve a la bandeja; reemplaza al botón «Volver») y debajo el títuloTipo N° número(h1de 16 px, recortado si no cabe) con, a su derecha, el icono de copiar el número (CopyNumberButton, compartido con el formulario) y el menú ⋮ con Anular (solo cuando hay algo que anular; ya no es un botón de la fila de acciones). A la derecha de la fila, el recorrido de estado en flechas (StatusSteps,src/components/user/status-steps.tsx, compartido con el formulario) con los estados de la copia: Pendiente › Recibido › Atendido › Archivado; Observado y Anulado cierran el recorrido con su paso (Pendiente › Recibido › Observado; Pendiente › Anulado) y Archivado omite Atendido, que es opcional. En pantallas angostas el recorrido se desplaza dentro de su contenedor (enfocable con teclado). Debajo, la fila de acciones con los botones compartidos (Action,src/components/user/toolbar-action.tsx): Recibir, Ver documento, Ver anexos y Responder. - Ver anexos con contador (24-oct-2026), una sola implementación: el contador ya existía en el formulario de emisión (
attachmentNames→Action items); no se duplicó. Su lectura se extrajo auseAttachmentNames(src/features/documents/use-attachment-names.ts: lee al abrir y al cerrar la ventana de anexos, cononIncreasepara el aviso «El documento tiene N anexos» del formulario) y el botón con sus reglas aViewAttachmentsAction(src/components/user/view-attachments-action.tsx: insignia verde con la cantidad y tooltip con los nombres; apagado sin anexos ni referencias, «Este documento no tiene anexos ni referencias»; con referencias avisa «Sin anexos propios. Clic para ver los de las referencias»;reasonfuerza otro motivo, p. ej. «Graba el documento primero»). Lo usan el formulario de emisión, «Documento recibido», la revisión de visto bueno y la edición de Mesa de partes (que ya trae sus anexos en la solicitud, por eso no usa el hook). Una pantalla nueva con «Ver anexos» debe usar estas dos piezas, no volver a leer ni a escribir las reglas. Los anexos de las referencias también cuentan: «Ver anexos» no se apaga por no tener anexos propios si el documento tiene referencias, porque la ventana de anexos muestra además los de cada documento referenciado; solo se apaga sin anexos ni referencias. - Catálogo vivo (
/design-system/componentes› «Cabecera de un documento»,document-header-showcase.tsx): muestra la tarjeta completa con su recorrido (en curso y archivado con cinta), los cuatro estados de «Ver anexos» (con anexos propios, cargando o sin lectura, sin anexos pero con referencias, sin anexos ni referencias), copiar número, logo institucional y la insignia del visto bueno propio, con las reglas. Un cambio en cualquiera de estas piezas se refleja y se documenta ahí. - Piezas compartidas de la cabecera:
StatusSteps(recorrido en flechas),CopyNumberButton(copiar el número), el menú ⋮ con Anular yAction/ViewAttachmentsAction. En pantallas angostasActiondeja solo el icono pero conserva el nombre accesible (max-sm:sr-only; anteshiddenlo quitaba y los botones quedaban sin nombre). - Cinta: Archivado y Anulado muestran además la cinta de estado en la esquina (ver
cinta-estado.md); la primera fila reserva su esquina y el recorrido se desplaza a la izquierda de la cinta, como en el formulario. - Cuerpo: una sola medida de 16 px entre tarjetas, dos columnas desde
lg. Los datos sonReadOnlyData(icono, etiqueta y valor; el asunto y las observaciones respetan los saltos de línea conmultiline), no cajas grises. «Referencias» (ReferenceListCard) usa las mismas filas que la tarjeta del formulario (icono, nombre, fecha, Emitido o Recibido, «Ver documento» y «Ver anexos»), sin «Quitar». «Destinatario» lista cada destino con su insignia; el propio se resalta. - Observar o archivar (antes «Atención / Archivar»; «Atención» no correspondía: el panel no tiene ninguna acción de atender y su título mezclaba un sustantivo con verbos): dos paneles, «Observar» y «Archivar», sin título propio: el botón de abajo ya lleva ese nombre y repetirlo como encabezado duplicaba la etiqueta (cada panel es un
role="group"con su nombre accesible; los campos se distinguen por «Motivo de la observación» / «Motivo del archivamiento» y «Fecha de observación» / «Fecha de archivamiento»). La obligatoriedad se marca como en el resto de formularios, con asterisco rojo en la etiqueta del campo obligatorio (el motivo de la observación;aria-required) y sin asterisco ni el texto «(opcional)» en el opcional (el motivo del archivamiento). Los campos son los normales del sistema (los mismos del formulario de emisión), no los de subrayado: etiqueta arriba conFieldLabel(components/admin/field-label.tsx, con el contador de 2000 caracteres a la derecha),Textareacon borde y, para las fechas,DateField(components/ui/date-field.tsx: se escribedd/mm/aaaacon las barras automáticas o se elige en el calendario propio del sistema, botón de la derecha o Alt + ↓; no el calendario nativo del navegador), con la fecha máxima de hoy. «Observar» usa el botón de contorno de peligro y se habilita con una observación y una fecha válida; «Archivar» usa el botón principal y se habilita con una fecha válida (una fecha incompleta o inexistente muestra su error bajo el campo y apaga el botón, en lugar de enviar la del servidor). La observación de la revisión de visto bueno usa el mismoFieldLabel+Textarea. Los campos de subrayado con etiqueta flotante quedan solo para donde el formulario de emisión ya los usa. - Texto de ayuda dentro del campo (placeholder): da un ejemplo entendible, no repite la etiqueta («Escribe el motivo…» bajo «Motivo de la observación» no aporta). Observar: «Por ejemplo: falta adjuntar el informe técnico firmado.»; Archivar obligatorio: «Por ejemplo: duplicado, no corresponde a la oficina.»; Archivar opcional: «Por ejemplo: se respondió con el oficio adjunto.»; observación de visto bueno: «Por ejemplo: falta el cuadro comparativo de costos.»
- Regla de la observación al archivar (decisión del 24-oct-2026): Observar exige el motivo siempre (el remitente necesita saber qué corregir). Archivar exige el motivo solo si el documento no se atendió (estado Pendiente, Recibido u Observado: se cierra sin respuesta y debe quedar escrito por qué, p. ej. «duplicado» o «no corresponde a la oficina»); con el documento ya Atendido el motivo es opcional. No se encontró una norma peruana que obligue a registrarlo; se decidió por trazabilidad. Front: la etiqueta «Motivo del archivamiento» lleva asterisco rojo y
aria-required, el campo propone un ejemplo, sin texto de ayuda adicional (el asterisco basta), y el botón «Archivar» se apaga sin motivo. Back:ArchiveDocumentdevuelveErrArchiveReasonRequired(«indica el motivo del archivamiento: el documento no se atendió», HTTP 422) con la funciónArchiveReasonRequired(estado), probada; además el texto de solo espacios cuenta como sin observación (se guarda nulo). La columnaNOTESsigue admitiendo nulos: la regla vive en el front y el back. - Un documento solo se modifica «En proyecto» (validado en front, back y base de datos, 24-oct-2026). Front: fuera de «En proyecto» el formulario queda en solo lectura (
FormReadOnlyProvider), las secciones ocultan agregar, quitar y reordenar, y la ventana de anexos abre en solo lectura (sin agregar, eliminar ni marcar firma). Back:UpdateDocument,UploadAttachments,BringAttachment,ToggleAttachmentSignatureySignAttachmentya exigían el estadodraft; se detectaron y corrigieron tres operaciones que solo estaban protegidas por la interfaz:GenerateDocx,LoadDoc(cargar el PDF o el DOCX, que reemplazan los archivos del documento) yDeleteAttachment(ni siquiera consultaba el documento). Las tres devuelvenErrDocumentReasonForbidden(HTTP 403) fuera de «En proyecto». Pruebadraft_only_test.go(cada operación rechazada en Pendiente de visto bueno, Firmado, Enviado y Anulado; eliminar un anexo en proyecto sí funciona); sin la corrección, la prueba falla. Base de datos: no hay restricción que lo imponga (elCHECKdeSTATUSsolo limita los valores permitidos); la regla vive en el back. Cambios que no son de edición del documento (visto bueno, firma y emisión, recepción, anular, eliminar un documento anulado, regresar a proyecto) tienen sus propias reglas de estado. Pendiente: una prueba que recorra tambiénUpdateDocumentcon un fake completo. - Mínimo del motivo (24-oct-2026): un motivo de observación o de archivamiento debe tener al menos 5 caracteres sin contar espacios («Duplicado» pasa, una sola letra no). Aplica a Observar (siempre), a Archivar (si es obligatorio, y si es opcional solo cuando se escribe algo) y a la observación del visto bueno. Front: el botón se apaga hasta llegar al mínimo y, solo si ya se empezó a escribir,
ReasonHintavisa «Faltan N caracteres.» (components/ui/reason-hint.tsx, conreasonMissingyMIN_REASON_CHARSdelib/reason.ts). Back:ReasonTooShort/MinReasonChars(document/app/document/reason.go, probados) yErrReasonTooShort(HTTP 422) en Observar, Archivar y observar un visto bueno; las notas en borrador del visto bueno («Guardar nota») no se validan. - Recorrido de estado, Observado y Anulado en rojo (24-oct-2026): el paso actual es
alerta(rojo con icono de error) cuando el estado pide acción o cerró mal: Observado (hay que levantar la observación) y Anulado. Aplica al formulario de emisión (trámite Observado o Anulado), «Documento recibido», la revisión de visto bueno y Mesa de partes. El resto de estados siguen con el paso actual de color. - Observación de Observar y de Archivar: obligatoria u opcional (revisado en front, back y base de datos, 24-oct-2026): Observar exige la observación (front: el botón se apaga sin texto; back:
ObserveDocumentdevuelveErrReceptionNoteRequired, «la observación es obligatoria», que se responde como error de validación; la regla vive solo en el back y el front, la columna no la exige). Archivar no la exige en ninguna capa: el front la deja sin asterisco (el campo opcional no lleva «(opcional)», como el resto de formularios), no apaga el botón y envíanotessolo si hay texto;ArchiveDocumentno validaNotes; y en la base de datosTRS_DERIVATION.NOTESadmite nulos (CLOBen Oracle,texten PostgreSQL, sin longitud máxima). Observaciones: (1)NOTESes una sola columna para Observar y Archivar yUpdateStatussolo la escribe si llega texto, así que archivar sin observación conserva la observación anterior de Observar y esa nota aparece después como «Observación» del estado Archivado; (2) el límite de 2000 caracteres existe solo en el front (el back y la columna no lo limitan); (3) un texto de solo espacios al archivar se guarda tal cual; (4) la fecha (at) es opcional en el back (sin ella usa el momento actual), no se valida contra el futuro y una fecha mal escrita se ignora sin error: por eso el front ahora exige una fecha válida.
| Estado de la copia | Recibir | Ver documento / anexos | Responder | Anular | Observar | Archivar (motivo) | Cinta |
|---|---|---|---|---|---|---|---|
| No leído | Principal | Sí | Apagado: «Recibe el documento antes de responder» | Apagado: «Aún no recibiste el documento» | Sí | Sí | No |
| Recibido | Apagado: «Este documento ya fue recibido» | Sí | Sí | Sí | Sí | Sí | No |
| Atendido | Apagado | Sí | Sí | Sí | No | Sí | No |
| Observado | Apagado | Sí | Sí | Sí | Sí | Sí | No |
| Archivado | Apagado | Sí | Sí | Sí | No | No | «Archivado» |
| Anulado | Apagado | Sí | Sí | Sí | No | No | «Anulado» |
(La disponibilidad de «Observar», «Archivar» y «Anular» no cambió: sale de canObserve, canArchive y canUndo.) En pantalla de celular las acciones muestran solo el icono con su nombre accesible, la insignia pasa bajo el título y no hay desborde horizontal.
Bandejas. En «Recepción de documentos» y las bandejas que comparten su menú (No leídos, Recibidos y Delegados), el N.º de emisión de cada fila es un enlace que abre esta pantalla (la misma a la que lleva «Ver detalle»), también en la vista de tarjetas. Se configura con linkNumberTo de DocumentsEmissionTable; en Administrativos y Personales el enlace usa linkNumber y lleva al formulario (/editar).
Revisión de visto bueno (24-oct-2026)
La pantalla vistos-buenos/[id]/vb-review-content.tsx sigue el mismo patrón que «Documento recibido» (antes: barra pegada arriba, botones de 12 px en negrita, cajas grises y texto de 10 a 12 px). Solo cambia la presentación; las reglas de qué se puede hacer (canAct, blockedByOrder) y las llamadas al servidor no cambian.
- Cabecera: tarjeta
sgd-panel. Ruta «Vistos buenos › Revisión de visto bueno» (el primer tramo vuelve a la bandeja y reemplaza a «Volver»), títuloTipo N° númeroy, a la derecha, la insignia del visto bueno de quien revisa en tipo oración: «Sin VB» (aviso), «Con VB» (éxito) u «Observado» (error). Debajo, los botones compartidos (Action): Guardar nota (antes «Grabar»; guarda solo la nota de observación en borrador), Visar documento (el paso que toca, de color), Ver documento y Ver anexos. Los atajos se conservan: G, M, A, X y O. - Botones apagados con motivo: los que no aplican quedan apagados (borde discontinuo, sin ejecutar la acción) y explican el motivo en el tooltip y como descripción: «Este documento ya no admite vistos buenos», «Ya diste tu visto bueno» o «Espera a que los revisores anteriores den su visto bueno».
- Cuerpo: una sola medida de 16 px entre tarjetas. Izquierda: Expediente, Remitente, Documento (
ReadOnlyData) y Referencias (ReferenceListCard). Derecha: Vistos buenos, Tu observación y Destinatario. La tarjeta «Emisión» ya no existe: el número es el título de la cabecera. - Vistos buenos: el avance escrito («1 de 3 vistos buenos aprobados»; la concordancia sigue al total), lo que falta en una línea de ayuda (se quitó la barra de avance: con el avance escrito y las insignias de cada fila se veía cargado) con
countLabel(«2 pendientes · 1 observado», sin mostrar los ceros; no se repiten insignias porque cada fila ya lleva la suya) y la lista de revisores con su oficina y la nota si la dejaron. La propia fila se resalta y lleva «(tú)». Con orden se muestra#ny la nota «Con orden: los vistos buenos se dan en el orden de la lista». - Tu observación (solo si quien abre la pantalla es revisor):
FloatingUnderlineTextareacon contador de 2000 caracteres; «Observar» usa el botón de contorno de peligro y se habilita con una nota escrita; «Anular observación» aparece si ya observó. Los avisos («Este documento ya no admite vistos buenos», «Ya diste tu visto bueno», «Espera a que los revisores anteriores…») salen sobre el campo, con icono.
| Caso | Guardar nota | Visar documento | Observar | Aviso y otros |
|---|---|---|---|---|
| Sin visto bueno | Sí | Principal | Sí, con nota escrita | — |
| Con visto bueno | Apagado: «Ya diste tu visto bueno» | Apagado: igual | Apagado | Insignia «Con VB»; nota de solo lectura |
| Observado | Sí | Principal (se puede visar tras anular) | Sí | «Anular observación» sobre la nota |
| Espera su turno (con orden) | Sí | Apagado: «Espera a que los revisores anteriores den su visto bueno» | Apagado | Aviso sobre la nota |
| Documento fuera de revisión | Apagado: «Este documento ya no admite vistos buenos» | Apagado: igual | Apagado | Aviso sobre la nota; Ver documento y Ver anexos siguen activos |
Verificación
Reordenación accesible (lote 1, 15/10/2026)
Destinatarios y Vistos Buenos conservan sus tablas compactas. Ambos reutilizan ui/row-reorder-controls.tsx: asa con nombre contextual, sensores Pointer/Keyboard de dnd-kit y botones Subir/Bajar de 24 px. Espacio/Enter inicia y confirma el arrastre por teclado, las flechas mueven y Escape cancela. Los botones cubren el uso con clic/toque sin arrastrar (2.5.7, independiente de 2.1.1). Al mover se enfoca el asa en su nueva posición; las instrucciones y anuncios están en español. El ejemplo de /design-system/componentes#a11y-heading usa el mismo control, sin datos reales.
destinatario/constants.ts centraliza reorderRecipients: solo reordena el tipo visible, conserva datos y posiciones de otros tipos y mantiene la regla existente ORIGINAL/COPIA por puesto en Oficinas. Prueba de regresión: desde app, node --test scripts/reorder-recipients.test.mjs (Node 24, soporte de tipos TypeScript). Cuatro casos ejecutados correctamente. La validación de interacción/foco en navegador, seis apariencias y NVDA sigue pendiente; no declarar cerrado N2 solo por las pruebas del modelo.
Verificación histórica (09/10/2026)
2026-10-09, navegador integrado con una página temporal (retirada): el formulario carga con las tarjetas en dos columnas y la cabecera en una fila; sin errores de compilación (tsc 0, ESLint 0 errores). No probado: crear/editar/despachar/firmar contra el backend real, lector de pantalla, ni el scroll interno con una ventana alta (el contenedor del formulario depende del main del layout del dashboard).
Revisión de visto bueno: cabecera completa (24-oct-2026)
La cabecera de la revisión de visto bueno usa las mismas piezas: icono de copiar el número junto al título, tu visto bueno («Sin VB», «Con VB», «Observado») en una insignia junto al título y, a la derecha, el recorrido del documento en flechas (En proyecto › Vistos buenos › Firma › Emitido; el paso de vistos buenos es el actual mientras el documento espera visados, y un documento anulado muestra «Anulado» con la cinta de estado). «Ver anexos» lleva el contador.
Edición de Mesa de partes: cabecera con Action (24-oct-2026)
features/mesa-partes/components/form/edit-toolbar.tsx deja la barra antigua (botones de 13 px, etiquetas en mayúsculas como «PARA VERIFICAR») y usa la tarjeta del formulario: ruta «Mesa de partes › Editar registro», título N° número con copiar y menú ⋮ (Anular, solo en «En registros» con permiso), insignia del expediente («Exp: …» o «Sin expediente») y recorrido En registros › Para verificar › Registrado (Anulado reemplaza al recorrido con la cinta de estado). Acciones, todas Action y en sentido de oración: Actualizar (de color; apagado sin cambios o fuera de «En registros»), Cargar documento, Ver documento, Subir anexos, Ver anexos (con contador; habilitado también con solo referencias: la ventana lista los anexos propios y, por cada referencia, abre la ventana de anexos compartida en solo lectura), Voucher (apagado hasta registrar), Cargo (registrado) y las transiciones de estado: Para verificar (apagado sin documento o sin permiso), Volver a en registros, Registrar documento (de color; apagado con cambios sin guardar), Volver a para verificar y Reactivar. «Volver» se reemplaza por el primer tramo de la ruta. Las reglas, permisos y llamadas no cambian; los atajos G, C, A, X y R se conservan.
Registro y edición de Mesa de partes: formulario como el de emisión (29-oct-2026)
La cabecera de edición se había perdido en un merge (volvió la barra antigua con «PARA VERIFICAR» en mayúsculas): se restituye con lo agregado después (Observar, Subsanar en «Observado», Anular también en «Observado», aviso de expediente faltante en «Para verificar») y el recorrido suma Observado y Anulado en rojo y Subsanado. El registro nuevo (form-toolbar.tsx) usa la misma tarjeta: ruta «Mesa de partes › Nuevo registro» (o «Subsanar …»), título con «El N° se asigna al grabar», recorrido En registros › Para verificar › Registrado y acciones Action: Grabar (G), Cargar documento, Ver documento y Voucher apagados con su motivo, y Cancelar (C). Las páginas ya no repiten la miga de pan sobre la tarjeta. Cuerpo: dos columnas desde lg con 16 px entre tarjetas (Expediente y Remitente a la izquierda; Documento y Referencias a la derecha) y Destinatarios a todo el ancho, con la SectionCard del formulario de emisión. La tarjeta «Detalle» desaparece: fecha, año y N° de emisión son ReadOnlyData en Expediente. Los campos dejan el subrayado con etiqueta flotante y usan los del formulario de emisión (shared/form-fields.tsx: etiqueta arriba con asterisco rojo en los obligatorios, control con borde de 36 px, ayuda o error debajo, contador dentro de los textos largos); las listas (tipo, origen, TUPA, ubigeo) buscan en el mismo campo. «Sensible» pasa a «Acceso restringido» (casilla con ayuda), como en emisión y en la vista de solo lectura. Referencias es una lista con ver documento, ver anexos y quitar con confirmación; Destinatarios lleva asterisco de tarjeta obligatoria, número en círculo y estado vacío explicativo. Los datos que se envían no cambian.
Íconos de los datos de solo lectura (24-oct-2026)
ReadOnlyData muestra el ícono solo, en gris suave de 18 px, sin el recuadro tintado que llevaba antes en cada fila (se veía cargado y repetía color sin aportar información: la etiqueta ya dice qué es el dato). Conserva el hueco de 28 px para que etiquetas y valores sigan alineados con el título de la tarjeta. Aplica al formulario de emisión (Expediente, Remitente, Documento, número de emisión), «Documento recibido» y la revisión de visto bueno. Las iniciales de las personas («Elaborado por», «Firmado por») conservan su avatar redondo. Las filas de Referencias (ReferenceListCard, usada en «Documento recibido» y la revisión de visto bueno, y la tarjeta del formulario) siguen el mismo criterio: ícono de documento solo, en gris suave de 18 px, sin recuadro. Propuesta aprobada: A, solo ícono en gris suave (mockup comparado con B, color de marca).