@vrplatform/kysely 1.3.45-6090 → 1.3.45-61
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/build/.data.tar +0 -0
- package/build/main/control-plane/index.d.ts +175 -0
- package/build/main/control-plane/index.js.map +1 -1
- package/build/main/index.d.ts +2 -2
- package/build/main/index.js +111 -22
- package/build/main/index.js.map +1 -1
- package/build/main/local/generate.js +2 -0
- package/build/main/local/generate.js.map +1 -1
- package/build/main/local/index.js +12 -0
- package/build/main/local/index.js.map +1 -1
- package/build/main/query/listing/status.js +2 -6
- package/build/main/query/listing/status.js.map +1 -1
- package/build/main/query/tenant/status.js +2 -2
- package/build/main/query/tenant/status.js.map +1 -1
- package/build/main/test/index.d.ts +0 -3
- package/build/main/test/index.js +0 -9
- package/build/main/test/index.js.map +1 -1
- package/build/main/v1.generated.d.ts +253 -2
- package/build/main/v1.generated.js.map +1 -1
- package/build/migrations-v2/0000000000015-durable-flow-events.ts +163 -0
- package/build/migrations-v2/0000000000016-billing-listing-facts.ts +539 -0
- package/build/migrations-v2/0000000000016-managed-team-access.ts +34 -0
- package/build/migrations-v2/0000000000017-drop-trial-until.ts +42 -0
- package/build/migrations-v2/0000000000017-webhook-secret-reencryption-failures.ts +18 -0
- package/build/migrations-v2/0000000000018-accounting-integrity-monitoring.ts +276 -0
- package/build/migrations-v2/0000000000018-durable-flow-event-sensitive-input.ts +28 -0
- package/build/migrations-v2/0000000000019-accounting-integrity-run-shards.ts +26 -0
- package/build/migrations-v2/0000000000019-asynchronous-operations.ts +736 -0
- package/build/migrations-v2/0000000000020-accounting-integrity-case-classification.ts +52 -0
- package/build/migrations-v2/0000000000021-payment-line-classification-monitor-indexes.ts +31 -0
- package/build/migrations-v2/0000000000022-accounting-integrity-controlled-repairs.ts +281 -0
- package/build/migrations-v2/0000000000023-line-classification-usage.ts +325 -0
- package/build/migrations-v2/0000000000024-tenant-region-migration.ts +108 -0
- package/build/migrations-v2/0000000000025-partner-ach-denial-default.ts +30 -0
- package/build/migrations-v2/0000000000026-line-classification-usage-capture.ts +399 -0
- package/build/migrations-v2/0000000000027-payout-replacement-chain.ts +27 -0
- package/build/migrations-v2/0000000000028-accounting-integrity-operator-workflow.ts +108 -0
- package/build/migrations-v2/0000000000029-accounting-integrity-definition-artifacts.ts +40 -0
- package/build/migrations-v2/0000000000030-accounting-integrity-review-metadata-compatibility.ts +49 -0
- package/build/migrations-v2/0000000000031-ui-permission-role-simplification.ts +70 -0
- package/build/migrations-v2/0000000000032-tenant-delete-ownership-cascades.ts +44 -0
- package/build/module/control-plane/index.d.ts +175 -0
- package/build/module/control-plane/index.js.map +1 -1
- package/build/module/index.d.ts +2 -2
- package/build/module/index.js +113 -23
- package/build/module/index.js.map +1 -1
- package/build/module/local/generate.js +2 -0
- package/build/module/local/generate.js.map +1 -1
- package/build/module/local/index.js +12 -0
- package/build/module/local/index.js.map +1 -1
- package/build/module/query/listing/status.js +2 -6
- package/build/module/query/listing/status.js.map +1 -1
- package/build/module/query/tenant/status.js +2 -2
- package/build/module/query/tenant/status.js.map +1 -1
- package/build/module/test/index.d.ts +0 -3
- package/build/module/test/index.js +0 -9
- package/build/module/test/index.js.map +1 -1
- package/build/module/v1.generated.d.ts +253 -2
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Kysely, sql } from 'kysely';
|
|
2
|
+
|
|
3
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
+
await sql`
|
|
5
|
+
create type health.accounting_integrity_urgency as enum (
|
|
6
|
+
'immediate',
|
|
7
|
+
'next_triage',
|
|
8
|
+
'backlog',
|
|
9
|
+
'none'
|
|
10
|
+
)
|
|
11
|
+
`.execute(db);
|
|
12
|
+
await sql`
|
|
13
|
+
create type health.accounting_integrity_confidence as enum (
|
|
14
|
+
'proven',
|
|
15
|
+
'probable',
|
|
16
|
+
'unknown'
|
|
17
|
+
)
|
|
18
|
+
`.execute(db);
|
|
19
|
+
await sql`
|
|
20
|
+
alter table health.accounting_integrity_case
|
|
21
|
+
add column urgency health.accounting_integrity_urgency,
|
|
22
|
+
add column confidence health.accounting_integrity_confidence
|
|
23
|
+
`.execute(db);
|
|
24
|
+
await sql`
|
|
25
|
+
update health.accounting_integrity_case
|
|
26
|
+
set
|
|
27
|
+
urgency = case
|
|
28
|
+
when severity = 'info'
|
|
29
|
+
then 'none'::health.accounting_integrity_urgency
|
|
30
|
+
when nullif(impact -> 'modifiedAt' ->> 'latest', '')::timestamptz >=
|
|
31
|
+
now() - interval '28 days'
|
|
32
|
+
then 'next_triage'::health.accounting_integrity_urgency
|
|
33
|
+
else 'backlog'::health.accounting_integrity_urgency
|
|
34
|
+
end,
|
|
35
|
+
confidence = 'probable'::health.accounting_integrity_confidence
|
|
36
|
+
`.execute(db);
|
|
37
|
+
await sql`
|
|
38
|
+
alter table health.accounting_integrity_case
|
|
39
|
+
alter column urgency set not null,
|
|
40
|
+
alter column confidence set not null
|
|
41
|
+
`.execute(db);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
45
|
+
await sql`
|
|
46
|
+
alter table health.accounting_integrity_case
|
|
47
|
+
drop column confidence,
|
|
48
|
+
drop column urgency
|
|
49
|
+
`.execute(db);
|
|
50
|
+
await sql`drop type health.accounting_integrity_confidence`.execute(db);
|
|
51
|
+
await sql`drop type health.accounting_integrity_urgency`.execute(db);
|
|
52
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import { sql } from 'kysely';
|
|
3
|
+
|
|
4
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
5
|
+
await sql`
|
|
6
|
+
create index if not exists payment_line_recent_classification_idx
|
|
7
|
+
on public.payment_line (updated_at, type2)
|
|
8
|
+
include (payment_id, reservation_id)
|
|
9
|
+
where type2 is not null and type2 != 'deviation'
|
|
10
|
+
`.execute(db);
|
|
11
|
+
|
|
12
|
+
await sql`
|
|
13
|
+
create index if not exists transaction_line_recent_classification_idx
|
|
14
|
+
on accounting.transaction_line (
|
|
15
|
+
updated_at,
|
|
16
|
+
match_line_type_classification
|
|
17
|
+
)
|
|
18
|
+
where match_line_type_classification is not null
|
|
19
|
+
`.execute(db);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
23
|
+
await sql`
|
|
24
|
+
drop index if exists
|
|
25
|
+
accounting.transaction_line_recent_classification_idx
|
|
26
|
+
`.execute(db);
|
|
27
|
+
|
|
28
|
+
await sql`
|
|
29
|
+
drop index if exists public.payment_line_recent_classification_idx
|
|
30
|
+
`.execute(db);
|
|
31
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { type Kysely, sql } from 'kysely';
|
|
2
|
+
|
|
3
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
4
|
+
await sql`
|
|
5
|
+
alter table health.accounting_integrity_run
|
|
6
|
+
add column scope_tenant_ids uuid[],
|
|
7
|
+
add column resolves_cases boolean not null default true,
|
|
8
|
+
add constraint accounting_integrity_run_scope_tenant_ids_check
|
|
9
|
+
check (
|
|
10
|
+
scope_tenant_ids is null or cardinality(scope_tenant_ids) > 0
|
|
11
|
+
)
|
|
12
|
+
`.execute(db);
|
|
13
|
+
|
|
14
|
+
await sql`
|
|
15
|
+
create type health.accounting_integrity_repair_plan_status as enum (
|
|
16
|
+
'draft',
|
|
17
|
+
'active',
|
|
18
|
+
'paused',
|
|
19
|
+
'failed',
|
|
20
|
+
'completed',
|
|
21
|
+
'canceled'
|
|
22
|
+
)
|
|
23
|
+
`.execute(db);
|
|
24
|
+
await sql`
|
|
25
|
+
create type health.accounting_integrity_repair_stage_status as enum (
|
|
26
|
+
'planned',
|
|
27
|
+
'dry_run_passed',
|
|
28
|
+
'approved',
|
|
29
|
+
'applying',
|
|
30
|
+
'verifying',
|
|
31
|
+
'verified',
|
|
32
|
+
'paused',
|
|
33
|
+
'failed',
|
|
34
|
+
'canceled'
|
|
35
|
+
)
|
|
36
|
+
`.execute(db);
|
|
37
|
+
await sql`
|
|
38
|
+
create type health.accounting_integrity_repair_scope_type as enum (
|
|
39
|
+
'case',
|
|
40
|
+
'tenant'
|
|
41
|
+
)
|
|
42
|
+
`.execute(db);
|
|
43
|
+
await sql`
|
|
44
|
+
create type health.accounting_integrity_repair_target_status as enum (
|
|
45
|
+
'pending',
|
|
46
|
+
'applying',
|
|
47
|
+
'applied',
|
|
48
|
+
'verifying',
|
|
49
|
+
'verified',
|
|
50
|
+
'paused',
|
|
51
|
+
'failed',
|
|
52
|
+
'canceled'
|
|
53
|
+
)
|
|
54
|
+
`.execute(db);
|
|
55
|
+
await sql`
|
|
56
|
+
create type health.accounting_integrity_repair_transition_type as enum (
|
|
57
|
+
'plan_created',
|
|
58
|
+
'plan_activated',
|
|
59
|
+
'dry_run_passed',
|
|
60
|
+
'approval_granted',
|
|
61
|
+
'approval_invalidated',
|
|
62
|
+
'stage_applying',
|
|
63
|
+
'target_applying',
|
|
64
|
+
'target_applied',
|
|
65
|
+
'target_verifying',
|
|
66
|
+
'target_verified',
|
|
67
|
+
'stage_verified',
|
|
68
|
+
'paused',
|
|
69
|
+
'failed',
|
|
70
|
+
'canceled',
|
|
71
|
+
'completed'
|
|
72
|
+
)
|
|
73
|
+
`.execute(db);
|
|
74
|
+
|
|
75
|
+
await sql`
|
|
76
|
+
create table health.accounting_integrity_repair_plan (
|
|
77
|
+
id uuid primary key default gen_random_uuid(),
|
|
78
|
+
data_region text not null,
|
|
79
|
+
environment text not null,
|
|
80
|
+
code text not null,
|
|
81
|
+
recipe_version integer not null,
|
|
82
|
+
git_revision text not null,
|
|
83
|
+
status health.accounting_integrity_repair_plan_status
|
|
84
|
+
not null default 'draft',
|
|
85
|
+
title text not null,
|
|
86
|
+
linear_ref text,
|
|
87
|
+
created_by text not null,
|
|
88
|
+
created_at timestamptz not null default now(),
|
|
89
|
+
updated_at timestamptz not null default now(),
|
|
90
|
+
completed_at timestamptz,
|
|
91
|
+
canceled_at timestamptz,
|
|
92
|
+
constraint accounting_integrity_repair_plan_recipe_version_check
|
|
93
|
+
check (recipe_version > 0),
|
|
94
|
+
constraint accounting_integrity_repair_plan_completion_check
|
|
95
|
+
check ((status = 'completed') = (completed_at is not null)),
|
|
96
|
+
constraint accounting_integrity_repair_plan_cancellation_check
|
|
97
|
+
check ((status = 'canceled') = (canceled_at is not null))
|
|
98
|
+
)
|
|
99
|
+
`.execute(db);
|
|
100
|
+
|
|
101
|
+
await sql`
|
|
102
|
+
create index accounting_integrity_repair_plan_status_idx
|
|
103
|
+
on health.accounting_integrity_repair_plan (
|
|
104
|
+
data_region,
|
|
105
|
+
environment,
|
|
106
|
+
status,
|
|
107
|
+
updated_at desc
|
|
108
|
+
)
|
|
109
|
+
`.execute(db);
|
|
110
|
+
|
|
111
|
+
await sql`
|
|
112
|
+
create table health.accounting_integrity_repair_stage (
|
|
113
|
+
id uuid primary key default gen_random_uuid(),
|
|
114
|
+
plan_id uuid not null
|
|
115
|
+
references health.accounting_integrity_repair_plan(id)
|
|
116
|
+
on delete cascade,
|
|
117
|
+
ordinal integer not null,
|
|
118
|
+
scope_type health.accounting_integrity_repair_scope_type not null,
|
|
119
|
+
tenant_id uuid not null,
|
|
120
|
+
status health.accounting_integrity_repair_stage_status
|
|
121
|
+
not null default 'planned',
|
|
122
|
+
manifest jsonb not null,
|
|
123
|
+
manifest_hash text not null,
|
|
124
|
+
limits jsonb not null,
|
|
125
|
+
dry_run_result jsonb,
|
|
126
|
+
approved_by text,
|
|
127
|
+
approved_at timestamptz,
|
|
128
|
+
approval_ref text,
|
|
129
|
+
apply_result jsonb,
|
|
130
|
+
verification_result jsonb,
|
|
131
|
+
started_at timestamptz,
|
|
132
|
+
completed_at timestamptz,
|
|
133
|
+
created_at timestamptz not null default now(),
|
|
134
|
+
updated_at timestamptz not null default now(),
|
|
135
|
+
constraint accounting_integrity_repair_stage_plan_ordinal_key
|
|
136
|
+
unique (plan_id, ordinal),
|
|
137
|
+
constraint accounting_integrity_repair_stage_ordinal_check
|
|
138
|
+
check (ordinal > 0),
|
|
139
|
+
constraint accounting_integrity_repair_stage_approval_check check (
|
|
140
|
+
(approved_by is null and approved_at is null and approval_ref is null)
|
|
141
|
+
or
|
|
142
|
+
(approved_by is not null and approved_at is not null and
|
|
143
|
+
approval_ref is not null)
|
|
144
|
+
),
|
|
145
|
+
constraint accounting_integrity_repair_stage_completion_check check (
|
|
146
|
+
(status = 'verified') = (completed_at is not null)
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
`.execute(db);
|
|
150
|
+
|
|
151
|
+
await sql`
|
|
152
|
+
create index accounting_integrity_repair_stage_plan_status_idx
|
|
153
|
+
on health.accounting_integrity_repair_stage (
|
|
154
|
+
plan_id,
|
|
155
|
+
status,
|
|
156
|
+
ordinal
|
|
157
|
+
)
|
|
158
|
+
`.execute(db);
|
|
159
|
+
|
|
160
|
+
await sql`
|
|
161
|
+
create table health.accounting_integrity_repair_target (
|
|
162
|
+
id uuid primary key default gen_random_uuid(),
|
|
163
|
+
stage_id uuid not null
|
|
164
|
+
references health.accounting_integrity_repair_stage(id)
|
|
165
|
+
on delete cascade,
|
|
166
|
+
ordinal integer not null,
|
|
167
|
+
case_id uuid not null,
|
|
168
|
+
case_version bigint not null,
|
|
169
|
+
case_content_hash text not null,
|
|
170
|
+
tenant_id uuid not null,
|
|
171
|
+
target_key text not null,
|
|
172
|
+
action jsonb not null,
|
|
173
|
+
before_state jsonb not null,
|
|
174
|
+
before_hash text not null,
|
|
175
|
+
expected_result jsonb not null,
|
|
176
|
+
lock_assessment jsonb not null,
|
|
177
|
+
effect_plan jsonb not null,
|
|
178
|
+
status health.accounting_integrity_repair_target_status
|
|
179
|
+
not null default 'pending',
|
|
180
|
+
idempotency_key text not null unique,
|
|
181
|
+
audit_action_id uuid,
|
|
182
|
+
apply_result jsonb,
|
|
183
|
+
verification_result jsonb,
|
|
184
|
+
started_at timestamptz,
|
|
185
|
+
completed_at timestamptz,
|
|
186
|
+
created_at timestamptz not null default now(),
|
|
187
|
+
updated_at timestamptz not null default now(),
|
|
188
|
+
constraint accounting_integrity_repair_target_stage_key
|
|
189
|
+
unique (stage_id, target_key),
|
|
190
|
+
constraint accounting_integrity_repair_target_stage_ordinal_key
|
|
191
|
+
unique (stage_id, ordinal),
|
|
192
|
+
constraint accounting_integrity_repair_target_ordinal_check
|
|
193
|
+
check (ordinal > 0),
|
|
194
|
+
constraint accounting_integrity_repair_target_case_version_check
|
|
195
|
+
check (case_version > 0),
|
|
196
|
+
constraint accounting_integrity_repair_target_completion_check check (
|
|
197
|
+
(status = 'verified') = (completed_at is not null)
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
`.execute(db);
|
|
201
|
+
|
|
202
|
+
await sql`
|
|
203
|
+
create index accounting_integrity_repair_target_stage_status_idx
|
|
204
|
+
on health.accounting_integrity_repair_target (
|
|
205
|
+
stage_id,
|
|
206
|
+
status,
|
|
207
|
+
ordinal
|
|
208
|
+
)
|
|
209
|
+
`.execute(db);
|
|
210
|
+
await sql`
|
|
211
|
+
create index accounting_integrity_repair_target_case_idx
|
|
212
|
+
on health.accounting_integrity_repair_target (case_id)
|
|
213
|
+
`.execute(db);
|
|
214
|
+
|
|
215
|
+
await sql`
|
|
216
|
+
create table health.accounting_integrity_repair_transition (
|
|
217
|
+
id uuid primary key default gen_random_uuid(),
|
|
218
|
+
plan_id uuid not null
|
|
219
|
+
references health.accounting_integrity_repair_plan(id)
|
|
220
|
+
on delete cascade,
|
|
221
|
+
stage_id uuid
|
|
222
|
+
references health.accounting_integrity_repair_stage(id)
|
|
223
|
+
on delete cascade,
|
|
224
|
+
target_id uuid
|
|
225
|
+
references health.accounting_integrity_repair_target(id)
|
|
226
|
+
on delete cascade,
|
|
227
|
+
type health.accounting_integrity_repair_transition_type not null,
|
|
228
|
+
actor text not null,
|
|
229
|
+
payload jsonb not null,
|
|
230
|
+
created_at timestamptz not null default now(),
|
|
231
|
+
constraint accounting_integrity_repair_transition_target_stage_check
|
|
232
|
+
check (target_id is null or stage_id is not null)
|
|
233
|
+
)
|
|
234
|
+
`.execute(db);
|
|
235
|
+
|
|
236
|
+
await sql`
|
|
237
|
+
create index accounting_integrity_repair_transition_plan_idx
|
|
238
|
+
on health.accounting_integrity_repair_transition (
|
|
239
|
+
plan_id,
|
|
240
|
+
created_at,
|
|
241
|
+
id
|
|
242
|
+
)
|
|
243
|
+
`.execute(db);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
247
|
+
await sql`
|
|
248
|
+
drop table if exists health.accounting_integrity_repair_transition
|
|
249
|
+
`.execute(db);
|
|
250
|
+
await sql`
|
|
251
|
+
drop table if exists health.accounting_integrity_repair_target
|
|
252
|
+
`.execute(db);
|
|
253
|
+
await sql`
|
|
254
|
+
drop table if exists health.accounting_integrity_repair_stage
|
|
255
|
+
`.execute(db);
|
|
256
|
+
await sql`
|
|
257
|
+
drop table if exists health.accounting_integrity_repair_plan
|
|
258
|
+
`.execute(db);
|
|
259
|
+
await sql`
|
|
260
|
+
drop type if exists
|
|
261
|
+
health.accounting_integrity_repair_transition_type
|
|
262
|
+
`.execute(db);
|
|
263
|
+
await sql`
|
|
264
|
+
drop type if exists health.accounting_integrity_repair_target_status
|
|
265
|
+
`.execute(db);
|
|
266
|
+
await sql`
|
|
267
|
+
drop type if exists health.accounting_integrity_repair_scope_type
|
|
268
|
+
`.execute(db);
|
|
269
|
+
await sql`
|
|
270
|
+
drop type if exists health.accounting_integrity_repair_stage_status
|
|
271
|
+
`.execute(db);
|
|
272
|
+
await sql`
|
|
273
|
+
drop type if exists health.accounting_integrity_repair_plan_status
|
|
274
|
+
`.execute(db);
|
|
275
|
+
await sql`
|
|
276
|
+
alter table health.accounting_integrity_run
|
|
277
|
+
drop constraint accounting_integrity_run_scope_tenant_ids_check,
|
|
278
|
+
drop column resolves_cases,
|
|
279
|
+
drop column scope_tenant_ids
|
|
280
|
+
`.execute(db);
|
|
281
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import { sql } from 'kysely';
|
|
3
|
+
|
|
4
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
5
|
+
await sql`
|
|
6
|
+
create table public.line_classification_usage (
|
|
7
|
+
tenant_id uuid not null references public.tenant(id) on delete cascade,
|
|
8
|
+
kind text not null,
|
|
9
|
+
name text not null,
|
|
10
|
+
app_id text,
|
|
11
|
+
mapping_status text,
|
|
12
|
+
first_seen_at timestamptz not null default now(),
|
|
13
|
+
last_seen_at timestamptz not null default now(),
|
|
14
|
+
revision integer not null default 1,
|
|
15
|
+
reported_revision integer not null default 0,
|
|
16
|
+
report_attempts integer not null default 0,
|
|
17
|
+
last_error text,
|
|
18
|
+
created_at timestamptz not null default now(),
|
|
19
|
+
updated_at timestamptz not null default now(),
|
|
20
|
+
primary key (tenant_id, kind, name),
|
|
21
|
+
constraint line_classification_usage_kind_check
|
|
22
|
+
check (kind in ('paymentLine', 'reservationLine')),
|
|
23
|
+
constraint line_classification_usage_mapping_status_check
|
|
24
|
+
check (
|
|
25
|
+
mapping_status is null or
|
|
26
|
+
mapping_status in ('excluded', 'mapped', 'unmapped')
|
|
27
|
+
),
|
|
28
|
+
constraint line_classification_usage_revision_check check (revision > 0),
|
|
29
|
+
constraint line_classification_usage_reported_revision_check
|
|
30
|
+
check (reported_revision >= 0 and reported_revision <= revision),
|
|
31
|
+
constraint line_classification_usage_report_attempts_check
|
|
32
|
+
check (report_attempts >= 0)
|
|
33
|
+
);
|
|
34
|
+
`.execute(db);
|
|
35
|
+
|
|
36
|
+
await sql`
|
|
37
|
+
create index line_classification_usage_pending_idx
|
|
38
|
+
on public.line_classification_usage (updated_at, tenant_id, kind, name)
|
|
39
|
+
where reported_revision < revision;
|
|
40
|
+
`.execute(db);
|
|
41
|
+
|
|
42
|
+
await sql`
|
|
43
|
+
create table public.line_classification_usage_backfill (
|
|
44
|
+
source text primary key,
|
|
45
|
+
cursor_id uuid,
|
|
46
|
+
completed_at timestamptz,
|
|
47
|
+
updated_at timestamptz not null default now(),
|
|
48
|
+
constraint line_classification_usage_backfill_source_check
|
|
49
|
+
check (source in ('paymentLine', 'transactionLine'))
|
|
50
|
+
);
|
|
51
|
+
`.execute(db);
|
|
52
|
+
|
|
53
|
+
await sql`
|
|
54
|
+
insert into public.line_classification_usage_backfill (source)
|
|
55
|
+
values ('paymentLine'), ('transactionLine');
|
|
56
|
+
`.execute(db);
|
|
57
|
+
|
|
58
|
+
await sql`
|
|
59
|
+
create or replace function public.capture_line_classification_usage()
|
|
60
|
+
returns trigger
|
|
61
|
+
language plpgsql
|
|
62
|
+
as $$
|
|
63
|
+
begin
|
|
64
|
+
insert into public.line_classification_usage (
|
|
65
|
+
tenant_id,
|
|
66
|
+
kind,
|
|
67
|
+
name,
|
|
68
|
+
app_id,
|
|
69
|
+
mapping_status,
|
|
70
|
+
first_seen_at,
|
|
71
|
+
last_seen_at
|
|
72
|
+
)
|
|
73
|
+
select distinct
|
|
74
|
+
line.tenant_id,
|
|
75
|
+
case
|
|
76
|
+
when line.reservation_id is not null and line.payment_id is null
|
|
77
|
+
then 'reservationLine'
|
|
78
|
+
when line.payment_id is not null then 'paymentLine'
|
|
79
|
+
when classification.type in ('paymentLine', 'reservationLine')
|
|
80
|
+
then classification.type
|
|
81
|
+
end,
|
|
82
|
+
coalesce(line.effective_type, line.type),
|
|
83
|
+
coalesce(
|
|
84
|
+
classification.app_id,
|
|
85
|
+
app.id
|
|
86
|
+
),
|
|
87
|
+
case
|
|
88
|
+
when (
|
|
89
|
+
line.reservation_id is not null and line.payment_id is null
|
|
90
|
+
) or classification.type = 'reservationLine' then
|
|
91
|
+
case
|
|
92
|
+
when mapping.id is null then 'unmapped'
|
|
93
|
+
when mapping.account_id is null then 'excluded'
|
|
94
|
+
else 'mapped'
|
|
95
|
+
end
|
|
96
|
+
else null
|
|
97
|
+
end,
|
|
98
|
+
now(),
|
|
99
|
+
now()
|
|
100
|
+
from new_payment_lines as line
|
|
101
|
+
left join public.payment_line_classification as classification
|
|
102
|
+
on classification.name = coalesce(line.effective_type, line.type)
|
|
103
|
+
left join public.app as app
|
|
104
|
+
on lower(app.id) = lower(
|
|
105
|
+
split_part(coalesce(line.effective_type, line.type), '_', 1)
|
|
106
|
+
)
|
|
107
|
+
and app.category = 'propertyManagementSystem'
|
|
108
|
+
left join accounting.account_reservation_line_type as mapping
|
|
109
|
+
on mapping.tenant_id = line.tenant_id
|
|
110
|
+
and mapping.line_type = coalesce(line.effective_type, line.type)
|
|
111
|
+
and mapping.booking_channel is null
|
|
112
|
+
where line.tenant_id is not null
|
|
113
|
+
and coalesce(line.effective_type, line.type) is not null
|
|
114
|
+
and coalesce(line.effective_type, line.type) != ''
|
|
115
|
+
and (
|
|
116
|
+
(line.reservation_id is not null and line.payment_id is null) or
|
|
117
|
+
line.payment_id is not null or
|
|
118
|
+
classification.type in ('paymentLine', 'reservationLine')
|
|
119
|
+
)
|
|
120
|
+
on conflict (tenant_id, kind, name) do update
|
|
121
|
+
set
|
|
122
|
+
app_id = coalesce(
|
|
123
|
+
excluded.app_id,
|
|
124
|
+
public.line_classification_usage.app_id
|
|
125
|
+
),
|
|
126
|
+
mapping_status = excluded.mapping_status,
|
|
127
|
+
last_seen_at = case
|
|
128
|
+
when public.line_classification_usage.app_id is distinct from
|
|
129
|
+
coalesce(
|
|
130
|
+
excluded.app_id,
|
|
131
|
+
public.line_classification_usage.app_id
|
|
132
|
+
) or
|
|
133
|
+
public.line_classification_usage.mapping_status is distinct from
|
|
134
|
+
excluded.mapping_status or
|
|
135
|
+
public.line_classification_usage.last_seen_at <
|
|
136
|
+
excluded.last_seen_at - interval '1 hour'
|
|
137
|
+
then greatest(
|
|
138
|
+
public.line_classification_usage.last_seen_at,
|
|
139
|
+
excluded.last_seen_at
|
|
140
|
+
)
|
|
141
|
+
else public.line_classification_usage.last_seen_at
|
|
142
|
+
end,
|
|
143
|
+
revision = case
|
|
144
|
+
when public.line_classification_usage.app_id is distinct from
|
|
145
|
+
coalesce(
|
|
146
|
+
excluded.app_id,
|
|
147
|
+
public.line_classification_usage.app_id
|
|
148
|
+
) or
|
|
149
|
+
public.line_classification_usage.mapping_status is distinct from
|
|
150
|
+
excluded.mapping_status or
|
|
151
|
+
public.line_classification_usage.last_seen_at <
|
|
152
|
+
excluded.last_seen_at - interval '1 hour'
|
|
153
|
+
then public.line_classification_usage.revision + 1
|
|
154
|
+
else public.line_classification_usage.revision
|
|
155
|
+
end,
|
|
156
|
+
updated_at = case
|
|
157
|
+
when public.line_classification_usage.app_id is distinct from
|
|
158
|
+
coalesce(
|
|
159
|
+
excluded.app_id,
|
|
160
|
+
public.line_classification_usage.app_id
|
|
161
|
+
) or
|
|
162
|
+
public.line_classification_usage.mapping_status is distinct from
|
|
163
|
+
excluded.mapping_status or
|
|
164
|
+
public.line_classification_usage.last_seen_at <
|
|
165
|
+
excluded.last_seen_at - interval '1 hour'
|
|
166
|
+
then now()
|
|
167
|
+
else public.line_classification_usage.updated_at
|
|
168
|
+
end;
|
|
169
|
+
return null;
|
|
170
|
+
end;
|
|
171
|
+
$$;
|
|
172
|
+
`.execute(db);
|
|
173
|
+
|
|
174
|
+
await sql`
|
|
175
|
+
create trigger payment_line_classification_usage_insert
|
|
176
|
+
after insert on public.payment_line
|
|
177
|
+
referencing new table as new_payment_lines
|
|
178
|
+
for each statement
|
|
179
|
+
execute function public.capture_line_classification_usage();
|
|
180
|
+
`.execute(db);
|
|
181
|
+
|
|
182
|
+
await sql`
|
|
183
|
+
create trigger payment_line_classification_usage_update
|
|
184
|
+
after update on public.payment_line
|
|
185
|
+
referencing new table as new_payment_lines
|
|
186
|
+
for each statement
|
|
187
|
+
execute function public.capture_line_classification_usage();
|
|
188
|
+
`.execute(db);
|
|
189
|
+
|
|
190
|
+
await sql`
|
|
191
|
+
create or replace function public.capture_transaction_line_classification_usage()
|
|
192
|
+
returns trigger
|
|
193
|
+
language plpgsql
|
|
194
|
+
as $$
|
|
195
|
+
begin
|
|
196
|
+
insert into public.line_classification_usage (
|
|
197
|
+
tenant_id,
|
|
198
|
+
kind,
|
|
199
|
+
name,
|
|
200
|
+
app_id,
|
|
201
|
+
mapping_status,
|
|
202
|
+
first_seen_at,
|
|
203
|
+
last_seen_at
|
|
204
|
+
)
|
|
205
|
+
select
|
|
206
|
+
line.tenant_id,
|
|
207
|
+
'paymentLine',
|
|
208
|
+
line.match_line_type_classification,
|
|
209
|
+
coalesce(classification.app_id, app.id),
|
|
210
|
+
null,
|
|
211
|
+
min(line.created_at),
|
|
212
|
+
max(line.updated_at)
|
|
213
|
+
from new_transaction_lines as line
|
|
214
|
+
left join public.payment_line_classification as classification
|
|
215
|
+
on classification.name = line.match_line_type_classification
|
|
216
|
+
left join public.app as app
|
|
217
|
+
on lower(app.id) = lower(
|
|
218
|
+
split_part(line.match_line_type_classification, '_', 1)
|
|
219
|
+
)
|
|
220
|
+
and app.category = 'propertyManagementSystem'
|
|
221
|
+
where line.match_line_type_classification is not null
|
|
222
|
+
and line.match_line_type_classification != ''
|
|
223
|
+
group by
|
|
224
|
+
line.tenant_id,
|
|
225
|
+
line.match_line_type_classification,
|
|
226
|
+
coalesce(classification.app_id, app.id)
|
|
227
|
+
on conflict (tenant_id, kind, name) do update
|
|
228
|
+
set
|
|
229
|
+
app_id = coalesce(
|
|
230
|
+
excluded.app_id,
|
|
231
|
+
public.line_classification_usage.app_id
|
|
232
|
+
),
|
|
233
|
+
first_seen_at = least(
|
|
234
|
+
public.line_classification_usage.first_seen_at,
|
|
235
|
+
excluded.first_seen_at
|
|
236
|
+
),
|
|
237
|
+
last_seen_at = case
|
|
238
|
+
when public.line_classification_usage.app_id is distinct from
|
|
239
|
+
coalesce(
|
|
240
|
+
excluded.app_id,
|
|
241
|
+
public.line_classification_usage.app_id
|
|
242
|
+
) or
|
|
243
|
+
public.line_classification_usage.last_seen_at <
|
|
244
|
+
excluded.last_seen_at - interval '1 hour'
|
|
245
|
+
then greatest(
|
|
246
|
+
public.line_classification_usage.last_seen_at,
|
|
247
|
+
excluded.last_seen_at
|
|
248
|
+
)
|
|
249
|
+
else public.line_classification_usage.last_seen_at
|
|
250
|
+
end,
|
|
251
|
+
revision = case
|
|
252
|
+
when public.line_classification_usage.app_id is distinct from
|
|
253
|
+
coalesce(
|
|
254
|
+
excluded.app_id,
|
|
255
|
+
public.line_classification_usage.app_id
|
|
256
|
+
) or
|
|
257
|
+
public.line_classification_usage.last_seen_at <
|
|
258
|
+
excluded.last_seen_at - interval '1 hour'
|
|
259
|
+
then public.line_classification_usage.revision + 1
|
|
260
|
+
else public.line_classification_usage.revision
|
|
261
|
+
end,
|
|
262
|
+
updated_at = case
|
|
263
|
+
when public.line_classification_usage.app_id is distinct from
|
|
264
|
+
coalesce(
|
|
265
|
+
excluded.app_id,
|
|
266
|
+
public.line_classification_usage.app_id
|
|
267
|
+
) or
|
|
268
|
+
public.line_classification_usage.last_seen_at <
|
|
269
|
+
excluded.last_seen_at - interval '1 hour'
|
|
270
|
+
then now()
|
|
271
|
+
else public.line_classification_usage.updated_at
|
|
272
|
+
end;
|
|
273
|
+
return null;
|
|
274
|
+
end;
|
|
275
|
+
$$;
|
|
276
|
+
`.execute(db);
|
|
277
|
+
|
|
278
|
+
await sql`
|
|
279
|
+
create trigger transaction_line_classification_usage_insert
|
|
280
|
+
after insert on accounting.transaction_line
|
|
281
|
+
referencing new table as new_transaction_lines
|
|
282
|
+
for each statement
|
|
283
|
+
execute function public.capture_transaction_line_classification_usage();
|
|
284
|
+
`.execute(db);
|
|
285
|
+
|
|
286
|
+
await sql`
|
|
287
|
+
create trigger transaction_line_classification_usage_update
|
|
288
|
+
after update on accounting.transaction_line
|
|
289
|
+
referencing new table as new_transaction_lines
|
|
290
|
+
for each statement
|
|
291
|
+
execute function public.capture_transaction_line_classification_usage();
|
|
292
|
+
`.execute(db);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
296
|
+
await sql`
|
|
297
|
+
drop trigger if exists transaction_line_classification_usage_update
|
|
298
|
+
on accounting.transaction_line;
|
|
299
|
+
`.execute(db);
|
|
300
|
+
await sql`
|
|
301
|
+
drop trigger if exists transaction_line_classification_usage_insert
|
|
302
|
+
on accounting.transaction_line;
|
|
303
|
+
`.execute(db);
|
|
304
|
+
await sql`
|
|
305
|
+
drop function if exists
|
|
306
|
+
public.capture_transaction_line_classification_usage();
|
|
307
|
+
`.execute(db);
|
|
308
|
+
await sql`
|
|
309
|
+
drop trigger if exists payment_line_classification_usage_update
|
|
310
|
+
on public.payment_line;
|
|
311
|
+
`.execute(db);
|
|
312
|
+
await sql`
|
|
313
|
+
drop trigger if exists payment_line_classification_usage_insert
|
|
314
|
+
on public.payment_line;
|
|
315
|
+
`.execute(db);
|
|
316
|
+
await sql`
|
|
317
|
+
drop function if exists public.capture_line_classification_usage();
|
|
318
|
+
`.execute(db);
|
|
319
|
+
await sql`
|
|
320
|
+
drop table if exists public.line_classification_usage_backfill;
|
|
321
|
+
`.execute(db);
|
|
322
|
+
await sql`
|
|
323
|
+
drop table if exists public.line_classification_usage;
|
|
324
|
+
`.execute(db);
|
|
325
|
+
}
|