{"id":"ARCHITECTURE_DECISIONS","title":"Decisiones de arquitectura","version":"nav88-20261106-v1","date":"2026-11-06T13:00:28.120741+01:00","classification":"PUBLIC_REVIEW","sha256":"ede1138aab286f5045f1f3895331afa9a0da36a841e8bc3e4d81949983d5d4ab","read_url":"/api/review/ARCHITECTURE_DECISIONS","total_bytes":13263,"fragment_count":1,"document_sha256":"ede1138aab286f5045f1f3895331afa9a0da36a841e8bc3e4d81949983d5d4ab","fragmented":false,"content_markdown":"# ARCHITECTURE_DECISIONS\n\n## Etapa D - decisiones\n\n- Adaptador del proveedor sobre casos de uso y repositorio genericos.\n- Se conserva la identidad por cuenta/familia/entorno; no se hereda UID de TEST.\n- Dos barreras de release independientes y cerradas, sin desbloqueo web.\n- Un ACK de creacion no es tracking: timestamp separado y evento local ACK.\n- Recibo cifrado antes de interpretar; replay local, nunca retry de GrabaServicios.\n- Escritura HTTP parcial es incierta, no ausencia demostrada de transmision.\n- Centros N:M por cuenta, direccion cifrada y snapshot de revision en borrador.\n- Trabajador de conocidas sin enumeracion; una ejecucion acotada sin scheduler.\n- Pausar conserva la llamada en curso y detiene antes del siguiente elemento.\n- Respuesta recibida es recuperable tras reinicio sin consumir otra llamada.\n- Importador es administrativo/temporal, manual, pausado y de cobertura parcial.\n- Seis areas de navegacion no sustituyen las comprobaciones de permiso reales.\n- Se conserva el aislamiento de red/UID del servicio 80 hasta nueva autorizacion.\n- No se aclara una incidencia multiple mediante inferencia global de SOLUCION.\n\n## Decisiones historicas\n\n## ADR C01 - canal JSON sin ampliar privilegios\n\nEl runtime 85 sigue siendo un paquete minimo de libreria estandar, sin BD,\ncredenciales, clientes GLS ni ejecucion de comandos. JSON se construye solo\ndesde el manifiesto y los Markdown sanitizados fijados por hash del release.\nNo se publica el arbol docs original ni se aceptan rutas arbitrarias.\n\nRespuesta individual: id, title, version, date, classification, sha256,\ncontent_markdown. El hash corresponde a bytes UTF-8 del Markdown completo,\nno al JSON serializado. Index y bundle conservan esos metadatos.\n\nLimites: JSON 1 MiB, documento completo preferido hasta 512 KiB, fragmentos\nUTF-8 de hasta 64 KiB y ocho documentos por bundle. No se corta una secuencia\nUTF-8. Cada fragmento tiene indice, offset, longitud y SHA; el documento\nmantiene hash total. Si el bundle no cabe, 413 y URLs individuales; no se\ndevuelve un subconjunto como si fuese completo.\n\n## ADR C02 - operativa y administracion separadas\n\n80 ofrece solo operativa local autenticada; 88 conserva administracion,\ndiagnosticos y laboratorio. Se comparte usuarios, PostgreSQL y servicios;\nno se crea otra administracion ni un repositorio paralelo.\n\nCookie y audiencia de 80 distintas de 88. Usuario activo y rol se consultan\nen cada acceso; la version de usuario invalida sesiones tras cambios.\nCSRF tambien en login, cookies HttpOnly/SameSite y expiracion. Login con\nlimitacion de fallos. No se registran passwords, consultas de destinatario\nni URLs completas en el access log operativo, que esta desactivado.\n\nEl servicio 80 se vincula solo a la IP LAN. Se configura IPAddressDeny any\ny allow para LAN/localhost, sin cambiar proxy ni abrir publicacion externa.\nUID y laboratorio quedan inaccesibles en su namespace de filesystem.\nSigue usando el usuario de aplicacion existente; separar un rol PostgreSQL\noperativo mas fino puede abordarse despues, sin presentar esto como un\naislamiento completo de usuarios Unix/BD entre 80 y 88.\n\n## ADR C03 - simulacion no es TEST GLS\n\nLa simulacion LOCAL no usa UID TEST ni PRODUCCION y no contacta endpoint.\nCuenta, transportista, namespace y data_mode propios evitan que identificadores\ninventados aparezcan como expediciones reales. Se preserva la cuenta GLS\nprevista en el borrador/snapshot, no se utiliza para transmitir.\n\nLa respuesta sintetica se procesa con el parser existente y se persiste por\nel mismo coordinador de intento unico. Tiene su presupuesto local; no se\nregistra como llamada externa ni se mezcla con historicos GLS.\nLa etiqueta generada lleva SIMULACION y no tiene barcode operativo.\n\n## ADR C04 - borradores, confirmacion e idempotencia\n\nPK interna UUID. Payload cifrado. Creacion idempotente por usuario y clave;\nedicion por revision compare-and-set. Solo propietario o admin; escritura\nsolo admin/operador. Revisar datos guardados antes de confirmar.\n\nEl borrador y la operacion se vinculan en una transaccion. Snapshot de negocio\ny XML con UID REDACTED quedan cifrados antes de la simulacion. Intento unico,\nrespuesta cifrada previa al commit y replay local reutilizan etapa B.\nNo se reenvia un resultado ambiguo. Un fallo de cuota anterior a cualquier\nclaim se cierra como not_sent con cero intentos y permite una nueva revision\nmanual; no se confunde con reintentar un alta enviada.\n\nEl endpoint real permanece 423 incluso si alguien modifica flags internos.\nActivar operaciones reales requiere revision/autorizacion y conectar el\nsender real validado; no basta con quitar disabled en el navegador.\n\n## ADR C05 - buscar no es sincronizar\n\nSolo PostgreSQL. Fecha operativa shipment_date, sin inventar fechas ausentes.\nFiltros combinables y paginacion ordenada fecha/id. Estados COD/incidencia\ndesconocidos no equivalen a false. Comodines de texto se tratan literalmente.\nLa ficha ofrece cronologia y documentos ya almacenados, sin llamadas GLS.\nEl inventario activo puede estar vacio: no se afirma cobertura historica.\n\n## ADR C06 - preparacion administrativa revisable\n\nImportador solo 88, texto pegado, candidatos tipados, otra agencia/ambiguos\napartados, revision firmada de 15 minutos y seleccion explicita hasta 25.\nCoincidir agencia no demuestra pertenencia al cliente. No se conserva el\ntexto original con posibles datos personales, solo candidatos revisados\nen payload cifrado. El job queda pausado, parcial y deduplicado.\n\nPreparar actualizacion/POD tampoco ejecuta un worker. Los jobs conocidos\nson acotados y reutilizan leases/checkpoints. No hay barridos ni XML\nespeculativo para GetEnvios. Las politicas de cuota se editan en 88 sin\nllamadas; el limite oficial no acreditado no se inventa.\n\n## ADR C07 - inventario antes de reorganizar\n\nSe conservan las 21 entradas del menu principal. Las nuevas herramientas\nse enlazan secundariamente desde Plataforma. ADMIN88_INVENTORY describe\n90 rutas y 36 plantillas, incluidos placeholders y legacy. La propuesta de\nseis areas es documental y no modifica URLs ni elimina capacidades.\n\n## Registro historico: etapa B\n\n## ADR B01 - un repositorio y cuentas explicitas\n\nSe extienden las entidades existentes en PostgreSQL. Cuenta y entorno son\nparte de la identidad, no atributos intercambiables de una URL. Una cuenta\napunta al secreto mediante referencia; no contiene UID, password ni token.\nLos identificadores del proveedor no son PK internas y se guardan como texto.\nNo se atribuyen expediciones de otra agencia a la cuenta actual.\n\n## ADR B02 - evidencia, observacion y proyeccion\n\nLa evidencia original cifrada es diferente de la observacion normalizada y\nde la proyeccion actual de shipment. La observacion conserva fecha capturada,\nfuente y hash; el replay reutiliza esa fecha. Una observacion antigua no pisa\nla proyeccion mas reciente. Los acontecimientos se conservan y versionan:\nun mismo codigo en dos momentos no es necesariamente un duplicado.\n\nLos nombres/codigos postales minimos de busqueda son privados en BD; las\ndirecciones y detalles completos se cifran. No se publican expediciones en\n85. La autorizacion de acceso a datos y su retencion se aplicaran en las\npantallas de etapa C; la nueva pantalla administrativa solo muestra totales.\n\n## ADR B03 - estados no equivalentes\n\nSe separan estado administrativo, ciclo de vida, resultado y terminalidad.\nUn cierre no prueba entrega; una anulacion administrativa no demuestra\ntracking operativo; devolucion en curso no equivale a devuelto al remitente.\nLos codigos GLS conservan namespace y valor original. El nucleo admite\notros transportistas sin compartir indebidamente las tablas de maestros GLS.\n\n## ADR B04 - creacion de un solo intento\n\n1. Borrador de negocio cifrado e idempotency_key persistidos localmente.\n2. Diario privado cifrado preparado y fsync previo al posible efecto externo.\n3. Reserva de cuota y claim compare-and-set; attempts solo puede ser 0 o 1.\n4. Marcador de dispatch duradero y una unica invocacion al sender.\n5. Recibo original cifrado guardado antes de interpretar o hacer commit.\n6. Ingesta de shipment/eventos y finalizacion de operation en una transaccion.\n\nSi falla el commit, el recibo permite replay local, sin red. Si falla el\nfichero de recibo, se intenta conservar una copia cifrada en BD. Si faltan\nambos, permanecen la intencion y el marcador: requiere conciliacion manual,\nno repeticion. Ninguna arquitectura local garantiza reconstruir un recibo\nque se perdio simultaneamente en red, disco y BD.\n\nUn timeout no demuestra que GLS no haya creado el envio. Se mantiene el\nconsumo incierto y el bloqueo de reenvio. Solo una prueba de no transmision\npermite devolver la reserva. El contador de peticiones confirmadas no se\nfabrica cuando se desconoce si hubo envio.\n\nLa futura recuperacion por identificador/referencia se preparara conforme\nal contrato de cada conector, con permiso y cuota propios; no se ejecuta\nautomaticamente desde el replay.\n\n## ADR B05 - trabajos y reintentos solo de lectura\n\nReutilizar synchronizations con lease, prioridad y checkpoint por item.\nNo instalar worker en esta fase. La cola solo acepta refresh_known,\nmanual_import y pod_fetch. Las creaciones ambiguas nunca entran en una cola\nde reintentos. Los trabajos reanudados conservan items ya procesados y\ncoverage parcial/completa explicita; parcial no se presenta como completo.\n\n## ADR B06 - cuotas compartidas, no consumo inventado\n\nLas reservas se aplican a todos los ambitos requeridos en una transaccion,\ncon locks ordenados y clave idempotente. El presupuesto habitual es 50 %\ndel oficial conocido; el limite interno puede ser mas estricto. Si no hay\ncuota acreditada se exige limite interno, rotulado como tal.\n\nLa reserva se protege para prioridades interactivas. Solo una excepcion\ncritica con permiso, motivo, vencimiento y coste acotado permite superar\npresupuesto/horario interno. Nunca salta el limite del proveedor. 429 crea\ncooldown, no un bucle de reintentos. El reset calendario oficial solo se\nusa si esta verificado; por defecto ventana movil conservadora.\n\nLa cuota puede ser compartida por credencial/familia y varias cuentas sin\nduplicar el secreto. El consumo legacy sin cuenta se imputa conservadoramente\na los ambitos compatibles. Integrar todos los clientes legacy y acordar\nsus ambitos reales es condicion previa a afirmar control global efectivo.\n\n## ADR B07 - siguiente etapa y ausencia de efectos\n\nEl coordinador no trae un sender GLS conectado. Tres barreras locales:\nactivacion del componente, interruptor global y flags de cuenta. Por defecto\ntodo esta inactivo. No se modifican permisos ni comportamiento del laboratorio\nprevio, que sigue siendo una herramienta distinta hasta su integracion.\nNo se inicia 80 ni Cerrar dia. El contrato de cierre sigue pendiente.\n\n## ADR B08 - publicacion coordinada\n\nEl control administrativo y la publicacion usan un bloqueo compartido.\nUna actualizacion expresamente autorizada puede conservar el interruptor\nactual al aprobar el hash del release nuevo. Si el operador lo apaga, se\nrespeta. Una combinacion incompleta de politica/estado falla cerrada con\n503. El proceso 85 conserva su aislamiento, allowlist y hashes fijos.\n\n## Registro historico: decisiones A\n\nLas decisiones de etapa A se conservan a continuacion como historial.\nLa aprobacion de un release nuevo se coordina ahora por ADR B08; no se\nhereda habilitacion por el mero hecho de copiar archivos.\n\n## ADR A01 - publicacion separada\n\nPuerto 85 sirve copias revisadas, no el arbol original. El runtime se instala\ncomo paquete minimo separado, usuario dedicado y filesystem de solo lectura.\nSe impide connect mediante el aislamiento del servicio; no usa PostgreSQL,\ncredenciales, cliente GLS, ejecucion de documentos ni formularios.\n\n## ADR A02 - publicacion autorizada y fail-closed\n\nLista explicita de documentos, formatos pasivos, revision de datos personales,\ncomparacion contra inventario real de secretos, validacion estructural JSON/HTML\ny hashes fijados en politica propiedad de root. No hay descubrimiento automatico\nde nuevos documentos privados. Las imagenes exigen revision visual expresa.\n\nLos archivos aprobados se copian a una release independiente. Los originales\nno se modifican. El usuario del servicio publico no puede cambiar ni los\narchivos ni su politica. No basta con pasar unas expresiones regulares.\n\n## ADR A03 - control inmediato\n\nEl estado se lee en cada peticion; una sustitucion atomica controla nuevas\nsolicitudes sin reiniciar. Una nueva release no hereda habilitacion de otra.\nTodos los resultados HTTP llevan no-store; no hay ETag/304 ni cache de contenido.\nUn proxy que ignore estas cabeceras debe configurarse expresamente sin cache.\n\nNo es posible retirar una copia que alguien haya descargado mientras el\ncanal estaba habilitado; por eso solo se publica informacion autorizada.\nUna descarga que ya estaba en curso al deshabilitar no puede prometerse revocada.\n\n## ADR A04 - continuidad\n\nPuerto 88 conserva sus funciones; no se crea cuenta especial de Work.\nPuerto 80 y los servicios comunes se abordaran despues de este primer hito.\nPersistencia y cuotas compartiran PostgreSQL existente, sin nuevo repositorio.\nLa migracion pendiente no se registra para evitar su aplicacion al reiniciar.\n"}