Organizaciones y sincronizacion external sync

Esta guia describe el modulo vigente de organizaciones en v3.0. El contenido fue contrastado contra la UI administrativa, las validaciones Wicket, ExcelUtils, la logica EJB de altas/cargas/sincronizacion y los procesos asincronos que actualizan organizaciones desde archivos o desde un servicio externo de sincronizacion.

Ubicacion en el flujo

  • La pantalla de organizaciones esta montada en /admin/election/organizations.
  • En el wizard de gestion vuelve a Convocatoria y continua hacia Padron.
  • Si la eleccion esta cerrada, la UI deriva a Eleccion cerrada y no permite edicion.
  • El comportamiento depende de manageOrganizationsManual. Todas las elecciones nuevas comienzan en modo manual y pueden cargar organizaciones y deudores por XLSX. Cualquier organización puede habilitar el modo automático si implementa el contrato HTTP descrito en esta guía; no se requiere MiLACNIC ni un servicio de LACNIC.

Reglas base del modulo

  • La identidad operativa del modulo es ORGID. Listados, cargas masivas, sincronizaciones y borrados reconcilian organizaciones por ORGID normalizado a mayusculas.
  • La tabla de organizaciones no expone una edicion manual de filas existentes. En modo manual hoy se puede agregar, cargar por Excel, eliminar y regenerar links.
  • Los estados member y deudor tienen impacto real aguas abajo: el padron automatico solo toma organizaciones con member=true, deudor=false y datos de contacto completos.
  • Mientras exista un proceso asincrono de organizaciones para esa eleccion, la pantalla bloquea cargas y acciones operativas, muestra el progreso y luego expone cualquier error de la corrida.

Alta manual individual

La tarjeta Agregar organizacion solo aparece cuando la eleccion se gestiona con manageOrganizationsManual=true y no hay procesamiento en curso.

  • El formulario actual pide Nombre, Org ID, Pais, Categoria, Votos, ASN, CNPJ, ID contacto, Nombre contacto, Email contacto e Idioma contacto.
  • Nombre, Pais, Categoria, Votos, ID contacto, Nombre contacto, Email contacto e Idioma contacto son obligatorios en la UI.
  • Votos debe ser entero entre 1 y 11. Pais debe ser ISO-2 valido. Org ID, si se informa manualmente, debe comenzar con letra o numero y solo admite letras, numeros, ., - o _.
  • ASN y CNPJ son opcionales y hoy se almacenan como texto; la UI solo limita largo maximo.
  • Org ID es un caso especial: en la UI puede dejarse vacio. Si llega vacio al backend, el EJB genera un UUID, lo normaliza a mayusculas y ese valor pasa a ser la identidad estable de la organizacion.
  • Al alta manual el backend genera doNominationToken si falta, deja member=true cuando no viene informado y persiste la organizacion con deudor=false por defecto.
  • Agregar una organizacion no marca automaticamente organizationsSet=true. Esa bandera se maneja aparte con el boton de completitud del wizard.

Listado y acciones operativas

  • La tabla muestra resumen de organizaciones listadas, no deudoras, miembros y miembros no deudores.
  • Los filtros actuales permiten buscar por ORGID, nombre, CNPJ, ASN, membershipContactId y membershipContactName; ademas pueden combinarse pais, votos, miembro, deudor e idioma de contacto.
  • La exportacion del listado genera un Excel con el mismo set de columnas de la carga alta/actualizacion.
  • Las filas de organizaciones deudoras se resaltan visualmente en rojo.
  • Cada fila permite ver el link de nominacion, ver los links de apoyo emitidos por esa organizacion como supporting organization y regenerar el token individual de nominacion.
  • El boton de eliminar por fila solo aparece en modo manual y se bloquea si la organizacion ya tiene nominaciones o apoyos asociados.

Cargas masivas en modo manual

La zona de cargas manuales aparece solo con manageOrganizationsManual=true. Los tres archivos usan exclusivamente .xlsx y se procesa solo la primera hoja.

Alta y actualizacion por Excel

