stagent 0.6.2 → 0.7.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 (176) hide show
  1. package/README.md +21 -2
  2. package/dist/cli.js +272 -1
  3. package/docs/.coverage-gaps.json +66 -16
  4. package/docs/.last-generated +1 -1
  5. package/docs/features/dashboard-kanban.md +13 -7
  6. package/docs/features/settings.md +15 -3
  7. package/docs/features/tables.md +122 -0
  8. package/docs/index.md +3 -2
  9. package/docs/journeys/developer.md +26 -16
  10. package/docs/journeys/personal-use.md +23 -9
  11. package/docs/journeys/power-user.md +40 -14
  12. package/docs/journeys/work-use.md +43 -15
  13. package/docs/manifest.json +27 -17
  14. package/package.json +3 -2
  15. package/src/app/api/chat/entities/search/route.ts +12 -3
  16. package/src/app/api/documents/[id]/route.ts +5 -1
  17. package/src/app/api/documents/[id]/versions/route.ts +53 -0
  18. package/src/app/api/documents/route.ts +5 -1
  19. package/src/app/api/projects/[id]/documents/route.ts +124 -0
  20. package/src/app/api/projects/[id]/route.ts +72 -3
  21. package/src/app/api/projects/__tests__/delete-project.test.ts +13 -0
  22. package/src/app/api/schedules/route.ts +19 -1
  23. package/src/app/api/snapshots/[id]/restore/route.ts +62 -0
  24. package/src/app/api/snapshots/[id]/route.ts +44 -0
  25. package/src/app/api/snapshots/route.ts +54 -0
  26. package/src/app/api/snapshots/settings/route.ts +67 -0
  27. package/src/app/api/tables/[id]/charts/[chartId]/route.ts +89 -0
  28. package/src/app/api/tables/[id]/charts/route.ts +72 -0
  29. package/src/app/api/tables/[id]/columns/route.ts +70 -0
  30. package/src/app/api/tables/[id]/export/route.ts +94 -0
  31. package/src/app/api/tables/[id]/history/route.ts +15 -0
  32. package/src/app/api/tables/[id]/import/route.ts +111 -0
  33. package/src/app/api/tables/[id]/route.ts +86 -0
  34. package/src/app/api/tables/[id]/rows/[rowId]/history/route.ts +32 -0
  35. package/src/app/api/tables/[id]/rows/[rowId]/route.ts +51 -0
  36. package/src/app/api/tables/[id]/rows/route.ts +101 -0
  37. package/src/app/api/tables/[id]/triggers/[triggerId]/route.ts +65 -0
  38. package/src/app/api/tables/[id]/triggers/route.ts +122 -0
  39. package/src/app/api/tables/route.ts +65 -0
  40. package/src/app/api/tables/templates/route.ts +92 -0
  41. package/src/app/api/tasks/[id]/route.ts +37 -2
  42. package/src/app/api/tasks/[id]/siblings/route.ts +48 -0
  43. package/src/app/api/tasks/route.ts +8 -9
  44. package/src/app/api/workflows/[id]/documents/route.ts +209 -0
  45. package/src/app/api/workflows/[id]/execute/route.ts +6 -2
  46. package/src/app/api/workflows/[id]/route.ts +16 -3
  47. package/src/app/api/workflows/[id]/status/route.ts +18 -2
  48. package/src/app/api/workflows/route.ts +13 -2
  49. package/src/app/documents/page.tsx +5 -1
  50. package/src/app/layout.tsx +0 -1
  51. package/src/app/manifest.ts +3 -3
  52. package/src/app/projects/[id]/page.tsx +62 -2
  53. package/src/app/settings/page.tsx +2 -0
  54. package/src/app/tables/[id]/page.tsx +67 -0
  55. package/src/app/tables/page.tsx +21 -0
  56. package/src/app/tables/templates/page.tsx +19 -0
  57. package/src/components/chat/chat-table-result.tsx +139 -0
  58. package/src/components/documents/document-browser.tsx +1 -1
  59. package/src/components/documents/document-chip-bar.tsx +17 -1
  60. package/src/components/documents/document-detail-view.tsx +51 -0
  61. package/src/components/documents/document-grid.tsx +5 -0
  62. package/src/components/documents/document-table.tsx +4 -0
  63. package/src/components/documents/types.ts +3 -0
  64. package/src/components/projects/project-form-sheet.tsx +109 -2
  65. package/src/components/schedules/schedule-form.tsx +91 -1
  66. package/src/components/settings/data-management-section.tsx +17 -12
  67. package/src/components/settings/database-snapshots-section.tsx +469 -0
  68. package/src/components/shared/app-sidebar.tsx +2 -0
  69. package/src/components/shared/document-picker-sheet.tsx +486 -0
  70. package/src/components/tables/table-browser.tsx +234 -0
  71. package/src/components/tables/table-cell-editor.tsx +226 -0
  72. package/src/components/tables/table-chart-builder.tsx +288 -0
  73. package/src/components/tables/table-chart-view.tsx +146 -0
  74. package/src/components/tables/table-column-header.tsx +103 -0
  75. package/src/components/tables/table-column-sheet.tsx +331 -0
  76. package/src/components/tables/table-create-sheet.tsx +240 -0
  77. package/src/components/tables/table-detail-sheet.tsx +144 -0
  78. package/src/components/tables/table-detail-tabs.tsx +278 -0
  79. package/src/components/tables/table-grid.tsx +61 -0
  80. package/src/components/tables/table-history-tab.tsx +148 -0
  81. package/src/components/tables/table-import-wizard.tsx +542 -0
  82. package/src/components/tables/table-list-table.tsx +95 -0
  83. package/src/components/tables/table-relation-combobox.tsx +217 -0
  84. package/src/components/tables/table-spreadsheet.tsx +499 -0
  85. package/src/components/tables/table-template-gallery.tsx +162 -0
  86. package/src/components/tables/table-template-preview.tsx +219 -0
  87. package/src/components/tables/table-toolbar.tsx +79 -0
  88. package/src/components/tables/table-triggers-tab.tsx +446 -0
  89. package/src/components/tables/types.ts +6 -0
  90. package/src/components/tables/use-spreadsheet-keys.ts +171 -0
  91. package/src/components/tables/utils.ts +29 -0
  92. package/src/components/tasks/task-card.tsx +8 -1
  93. package/src/components/tasks/task-create-panel.tsx +111 -14
  94. package/src/components/tasks/task-detail-view.tsx +47 -0
  95. package/src/components/tasks/task-edit-dialog.tsx +103 -2
  96. package/src/components/workflows/workflow-form-view.tsx +207 -7
  97. package/src/components/workflows/workflow-kanban-card.tsx +8 -1
  98. package/src/components/workflows/workflow-list.tsx +90 -45
  99. package/src/components/workflows/workflow-status-view.tsx +168 -23
  100. package/src/instrumentation.ts +3 -0
  101. package/src/lib/__tests__/npx-process-cwd.test.ts +17 -2
  102. package/src/lib/agents/__tests__/claude-agent.test.ts +5 -1
  103. package/src/lib/agents/claude-agent.ts +3 -1
  104. package/src/lib/agents/profiles/registry.ts +6 -3
  105. package/src/lib/agents/runtime/anthropic-direct.ts +29 -0
  106. package/src/lib/agents/runtime/openai-direct.ts +29 -0
  107. package/src/lib/book/__tests__/chapter-slugs.test.ts +80 -0
  108. package/src/lib/book/chapter-generator.ts +4 -19
  109. package/src/lib/book/chapter-mapping.ts +17 -0
  110. package/src/lib/book/content.ts +5 -16
  111. package/src/lib/book/update-detector.ts +3 -16
  112. package/src/lib/chat/engine.ts +1 -0
  113. package/src/lib/chat/stagent-tools.ts +2 -0
  114. package/src/lib/chat/system-prompt.ts +9 -1
  115. package/src/lib/chat/tool-catalog.ts +35 -0
  116. package/src/lib/chat/tools/settings-tools.ts +109 -0
  117. package/src/lib/chat/tools/table-tools.ts +955 -0
  118. package/src/lib/chat/tools/workflow-tools.ts +145 -2
  119. package/src/lib/constants/table-status.ts +68 -0
  120. package/src/lib/data/__tests__/clear.test.ts +1 -1
  121. package/src/lib/data/clear.ts +57 -0
  122. package/src/lib/data/seed-data/__tests__/profiles.test.ts +28 -23
  123. package/src/lib/data/seed-data/conversations.ts +350 -42
  124. package/src/lib/data/seed-data/documents.ts +564 -591
  125. package/src/lib/data/seed-data/learned-context.ts +101 -22
  126. package/src/lib/data/seed-data/notifications.ts +344 -70
  127. package/src/lib/data/seed-data/profile-test-results.ts +92 -11
  128. package/src/lib/data/seed-data/profiles.ts +144 -46
  129. package/src/lib/data/seed-data/projects.ts +50 -18
  130. package/src/lib/data/seed-data/repo-imports.ts +28 -13
  131. package/src/lib/data/seed-data/schedules.ts +208 -41
  132. package/src/lib/data/seed-data/table-templates.ts +234 -0
  133. package/src/lib/data/seed-data/tasks.ts +614 -116
  134. package/src/lib/data/seed-data/usage-ledger.ts +182 -103
  135. package/src/lib/data/seed-data/user-tables.ts +203 -0
  136. package/src/lib/data/seed-data/views.ts +52 -7
  137. package/src/lib/data/seed-data/workflows.ts +231 -84
  138. package/src/lib/data/seed.ts +55 -14
  139. package/src/lib/data/tables.ts +417 -0
  140. package/src/lib/db/bootstrap.ts +275 -0
  141. package/src/lib/db/index.ts +9 -0
  142. package/src/lib/db/migrations/0016_add_workflow_document_inputs.sql +13 -0
  143. package/src/lib/db/migrations/0017_add_document_picker_tables.sql +25 -0
  144. package/src/lib/db/migrations/0018_add_workflow_run_number.sql +2 -0
  145. package/src/lib/db/migrations/0019_add_tables_feature.sql +160 -0
  146. package/src/lib/db/migrations/0020_add_table_triggers.sql +19 -0
  147. package/src/lib/db/migrations/0021_add_row_history.sql +15 -0
  148. package/src/lib/db/schema.ts +445 -0
  149. package/src/lib/docs/reader.ts +2 -3
  150. package/src/lib/documents/context-builder.ts +75 -2
  151. package/src/lib/documents/document-resolver.ts +119 -0
  152. package/src/lib/documents/processors/spreadsheet.ts +2 -1
  153. package/src/lib/schedules/scheduler.ts +31 -1
  154. package/src/lib/snapshots/auto-backup.ts +132 -0
  155. package/src/lib/snapshots/retention.ts +64 -0
  156. package/src/lib/snapshots/snapshot-manager.ts +429 -0
  157. package/src/lib/tables/computed.ts +61 -0
  158. package/src/lib/tables/context-builder.ts +139 -0
  159. package/src/lib/tables/formula-engine.ts +415 -0
  160. package/src/lib/tables/history.ts +115 -0
  161. package/src/lib/tables/import.ts +343 -0
  162. package/src/lib/tables/query-builder.ts +152 -0
  163. package/src/lib/tables/trigger-evaluator.ts +146 -0
  164. package/src/lib/tables/types.ts +141 -0
  165. package/src/lib/tables/validation.ts +119 -0
  166. package/src/lib/utils/app-root.ts +20 -0
  167. package/src/lib/utils/stagent-paths.ts +20 -0
  168. package/src/lib/validators/__tests__/task.test.ts +43 -10
  169. package/src/lib/validators/task.ts +7 -1
  170. package/src/lib/workflows/blueprints/registry.ts +3 -3
  171. package/src/lib/workflows/engine.ts +24 -8
  172. package/src/lib/workflows/types.ts +14 -0
  173. package/tsconfig.json +3 -1
  174. package/public/icon.svg +0 -13
  175. package/src/components/tasks/file-upload.tsx +0 -120
  176. /package/docs/features/{playbook.md → user-guide.md} +0 -0
