@contractspec/lib.runtime-sandbox 0.11.0

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.
Files changed (63) hide show
  1. package/dist/_virtual/rolldown_runtime.js +18 -0
  2. package/dist/adapters/pglite/adapter.js +97 -0
  3. package/dist/adapters/pglite/adapter.js.map +1 -0
  4. package/dist/adapters/pglite/index.js +3 -0
  5. package/dist/index.d.ts +23 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +24 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/ports/database.port.d.ts +70 -0
  10. package/dist/ports/database.port.d.ts.map +1 -0
  11. package/dist/types/database.types.d.ts +47 -0
  12. package/dist/types/database.types.d.ts.map +1 -0
  13. package/dist/web/database/migrations.d.ts +12 -0
  14. package/dist/web/database/migrations.d.ts.map +1 -0
  15. package/dist/web/database/migrations.js +746 -0
  16. package/dist/web/database/migrations.js.map +1 -0
  17. package/dist/web/database/schema.d.ts +7349 -0
  18. package/dist/web/database/schema.d.ts.map +1 -0
  19. package/dist/web/database/schema.js +528 -0
  20. package/dist/web/database/schema.js.map +1 -0
  21. package/dist/web/events/local-pubsub.d.ts +10 -0
  22. package/dist/web/events/local-pubsub.d.ts.map +1 -0
  23. package/dist/web/events/local-pubsub.js +24 -0
  24. package/dist/web/events/local-pubsub.js.map +1 -0
  25. package/dist/web/graphql/local-client.d.ts +20 -0
  26. package/dist/web/graphql/local-client.d.ts.map +1 -0
  27. package/dist/web/graphql/local-client.js +536 -0
  28. package/dist/web/graphql/local-client.js.map +1 -0
  29. package/dist/web/index.d.ts +15 -0
  30. package/dist/web/index.d.ts.map +1 -0
  31. package/dist/web/index.js +68 -0
  32. package/dist/web/index.js.map +1 -0
  33. package/dist/web/runtime/seeders/index.js +358 -0
  34. package/dist/web/runtime/seeders/index.js.map +1 -0
  35. package/dist/web/runtime/services.d.ts +60 -0
  36. package/dist/web/runtime/services.d.ts.map +1 -0
  37. package/dist/web/runtime/services.js +80 -0
  38. package/dist/web/runtime/services.js.map +1 -0
  39. package/dist/web/storage/indexeddb.d.ts +22 -0
  40. package/dist/web/storage/indexeddb.d.ts.map +1 -0
  41. package/dist/web/storage/indexeddb.js +85 -0
  42. package/dist/web/storage/indexeddb.js.map +1 -0
  43. package/dist/web/utils/id.d.ts +5 -0
  44. package/dist/web/utils/id.d.ts.map +1 -0
  45. package/dist/web/utils/id.js +9 -0
  46. package/dist/web/utils/id.js.map +1 -0
  47. package/package.json +70 -0
  48. package/src/adapters/pglite/adapter.ts +152 -0
  49. package/src/adapters/pglite/index.ts +1 -0
  50. package/src/index.ts +41 -0
  51. package/src/ports/database.port.ts +82 -0
  52. package/src/ports/index.ts +4 -0
  53. package/src/types/database.types.ts +55 -0
  54. package/src/types/index.ts +1 -0
  55. package/src/web/database/migrations.ts +760 -0
  56. package/src/web/database/schema.ts +596 -0
  57. package/src/web/events/local-pubsub.ts +28 -0
  58. package/src/web/graphql/local-client.ts +747 -0
  59. package/src/web/index.ts +21 -0
  60. package/src/web/runtime/seeders/index.ts +449 -0
  61. package/src/web/runtime/services.ts +132 -0
  62. package/src/web/storage/indexeddb.ts +116 -0
  63. package/src/web/utils/id.ts +7 -0
