8. Headless-tila (palvelin)

Muista

Tässä osiossa kuvataan blunderDB:n edistynyt ja valinnainen tila, joka on tarkoitettu palvelinkäyttöön, monikäyttäjäympäristöihin ja automaatioon. blunderDB:n tavanomainen ja suositeltu käyttötapa on edelleen työpöytäsovellus, joka kuvataan edellisissä luvuissa. Jos käytät blunderDB:tä yksin omalla tietokoneellasi, et tarvitse tätä tilaa: voit ohittaa tämän luvun menettämättä mitään analyysiominaisuuksista.

8.1. Yleiskatsaus

Sama blunderdb-binääri voi työpöytäsovelluksen ja komentorivikomentojen (katso Komentoriviliittymä (CLI)) lisäksi toimia headless-tilassa: ilman graafista käyttöliittymää, ohjattuna kokonaan komentoriviltä tai verkon kautta. Tämä tila kattaa kolme käyttötapaa:

  • demoni serve — tarjoaa blunderDB:n moottorin HTTP + JSON -palveluna, jotta jaettua tietokantaa voidaan pyörittää palvelimella ja käyttää usean käyttäjän kesken;

  • yleiskäyttöinen call-välittäjä — kutsuu mitä tahansa tallennustoimintoa suoraan paikallisesti, skriptausta ja testausta varten;

  • migrate-komento — siirtää yhden käyttäjän SQLite-tietokannan monikäyttäjäiseen PostgreSQL-taustajärjestelmään.

Nämä kolme käyttötapaa nojaavat yhteiseen tallennuskerrokseen, joka osaa puhua kahdelle taustajärjestelmälle: SQLite (työpöytäsovelluksen tavanomainen .db-tiedostomuoto) ja PostgreSQL (monikäyttäjäisiin palvelinkäyttöönottoihin).

8.2. serve-demoni

blunderdb serve käynnistää moottorin HTTP-palveluna, joka vastaa JSON-muodossa. Sen avulla voi isännöidä asematietokantaa yhdellä koneella ja käyttää sitä useasta asiakkaasta.

# 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

Varoitus

Demoni ei suorita minkäänlaista todennusta. Se luottaa X-Tenant-ID-pyyntöotsakkeeseen ja on ajettava todennuksesta huolehtivan käänteisvälityspalvelimen (nginx, Caddy…) takana. Älä koskaan altista sitä suoraan julkiseen internetiin.

Valinnat:

Valinta

Oletus

Merkitys

--db <polku>

SQLite-tiedosto (oikotie komennolle --backend sqlite --dsn <polku>)

--backend <tyyppi>

sqlite

tallennustaustajärjestelmä: sqlite tai postgres

--dsn <merkkijono>

$BLUNDERDB_DSN

taustajärjestelmän yhteysmerkkijono

--addr <isäntä:portti>

:8080

kuunteluosoite

--log-level <taso>

info

lokitustaso: debug|info|warn|error

--metrics

true

tarjoaa /metrics (Prometheus-muoto)

--cors-allow-origin <alkuperä>

ottaa CORS:n käyttöön tälle alkuperälle (oletuksena pois käytöstä)

--rate-limit-rps <n>

0

pyyntöraja sekunnissa vuokralaista kohti (0 = pois käytöstä)

--rate-limit-burst <n>

2×rps

token-ämpärin koko pyyntöpiikkejä varten

--rls

false

PostgreSQL: ottaa käyttöön vuokralaiskohtaisen Row-Level Securityn (syvyyspuolustus, valinnainen)

--bearoff-ts <tiedosto>

valinnainen two-sided-bearoff-tietokanta (.bd), joka laajentaa sisäänrakennettua TS-06-06-tietokantaa EPC-päätepisteen kilpajuoksuanalyysiä varten; demoni ei koskaan lataa tietokantaa itse — liitä tiedosto taltiona ja osoita se tässä

Useimmat valinnat voidaan antaa myös ympäristömuuttujalla (BLUNDERDB_BACKEND, BLUNDERDB_DSN, BLUNDERDB_ADDR, BLUNDERDB_LOG_LEVEL, BLUNDERDB_RLS, BLUNDERDB_TS_PATH).

