8. Λειτουργία χωρίς γραφικό περιβάλλον (διακομιστής)
Σημείωση
Αυτή η ενότητα περιγράφει μια προηγμένη και προαιρετική λειτουργία του blunderDB, που προορίζεται για αναπτύξεις σε διακομιστή, για πολλαπλούς χρήστες και για αυτοματοποίηση. Η συνήθης και συνιστώμενη χρήση του blunderDB παραμένει η εφαρμογή γραφείου που περιγράφεται στα προηγούμενα κεφάλαια. Αν χρησιμοποιείτε το blunderDB μόνοι σας, στον υπολογιστή σας, δεν χρειάζεστε αυτή τη λειτουργία: μπορείτε να αγνοήσετε αυτό το κεφάλαιο χωρίς να χάσετε καμία από τις λειτουργίες ανάλυσης.
8.1. Επισκόπηση
Το ίδιο εκτελέσιμο blunderdb μπορεί, εκτός από την εφαρμογή γραφείου και τις εντολές γραμμής εντολών (δείτε Διεπαφή γραμμής εντολών (CLI)), να λειτουργήσει σε λειτουργία χωρίς γραφικό περιβάλλον: χωρίς γραφική διεπαφή, ελεγχόμενο εξ ολοκλήρου μέσω της γραμμής εντολών ή μέσω δικτύου. Αυτή η λειτουργία συγκεντρώνει τρεις χρήσεις:
ο δαίμονας
serve— εκθέτει τη μηχανή του blunderDB ως υπηρεσία HTTP + JSON, για να τρέχει μια κοινόχρηστη βάση σε διακομιστή και να την προσπελάζουν πολλοί χρήστες·ο γενικός dispatcher
call— καλεί οποιαδήποτε λειτουργία αποθήκευσης απευθείας, τοπικά, για scripting και δοκιμές·η εντολή
migrate— μεταφέρει μια βάση SQLite ενός χρήστη προς ένα backend PostgreSQL πολλαπλών χρηστών.
Αυτές οι τρεις χρήσεις βασίζονται σε ένα κοινό επίπεδο αποθήκευσης που γνωρίζει να επικοινωνεί με δύο backend: το SQLite (η συνήθης μορφή αρχείου .db της εφαρμογής γραφείου) και το PostgreSQL (για αναπτύξεις διακομιστή πολλαπλών χρηστών).
8.2. Ο δαίμονας serve
Το blunderdb serve εκκινεί τη μηχανή ως υπηρεσία HTTP που απαντά σε JSON. Επιτρέπει τη φιλοξενία μιας βάσης θέσεων σε ένα μηχάνημα και την προσπέλασή της από πολλούς πελάτες.
# 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
Προειδοποίηση
Ο δαίμονας δεν εκτελεί καμία πιστοποίηση ταυτότητας. Εμπιστεύεται την κεφαλίδα αιτήματος X-Tenant-ID και πρέπει να τρέχει πίσω από έναν reverse-proxy (nginx, Caddy…) υπεύθυνο για την πιστοποίηση ταυτότητας. Μην τον εκθέτετε ποτέ απευθείας στο δημόσιο Διαδίκτυο.
Επιλογές:
Επιλογή |
Προεπιλογή |
Σημασία |
|---|---|---|
|
– |
αρχείο SQLite (συντόμευση για |
|
|
backend αποθήκευσης: |
|
|
συμβολοσειρά σύνδεσης του backend |
|
|
διεύθυνση ακρόασης |
|
|
επίπεδο καταγραφής: |
|
|
εκθέτει το |
|
– |
ενεργοποιεί CORS για αυτή την προέλευση (απενεργοποιημένο εξ ορισμού) |
|
|
όριο αιτημάτων ανά δευτερόλεπτο και ανά tenant (0 = απενεργοποιημένο) |
|
|
μέγεθος του κάδου διακριτικών (token bucket) για τις αιχμές αιτημάτων |
|
|
PostgreSQL: ενεργοποιεί το Row-Level Security ανά tenant (άμυνα σε βάθος, προαιρετική) |
|
– |
προαιρετική βάση bearoff two-sided ( |
Οι περισσότερες επιλογές μπορούν επίσης να παρασχεθούν μέσω μεταβλητής περιβάλλοντος (BLUNDERDB_BACKEND, BLUNDERDB_DSN, BLUNDERDB_ADDR, BLUNDERDB_LOG_LEVEL, BLUNDERDB_RLS, BLUNDERDB_TS_PATH).
8.2.1. Σημεία πρόσβασης
Η υπηρεσία εκθέτει σημεία πρόσβασης λειτουργίας, πάντα διαθέσιμα:
GET /healthz— ζωτικότητα (η διεργασία τρέχει)·GET /readyz— διαθεσιμότητα (η αποθήκευση απαντά)·GET /metrics— μετρικές Prometheus (αν το--metricsείναι ενεργό).
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.
Δύο μέθοδοι της οικογένειας positions αποκωδικοποιούν μια θέση χωρίς να την αποθηκεύουν: η positions.fromXGID ανακατασκευάζει μια θέση από μια συμβολοσειρά XGID και η positions.fromXGP από ένα αρχείο μεμονωμένης θέσης .xgp.
Η οικογένεια anki αποκτά έξι μεθόδους που επεκτείνουν τον προγραμματιστή διαστηματικής επανάληψης (FSRS): anki.reviewLog (καταγραφή κάθε επανάληψης — βαθμολογία και αποτέλεσμα FSRS — για στατιστικά διατήρησης και ένα πιστό ιστορικό), anki.forecast (προβολή του αριθμού καρτών που οφείλονται τις επόμενες ημέρες, συμπεριλαμβανομένων των καθυστερημένων καρτών), anki.suspendCard / anki.buryCard / anki.removeCard (αφαίρεση μιας κάρτας από την ουρά επανάληψης προσωρινά ή οριστικά) και anki.optimizeParams (προσαρμόζει το στοχευόμενο ποσοστό διατήρησης ενός deck προς το ποσοστό επιτυχίας που παρατηρείται στις επαναλήψεις του).
8.2.2. Ανάπτυξη με Docker
Το αποθετήριο παρέχει ένα Dockerfile.serve που κατασκευάζει μια ελάχιστη εικόνα κοντέινερ του δαίμονα: μεταγλωττίζεται μόνο το εκτελέσιμο serve (καθαρή Go, χωρίς γραφική διεπαφή και χωρίς CGO, άρα στατικά συνδεδεμένο), και στη συνέχεια τοποθετείται σε μια εικόνα distroless.
# 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
Η εικόνα ακούει στη θύρα 8080 και διαμορφώνεται μέσω μεταβλητών περιβάλλοντος (BLUNDERDB_BACKEND, BLUNDERDB_DSN, BLUNDERDB_ADDR, BLUNDERDB_RLS).
Προειδοποίηση
Όπως και ο ίδιος ο δαίμονας, το κοντέινερ δεν εκτελεί καμία πιστοποίηση ταυτότητας: πρέπει να τοποθετείται πίσω από έναν reverse-proxy υπεύθυνο για την πιστοποίηση ταυτότητας και να μην εκτίθεται ποτέ απευθείας στο δημόσιο Διαδίκτυο.
8.3. Backend PostgreSQL και πολλαπλοί χρήστες
Για μια κοινόχρηστη ανάπτυξη, το blunderDB μπορεί να αποθηκεύει τα δεδομένα στο PostgreSQL αντί σε ένα αρχείο SQLite. Το backend επιλέγεται μέσω του --backend postgres και της συμβολοσειράς σύνδεσης --dsn. Το σχήμα δημιουργείται και μεταναστεύεται αυτόματα κατά την εκκίνηση.
Τα δεδομένα είναι διαχωρισμένα ανά tenant (μισθωτή): κάθε αίτημα φέρει ένα αναγνωριστικό scope (κεφαλίδα X-Tenant-ID, εξ ορισμού default), πράγμα που επιτρέπει σε πολλούς χρήστες να μοιράζονται το ίδιο instance χωρίς να βλέπουν τα δεδομένα των άλλων. Η επιλογή --rls ενεργοποιεί επιπλέον το Row-Level Security του PostgreSQL: εγκαθίστανται πολιτικές απομόνωσης ανά tenant και το app.tenant_id ορίζεται ανά σύνδεση. Πρόκειται για μια προαιρετική άμυνα σε βάθος, απενεργοποιημένη εξ ορισμού.
Όταν ένα tenant καταργείται, το POST /v1/tenant.purge διαγράφει οριστικά όλα τα δεδομένα του (θέσεις, αγώνες, συλλογές, ιστορικό κ.λπ.) για το τρέχον tenant (αυτό που φέρει το X-Tenant-ID), καθώς και την κατάσταση συνεδρίας του (τελευταία αναζήτηση, τελευταία θέση, ανοιχτές καρτέλες — τις λίγες γραμμές metadata με πρόθεμα αυτού του scope): η λειτουργία εκτελείται σε μία μοναδική συναλλαγή, είναι ιδεμποτική (κανένα σφάλμα κατά την εκκαθάριση ενός ήδη κενού tenant ή κατά την επανάληψη της κλήσης) και δεν επηρεάζει κανένα άλλο tenant ούτε την καθολική γραμμή έκδοσης σχήματος. Είναι διαθέσιμη μόνο με το backend PostgreSQL — επιστρέφει σφάλμα invalid σε ένα backend SQLite, το οποίο δεν έχει έννοια tenant.
8.4. Μετανάστευση μιας βάσης SQLite προς PostgreSQL
Το blunderdb migrate αντιγράφει μια βάση SQLite ενός χρήστη προς ένα backend PostgreSQL, υπό ένα επιλεγμένο scope tenant — είναι ο τρόπος για να « μεταφορτώσετε » μια βιβλιοθήκη γραφείου προς μια ανάπτυξη διακομιστή.
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.
Επιλογή |
Προεπιλογή |
Σημασία |
|---|---|---|
|
– |
βάση SQLite πηγής ( |
|
– |
DSN PostgreSQL προορισμού ( |
|
– |
scope tenant προορισμού (υποχρεωτικό εκτός από |
|
– |
μετρά τι θα αντιγραφόταν χωρίς να γράψει τίποτα |
|
|
|
Σημείωση
Δεν μεταναστεύονται (ακόμη) οι καταστάσεις της εφαρμογής: decks/κάρτες Anki, βιβλιοθήκη φίλτρων, ιστορικό αναζήτησης και εντολών, και μεταδεδομένα συνεδρίας. Η προτεραιότητα είναι η μετανάστευση της βιβλιοθήκης θέσεων και του ιστορικού αγώνων.
8.5. Ο γενικός dispatcher call
Συμπληρωματικά προς τις ιστορικές υποεντολές (Διεπαφή γραμμής εντολών (CLI)), το blunderdb call εκθέτει όλες τις λειτουργίες αποθήκευσης απευθείας, τοπικά. Περνά από τους ίδιους χειριστές με τον δαίμονα serve: η συμπεριφορά είναι επομένως πανομοιότυπη με το POST /v1/<famille>.<méthode>. Είναι χρήσιμο για το scripting και τις δοκιμές ολοκλήρωσης.
# 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}'
Επιλογές:
Επιλογή |
Προεπιλογή |
Σημασία |
|---|---|---|
|
– |
αρχείο SQLite (συντόμευση για |
|
|
|
|
|
συμβολοσειρά σύνδεσης του backend |
|
|
scope tenant (αποστέλλεται ως |
|
|
σώμα του αιτήματος σε μορφή JSON |
|
– |
διαβάζει το σώμα του αιτήματος από ένα αρχείο |
|
– |
εμφανίζει όλες τις μεθόδους |
Η απάντηση JSON (ή η ροή NDJSON για τα σημεία πρόσβασης *.list) γράφεται στην τυπική έξοδο. Σε περίπτωση σφάλματος, η διεργασία τερματίζεται με μη μηδενικό κωδικό και ο φάκελος {"error":{…}} εκτυπώνεται στην τυπική έξοδο ώστε να παραμένει αναλύσιμος (για παράδειγμα με το jq).