# Cuenta Única Ciudadana: segunda versión

Consolidación de información para la segunda versión del proyecto de Cuenta Única Ciudadana

# Bitácora del proyecto

## Propósito de este documento

Este documento funciona como un registro vivo del proyecto CUC v2. Aquí se documenta todo lo que se ha construido hasta el momento, lo que está en progreso y lo que falta por hacer. La idea es que cualquier persona del equipo, o cualquier colaborador externo que se sume al proyecto, pueda entender rápidamente en qué punto estamos y hacia dónde vamos.

El documento está organizado por áreas de trabajo. Cada sección describe las tareas completadas, las que están en curso y las que quedan pendientes. Cuando una tarea se complete, se debe mover a la sección correspondiente y registrar la fecha.

## 1. Portal Ciudadano

Esta es la aplicación principal que usan los ciudadanos. Es un proyecto en Next.js 16 con App Router, integrado con ORY Network para la gestión de identidades y AWS Rekognition para la verificación biométrica.

### Lo que ya se hizo

El esqueleto de la aplicación está construido y funcional en ambiente de desarrollo. Se tomaron decisiones fundamentales de arquitectura que definen el rumbo del proyecto:

Se eligió Next.js 16 como framework principal, aprovechando el App Router y los React Server Components para tener una separación clara entre lo que se ejecuta en el servidor y lo que llega al navegador del ciudadano. Esta decisión se tomó porque Next.js permite renderizar las páginas en el servidor, lo que mejora tanto el rendimiento como el SEO, algo importante para un portal gubernamental que debe ser accesible desde cualquier dispositivo y conexión.

La integración con ORY Network está funcionando. Se implementaron los flujos de inicio de sesión, recuperación de contraseña, verificación de email y gestión de configuraciones del usuario, todos delegados a los componentes oficiales de ORY Elements React. Esto significa que no estamos reinventando la rueda en temas de seguridad: ORY maneja el almacenamiento de credenciales, la emisión de tokens OAuth 2.0 y los flujos de OpenID Connect.

El flujo de registro de tres pasos ya está implementado en su forma base. El primer paso valida la cédula del ciudadano contra la API del Registro Civil dominicano. El segundo paso recoge el correo electrónico y la contraseña. El tercer paso realiza la verificación facial usando AWS Rekognition Face Liveness, que compara el rostro en vivo del ciudadano con la foto almacenada en la base de datos de la Junta Central Electoral. Este cambio de orden respecto a la versión anterior (donde la verificación facial era el segundo paso) fue intencional: permite que el ciudadano complete la información de su cuenta antes de pasar por el proceso biométrico, reduciendo la frustración en caso de que necesite corregir datos.

Se configuró la internacionalización con next-intl, soportando español e inglés. Todas las cadenas de texto están externalizadas en archivos de traducción, lo que facilita agregar nuevos idiomas en el futuro.

El sistema de componentes UI está basado en shadcn/ui con Radix UI y Tailwind CSS. Esto nos da componentes accesibles por defecto (cumplen con ARIA) y un sistema de diseño consistente. Se implementó soporte para modo oscuro usando next-themes.

La validación de formularios usa Zod para esquemas de validación y React Hook Form para la gestión del estado de los formularios. Esto asegura que los datos se validen tanto en el cliente como en el servidor.

Se crearon las rutas protegidas del dashboard ciudadano: página principal, perfil, configuraciones, historial, soporte y acerca de. Aunque varias de estas páginas aún son esqueletos, la estructura de navegación y el sistema de protección de rutas (que verifica la sesión de ORY antes de permitir el acceso) están completos.

El pipeline de CI/CD está configurado con GitHub Actions para desplegar automáticamente a Google Cloud Run cuando se hace push a la rama staging. El Dockerfile usa una imagen base de Bun para builds rápidos y produce una imagen optimizada con el output standalone de Next.js.

Las API routes del servidor están implementadas para todo el flujo de registro: búsqueda de ciudadano por cédula, creación de cuenta, creación de sesión de liveness, verificación de resultado de liveness, y reset de sesión de registro. También están las rutas para gestión de sesiones de ORY (obtener sesión actual, revocar sesiones, logout).

### Lo que está en progreso

El diseño visual gubernamental está siendo refinado. Aunque la estructura está lista, se necesita pulir la experiencia visual para que se sienta institucional pero moderna. Esto incluye el landing page, las transiciones entre pasos del registro y la consistencia visual en todas las pantallas.

Se está trabajando en la gestión de errores. El código tiene manejo básico de errores, pero falta una estrategia unificada que cubra todos los escenarios: errores de red, timeouts de ORY, fallos de Rekognition, problemas con la cámara del dispositivo, etc. Cada error debe mostrar un mensaje claro al ciudadano y, al mismo tiempo, registrarse internamente para que el equipo de soporte pueda diagnosticarlo.

### Lo que falta por hacer

**Funcionalidades del Dashboard Ciudadano.** Las páginas del dashboard están creadas como esqueletos pero necesitan contenido real. La página de perfil debe mostrar la información del ciudadano extraída de los traits de ORY (nombre, cédula, fecha de nacimiento, género). La página de historial debe mostrar las sesiones activas y el historial de actividad. La página de configuraciones necesita permitir el cambio de contraseña, la activación de segundo factor de autenticación (2FA) y la gestión de preferencias de notificación.

**Sistema de Notificaciones (Buzón Ciudadano).** Esta es una funcionalidad completamente nueva que no existía en CUC v1. La idea es que los ciudadanos puedan recibir notificaciones dentro de su cuenta: avisos de seguridad, comunicaciones gubernamentales, alertas de actividad sospechosa, recordatorios de trámites pendientes, entre otros. Se necesita definir la arquitectura del sistema de notificaciones (almacenamiento, entrega en tiempo real vs polling, tipos de notificación), diseñar la interfaz del buzón, implementar la API de notificaciones y conectarla con el backoffice para que los agentes puedan enviar notificaciones.

**Agente de Inteligencia Artificial.** Se planea incorporar un agente conversacional que ayude a los ciudadanos a resolver dudas sobre su cuenta, guiarlos en procesos y, cuando no pueda resolver un problema, escalar a un agente humano de Atención Ciudadana. La tecnología aún está en evaluación. Se debe definir qué modelo de lenguaje usar, cómo integrarlo en la interfaz, qué conocimiento base necesita, cómo manejar la escalación a humanos y cómo garantizar que las respuestas sean precisas y no generen confusión en temas gubernamentales.

**Mejoras en la Verificación Facial.** El flujo básico funciona, pero hay escenarios que necesitan mejor manejo: qué pasa cuando el ciudadano no tiene cámara, cuando la iluminación es mala, cuando el navegador no soporta la API de MediaDevices, cuando el rostro no coincide pero el ciudadano insiste en que es él. Se necesita una estrategia de fallback y un proceso claro de escalación para estos casos.

**Gestión de Dispositivos y Sesiones.** ORY maneja las sesiones, pero el ciudadano necesita poder ver en cuántos dispositivos tiene sesión activa y poder cerrar sesiones remotamente. Esto ya se ve en el código como un endpoint de revocación de sesión, pero la interfaz para que el ciudadano lo use aún no está construida.

**Accesibilidad.** Aunque shadcn/ui y Radix UI proporcionan componentes accesibles por defecto, se necesita una auditoría completa de accesibilidad (WCAG 2.1 AA como mínimo) en todos los flujos. Un portal gubernamental debe ser usable por personas con discapacidades visuales, motoras o cognitivas.

**Pruebas Automatizadas.** No hay tests en el proyecto actualmente. Se necesita implementar pruebas unitarias para la lógica de negocio (validaciones, servicios), pruebas de integración para las API routes, y pruebas end-to-end para los flujos críticos (registro, login, recuperación de contraseña). Dado que es un sistema de identidad, las pruebas son fundamentales para evitar regresiones que puedan afectar a miles de ciudadanos.

**Documentación del Proyecto Open Source.** Si el proyecto será open source, necesita un README completo, guías de contribución (CONTRIBUTING.md), código de conducta (CODE\_OF\_CONDUCT.md), documentación de la API interna, y guías para que desarrolladores externos puedan levantar el proyecto localmente.

**Seguridad: Rate Limiting y Protección contra Abuso.** La versión anterior usaba reCAPTCHA y Cloudflare. En la nueva versión, se necesita definir qué mecanismos de protección se van a implementar: rate limiting en las API routes, protección contra fuerza bruta en el login (ORY tiene esto incorporado, pero hay que configurarlo correctamente), y protección contra bots en el registro.

**Monitoreo y Observabilidad.** La versión anterior usaba Sentry. Se necesita decidir si se continúa con Sentry o se migra a otra solución. Además, se deben implementar métricas de rendimiento (tiempos de respuesta, tasas de error), métricas de negocio (registros completados vs abandonados, pasos donde se pierden usuarios), y alertas automáticas cuando algo falle.

## 2. Backoffice

El backoffice es una aplicación separada, también en Next.js 16, que le da herramientas al equipo de Atención Ciudadana y a los administradores para gestionar las cuentas de los ciudadanos y darles soporte.

### Lo que ya se hizo

Se definió la arquitectura base en AWS: EventBridge recibe los eventos (webhooks) que emite ORY Network cada vez que ocurre algo relevante (un ciudadano se registra, inicia sesión, cambia su contraseña, falla un intento de login, etc.). Estos eventos son procesados por funciones Lambda que los transforman y almacenan en DynamoDB. Esta arquitectura permite escalar horizontalmente sin preocuparse por la infraestructura, ya que cada componente es serverless.

### Lo que está en progreso

Se está trabajando en el diseño y la implementación de la aplicación web del backoffice. Las funcionalidades principales que se están construyendo incluyen la búsqueda y visualización de cuentas ciudadanas, la capacidad de realizar acciones sobre las cuentas (bloquear, desbloquear, restaurar, eliminar), y la visualización de métricas en tiempo real.

### Lo que falta por hacer

**Dashboard de Métricas en Tiempo Real.** Los administradores necesitan poder ver: cuántos ciudadanos se han registrado hoy, esta semana, este mes. Cuáles son las integraciones OAuth más populares (qué servicios gubernamentales reciben más tráfico desde CUC). En qué paso del registro se quedan los ciudadanos que no completan el proceso. Cuáles son los errores más frecuentes. Cuántas sesiones activas hay en este momento. Todo esto debe alimentarse de los eventos que llegan a EventBridge y se procesan con Lambda.

**Gestión de Cuentas Ciudadanas.** Los agentes de Atención Ciudadana necesitan poder buscar un ciudadano por cédula, correo o nombre. Ver toda la información de su cuenta. Ver el historial completo de actividad (cada login, cada cambio de contraseña, cada error). Realizar acciones administrativas como resetear la contraseña, desbloquear la cuenta, verificar manualmente una identidad cuando el proceso biométrico falle.

**Trazabilidad Completa del Journey del Ciudadano.** Esta es una de las funcionalidades más ambiciosas. La idea es que cuando un ciudadano llame a soporte diciendo "intenté registrarme y no pude", el agente pueda ver exactamente qué pasó: el ciudadano ingresó su cédula a las 10:15am, la validación fue exitosa, pasó al paso 2, ingresó su correo, pasó al paso 3, la verificación facial falló con un error de iluminación insuficiente a las 10:18am, el ciudadano lo intentó de nuevo y falló por timeout a las 10:19am, y luego abandonó el proceso. Para lograr esto, se necesita que el portal ciudadano envíe eventos detallados de cada acción del usuario, no solo los eventos que ORY emite naturalmente.

