From 8da1c9292391a39b8c08ed9f7cd7a2bb10217588 Mon Sep 17 00:00:00 2001 From: fallenbagel <98979876+fallenbagel@users.noreply.github.com> Date: Sat, 10 May 2025 03:38:22 +0800 Subject: [PATCH] fix(entity): use TIMESTAMPTZ in Postgres and sort issue comments oldest-first (#1654) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(entity): use TIMESTAMPTZ in Postgres and sort issue comments oldest-first Switch key datetime columns to TIMESTAMPTZ for proper UTC handling (“just now”) and sort issue comments on load so the original description stays first and in proper sorted order in fix-pgsql-timezone fixes #1569, fixes #1568 * refactor(migration): manually rewrite pgsql migration to preserve existing data Typeorm generated migration was dropping the entire column thus leading to data loss so this is an attempt at manually rewriting the migration to preserve the data * refactor(migrations): rename to be consistent with other migration files * fix: use id to order instead of createdAt to avoid non-existant createdAt --------- Co-authored-by: Gauthier --- server/entity/Blacklist.ts | 4 +- server/entity/DiscoverSlider.ts | 17 +- server/entity/Issue.ts | 17 +- server/entity/IssueComment.ts | 18 +- server/entity/Media.ts | 10 +- server/entity/MediaRequest.ts | 11 +- server/entity/OverrideRule.ts | 17 +- server/entity/Season.ts | 18 +- server/entity/SeasonRequest.ts | 18 +- server/entity/User.ts | 11 +- server/entity/UserPushSubscription.ts | 15 +- server/entity/Watchlist.ts | 11 +- .../1746811308203-FixIssueTimestamps.ts | 231 ++++++++++++++++++ 13 files changed, 320 insertions(+), 78 deletions(-) create mode 100644 server/migration/postgres/1746811308203-FixIssueTimestamps.ts diff --git a/server/entity/Blacklist.ts b/server/entity/Blacklist.ts index a6bac9d9..64c44e50 100644 --- a/server/entity/Blacklist.ts +++ b/server/entity/Blacklist.ts @@ -3,10 +3,10 @@ import dataSource from '@server/datasource'; import Media from '@server/entity/Media'; import { User } from '@server/entity/User'; import type { BlacklistItem } from '@server/interfaces/api/blacklistInterfaces'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; import type { EntityManager } from 'typeorm'; import { Column, - CreateDateColumn, Entity, Index, JoinColumn, @@ -47,7 +47,7 @@ export class Blacklist implements BlacklistItem { @Column({ nullable: true, type: 'varchar' }) public blacklistedTags?: string; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; constructor(init?: Partial) { diff --git a/server/entity/DiscoverSlider.ts b/server/entity/DiscoverSlider.ts index 261419a0..0de0aef8 100644 --- a/server/entity/DiscoverSlider.ts +++ b/server/entity/DiscoverSlider.ts @@ -2,13 +2,8 @@ import type { DiscoverSliderType } from '@server/constants/discover'; import { defaultSliders } from '@server/constants/discover'; import { getRepository } from '@server/datasource'; import logger from '@server/logger'; -import { - Column, - CreateDateColumn, - Entity, - PrimaryGeneratedColumn, - UpdateDateColumn, -} from 'typeorm'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; @Entity() class DiscoverSlider { @@ -55,10 +50,14 @@ class DiscoverSlider { @Column({ nullable: true }) public data?: string; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; constructor(init?: Partial) { diff --git a/server/entity/Issue.ts b/server/entity/Issue.ts index fae96967..8ff88e3b 100644 --- a/server/entity/Issue.ts +++ b/server/entity/Issue.ts @@ -1,13 +1,13 @@ import type { IssueType } from '@server/constants/issue'; import { IssueStatus } from '@server/constants/issue'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; import { + AfterLoad, Column, - CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, - UpdateDateColumn, } from 'typeorm'; import IssueComment from './IssueComment'; import Media from './Media'; @@ -55,12 +55,21 @@ class Issue { }) public comments: IssueComment[]; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; + @AfterLoad() + sortComments() { + this.comments?.sort((a, b) => a.id - b.id); + } + constructor(init?: Partial) { Object.assign(this, init); } diff --git a/server/entity/IssueComment.ts b/server/entity/IssueComment.ts index e4521639..c36b3746 100644 --- a/server/entity/IssueComment.ts +++ b/server/entity/IssueComment.ts @@ -1,11 +1,5 @@ -import { - Column, - CreateDateColumn, - Entity, - ManyToOne, - PrimaryGeneratedColumn, - UpdateDateColumn, -} from 'typeorm'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; import Issue from './Issue'; import { User } from './User'; @@ -28,10 +22,14 @@ class IssueComment { @Column({ type: 'text' }) public message: string; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; constructor(init?: Partial) { diff --git a/server/entity/Media.ts b/server/entity/Media.ts index 33155a1f..38726f70 100644 --- a/server/entity/Media.ts +++ b/server/entity/Media.ts @@ -15,13 +15,11 @@ import { getHostname } from '@server/utils/getHostname'; import { AfterLoad, Column, - CreateDateColumn, Entity, Index, OneToMany, OneToOne, PrimaryGeneratedColumn, - UpdateDateColumn, } from 'typeorm'; import Issue from './Issue'; import { MediaRequest } from './MediaRequest'; @@ -128,10 +126,14 @@ class Media { @OneToOne(() => Blacklist, (blacklist) => blacklist.media) public blacklist: Promise; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; /** diff --git a/server/entity/MediaRequest.ts b/server/entity/MediaRequest.ts index cd103ef4..e5dabc24 100644 --- a/server/entity/MediaRequest.ts +++ b/server/entity/MediaRequest.ts @@ -13,18 +13,17 @@ import notificationManager, { Notification } from '@server/lib/notifications'; import { Permission } from '@server/lib/permissions'; import { getSettings } from '@server/lib/settings'; import logger from '@server/logger'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; import { truncate } from 'lodash'; import { AfterInsert, AfterUpdate, Column, - CreateDateColumn, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn, RelationCount, - UpdateDateColumn, } from 'typeorm'; import Media from './Media'; import SeasonRequest from './SeasonRequest'; @@ -535,10 +534,14 @@ export class MediaRequest { }) public modifiedBy?: User; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; @Column({ type: 'varchar' }) diff --git a/server/entity/OverrideRule.ts b/server/entity/OverrideRule.ts index bf137343..aab72006 100644 --- a/server/entity/OverrideRule.ts +++ b/server/entity/OverrideRule.ts @@ -1,10 +1,5 @@ -import { - Column, - CreateDateColumn, - Entity, - PrimaryGeneratedColumn, - UpdateDateColumn, -} from 'typeorm'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; @Entity() class OverrideRule { @@ -38,10 +33,14 @@ class OverrideRule { @Column({ nullable: true }) public tags?: string; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; constructor(init?: Partial) { diff --git a/server/entity/Season.ts b/server/entity/Season.ts index d488a5c1..7d38581e 100644 --- a/server/entity/Season.ts +++ b/server/entity/Season.ts @@ -1,12 +1,6 @@ import { MediaStatus } from '@server/constants/media'; -import { - Column, - CreateDateColumn, - Entity, - ManyToOne, - PrimaryGeneratedColumn, - UpdateDateColumn, -} from 'typeorm'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; import Media from './Media'; @Entity() @@ -28,10 +22,14 @@ class Season { }) public media: Promise; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; constructor(init?: Partial) { diff --git a/server/entity/SeasonRequest.ts b/server/entity/SeasonRequest.ts index f9eeef50..9262877b 100644 --- a/server/entity/SeasonRequest.ts +++ b/server/entity/SeasonRequest.ts @@ -1,12 +1,6 @@ import { MediaRequestStatus } from '@server/constants/media'; -import { - Column, - CreateDateColumn, - Entity, - ManyToOne, - PrimaryGeneratedColumn, - UpdateDateColumn, -} from 'typeorm'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; import { MediaRequest } from './MediaRequest'; @Entity() @@ -25,10 +19,14 @@ class SeasonRequest { }) public request: MediaRequest; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; constructor(init?: Partial) { diff --git a/server/entity/User.ts b/server/entity/User.ts index 5f51af71..8a96f396 100644 --- a/server/entity/User.ts +++ b/server/entity/User.ts @@ -9,6 +9,7 @@ import { hasPermission, Permission } from '@server/lib/permissions'; import { getSettings } from '@server/lib/settings'; import logger from '@server/logger'; import { AfterDate } from '@server/utils/dateHelpers'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; import bcrypt from 'bcrypt'; import { randomUUID } from 'crypto'; import path from 'path'; @@ -16,14 +17,12 @@ import { default as generatePassword } from 'secure-random-password'; import { AfterLoad, Column, - CreateDateColumn, Entity, Not, OneToMany, OneToOne, PrimaryGeneratedColumn, RelationCount, - UpdateDateColumn, } from 'typeorm'; import Issue from './Issue'; import { MediaRequest } from './MediaRequest'; @@ -138,10 +137,14 @@ export class User { @OneToMany(() => Issue, (issue) => issue.createdBy, { cascade: true }) public createdIssues: Issue[]; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; public warnings: string[] = []; diff --git a/server/entity/UserPushSubscription.ts b/server/entity/UserPushSubscription.ts index f05dd0f2..b3c4d5d2 100644 --- a/server/entity/UserPushSubscription.ts +++ b/server/entity/UserPushSubscription.ts @@ -1,10 +1,5 @@ -import { - Column, - CreateDateColumn, - Entity, - ManyToOne, - PrimaryGeneratedColumn, -} from 'typeorm'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; import { User } from './User'; @Entity() @@ -30,7 +25,11 @@ export class UserPushSubscription { @Column({ nullable: true }) public userAgent: string; - @CreateDateColumn({ nullable: true }) + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + nullable: true, + }) public createdAt: Date; constructor(init?: Partial) { diff --git a/server/entity/Watchlist.ts b/server/entity/Watchlist.ts index df820120..10c26246 100644 --- a/server/entity/Watchlist.ts +++ b/server/entity/Watchlist.ts @@ -5,15 +5,14 @@ import Media from '@server/entity/Media'; import { User } from '@server/entity/User'; import type { WatchlistItem } from '@server/interfaces/api/discoverInterfaces'; import logger from '@server/logger'; +import { DbAwareColumn } from '@server/utils/DbColumnHelper'; import { Column, - CreateDateColumn, Entity, Index, ManyToOne, PrimaryGeneratedColumn, Unique, - UpdateDateColumn, } from 'typeorm'; import type { ZodNumber, ZodOptional, ZodString } from 'zod'; @@ -56,10 +55,14 @@ export class Watchlist implements WatchlistItem { }) public media: Media; - @CreateDateColumn() + @DbAwareColumn({ type: 'datetime', default: () => 'CURRENT_TIMESTAMP' }) public createdAt: Date; - @UpdateDateColumn() + @DbAwareColumn({ + type: 'datetime', + default: () => 'CURRENT_TIMESTAMP', + onUpdate: 'CURRENT_TIMESTAMP', + }) public updatedAt: Date; constructor(init?: Partial) { diff --git a/server/migration/postgres/1746811308203-FixIssueTimestamps.ts b/server/migration/postgres/1746811308203-FixIssueTimestamps.ts new file mode 100644 index 00000000..ac0bae3a --- /dev/null +++ b/server/migration/postgres/1746811308203-FixIssueTimestamps.ts @@ -0,0 +1,231 @@ +import type { MigrationInterface, QueryRunner } from 'typeorm'; + +export class FixIssueTimestamps1746811308203 implements MigrationInterface { + name = 'FixIssueTimestamps1746811308203'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE "watchlist" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "watchlist" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "override_rule" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "override_rule" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season_request" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season_request" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media_request" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media_request" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "user_push_subscription" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "user" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "user" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "blacklist" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue_comment" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue_comment" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "discover_slider" + ALTER COLUMN "createdAt" TYPE TIMESTAMP WITH TIME ZONE + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "discover_slider" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP WITH TIME ZONE + USING "updatedAt" AT TIME ZONE 'UTC' + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE "discover_slider" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "discover_slider" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue_comment" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue_comment" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "issue" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "blacklist" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "user" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "user" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "user_push_subscription" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media_request" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "media_request" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season_request" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "season_request" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "override_rule" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "override_rule" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "watchlist" + ALTER COLUMN "updatedAt" TYPE TIMESTAMP + USING "updatedAt" AT TIME ZONE 'UTC' + `); + await queryRunner.query(` + ALTER TABLE "watchlist" + ALTER COLUMN "createdAt" TYPE TIMESTAMP + USING "createdAt" AT TIME ZONE 'UTC' + `); + } +}