Skip to content

perf(user): add indexes on plexId, jellyfinUserId, and resetPasswordGuid#2806

Open
dougrathbone wants to merge 1 commit intoseerr-team:developfrom
dougrathbone:dougrathbone/perf/user-auth-indexes
Open

perf(user): add indexes on plexId, jellyfinUserId, and resetPasswordGuid#2806
dougrathbone wants to merge 1 commit intoseerr-team:developfrom
dougrathbone:dougrathbone/perf/user-auth-indexes

Conversation

@dougrathbone
Copy link
Copy Markdown
Contributor

@dougrathbone dougrathbone commented Apr 2, 2026

Description

User.plexId, User.jellyfinUserId, and User.resetPasswordGuid are looked up by value on every authentication request but have no database index. Every lookup is a full table scan.

While not a huge win on small instances, this seemed like a no-brainer quick win that might also help in situations where attackers try to brown out the host through brute force logins.

Query sites affected:

Column Code path Frequency
plexId Plex login (auth.ts), Tautulli watch stats, user import sync Every Plex login
jellyfinUserId Jellyfin login (auth.ts), avatar proxy (avatarproxy.ts), user sync Every Jellyfin/Emby login + every avatar load
resetPasswordGuid Password reset link validation (auth.ts) Every password reset

email is intentionally excluded -- its unique: true constraint already creates an implicit index in both SQLite and PostgreSQL.

Changes:

  • Added named @Index() decorators to the three columns in server/entity/User.ts
  • Added SQLite migration 1775000000000-AddUserLookupIndexes
  • Added PostgreSQL migration 1775000000000-AddUserLookupIndexes

Performance improvement:

Deployment size Before After
Small (< 50 users) Full table scan on every auth -- negligible Index seek -- negligible
Medium (100-500 users) Noticeable scan on busy instances Effectively instant
Large (500+ users, shared Plex/Jellyfin servers) Measurable latency on login and avatar requests Effectively instant

AI Disclosure: I used Claude Code to help write the tests and validate the SQLite db changes. I reviewed and understood all generated code before submitting.

How Has This Been Tested?

New test suite server/entity/User.index.test.ts using the real SQLite test database via setupTestDb().

Tests:

  1. user table has an index on plexId - queries sqlite_master and asserts IDX_user_plexId exists
  2. user table has an index on jellyfinUserId - same for IDX_user_jellyfinUserId
  3. user table has an index on resetPasswordGuid - same for IDX_user_resetPasswordGuid
  4. plexId lookup returns correct user - creates a user with a known plexId, queries by that value, asserts the correct record is returned

To run:

node server/test/index.mts server/entity/User.index.test.ts

To verify manually on a running instance:

SQLite:

SELECT name, tbl_name FROM sqlite_master WHERE type = 'index' AND tbl_name = 'user';

PostgreSQL:

SELECT indexname FROM pg_indexes WHERE tablename = 'user';

Both should show IDX_user_plexId, IDX_user_jellyfinUserId, and IDX_user_resetPasswordGuid after migration.

Screenshots / Logs (if applicable)

N/A -- backend-only change with no UI impact.

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly. (no documentation changes required for this fix)
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract (no new UI strings added)
  • Database migration (if required)

Summary by CodeRabbit

  • Performance Improvements
    • Enhanced database performance for user authentication lookups through optimized indexing on user identification fields across PostgreSQL and SQLite databases.

@dougrathbone dougrathbone requested a review from a team as a code owner April 2, 2026 11:33
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Database indexes are added to the User entity's plexId and jellyfinUserId properties through entity decorators and corresponding TypeORM migrations for PostgreSQL and SQLite databases to optimize query performance on these columns.

Changes

Cohort / File(s) Summary
User Entity Indexing
server/entity/User.ts
Added @Index decorators with explicit names (IDX_user_plexId and IDX_user_jellyfinUserId) to the plexId and jellyfinUserId properties.
Database Migrations
server/migration/postgres/1776334553142-AddUserAuthIndexes.ts, server/migration/sqlite/1776230665383-AddUserAuthIndexes.ts
Created parallel migration classes for PostgreSQL and SQLite that create and drop the same two indexes (IDX_user_plexId, IDX_user_jellyfinUserId) on the user table.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Suggested reviewers

  • danshilm