**Sistema de Tickets y Escalación.** Cuando el agente de IA no pueda resolver un problema del ciudadano, debe crear un ticket que un agente humano pueda gestionar desde el backoffice. Se necesita diseñar el flujo completo: cómo se crea el ticket, qué información incluye, cómo se asigna a un agente, cómo se le da seguimiento, y cómo se notifica al ciudadano cuando su caso se resuelve.

**Envío de Notificaciones.** Los agentes deben poder enviar notificaciones a ciudadanos individuales o grupos de ciudadanos desde el backoffice. Estas notificaciones llegan al buzón ciudadano del portal. Se necesita definir los tipos de notificación, las plantillas, y quién tiene permisos para enviar qué tipo de notificación.

**Control de Acceso Basado en Roles (RBAC).** El backoffice tendrá diferentes tipos de usuarios: administradores con acceso total, agentes de Atención Ciudadana con acceso limitado a gestión de cuentas y soporte, y visualizadores que solo pueden ver métricas. Se necesita implementar este sistema de permisos.

## 3. Infraestructura y DevOps

### Lo que ya se hizo

El CI/CD del portal ciudadano está configurado con GitHub Actions desplegando a Google Cloud Run. El Dockerfile está optimizado con multi-stage builds usando Bun como runtime. Las variables de entorno están separadas correctamente entre las de build time (NEXT\_PUBLIC\_\*) y las de runtime.

### Lo que falta por hacer

**Ambientes de Desarrollo, Staging y Producción.** Actualmente solo hay configuración para staging. Se necesita definir y configurar los tres ambientes con sus respectivas variables de entorno, URLs de ORY, credenciales de AWS, y dominios.

**Infraestructura como Código.** Los recursos de AWS (EventBridge, Lambda, DynamoDB) y de GCP (Cloud Run, Artifact Registry) deben estar definidos en código, idealmente usando Terraform o AWS CDK para los recursos de AWS y Terraform para los de GCP. Esto permite replicar la infraestructura de forma determinística y mantener un historial de cambios.

**Monitoreo de Infraestructura.** Se necesitan dashboards de CloudWatch para los recursos de AWS y de Cloud Monitoring para Cloud Run. Alertas automáticas cuando hay errores, latencia alta, o recursos saturados.

**Dominio y SSL.** Definir cuál será el dominio de CUC v2 (si se mantiene cuentaunica.gob.do o se migra a algo bajo digital.gob.do), configurar los certificados SSL y la integración con Cloudflare o el servicio de protección DDoS que se elija.

**Backups y Recuperación ante Desastres.** Aunque ORY Network maneja las identidades en su infraestructura, se necesita una estrategia de respaldo para los datos en DynamoDB, los logs, y las configuraciones. También se necesita un plan de recuperación ante desastres que defina los tiempos máximos aceptables de inactividad (RTO) y de pérdida de datos (RPO).

## 4. Seguridad

### Lo que ya se hizo

ORY Network proporciona cifrado en tránsito (HTTPS/TLS 1.2+), cifrado en reposo (AES-256), hash seguro de contraseñas (bcrypt con salt), y tokens de sesión con expiración configurable. AWS Rekognition maneja los datos biométricos bajo los estándares de cumplimiento de AWS (SOC 2, ISO 27001). La validación de cédulas incluye verificación de formato y checksum.

### Lo que falta por hacer

**Auditoría de Seguridad.** Antes del lanzamiento, se necesita una auditoría de seguridad completa: revisión del código, pruebas de penetración, y verificación de cumplimiento con las normativas dominicanas de protección de datos.

**Política de Contraseñas.** Definir y documentar la política de contraseñas: longitud mínima, complejidad requerida, verificación contra bases de datos de contraseñas filtradas (ORY soporta esto con HaveIBeenPwned), y política de expiración.

**Segundo Factor de Autenticación (2FA).** ORY soporta TOTP (Google Authenticator, Authy) y WebAuthn (llaves de seguridad, biometría del dispositivo). Se necesita implementar la interfaz para que los ciudadanos puedan activar y gestionar su 2FA.

**Manejo de Datos Sensibles.** Documentar qué datos personales se almacenan, dónde se almacenan, quién tiene acceso, por cuánto tiempo se retienen, y cómo se eliminan cuando el ciudadano lo solicita. Esto es especialmente importante para un proyecto open source donde el código es público.

## 5. Experiencia de Usuario e Investigación

### Lo que falta por hacer

**Pruebas de Usabilidad.** Antes del lanzamiento, se deben realizar pruebas de usabilidad con ciudadanos reales: personas de diferentes edades, niveles de educación, y familiaridad con tecnología. El registro con verificación facial es un proceso que puede intimidar a muchas personas, y necesitamos asegurarnos de que las instrucciones sean claras y el proceso sea lo más sencillo posible.

**Optimización del Flujo de Registro.** Medir la tasa de abandono en cada paso del registro e identificar oportunidades de mejora. Si muchos ciudadanos abandonan en la verificación facial, tal vez necesitamos mejorar las instrucciones o el manejo de errores en ese paso.

**Soporte para Dispositivos de Gama Baja.** Muchos ciudadanos dominicanos usan dispositivos Android de gama baja con cámaras de baja resolución. Se necesita probar el flujo de verificación facial en estos dispositivos y ajustar los umbrales de confianza si es necesario.

**Página de Estado del Servicio.** Crear una página pública donde los ciudadanos puedan verificar si CUC está funcionando correctamente. Esto reduce la carga de soporte cuando hay interrupciones planificadas o incidentes.

## Resumen del estado actual

Para tener una vista rápida del progreso general:

El portal ciudadano tiene su estructura base completa, con los flujos de autenticación y registro funcionando en desarrollo. Las decisiones de arquitectura están tomadas y validadas. Sin embargo, falta completar las funcionalidades del dashboard, el sistema de notificaciones, el agente de IA, las pruebas automatizadas, y la auditoría de seguridad y accesibilidad.

El backoffice tiene su arquitectura AWS definida pero la aplicación web está en etapas tempranas de desarrollo. Las funcionalidades más ambiciosas como la trazabilidad completa del journey del ciudadano y el sistema de tickets requieren trabajo coordinado entre el equipo del portal y el del backoffice.

La infraestructura necesita madurar en cuanto a ambientes, infraestructura como código, monitoreo, y planes de recuperación ante desastres.

Este es un proyecto ambicioso, y reconocemos que hay mucho por hacer. Pero la base es sólida: las decisiones tecnológicas están tomadas, la integración con ORY funciona, la verificación biométrica está probada, y el equipo tiene claridad sobre hacia dónde vamos.

---

*Este documento debe actualizarse cada vez que se complete una tarea significativa o se agreguen nuevas tareas al backlog del proyecto.*

# Arquitectura técnica

## Propósito de este documento

Este documento describe las tecnologías que componen CUC v2, cómo se relacionan entre sí y por qué se eligió cada una. Está dirigido a desarrolladores que trabajen en el proyecto (internos o contribuidores open source), arquitectos que necesiten entender el sistema completo, y equipos técnicos de instituciones que integren sus servicios con CUC.

No es un manual de instalación ni una guía de código. Es un mapa técnico que explica cómo las piezas encajan para formar el producto final.

## Vista general del ecosistema

CUC v2 se compone de tres grandes bloques técnicos que operan de forma independiente pero coordinada:

El **Portal Ciudadano** es la aplicación web que usan los ciudadanos para registrarse, iniciar sesión, gestionar su perfil y recibir notificaciones. Es una aplicación Next.js 16 desplegada en Google Cloud Run.

El **Backoffice** es la aplicación web que usan los agentes de Atención Ciudadana y los administradores para gestionar cuentas, ver métricas, dar soporte y enviar notificaciones. También es una aplicación Next.js 16, pero su infraestructura de backend está en AWS.

La **Capa de Eventos y Métricas** es la infraestructura serverless en AWS que captura, procesa y almacena los eventos que emiten tanto ORY Network como las aplicaciones. Alimenta los dashboards del backoffice y la trazabilidad del journey del ciudadano.

En el centro de todo está **ORY Network**, el servicio externo que gestiona las identidades de los ciudadanos y proporciona los protocolos de autenticación (OAuth 2.0, OpenID Connect) que las instituciones gubernamentales consumen.

## Portal Ciudadano

### Next.js 16 y el App Router

El portal está construido con Next.js 16, utilizando el App Router introducido en Next.js 13 y madurado en versiones posteriores. Se eligió Next.js por varias razones técnicas que son especialmente relevantes para un portal gubernamental.

La primera es el Server-Side Rendering (SSR). Las páginas del portal se renderizan en el servidor antes de llegar al navegador del ciudadano. Esto tiene dos beneficios directos: las páginas cargan más rápido porque el navegador recibe HTML listo en vez de un bundle de JavaScript que tiene que ejecutarse para mostrar contenido, y los motores de búsqueda pueden indexar las páginas correctamente. Para un servicio gubernamental que millones de personas van a buscar en Google, esto no es trivial.

La segunda razón son los React Server Components (RSC). Next.js 16 permite que ciertos componentes se ejecuten exclusivamente en el servidor, lo que significa que nunca se envía su código JavaScript al navegador. Esto reduce el peso de la página y mejora el rendimiento en dispositivos de gama baja, que es el tipo de dispositivo que usan muchos ciudadanos dominicanos. En la documentación de React se describe cómo los Server Components permiten que la aplicación aproveche la infraestructura del servidor sin sacrificar la interactividad en el cliente (referencia: react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023).

La tercera razón son las API Routes. Next.js permite crear endpoints HTTP dentro de la misma aplicación, lo que simplifica la arquitectura. Las rutas como `/api/registration/citizen` y `/api/registration/account` son parte del mismo proyecto y se despliegan juntas, eliminando la necesidad de un backend separado para operaciones simples.

### Estructura de la aplicación

La aplicación usa el sistema de archivos como router, organizado en dos grupos principales de rutas:

Las **rutas de autenticación** (`/app/(auth)/`) agrupan todo lo relacionado con el acceso: login, registro, recuperación de contraseña y verificación de email. Usan un layout compartido que muestra la marca gubernamental y un diseño limpio centrado en el formulario.

Las **rutas del dashboard** (`/app/(dashboard)/`) agrupan las funcionalidades que requieren una sesión activa: página principal, perfil, configuraciones, historial de actividad, soporte y acerca de. Están protegidas por un middleware que verifica la sesión de ORY antes de permitir el acceso. Si la sesión no existe o expiró, el ciudadano es redirigido al login.

Las **API routes** (`/app/api/`) contienen la lógica del servidor. Aquí es donde ocurren las operaciones sensibles: la consulta a la API del Registro Civil para validar cédulas, la comunicación con ORY Network para crear identidades, la interacción con AWS Rekognition para la verificación facial, y la gestión de cookies de sesión.

### Integración con ORY Network

ORY Network es el componente más crítico de CUC porque almacena y gestiona las identidades de todos los ciudadanos registrados. La integración se hace mediante el SDK oficial de ORY (`@ory/client`) y los componentes de interfaz de ORY Elements (`@ory/elements-react`).

ORY opera bajo un modelo de "flujos" (flows). Cuando un ciudadano quiere iniciar sesión, la aplicación crea un "login flow" en ORY, que devuelve la información necesaria para renderizar el formulario (qué campos mostrar, qué métodos de autenticación están disponibles, etc.). Cuando el ciudadano envía el formulario, la aplicación completa el flow en ORY, que valida las credenciales y emite una sesión. Este modelo tiene la ventaja de que la lógica de seguridad (validación de contraseñas, protección contra fuerza bruta, manejo de tokens) vive en ORY y no en nuestro código.

Los flujos implementados son: login flow (inicio de sesión con email y contraseña), registration flow (creación de identidad con traits personalizados: cédula, nombre, fecha de nacimiento, género, nacionalidad), recovery flow (recuperación de contraseña por email), verification flow (verificación de dirección de correo mediante OTP), y settings flow (cambio de contraseña y gestión de configuraciones).

