fivetech commited on
Commit
ad78afe
路
verified 路
1 Parent(s): 789633a

Create schema.sql

Browse files
Files changed (1) hide show
  1. 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
+ );