Columna Obligatoria Regla efectiva
ORGIDSiDebe venir informado, ser unico dentro del archivo y respetar el patron del sistema.
NAMESiNo admite vacio.
VOTESSiDebe ser entero entre 1 y 11.
CATEGORYSiDebe ser una categoria vigente del sistema.
COUNTRYSiDebe ser un codigo ISO de 2 letras.
CNPJNoSe persiste como texto si viene informado.
ASNNoSe persiste como texto si viene informado.
MEMBERSHIPCONTACTIDSiNo admite vacio.
MEMBERSHIPCONTACTNAMESiNo admite vacio.
MEMBERSHIPCONTACTEMAILSiValida formato basico de email.
MEMBERSHIPCONTACTLANGUAGESiSolo acepta SP/ES, EN o PT.
  • Sin marcar Sobreescribir completamente las organizaciones, la carga solo crea filas nuevas o actualiza filas existentes por ORGID. No elimina las organizaciones que no esten en el Excel.
  • Marcando ese check, la operacion pasa a ser snapshot: despues de crear/actualizar, elimina las organizaciones actuales cuyo ORGID no venga en el archivo.
  • Antes de eliminar por snapshot, el backend valida que ninguna organizacion a borrar tenga nominaciones o apoyos. Si una sola esta bloqueada, se rechaza toda la corrida.
  • La carga conserva los tokens de nominacion ya existentes y no modifica el estado deudor. Solo las filas nuevas reciben token nuevo.
  • Si el parser detecta errores de filas, la UI no encola la corrida y habilita la descarga de un reporte XLSX con el detalle de errores.

Archivo de organizaciones deudoras

  • Este archivo usa una sola columna obligatoria: ORGID.
  • Sin marcar Sobreescribir completamente los deudores actuales, la corrida solo marca deudor=true para las organizaciones listadas. No limpia deudores previos.
  • Marcando ese check, primero limpia deudor=false en todas las organizaciones actualmente deudoras y luego vuelve a marcar como deudoras solo las listadas en el Excel.
  • La operacion valida que todos los ORGID existan en la eleccion. Si falta alguno, la corrida completa se rechaza.
  • Este proceso no crea, no elimina y no toca otros campos de la organizacion.

Borrado por Excel

  • El archivo de borrado tambien usa una unica columna obligatoria: ORGID.
  • Antes de encolarlo, el backend valida que todos los ORGID existan y que ninguna de las organizaciones listadas tenga nominaciones o apoyos.
  • Si la validacion pasa, se eliminan exactamente las organizaciones listadas. No es snapshot ni afecta las no incluidas.

Modo automatico desde external sync

Cuando manageOrganizationsManual=false, la pantalla deja de mostrar alta manual y uploads. En su lugar muestra el estado de la ultima corrida automatica, el historial de sincronizaciones y los controles disponibles dentro de la ventana de calendario N_23_PERIODO_PADRON_MILACNIC_SYNC por compatibilidad historica.

  • La alerta superior informa fecha de ultima sincronizacion, estado, metricas y mensaje. Si nunca corrio, la pantalla lo deja explicito.
  • El boton Forzar sincronizacion de organizaciones solo se habilita cuando la eleccion esta dentro de la ventana N_23 y no hay otro proceso activo.
  • La corrida manual desde esta pantalla usa el sync completo de organizaciones sin regenerar masivamente los links de nominacion. Si una fila ya tiene token, lo conserva; solo genera token cuando falta.
  • El historial lista hasta 200 corridas y muestra fecha/hora, estado, metricas, duracion, datos del WS, syncRunId y mensaje. Al expandir una corrida se ven los cambios auditados.

Backend que debe implementar el cliente