La configuración del cliente ORY vive en `ory.config.ts` y `lib/ory/client.ts`. El SDK se inicializa con la URL del proyecto ORY y un token de acceso (PAT) para operaciones del servidor. Las cookies de sesión de ORY se pasan transparentemente entre el navegador y el servidor usando un sistema de reenvío de cookies implementado en `lib/ory/cookies.ts`.

Para referencia, la documentación oficial de ORY Kratos describe este modelo de flujos con detalle: docs.ory.sh/kratos/self-service. La decisión de usar ORY en lugar de construir un sistema propio se tomó porque un IAM gubernamental no es algo que se deba improvisar. ORY es open source, tiene auditorías de seguridad regulares (trimestrales por terceros), cumple con GDPR, y es usado por organizaciones que manejan cientos de millones de identidades (referencia: ory.com/security).

### Verificación biométrica con AWS Rekognition

El registro de CUC requiere que el ciudadano verifique su identidad mediante reconocimiento facial. Esto se hace en dos pasos técnicos: la prueba de vida (liveness detection) y la comparación facial (face comparison).

La **prueba de vida** verifica que frente a la cámara hay una persona real y no una fotografía, un video o un deepfake. Utiliza el servicio Face Liveness de AWS Rekognition, que le pide al ciudadano que realice movimientos específicos (seguir un óvalo con la cara) mientras la cámara captura imágenes. AWS analiza estas imágenes y devuelve un puntaje de confianza. Si el puntaje supera el umbral configurado (90% por defecto), se considera que la prueba fue exitosa.

La **comparación facial** toma la imagen capturada durante la prueba de vida y la compara con la foto oficial del ciudadano almacenada en la base de datos de la Junta Central Electoral, obtenida a través de la API del Registro Civil dominicano (`api.devs.digital.gob.do`). Si la similitud supera el umbral configurado (80% por defecto), se considera que el ciudadano es quien dice ser.

En el lado del cliente, la captura de imágenes se hace con el componente `FaceLivenessDetector` de AWS Amplify UI (`@aws-amplify/ui-react-liveness`). Este componente maneja toda la interacción con la cámara, las instrucciones al usuario y el envío de imágenes a AWS. Para funcionar, necesita autenticación temporal de AWS, que se obtiene a través de Amazon Cognito Identity Pool con acceso no autenticado (el ciudadano no necesita una cuenta de AWS, obviamente).

En el lado del servidor, las API routes crean la sesión de liveness (`CreateFaceLivenessSession`), obtienen los resultados (`GetFaceLivenessSessionResults`) y realizan la comparación facial (`CompareFaces`). Todo esto se ejecuta con el SDK de AWS para Node.js (`@aws-sdk/client-rekognition`).

Los umbrales de confianza son configurables por variables de entorno (`LIVENESS_CONFIDENCE_THRESHOLD` y `FACE_SIMILARITY_THRESHOLD`). La documentación oficial de AWS Rekognition Face Liveness describe las técnicas anti-spoofing que utiliza el servicio (referencia: aws.amazon.com/rekognition/face-liveness).

### Sistema de UI y diseño

El sistema de componentes está basado en **shadcn/ui**, que a su vez usa **Radix UI** como base de componentes headless y **Tailwind CSS** para el estilado. Esta combinación fue elegida por razones específicas.

Radix UI proporciona componentes que cumplen con las especificaciones WAI-ARIA por defecto: manejo correcto del foco, navegación por teclado, roles semánticos y estados accesibles. Para un portal gubernamental, la accesibilidad no es opcional; es un requisito legal y moral. Usar Radix como base garantiza que empezamos con una base accesible en vez de intentar agregarla después.

Tailwind CSS permite definir estilos directamente en los componentes, lo que facilita el mantenimiento y la contribución en un proyecto open source. Un contribuidor nuevo puede entender y modificar los estilos de un componente sin necesidad de rastrear archivos CSS separados.

shadcn/ui combina ambos: proporciona componentes pre-construidos (botones, formularios, diálogos, tablas, etc.) que se copian directamente al proyecto, lo que significa que tenemos control total sobre el código. No es una dependencia en tiempo de ejecución; es un punto de partida que podemos personalizar.

La aplicación soporta **modo oscuro** mediante `next-themes`, que gestiona la preferencia del usuario y persiste la selección.

### Internacionalización

La aplicación soporta español e inglés usando `next-intl`, una librería de internacionalización diseñada específicamente para Next.js. Todas las cadenas de texto están externalizadas en archivos JSON dentro del directorio `i18n/messages/`. Las traducciones de los componentes de ORY Elements se personalizan mediante `lib/ory/custom-translations.ts`, lo que permite que los mensajes de error y las instrucciones de ORY aparezcan en español con terminología gubernamental apropiada.

### Validación de datos

Los formularios usan **React Hook Form** para la gestión del estado y **Zod** para la validación de esquemas. Zod fue elegido porque permite definir esquemas de validación que se comparten entre el cliente y el servidor: el mismo esquema que valida la cédula en el formulario del navegador la valida también en la API route del servidor. Esto elimina la posibilidad de que un dato pase la validación del cliente pero falle en el servidor, o viceversa.

Las validaciones implementadas incluyen: formato de cédula (11 dígitos con checksum), formato de correo electrónico, fortaleza de contraseña (longitud mínima, y verificación de que no contenga la cédula del ciudadano), y formato de código OTP.

## Backoffice

### Arquitectura general

El backoffice es una aplicación Next.js 16 separada del portal ciudadano. Aunque comparten el mismo framework y muchas decisiones de diseño, son proyectos independientes con deployments independientes. Esta separación es intencional: el backoffice tiene requisitos de seguridad y acceso completamente diferentes al portal público.

### Infraestructura de eventos (AWS)

El corazón del backoffice es su infraestructura de eventos en AWS, diseñada como un pipeline serverless:

**Amazon EventBridge** es el punto de entrada. ORY Network emite webhooks cada vez que ocurre un evento relevante: un ciudadano se registra, inicia sesión, falla un intento de login, cambia su contraseña, verifica su email, etc. Estos webhooks se envían a EventBridge, que los categoriza según reglas predefinidas. EventBridge fue elegido sobre alternativas como SQS directo o SNS porque permite definir reglas de enrutamiento sofisticadas: diferentes tipos de eventos pueden ir a diferentes destinos, se pueden filtrar eventos por propiedades específicas, y se tiene un registro de auditoría integrado.

**AWS Lambda** procesa los eventos. Cada tipo de evento tiene una función Lambda asociada que lo transforma, enriquece con datos adicionales si es necesario, y lo persiste. Lambda fue la elección natural para este caso de uso porque es serverless (no hay que gestionar servidores), escala automáticamente con la carga (si un día hay 100 registros y otro día 10,000, Lambda se ajusta), y solo se paga por el tiempo de ejecución real.

**Amazon DynamoDB** almacena los datos procesados. DynamoDB es una base de datos NoSQL que fue elegida por su rendimiento predecible a cualquier escala y su modelo de costos (se paga por operación, no por hora de servidor). Los datos se organizan en tablas diseñadas para los patrones de consulta del backoffice: búsqueda de eventos por ciudadano (cédula o correo), métricas agregadas por período de tiempo, y logs de errores por tipo y severidad.

Esta arquitectura sigue el patrón Event-Driven Architecture (EDA), que está bien documentado por AWS como una best practice para sistemas que necesitan reaccionar a eventos en tiempo real y mantener un registro completo de lo que ocurre (referencia: aws.amazon.com/event-driven-architecture).

### Funcionalidades del backoffice

El backoffice expone la información recolectada mediante dashboards interactivos. Los administradores pueden ver métricas de registro (completados, abandonados, tasa de conversión por paso), métricas de uso (sesiones activas, integraciones OAuth más populares, distribución geográfica si está disponible), y métricas de errores (tipos de error más frecuentes, tendencias, impacto).

Para los agentes de Atención Ciudadana, la funcionalidad principal es la búsqueda de ciudadanos y la visualización de su journey completo: cada acción que realizaron, cada error que encontraron, cada interacción con el sistema. Esto se alimenta de los eventos en DynamoDB y se presenta en una línea de tiempo cronológica.

## Capa de eventos y métricas

### Flujo de datos

El flujo de datos del ecosistema funciona así:

Un ciudadano realiza una acción en el portal (por ejemplo, intenta registrarse). La aplicación Next.js procesa la solicitud y se comunica con ORY Network para crear la identidad. ORY procesa la solicitud y emite un webhook a EventBridge con los detalles del evento. EventBridge enruta el evento a la función Lambda correspondiente. Lambda transforma el evento, lo enriquece con metadata (timestamp, tipo de evento, identificador del ciudadano) y lo almacena en DynamoDB. El backoffice consulta DynamoDB para mostrar la información en sus dashboards y en las búsquedas de los agentes.

Además de los eventos de ORY, el portal ciudadano también puede emitir eventos propios para acciones que ORY no captura: en qué paso del registro está el ciudadano, cuánto tiempo pasa en cada pantalla, si la cámara se activó correctamente para la verificación facial, etc. Estos eventos de aplicación siguen el mismo camino: se envían a EventBridge y se procesan con Lambda.

### Tipos de eventos

Los eventos se clasifican en varias categorías. Los eventos de identidad incluyen: registro completado, registro abandonado (con paso donde se detuvo), verificación de email completada, y cambio de traits (información personal). Los eventos de sesión incluyen: login exitoso, login fallido (con razón del fallo), logout, y sesión revocada. Los eventos de seguridad incluyen: cambio de contraseña, activación/desactivación de 2FA, intento de fuerza bruta detectado, y sesión sospechosa. Los eventos de aplicación incluyen: navegación entre pasos del registro, error de cámara en verificación facial, resultado de liveness, y tiempo de permanencia en cada pantalla.

## Infraestructura de deployment

### Portal Ciudadano en Google Cloud Run

El portal ciudadano se despliega en Google Cloud Run, un servicio serverless que ejecuta contenedores Docker. El pipeline de CI/CD funciona así: cuando se hace push a la rama `staging` en GitHub, GitHub Actions construye la imagen Docker (usando el Dockerfile multi-stage con Bun como base), la sube a Google Artifact Registry, y despliega una nueva revisión en Cloud Run.

Cloud Run fue elegido porque escala a cero (si no hay tráfico, no hay costo), escala automáticamente con la demanda, proporciona HTTPS automático, y se integra nativamente con otros servicios de Google Cloud. El Dockerfile está optimizado para producción: usa Bun para instalar dependencias de forma rápida, construye la aplicación con el output standalone de Next.js (que produce un bundle mínimo), y ejecuta con un usuario no-root por seguridad.

### Backoffice en AWS

El backoffice se despliega en la infraestructura de AWS donde ya viven los servicios de eventos. Los detalles específicos del deployment del backoffice (ECS, Amplify Hosting, u otro) están en proceso de definición, pero la premisa es usar servicios managed para minimizar la carga operativa.

### Separación GCP y AWS

Es válido preguntar por qué el portal está en GCP y el backoffice en AWS. La razón es pragmática: el portal ciudadano se beneficia de Cloud Run por su simplicidad de deployment y su escalamiento automático para tráfico público variable. La infraestructura de eventos necesita EventBridge, que es un servicio exclusivo de AWS, y DynamoDB ofrece el rendimiento que necesitan las consultas en tiempo real del backoffice. Usar cada cloud para lo que mejor hace es una estrategia multi-cloud válida, aunque implica gestionar dos proveedores.

## Stack tecnológico completo

Para referencia rápida, estas son todas las tecnologías principales del proyecto:

