From a6e5e4f62524f65f489cbe56e6f47398e2227b00 Mon Sep 17 00:00:00 2001
From: Jason Rasmussen <jason@rasm.me>
Date: Wed, 7 May 2025 17:14:20 -0400
Subject: [PATCH] fix: schema ci checks (#18146)

---
 .github/workflows/test.yml                    |  6 +++---
 server/src/schema/enums.ts                    |  7 ++++++-
 server/src/schema/index.ts                    | 12 +++--------
 .../1746636476623-DropExtraIndexes.ts         | 21 +++++++++++++++++++
 server/src/schema/tables/asset.table.ts       |  3 +--
 .../tables/natural-earth-countries.table.ts   |  2 +-
 6 files changed, 35 insertions(+), 16 deletions(-)
 create mode 100644 server/src/schema/migrations/1746636476623-DropExtraIndexes.ts

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 64c084fa2e..d52ca4e6f7 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -593,8 +593,8 @@ jobs:
           echo "Changed files: ${CHANGED_FILES}"
           exit 1
 
-  generated-typeorm-migrations-up-to-date:
-    name: TypeORM Checks
+  sql-schema-up-to-date:
+    name: SQL Schema Checks
     runs-on: ubuntu-latest
     permissions:
       contents: read
@@ -641,7 +641,7 @@ jobs:
 
       - name: Generate new migrations
         continue-on-error: true
-        run: npm run migrations:generate TestMigration
+        run: npm run migrations:generate src/TestMigration
 
       - name: Find file changes
         uses: tj-actions/verify-changed-files@a1c6acee9df209257a246f2cc6ae8cb6581c1edf # v20
diff --git a/server/src/schema/enums.ts b/server/src/schema/enums.ts
index 100b92aa63..a1134df6bc 100644
--- a/server/src/schema/enums.ts
+++ b/server/src/schema/enums.ts
@@ -1,4 +1,4 @@
-import { AssetStatus, SourceType } from 'src/enum';
+import { AssetStatus, AssetVisibility, SourceType } from 'src/enum';
 import { registerEnum } from 'src/sql-tools';
 
 export const assets_status_enum = registerEnum({
@@ -10,3 +10,8 @@ export const asset_face_source_type = registerEnum({
   name: 'sourcetype',
   values: Object.values(SourceType),
 });
+
+export const asset_visibility_enum = registerEnum({
+  name: 'asset_visibility_enum',
+  values: Object.values(AssetVisibility),
+});
diff --git a/server/src/schema/index.ts b/server/src/schema/index.ts
index 1800f08c13..735dfd3ae9 100644
--- a/server/src/schema/index.ts
+++ b/server/src/schema/index.ts
@@ -1,5 +1,4 @@
-import { AssetVisibility } from 'src/enum';
-import { asset_face_source_type, assets_status_enum } from 'src/schema/enums';
+import { asset_face_source_type, asset_visibility_enum, assets_status_enum } from 'src/schema/enums';
 import {
   assets_delete_audit,
   f_concat_ws,
@@ -46,12 +45,7 @@ import { UserAuditTable } from 'src/schema/tables/user-audit.table';
 import { UserMetadataTable } from 'src/schema/tables/user-metadata.table';
 import { UserTable } from 'src/schema/tables/user.table';
 import { VersionHistoryTable } from 'src/schema/tables/version-history.table';
-import { ConfigurationParameter, Database, Extensions, registerEnum } from 'src/sql-tools';
-
-export const asset_visibility_enum = registerEnum({
-  name: 'asset_visibility_enum',
-  values: Object.values(AssetVisibility),
-});
+import { ConfigurationParameter, Database, Extensions } from 'src/sql-tools';
 
 @Extensions(['uuid-ossp', 'unaccent', 'cube', 'earthdistance', 'pg_trgm', 'plpgsql'])
 @ConfigurationParameter({ name: 'search_path', value: () => '"$user", public, vectors', scope: 'database' })
@@ -107,5 +101,5 @@ export class ImmichDatabase {
     assets_delete_audit,
   ];
 
-  enum = [assets_status_enum, asset_face_source_type];
+  enum = [assets_status_enum, asset_face_source_type, asset_visibility_enum];
 }
diff --git a/server/src/schema/migrations/1746636476623-DropExtraIndexes.ts b/server/src/schema/migrations/1746636476623-DropExtraIndexes.ts
new file mode 100644
index 0000000000..aae52829a5
--- /dev/null
+++ b/server/src/schema/migrations/1746636476623-DropExtraIndexes.ts
@@ -0,0 +1,21 @@
+import { Kysely, sql } from 'kysely';
+
+export async function up(db: Kysely<any>): Promise<void> {
+  const { rows } = await sql<{ db: string }>`SELECT current_database() as db`.execute(db);
+  const databaseName = rows[0].db;
+  await sql.raw(`ALTER DATABASE "${databaseName}" SET search_path TO "$user", public, vectors`).execute(db);
+  await sql`ALTER TABLE "naturalearth_countries" DROP CONSTRAINT IF EXISTS "PK_21a6d86d1ab5d841648212e5353";`.execute(db);
+  await sql`ALTER TABLE "naturalearth_countries" DROP CONSTRAINT IF EXISTS "naturalearth_countries_pkey";`.execute(db);
+  await sql`ALTER TABLE "naturalearth_countries" ADD CONSTRAINT "naturalearth_countries_pkey" PRIMARY KEY ("id") WITH (FILLFACTOR = 100);`.execute(db);
+  await sql`DROP INDEX IF EXISTS "IDX_02a43fd0b3c50fb6d7f0cb7282";`.execute(db);
+  await sql`DROP INDEX IF EXISTS "IDX_95ad7106dd7b484275443f580f";`.execute(db);
+  await sql`DROP INDEX IF EXISTS "IDX_7e077a8b70b3530138610ff5e0";`.execute(db);
+  await sql`DROP INDEX IF EXISTS "IDX_92e67dc508c705dd66c9461557";`.execute(db);
+  await sql`DROP INDEX IF EXISTS "IDX_6afb43681a21cf7815932bc38a";`.execute(db);
+}
+
+export async function down(db: Kysely<any>): Promise<void> {
+  const { rows } = await sql<{ db: string }>`SELECT current_database() as db`.execute(db);
+  const databaseName = rows[0].db;
+  await sql.raw(`ALTER DATABASE "${databaseName}" RESET "search_path"`).execute(db);
+}
diff --git a/server/src/schema/tables/asset.table.ts b/server/src/schema/tables/asset.table.ts
index 4552ac158d..d337984a46 100644
--- a/server/src/schema/tables/asset.table.ts
+++ b/server/src/schema/tables/asset.table.ts
@@ -1,7 +1,6 @@
 import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
 import { AssetStatus, AssetType, AssetVisibility } from 'src/enum';
-import { asset_visibility_enum } from 'src/schema';
-import { assets_status_enum } from 'src/schema/enums';
+import { asset_visibility_enum, assets_status_enum } from 'src/schema/enums';
 import { assets_delete_audit } from 'src/schema/functions';
 import { LibraryTable } from 'src/schema/tables/library.table';
 import { StackTable } from 'src/schema/tables/stack.table';
diff --git a/server/src/schema/tables/natural-earth-countries.table.ts b/server/src/schema/tables/natural-earth-countries.table.ts
index df1132d17d..e5e6ead772 100644
--- a/server/src/schema/tables/natural-earth-countries.table.ts
+++ b/server/src/schema/tables/natural-earth-countries.table.ts
@@ -1,6 +1,6 @@
 import { Column, PrimaryGeneratedColumn, Table } from 'src/sql-tools';
 
-@Table({ name: 'naturalearth_countries' })
+@Table({ name: 'naturalearth_countries', primaryConstraintName: 'naturalearth_countries_pkey' })
 export class NaturalEarthCountriesTable {
   @PrimaryGeneratedColumn({ strategy: 'identity' })
   id!: number;