Poem

🐰 With whiskers twitching at database speeds,
We've planted indexes where queries need,
plexId and jellyfinUserId now run faster still,
Performance hops up every database hill! ✨🏃‍♂️

🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions 'resetPasswordGuid' but the changeset only includes indexes for 'plexId' and 'jellyfinUserId', as the resetPasswordGuid index was removed during review iterations. Update the PR title to accurately reflect the current changes: 'perf(user): add indexes on plexId and jellyfinUserId' to match the actual implementation.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
server/migration/postgres/1775000000000-AddUserLookupIndexes.ts (1)

6-16: Consider IF NOT EXISTS for idempotency (same as SQLite migration).

PostgreSQL also supports IF NOT EXISTS for CREATE INDEX, which would make the migration idempotent in development environments where synchronize may have already created these indexes.

♻️ Proposed fix for idempotency
   public async up(queryRunner: QueryRunner): Promise<void> {
     await queryRunner.query(
-      `CREATE INDEX "IDX_user_plexId" ON "user" ("plexId")`
+      `CREATE INDEX IF NOT EXISTS "IDX_user_plexId" ON "user" ("plexId")`
     );
     await queryRunner.query(
-      `CREATE INDEX "IDX_user_jellyfinUserId" ON "user" ("jellyfinUserId")`
+      `CREATE INDEX IF NOT EXISTS "IDX_user_jellyfinUserId" ON "user" ("jellyfinUserId")`
     );
     await queryRunner.query(
-      `CREATE INDEX "IDX_user_resetPasswordGuid" ON "user" ("resetPasswordGuid")`
+      `CREATE INDEX IF NOT EXISTS "IDX_user_resetPasswordGuid" ON "user" ("resetPasswordGuid")`
     );
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/migration/postgres/1775000000000-AddUserLookupIndexes.ts` around lines
6 - 16, The CREATE INDEX statements in the migration's up(queryRunner:
QueryRunner) are not idempotent; change each queryRunner.query call that creates
"IDX_user_plexId", "IDX_user_jellyfinUserId", and "IDX_user_resetPasswordGuid"
to use CREATE INDEX IF NOT EXISTS so the migration can be safely re-run in
environments where synchronize already created those indexes; keep the same
index names and SQL calls but add IF NOT EXISTS to each CREATE INDEX string.
server/migration/sqlite/1775000000000-AddUserLookupIndexes.ts (2)

6-16: Consider IF NOT EXISTS for idempotency in development environments.

The migration may fail in development if synchronize: true has already created these indexes from the entity decorators. Adding IF NOT EXISTS would make the migration idempotent.

♻️ Proposed fix for idempotency
   public async up(queryRunner: QueryRunner): Promise<void> {
     await queryRunner.query(
-      `CREATE INDEX "IDX_user_plexId" ON "user" ("plexId")`
+      `CREATE INDEX IF NOT EXISTS "IDX_user_plexId" ON "user" ("plexId")`
     );
     await queryRunner.query(
-      `CREATE INDEX "IDX_user_jellyfinUserId" ON "user" ("jellyfinUserId")`
+      `CREATE INDEX IF NOT EXISTS "IDX_user_jellyfinUserId" ON "user" ("jellyfinUserId")`
     );
     await queryRunner.query(
-      `CREATE INDEX "IDX_user_resetPasswordGuid" ON "user" ("resetPasswordGuid")`
+      `CREATE INDEX IF NOT EXISTS "IDX_user_resetPasswordGuid" ON "user" ("resetPasswordGuid")`
     );
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/migration/sqlite/1775000000000-AddUserLookupIndexes.ts` around lines 6
- 16, The CREATE INDEX statements in the migration's up method (inside the
migration class implementing up(queryRunner: QueryRunner)) should be made
idempotent by adding IF NOT EXISTS to each SQL statement; update the three
queries for IDX_user_plexId, IDX_user_jellyfinUserId, and
IDX_user_resetPasswordGuid to use `CREATE INDEX IF NOT EXISTS ...` so the
migration won't fail when indexes already exist (e.g., when synchronize: true
created them).

