Backfill PATs seven_days_notification_sent_at column
What does this MR do and why?
Backfill PATs seven_days_notification_sent_at column. Part 2 of a multi-MR database change.
Includes a batched background migration to backfill the column using the
expired_at dates. Also creates a temporary index for the BBM.
Changes PersonalAccessTokens::ExpiringWorker to dual-write to both
the legacy expire_notification_delivered boolean column and the replacement
seven_days_notification_sent_at column.
- Part 1 here, implementing new columns: !165257 (merged)
- Broken out from this MR: !163818 (closed)
- Part 3 will be !166683 (merged)
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Database Review
Migration test results comment quick-link
Two existing update_all queries are updated to write to two columns instead of one:
Update personal_access_tokens expire_notification_delivered and seven_days_notification_sent_at
UPDATE "personal_access_tokens" SET "expire_notification_delivered" = TRUE, "seven_days_notification_sent_at" = '2024-09-11 04:57:01.960750' WHERE "personal_access_tokens"."id" IN (SELECT "personal_access_tokens"."id" FROM "personal_access_tokens" LEFT OUTER JOIN "users" ON "users"."id" = "personal_access_tokens"."user_id" WHERE 1=1 AND ((revoked = false AND expire_notification_delivered = false AND expires_at >= CURRENT_DATE AND expires_at <= '2024-09-18') and impersonation = false) AND "users"."user_type" = 6 AND 1=1 LIMIT 100)The batched background migration uses a scope and temporary index to backfill seven_days_notification_sent_at for personal_access_token rows where expire_notification_delivered is true :
Update personal_access_tokens seven_days_notification_sent_at
UPDATE "personal_access_tokens" SET seven_days_notification_sent_at = (expires_at - interval '7 days') WHERE "personal_access_tokens"."expire_notification_delivered" = TRUE AND "personal_access_tokens"."seven_days_notification_sent_at" IS NULL AND "personal_access_tokens"."expires_at" IS NOT NULL AND "personal_access_tokens"."id" BETWEEN 1 AND 31How to set up and validate locally
- Run migrations; ensure background migration completes
- Check for seven_days_notification_sent_atvalues inPersonalAccessTokenin the rails console:# should show a record with expiry notification sent PersonalAccessToken.where.not(seven_days_notification_sent_at: nil).first # should return 0 PersonalAccessToken.where(expire_notification_delivered: true, seven_days_notification_sent_at: nil).count
- Create a new personal, group, or project access token that expires tomorrow
- Run the ExpiringWorker-PersonalAccessTokens::ExpiringWorker.new.perform
- Ensure the new token has both expire_notification_deliveredandseven_days_notification_sent_atset
Related to #464040 (closed)