Plan sect.5: parola RAR vine per-cerere, stocata CRIPTATA in submission pana la primul login reusit pe cont, apoi stearsa; JWT 30h acopera restul. - app/crypto.py: Fernet, cheie din AUTOPASS_creds_key (nesetata -> efemera la runtime, creds nu supravietuiesc restartului). encrypt/decrypt_creds. - schema + migrare: submissions.rar_creds_enc (creds criptate). - ingestie: cripteaza rar_credentials, le lipeste de fiecare submission nou. Niciodata in clar in DB. - worker: AccountSessions (login per-cont cu creds decriptate, cache JWT in memorie, sterge creds-urile contului dupa primul login + refresh nomenclator). 401 creds gresite -> error fara retry; token expirat -> invalidare + requeue; fara creds (restart) -> requeue "indisponibile" (ROAAUTO re-trimite). claim_one intoarce account_id + creds_enc; recover_orphans filtrabil pe cont. - requirements: cryptography==46.0.5. Nota: refresh nomenclator e acum lazy la primul login per-cont (nu la pornire); seed-ul fallback acopera editorul offline. 10 teste noi (tests/test_creds_delivery.py). 95 pass total. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
80 lines
3.7 KiB
SQL
80 lines
3.7 KiB
SQL
-- Schema SQLite (WAL) pentru gateway RAR AUTOPASS.
|
|
-- Vezi plan.md sect. 5. NICIUN camp pentru parole RAR.
|
|
-- Validarea completa (T3) si criptarea PII (P2) vin ulterior; in schelet
|
|
-- payload-ul e stocat ca JSON text (camp payload_json), de inlocuit cu BLOB
|
|
-- criptat + purge_after cand se face T7/criptare.
|
|
|
|
PRAGMA journal_mode = WAL;
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
-- Conturi ROAAUTO (clientii care folosesc gateway-ul).
|
|
CREATE TABLE IF NOT EXISTS accounts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
cui TEXT,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
-- Cont implicit (id=1): auth API-key (CORE) inca neimplementat, deci ingestiile vin
|
|
-- cu account_id NULL. Le atribuim contului default ca FK + UNIQUE(account_id,...) din
|
|
-- operations_mapping sa fie valide; cand auth livreaza, account_id real va curge natural.
|
|
INSERT OR IGNORE INTO accounts (id, name) VALUES (1, 'default');
|
|
|
|
-- Chei API per cont (separate de creds RAR). Stocam doar hash-ul.
|
|
CREATE TABLE IF NOT EXISTS api_keys (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
|
|
key_hash TEXT NOT NULL UNIQUE,
|
|
active INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
revoked_at TEXT
|
|
);
|
|
|
|
-- Mapare operatie service -> codPrestatie RAR (← mapare_prestatii.DBF, T5).
|
|
CREATE TABLE IF NOT EXISTS operations_mapping (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
account_id INTEGER NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
|
|
cod_op_service TEXT NOT NULL,
|
|
cod_prestatie TEXT NOT NULL,
|
|
auto_send INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
UNIQUE (account_id, cod_op_service)
|
|
);
|
|
|
|
-- Cache nomenclator RAR {codPrestatie, numePrestatie} (← prestatii_rar.DBF / live).
|
|
CREATE TABLE IF NOT EXISTS nomenclator_rar (
|
|
cod_prestatie TEXT PRIMARY KEY,
|
|
nume_prestatie TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
-- Coada de prezentari catre RAR. Masina de stari: plan.md sect. 3.
|
|
CREATE TABLE IF NOT EXISTS submissions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
idempotency_key TEXT NOT NULL UNIQUE,
|
|
account_id INTEGER REFERENCES accounts(id) ON DELETE SET NULL,
|
|
status TEXT NOT NULL DEFAULT 'queued'
|
|
CHECK (status IN ('queued','sending','sent','needs_mapping','needs_data','error')),
|
|
payload_json TEXT NOT NULL, -- TODO(P2): inlocuit cu BLOB criptat
|
|
rar_creds_enc TEXT, -- creds RAR criptate (Fernet), sterse dupa primul login reusit (plan sect.5)
|
|
rar_status_code INTEGER,
|
|
rar_error TEXT,
|
|
id_prezentare INTEGER, -- data.id intors de RAR la succes
|
|
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
next_attempt_at TEXT, -- backoff: randul nu se ia inainte de acest moment (T2)
|
|
sending_since TEXT, -- pentru lease/timeout pe randuri 'sending' orfane (T2)
|
|
purge_after TEXT, -- sent + 90z (P2)
|
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_submissions_status ON submissions(status);
|
|
|
|
-- Heartbeat worker (un singur rand, id=1). /healthz citeste de aici.
|
|
CREATE TABLE IF NOT EXISTS worker_heartbeat (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
last_beat TEXT,
|
|
last_rar_login_ok TEXT,
|
|
detail TEXT
|
|
);
|
|
INSERT OR IGNORE INTO worker_heartbeat (id, last_beat, detail) VALUES (1, NULL, 'never started');
|