**Runtime y framework:** Next.js 16, React 19, TypeScript 5, Bun (package manager y runtime para builds).

**Autenticación e identidad:** ORY Network (Kratos para identidades, Hydra para OAuth 2.0/OIDC), @ory/client, @ory/elements-react, @ory/nextjs.

**Verificación biométrica:** AWS Rekognition (Face Liveness, CompareFaces), AWS Amplify (FaceLivenessDetector UI), Amazon Cognito (autenticación temporal para el cliente).

**UI y diseño:** shadcn/ui, Radix UI, Tailwind CSS, Lucide React (iconos), next-themes (modo oscuro), Recharts (gráficas).

**Formularios y validación:** React Hook Form, Zod.

**Internacionalización:** next-intl, react-intl.

**Infraestructura de eventos (AWS):** Amazon EventBridge, AWS Lambda, Amazon DynamoDB.

**Deployment (Portal):** Google Cloud Run, Google Artifact Registry, GitHub Actions, Docker.

**Monitoreo:** por definir (evaluando opciones entre Sentry, CloudWatch, y soluciones de observabilidad más completas).

## Consideraciones de seguridad en la arquitectura

La seguridad está integrada en cada capa de la arquitectura, no como una capa adicional.

En la capa de identidad, ORY Network proporciona: hash de contraseñas con bcrypt+salt, tokens de sesión con expiración configurable, protección contra fuerza bruta (rate limiting por IP y por cuenta), soporte para 2FA (TOTP y WebAuthn), y cifrado AES-256 en reposo para todos los datos de identidad.

En la capa de verificación biométrica, AWS Rekognition procesa las imágenes en tiempo real y no las almacena después del análisis (a menos que se configure explícitamente). Las imágenes del ciudadano nunca se guardan en nuestra infraestructura; solo se almacena el resultado de la comparación (exitosa o fallida) y los puntajes de confianza.

En la capa de aplicación, todas las comunicaciones son HTTPS con TLS 1.2+. Las API routes validan todos los inputs con Zod. Las cookies de sesión del registro usan cifrado y firma para prevenir manipulación. Los datos sensibles (tokens de ORY, claves de AWS) solo existen como variables de entorno en el servidor y nunca se exponen al cliente.

En la capa de infraestructura, Cloud Run ejecuta los contenedores con un usuario no-root. Las funciones Lambda tienen permisos mínimos (principio de menor privilegio). DynamoDB cifra los datos en reposo por defecto. EventBridge registra todos los eventos para auditoría.

## Diagramas de flujo

### Flujo de registro del ciudadano

```
Ciudadano → Portal (Next.js)
  │
  ├─ Paso 1: Ingresa cédula
  │   └─ API Route → API Registro Civil (valida cédula)
  │                 → ORY Network (verifica que no existe)
  │                 → Setea cookie de sesión de registro
  │
  ├─ Paso 2: Ingresa email y contraseña
  │   └─ Validación local con Zod (formato, fortaleza)
  │
  └─ Paso 3: Verificación facial
      ├─ API Route → AWS Rekognition (crea sesión liveness)
      ├─ Cliente → AWS Amplify FaceLivenessDetector (captura imagen)
      ├─ API Route → AWS Rekognition (obtiene resultado liveness)
      │            → API Registro Civil (obtiene foto JCE)
      │            → AWS Rekognition (compara rostros)
      └─ API Route → ORY Network (crea identidad con traits)
                   → ORY envía email de verificación
                   → Ciudadano ingresa OTP
                   → Cuenta activa

```

### Flujo de eventos hacia el backoffice

```
ORY Network ──webhook──→ Amazon EventBridge
                              │
                              ├─→ Lambda (procesa evento de registro)
                              │       └─→ DynamoDB (tabla: registros)
                              │
                              ├─→ Lambda (procesa evento de sesión)
                              │       └─→ DynamoDB (tabla: sesiones)
                              │
                              └─→ Lambda (procesa evento de error)
                                      └─→ DynamoDB (tabla: errores)

Portal Next.js ──eventos app──→ EventBridge (misma ruta)

Backoffice ←── consulta ←── DynamoDB

```

---

*Este documento debe actualizarse cuando se agreguen nuevos componentes o se modifique la arquitectura existente.*

# Temas de debate

## Propósito de este documento

En todo proyecto ambicioso hay decisiones que se toman con confianza y otras que se asumen sin discutir lo suficiente. Este documento recoge los temas que necesitan ser debatidos abiertamente por el equipo antes de avanzar más. No son críticas ni señalamientos: son puntos donde la decisión correcta no es obvia y donde diferentes perspectivas pueden llevar a mejores resultados.

Cada tema se presenta con el contexto necesario, las opciones disponibles, las implicaciones de cada una y las preguntas que el equipo debe responder. La idea es que este documento sirva como agenda para sesiones de discusión técnica, no como un dictamen.

## 1. Infraestructura multi-cloud: ¿pragmatismo o complejidad innecesaria?

Actualmente el portal ciudadano está en Google Cloud Platform (Cloud Run) y la infraestructura de eventos y el backoffice están en AWS (EventBridge, Lambda, DynamoDB). Esta decisión tiene sentido técnico: Cloud Run es excelente para aplicaciones web con tráfico variable y EventBridge es un servicio sin equivalente directo en GCP para este caso de uso.

Sin embargo, operar en dos proveedores cloud tiene implicaciones que vale la pena discutir. El equipo necesita mantener expertise en ambas plataformas. Los costos se dividen en dos facturas diferentes, lo que dificulta el seguimiento presupuestario. La comunicación entre los componentes (por ejemplo, el portal enviando eventos a EventBridge) cruza proveedores, lo que agrega latencia y puntos de fallo. Y si algún día se necesita un ambiente de disaster recovery, hay que replicarlo en dos clouds.

La alternativa sería consolidar todo en un solo proveedor. AWS tendría la ventaja de que ya aloja la parte más compleja (eventos, Lambda, DynamoDB) y el backoffice. El portal podría desplegarse en AWS Amplify Hosting, ECS Fargate, o incluso App Runner, que es el equivalente de AWS a Cloud Run. La desventaja es que Cloud Run ya funciona y migrar tiene un costo de tiempo.

**Preguntas para el equipo:** ¿Hemos medido la latencia adicional que introduce la comunicación cross-cloud? ¿Cuál es el costo operativo real de mantener dos proveedores (no solo en dinero, sino en tiempo del equipo)? ¿Hay un punto en el futuro donde la complejidad multi-cloud nos va a morder, por ejemplo cuando necesitemos un VPC privado para comunicar servicios? ¿O es que la separación actual es lo suficientemente limpia como para no ser un problema en la práctica?

## 2. El agente de IA: ¿qué problema resuelve exactamente?

Se ha mencionado que CUC v2 tendrá un agente de inteligencia artificial para ayudar a los ciudadanos. La tecnología está en investigación, lo cual es correcto, pero antes de elegir la tecnología, el equipo necesita alinear lo que espera de este agente.

Hay una diferencia grande entre un chatbot con respuestas predefinidas (que puede resolver el 80% de las preguntas frecuentes con muy poco riesgo), un agente conversacional basado en un modelo de lenguaje grande (que puede manejar preguntas abiertas pero puede generar respuestas incorrectas o confusas), y un sistema híbrido que usa IA para entender la intención del ciudadano y luego ejecuta acciones predefinidas (más seguro que un LLM puro pero más flexible que un chatbot).

En un contexto gubernamental, la precisión de las respuestas no es negociable. Si un ciudadano pregunta "¿puedo usar mi cuenta para acceder al portal de becas?" y el agente dice "sí" cuando la respuesta real es "depende de si el portal de becas ya está integrado", eso genera desconfianza. Los LLMs son propensos a este tipo de errores (conocidos como "alucinaciones" en la literatura técnica), y en un contexto donde la información gubernamental debe ser exacta, esto es un riesgo real.

También está el tema de la escalación a un agente humano. ¿Cómo se determina que el agente de IA no puede resolver el caso? ¿Después de cuántos intentos? ¿Según el tipo de pregunta? ¿El ciudadano puede pedir hablar con un humano directamente? ¿Qué pasa fuera del horario laboral cuando no hay agentes humanos disponibles?

**Preguntas para el equipo:** ¿Cuáles son los 20 casos de uso más comunes que el agente debe resolver? ¿Podemos empezar con algo más simple (un FAQ interactivo bien hecho) y evolucionar hacia IA cuando tengamos datos de qué preguntan realmente los ciudadanos? ¿Cuál es el presupuesto operativo para un servicio de IA (los modelos de lenguaje se cobran por uso y el costo puede escalar rápido)? ¿Quién se responsabiliza si el agente da información incorrecta a un ciudadano?

## 3. El buzón de notificaciones: ¿canal de comunicación o bandeja de spam gubernamental?

El buzón ciudadano es una funcionalidad con mucho potencial pero también con riesgo de mal uso. Si cada institución gubernamental puede enviar notificaciones a los ciudadanos a través de CUC, existe el riesgo de que el buzón se llene de mensajes irrelevantes y los ciudadanos dejen de prestarle atención, lo que anularía completamente su utilidad.

Hay varias preguntas de diseño que necesitan respuesta. ¿Quién puede enviar notificaciones? ¿Solo los agentes de CUC o cualquier institución integrada? ¿Hay un proceso de aprobación para las notificaciones masivas? ¿El ciudadano puede configurar qué tipo de notificaciones quiere recibir? ¿Hay límites de frecuencia?

También está el tema técnico. ¿Las notificaciones son en tiempo real (WebSockets, Server-Sent Events) o se consultan cada vez que el ciudadano abre su cuenta (polling)? La primera opción es mejor para la experiencia pero más compleja de implementar y mantener. La segunda es más simple pero menos inmediata.

Y un tema que nadie ha mencionado aún: ¿las notificaciones se envían también por correo electrónico o solo se muestran dentro de la plataforma? Si solo están dentro de la plataforma, el ciudadano no se entera hasta que inicia sesión. Si se envían por correo, ¿eso no duplica un canal que ya existe?

**Preguntas para el equipo:** ¿Cuál es el modelo de gobernanza de las notificaciones? ¿Hemos hablado con las instituciones que integran CUC para entender qué tipo de comunicaciones querrían enviar? ¿El buzón es un MVP que empieza solo con notificaciones del sistema (seguridad, actividad de cuenta) y después se abre a otras instituciones? ¿O lanzamos con la capacidad completa desde el inicio?

## 4. Open source: ¿estamos listos?

La decisión de hacer CUC v2 open source es excelente desde el punto de vista de transparencia y potencial de colaboración. Sin embargo, open source no es solo publicar el código en GitHub. Es un compromiso continuo que tiene implicaciones operativas.

Un proyecto open source gubernamental necesita, como mínimo: documentación clara de cómo contribuir (CONTRIBUTING.md), un código de conducta (CODE\_OF\_CONDUCT.md), un proceso de revisión de pull requests que sea oportuno (si alguien contribuye y no recibe respuesta en semanas, no va a volver), un proceso de reporte y manejo de vulnerabilidades de seguridad (SECURITY.md), y una licencia de software explícita que defina qué pueden hacer otros con el código.

También hay que pensar en qué partes del código son open source y cuáles no. El portal ciudadano puede ser completamente abierto. Pero el backoffice, que gestiona datos de ciudadanos y tiene acceso administrativo a las cuentas, ¿también debería ser público? ¿No facilita eso que alguien estudie el sistema para encontrar vectores de ataque?

Hay precedentes internacionales que vale la pena revisar. El servicio login.gov del gobierno de Estados Unidos es open source (github.com/18F/identity-idp) y ha navegado estos temas con éxito. El Gobierno del Reino Unido publica código a través de su Government Digital Service (GDS) en github.com/alphagov. Estonia, referente mundial en gobierno digital, también tiene componentes open source de su infraestructura X-Road. Estos casos demuestran que es posible, pero también que requiere un compromiso institucional sostenido.

