@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.
@@ -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;