@@ -28,6 +28,23 @@ const STAGENT_TABLES = [
28
28
  "channel_configs",
29
29
  "channel_bindings",
30
30
  "agent_messages",
31
+ "workflow_document_inputs",
32
+ "schedule_document_inputs",
33
+ "project_document_defaults",
34
+ "user_tables",
35
+ "user_table_columns",
36
+ "user_table_rows",
37
+ "user_table_views",
38
+ "user_table_relationships",
39
+ "user_table_templates",
40
+ "user_table_imports",
41
+ "table_document_inputs",
42
+ "task_table_inputs",
43
+ "workflow_table_inputs",
44
+ "schedule_table_inputs",
45
+ "user_table_triggers",
46
+ "user_table_row_history",
47
+ "snapshots",
31
48
  ] as const;
32
49
 
33
50
  export function bootstrapStagentDatabase(sqlite: Database.Database): void {
@@ -55,6 +72,7 @@ export function bootstrapStagentDatabase(sqlite: Database.Database): void {
55
72
  result TEXT,
56
73
  session_id TEXT,
57
74
  resume_count INTEGER DEFAULT 0 NOT NULL,
75
+ workflow_run_number INTEGER,
58
76
  created_at INTEGER NOT NULL,
59
77
  updated_at INTEGER NOT NULL,
60
78
  FOREIGN KEY (project_id) REFERENCES projects(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
@@ -68,6 +86,7 @@ export function bootstrapStagentDatabase(sqlite: Database.Database): void {
68
86
  name TEXT NOT NULL,
69
87
  definition TEXT NOT NULL,
70
88
  status TEXT DEFAULT 'draft' NOT NULL,
89
+ run_number INTEGER DEFAULT 0 NOT NULL,
71
90
  created_at INTEGER NOT NULL,
72
91
  updated_at INTEGER NOT NULL,
73
92
  FOREIGN KEY (project_id) REFERENCES projects(id) ON UPDATE NO ACTION ON DELETE NO ACTION
@@ -272,6 +291,8 @@ export function bootstrapStagentDatabase(sqlite: Database.Database): void {
272
291
 
273
292
  // Task source type
274
293
  addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN source_type TEXT;`);
294
+ addColumnIfMissing(`ALTER TABLE workflows ADD COLUMN run_number INTEGER DEFAULT 0 NOT NULL;`);
295
+ addColumnIfMissing(`ALTER TABLE tasks ADD COLUMN workflow_run_number INTEGER;`);
275
296
  addColumnIfMissing(`ALTER TABLE documents ADD COLUMN version INTEGER NOT NULL DEFAULT 1;`);
276
297
  addColumnIfMissing(`ALTER TABLE documents ADD COLUMN source TEXT DEFAULT 'upload';`);
277
298
  addColumnIfMissing(`ALTER TABLE documents ADD COLUMN conversation_id TEXT REFERENCES conversations(id);`);
@@ -566,6 +587,260 @@ export function bootstrapStagentDatabase(sqlite: Database.Database): void {
566
587
  CREATE INDEX IF NOT EXISTS idx_agent_messages_to_status ON agent_messages(to_profile_id, status);
567
588
  CREATE INDEX IF NOT EXISTS idx_agent_messages_task ON agent_messages(task_id);
568
589
  `);
590
+
591
+ // ── Workflow Document Pool ──────────────────────────────────────────
592
+ sqlite.exec(`
593
+ CREATE TABLE IF NOT EXISTS workflow_document_inputs (
594
+ id TEXT PRIMARY KEY NOT NULL,
595
+ workflow_id TEXT NOT NULL,
596
+ document_id TEXT NOT NULL,
597
+ step_id TEXT,
598
+ created_at INTEGER NOT NULL,
599
+ FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
600
+ FOREIGN KEY (document_id) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE NO ACTION
601
+ );
602
+
603
+ CREATE INDEX IF NOT EXISTS idx_wdi_workflow ON workflow_document_inputs(workflow_id);
604
+ CREATE INDEX IF NOT EXISTS idx_wdi_document ON workflow_document_inputs(document_id);
605
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_wdi_workflow_doc_step ON workflow_document_inputs(workflow_id, document_id, step_id);
606
+
607
+ CREATE TABLE IF NOT EXISTS schedule_document_inputs (
608
+ id TEXT PRIMARY KEY NOT NULL,
609
+ schedule_id TEXT NOT NULL,
610
+ document_id TEXT NOT NULL,
611
+ created_at INTEGER NOT NULL,
612
+ FOREIGN KEY (schedule_id) REFERENCES schedules(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
613
+ FOREIGN KEY (document_id) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE NO ACTION
614
+ );
615
+
616
+ CREATE INDEX IF NOT EXISTS idx_sdi_schedule ON schedule_document_inputs(schedule_id);
617
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_sdi_schedule_doc ON schedule_document_inputs(schedule_id, document_id);
618
+
619
+ CREATE TABLE IF NOT EXISTS project_document_defaults (
620
+ id TEXT PRIMARY KEY NOT NULL,
621
+ project_id TEXT NOT NULL,
622
+ document_id TEXT NOT NULL,
623
+ created_at INTEGER NOT NULL,
624
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
625
+ FOREIGN KEY (document_id) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE NO ACTION
626
+ );
627
+
628
+ CREATE INDEX IF NOT EXISTS idx_pdd_project ON project_document_defaults(project_id);
629
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_pdd_project_doc ON project_document_defaults(project_id, document_id);
630
+ `);
631
+
632
+ // ── User-Defined Tables (structured data) ──────────────────────────────
633
+ sqlite.exec(`
634
+ CREATE TABLE IF NOT EXISTS user_tables (
635
+ id TEXT PRIMARY KEY NOT NULL,
636
+ project_id TEXT,
637
+ name TEXT NOT NULL,
638
+ description TEXT,
639
+ column_schema TEXT NOT NULL DEFAULT '[]',
640
+ row_count INTEGER DEFAULT 0 NOT NULL,
641
+ source TEXT DEFAULT 'manual' NOT NULL,
642
+ template_id TEXT,
643
+ created_at INTEGER NOT NULL,
644
+ updated_at INTEGER NOT NULL,
645
+ FOREIGN KEY (project_id) REFERENCES projects(id) ON UPDATE NO ACTION ON DELETE NO ACTION
646
+ );
647
+
648
+ CREATE INDEX IF NOT EXISTS idx_user_tables_project_id ON user_tables(project_id);
649
+ CREATE INDEX IF NOT EXISTS idx_user_tables_source ON user_tables(source);
650
+
651
+ CREATE TABLE IF NOT EXISTS user_table_columns (
652
+ id TEXT PRIMARY KEY NOT NULL,
653
+ table_id TEXT NOT NULL,
654
+ name TEXT NOT NULL,
655
+ display_name TEXT NOT NULL,
656
+ data_type TEXT NOT NULL,
657
+ position INTEGER NOT NULL,
658
+ required INTEGER DEFAULT 0 NOT NULL,
659
+ default_value TEXT,
660
+ config TEXT,
661
+ created_at INTEGER NOT NULL,
662
+ updated_at INTEGER NOT NULL,
663
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
664
+ );
665
+
666
+ CREATE INDEX IF NOT EXISTS idx_user_table_columns_table_id ON user_table_columns(table_id);
667
+ CREATE INDEX IF NOT EXISTS idx_user_table_columns_position ON user_table_columns(table_id, position);
668
+
669
+ CREATE TABLE IF NOT EXISTS user_table_rows (
670
+ id TEXT PRIMARY KEY NOT NULL,
671
+ table_id TEXT NOT NULL,
672
+ data TEXT NOT NULL DEFAULT '{}',
673
+ position INTEGER NOT NULL,
674
+ created_by TEXT DEFAULT 'user',
675
+ created_at INTEGER NOT NULL,
676
+ updated_at INTEGER NOT NULL,
677
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
678
+ );
679
+
680
+ CREATE INDEX IF NOT EXISTS idx_user_table_rows_table_id ON user_table_rows(table_id);
681
+ CREATE INDEX IF NOT EXISTS idx_user_table_rows_position ON user_table_rows(table_id, position);
682
+
683
+ CREATE TABLE IF NOT EXISTS user_table_views (
684
+ id TEXT PRIMARY KEY NOT NULL,
685
+ table_id TEXT NOT NULL,
686
+ name TEXT NOT NULL,
687
+ type TEXT DEFAULT 'grid' NOT NULL,
688
+ config TEXT,
689
+ is_default INTEGER DEFAULT 0 NOT NULL,
690
+ created_at INTEGER NOT NULL,
691
+ updated_at INTEGER NOT NULL,
692
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
693
+ );
694
+
695
+ CREATE INDEX IF NOT EXISTS idx_user_table_views_table_id ON user_table_views(table_id);
696
+
697
+ CREATE TABLE IF NOT EXISTS user_table_relationships (
698
+ id TEXT PRIMARY KEY NOT NULL,
699
+ from_table_id TEXT NOT NULL,
700
+ from_column TEXT NOT NULL,
701
+ to_table_id TEXT NOT NULL,
702
+ to_column TEXT NOT NULL,
703
+ relationship_type TEXT NOT NULL,
704
+ config TEXT,
705
+ created_at INTEGER NOT NULL,
706
+ FOREIGN KEY (from_table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
707
+ FOREIGN KEY (to_table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
708
+ );
709
+
710
+ CREATE INDEX IF NOT EXISTS idx_user_table_rels_from ON user_table_relationships(from_table_id);
711
+ CREATE INDEX IF NOT EXISTS idx_user_table_rels_to ON user_table_relationships(to_table_id);
712
+
713
+ CREATE TABLE IF NOT EXISTS user_table_templates (
714
+ id TEXT PRIMARY KEY NOT NULL,
715
+ name TEXT NOT NULL,
716
+ description TEXT,
717
+ category TEXT NOT NULL,
718
+ column_schema TEXT NOT NULL,
719
+ sample_data TEXT,
720
+ scope TEXT DEFAULT 'system' NOT NULL,
721
+ icon TEXT,
722
+ created_at INTEGER NOT NULL,
723
+ updated_at INTEGER NOT NULL
724
+ );
725
+
726
+ CREATE INDEX IF NOT EXISTS idx_user_table_templates_category ON user_table_templates(category);
727
+ CREATE INDEX IF NOT EXISTS idx_user_table_templates_scope ON user_table_templates(scope);
728
+
729
+ CREATE TABLE IF NOT EXISTS user_table_imports (
730
+ id TEXT PRIMARY KEY NOT NULL,
731
+ table_id TEXT NOT NULL,
732
+ document_id TEXT,
733
+ row_count INTEGER DEFAULT 0 NOT NULL,
734
+ error_count INTEGER DEFAULT 0 NOT NULL,
735
+ errors TEXT,
736
+ status TEXT DEFAULT 'pending' NOT NULL,
737
+ created_at INTEGER NOT NULL,
738
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
739
+ FOREIGN KEY (document_id) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE NO ACTION
740
+ );
741
+
742
+ CREATE INDEX IF NOT EXISTS idx_user_table_imports_table_id ON user_table_imports(table_id);
743
+
744
+ CREATE TABLE IF NOT EXISTS table_document_inputs (
745
+ id TEXT PRIMARY KEY NOT NULL,
746
+ table_id TEXT NOT NULL,
747
+ document_id TEXT NOT NULL,
748
+ created_at INTEGER NOT NULL,
749
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
750
+ FOREIGN KEY (document_id) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE NO ACTION
751
+ );
752
+
753
+ CREATE INDEX IF NOT EXISTS idx_tdi_table ON table_document_inputs(table_id);
754
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tdi_table_doc ON table_document_inputs(table_id, document_id);
755
+
756
+ CREATE TABLE IF NOT EXISTS task_table_inputs (
757
+ id TEXT PRIMARY KEY NOT NULL,
758
+ task_id TEXT NOT NULL,
759
+ table_id TEXT NOT NULL,
760
+ created_at INTEGER NOT NULL,
761
+ FOREIGN KEY (task_id) REFERENCES tasks(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
762
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
763
+ );
764
+
765
+ CREATE INDEX IF NOT EXISTS idx_tti_task ON task_table_inputs(task_id);
766
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tti_task_table ON task_table_inputs(task_id, table_id);
767
+
768
+ CREATE TABLE IF NOT EXISTS workflow_table_inputs (
769
+ id TEXT PRIMARY KEY NOT NULL,
770
+ workflow_id TEXT NOT NULL,
771
+ table_id TEXT NOT NULL,
772
+ step_id TEXT,
773
+ created_at INTEGER NOT NULL,
774
+ FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
775
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
776
+ );
777
+
778
+ CREATE INDEX IF NOT EXISTS idx_wti_workflow ON workflow_table_inputs(workflow_id);
779
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_wti_workflow_table_step ON workflow_table_inputs(workflow_id, table_id, step_id);
780
+
781
+ CREATE TABLE IF NOT EXISTS schedule_table_inputs (
782
+ id TEXT PRIMARY KEY NOT NULL,
783
+ schedule_id TEXT NOT NULL,
784
+ table_id TEXT NOT NULL,
785
+ created_at INTEGER NOT NULL,
786
+ FOREIGN KEY (schedule_id) REFERENCES schedules(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
787
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
788
+ );
789
+
790
+ CREATE INDEX IF NOT EXISTS idx_sti_schedule ON schedule_table_inputs(schedule_id);
791
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_sti_schedule_table ON schedule_table_inputs(schedule_id, table_id);
792
+
793
+ CREATE TABLE IF NOT EXISTS user_table_triggers (
794
+ id TEXT PRIMARY KEY NOT NULL,
795
+ table_id TEXT NOT NULL,
796
+ name TEXT NOT NULL,
797
+ trigger_event TEXT NOT NULL,
798
+ condition TEXT,
799
+ action_type TEXT NOT NULL,
800
+ action_config TEXT NOT NULL,
801
+ status TEXT DEFAULT 'active' NOT NULL,
802
+ fire_count INTEGER DEFAULT 0 NOT NULL,
803
+ last_fired_at INTEGER,
804
+ created_at INTEGER NOT NULL,
805
+ updated_at INTEGER NOT NULL,
806
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
807
+ );
808
+
809
+ CREATE INDEX IF NOT EXISTS idx_user_table_triggers_table_id ON user_table_triggers(table_id);
810
+ CREATE INDEX IF NOT EXISTS idx_user_table_triggers_status ON user_table_triggers(status);
811
+
812
+ CREATE TABLE IF NOT EXISTS user_table_row_history (
813
+ id TEXT PRIMARY KEY NOT NULL,
814
+ row_id TEXT NOT NULL,
815
+ table_id TEXT NOT NULL,
816
+ previous_data TEXT NOT NULL,
817
+ changed_by TEXT DEFAULT 'user',
818
+ change_type TEXT NOT NULL,
819
+ created_at INTEGER NOT NULL,
820
+ FOREIGN KEY (table_id) REFERENCES user_tables(id) ON UPDATE NO ACTION ON DELETE NO ACTION
821
+ );
822
+
823
+ CREATE INDEX IF NOT EXISTS idx_row_history_row_id ON user_table_row_history(row_id);
824
+ CREATE INDEX IF NOT EXISTS idx_row_history_table_id ON user_table_row_history(table_id);
825
+ CREATE INDEX IF NOT EXISTS idx_row_history_created_at ON user_table_row_history(created_at);
826
+
827
+ CREATE TABLE IF NOT EXISTS snapshots (
828
+ id TEXT PRIMARY KEY NOT NULL,
829
+ label TEXT NOT NULL,
830
+ type TEXT DEFAULT 'manual' NOT NULL,
831
+ status TEXT DEFAULT 'in_progress' NOT NULL,
832
+ file_path TEXT NOT NULL,
833
+ size_bytes INTEGER DEFAULT 0 NOT NULL,
834
+ db_size_bytes INTEGER DEFAULT 0 NOT NULL,
835
+ files_size_bytes INTEGER DEFAULT 0 NOT NULL,
836
+ file_count INTEGER DEFAULT 0 NOT NULL,
837
+ error TEXT,
838
+ created_at INTEGER NOT NULL
839
+ );
840
+
841
+ CREATE INDEX IF NOT EXISTS idx_snapshots_type ON snapshots(type);
842
+ CREATE INDEX IF NOT EXISTS idx_snapshots_created_at ON snapshots(created_at);
843
+ `);
569
844
  }
570
845
 
571
846
  export function hasLegacyStagentTables(sqlite: Database.Database): boolean {
@@ -16,3 +16,12 @@ sqlite.pragma("foreign_keys = ON");
16
16
  bootstrapStagentDatabase(sqlite);
17
17
 
18
18
  export const db = drizzle(sqlite, { schema });
19
+ export { sqlite };
20
+
21
+ // Lazy seed: table templates (idempotent — checks before inserting)
22
+ import("@/lib/data/seed-data/table-templates").then(({ seedTableTemplates }) => {
23
+ seedTableTemplates().catch(() => {
24
+ // Template seeding is non-critical — log and continue
25
+ console.warn("[db] table template seeding failed");
26
+ });
27
+ });
@@ -0,0 +1,13 @@
1
+ CREATE TABLE IF NOT EXISTS workflow_document_inputs (
2
+ id TEXT PRIMARY KEY NOT NULL,
3
+ workflow_id TEXT NOT NULL,
4
+ document_id TEXT NOT NULL,
5
+ step_id TEXT,
6
+ created_at INTEGER NOT NULL,
7
+ FOREIGN KEY (workflow_id) REFERENCES workflows(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
8
+ FOREIGN KEY (document_id) REFERENCES documents(id) ON UPDATE NO ACTION ON DELETE NO ACTION
9
+ );
10
+
11
+ CREATE INDEX IF NOT EXISTS idx_wdi_workflow ON workflow_document_inputs(workflow_id);
12
+ CREATE INDEX IF NOT EXISTS idx_wdi_document ON workflow_document_inputs(document_id);
13
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_wdi_workflow_doc_step ON workflow_document_inputs(workflow_id, document_id, step_id);
@@ -0,0 +1,25 @@
1
+ -- Schedule document inputs (context documents for scheduled tasks)
2
+ CREATE TABLE IF NOT EXISTS `schedule_document_inputs` (
3
+ `id` text PRIMARY KEY NOT NULL,
4
+ `schedule_id` text NOT NULL,
5
+ `document_id` text NOT NULL,
6
+ `created_at` integer NOT NULL,
7
+ FOREIGN KEY (`schedule_id`) REFERENCES `schedules`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
8
+ FOREIGN KEY (`document_id`) REFERENCES `documents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
9
+ );
10
+
11
+ CREATE INDEX IF NOT EXISTS `idx_sdi_schedule` ON `schedule_document_inputs` (`schedule_id`);
12
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_sdi_schedule_doc` ON `schedule_document_inputs` (`schedule_id`, `document_id`);
13
+
14
+ -- Project document defaults (auto-attached to new tasks/workflows in project)
15
+ CREATE TABLE IF NOT EXISTS `project_document_defaults` (
16
+ `id` text PRIMARY KEY NOT NULL,
17
+ `project_id` text NOT NULL,
18
+ `document_id` text NOT NULL,
19
+ `created_at` integer NOT NULL,
20
+ FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
21
+ FOREIGN KEY (`document_id`) REFERENCES `documents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
22
+ );
23
+
24
+ CREATE INDEX IF NOT EXISTS `idx_pdd_project` ON `project_document_defaults` (`project_id`);
25
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_pdd_project_doc` ON `project_document_defaults` (`project_id`, `document_id`);
@@ -0,0 +1,2 @@
1
+ ALTER TABLE workflows ADD COLUMN run_number INTEGER DEFAULT 0 NOT NULL;
2
+ ALTER TABLE tasks ADD COLUMN workflow_run_number INTEGER;
@@ -0,0 +1,160 @@
1
+ -- User-defined structured data tables
2
+ CREATE TABLE IF NOT EXISTS `user_tables` (
3
+ `id` TEXT PRIMARY KEY NOT NULL,
4
+ `project_id` TEXT,
5
+ `name` TEXT NOT NULL,
6
+ `description` TEXT,
7
+ `column_schema` TEXT NOT NULL DEFAULT '[]',
8
+ `row_count` INTEGER DEFAULT 0 NOT NULL,
9
+ `source` TEXT DEFAULT 'manual' NOT NULL,
10
+ `template_id` TEXT,
11
+ `created_at` INTEGER NOT NULL,
12
+ `updated_at` INTEGER NOT NULL,
13
+ FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
14
+ );
15
+
16
+ CREATE INDEX IF NOT EXISTS `idx_user_tables_project_id` ON `user_tables`(`project_id`);
17
+ CREATE INDEX IF NOT EXISTS `idx_user_tables_source` ON `user_tables`(`source`);
18
+
19
+ CREATE TABLE IF NOT EXISTS `user_table_columns` (
20
+ `id` TEXT PRIMARY KEY NOT NULL,
21
+ `table_id` TEXT NOT NULL,
22
+ `name` TEXT NOT NULL,
23
+ `display_name` TEXT NOT NULL,
24
+ `data_type` TEXT NOT NULL,
25
+ `position` INTEGER NOT NULL,
26
+ `required` INTEGER DEFAULT 0 NOT NULL,
27
+ `default_value` TEXT,
28
+ `config` TEXT,
29
+ `created_at` INTEGER NOT NULL,
30
+ `updated_at` INTEGER NOT NULL,
31
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
32
+ );
33
+
34
+ CREATE INDEX IF NOT EXISTS `idx_user_table_columns_table_id` ON `user_table_columns`(`table_id`);
35
+ CREATE INDEX IF NOT EXISTS `idx_user_table_columns_position` ON `user_table_columns`(`table_id`, `position`);
36
+
37
+ CREATE TABLE IF NOT EXISTS `user_table_rows` (
38
+ `id` TEXT PRIMARY KEY NOT NULL,
39
+ `table_id` TEXT NOT NULL,
40
+ `data` TEXT NOT NULL DEFAULT '{}',
41
+ `position` INTEGER NOT NULL,
42
+ `created_by` TEXT DEFAULT 'user',
43
+ `created_at` INTEGER NOT NULL,
44
+ `updated_at` INTEGER NOT NULL,
45
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
46
+ );
47
+
48
+ CREATE INDEX IF NOT EXISTS `idx_user_table_rows_table_id` ON `user_table_rows`(`table_id`);
49
+ CREATE INDEX IF NOT EXISTS `idx_user_table_rows_position` ON `user_table_rows`(`table_id`, `position`);
50
+
51
+ CREATE TABLE IF NOT EXISTS `user_table_views` (
52
+ `id` TEXT PRIMARY KEY NOT NULL,
53
+ `table_id` TEXT NOT NULL,
54
+ `name` TEXT NOT NULL,
55
+ `type` TEXT DEFAULT 'grid' NOT NULL,
56
+ `config` TEXT,
57
+ `is_default` INTEGER DEFAULT 0 NOT NULL,
58
+ `created_at` INTEGER NOT NULL,
59
+ `updated_at` INTEGER NOT NULL,
60
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
61
+ );
62
+
63
+ CREATE INDEX IF NOT EXISTS `idx_user_table_views_table_id` ON `user_table_views`(`table_id`);
64
+
65
+ CREATE TABLE IF NOT EXISTS `user_table_relationships` (
66
+ `id` TEXT PRIMARY KEY NOT NULL,
67
+ `from_table_id` TEXT NOT NULL,
68
+ `from_column` TEXT NOT NULL,
69
+ `to_table_id` TEXT NOT NULL,
70
+ `to_column` TEXT NOT NULL,
71
+ `relationship_type` TEXT NOT NULL,
72
+ `config` TEXT,
73
+ `created_at` INTEGER NOT NULL,
74
+ FOREIGN KEY (`from_table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
75
+ FOREIGN KEY (`to_table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
76
+ );
77
+
78
+ CREATE INDEX IF NOT EXISTS `idx_user_table_rels_from` ON `user_table_relationships`(`from_table_id`);
79
+ CREATE INDEX IF NOT EXISTS `idx_user_table_rels_to` ON `user_table_relationships`(`to_table_id`);
80
+
81
+ CREATE TABLE IF NOT EXISTS `user_table_templates` (
82
+ `id` TEXT PRIMARY KEY NOT NULL,
83
+ `name` TEXT NOT NULL,
84
+ `description` TEXT,
85
+ `category` TEXT NOT NULL,
86
+ `column_schema` TEXT NOT NULL,
87
+ `sample_data` TEXT,
88
+ `scope` TEXT DEFAULT 'system' NOT NULL,
89
+ `icon` TEXT,
90
+ `created_at` INTEGER NOT NULL,
91
+ `updated_at` INTEGER NOT NULL
92
+ );
93
+
94
+ CREATE INDEX IF NOT EXISTS `idx_user_table_templates_category` ON `user_table_templates`(`category`);
95
+ CREATE INDEX IF NOT EXISTS `idx_user_table_templates_scope` ON `user_table_templates`(`scope`);
96
+
97
+ CREATE TABLE IF NOT EXISTS `user_table_imports` (
98
+ `id` TEXT PRIMARY KEY NOT NULL,
99
+ `table_id` TEXT NOT NULL,
100
+ `document_id` TEXT,
101
+ `row_count` INTEGER DEFAULT 0 NOT NULL,
102
+ `error_count` INTEGER DEFAULT 0 NOT NULL,
103
+ `errors` TEXT,
104
+ `status` TEXT DEFAULT 'pending' NOT NULL,
105
+ `created_at` INTEGER NOT NULL,
106
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
107
+ FOREIGN KEY (`document_id`) REFERENCES `documents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
108
+ );
109
+
110
+ CREATE INDEX IF NOT EXISTS `idx_user_table_imports_table_id` ON `user_table_imports`(`table_id`);
111
+
112
+ -- Junction tables for linking tables to other domain objects
113
+ CREATE TABLE IF NOT EXISTS `table_document_inputs` (
114
+ `id` TEXT PRIMARY KEY NOT NULL,
115
+ `table_id` TEXT NOT NULL,
116
+ `document_id` TEXT NOT NULL,
117
+ `created_at` INTEGER NOT NULL,
118
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
119
+ FOREIGN KEY (`document_id`) REFERENCES `documents`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
120
+ );
121
+
122
+ CREATE INDEX IF NOT EXISTS `idx_tdi_table` ON `table_document_inputs`(`table_id`);
123
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_tdi_table_doc` ON `table_document_inputs`(`table_id`, `document_id`);
124
+
125
+ CREATE TABLE IF NOT EXISTS `task_table_inputs` (
126
+ `id` TEXT PRIMARY KEY NOT NULL,
127
+ `task_id` TEXT NOT NULL,
128
+ `table_id` TEXT NOT NULL,
129
+ `created_at` INTEGER NOT NULL,
130
+ FOREIGN KEY (`task_id`) REFERENCES `tasks`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
131
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
132
+ );
133
+
134
+ CREATE INDEX IF NOT EXISTS `idx_tti_task` ON `task_table_inputs`(`task_id`);
135
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_tti_task_table` ON `task_table_inputs`(`task_id`, `table_id`);
136
+
137
+ CREATE TABLE IF NOT EXISTS `workflow_table_inputs` (
138
+ `id` TEXT PRIMARY KEY NOT NULL,
139
+ `workflow_id` TEXT NOT NULL,
140
+ `table_id` TEXT NOT NULL,
141
+ `step_id` TEXT,
142
+ `created_at` INTEGER NOT NULL,
143
+ FOREIGN KEY (`workflow_id`) REFERENCES `workflows`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
144
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
145
+ );
146
+
147
+ CREATE INDEX IF NOT EXISTS `idx_wti_workflow` ON `workflow_table_inputs`(`workflow_id`);
148
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_wti_workflow_table_step` ON `workflow_table_inputs`(`workflow_id`, `table_id`, `step_id`);
149
+
150
+ CREATE TABLE IF NOT EXISTS `schedule_table_inputs` (
151
+ `id` TEXT PRIMARY KEY NOT NULL,
152
+ `schedule_id` TEXT NOT NULL,
153
+ `table_id` TEXT NOT NULL,
154
+ `created_at` INTEGER NOT NULL,
155
+ FOREIGN KEY (`schedule_id`) REFERENCES `schedules`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION,
156
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
157
+ );
158
+
159
+ CREATE INDEX IF NOT EXISTS `idx_sti_schedule` ON `schedule_table_inputs`(`schedule_id`);
160
+ CREATE UNIQUE INDEX IF NOT EXISTS `idx_sti_schedule_table` ON `schedule_table_inputs`(`schedule_id`, `table_id`);
@@ -0,0 +1,19 @@
1
+ -- Workflow triggers for user-defined tables
2
+ CREATE TABLE IF NOT EXISTS `user_table_triggers` (
3
+ `id` TEXT PRIMARY KEY NOT NULL,
4
+ `table_id` TEXT NOT NULL,
5
+ `name` TEXT NOT NULL,
6
+ `trigger_event` TEXT NOT NULL,
7
+ `condition` TEXT,
8
+ `action_type` TEXT NOT NULL,
9
+ `action_config` TEXT NOT NULL,
10
+ `status` TEXT DEFAULT 'active' NOT NULL,
11
+ `fire_count` INTEGER DEFAULT 0 NOT NULL,
12
+ `last_fired_at` INTEGER,
13
+ `created_at` INTEGER NOT NULL,
14
+ `updated_at` INTEGER NOT NULL,
15
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
16
+ );
17
+
18
+ CREATE INDEX IF NOT EXISTS `idx_user_table_triggers_table_id` ON `user_table_triggers`(`table_id`);
19
+ CREATE INDEX IF NOT EXISTS `idx_user_table_triggers_status` ON `user_table_triggers`(`status`);
@@ -0,0 +1,15 @@
1
+ -- Row version history for user-defined tables
2
+ CREATE TABLE IF NOT EXISTS `user_table_row_history` (
3
+ `id` TEXT PRIMARY KEY NOT NULL,
4
+ `row_id` TEXT NOT NULL,
5
+ `table_id` TEXT NOT NULL,
6
+ `previous_data` TEXT NOT NULL,
7
+ `changed_by` TEXT DEFAULT 'user',
8
+ `change_type` TEXT NOT NULL,
9
+ `created_at` INTEGER NOT NULL,
10
+ FOREIGN KEY (`table_id`) REFERENCES `user_tables`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
11
+ );
12
+
13
+ CREATE INDEX IF NOT EXISTS `idx_row_history_row_id` ON `user_table_row_history`(`row_id`);
14
+ CREATE INDEX IF NOT EXISTS `idx_row_history_table_id` ON `user_table_row_history`(`table_id`);
15
+ CREATE INDEX IF NOT EXISTS `idx_row_history_created_at` ON `user_table_row_history`(`created_at`);