**Preguntas para el equipo:** ¿Tenemos el ancho de banda para atender contribuciones externas, o el código va a estar público pero en la práctica nadie va a revisar los pull requests? ¿Hemos definido la licencia? ¿MIT, Apache 2.0, algo más restrictivo? ¿El backoffice será open source o solo el portal ciudadano? ¿Hay una política de OGTIC sobre publicación de código fuente que debamos seguir?

## 5. Verificación facial: accesibilidad y casos límite

La verificación facial con AWS Rekognition es un componente central del registro, pero tiene limitaciones que debemos reconocer y planificar.

El primer tema es la accesibilidad. Un ciudadano que tiene una discapacidad visual severa puede tener dificultades con la prueba de liveness, que requiere seguir instrucciones visuales en pantalla. ¿Cuál es la alternativa para estos ciudadanos? ¿Un proceso de verificación presencial? ¿Una llamada de video con un agente? Si no hay alternativa, estamos excluyendo a un segmento de la población del acceso a servicios digitales.

El segundo tema son los dispositivos de gama baja. Los umbrales actuales son 90% para liveness y 80% para similitud facial. ¿Estos umbrales funcionan bien con cámaras de baja resolución? ¿Se han probado con los dispositivos más comunes en República Dominicana? Un umbral muy alto puede rechazar a ciudadanos legítimos; un umbral muy bajo puede aceptar intentos fraudulentos. Encontrar el balance correcto requiere datos que probablemente solo obtengamos en producción.

El tercer tema es la dependencia de la foto de la JCE. La comparación facial depende de la foto almacenada en la base de datos de la Junta Central Electoral. ¿Qué tan recientes son estas fotos? Si un ciudadano renovó su cédula hace 10 años y su apariencia cambió significativamente, la comparación puede fallar legítimamente. ¿Cuál es el proceso para estos casos?

Y el cuarto tema, más técnico: la dependencia de AWS. Si AWS Rekognition tiene una interrupción del servicio (ha pasado), el registro de CUC se detiene completamente. ¿Tenemos un plan de contingencia? ¿Se puede permitir un registro temporal sin verificación facial que se complete después?

**Preguntas para el equipo:** ¿Hemos hecho pruebas de usabilidad de la verificación facial con ciudadanos reales, especialmente adultos mayores y personas con dispositivos básicos? ¿Cuál es el plan para ciudadanos que no pueden pasar la verificación facial por razones legítimas? ¿Tenemos métricas de la v1 sobre la tasa de éxito/fracaso de la verificación facial? ¿Deberíamos tener un fallback manual para cuando Rekognition no esté disponible?

## 6. Monitoreo y observabilidad: ¿Sentry, CloudWatch o algo más?

La versión 1 usaba Sentry para captura de errores. La versión 2 tiene una infraestructura de eventos en AWS que cubre parte del monitoreo. Pero no se ha tomado una decisión clara sobre la estrategia completa de observabilidad.

Un sistema de identidad gubernamental necesita, como mínimo: monitoreo de errores de aplicación (el equivalente a lo que hacía Sentry), monitoreo de rendimiento (tiempos de respuesta de cada endpoint, tiempos de carga de cada página), monitoreo de infraestructura (uso de CPU, memoria, conexiones de red en Cloud Run, ejecuciones y errores en Lambda), alertas automáticas (cuando algo falle, el equipo debe enterarse antes que los ciudadanos), y dashboards operativos (una vista en tiempo real del estado del sistema).

Las opciones no son mutuamente excluyentes. Se podría usar Sentry para errores de aplicación (es excelente en esto y tiene contexto que CloudWatch no tiene, como el stack trace completo con variables locales), CloudWatch para la infraestructura de AWS, Cloud Monitoring para Cloud Run, y algo como Grafana para unificar dashboards. Pero eso son cuatro herramientas diferentes, lo que fragmenta la experiencia del equipo de operaciones.

Una alternativa sería usar una plataforma unificada como Datadog o New Relic que cubra todas las necesidades. Pero estas tienen un costo significativo que hay que evaluar.

**Preguntas para el equipo:** ¿Cuál fue la experiencia con Sentry en la v1? ¿Realmente se usaba o se instaló y nadie miraba las alertas? ¿Tenemos presupuesto para una herramienta de observabilidad comercial? ¿Quién va a ser responsable de mirar los dashboards y responder a las alertas? Porque la mejor herramienta del mundo no sirve si nadie la mira.

## 7. Protección contra bots y abuso: ¿qué reemplaza a reCAPTCHA?

La versión 1 usaba Google reCAPTCHA v3 para prevenir el registro automatizado por bots y Cloudflare para protección DDoS. En el código de la versión 2 no se ve ninguna implementación de CAPTCHA ni de protección similar.

ORY Network tiene protección contra fuerza bruta (rate limiting por IP y por cuenta), pero eso solo protege el login. El registro, que involucra llamadas a la API del Registro Civil y a AWS Rekognition (ambas con costo), necesita protección propia contra abuso.

Las opciones incluyen: mantener reCAPTCHA (funciona, pero Google recolecta datos del usuario, lo cual puede ser un problema de privacidad para un servicio gubernamental), usar Cloudflare Turnstile (alternativa a reCAPTCHA que es más respetuosa con la privacidad), implementar rate limiting propio en las API routes (más simple pero menos sofisticado), o confiar en la protección a nivel de Cloudflare/WAF si se mantiene Cloudflare como proxy.

**Preguntas para el equipo:** ¿Vamos a seguir usando Cloudflare como proxy/WAF? ¿Hay alguna política de OGTIC sobre el uso de servicios que recolectan datos de usuarios (como reCAPTCHA)? ¿Cuál es el costo estimado si un bot hace miles de llamadas a la API del Registro Civil o a Rekognition antes de que lo detectemos?

## 8. Pruebas de carga y límites del sistema

Antes de lanzar la v2, necesitamos entender los límites del sistema. ¿Cuántos registros simultáneos puede manejar? ¿Cuántos logins por segundo? ¿Qué pasa si hay un pico de tráfico (por ejemplo, porque el gobierno anuncia un nuevo servicio que requiere CUC)?

Cloud Run escala automáticamente, pero tiene límites configurables (máximo de instancias, máximo de conexiones por instancia). ORY Network tiene sus propios límites según el plan contratado. AWS Rekognition tiene límites de API por región. Lambda tiene límites de concurrencia. DynamoDB tiene límites de capacidad de lectura/escritura.

Cada uno de estos límites puede convertirse en un cuello de botella si no se dimensiona correctamente. Y en un servicio gubernamental, la caída del sistema durante un pico de demanda tiene implicaciones políticas además de técnicas.

**Preguntas para el equipo:** ¿Hemos hecho pruebas de carga? ¿Conocemos los límites del plan de ORY Network que estamos usando? ¿Cuál es el pico de tráfico más alto que ha tenido CUC v1? ¿Tenemos un plan de capacidad que defina cuántos usuarios simultáneos debemos soportar?

## 9. Migración de usuarios de v1 a v2

Un tema que no se ha discutido explícitamente: ¿cómo se migran los usuarios existentes de CUC v1 a CUC v2? Si ambas versiones usan ORY Network, las identidades deberían ser las mismas. Pero si hay cambios en los traits de la identidad (campos nuevos, estructura diferente), se necesita una estrategia de migración.

¿Se van a migrar todos los usuarios de golpe? ¿Se va a hacer una migración gradual donde algunos usuarios usan v1 y otros v2? ¿Los usuarios necesitan hacer algo (como iniciar sesión en el nuevo portal) para completar la migración, o es transparente?

Y si el dominio cambia (de cuentaunica.gob.do a algo diferente), ¿cómo se manejan las integraciones existentes que apuntan al dominio actual? ¿Hay un período de transición con ambos dominios activos?

**Preguntas para el equipo:** ¿Los traits de la identidad en ORY cambian entre v1 y v2? ¿Las integraciones OAuth existentes (gob.do, SoyYo RD, becas) necesitan actualizar algo de su lado? ¿Cuál es el plan de transición para que el lanzamiento no interrumpa los servicios que dependen de CUC?

## Próximos pasos

Se recomienda que el equipo tome este documento como agenda para una o varias sesiones de trabajo donde se discutan estos temas. Para cada tema, el resultado debería ser una decisión documentada con su justificación, o un plan de investigación con fecha de cierre si la información actual no es suficiente para decidir.

Los temas no tienen todos la misma urgencia. Los que bloquean el progreso del desarrollo (como la decisión de monitoreo y la protección contra bots) deberían discutirse primero. Los que afectan el lanzamiento pero no el desarrollo (como la estrategia open source y la migración de usuarios) pueden esperar un poco más, pero no indefinidamente.

---

*Este documento debe actualizarse después de cada sesión de debate, registrando las decisiones tomadas y eliminando los temas resueltos.*

# Versión 1 vs. Versión 2

## Introducción

Desde finales del año 2022, Cuenta Única Ciudadana ha sido el mecanismo oficial mediante el cual los ciudadanos dominicanos se identifican ante los portales y aplicaciones del Estado. Con una sola cuenta, vinculada al número de cédula, cualquier persona puede acceder a servicios como el portal gob.do, la aplicación Soy Yo RD (Carpeta Ciudadana), el portal de becas del gobierno y otras plataformas integradas. CUC eliminó la necesidad de tener múltiples credenciales para cada institución gubernamental, simplificando la vida digital de millones de dominicanos.

Sin embargo, como todo producto tecnológico, CUC ha acumulado aprendizajes. Tras más de dos años en producción, el equipo ha identificado oportunidades de mejora que van desde la experiencia del usuario hasta la capacidad del equipo interno de dar soporte efectivo a los ciudadanos. Este documento describe qué tiene la versión actual, qué trae la nueva versión, y por qué estos cambios son importantes tanto para los ciudadanos como para las instituciones gubernamentales que dependen de CUC.

## La versión actual: lo que tenemos hoy

La primera versión de CUC cumple su función principal: permite a los ciudadanos crear una cuenta digital segura y usarla para acceder a servicios gubernamentales. El sistema está construido sobre ORY Network para la gestión de identidades, lo que significa que las credenciales de los ciudadanos están protegidas con estándares internacionales de seguridad (OAuth 2.0, OpenID Connect, cifrado AES-256 en reposo, TLS 1.2+ en tránsito). La verificación de identidad usa AWS Rekognition para comparar el rostro del ciudadano con la foto oficial de la Junta Central Electoral, asegurando que quien se registra es realmente quien dice ser.

El proceso de registro actual consta de cuatro pasos: primero el ciudadano ingresa su cédula, luego pasa por la verificación facial (prueba de vida), después crea su cuenta con correo y contraseña, y finalmente activa la cuenta mediante un código enviado al correo electrónico. Este flujo funciona, pero la experiencia no siempre es fluida. Muchos ciudadanos se frustran durante la verificación facial, especialmente cuando usan dispositivos de gama baja o están en condiciones de iluminación difíciles, y para ese punto aún no han invertido tiempo en crear su cuenta, lo que facilita que abandonen el proceso.

### Limitaciones identificadas

A lo largo de estos años de operación, se han identificado varias áreas donde la versión actual se queda corta. La más significativa es la falta de visibilidad operativa. El equipo no tiene una forma sencilla de responder preguntas básicas como cuántos ciudadanos se registran por día, cuáles integraciones OAuth son las más utilizadas, en qué paso del registro se pierden los ciudadanos que no completan el proceso, o cuáles son los errores más frecuentes. Esta falta de métricas hace difícil tomar decisiones informadas sobre qué mejorar y cómo priorizar el trabajo.

