@synapsor/runner 1.6.2 → 1.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +141 -2
- package/CONTRIBUTING.md +10 -3
- package/README.md +65 -83
- package/SECURITY.md +14 -2
- package/THREAT_MODEL.md +64 -4
- package/dist/authoring.mjs +151 -16
- package/dist/cli.d.ts +31 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/local-ui.d.ts +145 -1
- package/dist/local-ui.d.ts.map +1 -1
- package/dist/runner.mjs +37488 -19009
- package/dist/runtime.mjs +4056 -235
- package/dist/shadow.mjs +2423 -65
- package/docs/README.md +36 -2
- package/docs/agent-guided-setup.md +239 -0
- package/docs/aggregate-reads.md +14 -5
- package/docs/app-owned-executors.md +5 -6
- package/docs/approval-roles-and-operator-identity.md +353 -0
- package/docs/auto-boundary-and-scoped-explore.md +89 -11
- package/docs/capability-authoring.md +21 -2
- package/docs/client-recipes.md +1 -1
- package/docs/cloud-mode.md +7 -7
- package/docs/conformance.md +6 -3
- package/docs/current-scope.md +32 -2
- package/docs/cursor-plugin.md +3 -3
- package/docs/database-enforced-scope.md +6 -0
- package/docs/dsl-json-parity.md +75 -0
- package/docs/dsl-reference.md +22 -1
- package/docs/fresh-developer-usability.md +155 -80
- package/docs/getting-started-own-database.md +45 -44
- package/docs/guarded-crud-writeback.md +19 -0
- package/docs/guided-onboarding.md +399 -0
- package/docs/human-attention-notifications.md +367 -0
- package/docs/limitations.md +49 -13
- package/docs/local-mode.md +36 -22
- package/docs/mcp-audit.md +14 -14
- package/docs/mcp-client-setup.md +11 -14
- package/docs/mcp-clients.md +1 -1
- package/docs/migrating-to-synapsor-spec.md +42 -0
- package/docs/openai-agents-sdk.md +2 -2
- package/docs/production.md +39 -0
- package/docs/proposal-evidence-freshness.md +7 -7
- package/docs/recipes.md +6 -6
- package/docs/release-notes.md +144 -4
- package/docs/release-policy.md +20 -7
- package/docs/reversible-change-sets.md +1 -1
- package/docs/reviewed-database-views.md +132 -0
- package/docs/reviewed-relationships.md +245 -0
- package/docs/rfcs/006-reviewed-reversible-change-sets.md +1 -1
- package/docs/runner-bundles.md +7 -7
- package/docs/runner-config-reference.md +132 -0
- package/docs/running-a-runner-fleet.md +16 -1
- package/docs/schema-api-candidates.md +1 -1
- package/docs/security-boundary.md +54 -0
- package/docs/store-lifecycle.md +20 -1
- package/docs/supervised-automatic-apply.md +267 -0
- package/docs/troubleshooting-first-run.md +85 -10
- package/docs/use-your-own-database.md +6 -4
- package/docs/workbench-ask.md +279 -0
- package/docs/writeback-executors.md +7 -7
- package/examples/auto-boundary-churn/README.md +1 -1
- package/examples/community-solar-clean-room/README.md +7 -0
- package/examples/community-solar-clean-room/docker-compose.yml +16 -0
- package/examples/community-solar-clean-room/package.json +15 -0
- package/examples/community-solar-clean-room/prisma/schema.prisma +171 -0
- package/examples/community-solar-clean-room/seed/postgres.sql +571 -0
- package/examples/fitflow-guided-onboarding/README.md +43 -0
- package/examples/fitflow-guided-onboarding/app/page.tsx +8 -0
- package/examples/fitflow-guided-onboarding/docker-compose.yml +16 -0
- package/examples/fitflow-guided-onboarding/package.json +18 -0
- package/examples/fitflow-guided-onboarding/prisma/schema.prisma +98 -0
- package/examples/fitflow-guided-onboarding/seed/postgres.sql +401 -0
- package/examples/openai-agents-http/Makefile +1 -1
- package/examples/openai-agents-http/README.md +1 -1
- package/examples/openai-agents-stdio/Makefile +1 -1
- package/examples/openai-agents-stdio/README.md +2 -2
- package/examples/openai-agents-stdio/agent.py +1 -4
- package/examples/operator-oidc/issuer.mjs +188 -0
- package/examples/reference-support-billing-app/README.md +16 -16
- package/examples/retail-clean-room/README.md +7 -0
- package/examples/retail-clean-room/docker-compose.yml +16 -0
- package/examples/retail-clean-room/package.json +9 -0
- package/examples/retail-clean-room/prisma/schema.prisma +239 -0
- package/examples/retail-clean-room/seed/postgres.sql +781 -0
- package/examples/retail-clean-room/view-recipe/average-retained-revenue.synapsor.sql +21 -0
- package/examples/retail-clean-room/view-recipe/synapsor.runner.json +25 -0
- package/examples/support-plan-credit/README.md +6 -2
- package/examples/support-plan-credit/mcp-client-examples/claude-code.sh +1 -4
- package/examples/support-plan-credit/mcp-client-examples/claude-desktop.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/codex.config.toml +1 -4
- package/examples/support-plan-credit/mcp-client-examples/cursor-global.mcp.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/cursor-project.mcp.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/generic-stdio.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/generic-stdio.mjs +1 -1
- package/examples/support-plan-credit/mcp-client-examples/google-adk.py +1 -1
- package/examples/support-plan-credit/mcp-client-examples/langchain.mjs +1 -1
- package/examples/support-plan-credit/mcp-client-examples/llamaindex.py +1 -1
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-stdio.ts +1 -1
- package/examples/support-plan-credit/mcp-client-examples/vscode.mcp.json +1 -4
- package/fixtures/compatibility/published-1.6.3/manifest.json +76 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/aggregate-read.synapsor.sql +21 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/billing-late-fee.synapsor.sql +56 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/bounded-set-multi-term.synapsor.sql +30 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/principal-row-scope.synapsor.sql +23 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/aggregate-read/contract.json +119 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/approval-quorum/contract.json +44 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/bounded-set-threats/contract.json +115 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/principal-row-scope/contract.json +78 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/proposal-capability/contract.json +101 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/reversible-change-sets/contract.json +98 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/valid/basic-read.contract.json +60 -0
- package/llms.txt +10 -5
- package/package.json +11 -3
- package/schemas/schema-candidate-review.schema.json +42 -0
- package/schemas/synapsor.runner.schema.json +227 -4
|
@@ -0,0 +1,781 @@
|
|
|
1
|
+
DO $$
|
|
2
|
+
BEGIN
|
|
3
|
+
CREATE ROLE retail_manager_reader LOGIN PASSWORD 'retail_manager_reader_password';
|
|
4
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
5
|
+
END
|
|
6
|
+
$$;
|
|
7
|
+
|
|
8
|
+
DO $$
|
|
9
|
+
BEGIN
|
|
10
|
+
CREATE ROLE retail_writer LOGIN PASSWORD 'retail_writer_password';
|
|
11
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
12
|
+
END
|
|
13
|
+
$$;
|
|
14
|
+
|
|
15
|
+
DO $$
|
|
16
|
+
BEGIN
|
|
17
|
+
CREATE ROLE retail_setup LOGIN PASSWORD 'retail_setup_password';
|
|
18
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
19
|
+
END
|
|
20
|
+
$$;
|
|
21
|
+
|
|
22
|
+
ALTER ROLE retail_manager_reader SET default_transaction_read_only = on;
|
|
23
|
+
|
|
24
|
+
CREATE TABLE public.merchants (
|
|
25
|
+
id text PRIMARY KEY,
|
|
26
|
+
name text NOT NULL
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE public.regions (
|
|
30
|
+
id text PRIMARY KEY,
|
|
31
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
32
|
+
name text NOT NULL,
|
|
33
|
+
shipping_region text NOT NULL,
|
|
34
|
+
UNIQUE (merchant_id, name)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE public.stores (
|
|
38
|
+
id text PRIMARY KEY,
|
|
39
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
40
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
41
|
+
name text NOT NULL,
|
|
42
|
+
channel text NOT NULL CHECK (channel IN ('retail', 'outlet', 'online')),
|
|
43
|
+
accounting_period text NOT NULL,
|
|
44
|
+
UNIQUE (merchant_id, name)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
CREATE TABLE public.staff_roles (
|
|
48
|
+
id text PRIMARY KEY,
|
|
49
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
50
|
+
role_code text NOT NULL,
|
|
51
|
+
display_name text NOT NULL,
|
|
52
|
+
UNIQUE (merchant_id, role_code)
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE public.staff (
|
|
56
|
+
id text PRIMARY KEY,
|
|
57
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
58
|
+
role_id text NOT NULL REFERENCES public.staff_roles(id) ON DELETE RESTRICT,
|
|
59
|
+
display_name text NOT NULL,
|
|
60
|
+
role_code text NOT NULL,
|
|
61
|
+
password_hash text NOT NULL,
|
|
62
|
+
session_token text NOT NULL,
|
|
63
|
+
api_access_token text NOT NULL,
|
|
64
|
+
risk_review_status text NOT NULL
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
CREATE TABLE public.store_assignments (
|
|
68
|
+
id text PRIMARY KEY,
|
|
69
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
70
|
+
store_id text NOT NULL REFERENCES public.stores(id) ON DELETE CASCADE,
|
|
71
|
+
staff_id text NOT NULL REFERENCES public.staff(id) ON DELETE CASCADE,
|
|
72
|
+
assignment_role text NOT NULL,
|
|
73
|
+
assigned_at timestamptz NOT NULL,
|
|
74
|
+
UNIQUE (store_id, staff_id, assignment_role)
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
CREATE TABLE public.customers (
|
|
78
|
+
id text PRIMARY KEY,
|
|
79
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
80
|
+
email text NOT NULL,
|
|
81
|
+
phone text NOT NULL,
|
|
82
|
+
tax_id text NOT NULL,
|
|
83
|
+
internal_risk_score integer NOT NULL CHECK (internal_risk_score BETWEEN 0 AND 1000),
|
|
84
|
+
status text NOT NULL CHECK (status IN ('active', 'paused', 'closed')),
|
|
85
|
+
created_at timestamptz NOT NULL
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
CREATE TABLE public.customer_addresses (
|
|
89
|
+
id text PRIMARY KEY,
|
|
90
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
91
|
+
customer_id text NOT NULL REFERENCES public.customers(id) ON DELETE CASCADE,
|
|
92
|
+
address_line_1 text NOT NULL,
|
|
93
|
+
address_line_2 text,
|
|
94
|
+
city text NOT NULL,
|
|
95
|
+
postal_code text NOT NULL,
|
|
96
|
+
shipping_region text NOT NULL,
|
|
97
|
+
home_address text NOT NULL
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
CREATE TABLE public.customer_sessions (
|
|
101
|
+
id text PRIMARY KEY,
|
|
102
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
103
|
+
customer_id text NOT NULL REFERENCES public.customers(id) ON DELETE CASCADE,
|
|
104
|
+
session_token text NOT NULL,
|
|
105
|
+
refresh_token text NOT NULL,
|
|
106
|
+
expires_at timestamptz NOT NULL
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
CREATE TABLE public.api_keys (
|
|
110
|
+
id text PRIMARY KEY,
|
|
111
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
112
|
+
owner_id text NOT NULL,
|
|
113
|
+
key_name text NOT NULL,
|
|
114
|
+
api_key_secret text NOT NULL,
|
|
115
|
+
created_at timestamptz NOT NULL
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
CREATE TABLE public.suppliers (
|
|
119
|
+
id text PRIMARY KEY,
|
|
120
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
121
|
+
name text NOT NULL,
|
|
122
|
+
status text NOT NULL,
|
|
123
|
+
contact_email text NOT NULL
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
CREATE TABLE public.supplier_accounts (
|
|
127
|
+
id text PRIMARY KEY,
|
|
128
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
129
|
+
supplier_id text NOT NULL REFERENCES public.suppliers(id) ON DELETE CASCADE,
|
|
130
|
+
bank_account_number text NOT NULL,
|
|
131
|
+
routing_number text NOT NULL,
|
|
132
|
+
payout_token text NOT NULL,
|
|
133
|
+
payment_status text NOT NULL
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
CREATE TABLE public.product_categories (
|
|
137
|
+
id text PRIMARY KEY,
|
|
138
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
139
|
+
name text NOT NULL,
|
|
140
|
+
category_group text NOT NULL,
|
|
141
|
+
UNIQUE (merchant_id, name)
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
CREATE TABLE public.products (
|
|
145
|
+
id text PRIMARY KEY,
|
|
146
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
147
|
+
primary_category_id text NOT NULL REFERENCES public.product_categories(id) ON DELETE RESTRICT,
|
|
148
|
+
supplier_id text NOT NULL REFERENCES public.suppliers(id) ON DELETE RESTRICT,
|
|
149
|
+
owner_id text NOT NULL,
|
|
150
|
+
name text NOT NULL,
|
|
151
|
+
status text NOT NULL CHECK (status IN ('draft', 'active', 'retired')),
|
|
152
|
+
version integer NOT NULL DEFAULT 1
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
CREATE TABLE public.product_variants (
|
|
156
|
+
id text PRIMARY KEY,
|
|
157
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
158
|
+
product_id text NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
159
|
+
sku text NOT NULL,
|
|
160
|
+
card_brand_display text NOT NULL,
|
|
161
|
+
pan_size_cm integer NOT NULL,
|
|
162
|
+
list_price_cents integer NOT NULL CHECK (list_price_cents >= 0),
|
|
163
|
+
UNIQUE (merchant_id, sku)
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
CREATE TABLE public.product_category_links (
|
|
167
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
168
|
+
product_id text NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
169
|
+
category_id text NOT NULL REFERENCES public.product_categories(id) ON DELETE CASCADE,
|
|
170
|
+
PRIMARY KEY (product_id, category_id)
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
CREATE TABLE public.price_history (
|
|
174
|
+
id text PRIMARY KEY,
|
|
175
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
176
|
+
product_variant_id text NOT NULL REFERENCES public.product_variants(id) ON DELETE CASCADE,
|
|
177
|
+
price_cents integer NOT NULL CHECK (price_cents >= 0),
|
|
178
|
+
effective_at timestamptz NOT NULL
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
CREATE TABLE public.warehouses (
|
|
182
|
+
id text PRIMARY KEY,
|
|
183
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
184
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
185
|
+
name text NOT NULL,
|
|
186
|
+
status text NOT NULL
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
CREATE TABLE public.inventory_levels (
|
|
190
|
+
id text PRIMARY KEY,
|
|
191
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
192
|
+
warehouse_id text NOT NULL REFERENCES public.warehouses(id) ON DELETE RESTRICT,
|
|
193
|
+
product_variant_id text NOT NULL REFERENCES public.product_variants(id) ON DELETE RESTRICT,
|
|
194
|
+
assigned_manager_id text NOT NULL REFERENCES public.staff(id) ON DELETE RESTRICT,
|
|
195
|
+
available_quantity integer NOT NULL CHECK (available_quantity >= 0),
|
|
196
|
+
reserved_quantity integer NOT NULL CHECK (reserved_quantity >= 0),
|
|
197
|
+
stockout_hours integer NOT NULL CHECK (stockout_hours >= 0),
|
|
198
|
+
version integer NOT NULL DEFAULT 1,
|
|
199
|
+
UNIQUE (warehouse_id, product_variant_id)
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
CREATE TABLE public.stock_movements (
|
|
203
|
+
id text PRIMARY KEY,
|
|
204
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
205
|
+
inventory_level_id text NOT NULL REFERENCES public.inventory_levels(id) ON DELETE RESTRICT,
|
|
206
|
+
movement_type text NOT NULL,
|
|
207
|
+
quantity integer NOT NULL,
|
|
208
|
+
occurred_at timestamptz NOT NULL
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
CREATE TABLE public.reorder_rules (
|
|
212
|
+
id text PRIMARY KEY,
|
|
213
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
214
|
+
inventory_level_id text NOT NULL REFERENCES public.inventory_levels(id) ON DELETE CASCADE,
|
|
215
|
+
reorder_point integer NOT NULL CHECK (reorder_point >= 0),
|
|
216
|
+
reorder_quantity integer NOT NULL CHECK (reorder_quantity > 0)
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
CREATE TABLE public.carts (
|
|
220
|
+
id text PRIMARY KEY,
|
|
221
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
222
|
+
store_id text NOT NULL REFERENCES public.stores(id) ON DELETE RESTRICT,
|
|
223
|
+
customer_id text NOT NULL REFERENCES public.customers(id) ON DELETE RESTRICT,
|
|
224
|
+
status text NOT NULL,
|
|
225
|
+
created_at timestamptz NOT NULL
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
CREATE TABLE public.cart_items (
|
|
229
|
+
id text PRIMARY KEY,
|
|
230
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
231
|
+
cart_id text NOT NULL REFERENCES public.carts(id) ON DELETE CASCADE,
|
|
232
|
+
product_variant_id text NOT NULL REFERENCES public.product_variants(id) ON DELETE RESTRICT,
|
|
233
|
+
quantity integer NOT NULL CHECK (quantity > 0)
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
CREATE TABLE public.checkout_sessions (
|
|
237
|
+
id text PRIMARY KEY,
|
|
238
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
239
|
+
cart_id text NOT NULL REFERENCES public.carts(id) ON DELETE RESTRICT,
|
|
240
|
+
checkout_token text NOT NULL,
|
|
241
|
+
status text NOT NULL,
|
|
242
|
+
expires_at timestamptz NOT NULL
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
CREATE TABLE public.orders (
|
|
246
|
+
id text PRIMARY KEY,
|
|
247
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
248
|
+
store_id text NOT NULL REFERENCES public.stores(id) ON DELETE RESTRICT,
|
|
249
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
250
|
+
customer_id text NOT NULL REFERENCES public.customers(id) ON DELETE RESTRICT,
|
|
251
|
+
assigned_manager_id text NOT NULL REFERENCES public.staff(id) ON DELETE RESTRICT,
|
|
252
|
+
channel text NOT NULL CHECK (channel IN ('retail', 'online', 'marketplace')),
|
|
253
|
+
status text NOT NULL CHECK (status IN ('placed', 'processing', 'fulfilled', 'cancelled')),
|
|
254
|
+
gross_revenue_cents integer NOT NULL CHECK (gross_revenue_cents >= 0),
|
|
255
|
+
net_revenue_cents integer NOT NULL CHECK (net_revenue_cents >= 0),
|
|
256
|
+
placed_at timestamptz NOT NULL,
|
|
257
|
+
version integer NOT NULL DEFAULT 1,
|
|
258
|
+
private_customer_note text NOT NULL
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
CREATE INDEX orders_trusted_scope_idx
|
|
262
|
+
ON public.orders(merchant_id, assigned_manager_id, placed_at);
|
|
263
|
+
|
|
264
|
+
CREATE TABLE public.order_items (
|
|
265
|
+
id text PRIMARY KEY,
|
|
266
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
267
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE CASCADE,
|
|
268
|
+
product_id text NOT NULL REFERENCES public.products(id) ON DELETE RESTRICT,
|
|
269
|
+
product_variant_id text NOT NULL REFERENCES public.product_variants(id) ON DELETE RESTRICT,
|
|
270
|
+
quantity integer NOT NULL CHECK (quantity > 0),
|
|
271
|
+
gross_line_revenue_cents integer NOT NULL CHECK (gross_line_revenue_cents >= 0),
|
|
272
|
+
net_line_revenue_cents integer NOT NULL CHECK (net_line_revenue_cents >= 0)
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
CREATE TABLE public.payment_methods (
|
|
276
|
+
id text PRIMARY KEY,
|
|
277
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
278
|
+
customer_id text NOT NULL REFERENCES public.customers(id) ON DELETE CASCADE,
|
|
279
|
+
card_on_file text NOT NULL,
|
|
280
|
+
full_pan text NOT NULL,
|
|
281
|
+
card_brand_display text NOT NULL,
|
|
282
|
+
bank_account_number text NOT NULL,
|
|
283
|
+
routing_number text NOT NULL
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
CREATE TABLE public.payments (
|
|
287
|
+
id text PRIMARY KEY,
|
|
288
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
289
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE RESTRICT,
|
|
290
|
+
payment_method_id text NOT NULL REFERENCES public.payment_methods(id) ON DELETE RESTRICT,
|
|
291
|
+
amount_cents integer NOT NULL CHECK (amount_cents >= 0),
|
|
292
|
+
payment_status text NOT NULL,
|
|
293
|
+
payment_token text NOT NULL,
|
|
294
|
+
pan_last_four text NOT NULL,
|
|
295
|
+
cvv_value text NOT NULL,
|
|
296
|
+
created_at timestamptz NOT NULL
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
CREATE TABLE public.payment_attempts (
|
|
300
|
+
id text PRIMARY KEY,
|
|
301
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
302
|
+
payment_id text NOT NULL REFERENCES public.payments(id) ON DELETE CASCADE,
|
|
303
|
+
attempt_number integer NOT NULL,
|
|
304
|
+
status text NOT NULL,
|
|
305
|
+
processor_token text NOT NULL,
|
|
306
|
+
attempted_at timestamptz NOT NULL
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
CREATE TABLE public.refunds (
|
|
310
|
+
id text PRIMARY KEY,
|
|
311
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
312
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE RESTRICT,
|
|
313
|
+
payment_id text NOT NULL REFERENCES public.payments(id) ON DELETE RESTRICT,
|
|
314
|
+
amount_cents integer NOT NULL CHECK (amount_cents >= 0),
|
|
315
|
+
reason_code text NOT NULL,
|
|
316
|
+
status text NOT NULL,
|
|
317
|
+
created_at timestamptz NOT NULL
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
CREATE TABLE public.shipments (
|
|
321
|
+
id text PRIMARY KEY,
|
|
322
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
323
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE RESTRICT,
|
|
324
|
+
warehouse_id text NOT NULL REFERENCES public.warehouses(id) ON DELETE RESTRICT,
|
|
325
|
+
carrier text NOT NULL,
|
|
326
|
+
tracking_token text NOT NULL,
|
|
327
|
+
status text NOT NULL,
|
|
328
|
+
shipped_at timestamptz
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
CREATE TABLE public.fulfillment_events (
|
|
332
|
+
id text PRIMARY KEY,
|
|
333
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
334
|
+
shipment_id text NOT NULL REFERENCES public.shipments(id) ON DELETE CASCADE,
|
|
335
|
+
event_type text NOT NULL,
|
|
336
|
+
delay_minutes integer NOT NULL CHECK (delay_minutes >= 0),
|
|
337
|
+
occurred_at timestamptz NOT NULL
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
CREATE TABLE public.return_reasons (
|
|
341
|
+
id text PRIMARY KEY,
|
|
342
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
343
|
+
reason_category text NOT NULL,
|
|
344
|
+
display_name text NOT NULL
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
CREATE TABLE public.returns (
|
|
348
|
+
id text PRIMARY KEY,
|
|
349
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
350
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE RESTRICT,
|
|
351
|
+
reason_id text NOT NULL REFERENCES public.return_reasons(id) ON DELETE RESTRICT,
|
|
352
|
+
status text NOT NULL,
|
|
353
|
+
requested_at timestamptz NOT NULL
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
CREATE TABLE public.return_items (
|
|
357
|
+
id text PRIMARY KEY,
|
|
358
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
359
|
+
return_id text NOT NULL REFERENCES public.returns(id) ON DELETE CASCADE,
|
|
360
|
+
order_item_id text NOT NULL REFERENCES public.order_items(id) ON DELETE RESTRICT,
|
|
361
|
+
quantity integer NOT NULL CHECK (quantity > 0)
|
|
362
|
+
);
|
|
363
|
+
|
|
364
|
+
CREATE TABLE public.promotions (
|
|
365
|
+
id text PRIMARY KEY,
|
|
366
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
367
|
+
name text NOT NULL,
|
|
368
|
+
promotion_category text NOT NULL,
|
|
369
|
+
starts_at timestamptz NOT NULL,
|
|
370
|
+
ends_at timestamptz NOT NULL
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
CREATE TABLE public.promotion_categories (
|
|
374
|
+
id text PRIMARY KEY,
|
|
375
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
376
|
+
name text NOT NULL
|
|
377
|
+
);
|
|
378
|
+
|
|
379
|
+
CREATE TABLE public.promotion_products (
|
|
380
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
381
|
+
promotion_id text NOT NULL REFERENCES public.promotions(id) ON DELETE CASCADE,
|
|
382
|
+
product_id text NOT NULL REFERENCES public.products(id) ON DELETE CASCADE,
|
|
383
|
+
PRIMARY KEY (promotion_id, product_id)
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
CREATE TABLE public.discounts (
|
|
387
|
+
id text PRIMARY KEY,
|
|
388
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
389
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE CASCADE,
|
|
390
|
+
promotion_id text REFERENCES public.promotions(id) ON DELETE SET NULL,
|
|
391
|
+
amount_cents integer NOT NULL CHECK (amount_cents >= 0),
|
|
392
|
+
discount_type text NOT NULL
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
CREATE TABLE public.support_cases (
|
|
396
|
+
id text PRIMARY KEY,
|
|
397
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
398
|
+
customer_id text NOT NULL REFERENCES public.customers(id) ON DELETE RESTRICT,
|
|
399
|
+
order_id text REFERENCES public.orders(id) ON DELETE SET NULL,
|
|
400
|
+
assigned_agent_id text NOT NULL REFERENCES public.staff(id) ON DELETE RESTRICT,
|
|
401
|
+
status text NOT NULL CHECK (status IN ('open', 'waiting', 'resolved')),
|
|
402
|
+
subject text NOT NULL,
|
|
403
|
+
private_support_notes text NOT NULL,
|
|
404
|
+
version integer NOT NULL DEFAULT 1
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
CREATE INDEX support_cases_trusted_scope_idx
|
|
408
|
+
ON public.support_cases(merchant_id, assigned_agent_id);
|
|
409
|
+
|
|
410
|
+
CREATE TABLE public.support_case_notes (
|
|
411
|
+
id text PRIMARY KEY,
|
|
412
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
413
|
+
support_case_id text NOT NULL REFERENCES public.support_cases(id) ON DELETE CASCADE,
|
|
414
|
+
author_id text NOT NULL REFERENCES public.staff(id) ON DELETE RESTRICT,
|
|
415
|
+
public_note text NOT NULL,
|
|
416
|
+
private_support_notes text NOT NULL,
|
|
417
|
+
created_at timestamptz NOT NULL
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
CREATE TABLE public.sales_line_facts (
|
|
421
|
+
id text PRIMARY KEY,
|
|
422
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
423
|
+
store_id text NOT NULL REFERENCES public.stores(id) ON DELETE RESTRICT,
|
|
424
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
425
|
+
product_id text NOT NULL REFERENCES public.products(id) ON DELETE RESTRICT,
|
|
426
|
+
product_category_id text NOT NULL REFERENCES public.product_categories(id) ON DELETE RESTRICT,
|
|
427
|
+
assigned_manager_id text NOT NULL REFERENCES public.staff(id) ON DELETE RESTRICT,
|
|
428
|
+
order_id text NOT NULL REFERENCES public.orders(id) ON DELETE RESTRICT,
|
|
429
|
+
channel text NOT NULL,
|
|
430
|
+
quantity integer NOT NULL CHECK (quantity > 0),
|
|
431
|
+
net_revenue_cents integer NOT NULL CHECK (net_revenue_cents >= 0),
|
|
432
|
+
sold_at timestamptz NOT NULL
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
CREATE INDEX sales_line_facts_scope_idx
|
|
436
|
+
ON public.sales_line_facts(merchant_id, assigned_manager_id, sold_at);
|
|
437
|
+
|
|
438
|
+
CREATE TABLE public.domain_events (
|
|
439
|
+
id text PRIMARY KEY,
|
|
440
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
441
|
+
aggregate_type text NOT NULL,
|
|
442
|
+
aggregate_id text NOT NULL,
|
|
443
|
+
event_type text NOT NULL,
|
|
444
|
+
payload_token text NOT NULL,
|
|
445
|
+
occurred_at timestamptz NOT NULL
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
CREATE TABLE public.audit_events (
|
|
449
|
+
id text PRIMARY KEY,
|
|
450
|
+
merchant_id text NOT NULL REFERENCES public.merchants(id) ON DELETE RESTRICT,
|
|
451
|
+
actor_id text NOT NULL,
|
|
452
|
+
action text NOT NULL,
|
|
453
|
+
object_type text NOT NULL,
|
|
454
|
+
object_id text NOT NULL,
|
|
455
|
+
private_audit_payload text NOT NULL,
|
|
456
|
+
occurred_at timestamptz NOT NULL
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
INSERT INTO public.merchants VALUES
|
|
460
|
+
('merchant-northstar', 'Northstar Outfitters'),
|
|
461
|
+
('merchant-rival', 'Rival Retail Group');
|
|
462
|
+
|
|
463
|
+
INSERT INTO public.regions VALUES
|
|
464
|
+
('region-pacific', 'merchant-northstar', 'Pacific', 'west'),
|
|
465
|
+
('region-mountain', 'merchant-northstar', 'Mountain', 'central'),
|
|
466
|
+
('region-rival', 'merchant-rival', 'Rival Region', 'east');
|
|
467
|
+
|
|
468
|
+
INSERT INTO public.stores VALUES
|
|
469
|
+
('store-seattle', 'merchant-northstar', 'region-pacific', 'Seattle Flagship', 'retail', '2026-Q2'),
|
|
470
|
+
('store-portland', 'merchant-northstar', 'region-pacific', 'Portland Market', 'retail', '2026-Q2'),
|
|
471
|
+
('store-denver', 'merchant-northstar', 'region-mountain', 'Denver Outlet', 'outlet', '2026-Q2'),
|
|
472
|
+
('store-rival', 'merchant-rival', 'region-rival', 'Rival Store', 'retail', '2026-Q2');
|
|
473
|
+
|
|
474
|
+
INSERT INTO public.staff_roles VALUES
|
|
475
|
+
('role-manager', 'merchant-northstar', 'store_manager', 'Store manager'),
|
|
476
|
+
('role-support', 'merchant-northstar', 'support_agent', 'Support agent'),
|
|
477
|
+
('role-rival', 'merchant-rival', 'store_manager', 'Store manager');
|
|
478
|
+
|
|
479
|
+
INSERT INTO public.staff VALUES
|
|
480
|
+
('staff-manager-alex', 'merchant-northstar', 'role-manager', 'Alex Rivera', 'store_manager', 'synthetic-password-hash-alex', 'synthetic-session-token-alex', 'synthetic-api-token-alex', 'clear'),
|
|
481
|
+
('staff-manager-jordan', 'merchant-northstar', 'role-manager', 'Jordan Lee', 'store_manager', 'synthetic-password-hash-jordan', 'synthetic-session-token-jordan', 'synthetic-api-token-jordan', 'reviewed'),
|
|
482
|
+
('staff-support-maya', 'merchant-northstar', 'role-support', 'Maya Chen', 'support_agent', 'synthetic-password-hash-maya', 'synthetic-session-token-maya', 'synthetic-api-token-maya', 'clear'),
|
|
483
|
+
('staff-support-noah', 'merchant-northstar', 'role-support', 'Noah Smith', 'support_agent', 'synthetic-password-hash-noah', 'synthetic-session-token-noah', 'synthetic-api-token-noah', 'clear'),
|
|
484
|
+
('staff-rival', 'merchant-rival', 'role-rival', 'Rival Operator', 'store_manager', 'rival-password-hash', 'rival-session-token', 'rival-api-token', 'clear');
|
|
485
|
+
|
|
486
|
+
INSERT INTO public.store_assignments VALUES
|
|
487
|
+
('assign-1', 'merchant-northstar', 'store-seattle', 'staff-manager-alex', 'manager', '2026-01-01T00:00:00Z'),
|
|
488
|
+
('assign-2', 'merchant-northstar', 'store-portland', 'staff-manager-alex', 'manager', '2026-01-01T00:00:00Z'),
|
|
489
|
+
('assign-3', 'merchant-northstar', 'store-denver', 'staff-manager-jordan', 'manager', '2026-01-01T00:00:00Z'),
|
|
490
|
+
('assign-rival', 'merchant-rival', 'store-rival', 'staff-rival', 'manager', '2026-01-01T00:00:00Z');
|
|
491
|
+
|
|
492
|
+
INSERT INTO public.customers
|
|
493
|
+
SELECT
|
|
494
|
+
'customer-' || n,
|
|
495
|
+
'merchant-northstar',
|
|
496
|
+
'customer' || n || '@example.test',
|
|
497
|
+
'+1-555-01' || lpad(n::text, 2, '0'),
|
|
498
|
+
'synthetic-tax-id-' || n,
|
|
499
|
+
100 + n,
|
|
500
|
+
'active',
|
|
501
|
+
'2026-01-01T00:00:00Z'::timestamptz + (n || ' days')::interval
|
|
502
|
+
FROM generate_series(1, 12) AS n;
|
|
503
|
+
|
|
504
|
+
INSERT INTO public.customers VALUES
|
|
505
|
+
('customer-rival', 'merchant-rival', 'rival@example.test', '+1-555-9999', 'rival-tax-id', 900, 'active', '2026-01-01T00:00:00Z');
|
|
506
|
+
|
|
507
|
+
INSERT INTO public.customer_addresses VALUES
|
|
508
|
+
('address-1', 'merchant-northstar', 'customer-1', '101 Private Way', NULL, 'Seattle', '98101', 'west', '101 Private Way, Seattle'),
|
|
509
|
+
('address-rival', 'merchant-rival', 'customer-rival', '999 Rival Road', NULL, 'Boston', '02101', 'east', '999 Rival Road, Boston');
|
|
510
|
+
|
|
511
|
+
INSERT INTO public.customer_sessions VALUES
|
|
512
|
+
('customer-session-1', 'merchant-northstar', 'customer-1', 'synthetic-customer-session-token', 'synthetic-refresh-token', '2027-01-01T00:00:00Z');
|
|
513
|
+
|
|
514
|
+
INSERT INTO public.api_keys VALUES
|
|
515
|
+
('api-key-1', 'merchant-northstar', 'staff-manager-alex', 'warehouse sync', 'synthetic-secret-api-key', '2026-01-01T00:00:00Z');
|
|
516
|
+
|
|
517
|
+
INSERT INTO public.suppliers VALUES
|
|
518
|
+
('supplier-outdoor', 'merchant-northstar', 'Outdoor Supply Co', 'active', 'supplier@example.test'),
|
|
519
|
+
('supplier-rival', 'merchant-rival', 'Rival Supplier', 'active', 'rival-supplier@example.test');
|
|
520
|
+
|
|
521
|
+
INSERT INTO public.supplier_accounts VALUES
|
|
522
|
+
('supplier-account-1', 'merchant-northstar', 'supplier-outdoor', '000111222333', '110000000', 'synthetic-payout-token', 'verified');
|
|
523
|
+
|
|
524
|
+
INSERT INTO public.product_categories VALUES
|
|
525
|
+
('category-camping', 'merchant-northstar', 'Camping', 'outdoor'),
|
|
526
|
+
('category-running', 'merchant-northstar', 'Running', 'fitness'),
|
|
527
|
+
('category-rival', 'merchant-rival', 'Rival Category', 'other');
|
|
528
|
+
|
|
529
|
+
INSERT INTO public.products VALUES
|
|
530
|
+
('product-tent', 'merchant-northstar', 'category-camping', 'supplier-outdoor', 'catalog-owner-1', 'Trail Tent', 'active', 1),
|
|
531
|
+
('product-shoe', 'merchant-northstar', 'category-running', 'supplier-outdoor', 'catalog-owner-2', 'Ridge Runner Shoe', 'active', 1),
|
|
532
|
+
('product-rival', 'merchant-rival', 'category-rival', 'supplier-rival', 'rival-owner', 'Rival Product', 'active', 1);
|
|
533
|
+
|
|
534
|
+
INSERT INTO public.product_variants VALUES
|
|
535
|
+
('variant-tent', 'merchant-northstar', 'product-tent', 'TENT-001', 'not_applicable', 42, 19900),
|
|
536
|
+
('variant-shoe', 'merchant-northstar', 'product-shoe', 'SHOE-001', 'not_applicable', 31, 12900),
|
|
537
|
+
('variant-rival', 'merchant-rival', 'product-rival', 'RIVAL-001', 'not_applicable', 28, 9900);
|
|
538
|
+
|
|
539
|
+
INSERT INTO public.product_category_links VALUES
|
|
540
|
+
('merchant-northstar', 'product-tent', 'category-camping'),
|
|
541
|
+
('merchant-northstar', 'product-tent', 'category-running'),
|
|
542
|
+
('merchant-northstar', 'product-shoe', 'category-running');
|
|
543
|
+
|
|
544
|
+
INSERT INTO public.price_history VALUES
|
|
545
|
+
('price-1', 'merchant-northstar', 'variant-tent', 19900, '2026-01-01T00:00:00Z'),
|
|
546
|
+
('price-2', 'merchant-northstar', 'variant-shoe', 12900, '2026-01-01T00:00:00Z');
|
|
547
|
+
|
|
548
|
+
INSERT INTO public.warehouses VALUES
|
|
549
|
+
('warehouse-pacific', 'merchant-northstar', 'region-pacific', 'Pacific Warehouse', 'active'),
|
|
550
|
+
('warehouse-mountain', 'merchant-northstar', 'region-mountain', 'Mountain Warehouse', 'active');
|
|
551
|
+
|
|
552
|
+
INSERT INTO public.inventory_levels VALUES
|
|
553
|
+
('inventory-tent', 'merchant-northstar', 'warehouse-pacific', 'variant-tent', 'staff-manager-alex', 42, 8, 3, 1),
|
|
554
|
+
('inventory-shoe', 'merchant-northstar', 'warehouse-pacific', 'variant-shoe', 'staff-manager-alex', 64, 12, 1, 1);
|
|
555
|
+
|
|
556
|
+
INSERT INTO public.stock_movements VALUES
|
|
557
|
+
('movement-1', 'merchant-northstar', 'inventory-tent', 'receipt', 20, '2026-06-01T00:00:00Z');
|
|
558
|
+
|
|
559
|
+
INSERT INTO public.reorder_rules VALUES
|
|
560
|
+
('reorder-1', 'merchant-northstar', 'inventory-tent', 10, 50);
|
|
561
|
+
|
|
562
|
+
INSERT INTO public.carts VALUES
|
|
563
|
+
('cart-1', 'merchant-northstar', 'store-seattle', 'customer-1', 'active', '2026-06-01T00:00:00Z');
|
|
564
|
+
|
|
565
|
+
INSERT INTO public.cart_items VALUES
|
|
566
|
+
('cart-item-1', 'merchant-northstar', 'cart-1', 'variant-tent', 1);
|
|
567
|
+
|
|
568
|
+
INSERT INTO public.checkout_sessions VALUES
|
|
569
|
+
('checkout-1', 'merchant-northstar', 'cart-1', 'synthetic-checkout-token', 'complete', '2026-07-01T00:00:00Z');
|
|
570
|
+
|
|
571
|
+
INSERT INTO public.orders
|
|
572
|
+
SELECT
|
|
573
|
+
'order-' || lpad(n::text, 3, '0'),
|
|
574
|
+
'merchant-northstar',
|
|
575
|
+
CASE WHEN n % 3 = 0 THEN 'store-portland' ELSE 'store-seattle' END,
|
|
576
|
+
'region-pacific',
|
|
577
|
+
'customer-' || (((n - 1) % 12) + 1),
|
|
578
|
+
'staff-manager-alex',
|
|
579
|
+
CASE WHEN n % 2 = 0 THEN 'online' ELSE 'retail' END,
|
|
580
|
+
CASE WHEN n % 5 = 0 THEN 'processing' ELSE 'fulfilled' END,
|
|
581
|
+
10000 + n * 100,
|
|
582
|
+
9000 + n * 90,
|
|
583
|
+
'2026-04-01T12:00:00Z'::timestamptz + (n * interval '3 days'),
|
|
584
|
+
1,
|
|
585
|
+
'synthetic private customer note ' || n
|
|
586
|
+
FROM generate_series(1, 30) AS n;
|
|
587
|
+
|
|
588
|
+
INSERT INTO public.orders VALUES
|
|
589
|
+
('order-manager-other', 'merchant-northstar', 'store-denver', 'region-mountain', 'customer-1', 'staff-manager-jordan', 'retail', 'processing', 18000, 16000, '2026-06-20T12:00:00Z', 1, 'other manager private note'),
|
|
590
|
+
('order-rival', 'merchant-rival', 'store-rival', 'region-rival', 'customer-rival', 'staff-rival', 'retail', 'fulfilled', 9900, 9000, '2026-06-20T12:00:00Z', 1, 'rival private note');
|
|
591
|
+
|
|
592
|
+
INSERT INTO public.order_items
|
|
593
|
+
SELECT
|
|
594
|
+
'item-' || lpad(n::text, 3, '0'),
|
|
595
|
+
'merchant-northstar',
|
|
596
|
+
'order-' || lpad(n::text, 3, '0'),
|
|
597
|
+
CASE WHEN n % 2 = 0 THEN 'product-shoe' ELSE 'product-tent' END,
|
|
598
|
+
CASE WHEN n % 2 = 0 THEN 'variant-shoe' ELSE 'variant-tent' END,
|
|
599
|
+
1,
|
|
600
|
+
10000 + n * 100,
|
|
601
|
+
9000 + n * 90
|
|
602
|
+
FROM generate_series(1, 30) AS n;
|
|
603
|
+
|
|
604
|
+
INSERT INTO public.payment_methods VALUES
|
|
605
|
+
('payment-method-1', 'merchant-northstar', 'customer-1', 'synthetic-card-on-file-token', '4111111111111111', 'Visa ending 1111', '000111222333', '110000000');
|
|
606
|
+
|
|
607
|
+
INSERT INTO public.payments
|
|
608
|
+
SELECT
|
|
609
|
+
'payment-' || lpad(n::text, 3, '0'),
|
|
610
|
+
'merchant-northstar',
|
|
611
|
+
'order-' || lpad(n::text, 3, '0'),
|
|
612
|
+
'payment-method-1',
|
|
613
|
+
9000 + n * 90,
|
|
614
|
+
'settled',
|
|
615
|
+
'synthetic-payment-token-' || n,
|
|
616
|
+
'1111',
|
|
617
|
+
'123',
|
|
618
|
+
'2026-04-01T12:05:00Z'::timestamptz + (n * interval '3 days')
|
|
619
|
+
FROM generate_series(1, 30) AS n;
|
|
620
|
+
|
|
621
|
+
INSERT INTO public.payment_attempts VALUES
|
|
622
|
+
('attempt-1', 'merchant-northstar', 'payment-001', 1, 'succeeded', 'synthetic-processor-token', '2026-04-04T12:05:00Z');
|
|
623
|
+
|
|
624
|
+
INSERT INTO public.refunds VALUES
|
|
625
|
+
('refund-1', 'merchant-northstar', 'order-005', 'payment-005', 1200, 'size', 'settled', '2026-05-01T00:00:00Z'),
|
|
626
|
+
('refund-2', 'merchant-northstar', 'order-010', 'payment-010', 800, 'damaged', 'settled', '2026-06-01T00:00:00Z');
|
|
627
|
+
|
|
628
|
+
INSERT INTO public.shipments VALUES
|
|
629
|
+
('shipment-1', 'merchant-northstar', 'order-001', 'warehouse-pacific', 'Synthetic Carrier', 'synthetic-tracking-token', 'delivered', '2026-04-05T00:00:00Z');
|
|
630
|
+
|
|
631
|
+
INSERT INTO public.fulfillment_events VALUES
|
|
632
|
+
('fulfillment-1', 'merchant-northstar', 'shipment-1', 'delivered', 15, '2026-04-07T00:00:00Z');
|
|
633
|
+
|
|
634
|
+
INSERT INTO public.return_reasons VALUES
|
|
635
|
+
('reason-size', 'merchant-northstar', 'size', 'Wrong size'),
|
|
636
|
+
('reason-damaged', 'merchant-northstar', 'damaged', 'Damaged item');
|
|
637
|
+
|
|
638
|
+
INSERT INTO public.returns VALUES
|
|
639
|
+
('return-1', 'merchant-northstar', 'order-005', 'reason-size', 'received', '2026-05-02T00:00:00Z'),
|
|
640
|
+
('return-2', 'merchant-northstar', 'order-010', 'reason-damaged', 'received', '2026-06-02T00:00:00Z');
|
|
641
|
+
|
|
642
|
+
INSERT INTO public.return_items VALUES
|
|
643
|
+
('return-item-1', 'merchant-northstar', 'return-1', 'item-005', 1);
|
|
644
|
+
|
|
645
|
+
INSERT INTO public.promotions VALUES
|
|
646
|
+
('promotion-spring', 'merchant-northstar', 'Spring Launch', 'seasonal', '2026-04-01T00:00:00Z', '2026-05-31T23:59:59Z');
|
|
647
|
+
|
|
648
|
+
INSERT INTO public.promotion_categories VALUES
|
|
649
|
+
('promotion-category-seasonal', 'merchant-northstar', 'Seasonal');
|
|
650
|
+
|
|
651
|
+
INSERT INTO public.promotion_products VALUES
|
|
652
|
+
('merchant-northstar', 'promotion-spring', 'product-tent'),
|
|
653
|
+
('merchant-northstar', 'promotion-spring', 'product-shoe');
|
|
654
|
+
|
|
655
|
+
INSERT INTO public.discounts VALUES
|
|
656
|
+
('discount-1', 'merchant-northstar', 'order-001', 'promotion-spring', 500, 'promotion');
|
|
657
|
+
|
|
658
|
+
INSERT INTO public.support_cases VALUES
|
|
659
|
+
('case-assigned', 'merchant-northstar', 'customer-1', 'order-001', 'staff-support-maya', 'open', 'Delivery question', 'synthetic private support note assigned', 1),
|
|
660
|
+
('case-unassigned', 'merchant-northstar', 'customer-2', 'order-002', 'staff-support-noah', 'open', 'Return question', 'synthetic private support note unassigned', 1),
|
|
661
|
+
('case-rival', 'merchant-rival', 'customer-rival', 'order-rival', 'staff-rival', 'open', 'Rival case', 'rival private support note', 1);
|
|
662
|
+
|
|
663
|
+
INSERT INTO public.support_case_notes VALUES
|
|
664
|
+
('case-note-1', 'merchant-northstar', 'case-assigned', 'staff-support-maya', 'We are checking delivery.', 'private escalation note', '2026-06-01T00:00:00Z');
|
|
665
|
+
|
|
666
|
+
INSERT INTO public.sales_line_facts
|
|
667
|
+
SELECT
|
|
668
|
+
'sales-fact-' || lpad(n::text, 3, '0'),
|
|
669
|
+
'merchant-northstar',
|
|
670
|
+
CASE WHEN n % 3 = 0 THEN 'store-portland' ELSE 'store-seattle' END,
|
|
671
|
+
'region-pacific',
|
|
672
|
+
CASE WHEN n % 2 = 0 THEN 'product-shoe' ELSE 'product-tent' END,
|
|
673
|
+
CASE WHEN n % 2 = 0 THEN 'category-running' ELSE 'category-camping' END,
|
|
674
|
+
'staff-manager-alex',
|
|
675
|
+
'order-' || lpad((((n - 1) % 30) + 1)::text, 3, '0'),
|
|
676
|
+
CASE WHEN n % 2 = 0 THEN 'online' ELSE 'retail' END,
|
|
677
|
+
1,
|
|
678
|
+
5000 + n * 75,
|
|
679
|
+
'2026-04-01T12:00:00Z'::timestamptz + (n * interval '3 hours')
|
|
680
|
+
FROM generate_series(1, 192) AS n;
|
|
681
|
+
|
|
682
|
+
INSERT INTO public.sales_line_facts VALUES
|
|
683
|
+
('sales-fact-other-manager', 'merchant-northstar', 'store-denver', 'region-mountain', 'product-tent', 'category-camping', 'staff-manager-jordan', 'order-manager-other', 'retail', 1, 16000, '2026-06-20T12:00:00Z'),
|
|
684
|
+
('sales-fact-rival', 'merchant-rival', 'store-rival', 'region-rival', 'product-rival', 'category-rival', 'staff-rival', 'order-rival', 'retail', 1, 9000, '2026-06-20T12:00:00Z');
|
|
685
|
+
|
|
686
|
+
INSERT INTO public.domain_events VALUES
|
|
687
|
+
('domain-event-1', 'merchant-northstar', 'order', 'order-001', 'order.fulfilled', 'synthetic-domain-payload-token', '2026-04-08T00:00:00Z');
|
|
688
|
+
|
|
689
|
+
INSERT INTO public.audit_events VALUES
|
|
690
|
+
('audit-event-1', 'merchant-northstar', 'staff-manager-alex', 'order.viewed', 'order', 'order-001', 'synthetic private audit payload', '2026-04-08T00:00:00Z');
|
|
691
|
+
|
|
692
|
+
ALTER TABLE public.merchants ENABLE ROW LEVEL SECURITY;
|
|
693
|
+
ALTER TABLE public.merchants FORCE ROW LEVEL SECURITY;
|
|
694
|
+
CREATE POLICY merchants_tenant_select
|
|
695
|
+
ON public.merchants FOR SELECT TO retail_manager_reader, retail_writer
|
|
696
|
+
USING (id = current_setting('app.tenant_id', true));
|
|
697
|
+
|
|
698
|
+
DO $$
|
|
699
|
+
DECLARE
|
|
700
|
+
table_name text;
|
|
701
|
+
BEGIN
|
|
702
|
+
FOR table_name IN
|
|
703
|
+
SELECT c.table_name
|
|
704
|
+
FROM information_schema.columns c
|
|
705
|
+
WHERE c.table_schema = 'public'
|
|
706
|
+
AND c.column_name = 'merchant_id'
|
|
707
|
+
AND c.table_name NOT IN ('orders', 'support_cases', 'sales_line_facts')
|
|
708
|
+
ORDER BY c.table_name
|
|
709
|
+
LOOP
|
|
710
|
+
EXECUTE format('ALTER TABLE public.%I ENABLE ROW LEVEL SECURITY', table_name);
|
|
711
|
+
EXECUTE format('ALTER TABLE public.%I FORCE ROW LEVEL SECURITY', table_name);
|
|
712
|
+
EXECUTE format(
|
|
713
|
+
'CREATE POLICY %I ON public.%I FOR SELECT TO retail_manager_reader, retail_writer USING (merchant_id = current_setting(''app.tenant_id'', true))',
|
|
714
|
+
table_name || '_tenant_select',
|
|
715
|
+
table_name
|
|
716
|
+
);
|
|
717
|
+
END LOOP;
|
|
718
|
+
END
|
|
719
|
+
$$;
|
|
720
|
+
|
|
721
|
+
ALTER TABLE public.orders ENABLE ROW LEVEL SECURITY;
|
|
722
|
+
ALTER TABLE public.orders FORCE ROW LEVEL SECURITY;
|
|
723
|
+
CREATE POLICY orders_manager_select
|
|
724
|
+
ON public.orders FOR SELECT TO retail_manager_reader, retail_writer
|
|
725
|
+
USING (
|
|
726
|
+
merchant_id = current_setting('app.tenant_id', true)
|
|
727
|
+
AND assigned_manager_id = current_setting('app.principal', true)
|
|
728
|
+
);
|
|
729
|
+
CREATE POLICY orders_manager_update
|
|
730
|
+
ON public.orders FOR UPDATE TO retail_writer
|
|
731
|
+
USING (
|
|
732
|
+
merchant_id = current_setting('app.tenant_id', true)
|
|
733
|
+
AND assigned_manager_id = current_setting('app.principal', true)
|
|
734
|
+
)
|
|
735
|
+
WITH CHECK (
|
|
736
|
+
merchant_id = current_setting('app.tenant_id', true)
|
|
737
|
+
AND assigned_manager_id = current_setting('app.principal', true)
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
ALTER TABLE public.support_cases ENABLE ROW LEVEL SECURITY;
|
|
741
|
+
ALTER TABLE public.support_cases FORCE ROW LEVEL SECURITY;
|
|
742
|
+
CREATE POLICY support_cases_agent_select
|
|
743
|
+
ON public.support_cases FOR SELECT TO retail_manager_reader, retail_writer
|
|
744
|
+
USING (
|
|
745
|
+
merchant_id = current_setting('app.tenant_id', true)
|
|
746
|
+
AND assigned_agent_id = current_setting('app.principal', true)
|
|
747
|
+
);
|
|
748
|
+
|
|
749
|
+
ALTER TABLE public.sales_line_facts ENABLE ROW LEVEL SECURITY;
|
|
750
|
+
ALTER TABLE public.sales_line_facts FORCE ROW LEVEL SECURITY;
|
|
751
|
+
CREATE POLICY sales_line_facts_manager_select
|
|
752
|
+
ON public.sales_line_facts FOR SELECT TO retail_manager_reader, retail_writer
|
|
753
|
+
USING (
|
|
754
|
+
merchant_id = current_setting('app.tenant_id', true)
|
|
755
|
+
AND assigned_manager_id = current_setting('app.principal', true)
|
|
756
|
+
);
|
|
757
|
+
|
|
758
|
+
CREATE VIEW public.reviewed_order_performance
|
|
759
|
+
WITH (security_barrier = true, security_invoker = true) AS
|
|
760
|
+
SELECT
|
|
761
|
+
orders.id AS order_id,
|
|
762
|
+
orders.merchant_id,
|
|
763
|
+
orders.assigned_manager_id,
|
|
764
|
+
orders.region_id,
|
|
765
|
+
ROUND(
|
|
766
|
+
(orders.net_revenue_cents::numeric / NULLIF(orders.gross_revenue_cents, 0))
|
|
767
|
+
* 10000
|
|
768
|
+
)::integer AS net_revenue_retention_basis_points
|
|
769
|
+
FROM public.orders;
|
|
770
|
+
|
|
771
|
+
GRANT CONNECT ON DATABASE northstar_commerce TO retail_manager_reader, retail_writer, retail_setup;
|
|
772
|
+
GRANT USAGE ON SCHEMA public TO retail_manager_reader, retail_writer, retail_setup;
|
|
773
|
+
GRANT SELECT ON ALL TABLES IN SCHEMA public TO retail_manager_reader, retail_writer;
|
|
774
|
+
GRANT UPDATE (status, version) ON public.orders TO retail_writer;
|
|
775
|
+
GRANT UPDATE (available_quantity, reserved_quantity, version) ON public.inventory_levels TO retail_writer;
|
|
776
|
+
|
|
777
|
+
CREATE TABLE public.synapsor_fixture_ready (
|
|
778
|
+
initialized_at timestamptz NOT NULL
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
INSERT INTO public.synapsor_fixture_ready VALUES (clock_timestamp());
|