@vrplatform/kysely 1.3.45-stage.6066 → 1.3.45-stage.607

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 (97) hide show
  1. package/build/.data.tar +0 -0
  2. package/build/main/control-plane/index.d.ts +312 -0
  3. package/build/main/control-plane/index.js.map +1 -1
  4. package/build/main/index.d.ts +13 -2
  5. package/build/main/index.js +217 -23
  6. package/build/main/index.js.map +1 -1
  7. package/build/main/local/generate.js +2 -0
  8. package/build/main/local/generate.js.map +1 -1
  9. package/build/main/local/index.js +110 -8
  10. package/build/main/local/index.js.map +1 -1
  11. package/build/main/postgres-error.d.ts +3 -3
  12. package/build/main/postgres-error.js +4 -3
  13. package/build/main/postgres-error.js.map +1 -1
  14. package/build/main/query/listing/status.js +2 -6
  15. package/build/main/query/listing/status.js.map +1 -1
  16. package/build/main/query/tenant/status.d.ts +1 -1
  17. package/build/main/query/tenant/status.js +6 -4
  18. package/build/main/query/tenant/status.js.map +1 -1
  19. package/build/main/regional.d.ts +1 -0
  20. package/build/main/regional.js +1 -0
  21. package/build/main/regional.js.map +1 -1
  22. package/build/main/test/index.d.ts +23 -3
  23. package/build/main/test/index.js +35 -13
  24. package/build/main/test/index.js.map +1 -1
  25. package/build/main/v1.generated.d.ts +560 -8
  26. package/build/main/v1.generated.js.map +1 -1
  27. package/build/migrations-v2/0000000000015-durable-flow-events.ts +163 -0
  28. package/build/migrations-v2/0000000000016-billing-listing-facts.ts +539 -0
  29. package/build/migrations-v2/0000000000016-managed-team-access.ts +34 -0
  30. package/build/migrations-v2/0000000000017-drop-trial-until.ts +42 -0
  31. package/build/migrations-v2/0000000000017-webhook-secret-reencryption-failures.ts +18 -0
  32. package/build/migrations-v2/0000000000018-accounting-integrity-monitoring.ts +276 -0
  33. package/build/migrations-v2/0000000000018-durable-flow-event-sensitive-input.ts +28 -0
  34. package/build/migrations-v2/0000000000019-accounting-integrity-run-shards.ts +26 -0
  35. package/build/migrations-v2/0000000000019-asynchronous-operations.ts +736 -0
  36. package/build/migrations-v2/0000000000020-accounting-integrity-case-classification.ts +52 -0
  37. package/build/migrations-v2/0000000000021-payment-line-classification-monitor-indexes.ts +31 -0
  38. package/build/migrations-v2/0000000000022-accounting-integrity-controlled-repairs.ts +281 -0
  39. package/build/migrations-v2/0000000000023-line-classification-usage.ts +325 -0
  40. package/build/migrations-v2/0000000000024-tenant-region-migration.ts +108 -0
  41. package/build/migrations-v2/0000000000025-partner-ach-denial-default.ts +30 -0
  42. package/build/migrations-v2/0000000000026-line-classification-usage-capture.ts +399 -0
  43. package/build/migrations-v2/0000000000027-payout-replacement-chain.ts +27 -0
  44. package/build/migrations-v2/0000000000028-accounting-integrity-operator-workflow.ts +108 -0
  45. package/build/migrations-v2/0000000000029-accounting-integrity-definition-artifacts.ts +40 -0
  46. package/build/migrations-v2/0000000000030-accounting-integrity-review-metadata-compatibility.ts +49 -0
  47. package/build/migrations-v2/0000000000031-ui-permission-role-simplification.ts +70 -0
  48. package/build/migrations-v2/0000000000032-tenant-delete-ownership-cascades.ts +44 -0
  49. package/build/migrations-v2/0000000000033-reservation-issue-seed-bucket-index.ts +19 -0
  50. package/build/migrations-v2/0000000000034-retire-recent-classification-indexes.ts +29 -0
  51. package/build/migrations-v2/0000000000035-core-change-autovacuum.ts +24 -0
  52. package/build/migrations-v2/0000000000036-journal-entry-inactive-reason-constraint.ts +33 -0
  53. package/build/migrations-v2/0000000000037-journal-entry-inactive-reasons.ts +19 -0
  54. package/build/migrations-v2/0000000000038-journal-entry-group-inactive-reason.ts +14 -0
  55. package/build/migrations-v2/0000000000039-reservation-guest-breakdown.ts +19 -0
  56. package/build/migrations-v2/0000000000040-csv-import-source-identity-index.ts +23 -0
  57. package/build/migrations-v2/0000000000041-payment-returns.ts +38 -0
  58. package/build/migrations-v2/0000000000042-operation-resource-types.ts +609 -0
  59. package/build/migrations-v2/0000000000043-reservation-journal-freshness.ts +149 -0
  60. package/build/migrations-v2/0000000000044-reservation-journal-freshness-backfill.ts +254 -0
  61. package/build/migrations-v2/0000000000045-reservation-journal-freshness-revision-repair.ts +83 -0
  62. package/build/migrations-v2/0000000000046-materialized-reservation-journal-operations.ts +709 -0
  63. package/build/migrations-v2/0000000000047-public-audit-completion.ts +77 -0
  64. package/build/migrations-v2/0000000000048-reservation-journal-full-refresh-repair.ts +136 -0
  65. package/build/migrations-v2/0000000000049-queued-journal-operation-failures.ts +60 -0
  66. package/build/migrations-v2/0000000000050-connection-oauth-state.ts +43 -0
  67. package/build/migrations-v2/0000000000051-owner-statement-email-delivery.ts +134 -0
  68. package/build/migrations-v2/0000000000052-fee-journal-lock-skip-operations.ts +59 -0
  69. package/build/migrations-v2/0000000000053-fee-journal-lock-skip-null-attempt.ts +44 -0
  70. package/build/migrations-v2/0000000000054-journal-refresh-issue-codes.ts +16 -0
  71. package/build/migrations-v2/0000000000055-tenant-billing-subscription.ts +8 -0
  72. package/build/module/control-plane/index.d.ts +312 -0
  73. package/build/module/control-plane/index.js.map +1 -1
  74. package/build/module/index.d.ts +13 -2
  75. package/build/module/index.js +219 -24
  76. package/build/module/index.js.map +1 -1
  77. package/build/module/local/generate.js +2 -0
  78. package/build/module/local/generate.js.map +1 -1
  79. package/build/module/local/index.js +110 -8
  80. package/build/module/local/index.js.map +1 -1
  81. package/build/module/postgres-error.d.ts +3 -3
  82. package/build/module/postgres-error.js +4 -3
  83. package/build/module/postgres-error.js.map +1 -1
  84. package/build/module/query/listing/status.js +2 -6
  85. package/build/module/query/listing/status.js.map +1 -1
  86. package/build/module/query/tenant/status.d.ts +1 -1
  87. package/build/module/query/tenant/status.js +6 -4
  88. package/build/module/query/tenant/status.js.map +1 -1
  89. package/build/module/regional.d.ts +1 -0
  90. package/build/module/regional.js +1 -0
  91. package/build/module/regional.js.map +1 -1
  92. package/build/module/test/index.d.ts +23 -3
  93. package/build/module/test/index.js +34 -13
  94. package/build/module/test/index.js.map +1 -1
  95. package/build/module/v1.generated.d.ts +560 -8
  96. package/build/module/v1.generated.js.map +1 -1
  97. package/package.json +4 -2