El soporte al ciudadano también es un punto débil. Aunque existe un backoffice que permite realizar algunas acciones sobre las cuentas, nunca se le dio el desarrollo necesario para convertirlo en una herramienta realmente útil. Cuando un ciudadano llama porque no puede completar su registro o tiene problemas con su cuenta, el equipo de Atención Ciudadana tiene herramientas limitadas para diagnosticar qué pasó y ayudarlo. No hay un historial detallado de las acciones del ciudadano, no hay logs organizados que permitan rastrear un problema, y no hay un sistema de tickets que permita darle seguimiento a los casos.

La estructura de logs es otro tema pendiente. Sentry captura errores de la aplicación, pero no hay una estructura consolidada que combine los eventos de ORY Network, los logs de la aplicación y los errores del sistema en un solo lugar donde se puedan consultar y analizar.

Finalmente, la experiencia del ciudadano, aunque funcional, no es todo lo que podría ser. El diseño actual no se adapta bien a todos los dispositivos, la navegación entre las diferentes partes del sistema (landing page, registro, login, perfil) no es completamente fluida, y no hay funcionalidades que le den al ciudadano una razón para volver a su cuenta más allá de necesitar iniciar sesión en otro servicio.

## La nueva versión: lo que estamos construyendo

CUC v2 no es un parche sobre lo que existe. Es una reconstrucción desde cero que mantiene las decisiones tecnológicas fundamentales que funcionaron (ORY Network, AWS Rekognition) pero replantea todo lo demás: la experiencia del usuario, las herramientas internas, la recolección de datos y la capacidad de dar soporte.

### Un portal unificado

La nueva versión consolida todo en una sola aplicación: el landing page, el registro, el inicio de sesión, la recuperación de contraseña y el perfil del ciudadano. En la versión actual, algunas de estas funcionalidades viven en dominios o contextos separados (cuentaunica.gob.do y registro.cuentaunica.gob.do). En la versión nueva, el ciudadano tiene una experiencia continua sin saltar entre diferentes sitios.

El portal está construido con Next.js 16, un framework de React que permite renderizar las páginas en el servidor. Esto no es solo una decisión técnica: significa que las páginas cargan más rápido, funcionan mejor en dispositivos con conexiones lentas, y son más fáciles de indexar por buscadores. Para un servicio gubernamental que debe ser accesible para todos los ciudadanos, independientemente de su dispositivo o conexión, esto es fundamental.

### Un registro más inteligente

El flujo de registro se rediseñó de cuatro pasos a tres, y se cambió el orden de las acciones. Ahora el ciudadano primero valida su cédula, luego crea su cuenta (correo y contraseña), y finalmente pasa por la verificación facial. Este cambio no es arbitrario: al permitir que el ciudadano ya haya invertido tiempo en crear su cuenta antes de llegar a la verificación facial, se reduce significativamente la tasa de abandono. Si la verificación facial falla, el ciudadano ya tiene su información guardada y solo necesita reintentar ese paso.

Además, todas las vistas del journey del ciudadano están personalizadas. A diferencia de la versión anterior donde algunas pantallas usaban los componentes genéricos de ORY, la nueva versión tiene un diseño gubernamental consistente en cada pantalla, con instrucciones claras en español y mensajes de error que realmente ayudan al ciudadano a entender qué debe hacer.

### Un backoffice que realmente sirve

Esta es quizás la mejora más significativa desde el punto de vista operativo. El nuevo backoffice es una aplicación completa que le da al equipo de Atención Ciudadana y a los administradores todas las herramientas que necesitan para hacer su trabajo.

La pieza central es la recolección de métricas en tiempo real. Cada evento que ocurre en el ecosistema de CUC (un registro, un inicio de sesión, un error, un cambio de contraseña) se captura mediante AWS EventBridge, se procesa con funciones Lambda y se almacena en DynamoDB. Esto permite tener dashboards en tiempo real que muestran el estado del sistema, las tendencias de uso y los problemas que necesitan atención.

Los agentes de Atención Ciudadana podrán ver la trazabilidad completa del journey de un ciudadano. Si alguien llama diciendo que no pudo registrarse, el agente puede ver exactamente qué pasos completó, dónde falló, qué error se produjo y cuándo ocurrió. Esto transforma el soporte de "no sé qué pasó, intente de nuevo" a "veo que su verificación facial falló por iluminación insuficiente, le voy a explicar cómo mejorar eso".

También podrán gestionar cuentas directamente: buscar ciudadanos, ver su información, bloquear o desbloquear cuentas, resetear contraseñas, y enviar notificaciones. Todo con un sistema de permisos que controla quién puede hacer qué.

### Buzón ciudadano y notificaciones

Una funcionalidad completamente nueva es el buzón de notificaciones dentro de la cuenta del ciudadano. Hoy, la cuenta CUC solo sirve para iniciar sesión en otros servicios. Con el buzón, el ciudadano tendrá una razón para visitar su cuenta: podrá recibir avisos de seguridad, comunicaciones gubernamentales, alertas sobre actividad sospechosa, recordatorios de trámites pendientes y respuestas a sus solicitudes de soporte.

Esto convierte a CUC de un simple mecanismo de autenticación a un punto de contacto permanente entre el ciudadano y el gobierno digital. Las instituciones gubernamentales podrán usar este canal para comunicarse con los ciudadanos de forma directa y segura, sin depender de correos electrónicos que pueden terminar en spam o de mensajes de texto que tienen limitaciones de contenido.

### Agente de inteligencia artificial

Se planea incorporar un asistente conversacional que ayude a los ciudadanos a resolver dudas sobre su cuenta, los guíe en procesos y, cuando no pueda resolver un problema, escale el caso a un agente humano de Atención Ciudadana. La tecnología específica aún está en evaluación, pero la visión es clara: el ciudadano debe poder obtener ayuda inmediata las 24 horas del día, y solo los casos complejos deben requerir intervención humana.

Cuando un caso se escala, el agente humano recibe toda la información del contexto: qué preguntó el ciudadano, qué respuestas se le dieron, y cuál es el problema real. Esto elimina la necesidad de que el ciudadano repita su situación múltiples veces.

### Proyecto open source

CUC v2 será un proyecto de código abierto. Esto significa que cualquier ciudadano, desarrollador o institución podrá ver el código fuente, reportar problemas, sugerir mejoras o contribuir directamente al desarrollo. Esta decisión responde a un principio de transparencia: los ciudadanos tienen derecho a saber cómo funciona el sistema que gestiona su identidad digital.

Además, al ser open source, otras instituciones gubernamentales de la región podrían adoptar o adaptar el sistema para sus propias necesidades, posicionando a la República Dominicana como referente en gobierno digital abierto en América Latina y el Caribe.

## Comparación directa

<table id="bkmrk-aspecto-cuc-v1-%28actu"><thead><tr><th>Aspecto</th><th>CUC v1 (Actual)</th><th>CUC v2 (Nueva)</th></tr></thead><tbody><tr><td>Framework</td><td>Next.js 13</td><td>Next.js 16 con App Router y React Server Components</td></tr><tr><td>Registro</td><td>4 pasos (cédula, facial, cuenta, activación)</td><td>3 pasos (cédula, cuenta, facial + activación)</td></tr><tr><td>Portales</td><td>Separados (cuentaunica.gob.do y registro.cuentaunica.gob.do)</td><td>Unificado en un solo portal</td></tr><tr><td>Backoffice</td><td>Básico, nunca completado</td><td>Aplicación completa con métricas en tiempo real</td></tr><tr><td>Métricas</td><td>Sin recolección estructurada</td><td>EventBridge + Lambda + DynamoDB en tiempo real</td></tr><tr><td>Soporte ciudadano</td><td>Herramientas limitadas</td><td>Trazabilidad completa, tickets, agente IA + humano</td></tr><tr><td>Notificaciones</td><td>No existe</td><td>Buzón ciudadano integrado</td></tr><tr><td>Diseño</td><td>Parcialmente responsive</td><td>Completamente responsive con diseño gubernamental</td></tr><tr><td>Internacionalización</td><td>Solo español</td><td>Español e inglés (extensible)</td></tr><tr><td>Logs</td><td>Sentry para errores</td><td>Estructura consolidada de eventos de ORY + app + errores</td></tr><tr><td>Código fuente</td><td>Open source parcial</td><td>Open source completo con guías de contribución</td></tr></tbody></table>

---

## Beneficios concretos

### Para los ciudadanos

El beneficio más inmediato es una experiencia más fluida y menos frustrante. El registro en tres pasos con el nuevo orden reduce el abandono. El diseño responsive permite registrarse cómodamente desde cualquier dispositivo. Los mensajes de error claros y en español ayudan al ciudadano a resolver problemas sin necesidad de llamar a soporte.

A mediano plazo, el buzón de notificaciones y el agente de IA transforman la cuenta de un simple mecanismo de login a un punto de contacto útil con el gobierno. El ciudadano puede recibir información relevante, obtener ayuda inmediata y resolver problemas sin tener que desplazarse a oficinas gubernamentales o esperar en líneas telefónicas.

### Para las instituciones gubernamentales

Las instituciones que integran CUC como su mecanismo de autenticación se benefician de métricas detalladas sobre el uso de sus integraciones: cuántos ciudadanos acceden a su servicio a través de CUC, en qué horarios, desde qué dispositivos. Esto les permite dimensionar mejor sus recursos y entender el comportamiento de sus usuarios.

Además, el canal de notificaciones les da una vía directa para comunicarse con los ciudadanos que usan sus servicios, sin depender de infraestructura propia de mensajería.

### Para el equipo de OGTIC

El equipo pasa de operar a ciegas a tener visibilidad completa del ecosistema. Las métricas en tiempo real permiten detectar problemas antes de que afecten a muchos ciudadanos. La trazabilidad del journey reduce drásticamente el tiempo de resolución de casos de soporte. El backoffice elimina la necesidad de intervenciones manuales directas en la base de datos o en ORY Network.

El hecho de ser open source también atrae talento: desarrolladores dominicanos pueden contribuir al proyecto, lo que multiplica la capacidad del equipo sin aumentar el presupuesto.

## Conclusión

CUC v1 sentó las bases de la identidad digital en la República Dominicana y demostró que era posible tener un sistema unificado de autenticación para los servicios gubernamentales. CUC v2 toma esas bases y construye sobre ellas un producto completo: no solo un sistema de login, sino una plataforma de identidad digital que conecta al ciudadano con su gobierno de forma permanente, segura e inteligente.

Los cambios no son cosméticos. Se está reconstruyendo la experiencia del ciudadano, se están creando herramientas que antes no existían para el equipo de soporte, se está implementando una infraestructura de datos que permite tomar decisiones basadas en evidencia, y se está abriendo el código para que la comunidad pueda participar. Es, en esencia, el paso de un MVP exitoso a un producto maduro que aspira a ser referente en la región.

# Resumen ejecutivo

## El contexto

Hoy en día, cuando un ciudadano dominicano necesita hacer un trámite en línea con el gobierno, usa un sistema llamado Cuenta Única Ciudadana (CUC). En vez de tener un usuario y contraseña diferente para cada portal gubernamental, CUC le permite al ciudadano tener una sola cuenta, vinculada a su número de cédula, para acceder a todos los servicios digitales del Estado.

Este sistema lleva operando desde finales de 2022 y está integrado con servicios como el portal gob.do, la aplicación Soy Yo RD (Carpeta Ciudadana), el portal de becas del gobierno, entre otros. Fue desarrollado por la División de Arquitectura Digital Gubernamental de la OGTIC y representó un avance significativo en la modernización de la relación entre el ciudadano y el Estado.

