Sistema transaccional georreferenciado sobre el mismo stack que ANAAR ya opera en
producción: Node + TypeScript, Express, Sequelize sobre MySQL 8, React 19 y Cloud Run. Control de acceso
por permisos modulo:accion, auditoría persistida, canal conversacional sobre WhatsApp Business
Platform y API pública de consulta. Un dominio, una API, N vistas con scope diferenciado.
dev / test separadostsc; ts-node-dev en desarrollosequelize-cli para migracionesmysql2equipo_dea y espaciovalorAnterior / valorActual por campo afectadocloudbuild.yaml por ambiente; despliegue reproducible| Decisión | Consecuencia |
|---|---|
| Se extiende el backend vigente de ANAAR | El modelo de Usuario, Rol, Permiso, RolPermiso y Auditoria ya existe y está en producción. La red se incorpora como módulos nuevos sobre ese núcleo, no como sistema paralelo. |
| Geo nativo en MySQL 8 | Ubicación como POINT con SRID 4326 e índice SPATIAL. Proximidad, estado operativo y ventana de acceso se resuelven en un solo JOIN: un plan de ejecución, sin sincronizar almacenes. |
| Monolito modular | Límites por módulo con contratos internos explícitos. Transacción única sobre padrón y auditoría: sin consistencia eventual en el dato del que depende un despacho. |
| Escritura conversacional, lectura web | El técnico y el declarante no ven formularios: el canal es WhatsApp. El backend expone los mismos casos de uso a ambas superficies. |
| API pública desacoplada del panel | Namespace /v1/publico con proyección reducida, cache de borde y rate limit propio. No comparte serialización con el panel: el dato sensible no se filtra por descuido. |
| Idempotencia en ingesta | Clave por mensaje entrante: el reenvío del proveedor no duplica inspecciones ni declaraciones. |
| Sistema | Protocolo | Sentido |
|---|---|---|
| WhatsApp Business Platform | Cloud API · webhooks | E/S |
| SIEN / línea 107 | REST + webhook de evento | S |
| ReNaDEAs nacional | export batch · superset | S |
| Pasarela de pagos | checkout + webhook | E/S |
| Geocoding y tiles | vector tiles · cache | E |
| Tecnovigilancia ANMAT | ingesta de recalls | E |
| Organismos terceros | API key + scope público | S |
| Telemetría de fabricante | campo origen_estado | E |
Los ocho puntos se implementan contra una capa de adaptadores con contrato propio, timeout,
circuit breaker y reintento con backoff. Ninguna caída de un tercero degrada la escritura del padrón.
axios para REST, fast-xml-parser donde el tercero responde XML.
Ambientes: producción y testing ya existen y están separados en Cloud Run, con pipeline
de Cloud Build por ambiente: no hay que montar infraestructura, se extiende la que está corriendo.
Pipeline: lint (ESLint) → tipos (tsc) → build de imagen → migración sequelize-cli
→ despliegue → verificación. Evidencia: validada por file-type, normalizada con
sharp, almacenada en Cloud Storage con retención por tipo de objeto y el registro de auditoría
fuera del ciclo de purga.
Comparten modelo de datos, API, motor de permisos y auditoría; no comparten proyección, rate limit, cache, bundle por rol ni MFA. Fuera de alcance: app móvil descargable, hardware o señalética, desarrollo del lado de terceros, prestación del mantenimiento, capacitación y sensores.
modulo:accion · scope :leer_propios vs :leer_todos| Permiso | Autoridad de aplicación |
ANAAR / fundación |
Responsable de espacio |
Prestador mantenim. |
Técnico en campo |
Operador 107 |
Instructor | Ciudadano anónimo |
|---|---|---|---|---|---|---|---|---|
| equipos:* | CRUD | CRU | RU* | RU* | R* | R* | — | R° |
| inspecciones:* | R | R | R* | CRUD* | CR* | — | — | — |
| alertas:* | RU | R | R* | RU* | — | — | — | — |
| despacho:consultar | R | — | — | — | — | RC | — | — |
| personas:leer_datos_contacto | R | R | RU⁺ | R* | — | R* | R* | — |
| usuarios:* · roles:* | CRUD | CRU* | — | CRU* | — | — | — | — |
| auditoria:leer | R | R* | R* | R* | — | — | — | — |
:leer_propios — por zona, espacio o contrato
°proyección pública
⁺propio registro
Misma convención para insumos:*, evidencia:*,
donaciones:*, certificados:*, formacion:*, export:renadeas.
El scope se aplica en la consulta, no en la pantalla: el endpoint nunca devuelve la fila que la interfaz
oculta. La suite de autorización recorre rol × endpoint × scope en cada build.
| Perfil | Funcional | Técnico |
|---|---|---|
| Autoridad de aplicaciónPanel web | Cumplimiento por espacio obligado · cobertura y criticidad · parque por estado · exportación al registro nacional. Único rol con visión provincial completa. | GET /v1/tableros/cumplimiento?corte=&tipo= GET /v1/equipos?bbox=&estado=&vence_en= POST /v1/export/renadeas → ExcelJS equipos:leer_todos · MFA obligatoria |
| ANAAR / fundaciónPanel web | Padrón operativo · relevamiento y su embudo · donaciones con trazabilidad aporte → serie → equipo · rendición pública. Opera el programa; no tiene la potestad regulatoria. | GET /v1/donaciones/trazabilidad?serie= POST /v1/compras → imputa a aporte webhook de pasarela → conciliación idempotente donaciones:* · equipos:leer_todos |
| Responsable de espacioWeb + WhatsApp | Ficha y estado de sus equipos · alertas de vencimiento · certificados y constancia de cumplimiento · ventanas de acceso. Ve sus equipos y nada más. | equipos:leer_propios → espacio_id ∈ asignacionesGET /v1/equipos/{id}/certificados.pdf → PDFKit PATCH /v1/espacios/{id}/ventanas-acceso |
| Prestador de mantenimientoPanel web | Hoja de ruta y visitas · SLA por técnico y por zona · cola de no conformidades · ABM de técnicos propios. Gobierna su operación; el sistema lo audita a él. | GET /v1/rutas?tecnico=&fecha= GET /v1/sla?ventana=&agrupar=tecnico|zona POST /v1/tecnicos → credencial individual |
| Técnico en campoWhatsApp | Escaneo de QR · checklist adaptado al modelo · foto obligatoria con geolocalización · cierre con certificado. Cero instalación, cero formulario web. | Cloud API webhook → ingesta idempotente identidad por vinculación de número + token checklist server-driven según modelo_dea media → GCS firmado · file-type + sharp geo: ST_Distance_Sphere(equipo, punto) |
| Operador del 107misma plataformaVista web | Consulta por dirección o coordenada · DEA más cercano con estado operativo y accesibilidad en ese momento · custodio para el despacho · registro del evento. Sin navegación: una pantalla, una consulta, un resultado. | Mismo build de la SPA, ruta y scope propios GET /v1/despacho/cercano?lat=&lng=&abierto=1 índice SPATIAL · orden por ST_Distance_Sphere · ventana_acceso y estado en el mismo JOIN POST /v1/despacho/evento → alerta de reposición despacho:consultar · custodio auditado |
| InstructorevolutivoPanel web | Cohortes, cupo y asistencia · evaluación práctica · emisión de credencial · banco de preguntas. Cierra el circuito que la parte en línea no puede cerrar. | formacion:leer_propios → cohorte_idPOST /v1/cohortes/{id}/evaluacion-practica credencial firmada + QR de verificación pública |
| Ciudadano · anónimoWeb pública | DEA más cercano con mapa, ruta, foto del frente, ubicación interna y horario · solicitud comunitaria · donación con rendición visible. Sin descarga, sin registro, sin fricción. | namespace /v1/publico · sin credencial proyección de lista blanca · sin datos personales cache de borde · rate limit por IP · widget en iframe |
Precisión de alcance: el acceso del 107 no es una aplicación dedicada: es una ruta más de la misma SPA, contra la misma API, con su permiso y su scope. El costo de esa vista es la consulta de proximidad y su política de acceso, no un producto paralelo.
| Rol | Producto concreto en este proyecto | Cuándo interviene |
|---|---|---|
| Arquitecto de software | Módulos y contratos sobre el backend vigente · modelo de datos y DER · esquema espacial e índices · auditoría · ambientes y pipeline. | Intervención concentrada en el arranque; revisión sostenida hasta el cierre |
| Líder de proyecto | Plan de fases · gestión de las seis dependencias de contraparte · coordinación con el SIEN y los organismos integradores · control de avance, riesgo y alcance. | Presencia sostenida durante todo el ciclo |
| Analista funcional | Especificación de los seis módulos · matriz de permisos rol × recurso · reglas de alertas y lead time · checklists por modelo · criterios de aceptación. | Fuerte al inicio, con retorno en cada aceptación |
| Marco normativo y datos personales | Encuadre en la Ley 3071 y el estándar nacional · tratamiento y retención de datos personales · valor probatorio de la auditoría · condiciones del comodato. | Entrada puntual: definición del modelo y su validación |
| Desarrollo | Backend Node/TypeScript sobre Express y Sequelize · frontend React del panel multi-rol y de la web pública · jobs de alertas · adaptadores de las ocho integraciones. | Núcleo de la construcción, con especialidades en paralelo |
| Diseño de experiencia conversacional | Dos flujos de WhatsApp: relevamiento declarativo y mantenimiento en campo · árboles de diálogo, validaciones y recuperación de error · plantillas de notificación. | Dos tramos: relevamiento primero, mantenimiento después |
| Diseño de experiencia de aplicación | Arquitectura de información por rol · componentes accesibles WCAG 2.1 AA · pantalla de DEA más cercano y vista de despacho optimizadas para urgencia · tableros y widget. | Siempre por delante de cada fase de construcción |
| QA | Plan de pruebas por módulo · suite de autorización rol × endpoint × scope · E2E de los flujos críticos · pruebas conversacionales sobre dispositivo real. | Desde el primer módulo, con picos en integración y puesta en marcha |
Ningún perfil está a tiempo completo durante el ciclo. Cada especialidad entra donde su competencia hace falta y sale cuando termina de aportarla: el arquitecto define y se corre, el analista especifica y vuelve en la aceptación, el desarrollo sostiene la construcción, QA acompaña desde el primer módulo.
La disponibilidad se reserva y tiene costo aunque la dedicación sea parcial. El tramo en que un arquitecto tiene que estar disponible se paga a valor de arquitecto, y lo mismo cada una de las otras siete especialidades. Son ocho disciplinas distintas, no una persona haciendo de todo: es la condición para que la arquitectura, el encuadre normativo, la experiencia y la calidad estén resueltos por quien corresponde.