1a50fad0a5
Drop the metadata_locked column + "Save and lock" UI end-to-end. The review endpoint now builds the deterministic title/short_description on every call; the owner's Create title / Create short desc buttons fire the build and write the result (force-overwrite contract). commitReview auto-fills only empty fields (no owner-clobber) and folds the deterministic copy into its single PUT (kills the client_rev 409 cascade). Taken wholesale from the branch: photo strip, wood primary/secondary, server-side thickness band (hidden from UI, passed to Woo on publish), and fixes #80/#82/#83/#84. - backend: remove metadata_locked from schema.sql, db sentinels, slabs.py client fields/exposure, review.py lock action; review always computes title/short_desc - frontend: slabs.ts + Review.svelte drop the lock model, add Create-string workflow + wood primary + photo strip - e2e: m3-create + review-photo-strip rewritten for the Create-string contract; thickness-band test asserts absence (per #90) - deploy: recreate LAN binds (override-m3.yml was absent); verify metadata_locked gone, review builds title, PUT persists Gates: backend 117/117, unit 88/88, tsc clean, e2e 6/6 (m3-create + photo-strip). Live UAT verified at 192.168.1.202:10881.
163 lines
5.1 KiB
SQL
163 lines
5.1 KiB
SQL
-- SlabUploader SQLite schema (S0)
|
|
-- Every table/column from docs/contracts/DATA-MODEL.md using CREATE TABLE IF NOT EXISTS
|
|
-- Taxonomy tables exist but remain EMPTY (S4 populates). Stdlib sqlite3 only.
|
|
-- Pragmas applied by db factory: journal_mode=WAL, foreign_keys=ON, busy_timeout=5000, synchronous=NORMAL
|
|
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
-- 2. slabs
|
|
CREATE TABLE IF NOT EXISTS slabs (
|
|
id TEXT PRIMARY KEY,
|
|
status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft','calibrated','ready','publishing','published','failed')),
|
|
sku TEXT UNIQUE CHECK(length(sku) BETWEEN 3 AND 24),
|
|
length_in REAL,
|
|
thickness_in REAL,
|
|
sqft REAL,
|
|
bdft REAL,
|
|
width_min_in REAL,
|
|
width_max_in REAL,
|
|
width_avg_in REAL,
|
|
species_id INTEGER,
|
|
wood_category_ids TEXT, -- JSON array of leaf ids
|
|
edge_type_term_id INTEGER,
|
|
figure_term_ids TEXT, -- JSON array
|
|
grade_term_id INTEGER,
|
|
thickness_term_id INTEGER,
|
|
moisture_term_id INTEGER,
|
|
fig_tag_ids TEXT, -- JSON array optional
|
|
feat_tag_ids TEXT, -- JSON array optional
|
|
price REAL,
|
|
price_source TEXT CHECK(price_source IN ('recommendation','override') OR price_source IS NULL),
|
|
title TEXT,
|
|
short_description TEXT,
|
|
description TEXT,
|
|
content_source TEXT CHECK(content_source IN ('manual','llm','template') OR content_source IS NULL),
|
|
species_confidence REAL,
|
|
figure_confidence REAL,
|
|
grade_confidence REAL,
|
|
inference_status TEXT CHECK(inference_status IN ('inferring','done','failed') OR inference_status IS NULL),
|
|
calibration_photo_id TEXT,
|
|
client_rev INTEGER NOT NULL DEFAULT 1,
|
|
server_rev INTEGER NOT NULL DEFAULT 1,
|
|
woo_product_id INTEGER,
|
|
published_at TEXT,
|
|
deleted_at TEXT,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (species_id) REFERENCES woo_categories(id),
|
|
FOREIGN KEY (calibration_photo_id) REFERENCES slab_photos(id)
|
|
);
|
|
|
|
-- 3. slab_photos
|
|
CREATE TABLE IF NOT EXISTS slab_photos (
|
|
id TEXT PRIMARY KEY,
|
|
slab_id TEXT NOT NULL,
|
|
seq INTEGER NOT NULL,
|
|
is_calibration INTEGER NOT NULL DEFAULT 0 CHECK(is_calibration IN (0,1)),
|
|
-- #90: lineup kind (clean cal / dimension-overlay copy / batch sibling).
|
|
-- Drives the Review photo strip labels and the PUBLISH-45 Woo image order.
|
|
role TEXT NOT NULL DEFAULT 'batch' CHECK(role IN ('calibration','overlay','batch')),
|
|
original_blob BLOB,
|
|
processed_blob BLOB,
|
|
width_px INTEGER,
|
|
height_px INTEGER,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (slab_id) REFERENCES slabs(id) ON DELETE CASCADE
|
|
);
|
|
|
|
-- 4. pricing_rules
|
|
CREATE TABLE IF NOT EXISTS pricing_rules (
|
|
id INTEGER PRIMARY KEY,
|
|
species_id INTEGER NOT NULL UNIQUE,
|
|
price_per_bdft REAL NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (species_id) REFERENCES woo_categories(id)
|
|
);
|
|
|
|
-- 5. Taxonomy cache (empty at S0; columns chosen to support FKs + S4 sync; ambiguity resolved in learnings)
|
|
CREATE TABLE IF NOT EXISTS woo_categories (
|
|
id INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
parent_id INTEGER,
|
|
woo_id INTEGER
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS woo_attributes (
|
|
id INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
woo_id INTEGER
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS woo_attribute_terms (
|
|
id INTEGER PRIMARY KEY,
|
|
attribute_id INTEGER NOT NULL,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
woo_id INTEGER,
|
|
FOREIGN KEY (attribute_id) REFERENCES woo_attributes(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS woo_tags (
|
|
id INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL UNIQUE,
|
|
woo_id INTEGER
|
|
);
|
|
|
|
-- 6. settings (key/value/value_enc per §6; secrets in value_enc = nonce||ciphertext)
|
|
CREATE TABLE IF NOT EXISTS settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT,
|
|
value_enc TEXT
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS schema_version (version INTEGER PRIMARY KEY);
|
|
|
|
-- 7. prompts + prompt_revisions (append-only revisions)
|
|
CREATE TABLE IF NOT EXISTS prompts (
|
|
id INTEGER PRIMARY KEY,
|
|
name TEXT NOT NULL CHECK(name IN ('call1','call2')),
|
|
active_revision_id INTEGER,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
FOREIGN KEY (active_revision_id) REFERENCES prompt_revisions(id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS prompt_revisions (
|
|
id INTEGER PRIMARY KEY,
|
|
prompt_id INTEGER NOT NULL,
|
|
content TEXT NOT NULL,
|
|
content_hash TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
created_by TEXT,
|
|
FOREIGN KEY (prompt_id) REFERENCES prompts(id)
|
|
);
|
|
|
|
-- 8. sync_log (append-only)
|
|
CREATE TABLE IF NOT EXISTS sync_log (
|
|
id INTEGER PRIMARY KEY,
|
|
slab_id TEXT,
|
|
woo_product_id INTEGER,
|
|
status TEXT NOT NULL CHECK(status IN ('success','failed')),
|
|
payload_hash TEXT,
|
|
message TEXT,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
-- 9. inference_log (append-only audit)
|
|
CREATE TABLE IF NOT EXISTS inference_log (
|
|
id INTEGER PRIMARY KEY,
|
|
slab_id TEXT,
|
|
call INTEGER NOT NULL CHECK(call IN (1,2)),
|
|
prompt_revision_id INTEGER,
|
|
model TEXT,
|
|
request_payload TEXT,
|
|
response_payload TEXT,
|
|
latency_ms INTEGER,
|
|
created_at TEXT NOT NULL,
|
|
FOREIGN KEY (prompt_revision_id) REFERENCES prompt_revisions(id)
|
|
);
|