Saltar a contenido

Modelo de datos

Este servicio comparte una única base de datos SQLite con ssigner-server (la app de escritorio que firma los documentos). El archivo se llama ssigner.db, y usa journal_mode=WAL específicamente para permitir que los dos procesos escriban al mismo tiempo sin corromper datos.

No hay un servidor de base de datos aparte — es un archivo, ubicado en una ruta fija del servidor (SSIGNER_DB_PATH).

Diagrama de relaciones

erDiagram
    clientes ||--o{ procesos : "es dueño de"
    clientes ||--o{ usuarios : "tiene"
    certificados ||--o{ procesos : "usa"
    usuarios }o--o{ procesos : "usuario_procesos (N:N)"
    procesos ||--o{ documentos : "genera"
    clientes_api ||--o{ documentos : "origina (opcional)"

Las 7 tablas

Tabla Qué guarda Quién la escribe Este servicio la...
clientes Las organizaciones a las que se les presta el servicio (ej. "OEFA") — la unidad de multi-tenancy Este servicio (vía la API de administración) Escribe
usuarios Personas: 1 admin único global (cliente_id NULL) + N firmantes (pertenecen a un cliente) Este servicio Escribe
usuario_procesos Join N:N — qué procesos puede operar cada firmante Este servicio (el ADMIN asigna) Escribe
clientes_api Credenciales machine-to-machine (client_id / secreto hasheado) Este servicio Escribe
documentos Un job de firma: documento recibido, proceso asociado, estado Este servicio Escribe
certificados Certificados digitales registrados y su vigencia ssigner-server Solo lee (para validar el certificado que corresponde a un proceso)
procesos Un "proceso de firma" configurado: rutas, certificado, apariencia de la firma ssigner-server Solo lee (para resolver la ruta de entrada y validar que el proceso exista/esté activo)

La regla general: quien no es dueño de una tabla, solo la lee. Este servicio nunca modifica certificados ni procesos — esa configuración vive enteramente del lado de ssigner-server, manejada por soporte técnico.

Detalle de las tablas que este servicio SÍ escribe

clientes

id              INTEGER PRIMARY KEY
nombre          TEXT NOT NULL
razon_social    TEXT
activo          INTEGER NOT NULL DEFAULT 1
fecha_creacion  TEXT NOT NULL

usuarios

id              INTEGER PRIMARY KEY
cliente_id      INTEGER REFERENCES clientes(id)   -- NULL para el admin global
nombre          TEXT NOT NULL
username        TEXT NOT NULL UNIQUE
password_hash   TEXT NOT NULL                      -- BCrypt, nunca en claro
rol             TEXT NOT NULL                       -- 'ADMIN' | 'FIRMANTE'
activo          INTEGER NOT NULL DEFAULT 1
fecha_creacion  TEXT NOT NULL

usuario_procesos

usuario_id  INTEGER NOT NULL REFERENCES usuarios(id)
proceso_id  INTEGER NOT NULL REFERENCES procesos(id)
PRIMARY KEY (usuario_id, proceso_id)
Importante: cada llamada a POST /api/v1/usuarios/{id}/procesos reemplaza la lista completa de esta tabla para ese usuario — no es un "agregar", es un "set". Ver Referencia de API.

clientes_api

id                  INTEGER PRIMARY KEY
nombre              TEXT NOT NULL
client_id           TEXT NOT NULL UNIQUE
client_secret_hash  TEXT NOT NULL   -- BCrypt, nunca en claro
activo              INTEGER NOT NULL DEFAULT 1
fecha_creacion      TEXT NOT NULL

documentos

tracking_id                    TEXT PRIMARY KEY     -- UUID generado al recibir el documento
id_proceso                     INTEGER NOT NULL REFERENCES procesos(id)
cliente_api_id                 INTEGER REFERENCES clientes_api(id)  -- NULL si lo envió un usuario, no un sistema
nombre_archivo_original         TEXT NOT NULL
nombre_archivo_fisico           TEXT NOT NULL         -- '<tracking_id>_<nombre_original>.pdf'
serial_certificado_solicitado   TEXT NOT NULL
ruta_entrada_generada           TEXT NOT NULL
ruta_salida_esperada            TEXT NOT NULL
estado                          TEXT NOT NULL DEFAULT 'RECIBIDO'
                                     -- RECIBIDO | EN_PROCESO | FIRMADO | ERROR | ENTREGADO
mensaje_error                   TEXT
fecha_recibido                  TEXT NOT NULL
fecha_firmado                   TEXT
fecha_entregado                 TEXT

Las tablas que solo se leen (propiedad de ssigner-server)

certificados (solo lectura)

Certificados digitales disponibles, con su vigencia (fecha_expiracion). Este servicio no necesita el detalle completo — cuando responde con información de un proceso, incluye un resumen del certificado asociado (alias, serial, commonName, fechaExpiracion).

procesos (solo lectura)

Tiene decenas de columnas del lado de ssigner-server (rutas, ~45 columnas de apariencia de firma: texto, imagen, TSA, glosa, QR, código de barras, posición vertical u horizontal). Este servicio solo necesita un subconjunto pequeño para operar:

id              -- este es el idProcesoFirma que se usa en toda la API
nombre
activo
cliente_id      -- nullable: no todo proceso pertenece a un cliente externo
certificado_id
ruta_entrada
ruta_salida

Estados de un documento

RECIBIDO → EN_PROCESO → FIRMADO → ENTREGADO
                ↓
              ERROR   (si pasan más de 15 minutos sin firmarse)
  • RECIBIDO: transitorio, prácticamente no se observa desde afuera (pasa a EN_PROCESO en la misma llamada de recepción).
  • EN_PROCESO: el archivo está esperando a que ssigner-server lo detecte y firme.
  • FIRMADO: ya está disponible para descargar.
  • ENTREGADO: alguien ya lo descargó al menos una vez (se marca automáticamente en la primera descarga exitosa).
  • ERROR: no se firmó a tiempo, o algo falló en el camino.

Migraciones

ssigner-server es responsable de correr las migraciones de esquema al arrancar (el script schema.sql de este servicio usa CREATE TABLE IF NOT EXISTS, así que nunca destruye datos existentes). Si necesitás agregar una columna a una tabla que este servicio SÍ posee, hacelo siguiendo el mismo patrón: agregar la columna al schema.sql para instalaciones nuevas, y un ALTER TABLE ADD COLUMN idempotente (verificando primero con PRAGMA table_info) para bases ya desplegadas.