La versión actual funciona. Los ciudadanos pueden registrarse verificando su identidad con reconocimiento facial (comparando su rostro con la foto de la Junta Central Electoral), crear su cuenta y usarla para acceder a los servicios integrados. La seguridad es sólida, basada en estándares internacionales como OAuth 2.0 y OpenID Connect.

## Por qué se necesita una nueva versión

Después de más de dos años en producción, se han identificado tres grandes oportunidades de mejora que la versión actual no puede resolver con ajustes menores.

La primera es la falta de visibilidad operativa. El equipo no tiene forma sencilla de saber cuántos ciudadanos se registran por día, cuáles servicios usan más CUC, en qué punto del registro se pierden los ciudadanos que no completan el proceso, o cuáles son los problemas más comunes. Sin esta información, es difícil tomar decisiones informadas sobre dónde invertir recursos para mejorar el servicio.

La segunda es la capacidad limitada de dar soporte. Cuando un ciudadano tiene un problema con su cuenta y llama a Atención Ciudadana, el equipo tiene herramientas muy básicas para diagnosticar qué pasó. No hay un historial detallado de las acciones del ciudadano, no hay forma de ver en qué paso se quedó si intentó registrarse y no pudo, y las acciones administrativas sobre las cuentas son limitadas.

La tercera es que CUC se queda corta como producto. Hoy la cuenta solo sirve para iniciar sesión en otros servicios. No le da al ciudadano una razón para visitar su cuenta, no tiene mecanismos de comunicación directa y no ofrece herramientas de autoservicio para resolver problemas comunes sin necesidad de contactar a soporte.

## Qué estamos construyendo

CUC versión 2 es una reconstrucción del sistema que mantiene las bases tecnológicas que funcionaron (la plataforma de identidades ORY Network y el reconocimiento facial de AWS) pero replantea la experiencia del ciudadano, crea herramientas internas robustas, e incorpora funcionalidades nuevas.

### Para el ciudadano

Un portal unificado donde todo ocurre en un solo sitio: el registro, el inicio de sesión, la gestión del perfil, la recuperación de contraseña. Ya no hay que saltar entre diferentes portales. El registro se simplificó de cuatro pasos a tres, con un orden que reduce la frustración. El diseño es responsive (funciona bien en celulares de cualquier gama) y más acorde con la imagen institucional del gobierno.

Un buzón de notificaciones donde el ciudadano puede recibir avisos de seguridad, comunicaciones gubernamentales, alertas sobre actividad sospechosa en su cuenta y respuestas a solicitudes de soporte. Esto convierte la cuenta de un simple mecanismo de login a un punto de contacto permanente con el gobierno digital.

Un asistente inteligente (en evaluación) que pueda ayudar al ciudadano a resolver dudas sobre su cuenta las 24 horas del día. Cuando el asistente no pueda resolver un problema, lo escala a un agente humano de Atención Ciudadana que ya tiene todo el contexto del caso.

### Para el equipo de soporte

Un backoffice completo que permite a los agentes de Atención Ciudadana buscar cualquier ciudadano, ver toda su información, entender exactamente qué pasó cuando algo falló (en qué paso se quedó, qué error tuvo, cuándo fue el último intento), y tomar acciones sobre la cuenta (desbloquear, resetear contraseña, enviar notificaciones). Esto transforma el soporte de reactivo y limitado a proactivo e informado.

### Para la toma de decisiones

Métricas en tiempo real que responden preguntas como: cuántos ciudadanos se registran por día, cuáles son las integraciones más usadas, en qué paso del registro se pierden los ciudadanos, cuáles son los errores más frecuentes. Toda esta información, que hoy no existe de forma estructurada, estará disponible en dashboards del backoffice.

## Estado actual del proyecto

El portal ciudadano tiene su estructura base construida y funcional en ambiente de desarrollo. Los flujos de registro (con verificación facial), inicio de sesión, recuperación de contraseña y verificación de email están implementados. La arquitectura de eventos del backoffice (que captura y procesa todo lo que ocurre en el sistema) está definida y en implementación con servicios de Amazon Web Services.

Queda pendiente completar las funcionalidades del perfil ciudadano, implementar el buzón de notificaciones, desarrollar el backoffice como producto terminado, definir la estrategia del agente inteligente, realizar pruebas de seguridad y usabilidad, y preparar la infraestructura de producción.

## Beneficios esperados

Para los ciudadanos, la experiencia de registro y uso de su cuenta digital será más sencilla, más rápida y más útil. Tendrán un canal directo de comunicación con el gobierno y acceso a ayuda inmediata cuando la necesiten.

Para las instituciones gubernamentales que integran CUC, tendrán visibilidad del uso de sus servicios y un canal de comunicación con los ciudadanos que los usan.

Para la OGTIC, el equipo pasará de operar con visibilidad limitada a tener control completo del ecosistema. Los tiempos de resolución de problemas se reducirán drásticamente. Las decisiones sobre mejoras se basarán en datos reales, no en intuición.

Para el país, CUC v2 será un proyecto de código abierto (open source), lo que significa que el código será público y cualquier persona podrá revisarlo, contribuir a mejorarlo o incluso adaptarlo. Esto posiciona a la República Dominicana como referente en gobierno digital abierto en la región del Caribe y América Latina, siguiendo el ejemplo de países como Estonia y Estados Unidos que han adoptado el modelo open source para sus servicios de identidad digital.

## Siguiente paso

El equipo de Arquitectura Digital Gubernamental continúa el desarrollo activo de CUC v2. Se estima que el portal ciudadano y el backoffice base estarán listos para pruebas internas en las próximas semanas, seguidos de una fase de pruebas con usuarios reales antes del lanzamiento público.

El apoyo institucional es fundamental para el éxito de este proyecto, particularmente en tres áreas: la coordinación con las instituciones que ya integran CUC para una transición sin interrupciones, la disponibilidad de recursos para completar el desarrollo y las pruebas de seguridad, y la definición de políticas de gobernanza para las nuevas funcionalidades (especialmente el canal de notificaciones).

# Seguridad y cumplimiento



# Roadmap del proyecto

## 1. Portal Ciudadano

Esta es la aplicación principal que usan los ciudadanos. Es un proyecto en Next.js 16 con App Router, integrado con ORY Network para la gestión de identidades y AWS Rekognition para la verificación biométrica.

### Lo que ya se hizo

El esqueleto de la aplicación está construido y funcional en ambiente de desarrollo. Se tomaron decisiones fundamentales de arquitectura que definen el rumbo del proyecto:

Se eligió Next.js 16 como framework principal, aprovechando el App Router y los React Server Components para tener una separación clara entre lo que se ejecuta en el servidor y lo que llega al navegador del ciudadano. Esta decisión se tomó porque Next.js permite renderizar las páginas en el servidor, lo que mejora tanto el rendimiento como el SEO, algo importante para un portal gubernamental que debe ser accesible desde cualquier dispositivo y conexión.

La integración con ORY Network está funcionando. Se implementaron los flujos de inicio de sesión, recuperación de contraseña, verificación de email y gestión de configuraciones del usuario, todos delegados a los componentes oficiales de ORY Elements React. Esto significa que no estamos reinventando la rueda en temas de seguridad: ORY maneja el almacenamiento de credenciales, la emisión de tokens OAuth 2.0 y los flujos de OpenID Connect.

El flujo de registro de tres pasos ya está implementado en su forma base. El primer paso valida la cédula del ciudadano contra la API del Registro Civil dominicano. El segundo paso recoge el correo electrónico y la contraseña. El tercer paso realiza la verificación facial usando AWS Rekognition Face Liveness, que compara el rostro en vivo del ciudadano con la foto almacenada en la base de datos de la Junta Central Electoral. Este cambio de orden respecto a la versión anterior (donde la verificación facial era el segundo paso) fue intencional: permite que el ciudadano complete la información de su cuenta antes de pasar por el proceso biométrico, reduciendo la frustración en caso de que necesite corregir datos.

Se configuró la internacionalización con next-intl, soportando español e inglés. Todas las cadenas de texto están externalizadas en archivos de traducción, lo que facilita agregar nuevos idiomas en el futuro.

El sistema de componentes UI está basado en shadcn/ui con Radix UI y Tailwind CSS. Esto nos da componentes accesibles por defecto (cumplen con ARIA) y un sistema de diseño consistente. Se implementó soporte para modo oscuro usando next-themes.

La validación de formularios usa Zod para esquemas de validación y React Hook Form para la gestión del estado de los formularios. Esto asegura que los datos se validen tanto en el cliente como en el servidor.

Se crearon las rutas protegidas del dashboard ciudadano: página principal, perfil, configuraciones, historial, soporte y acerca de. Aunque varias de estas páginas aún son esqueletos, la estructura de navegación y el sistema de protección de rutas (que verifica la sesión de ORY antes de permitir el acceso) están completos.

El pipeline de CI/CD está configurado con GitHub Actions para desplegar automáticamente a Google Cloud Run cuando se hace push a la rama staging. El Dockerfile usa una imagen base de Bun para builds rápidos y produce una imagen optimizada con el output standalone de Next.js.

Las API routes del servidor están implementadas para todo el flujo de registro: búsqueda de ciudadano por cédula, creación de cuenta, creación de sesión de liveness, verificación de resultado de liveness, y reset de sesión de registro. También están las rutas para gestión de sesiones de ORY (obtener sesión actual, revocar sesiones, logout).

### Lo que está en progreso

El diseño visual gubernamental está siendo refinado. Aunque la estructura está lista, se necesita pulir la experiencia visual para que se sienta institucional pero moderna. Esto incluye el landing page, las transiciones entre pasos del registro y la consistencia visual en todas las pantallas.

Se está trabajando en la gestión de errores. El código tiene manejo básico de errores, pero falta una estrategia unificada que cubra todos los escenarios: errores de red, timeouts de ORY, fallos de Rekognition, problemas con la cámara del dispositivo, etc. Cada error debe mostrar un mensaje claro al ciudadano y, al mismo tiempo, registrarse internamente para que el equipo de soporte pueda diagnosticarlo.

### Lo que falta por hacer

**Funcionalidades del Dashboard Ciudadano.** Las páginas del dashboard están creadas como esqueletos pero necesitan contenido real. La página de perfil debe mostrar la información del ciudadano extraída de los traits de ORY (nombre, cédula, fecha de nacimiento, género). La página de historial debe mostrar las sesiones activas y el historial de actividad. La página de configuraciones necesita permitir el cambio de contraseña, la activación de segundo factor de autenticación (2FA) y la gestión de preferencias de notificación.

**Sistema de Notificaciones (Buzón Ciudadano).** Esta es una funcionalidad completamente nueva que no existía en CUC v1. La idea es que los ciudadanos puedan recibir notificaciones dentro de su cuenta: avisos de seguridad, comunicaciones gubernamentales, alertas de actividad sospechosa, recordatorios de trámites pendientes, entre otros. Se necesita definir la arquitectura del sistema de notificaciones (almacenamiento, entrega en tiempo real vs polling, tipos de notificación), diseñar la interfaz del buzón, implementar la API de notificaciones y conectarla con el backoffice para que los agentes puedan enviar notificaciones.

**Agente de Inteligencia Artificial.** Se planea incorporar un agente conversacional que ayude a los ciudadanos a resolver dudas sobre su cuenta, guiarlos en procesos y, cuando no pueda resolver un problema, escalar a un agente humano de Atención Ciudadana. La tecnología aún está en evaluación. Se debe definir qué modelo de lenguaje usar, cómo integrarlo en la interfaz, qué conocimiento base necesita, cómo manejar la escalación a humanos y cómo garantizar que las respuestas sean precisas y no generen confusión en temas gubernamentales.

