38 lines
2.0 KiB
SQL
38 lines
2.0 KiB
SQL
-- Additive migration: old releases can still read their original email column.
|
|
-- Runtime identity is always account(provider_id, account_id), never an email pattern.
|
|
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS contact_email text;
|
|
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS root_admin boolean NOT NULL DEFAULT false;
|
|
ALTER TABLE "user" ADD COLUMN IF NOT EXISTS merged_into_user_id text;
|
|
ALTER TABLE account ADD COLUMN IF NOT EXISTS profile jsonb;
|
|
|
|
UPDATE "user" SET contact_email = lower(email)
|
|
WHERE contact_email IS NULL AND email !~* '@(osu\.local|discord\.local|identity\.invalid)$';
|
|
CREATE UNIQUE INDEX IF NOT EXISTS user_contact_email_unique ON "user" (contact_email);
|
|
|
|
-- Fail the transaction for conflicting connections; never guess which user owns one.
|
|
CREATE UNIQUE INDEX IF NOT EXISTS account_provider_identity_idx ON account (provider_id, account_id);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS account_user_provider_idx ON account (user_id, provider_id);
|
|
|
|
-- Profile backfill is best effort; OAuth refreshes it on the next successful sign-in.
|
|
UPDATE account a SET profile = jsonb_build_object(
|
|
'username', u.name, 'image', u.image, 'email', null, 'emailVerified', false,
|
|
'countryCode', u.country_code, 'globalRank', r.osu_rank_at_seed
|
|
)
|
|
FROM "user" u LEFT JOIN player_rating r ON r.user_id = u.id
|
|
WHERE a.user_id = u.id AND a.provider_id IN ('osu', 'discord') AND a.profile IS NULL;
|
|
|
|
-- Repair solo roster snapshots only where ownership is unambiguous. Match discovery
|
|
-- and authorization can then use the same persisted participant roster.
|
|
INSERT INTO team_member (team_id, user_id, role)
|
|
SELECT t.id, t.owner_id, 'owner' FROM team t
|
|
JOIN "user" u ON u.id = t.owner_id
|
|
WHERE t.is_personal AND NOT EXISTS (
|
|
SELECT 1 FROM team_member tm WHERE tm.team_id = t.id AND tm.user_id = t.owner_id
|
|
);
|
|
INSERT INTO match_participant_player (participant_id, user_id)
|
|
SELECT p.id, t.owner_id FROM match_participant p JOIN team t ON t.id = p.team_id
|
|
JOIN "user" u ON u.id = t.owner_id
|
|
WHERE t.is_personal AND NOT EXISTS (
|
|
SELECT 1 FROM match_participant_player pp WHERE pp.participant_id = p.id
|
|
);
|