@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.
- package/build/.data.tar +0 -0
- package/build/main/control-plane/index.d.ts +312 -0
- package/build/main/control-plane/index.js.map +1 -1
- package/build/main/index.d.ts +13 -2
- package/build/main/index.js +217 -23
- 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 +110 -8
- package/build/main/local/index.js.map +1 -1
- package/build/main/postgres-error.d.ts +3 -3
- package/build/main/postgres-error.js +4 -3
- package/build/main/postgres-error.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.d.ts +1 -1
- package/build/main/query/tenant/status.js +6 -4
- package/build/main/query/tenant/status.js.map +1 -1
- package/build/main/regional.d.ts +1 -0
- package/build/main/regional.js +1 -0
- package/build/main/regional.js.map +1 -1
- package/build/main/test/index.d.ts +23 -3
- package/build/main/test/index.js +35 -13
- package/build/main/test/index.js.map +1 -1
- package/build/main/v1.generated.d.ts +560 -8
- 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/migrations-v2/0000000000033-reservation-issue-seed-bucket-index.ts +19 -0
- package/build/migrations-v2/0000000000034-retire-recent-classification-indexes.ts +29 -0
- package/build/migrations-v2/0000000000035-core-change-autovacuum.ts +24 -0
- package/build/migrations-v2/0000000000036-journal-entry-inactive-reason-constraint.ts +33 -0
- package/build/migrations-v2/0000000000037-journal-entry-inactive-reasons.ts +19 -0
- package/build/migrations-v2/0000000000038-journal-entry-group-inactive-reason.ts +14 -0
- package/build/migrations-v2/0000000000039-reservation-guest-breakdown.ts +19 -0
- package/build/migrations-v2/0000000000040-csv-import-source-identity-index.ts +23 -0
- package/build/migrations-v2/0000000000041-payment-returns.ts +38 -0
- package/build/migrations-v2/0000000000042-operation-resource-types.ts +609 -0
- package/build/migrations-v2/0000000000043-reservation-journal-freshness.ts +149 -0
- package/build/migrations-v2/0000000000044-reservation-journal-freshness-backfill.ts +254 -0
- package/build/migrations-v2/0000000000045-reservation-journal-freshness-revision-repair.ts +83 -0
- package/build/migrations-v2/0000000000046-materialized-reservation-journal-operations.ts +709 -0
- package/build/migrations-v2/0000000000047-public-audit-completion.ts +77 -0
- package/build/migrations-v2/0000000000048-reservation-journal-full-refresh-repair.ts +136 -0
- package/build/migrations-v2/0000000000049-queued-journal-operation-failures.ts +60 -0
- package/build/migrations-v2/0000000000050-connection-oauth-state.ts +43 -0
- package/build/migrations-v2/0000000000051-owner-statement-email-delivery.ts +134 -0
- package/build/migrations-v2/0000000000052-fee-journal-lock-skip-operations.ts +59 -0
- package/build/migrations-v2/0000000000053-fee-journal-lock-skip-null-attempt.ts +44 -0
- package/build/migrations-v2/0000000000054-journal-refresh-issue-codes.ts +16 -0
- package/build/migrations-v2/0000000000055-tenant-billing-subscription.ts +8 -0
- package/build/module/control-plane/index.d.ts +312 -0
- package/build/module/control-plane/index.js.map +1 -1
- package/build/module/index.d.ts +13 -2
- package/build/module/index.js +219 -24
- 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 +110 -8
- package/build/module/local/index.js.map +1 -1
- package/build/module/postgres-error.d.ts +3 -3
- package/build/module/postgres-error.js +4 -3
- package/build/module/postgres-error.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.d.ts +1 -1
- package/build/module/query/tenant/status.js +6 -4
- package/build/module/query/tenant/status.js.map +1 -1
- package/build/module/regional.d.ts +1 -0
- package/build/module/regional.js +1 -0
- package/build/module/regional.js.map +1 -1
- package/build/module/test/index.d.ts +23 -3
- package/build/module/test/index.js +34 -13
- package/build/module/test/index.js.map +1 -1
- package/build/module/v1.generated.d.ts +560 -8
- package/build/module/v1.generated.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,149 @@
|
|
|
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 accounting.reservation_journal_freshness_control (
|
|
7
|
+
tenant_id uuid primary key references public.tenant(id) on delete cascade,
|
|
8
|
+
guards_enabled_at timestamptz,
|
|
9
|
+
created_at timestamptz not null default now(),
|
|
10
|
+
updated_at timestamptz not null default now()
|
|
11
|
+
)
|
|
12
|
+
`.execute(db);
|
|
13
|
+
await sql`
|
|
14
|
+
create table accounting.reservation_journal_state (
|
|
15
|
+
tenant_id uuid not null references public.tenant(id) on delete cascade,
|
|
16
|
+
reservation_id uuid primary key references public.reservation(id) on delete cascade,
|
|
17
|
+
desired_revision bigint not null default 0,
|
|
18
|
+
applied_revision bigint not null default 0,
|
|
19
|
+
stale_since timestamptz,
|
|
20
|
+
calculated_at timestamptz,
|
|
21
|
+
created_at timestamptz not null default now(),
|
|
22
|
+
updated_at timestamptz not null default now()
|
|
23
|
+
)
|
|
24
|
+
`.execute(db);
|
|
25
|
+
await sql`
|
|
26
|
+
create index reservation_journal_state_tenant_stale_idx
|
|
27
|
+
on accounting.reservation_journal_state (
|
|
28
|
+
tenant_id,
|
|
29
|
+
stale_since,
|
|
30
|
+
reservation_id
|
|
31
|
+
)
|
|
32
|
+
where desired_revision > applied_revision
|
|
33
|
+
`.execute(db);
|
|
34
|
+
await sql`
|
|
35
|
+
create function accounting.initialize_reservation_journal_state()
|
|
36
|
+
returns trigger
|
|
37
|
+
language plpgsql
|
|
38
|
+
as $$
|
|
39
|
+
begin
|
|
40
|
+
if new.tenant_id is not null then
|
|
41
|
+
insert into accounting.reservation_journal_state (
|
|
42
|
+
tenant_id,
|
|
43
|
+
reservation_id
|
|
44
|
+
) values (
|
|
45
|
+
new.tenant_id,
|
|
46
|
+
new.id
|
|
47
|
+
)
|
|
48
|
+
on conflict (reservation_id) do nothing;
|
|
49
|
+
end if;
|
|
50
|
+
return new;
|
|
51
|
+
end;
|
|
52
|
+
$$
|
|
53
|
+
`.execute(db);
|
|
54
|
+
await sql`
|
|
55
|
+
create table accounting.reservation_journal_invalidation (
|
|
56
|
+
id uuid primary key default gen_random_uuid(),
|
|
57
|
+
tenant_id uuid not null references public.tenant(id) on delete cascade,
|
|
58
|
+
reservation_id uuid not null references public.reservation(id) on delete cascade,
|
|
59
|
+
revision bigint not null,
|
|
60
|
+
action_id uuid references audit.action(id) on delete set null,
|
|
61
|
+
effect_id uuid references audit.effect(id) on delete set null,
|
|
62
|
+
source_resource_type core.operation_resource_type,
|
|
63
|
+
source_resource_id uuid,
|
|
64
|
+
applied_at timestamptz,
|
|
65
|
+
covered_by_effect_id uuid references audit.effect(id) on delete set null,
|
|
66
|
+
created_at timestamptz not null default now(),
|
|
67
|
+
unique (tenant_id, reservation_id, revision),
|
|
68
|
+
unique (effect_id)
|
|
69
|
+
)
|
|
70
|
+
`.execute(db);
|
|
71
|
+
await sql`
|
|
72
|
+
create index reservation_journal_invalidation_reservation_pending_idx
|
|
73
|
+
on accounting.reservation_journal_invalidation (
|
|
74
|
+
tenant_id,
|
|
75
|
+
reservation_id,
|
|
76
|
+
revision,
|
|
77
|
+
effect_id
|
|
78
|
+
)
|
|
79
|
+
where applied_at is null
|
|
80
|
+
`.execute(db);
|
|
81
|
+
await sql`
|
|
82
|
+
create index reservation_journal_invalidation_source_pending_idx
|
|
83
|
+
on accounting.reservation_journal_invalidation (
|
|
84
|
+
tenant_id,
|
|
85
|
+
source_resource_type,
|
|
86
|
+
source_resource_id,
|
|
87
|
+
revision
|
|
88
|
+
)
|
|
89
|
+
where applied_at is null
|
|
90
|
+
`.execute(db);
|
|
91
|
+
|
|
92
|
+
await sql`
|
|
93
|
+
create table accounting.reservation_journal_statement_impact (
|
|
94
|
+
invalidation_id uuid not null
|
|
95
|
+
references accounting.reservation_journal_invalidation(id) on delete cascade,
|
|
96
|
+
tenant_id uuid not null references public.tenant(id) on delete cascade,
|
|
97
|
+
listing_id uuid not null references public.listing(id) on delete cascade,
|
|
98
|
+
listing_ownership_period_id uuid not null
|
|
99
|
+
references public.listing_ownership_period(id) on delete cascade,
|
|
100
|
+
month date not null,
|
|
101
|
+
currency text not null,
|
|
102
|
+
created_at timestamptz not null default now(),
|
|
103
|
+
primary key (
|
|
104
|
+
invalidation_id,
|
|
105
|
+
listing_id,
|
|
106
|
+
listing_ownership_period_id,
|
|
107
|
+
month,
|
|
108
|
+
currency
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
`.execute(db);
|
|
112
|
+
await sql`
|
|
113
|
+
create index reservation_journal_statement_impact_scope_idx
|
|
114
|
+
on accounting.reservation_journal_statement_impact (
|
|
115
|
+
tenant_id,
|
|
116
|
+
listing_ownership_period_id,
|
|
117
|
+
month,
|
|
118
|
+
currency,
|
|
119
|
+
invalidation_id
|
|
120
|
+
)
|
|
121
|
+
`.execute(db);
|
|
122
|
+
await sql`
|
|
123
|
+
create trigger initialize_reservation_journal_state
|
|
124
|
+
after insert on public.reservation
|
|
125
|
+
for each row execute function accounting.initialize_reservation_journal_state()
|
|
126
|
+
`.execute(db);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function down(db: Kysely<unknown>): Promise<void> {
|
|
130
|
+
await sql`
|
|
131
|
+
drop table if exists accounting.reservation_journal_statement_impact
|
|
132
|
+
`.execute(db);
|
|
133
|
+
await sql`
|
|
134
|
+
drop table if exists accounting.reservation_journal_invalidation
|
|
135
|
+
`.execute(db);
|
|
136
|
+
await sql`
|
|
137
|
+
drop trigger if exists initialize_reservation_journal_state
|
|
138
|
+
on public.reservation
|
|
139
|
+
`.execute(db);
|
|
140
|
+
await sql`
|
|
141
|
+
drop function if exists accounting.initialize_reservation_journal_state
|
|
142
|
+
`.execute(db);
|
|
143
|
+
await sql`
|
|
144
|
+
drop table if exists accounting.reservation_journal_state
|
|
145
|
+
`.execute(db);
|
|
146
|
+
await sql`
|
|
147
|
+
drop table if exists accounting.reservation_journal_freshness_control
|
|
148
|
+
`.execute(db);
|
|
149
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
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
|
+
insert into accounting.reservation_journal_state (
|
|
7
|
+
tenant_id,
|
|
8
|
+
reservation_id,
|
|
9
|
+
calculated_at
|
|
10
|
+
)
|
|
11
|
+
select reservation.tenant_id, reservation.id, now()
|
|
12
|
+
from public.reservation as reservation
|
|
13
|
+
where reservation.tenant_id is not null
|
|
14
|
+
on conflict (reservation_id) do nothing
|
|
15
|
+
`.execute(db);
|
|
16
|
+
|
|
17
|
+
await sql`
|
|
18
|
+
with outstanding as (
|
|
19
|
+
select
|
|
20
|
+
effect.tenant_id,
|
|
21
|
+
effect.entity_id::uuid as reservation_id,
|
|
22
|
+
effect.action_id,
|
|
23
|
+
effect.id as effect_id,
|
|
24
|
+
effect.root_entity_type,
|
|
25
|
+
effect.root_entity_id,
|
|
26
|
+
effect.created_at,
|
|
27
|
+
effect.completed_at,
|
|
28
|
+
effect.status,
|
|
29
|
+
(
|
|
30
|
+
select attempt.status
|
|
31
|
+
from audit.effect_attempt as attempt
|
|
32
|
+
where attempt.tenant_id = effect.tenant_id
|
|
33
|
+
and attempt.effect_id = effect.id
|
|
34
|
+
order by attempt.attempt_num desc
|
|
35
|
+
limit 1
|
|
36
|
+
) as latest_attempt_status,
|
|
37
|
+
row_number() over (
|
|
38
|
+
partition by effect.tenant_id, effect.entity_id
|
|
39
|
+
order by effect.created_at, effect.id
|
|
40
|
+
) as revision
|
|
41
|
+
from audit.effect as effect
|
|
42
|
+
inner join public.reservation as reservation
|
|
43
|
+
on reservation.id = effect.entity_id
|
|
44
|
+
and reservation.tenant_id = effect.tenant_id
|
|
45
|
+
where effect.effect_type = 'REFRESH_RESERVATION_JOURNAL'
|
|
46
|
+
and effect.entity_type = 'reservation'
|
|
47
|
+
)
|
|
48
|
+
insert into accounting.reservation_journal_invalidation (
|
|
49
|
+
tenant_id,
|
|
50
|
+
reservation_id,
|
|
51
|
+
revision,
|
|
52
|
+
action_id,
|
|
53
|
+
effect_id,
|
|
54
|
+
source_resource_type,
|
|
55
|
+
source_resource_id,
|
|
56
|
+
applied_at,
|
|
57
|
+
covered_by_effect_id,
|
|
58
|
+
created_at
|
|
59
|
+
)
|
|
60
|
+
select
|
|
61
|
+
outstanding.tenant_id,
|
|
62
|
+
outstanding.reservation_id,
|
|
63
|
+
outstanding.revision,
|
|
64
|
+
outstanding.action_id,
|
|
65
|
+
outstanding.effect_id,
|
|
66
|
+
case outstanding.root_entity_type
|
|
67
|
+
when 'recurringFee' then 'recurring-fee'::core.operation_resource_type
|
|
68
|
+
when 'reservation' then 'reservation'::core.operation_resource_type
|
|
69
|
+
when 'listing' then 'listing'::core.operation_resource_type
|
|
70
|
+
when 'ownerStatement' then 'statement'::core.operation_resource_type
|
|
71
|
+
else 'team'::core.operation_resource_type
|
|
72
|
+
end,
|
|
73
|
+
case
|
|
74
|
+
when outstanding.root_entity_type in (
|
|
75
|
+
'recurringFee',
|
|
76
|
+
'reservation',
|
|
77
|
+
'listing',
|
|
78
|
+
'ownerStatement'
|
|
79
|
+
) then outstanding.root_entity_id
|
|
80
|
+
else outstanding.tenant_id
|
|
81
|
+
end,
|
|
82
|
+
case
|
|
83
|
+
when outstanding.status = 'completed'
|
|
84
|
+
and outstanding.latest_attempt_status is distinct from 'skipped_locked'
|
|
85
|
+
then outstanding.completed_at
|
|
86
|
+
else null
|
|
87
|
+
end,
|
|
88
|
+
case
|
|
89
|
+
when outstanding.status = 'completed'
|
|
90
|
+
and outstanding.latest_attempt_status is distinct from 'skipped_locked'
|
|
91
|
+
then outstanding.effect_id
|
|
92
|
+
else null
|
|
93
|
+
end,
|
|
94
|
+
outstanding.created_at
|
|
95
|
+
from outstanding
|
|
96
|
+
on conflict (effect_id) do nothing
|
|
97
|
+
`.execute(db);
|
|
98
|
+
|
|
99
|
+
await sql`
|
|
100
|
+
update accounting.reservation_journal_state as state
|
|
101
|
+
set
|
|
102
|
+
desired_revision = revisions.desired_revision,
|
|
103
|
+
applied_revision = revisions.applied_revision,
|
|
104
|
+
stale_since = revisions.stale_since,
|
|
105
|
+
calculated_at = coalesce(revisions.calculated_at, state.calculated_at),
|
|
106
|
+
updated_at = now()
|
|
107
|
+
from (
|
|
108
|
+
select
|
|
109
|
+
tenant_id,
|
|
110
|
+
reservation_id,
|
|
111
|
+
max(revision) as desired_revision,
|
|
112
|
+
coalesce(
|
|
113
|
+
min(revision) filter (where applied_at is null) - 1,
|
|
114
|
+
max(revision)
|
|
115
|
+
) as applied_revision,
|
|
116
|
+
min(created_at) filter (where applied_at is null) as stale_since,
|
|
117
|
+
max(applied_at) as calculated_at
|
|
118
|
+
from accounting.reservation_journal_invalidation
|
|
119
|
+
group by tenant_id, reservation_id
|
|
120
|
+
) as revisions
|
|
121
|
+
where state.tenant_id = revisions.tenant_id
|
|
122
|
+
and state.reservation_id = revisions.reservation_id
|
|
123
|
+
`.execute(db);
|
|
124
|
+
|
|
125
|
+
await sql`
|
|
126
|
+
with reservation_scope as (
|
|
127
|
+
select
|
|
128
|
+
invalidation.id as invalidation_id,
|
|
129
|
+
invalidation.tenant_id,
|
|
130
|
+
reservation.id as reservation_id,
|
|
131
|
+
listing_scope.listing_id,
|
|
132
|
+
coalesce(reservation.currency, tenant.default_currency) as currency,
|
|
133
|
+
least(
|
|
134
|
+
reservation.effective_check_in,
|
|
135
|
+
reservation.effective_check_out,
|
|
136
|
+
reservation.booked_at,
|
|
137
|
+
reservation.general_ledger_posting_at,
|
|
138
|
+
reservation.created_at,
|
|
139
|
+
line_bounds.minimum_at,
|
|
140
|
+
entry_bounds.minimum_at
|
|
141
|
+
) as minimum_at,
|
|
142
|
+
greatest(
|
|
143
|
+
reservation.effective_check_in,
|
|
144
|
+
reservation.effective_check_out,
|
|
145
|
+
reservation.booked_at,
|
|
146
|
+
reservation.general_ledger_posting_at,
|
|
147
|
+
reservation.created_at,
|
|
148
|
+
line_bounds.maximum_at,
|
|
149
|
+
entry_bounds.maximum_at
|
|
150
|
+
) as maximum_at
|
|
151
|
+
from accounting.reservation_journal_invalidation as invalidation
|
|
152
|
+
inner join public.reservation as reservation
|
|
153
|
+
on reservation.id = invalidation.reservation_id
|
|
154
|
+
and reservation.tenant_id = invalidation.tenant_id
|
|
155
|
+
inner join public.tenant as tenant
|
|
156
|
+
on tenant.id = invalidation.tenant_id
|
|
157
|
+
inner join lateral (
|
|
158
|
+
select coalesce(listing.parent_id, reservation.listing_id) as listing_id
|
|
159
|
+
from public.listing as listing
|
|
160
|
+
where listing.id = reservation.listing_id
|
|
161
|
+
union
|
|
162
|
+
select distinct coalesce(entry_listing.parent_id, entry.listing_id)
|
|
163
|
+
from accounting.journal_entry as entry
|
|
164
|
+
left join public.listing as entry_listing
|
|
165
|
+
on entry_listing.id = entry.listing_id
|
|
166
|
+
where entry.tenant_id = invalidation.tenant_id
|
|
167
|
+
and entry.reservation_id = invalidation.reservation_id
|
|
168
|
+
and entry.listing_id is not null
|
|
169
|
+
) as listing_scope on true
|
|
170
|
+
left join lateral (
|
|
171
|
+
select
|
|
172
|
+
min(line.general_ledger_posting_at) as minimum_at,
|
|
173
|
+
max(line.general_ledger_posting_at) as maximum_at
|
|
174
|
+
from public.payment_line as line
|
|
175
|
+
where line.tenant_id = invalidation.tenant_id
|
|
176
|
+
and line.reservation_id = invalidation.reservation_id
|
|
177
|
+
) as line_bounds on true
|
|
178
|
+
left join lateral (
|
|
179
|
+
select
|
|
180
|
+
min(entry.txn_at) as minimum_at,
|
|
181
|
+
max(entry.txn_at) as maximum_at
|
|
182
|
+
from accounting.journal_entry as entry
|
|
183
|
+
where entry.tenant_id = invalidation.tenant_id
|
|
184
|
+
and entry.reservation_id = invalidation.reservation_id
|
|
185
|
+
) as entry_bounds on true
|
|
186
|
+
where invalidation.applied_at is null
|
|
187
|
+
and listing_scope.listing_id is not null
|
|
188
|
+
), currencies as (
|
|
189
|
+
select
|
|
190
|
+
scope.invalidation_id,
|
|
191
|
+
scope.tenant_id,
|
|
192
|
+
scope.listing_id,
|
|
193
|
+
scope.minimum_at,
|
|
194
|
+
scope.maximum_at,
|
|
195
|
+
scope.currency
|
|
196
|
+
from reservation_scope as scope
|
|
197
|
+
where scope.currency is not null
|
|
198
|
+
union
|
|
199
|
+
select
|
|
200
|
+
scope.invalidation_id,
|
|
201
|
+
scope.tenant_id,
|
|
202
|
+
scope.listing_id,
|
|
203
|
+
scope.minimum_at,
|
|
204
|
+
scope.maximum_at,
|
|
205
|
+
entry.currency
|
|
206
|
+
from reservation_scope as scope
|
|
207
|
+
inner join accounting.journal_entry as entry
|
|
208
|
+
on entry.tenant_id = scope.tenant_id
|
|
209
|
+
and entry.reservation_id = scope.reservation_id
|
|
210
|
+
), months as (
|
|
211
|
+
select
|
|
212
|
+
currencies.*,
|
|
213
|
+
month::date as month
|
|
214
|
+
from currencies
|
|
215
|
+
cross join lateral generate_series(
|
|
216
|
+
date_trunc('month', currencies.minimum_at),
|
|
217
|
+
date_trunc('month', currencies.maximum_at),
|
|
218
|
+
interval '1 month'
|
|
219
|
+
) as month
|
|
220
|
+
where currencies.minimum_at is not null
|
|
221
|
+
and currencies.maximum_at is not null
|
|
222
|
+
)
|
|
223
|
+
insert into accounting.reservation_journal_statement_impact (
|
|
224
|
+
invalidation_id,
|
|
225
|
+
tenant_id,
|
|
226
|
+
listing_id,
|
|
227
|
+
listing_ownership_period_id,
|
|
228
|
+
month,
|
|
229
|
+
currency
|
|
230
|
+
)
|
|
231
|
+
select distinct
|
|
232
|
+
months.invalidation_id,
|
|
233
|
+
months.tenant_id,
|
|
234
|
+
months.listing_id,
|
|
235
|
+
ownership.id,
|
|
236
|
+
months.month,
|
|
237
|
+
months.currency
|
|
238
|
+
from months
|
|
239
|
+
inner join public.listing_ownership_period as ownership
|
|
240
|
+
on ownership.tenant_id = months.tenant_id
|
|
241
|
+
and ownership.listing_id = months.listing_id
|
|
242
|
+
and (
|
|
243
|
+
ownership.start_at is null
|
|
244
|
+
or ownership.start_at < months.month + interval '1 month'
|
|
245
|
+
)
|
|
246
|
+
and (
|
|
247
|
+
ownership.end_at is null
|
|
248
|
+
or ownership.end_at > months.month
|
|
249
|
+
)
|
|
250
|
+
on conflict do nothing
|
|
251
|
+
`.execute(db);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export async function down(_db: Kysely<unknown>): Promise<void> {}
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
with desired_revisions as (
|
|
7
|
+
select
|
|
8
|
+
state.tenant_id,
|
|
9
|
+
state.reservation_id,
|
|
10
|
+
max(invalidation.revision) as desired_revision
|
|
11
|
+
from accounting.reservation_journal_state as state
|
|
12
|
+
inner join accounting.reservation_journal_invalidation as invalidation
|
|
13
|
+
on invalidation.tenant_id = state.tenant_id
|
|
14
|
+
and invalidation.reservation_id = state.reservation_id
|
|
15
|
+
and invalidation.revision > state.desired_revision
|
|
16
|
+
group by state.tenant_id, state.reservation_id
|
|
17
|
+
)
|
|
18
|
+
update accounting.reservation_journal_state as state
|
|
19
|
+
set
|
|
20
|
+
desired_revision = greatest(
|
|
21
|
+
state.desired_revision,
|
|
22
|
+
desired_revisions.desired_revision
|
|
23
|
+
),
|
|
24
|
+
updated_at = now()
|
|
25
|
+
from desired_revisions
|
|
26
|
+
where state.tenant_id = desired_revisions.tenant_id
|
|
27
|
+
and state.reservation_id = desired_revisions.reservation_id
|
|
28
|
+
and state.desired_revision < desired_revisions.desired_revision
|
|
29
|
+
`.execute(db);
|
|
30
|
+
|
|
31
|
+
await sql`
|
|
32
|
+
with advancement as (
|
|
33
|
+
select
|
|
34
|
+
state.tenant_id,
|
|
35
|
+
state.reservation_id,
|
|
36
|
+
coalesce(
|
|
37
|
+
min(invalidation.revision) filter (
|
|
38
|
+
where invalidation.applied_at is null
|
|
39
|
+
) - 1,
|
|
40
|
+
max(invalidation.revision),
|
|
41
|
+
state.applied_revision
|
|
42
|
+
) as applied_revision,
|
|
43
|
+
min(invalidation.created_at) filter (
|
|
44
|
+
where invalidation.applied_at is null
|
|
45
|
+
) as stale_since,
|
|
46
|
+
max(invalidation.applied_at) as calculated_at
|
|
47
|
+
from accounting.reservation_journal_state as state
|
|
48
|
+
left join accounting.reservation_journal_invalidation as invalidation
|
|
49
|
+
on invalidation.tenant_id = state.tenant_id
|
|
50
|
+
and invalidation.reservation_id = state.reservation_id
|
|
51
|
+
where state.desired_revision > state.applied_revision
|
|
52
|
+
group by
|
|
53
|
+
state.tenant_id,
|
|
54
|
+
state.reservation_id,
|
|
55
|
+
state.applied_revision
|
|
56
|
+
)
|
|
57
|
+
update accounting.reservation_journal_state as state
|
|
58
|
+
set
|
|
59
|
+
applied_revision = greatest(
|
|
60
|
+
state.applied_revision,
|
|
61
|
+
advancement.applied_revision
|
|
62
|
+
),
|
|
63
|
+
stale_since = case
|
|
64
|
+
when greatest(
|
|
65
|
+
state.applied_revision,
|
|
66
|
+
advancement.applied_revision
|
|
67
|
+
) >= state.desired_revision then null
|
|
68
|
+
else coalesce(state.stale_since, advancement.stale_since)
|
|
69
|
+
end,
|
|
70
|
+
calculated_at = case
|
|
71
|
+
when advancement.applied_revision > state.applied_revision
|
|
72
|
+
then greatest(state.calculated_at, advancement.calculated_at)
|
|
73
|
+
else state.calculated_at
|
|
74
|
+
end,
|
|
75
|
+
updated_at = now()
|
|
76
|
+
from advancement
|
|
77
|
+
where state.tenant_id = advancement.tenant_id
|
|
78
|
+
and state.reservation_id = advancement.reservation_id
|
|
79
|
+
and state.applied_revision < advancement.applied_revision
|
|
80
|
+
`.execute(db);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export async function down(_db: Kysely<unknown>): Promise<void> {}
|