8. Modo headless (servidor)
Nota
Esta sección describe un modo avanzado y opcional de blunderDB, destinado a los despliegues en servidor, al uso multiusuario y a la automatización. El uso normal y recomendado de blunderDB sigue siendo la aplicación de escritorio descrita en los capítulos anteriores. Si utiliza blunderDB en solitario, en su propio ordenador, no necesita este modo: puede ignorar este capítulo sin perder ninguna de las funcionalidades de análisis.
8.1. Visión general
El mismo binario blunderdb puede, además de la aplicación de escritorio y de los comandos en línea (véase Interfaz de línea de comandos (CLI)), funcionar en modo headless: sin interfaz gráfica, controlado por completo desde la línea de comandos o a través de la red. Este modo agrupa tres usos:
el demonio
serve— expone el motor de blunderDB como un servicio HTTP + JSON, para ejecutar una base compartida en un servidor y acceder a ella entre varios usuarios;el despachador genérico
call— invoca cualquier operación de almacenamiento directamente, en local, para el scripting y las pruebas;el comando
migrate— transfiere una base SQLite de un solo usuario a un backend PostgreSQL multiusuario.
Estos tres usos se apoyan en una capa de almacenamiento común capaz de comunicarse con dos backends: SQLite (el formato de archivo .db habitual de la aplicación de escritorio) y PostgreSQL (para los despliegues en servidor multiusuario).
8.2. El demonio serve
blunderdb serve lanza el motor como un servicio HTTP que responde en JSON. Permite alojar una base de posiciones en una máquina y acceder a ella desde varios clientes.
# Servir une base SQLite locale sur le port 8080
blunderdb serve --db ma_base.db --addr :8080
# Servir un backend PostgreSQL
blunderdb serve --backend postgres \
--dsn "postgres://user:pass@host:5432/blunderdb?sslmode=disable" \
--addr :8080
Advertencia
El demonio no realiza ninguna autenticación. Confía en la cabecera de petición X-Tenant-ID y debe ejecutarse detrás de un reverse-proxy (nginx, Caddy…) encargado de la autenticación. Nunca lo exponga directamente en la Internet pública.
Opciones:
Opción |
Por defecto |
Significado |
|---|---|---|
|
– |
archivo SQLite (atajo de |
|
|
backend de almacenamiento: |
|
|
cadena de conexión del backend |
|
|
dirección de escucha |
|
|
nivel de registro: |
|
|
expone |
|
– |
activa CORS para este origen (desactivado por defecto) |
|
|
límite de peticiones por segundo y por tenant (0 = desactivado) |
|
|
tamaño del cubo de tokens para los picos de peticiones |
|
|
PostgreSQL: activa la Row-Level Security por tenant (defensa en profundidad, opcional) |
La mayoría de las opciones también pueden indicarse mediante variables de entorno (BLUNDERDB_BACKEND, BLUNDERDB_DSN, BLUNDERDB_ADDR, BLUNDERDB_LOG_LEVEL, BLUNDERDB_RLS).
8.2.1. Puntos de acceso
El servicio expone puntos de acceso de explotación, siempre presentes:
GET /healthz— vivacidad (el proceso está en ejecución);GET /readyz— disponibilidad (el almacenamiento responde);GET /metrics— métricas Prometheus (si--metricsestá activo).
La superficie funcional sigue el esquema POST /v1/<famille>.<méthode> (por ejemplo /v1/positions.save, /v1/matches.get). Las familias abarcan las posiciones, análisis, partidas, comentarios, colecciones, torneos, tarjetas Anki, filtros, sesiones, búsqueda, metadatos, estadísticas e importación. Los endpoints de listado devuelven un flujo NDJSON (un objeto JSON por línea). El servidor se detiene limpiamente con SIGINT / SIGTERM.
Dos métodos de la familia positions decodifican una posición sin guardarla: positions.fromXGID reconstruye una posición a partir de una cadena XGID, y positions.fromXGP a partir de un archivo de posición única .xgp.
8.3. Backend PostgreSQL y multiusuario
Para un despliegue compartido, blunderDB puede almacenar los datos en PostgreSQL en lugar de en un archivo SQLite. El backend se selecciona mediante --backend postgres y la cadena de conexión --dsn. El esquema se crea y se migra automáticamente al arrancar.
Los datos están compartimentados por tenant (inquilino): cada petición lleva un identificador de scope (cabecera X-Tenant-ID, por defecto default), lo que permite que varios usuarios compartan la misma instancia sin ver los datos de los demás. La opción --rls activa además la Row-Level Security de PostgreSQL: se instalan políticas de aislamiento por tenant y app.tenant_id se fija por conexión. Es una defensa en profundidad opcional, desactivada por defecto.
8.4. Migrar una base SQLite a PostgreSQL
blunderdb migrate copia una base SQLite de un solo usuario a un backend PostgreSQL, bajo un scope de tenant elegido: es la vía para « subir » una biblioteca de escritorio a un despliegue en servidor.
blunderdb migrate \
--from sqlite:///chemin/vers/base.db \
--to "postgres://user:pass@host:5432/db?sslmode=disable" \
--tenant-id mon-tenant
# Prévisualiser sans rien écrire
blunderdb migrate --from sqlite:///chemin/vers/base.db \
--tenant-id mon-tenant --dry-run
La migración copia las posiciones, sus análisis y comentarios, las partidas (juegos + jugadas), los torneos (con sus vínculos de partida) y las colecciones (con su composición), reasignando las claves primarias y foráneas, todo ello en una única transacción del lado de destino: la operación es atómica (un fallo deja el destino intacto, basta con relanzarla). El progreso y el balance final se emiten en NDJSON por la salida estándar.
Opción |
Por defecto |
Significado |
|---|---|---|
|
– |
base SQLite de origen ( |
|
– |
DSN PostgreSQL de destino ( |
|
– |
scope de tenant de destino (obligatorio salvo en |
|
– |
cuenta lo que se copiaría sin escribir nada |
|
|
|
Nota
No se migran (todavía) los estados de la aplicación: mazos/tarjetas Anki, biblioteca de filtros, historial de búsqueda y de comandos, y metadatos de sesión. La prioridad es la migración de la biblioteca de posiciones y del historial de partidas.
8.5. El despachador genérico call
Como complemento de los subcomandos históricos (Interfaz de línea de comandos (CLI)), blunderdb call expone todas las operaciones de almacenamiento directamente, en local. Pasa por los mismos gestores que el demonio serve: el comportamiento es, por tanto, idéntico al de POST /v1/<famille>.<méthode>. Resulta útil para el scripting y las pruebas de integración.
# Lister toutes les méthodes disponibles
blunderdb call --list
# Lectures
blunderdb call metadata.counts --db ma_base.db
blunderdb call positions.list --db ma_base.db --json '{"limit":10}'
blunderdb call matches.get --db ma_base.db --json '{"id":1}'
# Écritures
blunderdb call positions.save --db ma_base.db --json '{"position":{...}}'
blunderdb call matches.delete --db ma_base.db --json '{"id":42}'
Opciones:
Opción |
Por defecto |
Significado |
|---|---|---|
|
– |
archivo SQLite (atajo de |
|
|
|
|
|
cadena de conexión del backend |
|
|
scope de tenant (enviado como |
|
|
cuerpo de la petición en formato JSON |
|
– |
lee el cuerpo de la petición desde un archivo |
|
– |
muestra todos los métodos |
La respuesta JSON (o el flujo NDJSON para los endpoints *.list) se escribe en la salida estándar. En caso de error, el proceso termina con un código distinto de cero y la envoltura {"error":{…}} se imprime en la salida estándar para seguir siendo analizable (por ejemplo con jq).