diff --git a/init-scripts/init-script.sql b/init-scripts/init-script.sql index 9e113ce..b05bd83 100644 --- a/init-scripts/init-script.sql +++ b/init-scripts/init-script.sql @@ -215,7 +215,7 @@ CREATE TABLE users ( loyalty_stamps INT NOT NULL DEFAULT 0, referral_code CHAR(12) UNIQUE DEFAULT generate_referral_code(), -- GDPR fields - privacy_policy_and_terms_consent BOOLEAN NOT NULL DEFAULT TRUE, + privacy_policy_and_terms_consent BOOLEAN NOT NULL DEFAULT FALSE, policy_consent_updated_at TIMESTAMPTZ DEFAULT NOW(), -- UK GDPR: consent must be freely given, specific and unambiguous — it is -- OPT-IN, never a pre-ticked default. New users start with FALSE until they @@ -240,7 +240,7 @@ CREATE TABLE users ( two_factor_pending_code_expires TIMESTAMPTZ, two_factor_last_used_at TIMESTAMPTZ, -- staff fields - notes TEXT + notes TEXT -- protected health data. do not wipe ); CREATE TABLE user_social_logins ( @@ -1171,6 +1171,56 @@ BEGIN WHERE payment_id IN (SELECT id FROM payments WHERE created_by = target_id OR booking_id IN (SELECT id FROM bookings WHERE user_id = target_id)); + + -- Scrub bookings.created_by (free-text administrative link) + UPDATE bookings SET created_by = NULL WHERE created_by = target_id; + + -- Scrub booking_edit_requests.requested_by + UPDATE booking_edit_requests SET requested_by = NULL WHERE requested_by = target_id; + + -- Scrub referral_discounts.user_id (ON DELETE CASCADE never fires — user is kept) + UPDATE referral_discounts SET user_id = target_id WHERE user_id = target_id; + + -- Scrub default_hours_scheduled_changes.created_by + UPDATE default_hours_scheduled_changes SET created_by = NULL WHERE created_by = target_id; + + -- Scrub forgiven_no_shows.forgiven_by (no FK — free-text admin link) + UPDATE forgiven_no_shows SET forgiven_by = NULL WHERE forgiven_by = target_id; + + -- Scrub loyalty_redemptions.user_id + UPDATE loyalty_redemptions SET user_id = NULL WHERE user_id = target_id; + + -- Scrub discount_campaigns.created_by + UPDATE discount_campaigns SET created_by = NULL WHERE created_by = target_id; + + -- Scrub booking_discounts.user_id + UPDATE booking_discounts SET user_id = NULL WHERE user_id = target_id; + + -- Scrub refunds.free-text reason (created_by kept for HMRC audit trail) + UPDATE refunds SET reason = 'REDACTED' WHERE created_by = target_id; + + -- Scrub till_sales.notes (free-text PII — financial row survives) + UPDATE till_sales SET notes = NULL WHERE created_by = target_id; + + -- Scrub gift_cards.created_by and redeemed_by + UPDATE gift_cards SET created_by = NULL WHERE created_by = target_id; + UPDATE gift_cards SET redeemed_by = NULL WHERE redeemed_by = target_id; + + -- Scrub gift_card_transactions free-text notes (user_id kept for HMRC audit) + UPDATE gift_card_transactions SET notes = NULL WHERE user_id = target_id; + + -- Zero gift card balance (row survives for CleanupIdleAccounts flow) + UPDATE user_giftcard_balances SET balance = 0 WHERE user_id = target_id; + + -- Scrub affiliate_payouts.affiliate_id + UPDATE affiliate_payouts SET affiliate_id = NULL WHERE affiliate_id = target_id; + + -- Scrub gift_card_expired_balances.claimed_by_admin (admin PII) + UPDATE gift_card_expired_balances SET claimed_by_admin = NULL WHERE claimed_by_admin = target_id; + + -- Scrub custom_services.created_by and free-text notes + UPDATE custom_services SET created_by = NULL WHERE created_by = target_id; + UPDATE custom_services SET notes = NULL WHERE created_by = target_id; END; $$ LANGUAGE plpgsql; @@ -1246,6 +1296,13 @@ BEGIN UPDATE admin_audit_log SET target_user_id = NULL WHERE target_user_id = target_id; UPDATE admin_audit_log SET admin_id = NULL WHERE admin_id = target_id; + -- Scrub free-text dispute reason linked to this guest's payments + UPDATE disputes + SET reason = NULL + WHERE payment_id IN (SELECT id FROM payments + WHERE created_by = target_id + OR booking_id IN (SELECT id FROM bookings WHERE user_id = target_id)); + DELETE FROM users WHERE id = target_id AND account_role = 'guest'; END; $$ LANGUAGE plpgsql; @@ -2809,4 +2866,3 @@ CREATE TABLE IF NOT EXISTS pending_s3_deletions ( ); CREATE INDEX IF NOT EXISTS idx_pending_s3_deletions_created_at ON pending_s3_deletions (created_at); -