#!/usr/bin/env python3 """Offline test for the v5 thesis seed (init_db auto-seed + idempotency). Runs the real init_db against a throwaway DB (applies migration 0002 and the auto-seed), then asserts the Workshop substrate: a core line, one line per segment, the Option A/B banner as a 2-member variant group, the pillars/proof, and the segments table — and that re-seeding is a no-op. Run: cd backend && python3 test_thesis_seed.py """ import os import sqlite3 import sys import tempfile _tmp = tempfile.mkdtemp() os.environ["CRM_DATA_DIR"] = _tmp os.environ["CRM_DB_PATH"] = os.path.join(_tmp, "crm.db") sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import server # noqa: E402 import thesis_seed # noqa: E402 FAILS = [] def check(cond, msg): print((" PASS " if cond else " FAIL ") + msg) if not cond: FAILS.append(msg) def main(): server.init_db() conn = sqlite3.connect(server.DB_PATH) conn.row_factory = sqlite3.Row lines = {r["line_key"]: dict(r) for r in conn.execute("SELECT * FROM thesis_lines WHERE deleted_at IS NULL")} check("core" in lines and lines["core"]["is_core"] == 1, "core thesis line seeded (is_core)") seg_lines = [k for k in lines if k.startswith("seg_")] check(len(seg_lines) == 5, f"five per-segment lines seeded (got {len(seg_lines)}: {sorted(seg_lines)})") check(len(lines) == 6, f"exactly 6 lines total (got {len(lines)})") core_id = lines["core"]["id"] nodes = [dict(r) for r in conn.execute("SELECT * FROM thesis_nodes WHERE line_id=?", (core_id,))] types = [n["node_type"] for n in nodes] check("throughline" in types, "core has a throughline node") check("proof_point" in types, "core has a proof_point node") variants = [n for n in nodes if n["variant_group"] == "positioning"] check(len(variants) == 2, f"Option A/B banner is a 2-member variant group (got {len(variants)})") pillars = [n for n in nodes if n["node_type"] == "claim" and n["title"] and n["title"][0] in "123"] check(len(pillars) == 3, f"three pillar claims (got {len(pillars)})") segs = {r["segment_key"] for r in conn.execute("SELECT segment_key FROM segments WHERE status='active'")} check(segs == {"btc_native_hnwi", "institution", "family_office", "smaller_accredited", "ai_energy_operator"}, f"five active segments (got {sorted(segs)})") # segment lines each carry a segment_cut angle cut = conn.execute("""SELECT COUNT(*) FROM thesis_nodes n JOIN thesis_lines l ON l.id=n.line_id WHERE n.node_type='segment_cut' AND l.line_key LIKE 'seg_%'""").fetchone()[0] check(cut == 5, f"each segment line has a segment_cut angle (got {cut})") # idempotency: re-seeding does nothing (thesis not empty) thesis_seed.ensure_thesis_seed(conn) conn.commit() n2 = conn.execute("SELECT COUNT(*) FROM thesis_lines WHERE deleted_at IS NULL").fetchone()[0] check(n2 == 6, f"re-seed is a no-op when thesis already exists (got {n2})") conn.close() print() if FAILS: print(f"FAILED ({len(FAILS)})") sys.exit(1) print("ALL PASS (v5 thesis seed)") if __name__ == "__main__": main()