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)
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: transitorio, prácticamente no se observa desde afuera (pasa aEN_PROCESOen la misma llamada de recepción).EN_PROCESO: el archivo está esperando a quessigner-serverlo 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.