@vrplatform/kysely 1.3.45-stage.744 → 1.3.45-stage.850
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/main/v1.generated.d.ts +41 -0
- package/build/main/v1.generated.js.map +1 -1
- package/build/migrations-v2/0000000000059-billing-active-listing-cross-region-partner.ts +135 -0
- package/build/migrations-v2/0000000000060-accounting-integrity-change-driven.ts +99 -0
- package/build/module/v1.generated.d.ts +41 -0
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { Kysely } from 'kysely';
|
|
2
|
+
import { sql } from 'kysely';
|
|
3
|
+
|
|
4
|
+
// CUS-2977: a billing partner homed in another data region has no row in this
|
|
5
|
+
// regional database. That absence is valid and must not make the team count
|
|
6
|
+
// zero active listings. Only a locally present, non-active billing partner
|
|
7
|
+
// does, matching kysely `whereTenantActive` (PRO-17712). `create or replace`
|
|
8
|
+
// keeps the existing grants.
|
|
9
|
+
export async function up(db: Kysely<unknown>): Promise<void> {
|
|
10
|
+
await sql`
|
|
11
|
+
create or replace function billing.active_listing_count(
|
|
12
|
+
selected_tenant_id uuid
|
|
13
|
+
) returns integer
|
|
14
|
+
language sql
|
|
15
|
+
stable
|
|
16
|
+
as $$
|
|
17
|
+
select count(*)::integer
|
|
18
|
+
from public.listing as listing
|
|
19
|
+
inner join public.tenant as tenant
|
|
20
|
+
on tenant.id = listing.tenant_id
|
|
21
|
+
where listing.tenant_id = selected_tenant_id
|
|
22
|
+
and tenant.calculated_status = 'active'
|
|
23
|
+
and not exists (
|
|
24
|
+
select 1
|
|
25
|
+
from public.tenant as billing_partner
|
|
26
|
+
where billing_partner.id = coalesce(
|
|
27
|
+
tenant.calculated_billing_partner_id,
|
|
28
|
+
'7bfec41f-aa3f-4602-95d2-f7996e4f0e59'::uuid
|
|
29
|
+
)
|
|
30
|
+
and billing_partner.calculated_status is distinct from 'active'
|
|
31
|
+
)
|
|
32
|
+
and (
|
|
33
|
+
(
|
|
34
|
+
tenant.is_general_ledger = false
|
|
35
|
+
and listing.calculated_status = 'active'
|
|
36
|
+
) or (
|
|
37
|
+
tenant.is_general_ledger = true
|
|
38
|
+
and not exists (
|
|
39
|
+
select 1
|
|
40
|
+
from public.listing_ownership_period as ownership
|
|
41
|
+
where ownership.listing_id = coalesce(
|
|
42
|
+
listing.parent_id,
|
|
43
|
+
listing.id
|
|
44
|
+
)
|
|
45
|
+
and ownership.tenant_id = listing.tenant_id
|
|
46
|
+
and ownership.set_listing_inactive = true
|
|
47
|
+
and ownership.start_at <= current_date
|
|
48
|
+
and (
|
|
49
|
+
ownership.end_at is null
|
|
50
|
+
or ownership.end_at >= current_date
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
$$
|
|
56
|
+
`.execute(db);
|
|
57
|
+
|
|
58
|
+
// Append a corrected fact, effective now, for every active team whose
|
|
59
|
+
// billing partner has no local row. These are the only teams whose count
|
|
60
|
+
// changes. Completed-month billing reads the latest fact before the month
|
|
61
|
+
// ends, so applying this before the month closes corrects that month.
|
|
62
|
+
// Earlier wrong facts stay as recorded history.
|
|
63
|
+
await sql`
|
|
64
|
+
select billing.record_listing_facts(
|
|
65
|
+
array(
|
|
66
|
+
select tenant.id
|
|
67
|
+
from public.tenant as tenant
|
|
68
|
+
where tenant.type = 'propertyManager'
|
|
69
|
+
and tenant.calculated_status = 'active'
|
|
70
|
+
and tenant.calculated_billing_partner_id is not null
|
|
71
|
+
and not exists (
|
|
72
|
+
select 1
|
|
73
|
+
from public.tenant as billing_partner
|
|
74
|
+
where billing_partner.id = tenant.calculated_billing_partner_id
|
|
75
|
+
)
|
|
76
|
+
and exists (
|
|
77
|
+
select 1
|
|
78
|
+
from billing.listing_fact as fact
|
|
79
|
+
where fact.tenant_id = tenant.id
|
|
80
|
+
)
|
|
81
|
+
),
|
|
82
|
+
'daily_reconciliation',
|
|
83
|
+
gen_random_uuid(),
|
|
84
|
+
now(),
|
|
85
|
+
true
|
|
86
|
+
)
|
|
87
|
+
`.execute(db);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
91
|
+
await sql`
|
|
92
|
+
create or replace function billing.active_listing_count(
|
|
93
|
+
selected_tenant_id uuid
|
|
94
|
+
) returns integer
|
|
95
|
+
language sql
|
|
96
|
+
stable
|
|
97
|
+
as $$
|
|
98
|
+
select count(*)::integer
|
|
99
|
+
from public.listing as listing
|
|
100
|
+
inner join public.tenant as tenant
|
|
101
|
+
on tenant.id = listing.tenant_id
|
|
102
|
+
left join public.tenant as billing_partner
|
|
103
|
+
on billing_partner.id = tenant.calculated_billing_partner_id
|
|
104
|
+
where listing.tenant_id = selected_tenant_id
|
|
105
|
+
and tenant.calculated_status = 'active'
|
|
106
|
+
and (
|
|
107
|
+
tenant.calculated_billing_partner_id is null
|
|
108
|
+
or billing_partner.calculated_status = 'active'
|
|
109
|
+
)
|
|
110
|
+
and (
|
|
111
|
+
(
|
|
112
|
+
tenant.is_general_ledger = false
|
|
113
|
+
and listing.calculated_status = 'active'
|
|
114
|
+
) or (
|
|
115
|
+
tenant.is_general_ledger = true
|
|
116
|
+
and not exists (
|
|
117
|
+
select 1
|
|
118
|
+
from public.listing_ownership_period as ownership
|
|
119
|
+
where ownership.listing_id = coalesce(
|
|
120
|
+
listing.parent_id,
|
|
121
|
+
listing.id
|
|
122
|
+
)
|
|
123
|
+
and ownership.tenant_id = listing.tenant_id
|
|
124
|
+
and ownership.set_listing_inactive = true
|
|
125
|
+
and ownership.start_at <= current_date
|
|
126
|
+
and (
|
|
127
|
+
ownership.end_at is null
|
|
128
|
+
or ownership.end_at >= current_date
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
$$
|
|
134
|
+
`.execute(db);
|
|
135
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
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 type health.accounting_integrity_dirty_record_type as enum (
|
|
7
|
+
'reservation',
|
|
8
|
+
'transaction'
|
|
9
|
+
)
|
|
10
|
+
`.execute(db);
|
|
11
|
+
|
|
12
|
+
await sql`
|
|
13
|
+
create table health.accounting_integrity_dirty_record (
|
|
14
|
+
tenant_id uuid not null references public.tenant(id) on delete cascade,
|
|
15
|
+
record_type health.accounting_integrity_dirty_record_type not null,
|
|
16
|
+
record_id uuid not null,
|
|
17
|
+
dirty_version bigint not null default 1,
|
|
18
|
+
computed_version bigint not null default 0,
|
|
19
|
+
dirty_at timestamptz not null default now(),
|
|
20
|
+
computed_at timestamptz,
|
|
21
|
+
claimed_until timestamptz,
|
|
22
|
+
claim_token uuid,
|
|
23
|
+
created_at timestamptz not null default now(),
|
|
24
|
+
updated_at timestamptz not null default now(),
|
|
25
|
+
constraint accounting_integrity_dirty_record_identity_key
|
|
26
|
+
primary key (tenant_id, record_type, record_id),
|
|
27
|
+
constraint accounting_integrity_dirty_record_version_check
|
|
28
|
+
check (dirty_version >= 0 and computed_version >= 0)
|
|
29
|
+
)
|
|
30
|
+
`.execute(db);
|
|
31
|
+
|
|
32
|
+
await sql`
|
|
33
|
+
create index accounting_integrity_dirty_record_pending_idx
|
|
34
|
+
on health.accounting_integrity_dirty_record (
|
|
35
|
+
dirty_at,
|
|
36
|
+
tenant_id,
|
|
37
|
+
record_type,
|
|
38
|
+
record_id,
|
|
39
|
+
claimed_until
|
|
40
|
+
)
|
|
41
|
+
where dirty_version > computed_version
|
|
42
|
+
`.execute(db);
|
|
43
|
+
|
|
44
|
+
await sql`
|
|
45
|
+
create table health.accounting_integrity_sweep_cursor (
|
|
46
|
+
record_type health.accounting_integrity_dirty_record_type primary key,
|
|
47
|
+
last_tenant_id uuid,
|
|
48
|
+
last_record_id uuid,
|
|
49
|
+
cycle_started_at timestamptz not null default now(),
|
|
50
|
+
last_cycle_completed_at timestamptz,
|
|
51
|
+
definitions_hash text,
|
|
52
|
+
created_at timestamptz not null default now(),
|
|
53
|
+
updated_at timestamptz not null default now()
|
|
54
|
+
)
|
|
55
|
+
`.execute(db);
|
|
56
|
+
|
|
57
|
+
await sql`
|
|
58
|
+
create table health.accounting_integrity_comparison_finding (
|
|
59
|
+
id uuid primary key default gen_random_uuid(),
|
|
60
|
+
data_region text not null,
|
|
61
|
+
code text not null,
|
|
62
|
+
tenant_id uuid not null references public.tenant(id) on delete cascade,
|
|
63
|
+
record_type health.accounting_integrity_dirty_record_type not null,
|
|
64
|
+
record_id uuid not null,
|
|
65
|
+
case_key text not null,
|
|
66
|
+
severity health.accounting_integrity_severity not null,
|
|
67
|
+
content_hash text not null,
|
|
68
|
+
first_seen_at timestamptz not null,
|
|
69
|
+
created_at timestamptz not null default now(),
|
|
70
|
+
updated_at timestamptz not null default now(),
|
|
71
|
+
constraint accounting_integrity_comparison_finding_identity_key
|
|
72
|
+
unique (data_region, code, tenant_id, case_key)
|
|
73
|
+
)
|
|
74
|
+
`.execute(db);
|
|
75
|
+
|
|
76
|
+
await sql`
|
|
77
|
+
create index accounting_integrity_comparison_finding_report_idx
|
|
78
|
+
on health.accounting_integrity_comparison_finding (
|
|
79
|
+
data_region,
|
|
80
|
+
code,
|
|
81
|
+
case_key
|
|
82
|
+
)
|
|
83
|
+
`.execute(db);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
87
|
+
await sql`
|
|
88
|
+
drop table if exists health.accounting_integrity_comparison_finding
|
|
89
|
+
`.execute(db);
|
|
90
|
+
await sql`
|
|
91
|
+
drop table if exists health.accounting_integrity_sweep_cursor
|
|
92
|
+
`.execute(db);
|
|
93
|
+
await sql`
|
|
94
|
+
drop table if exists health.accounting_integrity_dirty_record
|
|
95
|
+
`.execute(db);
|
|
96
|
+
await sql`
|
|
97
|
+
drop type if exists health.accounting_integrity_dirty_record_type
|
|
98
|
+
`.execute(db);
|
|
99
|
+
}
|
|
@@ -38,6 +38,7 @@ export type Generated<T> = T extends ColumnType<infer S, infer I, infer U> ? Col
|
|
|
38
38
|
export type HealthAccountingIntegrityActionability = "automatically_repairable" | "blocked" | "code_fix_required" | "manual_repair" | "unknown";
|
|
39
39
|
export type HealthAccountingIntegrityCaseStatus = "open" | "resolved";
|
|
40
40
|
export type HealthAccountingIntegrityConfidence = "probable" | "proven" | "unknown";
|
|
41
|
+
export type HealthAccountingIntegrityDirtyRecordType = "reservation" | "transaction";
|
|
41
42
|
export type HealthAccountingIntegrityDeliveryChannel = "sentry" | "slack";
|
|
42
43
|
export type HealthAccountingIntegrityDeliveryStatus = "dead_letter" | "delivered" | "failed" | "pending" | "processing" | "suppressed";
|
|
43
44
|
export type HealthAccountingIntegrityRepairPlanStatus = "active" | "canceled" | "completed" | "draft" | "failed" | "paused";
|
|
@@ -1202,6 +1203,20 @@ export interface HealthAccountingIntegrityCase {
|
|
|
1202
1203
|
verification: Json;
|
|
1203
1204
|
version: Generated<Int8>;
|
|
1204
1205
|
}
|
|
1206
|
+
export interface HealthAccountingIntegrityComparisonFinding {
|
|
1207
|
+
caseKey: string;
|
|
1208
|
+
code: string;
|
|
1209
|
+
contentHash: string;
|
|
1210
|
+
createdAt: Generated<Timestamp>;
|
|
1211
|
+
dataRegion: string;
|
|
1212
|
+
firstSeenAt: Timestamp;
|
|
1213
|
+
id: Generated<string>;
|
|
1214
|
+
recordId: string;
|
|
1215
|
+
recordType: HealthAccountingIntegrityDirtyRecordType;
|
|
1216
|
+
severity: HealthAccountingIntegritySeverity;
|
|
1217
|
+
tenantId: string;
|
|
1218
|
+
updatedAt: Generated<Timestamp>;
|
|
1219
|
+
}
|
|
1205
1220
|
export interface HealthAccountingIntegrityDelivery {
|
|
1206
1221
|
attempts: Generated<number>;
|
|
1207
1222
|
caseId: string | null;
|
|
@@ -1221,6 +1236,19 @@ export interface HealthAccountingIntegrityDelivery {
|
|
|
1221
1236
|
status: Generated<HealthAccountingIntegrityDeliveryStatus>;
|
|
1222
1237
|
updatedAt: Generated<Timestamp>;
|
|
1223
1238
|
}
|
|
1239
|
+
export interface HealthAccountingIntegrityDirtyRecord {
|
|
1240
|
+
claimToken: string | null;
|
|
1241
|
+
claimedUntil: Timestamp | null;
|
|
1242
|
+
computedAt: Timestamp | null;
|
|
1243
|
+
computedVersion: Generated<Int8>;
|
|
1244
|
+
createdAt: Generated<Timestamp>;
|
|
1245
|
+
dirtyAt: Generated<Timestamp>;
|
|
1246
|
+
dirtyVersion: Generated<Int8>;
|
|
1247
|
+
recordId: string;
|
|
1248
|
+
recordType: HealthAccountingIntegrityDirtyRecordType;
|
|
1249
|
+
tenantId: string;
|
|
1250
|
+
updatedAt: Generated<Timestamp>;
|
|
1251
|
+
}
|
|
1224
1252
|
export interface HealthAccountingIntegrityOperatorEvent {
|
|
1225
1253
|
actorId: string;
|
|
1226
1254
|
caseId: string | null;
|
|
@@ -1340,6 +1368,16 @@ export interface HealthAccountingIntegrityRun {
|
|
|
1340
1368
|
unchangedCaseCount: Generated<Int8>;
|
|
1341
1369
|
updatedAt: Generated<Timestamp>;
|
|
1342
1370
|
}
|
|
1371
|
+
export interface HealthAccountingIntegritySweepCursor {
|
|
1372
|
+
createdAt: Generated<Timestamp>;
|
|
1373
|
+
cycleStartedAt: Generated<Timestamp>;
|
|
1374
|
+
definitionsHash: string | null;
|
|
1375
|
+
lastCycleCompletedAt: Timestamp | null;
|
|
1376
|
+
lastRecordId: string | null;
|
|
1377
|
+
lastTenantId: string | null;
|
|
1378
|
+
recordType: HealthAccountingIntegrityDirtyRecordType;
|
|
1379
|
+
updatedAt: Generated<Timestamp>;
|
|
1380
|
+
}
|
|
1343
1381
|
export interface HealthAccountingIntegrityTransition {
|
|
1344
1382
|
caseId: string;
|
|
1345
1383
|
caseVersion: Int8;
|
|
@@ -2758,8 +2796,11 @@ export interface DB {
|
|
|
2758
2796
|
"hdbCatalog.hdbSourceCatalogVersion": HdbCatalogHdbSourceCatalogVersion;
|
|
2759
2797
|
"hdbCatalog.hdbVersion": HdbCatalogHdbVersion;
|
|
2760
2798
|
"health.accountingIntegrityCase": HealthAccountingIntegrityCase;
|
|
2799
|
+
"health.accountingIntegrityComparisonFinding": HealthAccountingIntegrityComparisonFinding;
|
|
2761
2800
|
"health.accountingIntegrityDelivery": HealthAccountingIntegrityDelivery;
|
|
2801
|
+
"health.accountingIntegrityDirtyRecord": HealthAccountingIntegrityDirtyRecord;
|
|
2762
2802
|
"health.accountingIntegrityOperatorEvent": HealthAccountingIntegrityOperatorEvent;
|
|
2803
|
+
"health.accountingIntegritySweepCursor": HealthAccountingIntegritySweepCursor;
|
|
2763
2804
|
"health.accountingIntegrityRepairPlan": HealthAccountingIntegrityRepairPlan;
|
|
2764
2805
|
"health.accountingIntegrityRepairStage": HealthAccountingIntegrityRepairStage;
|
|
2765
2806
|
"health.accountingIntegrityRepairTarget": HealthAccountingIntegrityRepairTarget;
|