public
imalexnord
read
Slot
Calendar-first scheduling powered by Cloudflare Workers and Google Calendar.
Languages
Repository composition by tracked source files.
TypeScript
79%
CSS
19%
SQL
2%
HTML
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/user/imalexnord/slot.git
ssh://[email protected]:2222/user/imalexnord/slot.git
Trace
migrations/0005_activity.sql
Trace helps you understand code history line by line. See who changed each line, when it changed, and which commit introduced it.
Author
Date
Commit
Line
Code
1
CREATE TABLE IF NOT EXISTS activity_events (
2
id TEXT PRIMARY KEY,
3
booking_id TEXT,
4
type TEXT NOT NULL,
5
occurred_at TEXT NOT NULL DEFAULT (datetime('now')),
6
metadata TEXT,
7
idempotency_key TEXT
8
);
10
CREATE INDEX IF NOT EXISTS idx_activity_events_occurred_at
11
ON activity_events(occurred_at DESC);
12
CREATE INDEX IF NOT EXISTS idx_activity_events_booking_id
13
ON activity_events(booking_id);
14
CREATE UNIQUE INDEX IF NOT EXISTS idx_activity_events_idempotency_key
15
ON activity_events(idempotency_key)
16
WHERE idempotency_key IS NOT NULL;
18
-- Backfill the lifecycle points that can be reconstructed safely from existing
19
-- booking rows. Future changes are recorded as first-class activity events.
20
INSERT OR IGNORE INTO activity_events (id, booking_id, type, occurred_at, metadata, idempotency_key)
21
SELECT
22
'backfill-confirmed-' || id,
23
id,
24
'booking_confirmed',
25
created_at,
26
'{"backfilled":true}',
27
'booking:' || id || ':confirmed'
28
FROM bookings
29
WHERE status = 'confirmed'
30
OR (status = 'cancelled' AND (payment_status <> 'cancelled' OR paid_at IS NOT NULL));
32
INSERT OR IGNORE INTO activity_events (id, booking_id, type, occurred_at, metadata, idempotency_key)
33
SELECT
34
'backfill-paid-' || id,
35
id,
36
'payment_received',
37
paid_at,
38
'{"backfilled":true}',
39
'booking:' || id || ':paid'
40
FROM bookings
41
WHERE paid_at IS NOT NULL;
43
INSERT OR IGNORE INTO activity_events (id, booking_id, type, occurred_at, metadata, idempotency_key)
44
SELECT
45
'backfill-rescheduled-' || id,
46
id,
47
'booking_rescheduled',
48
rescheduled_at,
49
json_object('backfilled', 1, 'count', reschedule_count),
50
'booking:' || id || ':reschedule-backfill'
51
FROM bookings
52
WHERE rescheduled_at IS NOT NULL AND reschedule_count > 0;
54
INSERT OR IGNORE INTO activity_events (id, booking_id, type, occurred_at, metadata, idempotency_key)
55
SELECT
56
'backfill-suggested-' || id,
57
id,
58
'time_suggested',
59
proposed_at,
60
json_object('backfilled', 1, 'proposedStart', proposed_start_time, 'proposedEnd', proposed_end_time),
61
'booking:' || id || ':suggestion-backfill'
62
FROM bookings
63
WHERE proposed_at IS NOT NULL;
65
INSERT OR IGNORE INTO activity_events (id, booking_id, type, occurred_at, metadata, idempotency_key)
66
SELECT
67
'backfill-refunded-' || id,
68
id,
69
'refund_succeeded',
70
refunded_at,
71
json_object('backfilled', 1, 'amount', refunded_amount, 'currency', payment_currency),
72
CASE WHEN stripe_refund_id IS NOT NULL THEN 'refund:' || stripe_refund_id || ':succeeded' ELSE 'booking:' || id || ':refund-backfill' END
73
FROM bookings
74
WHERE refunded_at IS NOT NULL;
76
INSERT OR IGNORE INTO activity_events (id, booking_id, type, occurred_at, metadata, idempotency_key)
77
SELECT
78
'backfill-cancelled-' || id,
79
id,
80
CASE WHEN payment_status = 'cancelled' AND paid_at IS NULL THEN 'payment_hold_released' ELSE 'booking_cancelled' END,
81
cancelled_at,
82
'{"backfilled":true}',
83
'booking:' || id || ':cancelled'
84
FROM bookings
85
WHERE cancelled_at IS NOT NULL;