longevity: schema dei due database, identity separato da longevity
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import Database from 'better-sqlite3';
|
||||
import { mkdirSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
|
||||
/** Sotto questa copertura di peso un elemento calcolato e' 'insufficiente' e non ha valore. */
|
||||
export const COPERTURA_MINIMA = 0.4;
|
||||
|
||||
const SCHEMA_LONGEVITY = `
|
||||
CREATE TABLE IF NOT EXISTS soggetti (
|
||||
client_code TEXT PRIMARY KEY,
|
||||
sesso TEXT NOT NULL CHECK (sesso IN ('M','F')),
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS registro_test (
|
||||
test_id TEXT PRIMARY KEY,
|
||||
etichetta TEXT NOT NULL,
|
||||
unita TEXT,
|
||||
tipo_valore TEXT NOT NULL CHECK (tipo_valore IN ('num','txt')),
|
||||
curva TEXT,
|
||||
params TEXT,
|
||||
asse TEXT,
|
||||
sotto_dominio TEXT,
|
||||
range_min REAL,
|
||||
range_max REAL,
|
||||
attivo_da TEXT NOT NULL,
|
||||
attivo_a TEXT,
|
||||
note TEXT
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS sessioni (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
client_code TEXT NOT NULL REFERENCES soggetti(client_code),
|
||||
data TEXT NOT NULL,
|
||||
tipo TEXT NOT NULL CHECK (tipo IN ('checkup','questionario')),
|
||||
eta_alla_data INTEGER,
|
||||
operatore TEXT,
|
||||
note TEXT,
|
||||
quest_version TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessioni_cliente ON sessioni (client_code, data DESC);
|
||||
CREATE TABLE IF NOT EXISTS misure (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sessione_id INTEGER NOT NULL REFERENCES sessioni(id) ON DELETE CASCADE,
|
||||
client_code TEXT NOT NULL REFERENCES soggetti(client_code),
|
||||
test_id TEXT NOT NULL REFERENCES registro_test(test_id),
|
||||
valore_num REAL,
|
||||
valore_txt TEXT,
|
||||
unita TEXT,
|
||||
fonte TEXT NOT NULL CHECK (fonte IN
|
||||
('manuale','questionario','wellness_tower','vald','calibre','stress_index')),
|
||||
fuori_range INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_misure_cliente_test ON misure (client_code, test_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_misure_sessione ON misure (sessione_id);
|
||||
CREATE TABLE IF NOT EXISTS pesi (
|
||||
model_version TEXT NOT NULL,
|
||||
livello TEXT NOT NULL CHECK (livello IN ('asse','macro','fitness_age')),
|
||||
contenitore TEXT NOT NULL,
|
||||
elemento TEXT NOT NULL,
|
||||
peso REAL NOT NULL,
|
||||
PRIMARY KEY (model_version, livello, contenitore, elemento)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS profilo_note (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
client_code TEXT NOT NULL REFERENCES soggetti(client_code),
|
||||
sessione_id INTEGER REFERENCES sessioni(id),
|
||||
campo_id TEXT NOT NULL,
|
||||
testo TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS score (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
client_code TEXT NOT NULL REFERENCES soggetti(client_code),
|
||||
sessione_id INTEGER NOT NULL REFERENCES sessioni(id),
|
||||
tipo TEXT NOT NULL CHECK (tipo IN ('asse','macro','fitness_age')),
|
||||
nome TEXT NOT NULL,
|
||||
valore REAL,
|
||||
copertura REAL NOT NULL,
|
||||
stato TEXT NOT NULL CHECK (stato IN ('ok','insufficiente')),
|
||||
quest_version TEXT,
|
||||
model_version TEXT NOT NULL,
|
||||
calcolato_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_score_cliente ON score (client_code, calcolato_at DESC);
|
||||
`;
|
||||
|
||||
const SCHEMA_IDENTITY = `
|
||||
CREATE TABLE IF NOT EXISTS clienti (
|
||||
client_code TEXT PRIMARY KEY,
|
||||
user_id INTEGER,
|
||||
nome TEXT NOT NULL,
|
||||
cognome TEXT NOT NULL,
|
||||
data_nascita TEXT,
|
||||
email TEXT,
|
||||
telefono TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_clienti_user ON clienti (user_id);
|
||||
`;
|
||||
|
||||
function apri(p: string, schema: string): Database.Database {
|
||||
if (p !== ':memory:') mkdirSync(dirname(p), { recursive: true });
|
||||
const db = new Database(p);
|
||||
db.pragma('journal_mode = WAL');
|
||||
db.pragma('foreign_keys = ON');
|
||||
db.exec(schema);
|
||||
return db;
|
||||
}
|
||||
|
||||
export function createLongevityDb(path?: string): Database.Database {
|
||||
return apri(path ?? process.env.LONGEVITY_DB_PATH ?? 'data/longevity.db', SCHEMA_LONGEVITY);
|
||||
}
|
||||
|
||||
export function createIdentityDb(path?: string): Database.Database {
|
||||
return apri(path ?? process.env.IDENTITY_DB_PATH ?? 'data/identity.db', SCHEMA_IDENTITY);
|
||||
}
|
||||
Reference in New Issue
Block a user