@penclipai/db 2026.704.0 → 2026.714.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.
- package/dist/backup-lib.test.js +1 -1
- package/dist/backup-lib.test.js.map +1 -1
- package/dist/check-migration-safety.d.ts +27 -0
- package/dist/check-migration-safety.d.ts.map +1 -0
- package/dist/check-migration-safety.js +811 -0
- package/dist/check-migration-safety.js.map +1 -0
- package/dist/check-migration-safety.test.d.ts +2 -0
- package/dist/check-migration-safety.test.d.ts.map +1 -0
- package/dist/check-migration-safety.test.js +391 -0
- package/dist/check-migration-safety.test.js.map +1 -0
- package/dist/client.test.js +743 -0
- package/dist/client.test.js.map +1 -1
- package/dist/issue-comment-derived-attribution-migration.test.d.ts +2 -0
- package/dist/issue-comment-derived-attribution-migration.test.d.ts.map +1 -0
- package/dist/issue-comment-derived-attribution-migration.test.js +287 -0
- package/dist/issue-comment-derived-attribution-migration.test.js.map +1 -0
- package/dist/migration-safety-baseline.d.ts +135 -0
- package/dist/migration-safety-baseline.d.ts.map +1 -0
- package/dist/migration-safety-baseline.js +150 -0
- package/dist/migration-safety-baseline.js.map +1 -0
- package/dist/migrations/0128_user_specific_secrets.sql +178 -0
- package/dist/migrations/0129_agent_api_key_responsible_user.sql +41 -0
- package/dist/migrations/0131_repair_run_responsible_user_context_refs.sql +67 -0
- package/dist/migrations/0132_issue_comment_derived_attribution_fast.sql +82 -0
- package/dist/migrations/0133_resource_membership_stars.sql +7 -0
- package/dist/migrations/0134_run_responsible_user_invariant.sql +211 -0
- package/dist/migrations/0135_repair_run_responsible_user_updated_at_sweep.sql +84 -0
- package/dist/migrations/0136_acpx_default_engine_migration.sql +97 -0
- package/dist/migrations/0137_skill_studio_server_foundation.sql +76 -0
- package/dist/migrations/0138_skill_studio_run_retention.sql +5 -0
- package/dist/migrations/0139_skill_studio_run_templates.sql +44 -0
- package/dist/migrations/0140_built_in_managed_resources.sql +43 -0
- package/dist/migrations/0141_heartbeat_runs_company_created_at_index.sql +2 -0
- package/dist/migrations/0142_company_search_sort_indexes.sql +3 -0
- package/dist/migrations/0143_cases_foundation.sql +248 -0
- package/dist/migrations/0144_case_document_annotations.sql +31 -0
- package/dist/migrations/0145_inbox_dismissal_snooze_kind.sql +15 -0
- package/dist/migrations/0146_routine_activity_gate.sql +3 -0
- package/dist/migrations/0147_cost_event_status.sql +1 -0
- package/dist/migrations/meta/_journal.json +132 -6
- package/dist/schema/agent_api_keys.d.ts +23 -0
- package/dist/schema/agent_api_keys.d.ts.map +1 -1
- package/dist/schema/agent_api_keys.js +1 -0
- package/dist/schema/agent_api_keys.js.map +1 -1
- package/dist/schema/agent_memberships.d.ts +17 -0
- package/dist/schema/agent_memberships.d.ts.map +1 -1
- package/dist/schema/agent_memberships.js +2 -0
- package/dist/schema/agent_memberships.js.map +1 -1
- package/dist/schema/built_in_managed_resources.d.ts +197 -0
- package/dist/schema/built_in_managed_resources.d.ts.map +1 -0
- package/dist/schema/built_in_managed_resources.js +22 -0
- package/dist/schema/built_in_managed_resources.js.map +1 -0
- package/dist/schema/cases.d.ts +982 -0
- package/dist/schema/cases.d.ts.map +1 -0
- package/dist/schema/cases.js +122 -0
- package/dist/schema/cases.js.map +1 -0
- package/dist/schema/companies.d.ts +17 -0
- package/dist/schema/companies.d.ts.map +1 -1
- package/dist/schema/companies.js +1 -0
- package/dist/schema/companies.js.map +1 -1
- package/dist/schema/company_secrets.d.ts +51 -0
- package/dist/schema/company_secrets.d.ts.map +1 -1
- package/dist/schema/company_secrets.js +27 -3
- package/dist/schema/company_secrets.js.map +1 -1
- package/dist/schema/company_skills.d.ts +788 -0
- package/dist/schema/company_skills.d.ts.map +1 -1
- package/dist/schema/company_skills.js +63 -0
- package/dist/schema/company_skills.js.map +1 -1
- package/dist/schema/cost_events.d.ts +17 -0
- package/dist/schema/cost_events.d.ts.map +1 -1
- package/dist/schema/cost_events.js +1 -0
- package/dist/schema/cost_events.js.map +1 -1
- package/dist/schema/document_annotation_comments.d.ts +17 -0
- package/dist/schema/document_annotation_comments.d.ts.map +1 -1
- package/dist/schema/document_annotation_comments.js +4 -1
- package/dist/schema/document_annotation_comments.js.map +1 -1
- package/dist/schema/document_annotation_threads.d.ts +17 -0
- package/dist/schema/document_annotation_threads.d.ts.map +1 -1
- package/dist/schema/document_annotation_threads.js +4 -1
- package/dist/schema/document_annotation_threads.js.map +1 -1
- package/dist/schema/heartbeat_runs.d.ts +17 -0
- package/dist/schema/heartbeat_runs.d.ts.map +1 -1
- package/dist/schema/heartbeat_runs.js +3 -0
- package/dist/schema/heartbeat_runs.js.map +1 -1
- package/dist/schema/inbox_dismissals.d.ts +36 -0
- package/dist/schema/inbox_dismissals.d.ts.map +1 -1
- package/dist/schema/inbox_dismissals.js +2 -0
- package/dist/schema/inbox_dismissals.js.map +1 -1
- package/dist/schema/index.d.ts +5 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +5 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/issues.d.ts +34 -0
- package/dist/schema/issues.d.ts.map +1 -1
- package/dist/schema/issues.js +7 -0
- package/dist/schema/issues.js.map +1 -1
- package/dist/schema/project_memberships.d.ts +17 -0
- package/dist/schema/project_memberships.d.ts.map +1 -1
- package/dist/schema/project_memberships.js +2 -0
- package/dist/schema/project_memberships.js.map +1 -1
- package/dist/schema/routines.d.ts +85 -0
- package/dist/schema/routines.d.ts.map +1 -1
- package/dist/schema/routines.js +8 -0
- package/dist/schema/routines.js.map +1 -1
- package/dist/schema/secret_access_events.d.ts +103 -1
- package/dist/schema/secret_access_events.d.ts.map +1 -1
- package/dist/schema/secret_access_events.js +10 -1
- package/dist/schema/secret_access_events.js.map +1 -1
- package/dist/schema/user_secret_declarations.d.ts +229 -0
- package/dist/schema/user_secret_declarations.d.ts.map +1 -0
- package/dist/schema/user_secret_declarations.js +31 -0
- package/dist/schema/user_secret_declarations.js.map +1 -0
- package/dist/schema/user_secret_definitions.d.ts +316 -0
- package/dist/schema/user_secret_definitions.d.ts.map +1 -0
- package/dist/schema/user_secret_definitions.js +33 -0
- package/dist/schema/user_secret_definitions.js.map +1 -0
- package/dist/table-size-estimates.d.ts +372 -0
- package/dist/table-size-estimates.d.ts.map +1 -0
- package/dist/table-size-estimates.js +155 -0
- package/dist/table-size-estimates.js.map +1 -0
- package/package.json +3 -3
- package/dist/migrations/0126_issue_comment_derived_attribution.sql +0 -69
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
ALTER TABLE "companies" ADD COLUMN IF NOT EXISTS "default_responsible_user_id" text;
|
|
2
|
+
--> statement-breakpoint
|
|
3
|
+
WITH owner_defaults AS (
|
|
4
|
+
SELECT DISTINCT ON ("company_id")
|
|
5
|
+
"company_id",
|
|
6
|
+
"principal_id" AS "user_id"
|
|
7
|
+
FROM "company_memberships"
|
|
8
|
+
WHERE "principal_type" = 'user'
|
|
9
|
+
AND "status" = 'active'
|
|
10
|
+
AND "membership_role" = 'owner'
|
|
11
|
+
ORDER BY "company_id", "created_at" ASC, "id" ASC
|
|
12
|
+
)
|
|
13
|
+
UPDATE "companies" AS c
|
|
14
|
+
SET "default_responsible_user_id" = owner_defaults."user_id"
|
|
15
|
+
FROM owner_defaults
|
|
16
|
+
WHERE c."id" = owner_defaults."company_id"
|
|
17
|
+
AND c."default_responsible_user_id" IS NULL;
|
|
18
|
+
--> statement-breakpoint
|
|
19
|
+
WITH RECURSIVE issue_chain AS (
|
|
20
|
+
SELECT
|
|
21
|
+
child."id" AS "issue_id",
|
|
22
|
+
child."company_id",
|
|
23
|
+
child."parent_id",
|
|
24
|
+
child."responsible_user_id",
|
|
25
|
+
child."created_by_user_id",
|
|
26
|
+
0 AS "depth"
|
|
27
|
+
FROM "issues" AS child
|
|
28
|
+
WHERE child."responsible_user_id" IS NULL
|
|
29
|
+
UNION ALL
|
|
30
|
+
SELECT
|
|
31
|
+
issue_chain."issue_id",
|
|
32
|
+
parent."company_id",
|
|
33
|
+
parent."parent_id",
|
|
34
|
+
parent."responsible_user_id",
|
|
35
|
+
parent."created_by_user_id",
|
|
36
|
+
issue_chain."depth" + 1
|
|
37
|
+
FROM issue_chain
|
|
38
|
+
JOIN "issues" AS parent
|
|
39
|
+
ON parent."id" = issue_chain."parent_id"
|
|
40
|
+
AND parent."company_id" = issue_chain."company_id"
|
|
41
|
+
WHERE issue_chain."depth" < 50
|
|
42
|
+
),
|
|
43
|
+
resolved_issue_users AS (
|
|
44
|
+
SELECT DISTINCT ON ("issue_id")
|
|
45
|
+
"issue_id",
|
|
46
|
+
COALESCE("responsible_user_id", "created_by_user_id") AS "user_id"
|
|
47
|
+
FROM issue_chain
|
|
48
|
+
WHERE COALESCE("responsible_user_id", "created_by_user_id") IS NOT NULL
|
|
49
|
+
ORDER BY "issue_id", "depth" ASC
|
|
50
|
+
)
|
|
51
|
+
UPDATE "issues" AS i
|
|
52
|
+
SET "responsible_user_id" = resolved_issue_users."user_id"
|
|
53
|
+
FROM resolved_issue_users
|
|
54
|
+
WHERE i."id" = resolved_issue_users."issue_id"
|
|
55
|
+
AND i."responsible_user_id" IS NULL;
|
|
56
|
+
--> statement-breakpoint
|
|
57
|
+
UPDATE "issues" AS i
|
|
58
|
+
SET "responsible_user_id" = c."default_responsible_user_id"
|
|
59
|
+
FROM "companies" AS c
|
|
60
|
+
WHERE i."company_id" = c."id"
|
|
61
|
+
AND i."responsible_user_id" IS NULL
|
|
62
|
+
AND c."default_responsible_user_id" IS NOT NULL;
|
|
63
|
+
--> statement-breakpoint
|
|
64
|
+
WITH routine_responsible_users AS (
|
|
65
|
+
SELECT
|
|
66
|
+
r."id",
|
|
67
|
+
COALESCE(r."created_by_user_id", parent_issue."responsible_user_id", c."default_responsible_user_id") AS "user_id"
|
|
68
|
+
FROM "routines" AS r
|
|
69
|
+
JOIN "companies" AS c ON c."id" = r."company_id"
|
|
70
|
+
LEFT JOIN "issues" AS parent_issue
|
|
71
|
+
ON parent_issue."id" = r."parent_issue_id"
|
|
72
|
+
AND parent_issue."company_id" = r."company_id"
|
|
73
|
+
WHERE r."responsible_user_id" IS NULL
|
|
74
|
+
)
|
|
75
|
+
UPDATE "routines" AS r
|
|
76
|
+
SET "responsible_user_id" = routine_responsible_users."user_id"
|
|
77
|
+
FROM routine_responsible_users
|
|
78
|
+
WHERE r."id" = routine_responsible_users."id"
|
|
79
|
+
AND routine_responsible_users."user_id" IS NOT NULL;
|
|
80
|
+
--> statement-breakpoint
|
|
81
|
+
WITH routine_revision_responsible_users AS (
|
|
82
|
+
SELECT
|
|
83
|
+
rr."id",
|
|
84
|
+
COALESCE(rr."created_by_user_id", r."responsible_user_id", c."default_responsible_user_id") AS "user_id"
|
|
85
|
+
FROM "routine_revisions" AS rr
|
|
86
|
+
JOIN "routines" AS r
|
|
87
|
+
ON rr."routine_id" = r."id"
|
|
88
|
+
AND rr."company_id" = r."company_id"
|
|
89
|
+
JOIN "companies" AS c ON c."id" = rr."company_id"
|
|
90
|
+
WHERE rr."responsible_user_id" IS NULL
|
|
91
|
+
)
|
|
92
|
+
UPDATE "routine_revisions" AS rr
|
|
93
|
+
SET "responsible_user_id" = routine_revision_responsible_users."user_id"
|
|
94
|
+
FROM routine_revision_responsible_users
|
|
95
|
+
WHERE rr."id" = routine_revision_responsible_users."id"
|
|
96
|
+
AND routine_revision_responsible_users."user_id" IS NOT NULL;
|
|
97
|
+
--> statement-breakpoint
|
|
98
|
+
WITH routine_run_responsible_users AS (
|
|
99
|
+
SELECT
|
|
100
|
+
rr."id",
|
|
101
|
+
COALESCE(linked_issue."responsible_user_id", r."responsible_user_id", c."default_responsible_user_id") AS "user_id"
|
|
102
|
+
FROM "routine_runs" AS rr
|
|
103
|
+
JOIN "routines" AS r
|
|
104
|
+
ON rr."routine_id" = r."id"
|
|
105
|
+
AND rr."company_id" = r."company_id"
|
|
106
|
+
JOIN "companies" AS c ON c."id" = rr."company_id"
|
|
107
|
+
LEFT JOIN "issues" AS linked_issue
|
|
108
|
+
ON linked_issue."id" = rr."linked_issue_id"
|
|
109
|
+
AND linked_issue."company_id" = rr."company_id"
|
|
110
|
+
WHERE rr."responsible_user_id" IS NULL
|
|
111
|
+
)
|
|
112
|
+
UPDATE "routine_runs" AS rr
|
|
113
|
+
SET "responsible_user_id" = routine_run_responsible_users."user_id"
|
|
114
|
+
FROM routine_run_responsible_users
|
|
115
|
+
WHERE rr."id" = routine_run_responsible_users."id"
|
|
116
|
+
AND routine_run_responsible_users."user_id" IS NOT NULL;
|
|
117
|
+
--> statement-breakpoint
|
|
118
|
+
UPDATE "heartbeat_runs" AS h
|
|
119
|
+
SET "responsible_user_id" = original."responsible_user_id"
|
|
120
|
+
FROM "heartbeat_runs" AS original
|
|
121
|
+
WHERE h."retry_of_run_id" = original."id"
|
|
122
|
+
AND h."company_id" = original."company_id"
|
|
123
|
+
AND h."responsible_user_id" IS NULL
|
|
124
|
+
AND original."responsible_user_id" IS NOT NULL;
|
|
125
|
+
--> statement-breakpoint
|
|
126
|
+
WITH extracted_run_refs AS (
|
|
127
|
+
SELECT
|
|
128
|
+
h."id" AS "run_id",
|
|
129
|
+
h."company_id",
|
|
130
|
+
NULLIF(h."context_snapshot" ->> 'issueId', '') AS "issue_ref",
|
|
131
|
+
1 AS "ref_priority"
|
|
132
|
+
FROM "heartbeat_runs" AS h
|
|
133
|
+
WHERE h."responsible_user_id" IS NULL
|
|
134
|
+
AND NULLIF(h."context_snapshot" ->> 'issueId', '') IS NOT NULL
|
|
135
|
+
|
|
136
|
+
UNION ALL
|
|
137
|
+
|
|
138
|
+
SELECT
|
|
139
|
+
h."id" AS "run_id",
|
|
140
|
+
h."company_id",
|
|
141
|
+
NULLIF(h."context_snapshot" ->> 'taskId', '') AS "issue_ref",
|
|
142
|
+
2 AS "ref_priority"
|
|
143
|
+
FROM "heartbeat_runs" AS h
|
|
144
|
+
WHERE h."responsible_user_id" IS NULL
|
|
145
|
+
AND NULLIF(h."context_snapshot" ->> 'taskId', '') IS NOT NULL
|
|
146
|
+
),
|
|
147
|
+
uuid_run_refs AS (
|
|
148
|
+
SELECT
|
|
149
|
+
"run_id",
|
|
150
|
+
"company_id",
|
|
151
|
+
"issue_ref"::uuid AS "issue_id",
|
|
152
|
+
"ref_priority"
|
|
153
|
+
FROM extracted_run_refs
|
|
154
|
+
WHERE "issue_ref" ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
|
|
155
|
+
),
|
|
156
|
+
resolved_run_users AS (
|
|
157
|
+
SELECT DISTINCT ON ("run_id")
|
|
158
|
+
"run_id",
|
|
159
|
+
"responsible_user_id"
|
|
160
|
+
FROM (
|
|
161
|
+
SELECT
|
|
162
|
+
refs."run_id",
|
|
163
|
+
i."responsible_user_id",
|
|
164
|
+
refs."ref_priority",
|
|
165
|
+
1 AS "match_priority"
|
|
166
|
+
FROM uuid_run_refs AS refs
|
|
167
|
+
JOIN "issues" AS i
|
|
168
|
+
ON i."id" = refs."issue_id"
|
|
169
|
+
AND i."company_id" = refs."company_id"
|
|
170
|
+
WHERE i."responsible_user_id" IS NOT NULL
|
|
171
|
+
|
|
172
|
+
UNION ALL
|
|
173
|
+
|
|
174
|
+
SELECT
|
|
175
|
+
refs."run_id",
|
|
176
|
+
i."responsible_user_id",
|
|
177
|
+
refs."ref_priority",
|
|
178
|
+
2 AS "match_priority"
|
|
179
|
+
FROM extracted_run_refs AS refs
|
|
180
|
+
JOIN "issues" AS i
|
|
181
|
+
ON i."identifier" = refs."issue_ref"
|
|
182
|
+
AND i."company_id" = refs."company_id"
|
|
183
|
+
WHERE refs."issue_ref" IS NOT NULL
|
|
184
|
+
AND i."responsible_user_id" IS NOT NULL
|
|
185
|
+
) AS candidates
|
|
186
|
+
ORDER BY "run_id", "ref_priority" ASC, "match_priority" ASC
|
|
187
|
+
)
|
|
188
|
+
UPDATE "heartbeat_runs" AS h
|
|
189
|
+
SET "responsible_user_id" = resolved_run_users."responsible_user_id"
|
|
190
|
+
FROM resolved_run_users
|
|
191
|
+
WHERE h."id" = resolved_run_users."run_id"
|
|
192
|
+
AND h."responsible_user_id" IS NULL;
|
|
193
|
+
--> statement-breakpoint
|
|
194
|
+
UPDATE "heartbeat_runs" AS h
|
|
195
|
+
SET "responsible_user_id" = awr."requested_by_actor_id"
|
|
196
|
+
FROM "agent_wakeup_requests" AS awr
|
|
197
|
+
WHERE h."wakeup_request_id" = awr."id"
|
|
198
|
+
AND h."company_id" = awr."company_id"
|
|
199
|
+
AND h."responsible_user_id" IS NULL
|
|
200
|
+
AND awr."requested_by_actor_type" = 'user'
|
|
201
|
+
AND awr."requested_by_actor_id" IS NOT NULL;
|
|
202
|
+
--> statement-breakpoint
|
|
203
|
+
UPDATE "heartbeat_runs" AS h
|
|
204
|
+
SET "responsible_user_id" = c."default_responsible_user_id"
|
|
205
|
+
FROM "companies" AS c
|
|
206
|
+
WHERE h."company_id" = c."id"
|
|
207
|
+
AND h."responsible_user_id" IS NULL
|
|
208
|
+
AND c."default_responsible_user_id" IS NOT NULL;
|
|
209
|
+
--> statement-breakpoint
|
|
210
|
+
CREATE INDEX IF NOT EXISTS "companies_default_responsible_user_idx"
|
|
211
|
+
ON "companies" ("default_responsible_user_id");
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
DROP TABLE IF EXISTS "run_responsible_user_updated_at_sweeps";
|
|
2
|
+
--> statement-breakpoint
|
|
3
|
+
CREATE TEMP TABLE "run_responsible_user_updated_at_sweeps" ON COMMIT DROP AS
|
|
4
|
+
SELECT i."company_id", i."updated_at" AS "sweep_at"
|
|
5
|
+
FROM "issues" AS i
|
|
6
|
+
WHERE EXISTS (
|
|
7
|
+
SELECT 1
|
|
8
|
+
FROM "heartbeat_runs" AS h
|
|
9
|
+
WHERE h."company_id" = i."company_id"
|
|
10
|
+
AND h."updated_at" = i."updated_at"
|
|
11
|
+
)
|
|
12
|
+
AND EXISTS (
|
|
13
|
+
SELECT 1
|
|
14
|
+
FROM "companies" AS c
|
|
15
|
+
WHERE c."id" = i."company_id"
|
|
16
|
+
AND c."updated_at" = i."updated_at"
|
|
17
|
+
)
|
|
18
|
+
GROUP BY i."company_id", i."updated_at"
|
|
19
|
+
HAVING count(*) > 100;
|
|
20
|
+
--> statement-breakpoint
|
|
21
|
+
UPDATE "issues" AS i
|
|
22
|
+
SET "updated_at" = GREATEST(
|
|
23
|
+
i."created_at",
|
|
24
|
+
COALESCE(CASE WHEN i."started_at" <= sweep."sweep_at" THEN i."started_at" END, i."created_at"),
|
|
25
|
+
COALESCE(CASE WHEN i."completed_at" <= sweep."sweep_at" THEN i."completed_at" END, i."created_at"),
|
|
26
|
+
COALESCE(CASE WHEN i."cancelled_at" <= sweep."sweep_at" THEN i."cancelled_at" END, i."created_at"),
|
|
27
|
+
COALESCE(CASE WHEN i."monitor_wake_requested_at" <= sweep."sweep_at" THEN i."monitor_wake_requested_at" END, i."created_at"),
|
|
28
|
+
COALESCE(CASE WHEN i."monitor_last_triggered_at" <= sweep."sweep_at" THEN i."monitor_last_triggered_at" END, i."created_at"),
|
|
29
|
+
COALESCE(
|
|
30
|
+
(
|
|
31
|
+
SELECT max(GREATEST(c."created_at", c."updated_at"))
|
|
32
|
+
FROM "issue_comments" AS c
|
|
33
|
+
WHERE c."company_id" = i."company_id"
|
|
34
|
+
AND c."issue_id" = i."id"
|
|
35
|
+
AND c."created_at" <= sweep."sweep_at"
|
|
36
|
+
AND c."updated_at" <= sweep."sweep_at"
|
|
37
|
+
),
|
|
38
|
+
i."created_at"
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
FROM "run_responsible_user_updated_at_sweeps" AS sweep
|
|
42
|
+
WHERE i."company_id" = sweep."company_id"
|
|
43
|
+
AND i."updated_at" = sweep."sweep_at";
|
|
44
|
+
--> statement-breakpoint
|
|
45
|
+
UPDATE "heartbeat_runs" AS h
|
|
46
|
+
SET "updated_at" = GREATEST(
|
|
47
|
+
h."created_at",
|
|
48
|
+
COALESCE(CASE WHEN h."started_at" <= sweep."sweep_at" THEN h."started_at" END, h."created_at"),
|
|
49
|
+
COALESCE(CASE WHEN h."process_started_at" <= sweep."sweep_at" THEN h."process_started_at" END, h."created_at"),
|
|
50
|
+
COALESCE(CASE WHEN h."last_output_at" <= sweep."sweep_at" THEN h."last_output_at" END, h."created_at"),
|
|
51
|
+
COALESCE(CASE WHEN h."scheduled_retry_at" <= sweep."sweep_at" THEN h."scheduled_retry_at" END, h."created_at"),
|
|
52
|
+
COALESCE(CASE WHEN h."finished_at" <= sweep."sweep_at" THEN h."finished_at" END, h."created_at")
|
|
53
|
+
)
|
|
54
|
+
FROM "run_responsible_user_updated_at_sweeps" AS sweep
|
|
55
|
+
WHERE h."company_id" = sweep."company_id"
|
|
56
|
+
AND h."updated_at" = sweep."sweep_at";
|
|
57
|
+
--> statement-breakpoint
|
|
58
|
+
UPDATE "routine_runs" AS rr
|
|
59
|
+
SET "updated_at" = GREATEST(
|
|
60
|
+
rr."created_at",
|
|
61
|
+
COALESCE(CASE WHEN rr."triggered_at" <= sweep."sweep_at" THEN rr."triggered_at" END, rr."created_at"),
|
|
62
|
+
COALESCE(CASE WHEN rr."completed_at" <= sweep."sweep_at" THEN rr."completed_at" END, rr."created_at")
|
|
63
|
+
)
|
|
64
|
+
FROM "run_responsible_user_updated_at_sweeps" AS sweep
|
|
65
|
+
WHERE rr."company_id" = sweep."company_id"
|
|
66
|
+
AND rr."updated_at" = sweep."sweep_at";
|
|
67
|
+
--> statement-breakpoint
|
|
68
|
+
UPDATE "routines" AS r
|
|
69
|
+
SET "updated_at" = GREATEST(
|
|
70
|
+
r."created_at",
|
|
71
|
+
COALESCE(CASE WHEN r."last_triggered_at" <= sweep."sweep_at" THEN r."last_triggered_at" END, r."created_at"),
|
|
72
|
+
COALESCE(CASE WHEN r."last_enqueued_at" <= sweep."sweep_at" THEN r."last_enqueued_at" END, r."created_at")
|
|
73
|
+
)
|
|
74
|
+
FROM "run_responsible_user_updated_at_sweeps" AS sweep
|
|
75
|
+
WHERE r."company_id" = sweep."company_id"
|
|
76
|
+
AND r."updated_at" = sweep."sweep_at";
|
|
77
|
+
--> statement-breakpoint
|
|
78
|
+
UPDATE "companies" AS c
|
|
79
|
+
SET "updated_at" = c."created_at"
|
|
80
|
+
FROM "run_responsible_user_updated_at_sweeps" AS sweep
|
|
81
|
+
WHERE c."id" = sweep."company_id"
|
|
82
|
+
AND c."updated_at" = sweep."sweep_at";
|
|
83
|
+
--> statement-breakpoint
|
|
84
|
+
DROP TABLE IF EXISTS "run_responsible_user_updated_at_sweeps";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
WITH migrated_agents AS (
|
|
2
|
+
SELECT
|
|
3
|
+
"id",
|
|
4
|
+
"company_id",
|
|
5
|
+
CASE lower(COALESCE(NULLIF("adapter_config" ->> 'agent', ''), 'claude'))
|
|
6
|
+
WHEN 'codex' THEN 'codex_local'
|
|
7
|
+
ELSE 'claude_local'
|
|
8
|
+
END AS "next_adapter_type",
|
|
9
|
+
CASE lower(COALESCE(NULLIF("adapter_config" ->> 'agent', ''), 'claude'))
|
|
10
|
+
WHEN 'codex' THEN
|
|
11
|
+
(
|
|
12
|
+
"adapter_config"
|
|
13
|
+
- 'agent'
|
|
14
|
+
- 'effort'
|
|
15
|
+
- 'reasoningEffort'
|
|
16
|
+
- 'thinkingEffort'
|
|
17
|
+
)
|
|
18
|
+
|| jsonb_build_object('engine', 'acp')
|
|
19
|
+
|| CASE
|
|
20
|
+
WHEN COALESCE(
|
|
21
|
+
"adapter_config" -> 'modelReasoningEffort',
|
|
22
|
+
"adapter_config" -> 'reasoningEffort',
|
|
23
|
+
"adapter_config" -> 'thinkingEffort',
|
|
24
|
+
"adapter_config" -> 'effort'
|
|
25
|
+
) IS NULL THEN '{}'::jsonb
|
|
26
|
+
ELSE jsonb_build_object(
|
|
27
|
+
'modelReasoningEffort',
|
|
28
|
+
COALESCE(
|
|
29
|
+
"adapter_config" -> 'modelReasoningEffort',
|
|
30
|
+
"adapter_config" -> 'reasoningEffort',
|
|
31
|
+
"adapter_config" -> 'thinkingEffort',
|
|
32
|
+
"adapter_config" -> 'effort'
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
END
|
|
36
|
+
ELSE
|
|
37
|
+
(
|
|
38
|
+
"adapter_config"
|
|
39
|
+
- 'agent'
|
|
40
|
+
- 'modelReasoningEffort'
|
|
41
|
+
- 'reasoningEffort'
|
|
42
|
+
- 'thinkingEffort'
|
|
43
|
+
)
|
|
44
|
+
|| jsonb_build_object('engine', 'acp')
|
|
45
|
+
|| CASE
|
|
46
|
+
WHEN COALESCE(
|
|
47
|
+
"adapter_config" -> 'effort',
|
|
48
|
+
"adapter_config" -> 'thinkingEffort',
|
|
49
|
+
"adapter_config" -> 'reasoningEffort',
|
|
50
|
+
"adapter_config" -> 'modelReasoningEffort'
|
|
51
|
+
) IS NULL THEN '{}'::jsonb
|
|
52
|
+
ELSE jsonb_build_object(
|
|
53
|
+
'effort',
|
|
54
|
+
COALESCE(
|
|
55
|
+
"adapter_config" -> 'effort',
|
|
56
|
+
"adapter_config" -> 'thinkingEffort',
|
|
57
|
+
"adapter_config" -> 'reasoningEffort',
|
|
58
|
+
"adapter_config" -> 'modelReasoningEffort'
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
END
|
|
62
|
+
END AS "next_adapter_config"
|
|
63
|
+
FROM "agents"
|
|
64
|
+
WHERE "adapter_type" = 'acpx_local'
|
|
65
|
+
AND lower(COALESCE(NULLIF("adapter_config" ->> 'agent', ''), 'claude')) IN ('claude', 'codex')
|
|
66
|
+
),
|
|
67
|
+
updated_agents AS (
|
|
68
|
+
UPDATE "agents"
|
|
69
|
+
SET
|
|
70
|
+
"adapter_type" = migrated_agents."next_adapter_type",
|
|
71
|
+
"adapter_config" = migrated_agents."next_adapter_config",
|
|
72
|
+
"updated_at" = now()
|
|
73
|
+
FROM migrated_agents
|
|
74
|
+
WHERE "agents"."id" = migrated_agents."id"
|
|
75
|
+
RETURNING
|
|
76
|
+
"agents"."id",
|
|
77
|
+
"agents"."company_id",
|
|
78
|
+
migrated_agents."next_adapter_type"
|
|
79
|
+
),
|
|
80
|
+
cleared_task_sessions AS (
|
|
81
|
+
DELETE FROM "agent_task_sessions"
|
|
82
|
+
USING updated_agents
|
|
83
|
+
WHERE "agent_task_sessions"."agent_id" = updated_agents."id"
|
|
84
|
+
AND "agent_task_sessions"."company_id" = updated_agents."company_id"
|
|
85
|
+
AND "agent_task_sessions"."adapter_type" = 'acpx_local'
|
|
86
|
+
RETURNING "agent_task_sessions"."id"
|
|
87
|
+
)
|
|
88
|
+
UPDATE "agent_runtime_state"
|
|
89
|
+
SET
|
|
90
|
+
"adapter_type" = updated_agents."next_adapter_type",
|
|
91
|
+
"session_id" = NULL,
|
|
92
|
+
"state_json" = '{}'::jsonb,
|
|
93
|
+
"last_error" = NULL,
|
|
94
|
+
"updated_at" = now()
|
|
95
|
+
FROM updated_agents
|
|
96
|
+
WHERE "agent_runtime_state"."agent_id" = updated_agents."id"
|
|
97
|
+
AND "agent_runtime_state"."company_id" = updated_agents."company_id";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
ALTER TABLE "issues" ADD COLUMN IF NOT EXISTS "harness_kind" text;--> statement-breakpoint
|
|
2
|
+
CREATE INDEX IF NOT EXISTS "issues_company_harness_kind_idx" ON "issues" USING btree ("company_id","harness_kind");--> statement-breakpoint
|
|
3
|
+
CREATE TABLE IF NOT EXISTS "company_skill_test_inputs" (
|
|
4
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
5
|
+
"company_id" uuid NOT NULL,
|
|
6
|
+
"skill_id" uuid NOT NULL,
|
|
7
|
+
"name" text NOT NULL,
|
|
8
|
+
"content" text NOT NULL,
|
|
9
|
+
"created_by" text,
|
|
10
|
+
"deleted_at" timestamp with time zone,
|
|
11
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
12
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
13
|
+
);--> statement-breakpoint
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "company_skill_test_runs" (
|
|
15
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
16
|
+
"company_id" uuid NOT NULL,
|
|
17
|
+
"skill_id" uuid NOT NULL,
|
|
18
|
+
"input_id" uuid,
|
|
19
|
+
"input_snapshot" text NOT NULL,
|
|
20
|
+
"skill_version_id" uuid NOT NULL,
|
|
21
|
+
"agent_id" uuid NOT NULL,
|
|
22
|
+
"agent_config_snapshot" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
23
|
+
"issue_id" uuid NOT NULL,
|
|
24
|
+
"status" text DEFAULT 'queued' NOT NULL,
|
|
25
|
+
"output_document_key" text DEFAULT 'output' NOT NULL,
|
|
26
|
+
"output_snapshot" text DEFAULT '' NOT NULL,
|
|
27
|
+
"error" text,
|
|
28
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
29
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
30
|
+
);--> statement-breakpoint
|
|
31
|
+
DO $$ BEGIN
|
|
32
|
+
ALTER TABLE "company_skill_test_inputs" ADD CONSTRAINT "company_skill_test_inputs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
|
|
33
|
+
EXCEPTION
|
|
34
|
+
WHEN duplicate_object THEN null;
|
|
35
|
+
END $$;--> statement-breakpoint
|
|
36
|
+
DO $$ BEGIN
|
|
37
|
+
ALTER TABLE "company_skill_test_inputs" ADD CONSTRAINT "company_skill_test_inputs_skill_id_company_skills_id_fk" FOREIGN KEY ("skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
|
|
38
|
+
EXCEPTION
|
|
39
|
+
WHEN duplicate_object THEN null;
|
|
40
|
+
END $$;--> statement-breakpoint
|
|
41
|
+
DO $$ BEGIN
|
|
42
|
+
ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
|
|
43
|
+
EXCEPTION
|
|
44
|
+
WHEN duplicate_object THEN null;
|
|
45
|
+
END $$;--> statement-breakpoint
|
|
46
|
+
DO $$ BEGIN
|
|
47
|
+
ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_skill_id_company_skills_id_fk" FOREIGN KEY ("skill_id") REFERENCES "public"."company_skills"("id") ON DELETE cascade ON UPDATE no action;
|
|
48
|
+
EXCEPTION
|
|
49
|
+
WHEN duplicate_object THEN null;
|
|
50
|
+
END $$;--> statement-breakpoint
|
|
51
|
+
DO $$ BEGIN
|
|
52
|
+
ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_input_id_company_skill_test_inputs_id_fk" FOREIGN KEY ("input_id") REFERENCES "public"."company_skill_test_inputs"("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_test_runs" ADD CONSTRAINT "company_skill_test_runs_skill_version_id_company_skill_versions_id_fk" FOREIGN KEY ("skill_version_id") REFERENCES "public"."company_skill_versions"("id") ON DELETE restrict ON UPDATE no action;
|
|
58
|
+
EXCEPTION
|
|
59
|
+
WHEN duplicate_object THEN null;
|
|
60
|
+
END $$;--> statement-breakpoint
|
|
61
|
+
DO $$ BEGIN
|
|
62
|
+
ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_agent_id_agents_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agents"("id") ON DELETE restrict ON UPDATE no action;
|
|
63
|
+
EXCEPTION
|
|
64
|
+
WHEN duplicate_object THEN null;
|
|
65
|
+
END $$;--> statement-breakpoint
|
|
66
|
+
DO $$ BEGIN
|
|
67
|
+
ALTER TABLE "company_skill_test_runs" ADD CONSTRAINT "company_skill_test_runs_issue_id_issues_id_fk" FOREIGN KEY ("issue_id") REFERENCES "public"."issues"("id") ON DELETE restrict ON UPDATE no action;
|
|
68
|
+
EXCEPTION
|
|
69
|
+
WHEN duplicate_object THEN null;
|
|
70
|
+
END $$;--> statement-breakpoint
|
|
71
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_inputs_company_skill_name_idx" ON "company_skill_test_inputs" USING btree ("company_id","skill_id","name");--> statement-breakpoint
|
|
72
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_inputs_company_skill_active_idx" ON "company_skill_test_inputs" USING btree ("company_id","skill_id","deleted_at");--> statement-breakpoint
|
|
73
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_skill_created_idx" ON "company_skill_test_runs" USING btree ("company_id","skill_id","created_at");--> statement-breakpoint
|
|
74
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "company_skill_test_runs_company_issue_idx" ON "company_skill_test_runs" USING btree ("company_id","issue_id");--> statement-breakpoint
|
|
75
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_input_created_idx" ON "company_skill_test_runs" USING btree ("company_id","input_id","created_at");--> statement-breakpoint
|
|
76
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_status_idx" ON "company_skill_test_runs" USING btree ("company_id","status");
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "deleted_at" timestamp with time zone;--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "superseded_at" timestamp with time zone;--> statement-breakpoint
|
|
3
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "harness_issue_expires_at" timestamp with time zone;--> statement-breakpoint
|
|
4
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "harness_issue_deleted_at" timestamp with time zone;--> statement-breakpoint
|
|
5
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_runs_company_harness_expires_idx" ON "company_skill_test_runs" USING btree ("company_id","harness_issue_expires_at");
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS "company_skill_test_run_templates" (
|
|
2
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
3
|
+
"company_id" uuid NOT NULL,
|
|
4
|
+
"name" text NOT NULL,
|
|
5
|
+
"description" text,
|
|
6
|
+
"body" text NOT NULL,
|
|
7
|
+
"created_by_agent_id" uuid,
|
|
8
|
+
"created_by_user_id" text,
|
|
9
|
+
"updated_by_agent_id" uuid,
|
|
10
|
+
"updated_by_user_id" text,
|
|
11
|
+
"deleted_at" timestamp with time zone,
|
|
12
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
13
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
14
|
+
);
|
|
15
|
+
--> statement-breakpoint
|
|
16
|
+
DO $$ BEGIN
|
|
17
|
+
ALTER TABLE "company_skill_test_run_templates" ADD CONSTRAINT "company_skill_test_run_templates_company_id_companies_id_fk" FOREIGN KEY ("company_id") REFERENCES "public"."companies"("id") ON DELETE cascade ON UPDATE no action;
|
|
18
|
+
EXCEPTION
|
|
19
|
+
WHEN duplicate_object THEN null;
|
|
20
|
+
END $$;
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
DO $$ BEGIN
|
|
23
|
+
ALTER TABLE "company_skill_test_run_templates" ADD CONSTRAINT "company_skill_test_run_templates_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;
|
|
24
|
+
EXCEPTION
|
|
25
|
+
WHEN duplicate_object THEN null;
|
|
26
|
+
END $$;
|
|
27
|
+
--> statement-breakpoint
|
|
28
|
+
DO $$ BEGIN
|
|
29
|
+
ALTER TABLE "company_skill_test_run_templates" ADD CONSTRAINT "company_skill_test_run_templates_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;
|
|
30
|
+
EXCEPTION
|
|
31
|
+
WHEN duplicate_object THEN null;
|
|
32
|
+
END $$;
|
|
33
|
+
--> statement-breakpoint
|
|
34
|
+
CREATE INDEX IF NOT EXISTS "company_skill_test_run_templates_company_active_idx" ON "company_skill_test_run_templates" USING btree ("company_id","deleted_at","name");
|
|
35
|
+
--> statement-breakpoint
|
|
36
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "template_id" text;
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "template_name" text;
|
|
39
|
+
--> statement-breakpoint
|
|
40
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "template_body" text;
|
|
41
|
+
--> statement-breakpoint
|
|
42
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "rendered_template_body" text;
|
|
43
|
+
--> statement-breakpoint
|
|
44
|
+
ALTER TABLE "company_skill_test_runs" ADD COLUMN IF NOT EXISTS "harness_issue_description" text DEFAULT '' NOT NULL;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
CREATE TABLE IF NOT EXISTS "built_in_managed_resources" (
|
|
2
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
3
|
+
"company_id" uuid NOT NULL,
|
|
4
|
+
"bundle_key" text NOT NULL,
|
|
5
|
+
"resource_kind" text NOT NULL,
|
|
6
|
+
"resource_key" text NOT NULL,
|
|
7
|
+
"resource_id" uuid NOT NULL,
|
|
8
|
+
"stock_version" text NOT NULL,
|
|
9
|
+
"stock_hash" text NOT NULL,
|
|
10
|
+
"defaults_json" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
11
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
12
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
13
|
+
);
|
|
14
|
+
--> statement-breakpoint
|
|
15
|
+
|
|
16
|
+
DO $$
|
|
17
|
+
BEGIN
|
|
18
|
+
IF NOT EXISTS (
|
|
19
|
+
SELECT 1
|
|
20
|
+
FROM "pg_constraint" c
|
|
21
|
+
JOIN "pg_class" t ON t.oid = c.conrelid
|
|
22
|
+
JOIN "pg_namespace" n ON n.oid = t.relnamespace
|
|
23
|
+
WHERE n.nspname = 'public'
|
|
24
|
+
AND t.relname = 'built_in_managed_resources'
|
|
25
|
+
AND c.conname = 'built_in_managed_resources_company_id_companies_id_fk'
|
|
26
|
+
) THEN
|
|
27
|
+
ALTER TABLE "built_in_managed_resources"
|
|
28
|
+
ADD CONSTRAINT "built_in_managed_resources_company_id_companies_id_fk"
|
|
29
|
+
FOREIGN KEY ("company_id") REFERENCES "companies"("id") ON DELETE cascade ON UPDATE no action;
|
|
30
|
+
END IF;
|
|
31
|
+
END $$;
|
|
32
|
+
--> statement-breakpoint
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS "built_in_managed_resources_company_idx"
|
|
35
|
+
ON "built_in_managed_resources" ("company_id");
|
|
36
|
+
--> statement-breakpoint
|
|
37
|
+
|
|
38
|
+
CREATE INDEX IF NOT EXISTS "built_in_managed_resources_resource_idx"
|
|
39
|
+
ON "built_in_managed_resources" ("resource_kind", "resource_id");
|
|
40
|
+
--> statement-breakpoint
|
|
41
|
+
|
|
42
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "built_in_managed_resources_company_bundle_resource_uq"
|
|
43
|
+
ON "built_in_managed_resources" ("company_id", "bundle_key", "resource_kind", "resource_key");
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
CREATE INDEX IF NOT EXISTS "issues_company_updated_idx" ON "issues" ("company_id","updated_at");--> statement-breakpoint
|
|
2
|
+
CREATE INDEX IF NOT EXISTS "issues_company_created_idx" ON "issues" ("company_id","created_at");--> statement-breakpoint
|
|
3
|
+
CREATE INDEX IF NOT EXISTS "issues_company_priority_idx" ON "issues" ("company_id","priority");
|