Para usar organizaciones y padron en modo automatico, la organización operadora debe exponer un servicio HTTP de consulta que entregue el snapshot vigente de sus organizaciones. El scheduler ya esta incluido en Elecciones: el backend externo no debe implementar otro cron ni invocar periodicamente a Elecciones.

  • Metodo: GET sobre una URL absoluta http:// o, preferentemente, https://.
  • URL: se configura en MILACNIC_SYNC_ORGANIZATIONS_ENDPOINT_TEMPLATE. Puede contener {electionId}; Elecciones lo reemplaza por el identificador numerico de la eleccion antes de cada llamada.
  • Autenticacion: si se configura MILACNIC_SYNC_API_TOKEN, Elecciones envia el mismo secreto en Authorization: Bearer <token> y X-Auth-Token: <token>. El backend externo debe validar el token, usar HTTPS y no registrarlo en logs. El prefijo MILACNIC_SYNC_ se conserva únicamente por compatibilidad histórica.
  • Respuesta: debe devolver HTTP 2xx, Content-Type: application/json y el conjunto completo vigente, no solamente cambios incrementales.
  • Estabilidad: orgId debe ser estable, unico y conservarse entre corridas. Una organizacion miembro que desaparece del snapshot se marca localmente como member=false.

Contrato JSON recomendado

{
  "organizations": [
    {
      "orgId": "ORG-001",
      "name": "Organizacion de ejemplo",
      "votes": 1,
      "category": "isp-small-ipv4",
      "country": "UY",
      "cnpj": null,
      "asn": "AS12345",
      "membershipContactId": "CONTACT-001",
      "membershipContactName": "Nombre Apellido",
      "membershipContactEmail": "contacto@example.org",
      "membershipContactLanguage": "SP",
      "debtor": false
    }
  ]
}

Tambien se aceptan un array en la raiz, {"data": [...]}, {"data":{"organizations": [...]}} o {"items": [...]}. Se recomienda usar los nombres canonicos del ejemplo. El parser admite aliases en snake_case, pero no deben usarse como contrato nuevo.

CampoRequeridoUso
orgIdSiIdentidad de reconciliacion. Debe ser unica dentro del snapshot.
nameSiNombre visible de la organizacion.
votesPara padron automaticoCantidad de votos que tendra el representante.
membershipContactNamePara padron automaticoNombre del votante generado para organizaciones elegibles.
membershipContactEmailPara padron automaticoEmail del votante generado.
membershipContactLanguageRecomendadoSP/ES, EN o PT; si falta, el padron usa SP.
debtorRecomendadoBooleano que determina si la organizacion queda excluida del padron automatico.
category, country, cnpj, asn, membershipContactIdNoDatos complementarios; country debe ser ISO-2 cuando se informe.

Activacion y prueba de aceptacion

  1. Implementar el endpoint y comprobar que responde un snapshot valido con HTTP 2xx.
  2. Configurar MILACNIC_SYNC_ORGANIZATIONS_ENDPOINT_TEMPLATE, MILACNIC_SYNC_API_TOKEN y umbrales MILACNIC_SYNC_* acordes al volumen real del cliente.
  3. Configurar la ventana N_23_PERIODO_PADRON_MILACNIC_SYNC en la eleccion.
  4. Usar manageOrganizationsManual=false; para generar tambien el padron, usar manageVotersManual=false.
  5. Ejecutar Forzar sincronizacion de organizaciones y verificar la corrida, sus metricas y auditoria. Luego forzar el padron y confirmar que solo entren miembros no deudores con contacto y votos completos.

En operacion normal, Elecciones ejecuta el proceso combinado cada dos horas y solo procesa elecciones abiertas que esten dentro de la ventana N_23. Primero actualiza organizaciones desde el backend del cliente y despues recalcula el padron desde esas organizaciones locales.

