Add Flask web UI, Docker Compose, core engine + tests
- physcom core: CLI, 5-pass pipeline, SQLite repo, 37 tests - physcom_web: Flask app with HTMX for entity/domain/pipeline/results CRUD - Docker Compose: web + cli services sharing a named volume for the DB - Clean up local settings to use wildcard permissions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
111
src/physcom/db/schema.py
Normal file
111
src/physcom/db/schema.py
Normal file
@@ -0,0 +1,111 @@
|
||||
"""DDL, table creation, and schema initialization."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
DDL = """
|
||||
CREATE TABLE IF NOT EXISTS dimensions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
description TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS entities (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
dimension_id INTEGER NOT NULL REFERENCES dimensions(id),
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
UNIQUE(dimension_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS dependencies (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
entity_id INTEGER NOT NULL REFERENCES entities(id),
|
||||
category TEXT NOT NULL,
|
||||
key TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
unit TEXT,
|
||||
constraint_type TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS domains (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
description TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS metrics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
unit TEXT,
|
||||
description TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS domain_metric_weights (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
domain_id INTEGER NOT NULL REFERENCES domains(id),
|
||||
metric_id INTEGER NOT NULL REFERENCES metrics(id),
|
||||
weight REAL NOT NULL,
|
||||
norm_min REAL,
|
||||
norm_max REAL,
|
||||
UNIQUE(domain_id, metric_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS combinations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
hash TEXT UNIQUE NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
block_reason TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS combination_entities (
|
||||
combination_id INTEGER NOT NULL REFERENCES combinations(id),
|
||||
entity_id INTEGER NOT NULL REFERENCES entities(id),
|
||||
PRIMARY KEY (combination_id, entity_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS combination_scores (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
combination_id INTEGER NOT NULL REFERENCES combinations(id),
|
||||
domain_id INTEGER NOT NULL REFERENCES domains(id),
|
||||
metric_id INTEGER NOT NULL REFERENCES metrics(id),
|
||||
raw_value REAL,
|
||||
normalized_score REAL,
|
||||
estimation_method TEXT,
|
||||
confidence REAL,
|
||||
UNIQUE(combination_id, domain_id, metric_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS combination_results (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
combination_id INTEGER NOT NULL REFERENCES combinations(id),
|
||||
domain_id INTEGER NOT NULL REFERENCES domains(id),
|
||||
composite_score REAL,
|
||||
novelty_flag TEXT,
|
||||
llm_review TEXT,
|
||||
human_notes TEXT,
|
||||
pass_reached INTEGER,
|
||||
UNIQUE(combination_id, domain_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_deps_entity ON dependencies(entity_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_deps_category_key ON dependencies(category, key);
|
||||
CREATE INDEX IF NOT EXISTS idx_combo_status ON combinations(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_scores_combo_domain ON combination_scores(combination_id, domain_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_results_domain_score ON combination_results(domain_id, composite_score DESC);
|
||||
"""
|
||||
|
||||
|
||||
def init_db(db_path: str | Path) -> sqlite3.Connection:
|
||||
"""Create/open the database and ensure all tables exist."""
|
||||
db_path = Path(db_path)
|
||||
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
conn = sqlite3.connect(str(db_path))
|
||||
conn.execute("PRAGMA journal_mode=WAL")
|
||||
conn.execute("PRAGMA foreign_keys=ON")
|
||||
conn.executescript(DDL)
|
||||
conn.commit()
|
||||
return conn
|
||||
Reference in New Issue
Block a user