Files
praxis/db/schema.sql
T
Praxis CI 73b583342b feat(P01-04-01,P01-04-02): SQLite schema + async store (D-007)
db/schema.sql + db/migrations/0001_init.sql — four tables: learner (single
hardcoded 'learner-1'/'Alex' row, D-007 no auth), sessions (id, learner_id,
scenario_id, started_at, ended_at, branch_path_json, outcome,
cost_estimated_cents, debrief_text, cost_breakdown_json), turns (id,
session_id, seq, role, asr_text, tts_text, latency_ms), progress (learner_id,
scenario_id, attempts, last_outcome). db/migrate.py applies migrations
idempotently via a _migrations tracking table.

db/store.py — PraxisStore async access layer (aiosqlite): start_session,
log_turn, end_session (branch_path + outcome + cost + debrief),
update_progress (increment attempts + last_outcome), get_session, get_turns,
get_learner. Type-annotated SessionRow/TurnRow dataclasses. 6 tests pass
(migration creates all tables, hardcoded learner exists, idempotent
migrations, start→log→end→query full session, update_progress, get_learner).

---ci---
phase: 1
milestone: v0.1
plan: 04
task: 04-01,04-02
status: execute
persona: data-engineer
requirements:
  covered: [REQ-STATE-01]
---/ci---
2026-08-01 13:14:57 +00:00

46 lines
1.9 KiB
SQL

-- Praxis v0.1 SQLite schema — learner state (D-007).
-- Single hardcoded learner, no auth, no multi-tenant.
-- The single learner row (D-007). v0.1 has one hardcoded profile.
CREATE TABLE IF NOT EXISTS learner (
id TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- Session log: one row per voice session.
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
learner_id TEXT NOT NULL REFERENCES learner(id),
scenario_id TEXT NOT NULL,
started_at TEXT NOT NULL DEFAULT (datetime('now')),
ended_at TEXT,
branch_path_json TEXT, -- JSON array of branch ids taken
outcome TEXT, -- 'success' | 'failure' | NULL
cost_estimated_cents INTEGER, -- derived per-session cost (D-012)
debrief_text TEXT, -- TASK-05-05: the generated debrief
cost_breakdown_json TEXT -- TASK-04-04: token/minute/char breakdown
);
-- Turn log: one row per ASR/TTS turn within a session.
CREATE TABLE IF NOT EXISTS turns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL REFERENCES sessions(id),
seq INTEGER NOT NULL,
role TEXT NOT NULL, -- 'user' | 'assistant'
asr_text TEXT,
tts_text TEXT,
latency_ms REAL,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
UNIQUE(session_id, seq)
);
-- Progress: per-learner per-scenario progression (v0.1: attempts + last outcome).
CREATE TABLE IF NOT EXISTS progress (
learner_id TEXT NOT NULL REFERENCES learner(id),
scenario_id TEXT NOT NULL,
attempts INTEGER NOT NULL DEFAULT 0,
last_outcome TEXT,
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
PRIMARY KEY (learner_id, scenario_id)
);