Read calendar event creators from the admin module, and archive the old ones (#14)
Jenkins Production Deployment
Jenkins Production Deployment
Reviewed-on: #14 Co-authored-by: Patrick Müller <mail@pmueller.me> Co-committed-by: Patrick Müller <mail@pmueller.me>
This commit was merged in pull request #14.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
-- Nachklang e.V. Calendar module — step 1 of docs/calendar-auth-migration.md.
|
||||
-- Adds the bridging columns that let an event record who created it as an
|
||||
-- *admin* user id (VARCHAR(36)) alongside the legacy calendar users.user_id
|
||||
-- (INT). Apply manually against the CALENDAR_DB database:
|
||||
-- mysql -h <DB_HOST> -u <DB_USER> -p <CALENDAR_DB> < 001_add_admin_user_bridge.sql
|
||||
--
|
||||
-- Numbered 001 because this is the first migration this repo owns for the
|
||||
-- calendar schema: the tables themselves predate it and were provided by the
|
||||
-- repo owner (mirrored for dev in docker/init/01-calendar-schema-dev.sql).
|
||||
--
|
||||
-- Nothing reads these columns yet — step 3 introduces the dual-read. Adding
|
||||
-- them first means the backfill in step 2 has somewhere to write, and this
|
||||
-- migration can be applied to production on its own without any code change.
|
||||
--
|
||||
-- No foreign key, on purpose. The admin `user` table lives in a *different*
|
||||
-- database (nachklang_admin) behind a different connection pool, and a
|
||||
-- cross-schema FK would tie the two schemas' lifecycles together: you could no
|
||||
-- longer dump, restore or move one without the other. The reference is
|
||||
-- enforced in application code, which is also where the legacy/new fallback
|
||||
-- lives.
|
||||
--
|
||||
-- The collation is pinned to the admin database's (utf8mb4_unicode_ci) rather
|
||||
-- than inherited from the calendar tables' utf8mb4_general_ci. These columns
|
||||
-- hold ids that only ever compare against nachklang_admin.user.id, and a
|
||||
-- mismatched collation makes any such comparison fail at runtime with
|
||||
-- "Illegal mix of collations" instead of at review time.
|
||||
|
||||
ALTER TABLE `events`
|
||||
ADD COLUMN IF NOT EXISTS `created_by_user_id` VARCHAR(36)
|
||||
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
||||
NULL DEFAULT NULL AFTER `created_by_id`,
|
||||
ADD KEY IF NOT EXISTS `events_created_by_user_idx` (`created_by_user_id`);
|
||||
|
||||
ALTER TABLE `event_versions`
|
||||
ADD COLUMN IF NOT EXISTS `version_created_by_user_id` VARCHAR(36)
|
||||
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
||||
NULL DEFAULT NULL AFTER `version_created_by_id`,
|
||||
ADD KEY IF NOT EXISTS `event_versions_created_by_user_idx` (`version_created_by_user_id`);
|
||||
@@ -0,0 +1,42 @@
|
||||
-- Nachklang e.V. Calendar module — step 5 preparation, brought forward.
|
||||
-- Apply manually against the CALENDAR_DB database, after 001:
|
||||
-- mysql -h <DB_HOST> -u <DB_USER> -p <CALENDAR_DB> < 002_snapshot_legacy_creator_names.sql
|
||||
--
|
||||
-- Snapshots the creator's and last editor's *name* onto the event itself.
|
||||
--
|
||||
-- Why: the creator is only ever rendered as a name (nothing authorises on it),
|
||||
-- and today that name comes from joining the calendar's own `users` table.
|
||||
-- Step 5 drops that table, which would silently erase the authorship of every
|
||||
-- event created before the cutover. There is no account backfill to save them
|
||||
-- either - that was dropped deliberately, see docs/calendar-auth-migration.md.
|
||||
-- One text column per reference keeps the history at no ongoing cost.
|
||||
--
|
||||
-- These columns are an archive, not a source of truth. Nothing writes them
|
||||
-- after this backfill: events created from the cutover onwards carry an admin
|
||||
-- user id, whose name is resolved live so that renaming an account updates
|
||||
-- everywhere. The read path prefers the live admin name, falls back to this
|
||||
-- snapshot, and falls back again to the join until step 5 removes it.
|
||||
--
|
||||
-- The whole file is re-runnable: IF NOT EXISTS on the columns, and the backfill
|
||||
-- only touches rows with no snapshot yet. Step 4's migration re-runs the
|
||||
-- backfill, to catch anything created between this migration and the cutover.
|
||||
--
|
||||
-- No charset clause: unlike 001's id columns these hold display text that is
|
||||
-- only ever compared against other calendar data, so they inherit the tables'
|
||||
-- utf8mb4_general_ci like the columns they are copied from.
|
||||
|
||||
ALTER TABLE `events`
|
||||
ADD COLUMN IF NOT EXISTS `created_by_name` VARCHAR(255) NULL DEFAULT NULL AFTER `created_by_user_id`;
|
||||
|
||||
ALTER TABLE `event_versions`
|
||||
ADD COLUMN IF NOT EXISTS `version_created_by_name` VARCHAR(255) NULL DEFAULT NULL AFTER `version_created_by_user_id`;
|
||||
|
||||
UPDATE `events` e
|
||||
JOIN `users` u ON u.user_id = e.created_by_id
|
||||
SET e.created_by_name = u.full_name
|
||||
WHERE e.created_by_name IS NULL;
|
||||
|
||||
UPDATE `event_versions` v
|
||||
JOIN `users` u ON u.user_id = v.version_created_by_id
|
||||
SET v.version_created_by_name = u.full_name
|
||||
WHERE v.version_created_by_name IS NULL;
|
||||
@@ -0,0 +1,32 @@
|
||||
-- Nachklang e.V. Calendar module — step 4 of docs/calendar-auth-migration.md,
|
||||
-- the cutover. Apply manually against the CALENDAR_DB database, after 002,
|
||||
-- and BEFORE deploying the API build that goes with it:
|
||||
-- mysql -h <DB_HOST> -u <DB_USER> -p <CALENDAR_DB> < 003_allow_null_legacy_creator.sql
|
||||
--
|
||||
-- From the cutover on, an event's creator is an admin-module user id. There is
|
||||
-- no legacy calendar user id to write any more, and `events.created_by_id` is
|
||||
-- NOT NULL - so without this the very first event created after the deploy
|
||||
-- fails to insert. `event_versions.version_created_by_id` is already nullable.
|
||||
--
|
||||
-- The foreign key to `users` is kept: it permits NULL, so it costs nothing
|
||||
-- until step 5 drops the column and the table together.
|
||||
--
|
||||
-- Applying this early is harmless. Widening a column to accept NULL cannot
|
||||
-- break the running pre-cutover build, which always supplies a value, so this
|
||||
-- can go out ahead of the deploy rather than during it.
|
||||
|
||||
ALTER TABLE `events`
|
||||
MODIFY COLUMN `created_by_id` INT(11) NULL DEFAULT NULL;
|
||||
|
||||
-- Re-run of 002's backfill, to catch anything created between the two
|
||||
-- migrations while the legacy path was still writing events. Idempotent by
|
||||
-- construction: it only touches rows that have no snapshot yet.
|
||||
UPDATE `events` e
|
||||
JOIN `users` u ON u.user_id = e.created_by_id
|
||||
SET e.created_by_name = u.full_name
|
||||
WHERE e.created_by_name IS NULL;
|
||||
|
||||
UPDATE `event_versions` v
|
||||
JOIN `users` u ON u.user_id = v.version_created_by_id
|
||||
SET v.version_created_by_name = u.full_name
|
||||
WHERE v.version_created_by_name IS NULL;
|
||||
Reference in New Issue
Block a user