**Mejoras en la Verificación Facial.** El flujo básico funciona, pero hay escenarios que necesitan mejor manejo: qué pasa cuando el ciudadano no tiene cámara, cuando la iluminación es mala, cuando el navegador no soporta la API de MediaDevices, cuando el rostro no coincide pero el ciudadano insiste en que es él. Se necesita una estrategia de fallback y un proceso claro de escalación para estos casos.

**Gestión de Dispositivos y Sesiones.** ORY maneja las sesiones, pero el ciudadano necesita poder ver en cuántos dispositivos tiene sesión activa y poder cerrar sesiones remotamente. Esto ya se ve en el código como un endpoint de revocación de sesión, pero la interfaz para que el ciudadano lo use aún no está construida.

**Accesibilidad.** Aunque shadcn/ui y Radix UI proporcionan componentes accesibles por defecto, se necesita una auditoría completa de accesibilidad (WCAG 2.1 AA como mínimo) en todos los flujos. Un portal gubernamental debe ser usable por personas con discapacidades visuales, motoras o cognitivas.

**Pruebas Automatizadas.** No hay tests en el proyecto actualmente. Se necesita implementar pruebas unitarias para la lógica de negocio (validaciones, servicios), pruebas de integración para las API routes, y pruebas end-to-end para los flujos críticos (registro, login, recuperación de contraseña). Dado que es un sistema de identidad, las pruebas son fundamentales para evitar regresiones que puedan afectar a miles de ciudadanos.

**Documentación del Proyecto Open Source.** Si el proyecto será open source, necesita un README completo, guías de contribución (CONTRIBUTING.md), código de conducta (CODE\_OF\_CONDUCT.md), documentación de la API interna, y guías para que desarrolladores externos puedan levantar el proyecto localmente.

**Seguridad: Rate Limiting y Protección contra Abuso.** La versión anterior usaba reCAPTCHA y Cloudflare. En la nueva versión, se necesita definir qué mecanismos de protección se van a implementar: rate limiting en las API routes, protección contra fuerza bruta en el login (ORY tiene esto incorporado, pero hay que configurarlo correctamente), y protección contra bots en el registro.

**Monitoreo y Observabilidad.** La versión anterior usaba Sentry. Se necesita decidir si se continúa con Sentry o se migra a otra solución. Además, se deben implementar métricas de rendimiento (tiempos de respuesta, tasas de error), métricas de negocio (registros completados vs abandonados, pasos donde se pierden usuarios), y alertas automáticas cuando algo falle.

## 2. Backoffice

El backoffice es una aplicación separada, también en Next.js 16, que le da herramientas al equipo de Atención Ciudadana y a los administradores para gestionar las cuentas de los ciudadanos y darles soporte.

### Lo que ya se hizo

Se definió la arquitectura base en AWS: EventBridge recibe los eventos (webhooks) que emite ORY Network cada vez que ocurre algo relevante (un ciudadano se registra, inicia sesión, cambia su contraseña, falla un intento de login, etc.). Estos eventos son procesados por funciones Lambda que los transforman y almacenan en DynamoDB. Esta arquitectura permite escalar horizontalmente sin preocuparse por la infraestructura, ya que cada componente es serverless.

### Lo que está en progreso

Se está trabajando en el diseño y la implementación de la aplicación web del backoffice. Las funcionalidades principales que se están construyendo incluyen la búsqueda y visualización de cuentas ciudadanas, la capacidad de realizar acciones sobre las cuentas (bloquear, desbloquear, restaurar, eliminar), y la visualización de métricas en tiempo real.

### Lo que falta por hacer

**Dashboard de Métricas en Tiempo Real.** Los administradores necesitan poder ver: cuántos ciudadanos se han registrado hoy, esta semana, este mes. Cuáles son las integraciones OAuth más populares (qué servicios gubernamentales reciben más tráfico desde CUC). En qué paso del registro se quedan los ciudadanos que no completan el proceso. Cuáles son los errores más frecuentes. Cuántas sesiones activas hay en este momento. Todo esto debe alimentarse de los eventos que llegan a EventBridge y se procesan con Lambda.

**Gestión de Cuentas Ciudadanas.** Los agentes de Atención Ciudadana necesitan poder buscar un ciudadano por cédula, correo o nombre. Ver toda la información de su cuenta. Ver el historial completo de actividad (cada login, cada cambio de contraseña, cada error). Realizar acciones administrativas como resetear la contraseña, desbloquear la cuenta, verificar manualmente una identidad cuando el proceso biométrico falle.

**Trazabilidad Completa del Journey del Ciudadano.** Esta es una de las funcionalidades más ambiciosas. La idea es que cuando un ciudadano llame a soporte diciendo "intenté registrarme y no pude", el agente pueda ver exactamente qué pasó: el ciudadano ingresó su cédula a las 10:15am, la validación fue exitosa, pasó al paso 2, ingresó su correo, pasó al paso 3, la verificación facial falló con un error de iluminación insuficiente a las 10:18am, el ciudadano lo intentó de nuevo y falló por timeout a las 10:19am, y luego abandonó el proceso. Para lograr esto, se necesita que el portal ciudadano envíe eventos detallados de cada acción del usuario, no solo los eventos que ORY emite naturalmente.

**Sistema de Tickets y Escalación.** Cuando el agente de IA no pueda resolver un problema del ciudadano, debe crear un ticket que un agente humano pueda gestionar desde el backoffice. Se necesita diseñar el flujo completo: cómo se crea el ticket, qué información incluye, cómo se asigna a un agente, cómo se le da seguimiento, y cómo se notifica al ciudadano cuando su caso se resuelve.

**Envío de Notificaciones.** Los agentes deben poder enviar notificaciones a ciudadanos individuales o grupos de ciudadanos desde el backoffice. Estas notificaciones llegan al buzón ciudadano del portal. Se necesita definir los tipos de notificación, las plantillas, y quién tiene permisos para enviar qué tipo de notificación.

**Control de Acceso Basado en Roles (RBAC).** El backoffice tendrá diferentes tipos de usuarios: administradores con acceso total, agentes de Atención Ciudadana con acceso limitado a gestión de cuentas y soporte, y visualizadores que solo pueden ver métricas. Se necesita implementar este sistema de permisos.

## 3. Infraestructura y DevOps

### Lo que ya se hizo

El CI/CD del portal ciudadano está configurado con GitHub Actions desplegando a Google Cloud Run. El Dockerfile está optimizado con multi-stage builds usando Bun como runtime. Las variables de entorno están separadas correctamente entre las de build time (NEXT\_PUBLIC\_\*) y las de runtime.

### Lo que falta por hacer

**Ambientes de Desarrollo, Staging y Producción.** Actualmente solo hay configuración para staging. Se necesita definir y configurar los tres ambientes con sus respectivas variables de entorno, URLs de ORY, credenciales de AWS, y dominios.

**Infraestructura como Código.** Los recursos de AWS (EventBridge, Lambda, DynamoDB) y de GCP (Cloud Run, Artifact Registry) deben estar definidos en código, idealmente usando Terraform o AWS CDK para los recursos de AWS y Terraform para los de GCP. Esto permite replicar la infraestructura de forma determinística y mantener un historial de cambios.

**Monitoreo de Infraestructura.** Se necesitan dashboards de CloudWatch para los recursos de AWS y de Cloud Monitoring para Cloud Run. Alertas automáticas cuando hay errores, latencia alta, o recursos saturados.

**Dominio y SSL.** Definir cuál será el dominio de CUC v2 (si se mantiene cuentaunica.gob.do o se migra a algo bajo digital.gob.do), configurar los certificados SSL y la integración con Cloudflare o el servicio de protección DDoS que se elija.

**Backups y Recuperación ante Desastres.** Aunque ORY Network maneja las identidades en su infraestructura, se necesita una estrategia de respaldo para los datos en DynamoDB, los logs, y las configuraciones. También se necesita un plan de recuperación ante desastres que defina los tiempos máximos aceptables de inactividad (RTO) y de pérdida de datos (RPO).

## 4. Seguridad

### Lo que ya se hizo

ORY Network proporciona cifrado en tránsito (HTTPS/TLS 1.2+), cifrado en reposo (AES-256), hash seguro de contraseñas (bcrypt con salt), y tokens de sesión con expiración configurable. AWS Rekognition maneja los datos biométricos bajo los estándares de cumplimiento de AWS (SOC 2, ISO 27001). La validación de cédulas incluye verificación de formato y checksum.

### Lo que falta por hacer

**Auditoría de Seguridad.** Antes del lanzamiento, se necesita una auditoría de seguridad completa: revisión del código, pruebas de penetración, y verificación de cumplimiento con las normativas dominicanas de protección de datos.

**Política de Contraseñas.** Definir y documentar la política de contraseñas: longitud mínima, complejidad requerida, verificación contra bases de datos de contraseñas filtradas (ORY soporta esto con HaveIBeenPwned), y política de expiración.

**Segundo Factor de Autenticación (2FA).** ORY soporta TOTP (Google Authenticator, Authy) y WebAuthn (llaves de seguridad, biometría del dispositivo). Se necesita implementar la interfaz para que los ciudadanos puedan activar y gestionar su 2FA.

**Manejo de Datos Sensibles.** Documentar qué datos personales se almacenan, dónde se almacenan, quién tiene acceso, por cuánto tiempo se retienen, y cómo se eliminan cuando el ciudadano lo solicita. Esto es especialmente importante para un proyecto open source donde el código es público.

## 5. Experiencia de Usuario e Investigación

### Lo que falta por hacer

**Pruebas de Usabilidad.** Antes del lanzamiento, se deben realizar pruebas de usabilidad con ciudadanos reales: personas de diferentes edades, niveles de educación, y familiaridad con tecnología. El registro con verificación facial es un proceso que puede intimidar a muchas personas, y necesitamos asegurarnos de que las instrucciones sean claras y el proceso sea lo más sencillo posible.

**Optimización del Flujo de Registro.** Medir la tasa de abandono en cada paso del registro e identificar oportunidades de mejora. Si muchos ciudadanos abandonan en la verificación facial, tal vez necesitamos mejorar las instrucciones o el manejo de errores en ese paso.

**Soporte para Dispositivos de Gama Baja.** Muchos ciudadanos dominicanos usan dispositivos Android de gama baja con cámaras de baja resolución. Se necesita probar el flujo de verificación facial en estos dispositivos y ajustar los umbrales de confianza si es necesario.

**Página de Estado del Servicio.** Crear una página pública donde los ciudadanos puedan verificar si CUC está funcionando correctamente. Esto reduce la carga de soporte cuando hay interrupciones planificadas o incidentes.

## Resumen del estado actual

Para tener una vista rápida del progreso general:

El portal ciudadano tiene su estructura base completa, con los flujos de autenticación y registro funcionando en desarrollo. Las decisiones de arquitectura están tomadas y validadas. Sin embargo, falta completar las funcionalidades del dashboard, el sistema de notificaciones, el agente de IA, las pruebas automatizadas, y la auditoría de seguridad y accesibilidad.

El backoffice tiene su arquitectura AWS definida pero la aplicación web está en etapas tempranas de desarrollo. Las funcionalidades más ambiciosas como la trazabilidad completa del journey del ciudadano y el sistema de tickets requieren trabajo coordinado entre el equipo del portal y el del backoffice.

La infraestructura necesita madurar en cuanto a ambientes, infraestructura como código, monitoreo, y planes de recuperación ante desastres.

Este es un proyecto ambicioso, y reconocemos que hay mucho por hacer. Pero la base es sólida: las decisiones tecnológicas están tomadas, la integración con ORY funciona, la verificación biométrica está probada, y el equipo tiene claridad sobre hacia dónde vamos.

# Propuesta de valor