refactor(bookings): use computed booking fields and LATERAL joins
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -428,16 +428,19 @@ func GetAllUserBookingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
dataQuery := `
|
||||
SELECT
|
||||
b.id, b.start_time, b.status, b.notes, b.created_at, b.updated_at, b.created_by,
|
||||
(SELECT total_amount FROM bookings WHERE id = b.id) AS total_amount,
|
||||
(SELECT COALESCE(SUM(amount), 0)
|
||||
FROM payments
|
||||
WHERE booking_id = b.id AND status = 'completed') AS amount_paid,
|
||||
(SELECT total_duration_minutes FROM bookings WHERE id = b.id) AS duration_minutes,
|
||||
b.total_amount,
|
||||
COALESCE(pt.amount_paid, 0) AS amount_paid,
|
||||
b.total_duration_minutes AS duration_minutes,
|
||||
b.deposit_required,
|
||||
(SELECT COALESCE(SUM(amount), 0)
|
||||
COALESCE(pt.pre_start_amount_paid, 0) AS pre_start_amount_paid
|
||||
FROM bookings b
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
COALESCE(SUM(amount) FILTER (WHERE status = 'completed'), 0) AS amount_paid,
|
||||
COALESCE(SUM(amount) FILTER (WHERE status = 'completed' AND created_at < b.start_time), 0) AS pre_start_amount_paid
|
||||
FROM payments
|
||||
WHERE booking_id = b.id AND status = 'completed' AND created_at < b.start_time) AS pre_start_amount_paid
|
||||
FROM bookings b` + whereClause
|
||||
WHERE booking_id = b.id
|
||||
) pt ON true` + whereClause
|
||||
|
||||
dataArgs := make([]interface{}, len(whereArgs))
|
||||
copy(dataArgs, whereArgs)
|
||||
@@ -662,13 +665,16 @@ func GetAllAdminBookingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
COALESCE(bt.total_amount, 0) - COALESCE(pt.total_paid, 0) AS amount_due,
|
||||
b.deposit_required,
|
||||
COALESCE(bt.service_count, 0) AS service_count,
|
||||
(SELECT COALESCE(SUM(p2.amount), 0)
|
||||
FROM payments p2
|
||||
WHERE p2.booking_id = b.id AND p2.status = 'completed' AND p2.created_at < b.start_time) AS pre_start_amount_paid
|
||||
COALESCE(pre_pay.pre_start_amount_paid, 0) AS pre_start_amount_paid
|
||||
FROM bookings b
|
||||
LEFT JOIN users u ON b.user_id = u.id
|
||||
LEFT JOIN booking_totals bt ON b.id = bt.booking_id
|
||||
LEFT JOIN payment_totals pt ON b.id = pt.booking_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT COALESCE(SUM(amount), 0) AS pre_start_amount_paid
|
||||
FROM payments
|
||||
WHERE booking_id = b.id AND status = 'completed' AND created_at < b.start_time
|
||||
) pre_pay ON true
|
||||
`
|
||||
|
||||
var args []interface{}
|
||||
@@ -1734,13 +1740,16 @@ func SearchAdminBookingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
COALESCE(pt.total_paid, 0) AS amount_paid,
|
||||
COALESCE(bt.total_amount, 0) - COALESCE(pt.total_paid, 0) AS amount_due,
|
||||
b.deposit_required,
|
||||
(SELECT COALESCE(SUM(p2.amount), 0)
|
||||
FROM payments p2
|
||||
WHERE p2.booking_id = b.id AND p2.status = 'completed' AND p2.created_at < b.start_time) AS pre_start_amount_paid
|
||||
COALESCE(pre_pay.pre_start_amount_paid, 0) AS pre_start_amount_paid
|
||||
FROM bookings b
|
||||
LEFT JOIN users u ON b.user_id = u.id
|
||||
LEFT JOIN booking_totals bt ON b.id = bt.booking_id
|
||||
LEFT JOIN payment_totals pt ON b.id = pt.booking_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT COALESCE(SUM(amount), 0) AS pre_start_amount_paid
|
||||
FROM payments
|
||||
WHERE booking_id = b.id AND status = 'completed' AND created_at < b.start_time
|
||||
) pre_pay ON true
|
||||
-- NOTE: ILIKE with leading wildcard prevents B-tree index usage.
|
||||
-- At scale, replace with pg_trgm GIN index: CREATE INDEX idx_bookings_search_trgm ON bookings USING GIN (id gin_trgm_ops, notes gin_trgm_ops);
|
||||
-- Also consider indexes on users (n_first_name, n_last_name, fn, email, phone) for the joined table.
|
||||
|
||||
Reference in New Issue
Block a user