feat(t207): audit local procurement results
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE execution_events (
|
||||
id TEXT PRIMARY KEY NOT NULL
|
||||
CHECK (length(id) = 36),
|
||||
task_id TEXT NOT NULL
|
||||
REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
execution_id TEXT NOT NULL
|
||||
REFERENCES task_executions(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
step TEXT NOT NULL
|
||||
CHECK (
|
||||
length(trim(step)) > 0
|
||||
AND length(CAST(step AS BLOB)) <= 64
|
||||
),
|
||||
event_type TEXT NOT NULL
|
||||
CHECK (
|
||||
length(trim(event_type)) > 0
|
||||
AND length(CAST(event_type AS BLOB)) <= 64
|
||||
),
|
||||
message TEXT NOT NULL
|
||||
CHECK (length(CAST(message AS BLOB)) <= 1000),
|
||||
occurred_at TEXT NOT NULL,
|
||||
received_at TEXT NOT NULL,
|
||||
received_after_execution_expiry INTEGER NOT NULL DEFAULT 0
|
||||
CHECK (received_after_execution_expiry IN (0, 1))
|
||||
);
|
||||
|
||||
CREATE INDEX execution_events_execution_occurred_idx
|
||||
ON execution_events (execution_id, occurred_at ASC, id ASC);
|
||||
|
||||
CREATE TABLE execution_evidence_assets (
|
||||
id TEXT PRIMARY KEY NOT NULL
|
||||
CHECK (length(id) = 36),
|
||||
task_id TEXT NOT NULL
|
||||
REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
execution_id TEXT NOT NULL
|
||||
REFERENCES task_executions(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
media_type TEXT NOT NULL
|
||||
CHECK (media_type = 'image/jpeg'),
|
||||
size_bytes INTEGER NOT NULL
|
||||
CHECK (size_bytes > 0),
|
||||
sha256 TEXT NOT NULL
|
||||
CHECK (
|
||||
length(sha256) = 64
|
||||
AND sha256 NOT GLOB '*[^0-9a-f]*'
|
||||
),
|
||||
storage_key TEXT NOT NULL UNIQUE
|
||||
CHECK (
|
||||
length(storage_key) > 0
|
||||
AND substr(storage_key, 1, 1) <> '/'
|
||||
AND instr(storage_key, '\') = 0
|
||||
AND instr(storage_key, '..') = 0
|
||||
),
|
||||
created_at TEXT NOT NULL,
|
||||
received_after_execution_expiry INTEGER NOT NULL DEFAULT 0
|
||||
CHECK (received_after_execution_expiry IN (0, 1))
|
||||
);
|
||||
|
||||
CREATE INDEX execution_evidence_execution_created_idx
|
||||
ON execution_evidence_assets (execution_id, created_at ASC, id ASC);
|
||||
|
||||
CREATE TABLE execution_candidate_batches (
|
||||
execution_id TEXT PRIMARY KEY NOT NULL
|
||||
REFERENCES task_executions(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
task_id TEXT NOT NULL
|
||||
REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
task_content_sha256 TEXT NOT NULL
|
||||
CHECK (
|
||||
length(task_content_sha256) = 64
|
||||
AND task_content_sha256 NOT GLOB '*[^0-9a-f]*'
|
||||
),
|
||||
execution_mode TEXT NOT NULL
|
||||
CHECK (execution_mode IN ('MANUAL_FIRST', 'AI_ASSISTED')),
|
||||
search_query TEXT NOT NULL
|
||||
CHECK (
|
||||
length(trim(search_query)) > 0
|
||||
AND length(CAST(search_query AS BLOB)) <= 512
|
||||
),
|
||||
provenance_json TEXT,
|
||||
candidates_json TEXT NOT NULL
|
||||
CHECK (length(CAST(candidates_json AS BLOB)) <= 65536),
|
||||
recommendation_json TEXT,
|
||||
received_at TEXT NOT NULL,
|
||||
received_after_execution_expiry INTEGER NOT NULL DEFAULT 0
|
||||
CHECK (received_after_execution_expiry IN (0, 1))
|
||||
);
|
||||
|
||||
CREATE TABLE execution_outcomes (
|
||||
execution_id TEXT PRIMARY KEY NOT NULL
|
||||
REFERENCES task_executions(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
task_id TEXT NOT NULL
|
||||
REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE CASCADE,
|
||||
result_type TEXT NOT NULL
|
||||
CHECK (result_type IN ('COMPLETE', 'FAIL')),
|
||||
execution_mode TEXT
|
||||
CHECK (execution_mode IS NULL OR execution_mode IN ('MANUAL_FIRST', 'AI_ASSISTED')),
|
||||
task_content_sha256 TEXT
|
||||
CHECK (
|
||||
task_content_sha256 IS NULL
|
||||
OR (
|
||||
length(task_content_sha256) = 64
|
||||
AND task_content_sha256 NOT GLOB '*[^0-9a-f]*'
|
||||
)
|
||||
),
|
||||
outcome TEXT
|
||||
CHECK (
|
||||
outcome IS NULL
|
||||
OR outcome IN (
|
||||
'CANDIDATE_ACCEPTED',
|
||||
'CANDIDATE_REJECTED',
|
||||
'NO_MATCH',
|
||||
'MANUAL_REQUIRED'
|
||||
)
|
||||
),
|
||||
operator_reason TEXT
|
||||
CHECK (
|
||||
operator_reason IS NULL
|
||||
OR length(CAST(operator_reason AS BLOB)) <= 1000
|
||||
),
|
||||
selected_candidate_json TEXT,
|
||||
evidence_asset_ids_json TEXT,
|
||||
error_code TEXT
|
||||
CHECK (error_code IS NULL OR length(CAST(error_code AS BLOB)) <= 64),
|
||||
error_message TEXT
|
||||
CHECK (error_message IS NULL OR length(CAST(error_message AS BLOB)) <= 1000),
|
||||
error_step TEXT
|
||||
CHECK (error_step IS NULL OR length(CAST(error_step AS BLOB)) <= 64),
|
||||
retryable INTEGER
|
||||
CHECK (retryable IS NULL OR retryable IN (0, 1)),
|
||||
order_submitted INTEGER NOT NULL DEFAULT 0
|
||||
CHECK (order_submitted = 0),
|
||||
received_at TEXT NOT NULL,
|
||||
received_after_execution_expiry INTEGER NOT NULL DEFAULT 0
|
||||
CHECK (received_after_execution_expiry IN (0, 1)),
|
||||
CHECK (
|
||||
(result_type = 'COMPLETE'
|
||||
AND execution_mode IS NOT NULL
|
||||
AND task_content_sha256 IS NOT NULL
|
||||
AND outcome IS NOT NULL
|
||||
AND operator_reason IS NOT NULL
|
||||
AND error_code IS NULL)
|
||||
OR
|
||||
(result_type = 'FAIL'
|
||||
AND error_code IS NOT NULL
|
||||
AND error_message IS NOT NULL
|
||||
AND error_step IS NOT NULL)
|
||||
)
|
||||
);
|
||||
|
||||
CREATE TABLE execution_result_requests (
|
||||
user_id TEXT NOT NULL
|
||||
REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
device_id TEXT NOT NULL
|
||||
REFERENCES devices(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
operation TEXT NOT NULL
|
||||
CHECK (operation IN ('EVENTS', 'EVIDENCE', 'CANDIDATES', 'COMPLETE', 'FAIL')),
|
||||
idempotency_key TEXT NOT NULL
|
||||
CHECK (
|
||||
length(trim(idempotency_key)) > 0
|
||||
AND length(CAST(idempotency_key AS BLOB)) <= 128
|
||||
),
|
||||
request_sha256 TEXT NOT NULL
|
||||
CHECK (
|
||||
length(request_sha256) = 64
|
||||
AND request_sha256 NOT GLOB '*[^0-9a-f]*'
|
||||
),
|
||||
claim_token_sha256 TEXT NOT NULL
|
||||
CHECK (
|
||||
length(claim_token_sha256) = 64
|
||||
AND claim_token_sha256 NOT GLOB '*[^0-9a-f]*'
|
||||
),
|
||||
task_id TEXT NOT NULL
|
||||
REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
execution_id TEXT NOT NULL
|
||||
REFERENCES task_executions(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
|
||||
resource_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
PRIMARY KEY (user_id, device_id, operation, idempotency_key)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
CREATE TEMP TABLE execution_results_v5_down_guard (
|
||||
allowed INTEGER NOT NULL
|
||||
CHECK (allowed = 1)
|
||||
);
|
||||
|
||||
INSERT INTO execution_results_v5_down_guard (allowed)
|
||||
SELECT CASE
|
||||
WHEN EXISTS (SELECT 1 FROM execution_events)
|
||||
OR EXISTS (SELECT 1 FROM execution_evidence_assets)
|
||||
OR EXISTS (SELECT 1 FROM execution_candidate_batches)
|
||||
OR EXISTS (SELECT 1 FROM execution_outcomes)
|
||||
OR EXISTS (SELECT 1 FROM execution_result_requests)
|
||||
THEN 0
|
||||
ELSE 1
|
||||
END;
|
||||
|
||||
DROP TABLE execution_results_v5_down_guard;
|
||||
DROP TABLE execution_result_requests;
|
||||
DROP TABLE execution_outcomes;
|
||||
DROP TABLE execution_candidate_batches;
|
||||
DROP INDEX execution_evidence_execution_created_idx;
|
||||
DROP TABLE execution_evidence_assets;
|
||||
DROP INDEX execution_events_execution_occurred_idx;
|
||||
DROP TABLE execution_events;
|
||||
Reference in New Issue
Block a user