8.2.1. Päätepisteet

Palvelu tarjoaa hallinnolliset päätepisteet, jotka ovat aina läsnä:

  • GET /healthz — elossaolo (prosessi on käynnissä);

  • GET /readyz — valmius (tallennus vastaa);

  • GET /metrics — Prometheus-metriikat (jos --metrics on käytössä).

La surface métier suit le schéma POST /v1/<famille>.<méthode> (par exemple /v1/positions.save, /v1/matches.get). Les familles couvrent les positions, analyses, matchs, commentaires, collections, tournois, cartes Anki, filtres, sessions, historique (recherche et commandes), recherche, métadonnées, statistiques, import et export, ainsi que le cycle de vie des tenants (tenant.purge, réservé au backend PostgreSQL). Les endpoints de listing renvoient un flux NDJSON (un objet JSON par ligne). Le serveur s’arrête proprement sur SIGINT / SIGTERM.

Kaksi positions-perheen metodia purkaa aseman tallentamatta sitä: positions.fromXGID rakentaa aseman XGID-merkkijonosta ja positions.fromXGP yksittäisen aseman .xgp-tiedostosta.

anki-perhe saa kuusi uutta metodia, jotka laajentavat aikaväliin perustuvaa kertausajastinta (FSRS): anki.reviewLog (loki jokaisesta kertauksesta — arvosana ja FSRS-tulos — säilytystilastoja ja tarkkaa historiaa varten), anki.forecast (ennuste erääntyvien korttien määrästä tulevina päivinä, myöhässä olevat kortit mukaan lukien), anki.suspendCard / anki.buryCard / anki.removeCard (kortin poistaminen kertausjonosta väliaikaisesti tai pysyvästi) sekä anki.optimizeParams (säätää pakan tavoitesäilytysastetta kohti sen kertauksissa havaittua onnistumisastetta).

8.2.2. Käyttöönotto Dockerilla

Arkisto tarjoaa Dockerfile.serve-tiedoston, joka rakentaa demonista minimaalisen konttikuvan: vain serve-binääri käännetään (puhdas Go, ilman graafista käyttöliittymää ja ilman CGO:ta, siis staattisesti linkitetty) ja sijoitetaan sitten distroless-kuvaan.

# Construire l'image (depuis la racine du dépôt)
docker build -f Dockerfile.serve -t blunderdb-serve .

# Lancer le démon (le backend par défaut de l'image est postgres)
docker run --rm -p 8080:8080 \
    -e BLUNDERDB_DSN="postgres://user:pass@hôte:5432/blunderdb?sslmode=disable" \
    blunderdb-serve

Kuva kuuntelee porttia 8080 ja konfiguroidaan ympäristömuuttujilla (BLUNDERDB_BACKEND, BLUNDERDB_DSN, BLUNDERDB_ADDR, BLUNDERDB_RLS).

Varoitus

Kuten demoni itsekin, kontti ei suorita minkäänlaista todennusta: se on sijoitettava todennuksesta huolehtivan käänteisvälityspalvelimen taakse eikä sitä saa koskaan altistaa suoraan julkiseen internetiin.

8.3. PostgreSQL-taustajärjestelmä ja monikäyttäjäisyys

Jaettua käyttöönottoa varten blunderDB voi tallentaa tiedot PostgreSQL:ään SQLite-tiedoston sijaan. Taustajärjestelmä valitaan valinnalla --backend postgres ja yhteysmerkkijonolla --dsn. Skeema luodaan ja migroidaan automaattisesti käynnistyksen yhteydessä.

Tiedot on eristetty vuokralaisittain: jokainen pyyntö sisältää scope-tunnisteen (otsake X-Tenant-ID, oletuksena default), mikä sallii usean käyttäjän jakaa saman instanssin näkemättä toistensa tietoja. Valinta --rls ottaa lisäksi käyttöön PostgreSQL:n Row-Level Securityn: vuokralaiskohtaiset eristyskäytännöt asennetaan ja app.tenant_id asetetaan yhteyskohtaisesti. Tämä on valinnainen syvyyspuolustus, joka on oletuksena pois käytöstä.