Reglas efectivas del sync completo

  • Solo corre para elecciones abiertas y en gestion automatica. Si la corrida fue lanzada desde esta pantalla, ademas exige estar dentro de N_23.
  • La fuente remota se resuelve desde MILACNIC_SYNC_ORGANIZATIONS_ENDPOINT_TEMPLATE y el token desde MILACNIC_SYNC_API_TOKEN. El prefijo se conserva por compatibilidad con la configuracion previa. Si el endpoint no esta configurado, la sincronizacion se omite y no se consulta ningun servicio remoto.
  • Antes de aplicar cambios, el backend valida umbrales configurables: minimo de organizaciones recibidas, minimo/maximo de deudoras, minimo de organizaciones de Brasil y maximo de desactivaciones de member.
  • Si el payload remoto trae ORGID duplicados o queda por debajo de esos umbrales, la corrida termina en error y no aplica cambios.
  • Las organizaciones nuevas se crean con datos remotos, member=true, deudor segun el payload y un doNominationToken nuevo.
  • Las organizaciones existentes se actualizan en nombre, votos, categoria, pais, CNPJ, ASN y datos de contacto si el payload trae valores para esos campos. Si la fila reaparece en external sync y estaba con member=false, vuelve a member=true.
  • La ausencia en external sync no elimina la organizacion local. El efecto real es dejar member=false para las organizaciones que antes eran miembros y ya no aparecen en el payload.
  • El sync completo no sube automaticamente deudor=true en organizaciones existentes. En la implementacion actual solo limpia deudor cuando una organizacion ya marcada como deudora vuelve desde external sync con deudor=false.

Acciones avanzadas

  • Actualizar estado de deudor desde external sync: usa el mismo WS, pero solo sincroniza el campo deudor para organizaciones ya existentes. Si external sync informa deudor=true, lo marca; si la organizacion no aparece o viene con deudor=false, queda como no deudora. No crea, no elimina y no modifica otros datos. Solo esta disponible en gestion automatica, dentro de N_23 y con organizaciones cargadas.
  • Regenerar links de nominacion: genera nuevos tokens para todas las organizaciones actuales sin ejecutar una sincronizacion.
  • Regenerar links de apoyo: genera nuevos tokens de apoyo para las organizaciones que hoy tienen links de apoyo emitidos.
  • Eliminar completamente las organizaciones: borra todas las organizaciones actuales y deja organizationsSet=false. No esta disponible si ya existen nominaciones.
  • Todas estas acciones corren en segundo plano y quedan deshabilitadas mientras exista otro proceso activo.

Relacion con el padron automatico

  • Si la eleccion usa padron automatico, el modulo de padron toma como fuente inmediata a las organizaciones ya guardadas localmente, no al WS directamente.
  • Solo generan votante automatico las organizaciones con member=true, deudor=false, ORGID, membershipContactName, membershipContactEmail y votes.
  • Por eso, cambios en member, deudor, votos o datos de contacto dentro de organizaciones impactan directamente en el siguiente recalculo del padron.

Completitud y navegacion

  • Atras: vuelve a Convocatoria.
  • Continuar despues: navega a Padron sin marcar organizaciones como completadas.
  • Marcar como terminada y seguir: solo deja organizationsSet=true y navega a Padron. La implementacion actual no valida que exista al menos una organizacion cargada ni que una sincronizacion automatica haya corrido.

Siguiente modulo

Despues de organizaciones, el wizard continua en padron.

  • Padron: cargue, sincronice y mantenga votantes desde esta guia.

Fuentes contrastadas

ElectionsManagerApp, ElectionOrganizationsDashboard, ElectionOrganizationsForm, AddOrganizationPanel, OrganizationsListPanel, UploadOrganizationsDebtorsFilePanel, AutomaticOrganizationsSyncActionsPanel, OrganizationsAdvancedActionsPanel, OrganizationDeleteActionValidator, OrganizationBulkDeleteActionValidator, OrganizationExcelFileValidator, OrganizationValidationRules, ExcelUtils.processOrganizationsDebtorsExcel, ExcelUtils.processOrganizationsUpsertExcel, ExcelUtils.exportOrganizationsUpsertToExcel, ElectionsManagerEJBBean.addOrganization, upsertOrganizationsFromExcel, removeOrganizationsFromExcel, updateOrganizationsDebtors, validateOrganizationsDeleteCanBeApplied, validateOrganizationsUpsertOverwriteCanBeApplied, validateOrganizationsDebtorsCanBeApplied, executeMilacnicSyncForElection, syncOrganizationsForElectionFromMilacnic, executeMilacnicDebtorMirrorSyncForElection, syncOrganizationsDebtorMirrorForElectionFromMilacnic y ElectionsManagerApp.properties.xml.