@@ -0,0 +1,760 @@
1
+ /**
2
+ * Schema migrations for PGLite sandbox runtime.
3
+ *
4
+ * These migrations create all tables defined in schema.ts.
5
+ * Using raw SQL for migrations to work with DatabasePort interface.
6
+ */
7
+ import type { Migration } from '@contractspec/lib.runtime-sandbox';
8
+
9
+ /**
10
+ * All migrations for the sandbox runtime database.
11
+ * Each migration should be idempotent (CREATE TABLE IF NOT EXISTS).
12
+ */
13
+ export const SANDBOX_MIGRATIONS: Migration[] = [
14
+ // ============ Todos Template ============
15
+ {
16
+ id: '001_template_task_category',
17
+ sql: `
18
+ CREATE TABLE IF NOT EXISTS template_task_category (
19
+ id TEXT PRIMARY KEY,
20
+ "projectId" TEXT NOT NULL,
21
+ name TEXT NOT NULL,
22
+ color TEXT,
23
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
24
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
25
+ );
26
+ `,
27
+ },
28
+ {
29
+ id: '002_template_task',
30
+ sql: `
31
+ CREATE TABLE IF NOT EXISTS template_task (
32
+ id TEXT PRIMARY KEY,
33
+ "projectId" TEXT NOT NULL,
34
+ "categoryId" TEXT,
35
+ title TEXT NOT NULL,
36
+ description TEXT,
37
+ completed INTEGER DEFAULT 0,
38
+ priority TEXT DEFAULT 'MEDIUM',
39
+ "dueDate" TEXT,
40
+ tags TEXT,
41
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
42
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
43
+ );
44
+ `,
45
+ },
46
+ // ============ Messaging Template ============
47
+ {
48
+ id: '003_template_conversation',
49
+ sql: `
50
+ CREATE TABLE IF NOT EXISTS template_conversation (
51
+ id TEXT PRIMARY KEY,
52
+ "projectId" TEXT NOT NULL,
53
+ name TEXT,
54
+ "isGroup" INTEGER DEFAULT 0,
55
+ "avatarUrl" TEXT,
56
+ "lastMessageId" TEXT,
57
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
58
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
59
+ );
60
+ `,
61
+ },
62
+ {
63
+ id: '004_template_conversation_participant',
64
+ sql: `
65
+ CREATE TABLE IF NOT EXISTS template_conversation_participant (
66
+ id TEXT PRIMARY KEY,
67
+ "conversationId" TEXT NOT NULL,
68
+ "projectId" TEXT NOT NULL,
69
+ "userId" TEXT NOT NULL,
70
+ "displayName" TEXT,
71
+ role TEXT,
72
+ "joinedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
73
+ "lastReadAt" TEXT
74
+ );
75
+ `,
76
+ },
77
+ {
78
+ id: '005_template_message',
79
+ sql: `
80
+ CREATE TABLE IF NOT EXISTS template_message (
81
+ id TEXT PRIMARY KEY,
82
+ "conversationId" TEXT NOT NULL,
83
+ "projectId" TEXT NOT NULL,
84
+ "senderId" TEXT NOT NULL,
85
+ "senderName" TEXT,
86
+ content TEXT NOT NULL,
87
+ attachments TEXT,
88
+ status TEXT DEFAULT 'SENT',
89
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
90
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
91
+ );
92
+ `,
93
+ },
94
+ // ============ Recipes Template ============
95
+ {
96
+ id: '006_template_recipe_category',
97
+ sql: `
98
+ CREATE TABLE IF NOT EXISTS template_recipe_category (
99
+ id TEXT PRIMARY KEY,
100
+ "nameEn" TEXT NOT NULL,
101
+ "nameFr" TEXT NOT NULL,
102
+ icon TEXT
103
+ );
104
+ `,
105
+ },
106
+ {
107
+ id: '007_template_recipe',
108
+ sql: `
109
+ CREATE TABLE IF NOT EXISTS template_recipe (
110
+ id TEXT PRIMARY KEY,
111
+ "projectId" TEXT NOT NULL,
112
+ "categoryId" TEXT,
113
+ "slugEn" TEXT NOT NULL,
114
+ "slugFr" TEXT NOT NULL,
115
+ "nameEn" TEXT NOT NULL,
116
+ "nameFr" TEXT NOT NULL,
117
+ "descriptionEn" TEXT,
118
+ "descriptionFr" TEXT,
119
+ "heroImageUrl" TEXT,
120
+ "prepTimeMinutes" INTEGER,
121
+ "cookTimeMinutes" INTEGER,
122
+ servings INTEGER,
123
+ "isFavorite" INTEGER DEFAULT 0,
124
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
125
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
126
+ );
127
+ `,
128
+ },
129
+ {
130
+ id: '008_template_recipe_ingredient',
131
+ sql: `
132
+ CREATE TABLE IF NOT EXISTS template_recipe_ingredient (
133
+ id TEXT PRIMARY KEY,
134
+ "recipeId" TEXT NOT NULL,
135
+ "nameEn" TEXT NOT NULL,
136
+ "nameFr" TEXT NOT NULL,
137
+ quantity TEXT NOT NULL,
138
+ ordering INTEGER DEFAULT 0
139
+ );
140
+ `,
141
+ },
142
+ {
143
+ id: '009_template_recipe_instruction',
144
+ sql: `
145
+ CREATE TABLE IF NOT EXISTS template_recipe_instruction (
146
+ id TEXT PRIMARY KEY,
147
+ "recipeId" TEXT NOT NULL,
148
+ "contentEn" TEXT NOT NULL,
149
+ "contentFr" TEXT NOT NULL,
150
+ ordering INTEGER DEFAULT 0
151
+ );
152
+ `,
153
+ },
154
+ // ============ CRM Template ============
155
+ {
156
+ id: '010_crm_pipeline',
157
+ sql: `
158
+ CREATE TABLE IF NOT EXISTS crm_pipeline (
159
+ id TEXT PRIMARY KEY,
160
+ "projectId" TEXT NOT NULL,
161
+ name TEXT NOT NULL,
162
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
163
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
164
+ );
165
+ `,
166
+ },
167
+ {
168
+ id: '011_crm_stage',
169
+ sql: `
170
+ CREATE TABLE IF NOT EXISTS crm_stage (
171
+ id TEXT PRIMARY KEY,
172
+ "pipelineId" TEXT NOT NULL,
173
+ name TEXT NOT NULL,
174
+ position INTEGER NOT NULL,
175
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
176
+ );
177
+ `,
178
+ },
179
+ {
180
+ id: '012_crm_deal',
181
+ sql: `
182
+ CREATE TABLE IF NOT EXISTS crm_deal (
183
+ id TEXT PRIMARY KEY,
184
+ "projectId" TEXT NOT NULL,
185
+ "pipelineId" TEXT NOT NULL,
186
+ "stageId" TEXT NOT NULL,
187
+ name TEXT NOT NULL,
188
+ value REAL NOT NULL DEFAULT 0,
189
+ currency TEXT DEFAULT 'USD',
190
+ status TEXT DEFAULT 'OPEN',
191
+ "contactId" TEXT,
192
+ "companyId" TEXT,
193
+ "ownerId" TEXT NOT NULL,
194
+ "expectedCloseDate" TEXT,
195
+ "wonSource" TEXT,
196
+ "lostReason" TEXT,
197
+ notes TEXT,
198
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
199
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
200
+ );
201
+ `,
202
+ },
203
+ {
204
+ id: '013_crm_company',
205
+ sql: `
206
+ CREATE TABLE IF NOT EXISTS crm_company (
207
+ id TEXT PRIMARY KEY,
208
+ "projectId" TEXT NOT NULL,
209
+ name TEXT NOT NULL,
210
+ domain TEXT,
211
+ industry TEXT,
212
+ size TEXT,
213
+ website TEXT,
214
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
215
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
216
+ );
217
+ `,
218
+ },
219
+ {
220
+ id: '014_crm_contact',
221
+ sql: `
222
+ CREATE TABLE IF NOT EXISTS crm_contact (
223
+ id TEXT PRIMARY KEY,
224
+ "projectId" TEXT NOT NULL,
225
+ "companyId" TEXT,
226
+ "firstName" TEXT NOT NULL,
227
+ "lastName" TEXT,
228
+ email TEXT,
229
+ phone TEXT,
230
+ title TEXT,
231
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
232
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
233
+ );
234
+ `,
235
+ },
236
+ // ============ SaaS Template ============
237
+ {
238
+ id: '015_saas_project',
239
+ sql: `
240
+ CREATE TABLE IF NOT EXISTS saas_project (
241
+ id TEXT PRIMARY KEY,
242
+ "projectId" TEXT NOT NULL,
243
+ "organizationId" TEXT NOT NULL,
244
+ name TEXT NOT NULL,
245
+ description TEXT,
246
+ status TEXT DEFAULT 'DRAFT',
247
+ tier TEXT DEFAULT 'FREE',
248
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
249
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
250
+ );
251
+ `,
252
+ },
253
+ {
254
+ id: '016_saas_subscription',
255
+ sql: `
256
+ CREATE TABLE IF NOT EXISTS saas_subscription (
257
+ id TEXT PRIMARY KEY,
258
+ "projectId" TEXT NOT NULL,
259
+ "organizationId" TEXT NOT NULL,
260
+ plan TEXT NOT NULL DEFAULT 'FREE',
261
+ status TEXT DEFAULT 'ACTIVE',
262
+ "billingCycle" TEXT DEFAULT 'MONTHLY',
263
+ "currentPeriodStart" TEXT,
264
+ "currentPeriodEnd" TEXT,
265
+ "cancelAtPeriodEnd" INTEGER DEFAULT 0,
266
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
267
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
268
+ );
269
+ `,
270
+ },
271
+ {
272
+ id: '017_saas_usage',
273
+ sql: `
274
+ CREATE TABLE IF NOT EXISTS saas_usage (
275
+ id TEXT PRIMARY KEY,
276
+ "projectId" TEXT NOT NULL,
277
+ "organizationId" TEXT NOT NULL,
278
+ "metricName" TEXT NOT NULL,
279
+ value REAL NOT NULL DEFAULT 0,
280
+ "periodStart" TEXT NOT NULL,
281
+ "periodEnd" TEXT NOT NULL,
282
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
283
+ );
284
+ `,
285
+ },
286
+ // ============ Agent Console Template ============
287
+ {
288
+ id: '018_agent_tool',
289
+ sql: `
290
+ CREATE TABLE IF NOT EXISTS agent_tool (
291
+ id TEXT PRIMARY KEY,
292
+ "projectId" TEXT NOT NULL,
293
+ "organizationId" TEXT NOT NULL,
294
+ name TEXT NOT NULL,
295
+ description TEXT,
296
+ version TEXT DEFAULT '1.0.0',
297
+ category TEXT DEFAULT 'UTILITY',
298
+ status TEXT DEFAULT 'ACTIVE',
299
+ "inputSchema" TEXT,
300
+ "outputSchema" TEXT,
301
+ endpoint TEXT,
302
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
303
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
304
+ );
305
+ `,
306
+ },
307
+ {
308
+ id: '019_agent_definition',
309
+ sql: `
310
+ CREATE TABLE IF NOT EXISTS agent_definition (
311
+ id TEXT PRIMARY KEY,
312
+ "projectId" TEXT NOT NULL,
313
+ "organizationId" TEXT NOT NULL,
314
+ name TEXT NOT NULL,
315
+ description TEXT,
316
+ "modelProvider" TEXT DEFAULT 'openai',
317
+ "modelName" TEXT DEFAULT 'gpt-4',
318
+ "systemPrompt" TEXT,
319
+ temperature REAL DEFAULT 0.7,
320
+ "maxTokens" INTEGER DEFAULT 4096,
321
+ status TEXT DEFAULT 'DRAFT',
322
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
323
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
324
+ );
325
+ `,
326
+ },
327
+ {
328
+ id: '020_agent_tool_assignment',
329
+ sql: `
330
+ CREATE TABLE IF NOT EXISTS agent_tool_assignment (
331
+ id TEXT PRIMARY KEY,
332
+ "agentId" TEXT NOT NULL,
333
+ "toolId" TEXT NOT NULL,
334
+ "assignedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
335
+ );
336
+ `,
337
+ },
338
+ {
339
+ id: '021_agent_run',
340
+ sql: `
341
+ CREATE TABLE IF NOT EXISTS agent_run (
342
+ id TEXT PRIMARY KEY,
343
+ "projectId" TEXT NOT NULL,
344
+ "agentId" TEXT NOT NULL,
345
+ status TEXT DEFAULT 'QUEUED',
346
+ input TEXT,
347
+ output TEXT,
348
+ "totalTokens" INTEGER DEFAULT 0,
349
+ "promptTokens" INTEGER DEFAULT 0,
350
+ "completionTokens" INTEGER DEFAULT 0,
351
+ "estimatedCostUsd" REAL DEFAULT 0,
352
+ "durationMs" INTEGER,
353
+ "errorMessage" TEXT,
354
+ "queuedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
355
+ "startedAt" TEXT,
356
+ "completedAt" TEXT
357
+ );
358
+ `,
359
+ },
360
+ {
361
+ id: '022_agent_run_step',
362
+ sql: `
363
+ CREATE TABLE IF NOT EXISTS agent_run_step (
364
+ id TEXT PRIMARY KEY,
365
+ "runId" TEXT NOT NULL,
366
+ "stepNumber" INTEGER NOT NULL,
367
+ type TEXT NOT NULL,
368
+ "toolId" TEXT,
369
+ "toolInput" TEXT,
370
+ "toolOutput" TEXT,
371
+ reasoning TEXT,
372
+ "tokensUsed" INTEGER DEFAULT 0,
373
+ "durationMs" INTEGER,
374
+ status TEXT DEFAULT 'PENDING',
375
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
376
+ );
377
+ `,
378
+ },
379
+ {
380
+ id: '023_agent_run_log',
381
+ sql: `
382
+ CREATE TABLE IF NOT EXISTS agent_run_log (
383
+ id TEXT PRIMARY KEY,
384
+ "runId" TEXT NOT NULL,
385
+ level TEXT DEFAULT 'INFO',
386
+ message TEXT NOT NULL,
387
+ metadata TEXT,
388
+ timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
389
+ );
390
+ `,
391
+ },
392
+ // ============ Workflow Template ============
393
+ {
394
+ id: '024_workflow_definition',
395
+ sql: `
396
+ CREATE TABLE IF NOT EXISTS workflow_definition (
397
+ id TEXT PRIMARY KEY,
398
+ "projectId" TEXT NOT NULL,
399
+ "organizationId" TEXT NOT NULL,
400
+ name TEXT NOT NULL,
401
+ description TEXT,
402
+ type TEXT DEFAULT 'APPROVAL',
403
+ status TEXT DEFAULT 'DRAFT',
404
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
405
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
406
+ );
407
+ `,
408
+ },
409
+ {
410
+ id: '025_workflow_step',
411
+ sql: `
412
+ CREATE TABLE IF NOT EXISTS workflow_step (
413
+ id TEXT PRIMARY KEY,
414
+ "definitionId" TEXT NOT NULL,
415
+ name TEXT NOT NULL,
416
+ description TEXT,
417
+ "stepOrder" INTEGER NOT NULL,
418
+ type TEXT DEFAULT 'APPROVAL',
419
+ "requiredRoles" TEXT,
420
+ "autoApproveCondition" TEXT,
421
+ "timeoutHours" INTEGER,
422
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
423
+ );
424
+ `,
425
+ },
426
+ {
427
+ id: '026_workflow_instance',
428
+ sql: `
429
+ CREATE TABLE IF NOT EXISTS workflow_instance (
430
+ id TEXT PRIMARY KEY,
431
+ "projectId" TEXT NOT NULL,
432
+ "definitionId" TEXT NOT NULL,
433
+ status TEXT DEFAULT 'PENDING',
434
+ "currentStepId" TEXT,
435
+ data TEXT,
436
+ "requestedBy" TEXT NOT NULL,
437
+ "startedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
438
+ "completedAt" TEXT
439
+ );
440
+ `,
441
+ },
442
+ {
443
+ id: '027_workflow_approval',
444
+ sql: `
445
+ CREATE TABLE IF NOT EXISTS workflow_approval (
446
+ id TEXT PRIMARY KEY,
447
+ "instanceId" TEXT NOT NULL,
448
+ "stepId" TEXT NOT NULL,
449
+ status TEXT DEFAULT 'PENDING',
450
+ "actorId" TEXT,
451
+ comment TEXT,
452
+ "decidedAt" TEXT,
453
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
454
+ );
455
+ `,
456
+ },
457
+ // ============ Marketplace Template ============
458
+ {
459
+ id: '028_marketplace_store',
460
+ sql: `
461
+ CREATE TABLE IF NOT EXISTS marketplace_store (
462
+ id TEXT PRIMARY KEY,
463
+ "projectId" TEXT NOT NULL,
464
+ "organizationId" TEXT NOT NULL,
465
+ name TEXT NOT NULL,
466
+ description TEXT,
467
+ status TEXT DEFAULT 'PENDING',
468
+ rating REAL DEFAULT 0,
469
+ "reviewCount" INTEGER DEFAULT 0,
470
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
471
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
472
+ );
473
+ `,
474
+ },
475
+ {
476
+ id: '029_marketplace_product',
477
+ sql: `
478
+ CREATE TABLE IF NOT EXISTS marketplace_product (
479
+ id TEXT PRIMARY KEY,
480
+ "storeId" TEXT NOT NULL,
481
+ name TEXT NOT NULL,
482
+ description TEXT,
483
+ price REAL NOT NULL DEFAULT 0,
484
+ currency TEXT DEFAULT 'USD',
485
+ status TEXT DEFAULT 'DRAFT',
486
+ stock INTEGER DEFAULT 0,
487
+ category TEXT,
488
+ "imageUrl" TEXT,
489
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
490
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
491
+ );
492
+ `,
493
+ },
494
+ {
495
+ id: '030_marketplace_order',
496
+ sql: `
497
+ CREATE TABLE IF NOT EXISTS marketplace_order (
498
+ id TEXT PRIMARY KEY,
499
+ "projectId" TEXT NOT NULL,
500
+ "storeId" TEXT NOT NULL,
501
+ "customerId" TEXT NOT NULL,
502
+ status TEXT DEFAULT 'PENDING',
503
+ total REAL NOT NULL DEFAULT 0,
504
+ currency TEXT DEFAULT 'USD',
505
+ "shippingAddress" TEXT,
506
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
507
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
508
+ );
509
+ `,
510
+ },
511
+ {
512
+ id: '031_marketplace_order_item',
513
+ sql: `
514
+ CREATE TABLE IF NOT EXISTS marketplace_order_item (
515
+ id TEXT PRIMARY KEY,
516
+ "orderId" TEXT NOT NULL,
517
+ "productId" TEXT NOT NULL,
518
+ quantity INTEGER NOT NULL DEFAULT 1,
519
+ price REAL NOT NULL DEFAULT 0,
520
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
521
+ );
522
+ `,
523
+ },
524
+ {
525
+ id: '032_marketplace_payout',
526
+ sql: `
527
+ CREATE TABLE IF NOT EXISTS marketplace_payout (
528
+ id TEXT PRIMARY KEY,
529
+ "storeId" TEXT NOT NULL,
530
+ amount REAL NOT NULL DEFAULT 0,
531
+ currency TEXT DEFAULT 'USD',
532
+ status TEXT DEFAULT 'PENDING',
533
+ "processedAt" TEXT,
534
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
535
+ );
536
+ `,
537
+ },
538
+ {
539
+ id: '033_marketplace_review',
540
+ sql: `
541
+ CREATE TABLE IF NOT EXISTS marketplace_review (
542
+ id TEXT PRIMARY KEY,
543
+ "productId" TEXT NOT NULL,
544
+ "customerId" TEXT NOT NULL,
545
+ "orderId" TEXT,
546
+ rating INTEGER NOT NULL,
547
+ comment TEXT,
548
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
549
+ );
550
+ `,
551
+ },
552
+ // ============ Integration Hub Template ============
553
+ {
554
+ id: '034_integration',
555
+ sql: `
556
+ CREATE TABLE IF NOT EXISTS integration (
557
+ id TEXT PRIMARY KEY,
558
+ "projectId" TEXT NOT NULL,
559
+ "organizationId" TEXT NOT NULL,
560
+ name TEXT NOT NULL,
561
+ description TEXT,
562
+ type TEXT NOT NULL,
563
+ status TEXT DEFAULT 'INACTIVE',
564
+ "iconUrl" TEXT,
565
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
566
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
567
+ );
568
+ `,
569
+ },
570
+ {
571
+ id: '035_integration_connection',
572
+ sql: `
573
+ CREATE TABLE IF NOT EXISTS integration_connection (
574
+ id TEXT PRIMARY KEY,
575
+ "integrationId" TEXT NOT NULL,
576
+ name TEXT NOT NULL,
577
+ status TEXT DEFAULT 'DISCONNECTED',
578
+ credentials TEXT,
579
+ config TEXT,
580
+ "lastSyncAt" TEXT,
581
+ "errorMessage" TEXT,
582
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
583
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
584
+ );
585
+ `,
586
+ },
587
+ {
588
+ id: '036_integration_sync_config',
589
+ sql: `
590
+ CREATE TABLE IF NOT EXISTS integration_sync_config (
591
+ id TEXT PRIMARY KEY,
592
+ "connectionId" TEXT NOT NULL,
593
+ name TEXT NOT NULL,
594
+ "sourceEntity" TEXT NOT NULL,
595
+ "targetEntity" TEXT NOT NULL,
596
+ frequency TEXT DEFAULT 'DAILY',
597
+ status TEXT DEFAULT 'ACTIVE',
598
+ "lastRunAt" TEXT,
599
+ "lastRunStatus" TEXT,
600
+ "recordsSynced" INTEGER DEFAULT 0,
601
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
602
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
603
+ );
604
+ `,
605
+ },
606
+ {
607
+ id: '037_integration_field_mapping',
608
+ sql: `
609
+ CREATE TABLE IF NOT EXISTS integration_field_mapping (
610
+ id TEXT PRIMARY KEY,
611
+ "syncConfigId" TEXT NOT NULL,
612
+ "sourceField" TEXT NOT NULL,
613
+ "targetField" TEXT NOT NULL,
614
+ "transformType" TEXT,
615
+ "transformConfig" TEXT,
616
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
617
+ );
618
+ `,
619
+ },
620
+ // ============ Analytics Dashboard Template ============
621
+ {
622
+ id: '038_analytics_dashboard',
623
+ sql: `
624
+ CREATE TABLE IF NOT EXISTS analytics_dashboard (
625
+ id TEXT PRIMARY KEY,
626
+ "projectId" TEXT NOT NULL,
627
+ "organizationId" TEXT NOT NULL,
628
+ name TEXT NOT NULL,
629
+ slug TEXT NOT NULL,
630
+ description TEXT,
631
+ status TEXT DEFAULT 'DRAFT',
632
+ "refreshInterval" TEXT DEFAULT 'NONE',
633
+ "isPublic" INTEGER DEFAULT 0,
634
+ "shareToken" TEXT,
635
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
636
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
637
+ );
638
+ `,
639
+ },
640
+ {
641
+ id: '039_analytics_widget',
642
+ sql: `
643
+ CREATE TABLE IF NOT EXISTS analytics_widget (
644
+ id TEXT PRIMARY KEY,
645
+ "dashboardId" TEXT NOT NULL,
646
+ name TEXT NOT NULL,
647
+ type TEXT NOT NULL,
648
+ "gridX" INTEGER DEFAULT 0,
649
+ "gridY" INTEGER DEFAULT 0,
650
+ "gridWidth" INTEGER DEFAULT 6,
651
+ "gridHeight" INTEGER DEFAULT 4,
652
+ "queryId" TEXT,
653
+ config TEXT,
654
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
655
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
656
+ );
657
+ `,
658
+ },
659
+ {
660
+ id: '040_analytics_query',
661
+ sql: `
662
+ CREATE TABLE IF NOT EXISTS analytics_query (
663
+ id TEXT PRIMARY KEY,
664
+ "projectId" TEXT NOT NULL,
665
+ "organizationId" TEXT NOT NULL,
666
+ name TEXT NOT NULL,
667
+ description TEXT,
668
+ type TEXT NOT NULL,
669
+ definition TEXT NOT NULL,
670
+ sql TEXT,
671
+ "cacheTtlSeconds" INTEGER DEFAULT 300,
672
+ "isShared" INTEGER DEFAULT 0,
673
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
674
+ "updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
675
+ );
676
+ `,
677
+ },
678
+ // ============ Policy-Safe Knowledge Assistant Template ============
679
+ {
680
+ id: '041_psa_user_context',
681
+ sql: `
682
+ CREATE TABLE IF NOT EXISTS psa_user_context (
683
+ "projectId" TEXT PRIMARY KEY,
684
+ locale TEXT NOT NULL,
685
+ jurisdiction TEXT NOT NULL,
686
+ "allowedScope" TEXT NOT NULL,
687
+ "kbSnapshotId" TEXT
688
+ );
689
+ `,
690
+ },
691
+ {
692
+ id: '042_psa_rule',
693
+ sql: `
694
+ CREATE TABLE IF NOT EXISTS psa_rule (
695
+ id TEXT PRIMARY KEY,
696
+ "projectId" TEXT NOT NULL,
697
+ jurisdiction TEXT NOT NULL,
698
+ "topicKey" TEXT NOT NULL
699
+ );
700
+ `,
701
+ },
702
+ {
703
+ id: '043_psa_rule_version',
704
+ sql: `
705
+ CREATE TABLE IF NOT EXISTS psa_rule_version (
706
+ id TEXT PRIMARY KEY,
707
+ "ruleId" TEXT NOT NULL,
708
+ jurisdiction TEXT NOT NULL,
709
+ "topicKey" TEXT NOT NULL,
710
+ version INTEGER NOT NULL,
711
+ content TEXT NOT NULL,
712
+ status TEXT NOT NULL,
713
+ "sourceRefsJson" TEXT NOT NULL,
714
+ "approvedBy" TEXT,
715
+ "approvedAt" TEXT,
716
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
717
+ );
718
+ `,
719
+ },
720
+ {
721
+ id: '044_psa_snapshot',
722
+ sql: `
723
+ CREATE TABLE IF NOT EXISTS psa_snapshot (
724
+ id TEXT PRIMARY KEY,
725
+ jurisdiction TEXT NOT NULL,
726
+ "asOfDate" TEXT NOT NULL,
727
+ "includedRuleVersionIdsJson" TEXT NOT NULL,
728
+ "publishedAt" TEXT NOT NULL
729
+ );
730
+ `,
731
+ },
732
+ {
733
+ id: '045_psa_change_candidate',
734
+ sql: `
735
+ CREATE TABLE IF NOT EXISTS psa_change_candidate (
736
+ id TEXT PRIMARY KEY,
737
+ "projectId" TEXT NOT NULL,
738
+ jurisdiction TEXT NOT NULL,
739
+ "detectedAt" TEXT NOT NULL,
740
+ "diffSummary" TEXT NOT NULL,
741
+ "riskLevel" TEXT NOT NULL,
742
+ "proposedRuleVersionIdsJson" TEXT NOT NULL
743
+ );
744
+ `,
745
+ },
746
+ {
747
+ id: '046_psa_review_task',
748
+ sql: `
749
+ CREATE TABLE IF NOT EXISTS psa_review_task (
750
+ id TEXT PRIMARY KEY,
751
+ "changeCandidateId" TEXT NOT NULL,
752
+ status TEXT NOT NULL,
753
+ "assignedRole" TEXT NOT NULL,
754
+ decision TEXT,
755
+ "decidedAt" TEXT,
756
+ "decidedBy" TEXT
757
+ );
758
+ `,
759
+ },
760
+ ];