@penclipai/db 2026.608.0 → 2026.702.0-canary.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 (142) hide show
  1. package/dist/environment-custom-images-schema.test.d.ts +2 -0
  2. package/dist/environment-custom-images-schema.test.d.ts.map +1 -0
  3. package/dist/environment-custom-images-schema.test.js +26 -0
  4. package/dist/environment-custom-images-schema.test.js.map +1 -0
  5. package/dist/external-objects-schema.test.d.ts +2 -0
  6. package/dist/external-objects-schema.test.d.ts.map +1 -0
  7. package/dist/external-objects-schema.test.js +46 -0
  8. package/dist/external-objects-schema.test.js.map +1 -0
  9. package/dist/migrations/0099_skills_store_foundation.sql +121 -0
  10. package/dist/migrations/0100_skill_install_count_backfill.sql +3 -0
  11. package/dist/migrations/0101_plugin_company_id_tenant_isolation.sql +14 -0
  12. package/dist/migrations/0102_managed_sandbox_dedup_index.sql +33 -0
  13. package/dist/migrations/0103_agent_error_reason.sql +1 -0
  14. package/dist/migrations/0104_issue_watchdogs.sql +90 -0
  15. package/dist/migrations/0105_instance_scoped_environments.sql +170 -0
  16. package/dist/migrations/0106_external_object_references.sql +106 -0
  17. package/dist/migrations/0107_external_object_display_metadata.sql +5 -0
  18. package/dist/migrations/0108_workspace_operations_issue_id.sql +41 -0
  19. package/dist/migrations/0109_routine_description_annotations.sql +170 -0
  20. package/dist/migrations/0110_document_company_cascade.sql +31 -0
  21. package/dist/migrations/0111_backfill_skill_create_human_defaults.sql +29 -0
  22. package/dist/migrations/0112_rename_skill_create_permission_key.sql +30 -0
  23. package/dist/migrations/0113_pipeline_foundation.sql +335 -0
  24. package/dist/migrations/0114_pipeline_case_issue_unlinked_event.sql +3 -0
  25. package/dist/migrations/0115_pipeline_routine_origin.sql +3 -0
  26. package/dist/migrations/0116_pipeline_upstream_drift_event.sql +3 -0
  27. package/dist/migrations/0117_pipeline_transition_forced_event.sql +3 -0
  28. package/dist/migrations/0118_pipeline_case_agent_fanout.sql +3 -0
  29. package/dist/migrations/0119_pipeline_drift_acknowledged_event.sql +3 -0
  30. package/dist/migrations/0120_pipeline_stage_working_primitives.sql +19 -0
  31. package/dist/migrations/0121_pipeline_automation_retry_effects.sql +43 -0
  32. package/dist/migrations/0122_pipeline_case_documents.sql +28 -0
  33. package/dist/migrations/0123_document_annotation_source_trust.sql +1 -0
  34. package/dist/migrations/0124_agent_api_key_scope_config.sql +1 -0
  35. package/dist/migrations/0125_environment_custom_image_templates.sql +147 -0
  36. package/dist/migrations/meta/0098_snapshot.json +122 -8
  37. package/dist/migrations/meta/{0090_snapshot.json → 0099_snapshot.json} +7551 -4095
  38. package/dist/migrations/meta/_journal.json +189 -0
  39. package/dist/pipelines-schema.test.d.ts +2 -0
  40. package/dist/pipelines-schema.test.d.ts.map +1 -0
  41. package/dist/pipelines-schema.test.js +205 -0
  42. package/dist/pipelines-schema.test.js.map +1 -0
  43. package/dist/schema/agent_api_keys.d.ts +37 -0
  44. package/dist/schema/agent_api_keys.d.ts.map +1 -1
  45. package/dist/schema/agent_api_keys.js +2 -1
  46. package/dist/schema/agent_api_keys.js.map +1 -1
  47. package/dist/schema/agents.d.ts +17 -0
  48. package/dist/schema/agents.d.ts.map +1 -1
  49. package/dist/schema/agents.js +1 -0
  50. package/dist/schema/agents.js.map +1 -1
  51. package/dist/schema/company_skills.d.ts +718 -0
  52. package/dist/schema/company_skills.d.ts.map +1 -1
  53. package/dist/schema/company_skills.js +61 -1
  54. package/dist/schema/company_skills.js.map +1 -1
  55. package/dist/schema/document_annotation_comments.d.ts +38 -1
  56. package/dist/schema/document_annotation_comments.d.ts.map +1 -1
  57. package/dist/schema/document_annotation_comments.js +8 -2
  58. package/dist/schema/document_annotation_comments.js.map +1 -1
  59. package/dist/schema/document_annotation_threads.d.ts +18 -1
  60. package/dist/schema/document_annotation_threads.d.ts.map +1 -1
  61. package/dist/schema/document_annotation_threads.js +7 -2
  62. package/dist/schema/document_annotation_threads.js.map +1 -1
  63. package/dist/schema/document_revisions.js +1 -1
  64. package/dist/schema/document_revisions.js.map +1 -1
  65. package/dist/schema/documents.js +1 -1
  66. package/dist/schema/documents.js.map +1 -1
  67. package/dist/schema/environment_custom_image_setup_sessions.d.ts +368 -0
  68. package/dist/schema/environment_custom_image_setup_sessions.d.ts.map +1 -0
  69. package/dist/schema/environment_custom_image_setup_sessions.js +40 -0
  70. package/dist/schema/environment_custom_image_setup_sessions.js.map +1 -0
  71. package/dist/schema/environment_custom_image_templates.d.ts +301 -0
  72. package/dist/schema/environment_custom_image_templates.d.ts.map +1 -0
  73. package/dist/schema/environment_custom_image_templates.js +34 -0
  74. package/dist/schema/environment_custom_image_templates.js.map +1 -0
  75. package/dist/schema/environments.d.ts +19 -17
  76. package/dist/schema/environments.d.ts.map +1 -1
  77. package/dist/schema/environments.js +8 -6
  78. package/dist/schema/environments.js.map +1 -1
  79. package/dist/schema/external_object_mentions.d.ts +337 -0
  80. package/dist/schema/external_object_mentions.d.ts.map +1 -0
  81. package/dist/schema/external_object_mentions.js +34 -0
  82. package/dist/schema/external_object_mentions.js.map +1 -0
  83. package/dist/schema/external_objects.d.ts +509 -0
  84. package/dist/schema/external_objects.d.ts.map +1 -0
  85. package/dist/schema/external_objects.js +41 -0
  86. package/dist/schema/external_objects.js.map +1 -0
  87. package/dist/schema/index.d.ts +10 -1
  88. package/dist/schema/index.d.ts.map +1 -1
  89. package/dist/schema/index.js +10 -1
  90. package/dist/schema/index.js.map +1 -1
  91. package/dist/schema/instance_settings.d.ts +17 -0
  92. package/dist/schema/instance_settings.d.ts.map +1 -1
  93. package/dist/schema/instance_settings.js +2 -0
  94. package/dist/schema/instance_settings.js.map +1 -1
  95. package/dist/schema/issue_watchdogs.d.ts +348 -0
  96. package/dist/schema/issue_watchdogs.d.ts.map +1 -0
  97. package/dist/schema/issue_watchdogs.js +36 -0
  98. package/dist/schema/issue_watchdogs.js.map +1 -0
  99. package/dist/schema/issues.d.ts.map +1 -1
  100. package/dist/schema/issues.js +6 -0
  101. package/dist/schema/issues.js.map +1 -1
  102. package/dist/schema/pipeline_case_events.d.ts +231 -0
  103. package/dist/schema/pipeline_case_events.d.ts.map +1 -0
  104. package/dist/schema/pipeline_case_events.js +52 -0
  105. package/dist/schema/pipeline_case_events.js.map +1 -0
  106. package/dist/schema/pipeline_cases.d.ts +1388 -0
  107. package/dist/schema/pipeline_cases.d.ts.map +1 -0
  108. package/dist/schema/pipeline_cases.js +138 -0
  109. package/dist/schema/pipeline_cases.js.map +1 -0
  110. package/dist/schema/pipelines.d.ts +500 -0
  111. package/dist/schema/pipelines.d.ts.map +1 -0
  112. package/dist/schema/pipelines.js +52 -0
  113. package/dist/schema/pipelines.js.map +1 -0
  114. package/dist/schema/plugin_entities.d.ts +17 -0
  115. package/dist/schema/plugin_entities.d.ts.map +1 -1
  116. package/dist/schema/plugin_entities.js +17 -2
  117. package/dist/schema/plugin_entities.js.map +1 -1
  118. package/dist/schema/plugin_jobs.d.ts +19 -2
  119. package/dist/schema/plugin_jobs.d.ts.map +1 -1
  120. package/dist/schema/plugin_jobs.js +4 -0
  121. package/dist/schema/plugin_jobs.js.map +1 -1
  122. package/dist/schema/plugin_logs.d.ts +17 -0
  123. package/dist/schema/plugin_logs.d.ts.map +1 -1
  124. package/dist/schema/plugin_logs.js +4 -0
  125. package/dist/schema/plugin_logs.js.map +1 -1
  126. package/dist/schema/plugin_webhooks.d.ts +17 -0
  127. package/dist/schema/plugin_webhooks.d.ts.map +1 -1
  128. package/dist/schema/plugin_webhooks.js +4 -0
  129. package/dist/schema/plugin_webhooks.js.map +1 -1
  130. package/dist/schema/routine_documents.d.ts +127 -0
  131. package/dist/schema/routine_documents.d.ts.map +1 -0
  132. package/dist/schema/routine_documents.js +18 -0
  133. package/dist/schema/routine_documents.js.map +1 -0
  134. package/dist/schema/routines.d.ts +34 -0
  135. package/dist/schema/routines.d.ts.map +1 -1
  136. package/dist/schema/routines.js +3 -0
  137. package/dist/schema/routines.js.map +1 -1
  138. package/dist/schema/workspace_operations.d.ts +17 -0
  139. package/dist/schema/workspace_operations.d.ts.map +1 -1
  140. package/dist/schema/workspace_operations.js +5 -0
  141. package/dist/schema/workspace_operations.js.map +1 -1
  142. package/package.json +4 -4
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=environment-custom-images-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-custom-images-schema.test.d.ts","sourceRoot":"","sources":["../src/environment-custom-images-schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import { getTableConfig } from "drizzle-orm/pg-core";
2
+ import { describe, expect, it } from "vitest";
3
+ import { environmentCustomImageSetupSessions } from "./schema/environment_custom_image_setup_sessions.js";
4
+ import { environmentCustomImageTemplates } from "./schema/environment_custom_image_templates.js";
5
+ function indexColumns(table, indexName) {
6
+ const index = getTableConfig(table).indexes.find((candidate) => candidate.config.name === indexName);
7
+ if (!index)
8
+ return [];
9
+ return index.config.columns.map((column) => column.name);
10
+ }
11
+ function indexWhere(table, indexName) {
12
+ return getTableConfig(table).indexes.find((candidate) => candidate.config.name === indexName)?.config.where;
13
+ }
14
+ describe("environment customImage schema", () => {
15
+ it("scopes template lookup and active uniqueness by company and environment", () => {
16
+ expect(indexColumns(environmentCustomImageTemplates, "environment_custom_image_templates_company_environment_status_idx")).toEqual(["company_id", "environment_id", "status"]);
17
+ expect(indexColumns(environmentCustomImageTemplates, "environment_custom_image_templates_company_environment_active_uq")).toEqual(["company_id", "environment_id"]);
18
+ expect(indexWhere(environmentCustomImageTemplates, "environment_custom_image_templates_company_environment_active_uq")).toBeDefined();
19
+ });
20
+ it("scopes setup-session lookup and active uniqueness by company and environment", () => {
21
+ expect(indexColumns(environmentCustomImageSetupSessions, "environment_custom_image_setup_sessions_company_environment_status_idx")).toEqual(["company_id", "environment_id", "status"]);
22
+ expect(indexColumns(environmentCustomImageSetupSessions, "environment_custom_image_setup_sessions_company_environment_active_uq")).toEqual(["company_id", "environment_id"]);
23
+ expect(indexWhere(environmentCustomImageSetupSessions, "environment_custom_image_setup_sessions_company_environment_active_uq")).toBeDefined();
24
+ });
25
+ });
26
+ //# sourceMappingURL=environment-custom-images-schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-custom-images-schema.test.js","sourceRoot":"","sources":["../src/environment-custom-images-schema.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,mCAAmC,EAAE,MAAM,qDAAqD,CAAC;AAC1G,OAAO,EAAE,+BAA+B,EAAE,MAAM,gDAAgD,CAAC;AAEjG,SAAS,YAAY,CAAC,KAA2C,EAAE,SAAiB;IAClF,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IACrG,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAE,MAA2B,CAAC,IAAI,CAAC,CAAC;AACjF,CAAC;AAED,SAAS,UAAU,CAAC,KAA2C,EAAE,SAAiB;IAChF,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC;AAC9G,CAAC;AAED,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,CAAC,YAAY,CACjB,+BAA+B,EAC/B,mEAAmE,CACpE,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,YAAY,CACjB,+BAA+B,EAC/B,kEAAkE,CACnE,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,UAAU,CACf,+BAA+B,EAC/B,kEAAkE,CACnE,CAAC,CAAC,WAAW,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,CAAC,YAAY,CACjB,mCAAmC,EACnC,wEAAwE,CACzE,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,YAAY,CACjB,mCAAmC,EACnC,uEAAuE,CACxE,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,UAAU,CACf,mCAAmC,EACnC,uEAAuE,CACxE,CAAC,CAAC,WAAW,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=external-objects-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-objects-schema.test.d.ts","sourceRoot":"","sources":["../src/external-objects-schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { getTableConfig } from "drizzle-orm/pg-core";
2
+ import { describe, expect, it } from "vitest";
3
+ import { externalObjectMentions } from "./schema/external_object_mentions.js";
4
+ import { externalObjects } from "./schema/external_objects.js";
5
+ function indexColumns(table, indexName) {
6
+ const index = getTableConfig(table).indexes.find((candidate) => candidate.config.name === indexName);
7
+ if (!index)
8
+ return [];
9
+ return index.config.columns.map((column) => column.name);
10
+ }
11
+ describe("external object reference schema", () => {
12
+ it("scopes external object uniqueness by company", () => {
13
+ expect(indexColumns(externalObjects, "external_objects_company_external_id_uq")).toEqual([
14
+ "company_id",
15
+ "provider_key",
16
+ "object_type",
17
+ "external_id",
18
+ ]);
19
+ expect(indexColumns(externalObjects, "external_objects_company_identity_uq")).toEqual([
20
+ "company_id",
21
+ "provider_key",
22
+ "object_type",
23
+ "canonical_identity_hash",
24
+ ]);
25
+ });
26
+ it("indexes status, refresh scheduling, source issue, and object lookups by company", () => {
27
+ expect(indexColumns(externalObjects, "external_objects_company_provider_status_idx")).toEqual([
28
+ "company_id",
29
+ "provider_key",
30
+ "status_category",
31
+ ]);
32
+ expect(indexColumns(externalObjects, "external_objects_company_refresh_idx")).toEqual([
33
+ "company_id",
34
+ "next_refresh_at",
35
+ ]);
36
+ expect(indexColumns(externalObjectMentions, "external_object_mentions_company_source_issue_idx")).toEqual([
37
+ "company_id",
38
+ "source_issue_id",
39
+ ]);
40
+ expect(indexColumns(externalObjectMentions, "external_object_mentions_company_object_idx")).toEqual([
41
+ "company_id",
42
+ "object_id",
43
+ ]);
44
+ });
45
+ });
46
+ //# sourceMappingURL=external-objects-schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-objects-schema.test.js","sourceRoot":"","sources":["../src/external-objects-schema.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,SAAS,YAAY,CAAC,KAA2C,EAAE,SAAiB;IAClF,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;IACrG,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAE,MAA2B,CAAC,IAAI,CAAC,CAAC;AACjF,CAAC;AAED,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;IAChD,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,yCAAyC,CAAC,CAAC,CAAC,OAAO,CAAC;YACvF,YAAY;YACZ,cAAc;YACd,aAAa;YACb,aAAa;SACd,CAAC,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,sCAAsC,CAAC,CAAC,CAAC,OAAO,CAAC;YACpF,YAAY;YACZ,cAAc;YACd,aAAa;YACb,yBAAyB;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,8CAA8C,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5F,YAAY;YACZ,cAAc;YACd,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,sCAAsC,CAAC,CAAC,CAAC,OAAO,CAAC;YACpF,YAAY;YACZ,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,sBAAsB,EAAE,mDAAmD,CAAC,CAAC,CAAC,OAAO,CAAC;YACxG,YAAY;YACZ,iBAAiB;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,sBAAsB,EAAE,6CAA6C,CAAC,CAAC,CAAC,OAAO,CAAC;YAClG,YAAY;YACZ,WAAW;SACZ,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,121 @@
1
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "icon_url" text;--> statement-breakpoint
2
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "color" text;--> statement-breakpoint
3
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "tagline" text;--> statement-breakpoint
4
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "author_name" text;--> statement-breakpoint
5
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "homepage_url" text;--> statement-breakpoint
6
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "categories" text[] NOT NULL DEFAULT '{}';--> statement-breakpoint
7
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "sharing_scope" text NOT NULL DEFAULT 'company';--> statement-breakpoint
8
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "public_share_token" text;--> statement-breakpoint
9
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "forked_from_skill_id" uuid;--> statement-breakpoint
10
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "forked_from_company_id" uuid;--> statement-breakpoint
11
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "star_count" integer NOT NULL DEFAULT 0;--> statement-breakpoint
12
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "install_count" integer NOT NULL DEFAULT 0;--> statement-breakpoint
13
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "fork_count" integer NOT NULL DEFAULT 0;--> statement-breakpoint
14
+ ALTER TABLE "company_skills" ADD COLUMN IF NOT EXISTS "current_version_id" uuid;--> statement-breakpoint
15
+ CREATE TABLE IF NOT EXISTS "company_skill_versions" (
16
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
17
+ "company_id" uuid NOT NULL,
18
+ "company_skill_id" uuid NOT NULL,
19
+ "revision_number" integer NOT NULL,
20
+ "label" text,
21
+ "file_inventory" jsonb DEFAULT '[]'::jsonb NOT NULL,
22
+ "author_agent_id" uuid,
23
+ "author_user_id" text,
24
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
25
+ );--> statement-breakpoint
26
+ CREATE TABLE IF NOT EXISTS "company_skill_stars" (
27
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
28
+ "company_id" uuid NOT NULL,
29
+ "company_skill_id" uuid NOT NULL,
30
+ "agent_id" uuid,
31
+ "user_id" text,
32
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
33
+ );--> statement-breakpoint
34
+ CREATE TABLE IF NOT EXISTS "company_skill_comments" (
35
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
36
+ "company_id" uuid NOT NULL,
37
+ "company_skill_id" uuid NOT NULL,
38
+ "parent_comment_id" uuid,
39
+ "author_agent_id" uuid,
40
+ "author_user_id" text,
41
+ "body" text NOT NULL,
42
+ "deleted_at" timestamp with time zone,
43
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
44
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
45
+ );--> statement-breakpoint
46
+ DO $$ BEGIN
47
+ ALTER TABLE "company_skills" ADD CONSTRAINT "company_skills_forked_from_skill_id_company_skills_id_fk" FOREIGN KEY ("forked_from_skill_id") REFERENCES "public"."company_skills"("id") ON DELETE set null ON UPDATE no action;
48
+ EXCEPTION
49
+ WHEN duplicate_object THEN null;
50
+ END $$;--> statement-breakpoint
51
+ DO $$ BEGIN
52
+ ALTER TABLE "company_skills" ADD CONSTRAINT "company_skills_forked_from_company_id_companies_id_fk" FOREIGN KEY ("forked_from_company_id") REFERENCES "public"."companies"("id") ON DELETE set null ON UPDATE no action;
53
+ EXCEPTION
54
+ WHEN duplicate_object THEN null;
55
+ END $$;--> statement-breakpoint
56
+ DO $$ BEGIN
57
+ ALTER TABLE "company_skill_versions" ADD CONSTRAINT "company_skill_versions_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
58
+ EXCEPTION
59
+ WHEN duplicate_object THEN null;
60
+ END $$;--> statement-breakpoint
61
+ DO $$ BEGIN
62
+ ALTER TABLE "company_skill_versions" ADD CONSTRAINT "company_skill_versions_company_skill_id_company_skills_id_fk" FOREIGN KEY ("company_skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
63
+ EXCEPTION
64
+ WHEN duplicate_object THEN null;
65
+ END $$;--> statement-breakpoint
66
+ DO $$ BEGIN
67
+ ALTER TABLE "company_skill_versions" ADD CONSTRAINT "company_skill_versions_author_agent_id_agents_id_fk" FOREIGN KEY ("author_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
68
+ EXCEPTION
69
+ WHEN duplicate_object THEN null;
70
+ END $$;--> statement-breakpoint
71
+ DO $$ BEGIN
72
+ ALTER TABLE "company_skills" ADD CONSTRAINT "company_skills_current_version_id_company_skill_versions_id_fk" FOREIGN KEY ("current_version_id") REFERENCES "public"."company_skill_versions"("id") ON DELETE set null ON UPDATE no action;
73
+ EXCEPTION
74
+ WHEN duplicate_object THEN null;
75
+ END $$;--> statement-breakpoint
76
+ DO $$ BEGIN
77
+ ALTER TABLE "company_skill_stars" ADD CONSTRAINT "company_skill_stars_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
78
+ EXCEPTION
79
+ WHEN duplicate_object THEN null;
80
+ END $$;--> statement-breakpoint
81
+ DO $$ BEGIN
82
+ ALTER TABLE "company_skill_stars" ADD CONSTRAINT "company_skill_stars_company_skill_id_company_skills_id_fk" FOREIGN KEY ("company_skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
83
+ EXCEPTION
84
+ WHEN duplicate_object THEN null;
85
+ END $$;--> statement-breakpoint
86
+ DO $$ BEGIN
87
+ ALTER TABLE "company_skill_stars" ADD CONSTRAINT "company_skill_stars_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE cascade ON UPDATE no action;
88
+ EXCEPTION
89
+ WHEN duplicate_object THEN null;
90
+ END $$;--> statement-breakpoint
91
+ DO $$ BEGIN
92
+ ALTER TABLE "company_skill_comments" ADD CONSTRAINT "company_skill_comments_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
93
+ EXCEPTION
94
+ WHEN duplicate_object THEN null;
95
+ END $$;--> statement-breakpoint
96
+ DO $$ BEGIN
97
+ ALTER TABLE "company_skill_comments" ADD CONSTRAINT "company_skill_comments_company_skill_id_company_skills_id_fk" FOREIGN KEY ("company_skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
98
+ EXCEPTION
99
+ WHEN duplicate_object THEN null;
100
+ END $$;--> statement-breakpoint
101
+ DO $$ BEGIN
102
+ ALTER TABLE "company_skill_comments" ADD CONSTRAINT "company_skill_comments_parent_comment_id_company_skill_comments_id_fk" FOREIGN KEY ("parent_comment_id") REFERENCES "public"."company_skill_comments"("id") ON DELETE set null ON UPDATE no action;
103
+ EXCEPTION
104
+ WHEN duplicate_object THEN null;
105
+ END $$;--> statement-breakpoint
106
+ DO $$ BEGIN
107
+ ALTER TABLE "company_skill_comments" ADD CONSTRAINT "company_skill_comments_author_agent_id_agents_id_fk" FOREIGN KEY ("author_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
108
+ EXCEPTION
109
+ WHEN duplicate_object THEN null;
110
+ END $$;--> statement-breakpoint
111
+ CREATE INDEX IF NOT EXISTS "company_skills_company_categories_idx" ON "company_skills" USING gin ("categories");--> statement-breakpoint
112
+ CREATE INDEX IF NOT EXISTS "company_skills_company_sharing_scope_idx" ON "company_skills" USING btree ("company_id","sharing_scope");--> statement-breakpoint
113
+ CREATE INDEX IF NOT EXISTS "company_skills_company_current_version_idx" ON "company_skills" USING btree ("company_id","current_version_id");--> statement-breakpoint
114
+ CREATE INDEX IF NOT EXISTS "company_skills_company_forked_from_idx" ON "company_skills" USING btree ("company_id","forked_from_skill_id");--> statement-breakpoint
115
+ CREATE UNIQUE INDEX IF NOT EXISTS "company_skill_versions_skill_revision_idx" ON "company_skill_versions" USING btree ("company_skill_id","revision_number");--> statement-breakpoint
116
+ CREATE INDEX IF NOT EXISTS "company_skill_versions_company_skill_created_idx" ON "company_skill_versions" USING btree ("company_id","company_skill_id","created_at");--> statement-breakpoint
117
+ CREATE UNIQUE INDEX IF NOT EXISTS "company_skill_stars_skill_agent_idx" ON "company_skill_stars" USING btree ("company_skill_id","agent_id");--> statement-breakpoint
118
+ CREATE UNIQUE INDEX IF NOT EXISTS "company_skill_stars_skill_user_idx" ON "company_skill_stars" USING btree ("company_skill_id","user_id");--> statement-breakpoint
119
+ CREATE INDEX IF NOT EXISTS "company_skill_stars_company_skill_created_idx" ON "company_skill_stars" USING btree ("company_id","company_skill_id","created_at");--> statement-breakpoint
120
+ CREATE INDEX IF NOT EXISTS "company_skill_comments_company_skill_created_idx" ON "company_skill_comments" USING btree ("company_id","company_skill_id","created_at");--> statement-breakpoint
121
+ CREATE INDEX IF NOT EXISTS "company_skill_comments_parent_idx" ON "company_skill_comments" USING btree ("parent_comment_id");
@@ -0,0 +1,3 @@
1
+ UPDATE "company_skills" SET "install_count" = 0 WHERE "install_count" IS NULL;--> statement-breakpoint
2
+ ALTER TABLE "company_skills" ALTER COLUMN "install_count" SET DEFAULT 0;--> statement-breakpoint
3
+ ALTER TABLE "company_skills" ALTER COLUMN "install_count" SET NOT NULL;
@@ -0,0 +1,14 @@
1
+ DROP INDEX "plugin_entities_external_idx";--> statement-breakpoint
2
+ ALTER TABLE "plugin_entities" ADD COLUMN "company_id" uuid;--> statement-breakpoint
3
+ ALTER TABLE "plugin_job_runs" ADD COLUMN "company_id" uuid;--> statement-breakpoint
4
+ ALTER TABLE "plugin_logs" ADD COLUMN "company_id" uuid;--> statement-breakpoint
5
+ ALTER TABLE "plugin_webhook_deliveries" ADD COLUMN "company_id" uuid;--> statement-breakpoint
6
+ ALTER TABLE "plugin_entities" ADD CONSTRAINT "plugin_entities_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
7
+ ALTER TABLE "plugin_job_runs" ADD CONSTRAINT "plugin_job_runs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
8
+ ALTER TABLE "plugin_logs" ADD CONSTRAINT "plugin_logs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
9
+ ALTER TABLE "plugin_webhook_deliveries" ADD CONSTRAINT "plugin_webhook_deliveries_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
10
+ CREATE INDEX "plugin_entities_company_idx" ON "plugin_entities" USING btree ("company_id");--> statement-breakpoint
11
+ CREATE INDEX "plugin_job_runs_company_idx" ON "plugin_job_runs" USING btree ("company_id");--> statement-breakpoint
12
+ CREATE INDEX "plugin_logs_company_idx" ON "plugin_logs" USING btree ("company_id");--> statement-breakpoint
13
+ CREATE INDEX "plugin_webhook_deliveries_company_idx" ON "plugin_webhook_deliveries" USING btree ("company_id");--> statement-breakpoint
14
+ ALTER TABLE "plugin_entities" ADD CONSTRAINT "plugin_entities_external_idx" UNIQUE NULLS NOT DISTINCT("company_id","plugin_id","entity_type","external_id");
@@ -0,0 +1,33 @@
1
+ -- One-shot dedup of any pre-existing managed sandbox rows duplicated per company.
2
+ -- Keeps the oldest row per (company_id) where driver='sandbox' AND metadata.managedByPaperclip is true.
3
+ -- Scoped to Paperclip-managed rows only: tenant-created sandbox envs (without the marker) are untouched.
4
+ DO $$
5
+ DECLARE
6
+ deleted_count integer;
7
+ BEGIN
8
+ WITH ranked AS (
9
+ SELECT
10
+ id,
11
+ row_number() OVER (
12
+ PARTITION BY company_id
13
+ ORDER BY created_at ASC, id ASC
14
+ ) AS rn
15
+ FROM environments
16
+ WHERE driver = 'sandbox'
17
+ AND (metadata ->> 'managedByPaperclip')::boolean = true
18
+ ),
19
+ deleted AS (
20
+ DELETE FROM environments
21
+ WHERE id IN (SELECT id FROM ranked WHERE rn > 1)
22
+ RETURNING 1
23
+ )
24
+ SELECT count(*) INTO deleted_count FROM deleted;
25
+
26
+ IF deleted_count > 0 THEN
27
+ RAISE NOTICE 'environments_company_managed_sandbox_idx dedup removed % duplicate managed-sandbox row(s)', deleted_count;
28
+ END IF;
29
+ END $$;
30
+ --> statement-breakpoint
31
+ CREATE UNIQUE INDEX IF NOT EXISTS "environments_company_managed_sandbox_idx"
32
+ ON "environments" ("company_id")
33
+ WHERE driver = 'sandbox' AND (metadata ->> 'managedByPaperclip')::boolean = true;
@@ -0,0 +1 @@
1
+ ALTER TABLE "agents" ADD COLUMN "error_reason" text;
@@ -0,0 +1,90 @@
1
+ CREATE TABLE IF NOT EXISTS "issue_watchdogs" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "company_id" uuid NOT NULL,
4
+ "issue_id" uuid NOT NULL,
5
+ "watchdog_agent_id" uuid NOT NULL,
6
+ "instructions" text,
7
+ "status" text DEFAULT 'active' NOT NULL,
8
+ "watchdog_issue_id" uuid,
9
+ "last_observed_fingerprint" text,
10
+ "last_reviewed_fingerprint" text,
11
+ "last_triggered_at" timestamp with time zone,
12
+ "last_completed_at" timestamp with time zone,
13
+ "trigger_count" integer DEFAULT 0 NOT NULL,
14
+ "created_by_agent_id" uuid,
15
+ "created_by_user_id" text,
16
+ "created_by_run_id" uuid,
17
+ "updated_by_agent_id" uuid,
18
+ "updated_by_user_id" text,
19
+ "updated_by_run_id" uuid,
20
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
21
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
22
+ );
23
+ --> statement-breakpoint
24
+ DO $$ BEGIN
25
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
26
+ EXCEPTION
27
+ WHEN duplicate_object THEN null;
28
+ END $$;
29
+ --> statement-breakpoint
30
+ DO $$ BEGIN
31
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_issue_id_issues_id_fk" FOREIGN KEY ("issue_id") REFERENCES "public"."issues"("id") ON DELETE cascade ON UPDATE no action;
32
+ EXCEPTION
33
+ WHEN duplicate_object THEN null;
34
+ END $$;
35
+ --> statement-breakpoint
36
+ DO $$ BEGIN
37
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_watchdog_agent_id_agents_id_fk" FOREIGN KEY ("watchdog_agent_id") REFERENCES "public"."agents"("id") ON DELETE no action ON UPDATE no action;
38
+ EXCEPTION
39
+ WHEN duplicate_object THEN null;
40
+ END $$;
41
+ --> statement-breakpoint
42
+ DO $$ BEGIN
43
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_watchdog_issue_id_issues_id_fk" FOREIGN KEY ("watchdog_issue_id") REFERENCES "public"."issues"("id") ON DELETE set null ON UPDATE no action;
44
+ EXCEPTION
45
+ WHEN duplicate_object THEN null;
46
+ END $$;
47
+ --> statement-breakpoint
48
+ DO $$ BEGIN
49
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_created_by_agent_id_agents_id_fk" FOREIGN KEY ("created_by_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
50
+ EXCEPTION
51
+ WHEN duplicate_object THEN null;
52
+ END $$;
53
+ --> statement-breakpoint
54
+ DO $$ BEGIN
55
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_created_by_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("created_by_run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE set null ON UPDATE no action;
56
+ EXCEPTION
57
+ WHEN duplicate_object THEN null;
58
+ END $$;
59
+ --> statement-breakpoint
60
+ DO $$ BEGIN
61
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_updated_by_agent_id_agents_id_fk" FOREIGN KEY ("updated_by_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;
62
+ EXCEPTION
63
+ WHEN duplicate_object THEN null;
64
+ END $$;
65
+ --> statement-breakpoint
66
+ DO $$ BEGIN
67
+ ALTER TABLE "issue_watchdogs" ADD CONSTRAINT "issue_watchdogs_updated_by_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("updated_by_run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE set null ON UPDATE no action;
68
+ EXCEPTION
69
+ WHEN duplicate_object THEN null;
70
+ END $$;
71
+ --> statement-breakpoint
72
+ CREATE UNIQUE INDEX IF NOT EXISTS "issue_watchdogs_company_issue_uq"
73
+ ON "issue_watchdogs" USING btree ("company_id","issue_id");
74
+ --> statement-breakpoint
75
+ CREATE INDEX IF NOT EXISTS "issue_watchdogs_company_status_idx"
76
+ ON "issue_watchdogs" USING btree ("company_id","status");
77
+ --> statement-breakpoint
78
+ CREATE INDEX IF NOT EXISTS "issue_watchdogs_company_agent_idx"
79
+ ON "issue_watchdogs" USING btree ("company_id","watchdog_agent_id");
80
+ --> statement-breakpoint
81
+ CREATE UNIQUE INDEX IF NOT EXISTS "issue_watchdogs_company_watchdog_issue_uq"
82
+ ON "issue_watchdogs" USING btree ("company_id","watchdog_issue_id")
83
+ WHERE "watchdog_issue_id" is not null;
84
+ --> statement-breakpoint
85
+ CREATE UNIQUE INDEX IF NOT EXISTS "issues_active_task_watchdog_uq"
86
+ ON "issues" USING btree ("company_id","origin_kind","origin_id")
87
+ WHERE "origin_kind" = 'task_watchdog'
88
+ AND "origin_id" IS NOT NULL
89
+ AND "hidden_at" IS NULL
90
+ AND "status" NOT IN ('done', 'cancelled');
@@ -0,0 +1,170 @@
1
+ ALTER TABLE "environments" ADD COLUMN "env_vars" jsonb DEFAULT '{}'::jsonb NOT NULL;--> statement-breakpoint
2
+ ALTER TABLE "instance_settings" ADD COLUMN "default_environment_id" uuid;--> statement-breakpoint
3
+ DO $$
4
+ BEGIN
5
+ CREATE TEMP TABLE environment_migration_map (
6
+ old_id uuid PRIMARY KEY,
7
+ new_id uuid NOT NULL
8
+ ) ON COMMIT DROP;
9
+
10
+ WITH ranked AS (
11
+ SELECT
12
+ e.id,
13
+ CASE
14
+ -- Only collapse classes that are globally singleton by design.
15
+ -- Named remote environments may legitimately differ across companies
16
+ -- even when they share the same display name.
17
+ WHEN e.driver = 'local' THEN '__paperclip_builtin_local__'
18
+ WHEN e.driver = 'sandbox' AND (e.metadata ->> 'managedByPaperclip')::boolean = true
19
+ THEN '__paperclip_managed_sandbox__'
20
+ ELSE e.id::text
21
+ END AS group_key,
22
+ row_number() OVER (
23
+ PARTITION BY CASE
24
+ WHEN e.driver = 'local' THEN '__paperclip_builtin_local__'
25
+ WHEN e.driver = 'sandbox' AND (e.metadata ->> 'managedByPaperclip')::boolean = true
26
+ THEN '__paperclip_managed_sandbox__'
27
+ ELSE e.id::text
28
+ END
29
+ ORDER BY e.created_at ASC, e.id ASC
30
+ ) AS rn
31
+ FROM "environments" e
32
+ ),
33
+ canonical AS (
34
+ SELECT
35
+ ranked.group_key,
36
+ ranked.id AS canonical_id
37
+ FROM ranked
38
+ WHERE ranked.rn = 1
39
+ )
40
+ INSERT INTO environment_migration_map (old_id, new_id)
41
+ SELECT ranked.id, canonical.canonical_id
42
+ FROM ranked
43
+ JOIN canonical ON canonical.group_key = ranked.group_key;
44
+
45
+ UPDATE "agents" AS agents
46
+ SET "default_environment_id" = map.new_id
47
+ FROM environment_migration_map AS map
48
+ WHERE agents."default_environment_id" = map.old_id
49
+ AND agents."default_environment_id" IS DISTINCT FROM map.new_id;
50
+
51
+ UPDATE "environment_leases" AS leases
52
+ SET "environment_id" = map.new_id
53
+ FROM environment_migration_map AS map
54
+ WHERE leases."environment_id" = map.old_id
55
+ AND leases."environment_id" IS DISTINCT FROM map.new_id;
56
+
57
+ DELETE FROM "environments" AS environments
58
+ USING environment_migration_map AS map
59
+ WHERE environments."id" = map.old_id
60
+ AND map.old_id <> map.new_id;
61
+ END $$;
62
+ --> statement-breakpoint
63
+ UPDATE "issues"
64
+ SET "execution_workspace_settings" = "execution_workspace_settings" - 'environmentId'
65
+ WHERE jsonb_typeof("execution_workspace_settings") = 'object'
66
+ AND "execution_workspace_settings" ? 'environmentId';
67
+ --> statement-breakpoint
68
+ DROP INDEX IF EXISTS "environments_company_managed_sandbox_idx";--> statement-breakpoint
69
+ DROP INDEX IF EXISTS "environments_company_status_idx";--> statement-breakpoint
70
+ DROP INDEX IF EXISTS "environments_company_driver_idx";--> statement-breakpoint
71
+ DROP INDEX IF EXISTS "environments_company_name_idx";--> statement-breakpoint
72
+ ALTER TABLE "environments" DROP CONSTRAINT IF EXISTS "environments_company_id_companies_id_fk";--> statement-breakpoint
73
+ ALTER TABLE "environments" DROP COLUMN "company_id";--> statement-breakpoint
74
+ INSERT INTO "environments" (
75
+ "id",
76
+ "name",
77
+ "description",
78
+ "driver",
79
+ "status",
80
+ "config",
81
+ "env_vars",
82
+ "metadata",
83
+ "created_at",
84
+ "updated_at"
85
+ )
86
+ SELECT
87
+ gen_random_uuid(),
88
+ 'Local',
89
+ 'Default execution environment for Paperclip runs on this machine.',
90
+ 'local',
91
+ 'active',
92
+ '{}'::jsonb,
93
+ '{}'::jsonb,
94
+ '{"managedByPaperclip": true, "defaultForInstance": true}'::jsonb,
95
+ now(),
96
+ now()
97
+ WHERE NOT EXISTS (
98
+ SELECT 1
99
+ FROM "environments"
100
+ WHERE "driver" = 'local'
101
+ );
102
+ --> statement-breakpoint
103
+ UPDATE "environments"
104
+ SET
105
+ "metadata" = COALESCE("metadata", '{}'::jsonb) || '{"managedByPaperclip": true, "defaultForInstance": true}'::jsonb,
106
+ "updated_at" = now()
107
+ WHERE "driver" = 'local';
108
+ --> statement-breakpoint
109
+ WITH duplicate_names AS (
110
+ SELECT
111
+ "id",
112
+ "name",
113
+ "driver",
114
+ row_number() OVER (PARTITION BY "name" ORDER BY "created_at" ASC, "id" ASC) AS rn
115
+ FROM "environments"
116
+ )
117
+ UPDATE "environments" AS environments
118
+ SET
119
+ "name" = duplicate_names."name" || ' (' || duplicate_names."driver" || ' ' || substring(duplicate_names."id"::text from 1 for 8) || ')',
120
+ "updated_at" = now()
121
+ FROM duplicate_names
122
+ WHERE environments."id" = duplicate_names."id"
123
+ AND duplicate_names.rn > 1;
124
+ --> statement-breakpoint
125
+ INSERT INTO "instance_settings" (
126
+ "id",
127
+ "singleton_key",
128
+ "default_environment_id",
129
+ "general",
130
+ "experimental",
131
+ "created_at",
132
+ "updated_at"
133
+ )
134
+ SELECT
135
+ gen_random_uuid(),
136
+ 'default',
137
+ local_env."id",
138
+ '{}'::jsonb,
139
+ '{}'::jsonb,
140
+ now(),
141
+ now()
142
+ FROM (
143
+ SELECT "id"
144
+ FROM "environments"
145
+ WHERE "driver" = 'local'
146
+ ORDER BY "created_at" ASC, "id" ASC
147
+ LIMIT 1
148
+ ) AS local_env
149
+ ON CONFLICT ("singleton_key") DO UPDATE
150
+ SET
151
+ "default_environment_id" = EXCLUDED."default_environment_id",
152
+ "updated_at" = now();
153
+ --> statement-breakpoint
154
+ ALTER TABLE "instance_settings"
155
+ ADD CONSTRAINT "instance_settings_default_environment_id_environments_id_fk"
156
+ FOREIGN KEY ("default_environment_id")
157
+ REFERENCES "public"."environments"("id")
158
+ ON DELETE set null
159
+ ON UPDATE no action;
160
+ --> statement-breakpoint
161
+ CREATE INDEX "environments_status_idx" ON "environments" USING btree ("status");--> statement-breakpoint
162
+ CREATE UNIQUE INDEX "environments_local_driver_idx"
163
+ ON "environments" USING btree ("driver")
164
+ WHERE "driver" = 'local';
165
+ --> statement-breakpoint
166
+ CREATE UNIQUE INDEX "environments_managed_sandbox_idx"
167
+ ON "environments" USING btree ("driver")
168
+ WHERE "driver" = 'sandbox' AND ("metadata" ->> 'managedByPaperclip')::boolean = true;
169
+ --> statement-breakpoint
170
+ CREATE UNIQUE INDEX "environments_name_idx" ON "environments" USING btree ("name");