@@ -0,0 +1,609 @@
1
+ import type { Kysely } from 'kysely';
2
+ import { sql } from 'kysely';
3
+
4
+ async function replaceStatusFunctions(
5
+ db: Kysely<unknown>,
6
+ statusType: 'core.operation_status' | 'text'
7
+ ) {
8
+ const cast = statusType === 'text' ? sql`` : sql`::core.operation_status`;
9
+
10
+ await sql`
11
+ create or replace function core.refresh_operation_state(target_operation_id uuid)
12
+ returns void
13
+ language plpgsql
14
+ as $$
15
+ declare
16
+ next_status ${sql.raw(statusType)};
17
+ next_started_at timestamptz;
18
+ next_finished_at timestamptz;
19
+ begin
20
+ select
21
+ case
22
+ when count(*) filter (where required) = 0 then 'queued'
23
+ when bool_and(status = 'completed') filter (where required)
24
+ then 'completed'
25
+ when bool_and(status in ('completed', 'failed')) filter (where required)
26
+ then 'failed'
27
+ when bool_or(status = 'running') filter (where required)
28
+ or bool_or(status in ('completed', 'failed')) filter (where required)
29
+ then 'running'
30
+ else 'queued'
31
+ end${cast},
32
+ min(started_at) filter (where required),
33
+ max(finished_at) filter (where required)
34
+ into next_status, next_started_at, next_finished_at
35
+ from core.operation_source
36
+ where operation_id = target_operation_id;
37
+
38
+ update core.operation
39
+ set
40
+ status = next_status,
41
+ started_at = coalesce(core.operation.started_at, next_started_at),
42
+ finished_at = case
43
+ when next_status in ('completed', 'failed')
44
+ then coalesce(next_finished_at, now())
45
+ else null
46
+ end,
47
+ failure_code = case when next_status = 'failed' then 'operation_failed' end,
48
+ failure_message = case when next_status = 'failed' then 'Operation failed' end,
49
+ updated_at = now(),
50
+ source_version = source_version + 1
51
+ where id = target_operation_id
52
+ and (
53
+ status is distinct from next_status
54
+ or started_at is distinct from coalesce(started_at, next_started_at)
55
+ or finished_at is distinct from case
56
+ when next_status in ('completed', 'failed')
57
+ then coalesce(next_finished_at, finished_at, now())
58
+ else null
59
+ end
60
+ );
61
+ end;
62
+ $$
63
+ `.execute(db);
64
+
65
+ await sql`
66
+ create or replace function core.refresh_audit_action_source(target_action_id uuid)
67
+ returns void
68
+ language plpgsql
69
+ as $$
70
+ declare
71
+ target_operation_id uuid;
72
+ begin
73
+ update core.operation_source as source
74
+ set
75
+ status = state.status,
76
+ started_at = state.started_at,
77
+ finished_at = state.finished_at,
78
+ source_version = source.source_version + 1
79
+ from (
80
+ select
81
+ case
82
+ when count(*) = 0 then 'completed'
83
+ when bool_and(effect.status = 'completed') then 'completed'
84
+ when bool_and(
85
+ effect.status in ('completed', 'dead_letter')
86
+ or (
87
+ effect.status = 'failed'
88
+ and effect.retry_count >= effect.max_retries
89
+ )
90
+ ) then 'failed'
91
+ when bool_or(effect.status in ('claimed', 'running'))
92
+ or bool_or(
93
+ effect.status in ('completed', 'dead_letter')
94
+ or (
95
+ effect.status = 'failed'
96
+ and effect.retry_count >= effect.max_retries
97
+ )
98
+ ) then 'running'
99
+ else 'queued'
100
+ end${cast} as status,
101
+ case
102
+ when count(*) = 0 then now()
103
+ else min(coalesce(effect.last_attempt_at, effect.claimed_at))
104
+ end as started_at,
105
+ case
106
+ when count(*) = 0 then now()
107
+ when bool_and(
108
+ effect.status in ('completed', 'dead_letter')
109
+ or (
110
+ effect.status = 'failed'
111
+ and effect.retry_count >= effect.max_retries
112
+ )
113
+ ) then coalesce(
114
+ max(coalesce(effect.completed_at, effect.last_attempt_at)),
115
+ now()
116
+ )
117
+ end as finished_at
118
+ from audit.effect
119
+ where action_id = target_action_id
120
+ ) as state
121
+ where source.source_type = 'audit-action'
122
+ and source.source_id = target_action_id
123
+ and (
124
+ source.status is distinct from state.status
125
+ or source.started_at is distinct from state.started_at
126
+ or source.finished_at is distinct from state.finished_at
127
+ );
128
+
129
+ for target_operation_id in
130
+ select operation_id
131
+ from core.operation_source
132
+ where source_type = 'audit-action'
133
+ and source_id = target_action_id
134
+ loop
135
+ perform core.refresh_operation_state(target_operation_id);
136
+ end loop;
137
+ end;
138
+ $$
139
+ `.execute(db);
140
+
141
+ await sql`
142
+ create or replace function core.refresh_sync_operation()
143
+ returns trigger
144
+ language plpgsql
145
+ as $$
146
+ declare
147
+ target_operation_id uuid;
148
+ begin
149
+ update core.operation_source as source
150
+ set
151
+ status = case
152
+ when new.status = 'started' then 'running'
153
+ when new.status = 'completed' then 'completed'
154
+ when new.status in ('failed', 'canceled') then 'failed'
155
+ else 'queued'
156
+ end${cast},
157
+ started_at = case
158
+ when new.status = 'started'
159
+ then coalesce(source.started_at, new.updated_at)
160
+ else source.started_at
161
+ end,
162
+ finished_at = case
163
+ when new.status in ('completed', 'failed', 'canceled')
164
+ then coalesce(new.synced_at, new.updated_at, now())
165
+ end,
166
+ source_version = source.source_version + 1
167
+ where source.source_type = 'sync'
168
+ and source.source_id = new.id;
169
+
170
+ for target_operation_id in
171
+ select operation_id
172
+ from core.operation_source
173
+ where source_type = 'sync' and source_id = new.id
174
+ loop
175
+ perform core.refresh_operation_state(target_operation_id);
176
+ end loop;
177
+ return new;
178
+ end;
179
+ $$
180
+ `.execute(db);
181
+
182
+ await sql`
183
+ create or replace function core.refresh_webhook_delivery_operation()
184
+ returns trigger
185
+ language plpgsql
186
+ as $$
187
+ declare
188
+ target_operation_id uuid;
189
+ begin
190
+ update core.operation_source as source
191
+ set
192
+ status = case
193
+ when new.status in ('queued', 'retrying') then 'queued'
194
+ when new.status = 'delivering' then 'running'
195
+ when new.status = 'succeeded' then 'completed'
196
+ else 'failed'
197
+ end${cast},
198
+ started_at = case
199
+ when new.status = 'delivering'
200
+ then coalesce(source.started_at, new.claimed_at, new.updated_at)
201
+ else source.started_at
202
+ end,
203
+ finished_at = case
204
+ when new.status = 'succeeded'
205
+ then coalesce(new.delivered_at, new.updated_at, now())
206
+ when new.status in ('failed', 'canceled')
207
+ then coalesce(new.failed_at, new.updated_at, now())
208
+ end,
209
+ source_version = source.source_version + 1
210
+ where source.source_type = 'webhook-delivery'
211
+ and source.source_id = new.id;
212
+
213
+ for target_operation_id in
214
+ select operation_id
215
+ from core.operation_source
216
+ where source_type = 'webhook-delivery' and source_id = new.id
217
+ loop
218
+ perform core.refresh_operation_state(target_operation_id);
219
+ end loop;
220
+ return new;
221
+ end;
222
+ $$
223
+ `.execute(db);
224
+ }
225
+
226
+ export async function up(db: Kysely<unknown>): Promise<void> {
227
+ await sql`
228
+ create type core.operation_type as enum (
229
+ 'ach-verification',
230
+ 'bank-rule-run',
231
+ 'calendar-block',
232
+ 'calendar-unblock',
233
+ 'connection-archive',
234
+ 'connection-connect',
235
+ 'connection-extract',
236
+ 'connection-sync',
237
+ 'csv-import',
238
+ 'csv-import-preview',
239
+ 'export',
240
+ 'flow-run',
241
+ 'historical-gl-import',
242
+ 'historical-statement-import',
243
+ 'listing-journal-refresh',
244
+ 'plaid-initial-sync',
245
+ 'pms-cutover',
246
+ 'pms-cutover-preview',
247
+ 'provider-payment',
248
+ 'provider-payment-recovery',
249
+ 'recurring-transaction-run',
250
+ 'reservation-journal-refresh',
251
+ 'team-delete',
252
+ 'team-demo-data',
253
+ 'team-duplicate',
254
+ 'team-initialize',
255
+ 'transaction-journal-refresh',
256
+ 'vri-statement-import',
257
+ 'vri-team-migration',
258
+ 'webhook-test'
259
+ )
260
+ `.execute(db);
261
+ await sql`
262
+ create type core.operation_status as enum (
263
+ 'queued',
264
+ 'running',
265
+ 'completed',
266
+ 'failed'
267
+ )
268
+ `.execute(db);
269
+ await sql`
270
+ create type core.operation_source_type as enum (
271
+ 'audit-action',
272
+ 'export-job',
273
+ 'sync',
274
+ 'webhook-delivery'
275
+ )
276
+ `.execute(db);
277
+ await sql`
278
+ create type core.operation_resource_type as enum (
279
+ 'bank-rule',
280
+ 'connection',
281
+ 'contact',
282
+ 'file',
283
+ 'flow',
284
+ 'listing',
285
+ 'recurring-fee',
286
+ 'recurring-transaction-template',
287
+ 'reservation',
288
+ 'statement',
289
+ 'team',
290
+ 'transaction',
291
+ 'webhook'
292
+ )
293
+ `.execute(db);
294
+ await sql`
295
+ create type core.operation_resource_role as enum (
296
+ 'source',
297
+ 'target',
298
+ 'result'
299
+ )
300
+ `.execute(db);
301
+ await sql`
302
+ create type core.csv_operation_result_kind as enum ('import', 'preview')
303
+ `.execute(db);
304
+ await sql`
305
+ create type core.csv_operation_result_status as enum (
306
+ 'queued',
307
+ 'processing',
308
+ 'completed',
309
+ 'failed'
310
+ )
311
+ `.execute(db);
312
+ await sql`
313
+ create type core.async_operation_result_status as enum (
314
+ 'queued',
315
+ 'completed',
316
+ 'failed'
317
+ )
318
+ `.execute(db);
319
+ await sql`
320
+ create type core.export_job_format as enum ('csv', 'pdf', 'zip')
321
+ `.execute(db);
322
+ await sql`
323
+ create type core.export_job_task_id as enum (
324
+ 'api/export-route',
325
+ 'api/export-journal-entries-csv',
326
+ 'api/export-manager-statement-pdf',
327
+ 'api/export-owner-statement-combined-csv',
328
+ 'api/export-owner-statement-pdf',
329
+ 'api/export-owner-statement-pdf-batch-zip',
330
+ 'api/export-owner-statement-summary-pdf',
331
+ 'api/export-owner-statement-summary-pdf-batch-zip',
332
+ 'api/export-trust-reconciliation-pdf'
333
+ )
334
+ `.execute(db);
335
+
336
+ await sql`
337
+ alter table core.operation
338
+ drop constraint operation_type_check,
339
+ drop constraint operation_status_check,
340
+ drop constraint operation_failure_check,
341
+ drop constraint operation_finished_check,
342
+ alter column status drop default
343
+ `.execute(db);
344
+ await sql`
345
+ alter table core.operation
346
+ alter column type type core.operation_type using type::core.operation_type,
347
+ alter column status type core.operation_status using status::core.operation_status,
348
+ alter column status set default 'queued'::core.operation_status,
349
+ add constraint operation_failure_check check (
350
+ (status = 'failed' and failure_code is not null and failure_message is not null)
351
+ or (status != 'failed' and failure_code is null and failure_message is null)
352
+ ),
353
+ add constraint operation_finished_check check (
354
+ (status in ('completed', 'failed') and finished_at is not null)
355
+ or (status in ('queued', 'running') and finished_at is null)
356
+ )
357
+ `.execute(db);
358
+
359
+ await sql`
360
+ alter table core.operation_source
361
+ drop constraint operation_source_type_check,
362
+ drop constraint operation_source_status_check,
363
+ drop constraint operation_source_finished_check,
364
+ alter column status drop default
365
+ `.execute(db);
366
+ await sql`
367
+ alter table core.operation_source
368
+ alter column source_type type core.operation_source_type
369
+ using source_type::core.operation_source_type,
370
+ alter column status type core.operation_status using status::core.operation_status,
371
+ alter column status set default 'queued'::core.operation_status,
372
+ add constraint operation_source_finished_check check (
373
+ (status in ('completed', 'failed') and finished_at is not null)
374
+ or (status in ('queued', 'running') and finished_at is null)
375
+ )
376
+ `.execute(db);
377
+
378
+ await sql`
379
+ alter table core.operation_resource
380
+ drop constraint operation_resource_type_check,
381
+ drop constraint operation_resource_role_check,
382
+ alter column resource_type type core.operation_resource_type
383
+ using resource_type::core.operation_resource_type,
384
+ alter column role type core.operation_resource_role
385
+ using role::core.operation_resource_role
386
+ `.execute(db);
387
+
388
+ await sql`
389
+ alter table core.csv_operation_result
390
+ drop constraint csv_operation_result_kind_check,
391
+ drop constraint csv_operation_result_status_check,
392
+ drop constraint csv_operation_result_terminal_check,
393
+ alter column status drop default
394
+ `.execute(db);
395
+ await sql`
396
+ alter table core.csv_operation_result
397
+ alter column kind type core.csv_operation_result_kind
398
+ using kind::core.csv_operation_result_kind,
399
+ alter column status type core.csv_operation_result_status
400
+ using status::core.csv_operation_result_status,
401
+ alter column status set default 'queued'::core.csv_operation_result_status,
402
+ add constraint csv_operation_result_terminal_check check (
403
+ (status = 'completed' and result is not null and error_message is null)
404
+ or (status = 'failed' and error_message is not null)
405
+ or (status in ('queued', 'processing') and result is null and error_message is null)
406
+ )
407
+ `.execute(db);
408
+
409
+ await sql`
410
+ alter table core.async_operation_result
411
+ drop constraint async_operation_result_status_check,
412
+ drop constraint async_operation_result_terminal_check,
413
+ alter column status drop default
414
+ `.execute(db);
415
+ await sql`
416
+ alter table core.async_operation_result
417
+ alter column type type core.operation_type using type::core.operation_type,
418
+ alter column status type core.async_operation_result_status
419
+ using status::core.async_operation_result_status,
420
+ alter column status set default 'queued'::core.async_operation_result_status,
421
+ add constraint async_operation_result_terminal_check check (
422
+ (status = 'completed' and result is not null and error_message is null)
423
+ or (status = 'failed' and error_message is not null)
424
+ or (status = 'queued' and result is null and error_message is null)
425
+ )
426
+ `.execute(db);
427
+
428
+ await sql`
429
+ alter table core.export_job
430
+ drop constraint export_job_format_check,
431
+ drop constraint export_job_status_check,
432
+ drop constraint export_job_terminal_check,
433
+ alter column status drop default
434
+ `.execute(db);
435
+ await sql`
436
+ drop trigger refresh_export_job_operation on core.export_job
437
+ `.execute(db);
438
+ await sql`
439
+ alter table core.export_job
440
+ alter column task_id type core.export_job_task_id using task_id::core.export_job_task_id,
441
+ alter column format type core.export_job_format using format::core.export_job_format,
442
+ alter column status type core.operation_status using status::core.operation_status,
443
+ alter column status set default 'queued'::core.operation_status,
444
+ add constraint export_job_terminal_check check (
445
+ (status = 'completed' and finished_at is not null and error_message is null)
446
+ or (status = 'failed' and finished_at is not null and error_message is not null)
447
+ or (status in ('queued', 'running') and finished_at is null and error_message is null)
448
+ )
449
+ `.execute(db);
450
+
451
+ await replaceStatusFunctions(db, 'core.operation_status');
452
+ await sql`
453
+ create trigger refresh_export_job_operation
454
+ after insert or update of status, started_at, finished_at
455
+ on core.export_job
456
+ for each row execute function core.refresh_export_job_operation()
457
+ `.execute(db);
458
+ }
459
+
460
+ export async function down(db: Kysely<unknown>): Promise<void> {
461
+ await sql`
462
+ alter table core.operation
463
+ drop constraint operation_failure_check,
464
+ drop constraint operation_finished_check,
465
+ alter column status drop default
466
+ `.execute(db);
467
+ await sql`
468
+ alter table core.operation
469
+ alter column type type text using type::text,
470
+ alter column status type text using status::text,
471
+ alter column status set default 'queued',
472
+ add constraint operation_type_check check (type in (
473
+ 'ach-verification', 'bank-rule-run', 'calendar-block', 'calendar-unblock',
474
+ 'connection-archive', 'connection-connect', 'connection-extract',
475
+ 'connection-sync', 'csv-import', 'csv-import-preview', 'export', 'flow-run',
476
+ 'historical-gl-import', 'historical-statement-import',
477
+ 'listing-journal-refresh', 'plaid-initial-sync', 'pms-cutover',
478
+ 'pms-cutover-preview', 'provider-payment', 'provider-payment-recovery',
479
+ 'recurring-transaction-run', 'reservation-journal-refresh', 'team-demo-data',
480
+ 'team-duplicate', 'team-initialize', 'transaction-journal-refresh',
481
+ 'vri-statement-import', 'vri-team-migration', 'webhook-test'
482
+ )),
483
+ add constraint operation_status_check
484
+ check (status in ('queued', 'running', 'completed', 'failed')),
485
+ add constraint operation_failure_check check (
486
+ (status = 'failed' and failure_code is not null and failure_message is not null)
487
+ or (status != 'failed' and failure_code is null and failure_message is null)
488
+ ),
489
+ add constraint operation_finished_check check (
490
+ (status in ('completed', 'failed') and finished_at is not null)
491
+ or (status in ('queued', 'running') and finished_at is null)
492
+ )
493
+ `.execute(db);
494
+
495
+ await sql`
496
+ alter table core.operation_source
497
+ drop constraint operation_source_finished_check,
498
+ alter column status drop default
499
+ `.execute(db);
500
+ await sql`
501
+ alter table core.operation_source
502
+ alter column source_type type text using source_type::text,
503
+ alter column status type text using status::text,
504
+ alter column status set default 'queued',
505
+ add constraint operation_source_type_check check (source_type in (
506
+ 'audit-action', 'export-job', 'sync', 'webhook-delivery'
507
+ )),
508
+ add constraint operation_source_status_check
509
+ check (status in ('queued', 'running', 'completed', 'failed')),
510
+ add constraint operation_source_finished_check check (
511
+ (status in ('completed', 'failed') and finished_at is not null)
512
+ or (status in ('queued', 'running') and finished_at is null)
513
+ )
514
+ `.execute(db);
515
+
516
+ await sql`
517
+ alter table core.operation_resource
518
+ alter column resource_type type text using resource_type::text,
519
+ alter column role type text using role::text,
520
+ add constraint operation_resource_type_check check (resource_type in (
521
+ 'bank-rule', 'connection', 'contact', 'file', 'flow', 'listing',
522
+ 'recurring-transaction-template', 'statement', 'team', 'transaction', 'webhook'
523
+ )),
524
+ add constraint operation_resource_role_check
525
+ check (role in ('source', 'target', 'result'))
526
+ `.execute(db);
527
+
528
+ await sql`
529
+ alter table core.csv_operation_result
530
+ drop constraint csv_operation_result_terminal_check,
531
+ alter column status drop default
532
+ `.execute(db);
533
+ await sql`
534
+ alter table core.csv_operation_result
535
+ alter column kind type text using kind::text,
536
+ alter column status type text using status::text,
537
+ alter column status set default 'queued',
538
+ add constraint csv_operation_result_kind_check check (kind in ('import', 'preview')),
539
+ add constraint csv_operation_result_status_check
540
+ check (status in ('queued', 'processing', 'completed', 'failed')),
541
+ add constraint csv_operation_result_terminal_check check (
542
+ (status = 'completed' and result is not null and error_message is null)
543
+ or (status = 'failed' and error_message is not null)
544
+ or (status in ('queued', 'processing') and result is null and error_message is null)
545
+ )
546
+ `.execute(db);
547
+
548
+ await sql`
549
+ alter table core.async_operation_result
550
+ drop constraint async_operation_result_terminal_check,
551
+ alter column status drop default
552
+ `.execute(db);
553
+ await sql`
554
+ alter table core.async_operation_result
555
+ alter column type type text using type::text,
556
+ alter column status type text using status::text,
557
+ alter column status set default 'queued',
558
+ add constraint async_operation_result_status_check
559
+ check (status in ('queued', 'completed', 'failed')),
560
+ add constraint async_operation_result_terminal_check check (
561
+ (status = 'completed' and result is not null and error_message is null)
562
+ or (status = 'failed' and error_message is not null)
563
+ or (status = 'queued' and result is null and error_message is null)
564
+ )
565
+ `.execute(db);
566
+
567
+ await sql`
568
+ alter table core.export_job
569
+ drop constraint export_job_terminal_check,
570
+ alter column status drop default
571
+ `.execute(db);
572
+ await sql`
573
+ drop trigger refresh_export_job_operation on core.export_job
574
+ `.execute(db);
575
+ await sql`
576
+ alter table core.export_job
577
+ alter column task_id type text using task_id::text,
578
+ alter column format type text using format::text,
579
+ alter column status type text using status::text,
580
+ alter column status set default 'queued',
581
+ add constraint export_job_format_check check (format in ('csv', 'pdf', 'zip')),
582
+ add constraint export_job_status_check
583
+ check (status in ('queued', 'running', 'completed', 'failed')),
584
+ add constraint export_job_terminal_check check (
585
+ (status = 'completed' and finished_at is not null and error_message is null)
586
+ or (status = 'failed' and finished_at is not null and error_message is not null)
587
+ or (status in ('queued', 'running') and finished_at is null and error_message is null)
588
+ )
589
+ `.execute(db);
590
+
591
+ await replaceStatusFunctions(db, 'text');
592
+ await sql`
593
+ create trigger refresh_export_job_operation
594
+ after insert or update of status, started_at, finished_at
595
+ on core.export_job
596
+ for each row execute function core.refresh_export_job_operation()
597
+ `.execute(db);
598
+
599
+ await sql`drop type core.export_job_task_id`.execute(db);
600
+ await sql`drop type core.export_job_format`.execute(db);
601
+ await sql`drop type core.async_operation_result_status`.execute(db);
602
+ await sql`drop type core.csv_operation_result_status`.execute(db);
603
+ await sql`drop type core.csv_operation_result_kind`.execute(db);
604
+ await sql`drop type core.operation_resource_role`.execute(db);
605
+ await sql`drop type core.operation_resource_type`.execute(db);
606
+ await sql`drop type core.operation_source_type`.execute(db);
607
+ await sql`drop type core.operation_status`.execute(db);
608
+ await sql`drop type core.operation_type`.execute(db);
609
+ }