-- Migration 001: Initial Schema -- -- Domain model mapped to PostgreSQL tables. -- Domain does NOT know about this schema. -- Schema is infrastructure concern. -- Sessions CREATE TABLE IF NOT EXISTS field_sessions ( id VARCHAR(32) PRIMARY KEY, location_lat DECIMAL(10, 8) NOT NULL, location_lng DECIMAL(11, 8) NOT NULL, location_accuracy DECIMAL(10, 2), date DATE NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'planned', mission_ids TEXT[] DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Missions CREATE TABLE IF NOT EXISTS missions ( id VARCHAR(32) PRIMARY KEY, session_id VARCHAR(32) NOT NULL REFERENCES field_sessions(id), location_lat DECIMAL(10, 8) NOT NULL, location_lng DECIMAL(11, 8) NOT NULL, location_accuracy DECIMAL(10, 2), status VARCHAR(20) NOT NULL DEFAULT 'created', device_model VARCHAR(100) NOT NULL, device_os VARCHAR(100) NOT NULL, device_app_version VARCHAR(50) NOT NULL, artifact_ids TEXT[] DEFAULT '{}', observation_ids TEXT[] DEFAULT '{}', sequence_number INTEGER NOT NULL DEFAULT 1, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Artifacts CREATE TABLE IF NOT EXISTS artifacts ( id VARCHAR(32) PRIMARY KEY, type VARCHAR(50) NOT NULL, version_major INTEGER NOT NULL DEFAULT 1, version_minor INTEGER NOT NULL DEFAULT 0, version_patch INTEGER NOT NULL DEFAULT 0, hash_algorithm VARCHAR(20) NOT NULL DEFAULT 'sha256', hash_value VARCHAR(64) NOT NULL, created_by VARCHAR(100) NOT NULL, storage_protocol VARCHAR(20) NOT NULL, storage_bucket VARCHAR(200), storage_path TEXT NOT NULL, parent_id VARCHAR(32) REFERENCES artifacts(id), lineage TEXT[] DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Decision Cases CREATE TABLE IF NOT EXISTS decision_cases ( id VARCHAR(32) PRIMARY KEY, mission_id VARCHAR(32) NOT NULL REFERENCES missions(id), title VARCHAR(500) NOT NULL, description TEXT NOT NULL, priority VARCHAR(20) NOT NULL, confidence VARCHAR(20) NOT NULL, recommended_action TEXT NOT NULL, observation_ids TEXT[] DEFAULT '{}', evidence_ids TEXT[] DEFAULT '{}', finding_id VARCHAR(32) NOT NULL, decision_id VARCHAR(32) NOT NULL, review_id VARCHAR(32) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'pending', version INTEGER NOT NULL DEFAULT 1, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Indexes for common queries CREATE INDEX IF NOT EXISTS idx_missions_session_id ON missions(session_id); CREATE INDEX IF NOT EXISTS idx_missions_status ON missions(status); CREATE INDEX IF NOT EXISTS idx_decision_cases_mission_id ON decision_cases(mission_id); CREATE INDEX IF NOT EXISTS idx_decision_cases_status ON decision_cases(status); CREATE INDEX IF NOT EXISTS idx_field_sessions_date ON field_sessions(date); CREATE INDEX IF NOT EXISTS idx_field_sessions_status ON field_sessions(status); -- Update trigger for updated_at CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ language 'plpgsql'; CREATE TRIGGER update_field_sessions_updated_at BEFORE UPDATE ON field_sessions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); CREATE TRIGGER update_missions_updated_at BEFORE UPDATE ON missions FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();