feat(foundation): schema Treapta 2 + migrari aditive + openpyxl pinned (#1)

- accounts.rar_creds_enc TEXT (creds RAR durabile per-cont, D4)
- submissions.batch_id, row_index (T7 scoping R1)
- submissions.purge_after (T16 GDPR)
- Tabele noi: column_mappings, import_batches, import_rows, import_attestations
- _migrate idempotent pe DB veche (ALTER aditiv, pattern existent)
- openpyxl==3.1.5 adaugat in requirements.txt (Issue 4, PINNED)
- 15 teste noi: coloane, tabele, idempotenta, migrare DB veche, openpyxl

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-16 20:13:19 +00:00
parent 4295a0aa31
commit 80897ccbb1
4 changed files with 270 additions and 14 deletions

View File

@@ -43,11 +43,33 @@ def init_db() -> None:
def _migrate(conn: sqlite3.Connection) -> None:
"""Migrari aditive pentru DB create inainte de o coloana noua (CREATE IF NOT EXISTS nu altereaza)."""
cols = {r["name"] for r in conn.execute("PRAGMA table_info(submissions)").fetchall()}
if "next_attempt_at" not in cols:
# Coloane submissions
sub_cols = {r["name"] for r in conn.execute("PRAGMA table_info(submissions)").fetchall()}
if "next_attempt_at" not in sub_cols:
conn.execute("ALTER TABLE submissions ADD COLUMN next_attempt_at TEXT")
if "rar_creds_enc" not in cols:
if "rar_creds_enc" not in sub_cols:
conn.execute("ALTER TABLE submissions ADD COLUMN rar_creds_enc TEXT")
if "purge_after" not in sub_cols:
conn.execute("ALTER TABLE submissions ADD COLUMN purge_after TEXT")
if "batch_id" not in sub_cols:
conn.execute("ALTER TABLE submissions ADD COLUMN batch_id INTEGER")
if "row_index" not in sub_cols:
conn.execute("ALTER TABLE submissions ADD COLUMN row_index INTEGER")
# Coloane accounts
acc_cols = {r["name"] for r in conn.execute("PRAGMA table_info(accounts)").fetchall()}
if "rar_creds_enc" not in acc_cols:
conn.execute("ALTER TABLE accounts ADD COLUMN rar_creds_enc TEXT")
# Index batch_id pe submissions (poate lipsi pe DB veche)
existing_idx = {r["name"] for r in conn.execute(
"SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='submissions'"
).fetchall()}
if "idx_submissions_batch" not in existing_idx:
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_submissions_batch ON submissions(batch_id) "
"WHERE batch_id IS NOT NULL"
)
def _now_iso() -> str: