|
| 1 | +-- ACME ERP — multi-schema fixture for Brain, MCP, and chat-access-policy tests. |
| 2 | +-- Schemas: crm, sales, finance, inventory, hr, marts (analytics mart). |
| 3 | +-- Duplicate bare table names (customers, orders) across crm/sales on purpose. |
| 4 | + |
| 5 | +SELECT 'Creating acme_erp multi-schema database' AS status; |
| 6 | + |
| 7 | +DROP DATABASE IF EXISTS acme_erp; |
| 8 | +CREATE DATABASE acme_erp; |
| 9 | + |
| 10 | +\connect acme_erp |
| 11 | + |
| 12 | +CREATE EXTENSION IF NOT EXISTS pg_stat_statements; |
| 13 | + |
| 14 | +CREATE SCHEMA crm; |
| 15 | +CREATE SCHEMA sales; |
| 16 | +CREATE SCHEMA finance; |
| 17 | +CREATE SCHEMA inventory; |
| 18 | +CREATE SCHEMA hr; |
| 19 | +CREATE SCHEMA marts; |
| 20 | + |
| 21 | +-- CRM |
| 22 | +CREATE TABLE crm.customers ( |
| 23 | + id SERIAL PRIMARY KEY, |
| 24 | + name TEXT NOT NULL, |
| 25 | + email TEXT, |
| 26 | + amount NUMERIC(12, 2) DEFAULT 0, |
| 27 | + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
| 28 | +); |
| 29 | + |
| 30 | +CREATE TABLE crm.accounts ( |
| 31 | + id SERIAL PRIMARY KEY, |
| 32 | + customer_id INT REFERENCES crm.customers(id), |
| 33 | + balance NUMERIC(14, 2) NOT NULL DEFAULT 0 |
| 34 | +); |
| 35 | + |
| 36 | +-- Sales (same bare names as crm) |
| 37 | +CREATE TABLE sales.customers ( |
| 38 | + id SERIAL PRIMARY KEY, |
| 39 | + name TEXT NOT NULL, |
| 40 | + email TEXT, |
| 41 | + revenue NUMERIC(12, 2) DEFAULT 0 |
| 42 | +); |
| 43 | + |
| 44 | +CREATE TABLE sales.orders ( |
| 45 | + id SERIAL PRIMARY KEY, |
| 46 | + customer_id INT REFERENCES sales.customers(id), |
| 47 | + amount NUMERIC(12, 2) NOT NULL, |
| 48 | + currency VARCHAR(3) NOT NULL DEFAULT 'USD', |
| 49 | + status TEXT NOT NULL DEFAULT 'open', |
| 50 | + ordered_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
| 51 | +); |
| 52 | + |
| 53 | +-- Finance |
| 54 | +CREATE TABLE finance.ledger ( |
| 55 | + id SERIAL PRIMARY KEY, |
| 56 | + account_code TEXT NOT NULL, |
| 57 | + amount NUMERIC(14, 2) NOT NULL, |
| 58 | + currency VARCHAR(3) NOT NULL DEFAULT 'USD', |
| 59 | + posted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP |
| 60 | +); |
| 61 | + |
| 62 | +-- Inventory |
| 63 | +CREATE TABLE inventory.products ( |
| 64 | + id SERIAL PRIMARY KEY, |
| 65 | + sku TEXT UNIQUE NOT NULL, |
| 66 | + name TEXT NOT NULL, |
| 67 | + stock_qty INT NOT NULL DEFAULT 0, |
| 68 | + unit_cost NUMERIC(10, 2) |
| 69 | +); |
| 70 | + |
| 71 | +-- HR |
| 72 | +CREATE TABLE hr.employees ( |
| 73 | + id SERIAL PRIMARY KEY, |
| 74 | + full_name TEXT NOT NULL, |
| 75 | + email TEXT, |
| 76 | + salary NUMERIC(12, 2), |
| 77 | + department TEXT |
| 78 | +); |
| 79 | + |
| 80 | +-- Marts — policy-test schema (numeric amount + string currency, like production marts) |
| 81 | +CREATE TABLE marts.fct_enrollment ( |
| 82 | + id SERIAL PRIMARY KEY, |
| 83 | + program_code TEXT NOT NULL, |
| 84 | + amount NUMERIC(12, 2) NOT NULL, |
| 85 | + currency VARCHAR(3) NOT NULL, |
| 86 | + enrolled_at DATE NOT NULL |
| 87 | +); |
| 88 | + |
| 89 | +CREATE TABLE marts.dim_ott_subscription ( |
| 90 | + id SERIAL PRIMARY KEY, |
| 91 | + subscriber_id TEXT NOT NULL, |
| 92 | + amount NUMERIC(10, 2) NOT NULL, |
| 93 | + currency VARCHAR(3) NOT NULL, |
| 94 | + plan_name TEXT |
| 95 | +); |
| 96 | + |
| 97 | +CREATE TABLE marts.rpt_revenue_monthly ( |
| 98 | + month DATE NOT NULL, |
| 99 | + region TEXT NOT NULL, |
| 100 | + amount NUMERIC(14, 2) NOT NULL, |
| 101 | + currency VARCHAR(3) NOT NULL, |
| 102 | + PRIMARY KEY (month, region) |
| 103 | +); |
| 104 | + |
| 105 | +-- Seed rows |
| 106 | +INSERT INTO crm.customers (name, email, amount) VALUES |
| 107 | + ('Acme Corp', 'acme@example.com', 1200.50), |
| 108 | + ('Globex', 'globex@example.com', 800.00); |
| 109 | + |
| 110 | +INSERT INTO crm.accounts (customer_id, balance) VALUES (1, 500.00), (2, 250.75); |
| 111 | + |
| 112 | +INSERT INTO sales.customers (name, email, revenue) VALUES |
| 113 | + ('Retail One', 'r1@example.com', 4200.00), |
| 114 | + ('Retail Two', 'r2@example.com', 3100.25); |
| 115 | + |
| 116 | +INSERT INTO sales.orders (customer_id, amount, currency, status) VALUES |
| 117 | + (1, 199.99, 'USD', 'shipped'), |
| 118 | + (2, 89.50, 'EUR', 'open'); |
| 119 | + |
| 120 | +INSERT INTO finance.ledger (account_code, amount, currency) VALUES |
| 121 | + ('CASH', 10000.00, 'USD'), |
| 122 | + ('AR', 2500.00, 'USD'); |
| 123 | + |
| 124 | +INSERT INTO inventory.products (sku, name, stock_qty, unit_cost) VALUES |
| 125 | + ('SKU-001', 'Widget', 120, 4.50), |
| 126 | + ('SKU-002', 'Gadget', 45, 12.00); |
| 127 | + |
| 128 | +INSERT INTO hr.employees (full_name, email, salary, department) VALUES |
| 129 | + ('Jane Doe', 'jane@acme.com', 95000.00, 'Engineering'), |
| 130 | + ('John Smith', 'john@acme.com', 82000.00, 'Sales'); |
| 131 | + |
| 132 | +INSERT INTO marts.fct_enrollment (program_code, amount, currency, enrolled_at) VALUES |
| 133 | + ('IEO', 150.00, 'USD', CURRENT_DATE - 30), |
| 134 | + ('OTT', 9.99, 'INR', CURRENT_DATE - 7); |
| 135 | + |
| 136 | +INSERT INTO marts.dim_ott_subscription (subscriber_id, amount, currency, plan_name) VALUES |
| 137 | + ('sub-100', 12.99, 'USD', 'Premium'), |
| 138 | + ('sub-200', 499.00, 'INR', 'Annual'); |
| 139 | + |
| 140 | +INSERT INTO marts.rpt_revenue_monthly (month, region, amount, currency) VALUES |
| 141 | + (DATE_TRUNC('month', CURRENT_DATE)::date, 'NA', 125000.00, 'USD'), |
| 142 | + (DATE_TRUNC('month', CURRENT_DATE)::date, 'APAC', 98000.00, 'INR'); |
0 commit comments