diff --git a/backend/handlers/scheduling/default-hours.go b/backend/handlers/scheduling/default-hours.go index a4645f5..3927e7c 100644 --- a/backend/handlers/scheduling/default-hours.go +++ b/backend/handlers/scheduling/default-hours.go @@ -317,6 +317,11 @@ func GetAvailableHours(w http.ResponseWriter, r *http.Request) { log.Printf("Failed to anonymize stale guest accounts: %v", err) } + // Clean up expired loyalty redemptions (pending past expires_at) + if err := CleanupExpiredLoyaltyRedemptions(r.Context()); err != nil { + log.Printf("Failed to cleanup expired loyalty redemptions: %v", err) + } + // Load default hours defaultMap := map[int]DefaultHours{} defRows, _ := db.DB.Query(r.Context(), `SELECT weekday, start_time::text, end_time::text, is_open FROM working_hours`) diff --git a/backend/handlers/scheduling/time-blockers.go b/backend/handlers/scheduling/time-blockers.go index 2bf9107..9c0ac93 100644 --- a/backend/handlers/scheduling/time-blockers.go +++ b/backend/handlers/scheduling/time-blockers.go @@ -391,5 +391,69 @@ func AnonymizeStaleGuestAccounts(ctx context.Context) error { HAVING MAX(start_time) < NOW() - INTERVAL '6 months' ) `) + if err != nil { + return err + } + + // Anonymize patch test records for stale guests (medical-adjacent PII) + _, err = db.DB.Exec(ctx, ` + UPDATE user_patch_tests SET user_id = NULL + WHERE user_id IN ( + SELECT id FROM users + WHERE account_role = 'guest' + AND n_first_name = 'Guest' + AND n_last_name = 'Anonymized' + ) + `) + if err != nil { + return err + } + + // Anonymize referral relationships for stale guests + _, err = db.DB.Exec(ctx, ` + UPDATE user_referrals SET referrer_id = NULL + WHERE referrer_id IN ( + SELECT id FROM users + WHERE account_role = 'guest' + AND n_first_name = 'Guest' + AND n_last_name = 'Anonymized' + ) + `) + if err != nil { + return err + } + + _, err = db.DB.Exec(ctx, ` + UPDATE user_referrals SET referred_id = NULL + WHERE referred_id IN ( + SELECT id FROM users + WHERE account_role = 'guest' + AND n_first_name = 'Guest' + AND n_last_name = 'Anonymized' + ) + `) + if err != nil { + return err + } + + // Anonymize admin notification references for stale guests + _, err = db.DB.Exec(ctx, ` + UPDATE admin_notifications SET user_id = NULL + WHERE user_id IN ( + SELECT id FROM users + WHERE account_role = 'guest' + AND n_first_name = 'Guest' + AND n_last_name = 'Anonymized' + ) + `) + return err +} + +func CleanupExpiredLoyaltyRedemptions(ctx context.Context) error { + _, err := db.DB.Exec(ctx, ` + DELETE FROM loyalty_redemptions + WHERE status = 'pending' + AND expires_at < NOW() + `) return err }