18-22: Optional: Add IF EXISTS to down() for defensive rollback.

This is less critical than up(), but adding IF EXISTS prevents errors if the migration is rolled back after a partial failure.

♻️ Optional defensive fix
   public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(`DROP INDEX "IDX_user_resetPasswordGuid"`);
-    await queryRunner.query(`DROP INDEX "IDX_user_jellyfinUserId"`);
-    await queryRunner.query(`DROP INDEX "IDX_user_plexId"`);
+    await queryRunner.query(`DROP INDEX IF EXISTS "IDX_user_resetPasswordGuid"`);
+    await queryRunner.query(`DROP INDEX IF EXISTS "IDX_user_jellyfinUserId"`);
+    await queryRunner.query(`DROP INDEX IF EXISTS "IDX_user_plexId"`);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/migration/sqlite/1775000000000-AddUserLookupIndexes.ts` around lines
18 - 22, Update the down(queryRunner: QueryRunner) method in the
AddUserLookupIndexes migration to use defensive DROP INDEX statements with IF
EXISTS; replace the three DROP INDEX "IDX_user_resetPasswordGuid",
"IDX_user_jellyfinUserId", and "IDX_user_plexId" calls so they execute DROP
INDEX IF EXISTS "IDX_user_resetPasswordGuid", DROP INDEX IF EXISTS
"IDX_user_jellyfinUserId", and DROP INDEX IF EXISTS "IDX_user_plexId"
respectively to avoid errors on partial rollbacks.
server/entity/User.index.test.ts (1)

49-52: Consider using assert.notStrictEqual for cleaner type narrowing.

The current pattern works but the ! assertion after assert.ok(found !== null) is slightly redundant. Using assert.notStrictEqual or assigning the assertion inline would be cleaner.

♻️ Optional refinement
     const found = await repo.findOne({ where: { plexId: 99999 } });
-    assert.ok(found !== null);
-    assert.strictEqual(found!.email, 'plextest@seerr.dev');
-    assert.strictEqual(found!.plexId, 99999);
+    assert.notStrictEqual(found, null);
+    assert.strictEqual(found?.email, 'plextest@seerr.dev');
+    assert.strictEqual(found?.plexId, 99999);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/entity/User.index.test.ts` around lines 49 - 52, Replace the
null-check pattern on the retrieved user to use assert.notStrictEqual for better
type narrowing: where the test calls repo.findOne(...) and then uses
assert.ok(found !== null) followed by non-null assertions on found (variable
found), change the assertion to assert.notStrictEqual(found, null) (or
assert.notStrictEqual(found, null, 'expected user to exist')) and then remove
the unnecessary non-null (!) operator when accessing found.email and
found.plexId so the TypeScript compiler correctly infers found is non-null.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/migration/postgres/1775000000000-AddUserLookupIndexes.ts`:
- Around line 6-22: The up() migration creates indexes without schema
qualification while down() drops them using "public" qualification, which can
fail on non-default schemas; update either up() or down() to be
consistent—preferably remove the "public" prefix from the DROP INDEX calls in
down() (referencing down() and the DROP INDEX statements for
"IDX_user_resetPasswordGuid", "IDX_user_jellyfinUserId", and "IDX_user_plexId")
or alternatively add "public" to the CREATE INDEX calls in up() so both up() and
down() use the same schema resolution when invoking queryRunner.query().

---

Nitpick comments:
In `@server/entity/User.index.test.ts`:
- Around line 49-52: Replace the null-check pattern on the retrieved user to use
assert.notStrictEqual for better type narrowing: where the test calls
repo.findOne(...) and then uses assert.ok(found !== null) followed by non-null
assertions on found (variable found), change the assertion to
assert.notStrictEqual(found, null) (or assert.notStrictEqual(found, null,
'expected user to exist')) and then remove the unnecessary non-null (!) operator
when accessing found.email and found.plexId so the TypeScript compiler correctly
infers found is non-null.

In `@server/migration/postgres/1775000000000-AddUserLookupIndexes.ts`:
- Around line 6-16: The CREATE INDEX statements in the migration's
up(queryRunner: QueryRunner) are not idempotent; change each queryRunner.query
call that creates "IDX_user_plexId", "IDX_user_jellyfinUserId", and
"IDX_user_resetPasswordGuid" to use CREATE INDEX IF NOT EXISTS so the migration
can be safely re-run in environments where synchronize already created those
indexes; keep the same index names and SQL calls but add IF NOT EXISTS to each
CREATE INDEX string.

In `@server/migration/sqlite/1775000000000-AddUserLookupIndexes.ts`:
- Around line 6-16: The CREATE INDEX statements in the migration's up method
(inside the migration class implementing up(queryRunner: QueryRunner)) should be
made idempotent by adding IF NOT EXISTS to each SQL statement; update the three
queries for IDX_user_plexId, IDX_user_jellyfinUserId, and
IDX_user_resetPasswordGuid to use `CREATE INDEX IF NOT EXISTS ...` so the
migration won't fail when indexes already exist (e.g., when synchronize: true
created them).
- Around line 18-22: Update the down(queryRunner: QueryRunner) method in the
AddUserLookupIndexes migration to use defensive DROP INDEX statements with IF
EXISTS; replace the three DROP INDEX "IDX_user_resetPasswordGuid",
"IDX_user_jellyfinUserId", and "IDX_user_plexId" calls so they execute DROP
INDEX IF EXISTS "IDX_user_resetPasswordGuid", DROP INDEX IF EXISTS
"IDX_user_jellyfinUserId", and DROP INDEX IF EXISTS "IDX_user_plexId"
respectively to avoid errors on partial rollbacks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4fa613c7-e9e9-4003-8072-f315583a276c

📥 Commits

Reviewing files that changed from the base of the PR and between 868430b and d650d48.

📒 Files selected for processing (4)
  • server/entity/User.index.test.ts
  • server/entity/User.ts
  • server/migration/postgres/1775000000000-AddUserLookupIndexes.ts
  • server/migration/sqlite/1775000000000-AddUserLookupIndexes.ts

Comment thread server/migration/sqlite/1776230665383-AddUserAuthIndexes.ts
Copy link
Copy Markdown
Collaborator

@fallenbagel fallenbagel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our contributing guide, we expect AI-assisted development, not AI-driven development. This PR (along with #2804 and #2805) was submitted in rapid succession, and the quality issues across them suggest heavy AI generation with insufficient review.

Things I noticed in this PR:

  • Migrations appear to be AI-written and not generated. The sqlite and postgres files are byte-for-byte identical. This never happens with typeorm migration:generate. Please regenerate following the instructions in CONTRIBUTING.md.

  • Irrelevant test files written. You're testing that TypeORM applied an @Index decorator, which is TypeORM's job, not ours/applications. The tests are also sqlite-only and would break on postgres. This is also another red flag that led us to flag this PR. A human reviewer would have caught that these serve no purpose.

  • Why is an index being added on resetPasswordGuid? This is only hit during password resets (which doesn't happen always) and adds write overhead for negligible benefit, unlike plexId/jellyfinUserId which are used on every auth lookup.

CC: @seerr-team/seerr-core

@dougrathbone
Copy link
Copy Markdown
Contributor Author

@fallenbagel fair feedback - makes sense re:test scope.

I wasn't aware of the typeorm migration:generate workflow. I used Claude to help with the migration because I wanted precision on the migration to save time on round tripping the db during QA, but I wasn't aware of the migration guidance.

On resetPasswordGuid - I take your point, but added the index because its used on password recovery as a lookup for the reset link.

Re the timing of the PRs - I was working on the branches locally before submitting, so the close submit times are just me pushing a batch of work at once rather than these being rapid-fire generated.

I want to be clear that Im investigating the codebase by hand with Claude as an assistant, not the other way around. I'm putting in spare hours working through the code as a relative newcomer, and I appreciate you taking the time to review and point me in the right direction. In my defence, i'm not simply yoloing random PRs at you guys using AI.

I'll rework the above based on your feedback.

@dougrathbone dougrathbone force-pushed the dougrathbone/perf/user-auth-indexes branch from 7c6e40f to a69fd91 Compare April 14, 2026 09:11
@dougrathbone
Copy link
Copy Markdown
Contributor Author

Thanks for the detailed feedback, all good points.

  • Removed the index verification tests - agreed, testing TypeORM's own decorator behavior serves no purpose
  • Dropped the resetPasswordGuid index since it's only hit during password resets, not worth the write overhead
  • Regenerated the sqlite migration properly using pnpm migration:generate. Postgres migration written to match the existing pattern (schema-qualified DROP INDEX in down()) since I don't have a local postgres instance. Happy to regenerate that one too if you'd prefer.

I wasn't aware of the typeorm migration:generate workflow, appreciate the callout. Will follow the documented process going forward.

@fallenbagel
Copy link
Copy Markdown
Collaborator

On resetPasswordGuid - I take your point, but added the index because its used on password recovery as a lookup for the reset link

Re-iterating my point about this. Password reset link is not something you hit always so this does not bring much value and instead just adds write overhead.

As for the changes, I'll re-review later

@fallenbagel
Copy link
Copy Markdown
Collaborator

fallenbagel commented Apr 14, 2026

Regenerated the sqlite migration properly using pnpm migration:generate. Postgres migration written to match the existing pattern (schema-qualified DROP INDEX in down()) since I don't have a local postgres instance. Happy to regenerate that one too if you'd prefer.

Please follow the exact steps in the contribution guide, including the Postgres migration. Do not modify generated TypeORM migrations, as that can cause issues later. We’ll review the result.

I wasn't aware of the typeorm migration:generate workflow, appreciate the callout. Will follow the documented process going forward.

Reading and adhering to the contribution guide in full is expected of every external contributor. It covers everything required for submissions (setup, workflow, contribution standards, etc.), including the migration process and the one-line Docker command for Postgres.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
server/migration/postgres/1776157803546-AddUserAuthIndexes.ts (1)

6-17: ⚠️ Potential issue | 🟡 Minor

Make schema resolution consistent between up() and down().

up() uses unqualified index creation, while down() hard-codes "public". That can make rollback fail when search_path/schema differs.

Suggested fix (match `down()` to `up()` behavior)
   public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(`DROP INDEX "public"."IDX_user_jellyfinUserId"`);
-    await queryRunner.query(`DROP INDEX "public"."IDX_user_plexId"`);
+    await queryRunner.query(`DROP INDEX "IDX_user_jellyfinUserId"`);
+    await queryRunner.query(`DROP INDEX "IDX_user_plexId"`);
   }
#!/bin/bash
# Verify schema-qualification mismatch in this migration file.
rg -nP 'CREATE INDEX|DROP INDEX' server/migration/postgres/1776157803546-AddUserAuthIndexes.ts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/migration/postgres/1776157803546-AddUserAuthIndexes.ts` around lines 6
- 17, The down() method in the migration mismatches up(): up() creates
unqualified indexes ("IDX_user_plexId", "IDX_user_jellyfinUserId") but down()
drops "public"."IDX_..." which can fail if search_path differs; update the
down() implementation in class/method AddUserAuthIndexes.up/down (methods up and
down) to drop the same unqualified index names (remove the hard-coded "public"
schema) or alternatively qualify both CREATE INDEX calls — keep create/drop
behavior consistent so the DROP INDEX statements use the same identifier format
as the CREATE INDEX statements.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@server/migration/postgres/1776157803546-AddUserAuthIndexes.ts`:
- Around line 6-17: The down() method in the migration mismatches up(): up()
creates unqualified indexes ("IDX_user_plexId", "IDX_user_jellyfinUserId") but
down() drops "public"."IDX_..." which can fail if search_path differs; update
the down() implementation in class/method AddUserAuthIndexes.up/down (methods up
and down) to drop the same unqualified index names (remove the hard-coded
"public" schema) or alternatively qualify both CREATE INDEX calls — keep
create/drop behavior consistent so the DROP INDEX statements use the same
identifier format as the CREATE INDEX statements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8fbc86d5-7c0c-4ebd-b904-aaf0154fd7a0

📥 Commits

Reviewing files that changed from the base of the PR and between 7c6e40f and a69fd91.

📒 Files selected for processing (3)
  • server/entity/User.ts
  • server/migration/postgres/1776157803546-AddUserAuthIndexes.ts
  • server/migration/sqlite/1776157803546-AddUserAuthIndexes.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • server/entity/User.ts

These columns are queried on every authentication lookup. Adding
indexes avoids full table scans during Plex and Jellyfin sign-in.

Migrations generated with `pnpm migration:generate` for both SQLite
and PostgreSQL per CONTRIBUTING.md.
@dougrathbone dougrathbone force-pushed the dougrathbone/perf/user-auth-indexes branch from a69fd91 to 2d802ad Compare April 16, 2026 10:18
@dougrathbone
Copy link
Copy Markdown
Contributor Author

@fallenbagel Updated the branch to address all feedback:

  1. Removed resetPasswordGuid index — only plexId and jellyfinUserId remain (the two columns hit on every auth lookup).
  2. Removed the test file — agreed, testing that TypeORM applies @Index is TypeORM's job.
  3. Migrations properly generated with migration:generate — followed the CONTRIBUTING.md process:
    • Reset SQLite DB, ran pnpm migration:generate server/migration/sqlite/AddUserAuthIndexes
    • Spun up a fresh Docker postgres container, ran pnpm migration:run to apply existing migrations, then ran DB_TYPE="postgres" DB_USER=postgres DB_PASS=postgres pnpm migration:generate server/migration/postgres/AddUserAuthIndexes
    • The two migration files are no longer byte-for-byte identical — postgres down() has the "public" schema qualification that TypeORM generates, matching every other postgres migration in the repo.
  4. Squashed commit history — the five fixup commits are now a single clean commit.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
server/migration/postgres/1776334553142-AddUserAuthIndexes.ts (1)

6-18: ⚠️ Potential issue | 🟡 Minor

Make up()/down() schema resolution consistent.

up() relies on search_path, but down() hardcodes "public" (Line 16-17). This can break rollback outside the default schema.

Suggested fix
   public async down(queryRunner: QueryRunner): Promise<void> {
-    await queryRunner.query(`DROP INDEX "public"."IDX_user_jellyfinUserId"`);
-    await queryRunner.query(`DROP INDEX "public"."IDX_user_plexId"`);
+    await queryRunner.query(`DROP INDEX "IDX_user_jellyfinUserId"`);
+    await queryRunner.query(`DROP INDEX "IDX_user_plexId"`);
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/migration/postgres/1776334553142-AddUserAuthIndexes.ts` around lines 6
- 18, The down() currently hardcodes the "public" schema while up() creates
indexes relying on the current search_path; update down() in AddUserAuthIndexes
(methods up/down) to mirror up() by dropping the same index names without the
"public" schema qualifier (or construct the schema dynamically from the
connection) so rollback works when using a non-default schema; change the two
queryRunner.query calls in down() that DROP INDEX
"public"."IDX_user_jellyfinUserId" and DROP INDEX "public"."IDX_user_plexId" to
drop "IDX_user_jellyfinUserId" and "IDX_user_plexId" (or resolve schema
consistently).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@server/migration/postgres/1776334553142-AddUserAuthIndexes.ts`:
- Around line 6-18: The down() currently hardcodes the "public" schema while
up() creates indexes relying on the current search_path; update down() in
AddUserAuthIndexes (methods up/down) to mirror up() by dropping the same index
names without the "public" schema qualifier (or construct the schema dynamically
from the connection) so rollback works when using a non-default schema; change
the two queryRunner.query calls in down() that DROP INDEX
"public"."IDX_user_jellyfinUserId" and DROP INDEX "public"."IDX_user_plexId" to
drop "IDX_user_jellyfinUserId" and "IDX_user_plexId" (or resolve schema
consistently).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eec61302-4dae-47c4-93f9-938b638bf64a

📥 Commits

Reviewing files that changed from the base of the PR and between a69fd91 and 2d802ad.

📒 Files selected for processing (3)
  • server/entity/User.ts
  • server/migration/postgres/1776334553142-AddUserAuthIndexes.ts
  • server/migration/sqlite/1776230665383-AddUserAuthIndexes.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants