Spaces:
Running
Running
Create schema.sql
Browse files- data/schema.sql +77 -0
data/schema.sql
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
-- FiveTech: esquema SQLite WASM/sql.js. Ejecutar PRAGMA foreign_keys=ON en cada conexi贸n.
|
| 2 |
+
PRAGMA foreign_keys = ON;
|
| 3 |
+
CREATE TABLE IF NOT EXISTS suppliers (
|
| 4 |
+
id TEXT PRIMARY KEY, name TEXT NOT NULL, country TEXT NOT NULL,
|
| 5 |
+
contact_email TEXT, lead_days INTEGER NOT NULL CHECK (lead_days >= 0), active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0,1))
|
| 6 |
+
);
|
| 7 |
+
CREATE TABLE IF NOT EXISTS products (
|
| 8 |
+
sku TEXT PRIMARY KEY, name TEXT NOT NULL, category TEXT NOT NULL,
|
| 9 |
+
unit TEXT NOT NULL, sale_price_cents INTEGER NOT NULL CHECK (sale_price_cents >= 0),
|
| 10 |
+
reorder_point INTEGER NOT NULL CHECK (reorder_point >= 0), target_stock INTEGER NOT NULL CHECK (target_stock >= reorder_point),
|
| 11 |
+
active INTEGER NOT NULL DEFAULT 1 CHECK (active IN (0,1))
|
| 12 |
+
);
|
| 13 |
+
CREATE TABLE IF NOT EXISTS supplier_products (
|
| 14 |
+
supplier_id TEXT NOT NULL REFERENCES suppliers(id), sku TEXT NOT NULL REFERENCES products(sku),
|
| 15 |
+
unit_cost_cents INTEGER NOT NULL CHECK (unit_cost_cents >= 0), min_order_qty INTEGER NOT NULL DEFAULT 1 CHECK (min_order_qty > 0),
|
| 16 |
+
PRIMARY KEY (supplier_id, sku)
|
| 17 |
+
);
|
| 18 |
+
CREATE TABLE IF NOT EXISTS inventory (
|
| 19 |
+
sku TEXT PRIMARY KEY REFERENCES products(sku), on_hand INTEGER NOT NULL DEFAULT 0 CHECK (on_hand >= 0),
|
| 20 |
+
reserved INTEGER NOT NULL DEFAULT 0 CHECK (reserved >= 0 AND reserved <= on_hand),
|
| 21 |
+
updated_at TEXT NOT NULL
|
| 22 |
+
);
|
| 23 |
+
CREATE TABLE IF NOT EXISTS sales_orders (
|
| 24 |
+
id TEXT PRIMARY KEY, customer_name TEXT NOT NULL, region TEXT NOT NULL,
|
| 25 |
+
placed_at TEXT NOT NULL, status TEXT NOT NULL CHECK (status IN ('pendiente','confirmado','enviado','cancelado'))
|
| 26 |
+
);
|
| 27 |
+
CREATE TABLE IF NOT EXISTS sales_order_lines (
|
| 28 |
+
order_id TEXT NOT NULL REFERENCES sales_orders(id), line_no INTEGER NOT NULL CHECK (line_no > 0),
|
| 29 |
+
sku TEXT NOT NULL REFERENCES products(sku), quantity INTEGER NOT NULL CHECK (quantity > 0),
|
| 30 |
+
unit_price_cents INTEGER NOT NULL CHECK (unit_price_cents >= 0), PRIMARY KEY (order_id, line_no)
|
| 31 |
+
);
|
| 32 |
+
CREATE TABLE IF NOT EXISTS purchase_proposals (
|
| 33 |
+
id TEXT PRIMARY KEY, sku TEXT NOT NULL, supplier_id TEXT NOT NULL,
|
| 34 |
+
proposed_qty INTEGER NOT NULL CHECK (proposed_qty > 0), unit_cost_cents INTEGER NOT NULL CHECK (unit_cost_cents >= 0),
|
| 35 |
+
currency TEXT NOT NULL DEFAULT 'USD' CHECK (length(currency) = 3),
|
| 36 |
+
agent_id TEXT NOT NULL, rationale TEXT NOT NULL, created_at TEXT NOT NULL,
|
| 37 |
+
FOREIGN KEY (supplier_id, sku) REFERENCES supplier_products(supplier_id, sku)
|
| 38 |
+
);
|
| 39 |
+
-- Una decisi贸n por propuesta. Las propuestas pendientes a煤n no tienen decidido_por/decidido_at.
|
| 40 |
+
CREATE TABLE IF NOT EXISTS approval_queue (
|
| 41 |
+
proposal_id TEXT PRIMARY KEY REFERENCES purchase_proposals(id),
|
| 42 |
+
status TEXT NOT NULL DEFAULT 'pendiente' CHECK (status IN ('pendiente','aprobada','rechazada')),
|
| 43 |
+
decided_by TEXT, decided_at TEXT, decision_reason TEXT,
|
| 44 |
+
CHECK ((status = 'pendiente' AND decided_by IS NULL AND decided_at IS NULL)
|
| 45 |
+
OR (status <> 'pendiente' AND decided_by IS NOT NULL AND decided_at IS NOT NULL))
|
| 46 |
+
);
|
| 47 |
+
CREATE TABLE IF NOT EXISTS stock_movements (
|
| 48 |
+
id TEXT PRIMARY KEY, sku TEXT NOT NULL REFERENCES products(sku),
|
| 49 |
+
delta INTEGER NOT NULL CHECK (delta <> 0), reason TEXT NOT NULL, proposal_id TEXT REFERENCES purchase_proposals(id),
|
| 50 |
+
created_at TEXT NOT NULL
|
| 51 |
+
);
|
| 52 |
+
CREATE TABLE IF NOT EXISTS audit_log (
|
| 53 |
+
id TEXT PRIMARY KEY, occurred_at TEXT NOT NULL, actor TEXT NOT NULL, action TEXT NOT NULL,
|
| 54 |
+
entity_type TEXT NOT NULL, entity_id TEXT NOT NULL, details_json TEXT NOT NULL CHECK (json_valid(details_json))
|
| 55 |
+
);
|
| 56 |
+
CREATE INDEX IF NOT EXISTS idx_orders_placed ON sales_orders(placed_at);
|
| 57 |
+
CREATE INDEX IF NOT EXISTS idx_lines_sku ON sales_order_lines(sku);
|
| 58 |
+
CREATE INDEX IF NOT EXISTS idx_approval_status ON approval_queue(status);
|
| 59 |
+
CREATE INDEX IF NOT EXISTS idx_audit_time ON audit_log(occurred_at);
|
| 60 |
+
CREATE VIEW IF NOT EXISTS stock_status AS
|
| 61 |
+
SELECT p.sku, p.name, i.on_hand, i.reserved, i.on_hand - i.reserved AS available,
|
| 62 |
+
p.reorder_point, p.target_stock,
|
| 63 |
+
CASE WHEN i.on_hand - i.reserved <= p.reorder_point THEN 1 ELSE 0 END AS needs_restock
|
| 64 |
+
FROM products p JOIN inventory i ON i.sku = p.sku;
|
| 65 |
+
CREATE TABLE IF NOT EXISTS workforce (
|
| 66 |
+
id TEXT PRIMARY KEY, name TEXT NOT NULL, role TEXT NOT NULL, team TEXT NOT NULL,
|
| 67 |
+
capacity_hours INTEGER NOT NULL CHECK(capacity_hours >= 0), assigned_hours INTEGER NOT NULL CHECK(assigned_hours >= 0),
|
| 68 |
+
status TEXT NOT NULL CHECK(status IN ('disponible','ocupado','ausente'))
|
| 69 |
+
);
|
| 70 |
+
CREATE TABLE IF NOT EXISTS production_jobs (
|
| 71 |
+
id TEXT PRIMARY KEY, sku TEXT NOT NULL REFERENCES products(sku), quantity INTEGER NOT NULL CHECK(quantity > 0),
|
| 72 |
+
stage TEXT NOT NULL, due_at TEXT NOT NULL, owner TEXT NOT NULL, order_id TEXT REFERENCES sales_orders(id)
|
| 73 |
+
);
|
| 74 |
+
CREATE TABLE IF NOT EXISTS planning_tasks (
|
| 75 |
+
id TEXT PRIMARY KEY, title TEXT NOT NULL, due_at TEXT NOT NULL, team TEXT NOT NULL,
|
| 76 |
+
status TEXT NOT NULL CHECK(status IN ('pendiente','en_curso','hecho')), linked_order_id TEXT REFERENCES sales_orders(id)
|
| 77 |
+
);
|