Kun vuokralainen poistetaan käytöstä, POST /v1/tenant.purge poistaa pysyvästi kaikki sen tiedot (asemat, ottelut, kokoelmat, historia jne.) nykyiseltä vuokralaiselta (se, jonka otsake X-Tenant-ID määrittää), sekä sen istunnon tilan (viimeisin haku, viimeisin asema, avoimet välilehdet — ne muutamat metadata-rivit, joiden etuliitteenä on tämä scope): toiminto suoritetaan yhdessä transaktiossa, on idempotentti (tyhjän vuokralaisen tyhjentäminen tai kutsun toistaminen ei aiheuta virhettä) eikä vaikuta muihin vuokralaisiin eikä skeeman version globaaliin riviin. Se on käytettävissä vain PostgreSQL-taustajärjestelmän kanssa — SQLite-taustajärjestelmässä, jolla ei ole vuokralaisen käsitettä, se palauttaa invalid-virheen.

8.4. SQLite-tietokannan siirtäminen PostgreSQL:ään

blunderdb migrate kopioi yhden käyttäjän SQLite-tietokannan PostgreSQL-taustajärjestelmään valitun vuokralais-scopen alle — tämä on tapa « ladata » työpöytäkirjasto palvelinkäyttöönottoon.

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 migration copie les positions, leurs analyses et commentaires, les matchs (parties + coups), les tournois (avec leurs liens de match) et les collections (avec leur composition), en réattribuant les clés primaires et étrangères, le tout dans une seule transaction côté destination : l’opération est atomique (un échec laisse la destination intacte, il suffit de relancer). La progression et le bilan final sont émis en NDJSON sur la sortie standard. Si la base source est assez ancienne pour nécessiter sa propre mise à niveau de schéma sur place, celle-ci s’exécute d’abord et émet ses propres événements "schema-migration" (phase/effectué/total) avant que la copie ligne à ligne ne commence.

Valinta

Oletus

Merkitys

--from <uri>

lähde-SQLite-tietokanta (sqlite:///polku tai pelkkä polku)

--to <dsn>

kohde-PostgreSQL:n DSN (postgres://…)

--tenant-id <scope>

kohteen vuokralais-scope (pakollinen paitsi --dry-run-tilassa)

--dry-run

laskee, mitä kopioitaisiin, kirjoittamatta mitään

--on-conflict <käytäntö>

""

"" keskeyttää, jos vuokralaisella on jo tietoja; skip yhdistää (asemien deduplikointi Zobrist-hashin perusteella)

Muista

Vielä migroimatta jäävät sovellustilat: Anki-pakat/-kortit, suodatinkirjasto, haku- ja komentohistoria sekä istunnon metatiedot. Etusijalla on asemakirjaston ja otteluhistorian migraatio.

8.5. Yleiskäyttöinen call-välittäjä

Aiempien alikomentojen (Komentoriviliittymä (CLI)) lisäksi blunderdb call tarjoaa kaikki tallennustoiminnot suoraan paikallisesti. Se kulkee samojen käsittelijöiden kautta kuin serve-demoni: toiminta on siis identtinen komennon POST /v1/<perhe>.<metodi> kanssa. Tämä on hyödyllistä skriptauksessa ja integraatiotesteissä.

# 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}'

Valinnat:

Valinta

Oletus

Merkitys

--db <polku>

SQLite-tiedosto (oikotie komennolle --backend sqlite --dsn <polku>)

--backend <tyyppi>

sqlite

sqlite tai postgres

--dsn <merkkijono>

$BLUNDERDB_DSN

taustajärjestelmän yhteysmerkkijono

--scope <merkkijono>

default

vuokralais-scope (lähetetään otsakkeena X-Tenant-ID)

--json <merkkijono>

{}

pyynnön runko JSON-muodossa

--json-file <polku>

lukee pyynnön rungon tiedostosta

--list

näyttää kaikki metodit <perhe>.<metodi> ja lopettaa

JSON-vastaus (tai NDJSON-virta *.list-päätepisteille) kirjoitetaan vakiotulosteeseen. Virhetilanteessa prosessi päättyy nollasta poikkeavalla koodilla ja kuori {"error":{…}} tulostetaan vakiotulosteeseen, jotta se pysyy jäsenneltävänä (esimerkiksi jq:lla).