diff --git a/server/src/database.ts b/server/src/database.ts
index 371448efe4..4ec76fa9d2 100644
--- a/server/src/database.ts
+++ b/server/src/database.ts
@@ -10,6 +10,20 @@ export type AuthUser = {
   quotaSizeInBytes: number | null;
 };
 
+export type Library = {
+  id: string;
+  ownerId: string;
+  createdAt: Date;
+  updatedAt: Date;
+  updateId: string;
+  name: string;
+  importPaths: string[];
+  exclusionPatterns: string[];
+  deletedAt: Date | null;
+  refreshedAt: Date | null;
+  assets?: Asset[];
+};
+
 export type AuthApiKey = {
   id: string;
   permissions: Permission[];
diff --git a/server/src/dtos/library.dto.ts b/server/src/dtos/library.dto.ts
index 7fb363dd9a..a0aaace13d 100644
--- a/server/src/dtos/library.dto.ts
+++ b/server/src/dtos/library.dto.ts
@@ -1,6 +1,6 @@
 import { ApiProperty } from '@nestjs/swagger';
 import { ArrayMaxSize, ArrayUnique, IsNotEmpty, IsString } from 'class-validator';
-import { LibraryEntity } from 'src/entities/library.entity';
+import { Library } from 'src/database';
 import { Optional, ValidateUUID } from 'src/validation';
 
 export class CreateLibraryDto {
@@ -120,7 +120,7 @@ export class LibraryStatsResponseDto {
   usage = 0;
 }
 
-export function mapLibrary(entity: LibraryEntity): LibraryResponseDto {
+export function mapLibrary(entity: Library): LibraryResponseDto {
   let assetCount = 0;
   if (entity.assets) {
     assetCount = entity.assets.length;
diff --git a/server/src/entities/library.entity.ts b/server/src/entities/library.entity.ts
index a594fd83ad..0471661fca 100644
--- a/server/src/entities/library.entity.ts
+++ b/server/src/entities/library.entity.ts
@@ -26,7 +26,7 @@ export class LibraryEntity {
   assets!: AssetEntity[];
 
   @ManyToOne(() => UserEntity, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
-  owner!: UserEntity;
+  owner?: UserEntity;
 
   @Column()
   ownerId!: string;
diff --git a/server/src/queries/library.repository.sql b/server/src/queries/library.repository.sql
index b0b20fd8a2..43500a8748 100644
--- a/server/src/queries/library.repository.sql
+++ b/server/src/queries/library.repository.sql
@@ -2,34 +2,7 @@
 
 -- LibraryRepository.get
 select
-  "libraries".*,
-  (
-    select
-      to_json(obj)
-    from
-      (
-        select
-          "users"."id",
-          "users"."email",
-          "users"."createdAt",
-          "users"."profileImagePath",
-          "users"."isAdmin",
-          "users"."shouldChangePassword",
-          "users"."deletedAt",
-          "users"."oauthId",
-          "users"."updatedAt",
-          "users"."storageLabel",
-          "users"."name",
-          "users"."quotaSizeInBytes",
-          "users"."quotaUsageInBytes",
-          "users"."status",
-          "users"."profileChangedAt"
-        from
-          "users"
-        where
-          "users"."id" = "libraries"."ownerId"
-      ) as obj
-  ) as "owner"
+  "libraries".*
 from
   "libraries"
 where
@@ -38,34 +11,7 @@ where
 
 -- LibraryRepository.getAll
 select
-  "libraries".*,
-  (
-    select
-      to_json(obj)
-    from
-      (
-        select
-          "users"."id",
-          "users"."email",
-          "users"."createdAt",
-          "users"."profileImagePath",
-          "users"."isAdmin",
-          "users"."shouldChangePassword",
-          "users"."deletedAt",
-          "users"."oauthId",
-          "users"."updatedAt",
-          "users"."storageLabel",
-          "users"."name",
-          "users"."quotaSizeInBytes",
-          "users"."quotaUsageInBytes",
-          "users"."status",
-          "users"."profileChangedAt"
-        from
-          "users"
-        where
-          "users"."id" = "libraries"."ownerId"
-      ) as obj
-  ) as "owner"
+  "libraries".*
 from
   "libraries"
 where
@@ -75,34 +21,7 @@ order by
 
 -- LibraryRepository.getAllDeleted
 select
-  "libraries".*,
-  (
-    select
-      to_json(obj)
-    from
-      (
-        select
-          "users"."id",
-          "users"."email",
-          "users"."createdAt",
-          "users"."profileImagePath",
-          "users"."isAdmin",
-          "users"."shouldChangePassword",
-          "users"."deletedAt",
-          "users"."oauthId",
-          "users"."updatedAt",
-          "users"."storageLabel",
-          "users"."name",
-          "users"."quotaSizeInBytes",
-          "users"."quotaUsageInBytes",
-          "users"."status",
-          "users"."profileChangedAt"
-        from
-          "users"
-        where
-          "users"."id" = "libraries"."ownerId"
-      ) as obj
-  ) as "owner"
+  "libraries".*
 from
   "libraries"
 where
diff --git a/server/src/repositories/library.repository.ts b/server/src/repositories/library.repository.ts
index bd2cb0c1df..efa6e880d1 100644
--- a/server/src/repositories/library.repository.ts
+++ b/server/src/repositories/library.repository.ts
@@ -1,31 +1,11 @@
 import { Injectable } from '@nestjs/common';
-import { ExpressionBuilder, Insertable, Kysely, sql, Updateable } from 'kysely';
-import { jsonObjectFrom } from 'kysely/helpers/postgres';
+import { Insertable, Kysely, sql, Updateable } from 'kysely';
 import { InjectKysely } from 'nestjs-kysely';
 import { DB, Libraries } from 'src/db';
 import { DummyValue, GenerateSql } from 'src/decorators';
 import { LibraryStatsResponseDto } from 'src/dtos/library.dto';
-import { LibraryEntity } from 'src/entities/library.entity';
 import { AssetType } from 'src/enum';
 
-const userColumns = [
-  'users.id',
-  'users.email',
-  'users.createdAt',
-  'users.profileImagePath',
-  'users.isAdmin',
-  'users.shouldChangePassword',
-  'users.deletedAt',
-  'users.oauthId',
-  'users.updatedAt',
-  'users.storageLabel',
-  'users.name',
-  'users.quotaSizeInBytes',
-  'users.quotaUsageInBytes',
-  'users.status',
-  'users.profileChangedAt',
-] as const;
-
 export enum AssetSyncResult {
   DO_NOTHING,
   UPDATE,
@@ -33,72 +13,59 @@ export enum AssetSyncResult {
   CHECK_OFFLINE,
 }
 
-const withOwner = (eb: ExpressionBuilder<DB, 'libraries'>) => {
-  return jsonObjectFrom(eb.selectFrom('users').whereRef('users.id', '=', 'libraries.ownerId').select(userColumns)).as(
-    'owner',
-  );
-};
-
 @Injectable()
 export class LibraryRepository {
   constructor(@InjectKysely() private db: Kysely<DB>) {}
 
   @GenerateSql({ params: [DummyValue.UUID] })
-  get(id: string, withDeleted = false): Promise<LibraryEntity | undefined> {
+  get(id: string, withDeleted = false) {
     return this.db
       .selectFrom('libraries')
       .selectAll('libraries')
-      .select(withOwner)
       .where('libraries.id', '=', id)
       .$if(!withDeleted, (qb) => qb.where('libraries.deletedAt', 'is', null))
-      .executeTakeFirst() as Promise<LibraryEntity | undefined>;
+      .executeTakeFirst();
   }
 
   @GenerateSql({ params: [] })
-  getAll(withDeleted = false): Promise<LibraryEntity[]> {
+  getAll(withDeleted = false) {
     return this.db
       .selectFrom('libraries')
       .selectAll('libraries')
-      .select(withOwner)
       .orderBy('createdAt', 'asc')
       .$if(!withDeleted, (qb) => qb.where('libraries.deletedAt', 'is', null))
-      .execute() as unknown as Promise<LibraryEntity[]>;
+      .execute();
   }
 
   @GenerateSql()
-  getAllDeleted(): Promise<LibraryEntity[]> {
+  getAllDeleted() {
     return this.db
       .selectFrom('libraries')
       .selectAll('libraries')
-      .select(withOwner)
       .where('libraries.deletedAt', 'is not', null)
       .orderBy('createdAt', 'asc')
-      .execute() as unknown as Promise<LibraryEntity[]>;
+      .execute();
   }
 
-  create(library: Insertable<Libraries>): Promise<LibraryEntity> {
-    return this.db
-      .insertInto('libraries')
-      .values(library)
-      .returningAll()
-      .executeTakeFirstOrThrow() as Promise<LibraryEntity>;
+  create(library: Insertable<Libraries>) {
+    return this.db.insertInto('libraries').values(library).returningAll().executeTakeFirstOrThrow();
   }
 
-  async delete(id: string): Promise<void> {
+  async delete(id: string) {
     await this.db.deleteFrom('libraries').where('libraries.id', '=', id).execute();
   }
 
-  async softDelete(id: string): Promise<void> {
+  async softDelete(id: string) {
     await this.db.updateTable('libraries').set({ deletedAt: new Date() }).where('libraries.id', '=', id).execute();
   }
 
-  update(id: string, library: Updateable<Libraries>): Promise<LibraryEntity> {
+  update(id: string, library: Updateable<Libraries>) {
     return this.db
       .updateTable('libraries')
       .set(library)
       .where('libraries.id', '=', id)
       .returningAll()
-      .executeTakeFirstOrThrow() as Promise<LibraryEntity>;
+      .executeTakeFirstOrThrow();
   }
 
   @GenerateSql({ params: [DummyValue.UUID] })
diff --git a/server/src/services/library.service.spec.ts b/server/src/services/library.service.spec.ts
index 5c89b09561..5d6dfb21f5 100644
--- a/server/src/services/library.service.spec.ts
+++ b/server/src/services/library.service.spec.ts
@@ -3,16 +3,14 @@ import { Stats } from 'node:fs';
 import { defaults, SystemConfig } from 'src/config';
 import { JOBS_LIBRARY_PAGINATION_SIZE } from 'src/constants';
 import { mapLibrary } from 'src/dtos/library.dto';
-import { UserEntity } from 'src/entities/user.entity';
 import { AssetType, ImmichWorker, JobName, JobStatus } from 'src/enum';
 import { LibraryService } from 'src/services/library.service';
 import { ILibraryBulkIdsJob, ILibraryFileJob } from 'src/types';
 import { assetStub } from 'test/fixtures/asset.stub';
 import { authStub } from 'test/fixtures/auth.stub';
-import { libraryStub } from 'test/fixtures/library.stub';
 import { systemConfigStub } from 'test/fixtures/system-config.stub';
-import { userStub } from 'test/fixtures/user.stub';
 import { makeMockWatcher } from 'test/repositories/storage.repository.mock';
+import { factory, newUuid } from 'test/small.factory';
 import { makeStream, newTestService, ServiceMocks } from 'test/utils';
 import { vitest } from 'vitest';
 
@@ -59,26 +57,19 @@ describe(LibraryService.name, () => {
     });
 
     it('should initialize watcher for all external libraries', async () => {
-      mocks.library.getAll.mockResolvedValue([
-        libraryStub.externalLibraryWithImportPaths1,
-        libraryStub.externalLibraryWithImportPaths2,
-      ]);
+      const library1 = factory.library({ importPaths: ['/foo', '/bar'] });
+      const library2 = factory.library({ importPaths: ['/xyz', '/asdf'] });
+
+      mocks.library.getAll.mockResolvedValue([library1, library2]);
 
       mocks.library.get.mockImplementation((id) =>
-        Promise.resolve(
-          [libraryStub.externalLibraryWithImportPaths1, libraryStub.externalLibraryWithImportPaths2].find(
-            (library) => library.id === id,
-          ),
-        ),
+        Promise.resolve([library1, library2].find((library) => library.id === id)),
       );
 
       await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
 
       expect(mocks.storage.watch.mock.calls).toEqual(
-        expect.arrayContaining([
-          (libraryStub.externalLibrary1.importPaths, expect.anything()),
-          (libraryStub.externalLibrary2.importPaths, expect.anything()),
-        ]),
+        expect.arrayContaining([(library1.importPaths, expect.anything()), (library2.importPaths, expect.anything())]),
       );
     });
 
@@ -153,33 +144,36 @@ describe(LibraryService.name, () => {
 
   describe('handleQueueSyncFiles', () => {
     it('should queue refresh of a new asset', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.storage.walk.mockImplementation(mockWalk);
       mocks.storage.stat.mockResolvedValue({ isDirectory: () => true } as Stats);
       mocks.storage.checkFileExists.mockResolvedValue(true);
       mocks.asset.filterNewExternalAssetPaths.mockResolvedValue(['/data/user1/photo.jpg']);
 
-      await sut.handleQueueSyncFiles({ id: libraryStub.externalLibraryWithImportPaths1.id });
+      await sut.handleQueueSyncFiles({ id: library.id });
 
       expect(mocks.job.queue).toHaveBeenCalledWith({
         name: JobName.LIBRARY_SYNC_FILES,
         data: {
-          libraryId: libraryStub.externalLibraryWithImportPaths1.id,
+          libraryId: library.id,
           paths: ['/data/user1/photo.jpg'],
           progressCounter: 1,
         },
       });
     });
 
-    it("should fail when library can't be found", async () => {
-      await expect(sut.handleQueueSyncFiles({ id: libraryStub.externalLibraryWithImportPaths1.id })).resolves.toBe(
-        JobStatus.SKIPPED,
-      );
+    it('should fail when library is not found', async () => {
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+      await expect(sut.handleQueueSyncFiles({ id: library.id })).resolves.toBe(JobStatus.SKIPPED);
     });
 
     it('should ignore import paths that do not exist', async () => {
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
       mocks.storage.stat.mockImplementation((path): Promise<Stats> => {
-        if (path === libraryStub.externalLibraryWithImportPaths1.importPaths[0]) {
+        if (path === library.importPaths[0]) {
           const error = { code: 'ENOENT' } as any;
           throw error;
         }
@@ -190,12 +184,12 @@ describe(LibraryService.name, () => {
 
       mocks.storage.checkFileExists.mockResolvedValue(true);
 
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+      mocks.library.get.mockResolvedValue(library);
 
-      await sut.handleQueueSyncFiles({ id: libraryStub.externalLibraryWithImportPaths1.id });
+      await sut.handleQueueSyncFiles({ id: library.id });
 
       expect(mocks.storage.walk).toHaveBeenCalledWith({
-        pathsToCrawl: [libraryStub.externalLibraryWithImportPaths1.importPaths[1]],
+        pathsToCrawl: [library.importPaths[1]],
         exclusionPatterns: [],
         includeHidden: false,
         take: JOBS_LIBRARY_PAGINATION_SIZE,
@@ -205,18 +199,20 @@ describe(LibraryService.name, () => {
 
   describe('handleQueueSyncFiles', () => {
     it('should queue refresh of a new asset', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.storage.walk.mockImplementation(mockWalk);
       mocks.storage.stat.mockResolvedValue({ isDirectory: () => true } as Stats);
       mocks.storage.checkFileExists.mockResolvedValue(true);
       mocks.asset.filterNewExternalAssetPaths.mockResolvedValue(['/data/user1/photo.jpg']);
 
-      await sut.handleQueueSyncFiles({ id: libraryStub.externalLibraryWithImportPaths1.id });
+      await sut.handleQueueSyncFiles({ id: library.id });
 
       expect(mocks.job.queue).toHaveBeenCalledWith({
         name: JobName.LIBRARY_SYNC_FILES,
         data: {
-          libraryId: libraryStub.externalLibraryWithImportPaths1.id,
+          libraryId: library.id,
           paths: ['/data/user1/photo.jpg'],
           progressCounter: 1,
         },
@@ -224,12 +220,16 @@ describe(LibraryService.name, () => {
     });
 
     it("should fail when library can't be found", async () => {
-      await expect(sut.handleQueueSyncFiles({ id: libraryStub.externalLibrary1.id })).resolves.toBe(JobStatus.SKIPPED);
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+      await expect(sut.handleQueueSyncFiles({ id: library.id })).resolves.toBe(JobStatus.SKIPPED);
     });
 
     it('should ignore import paths that do not exist', async () => {
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
       mocks.storage.stat.mockImplementation((path): Promise<Stats> => {
-        if (path === libraryStub.externalLibraryWithImportPaths1.importPaths[0]) {
+        if (path === library.importPaths[0]) {
           const error = { code: 'ENOENT' } as any;
           throw error;
         }
@@ -240,12 +240,12 @@ describe(LibraryService.name, () => {
 
       mocks.storage.checkFileExists.mockResolvedValue(true);
 
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+      mocks.library.get.mockResolvedValue(library);
 
-      await sut.handleQueueSyncFiles({ id: libraryStub.externalLibraryWithImportPaths1.id });
+      await sut.handleQueueSyncFiles({ id: library.id });
 
       expect(mocks.storage.walk).toHaveBeenCalledWith({
-        pathsToCrawl: [libraryStub.externalLibraryWithImportPaths1.importPaths[1]],
+        pathsToCrawl: [library.importPaths[1]],
         exclusionPatterns: [],
         includeHidden: false,
         take: JOBS_LIBRARY_PAGINATION_SIZE,
@@ -255,51 +255,57 @@ describe(LibraryService.name, () => {
 
   describe('handleQueueSyncAssets', () => {
     it('should call the offline check', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.storage.walk.mockImplementation(async function* generator() {});
       mocks.asset.getAll.mockResolvedValue({ items: [assetStub.external], hasNextPage: false });
       mocks.asset.getLibraryAssetCount.mockResolvedValue(1);
       mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(1) });
 
-      const response = await sut.handleQueueSyncAssets({ id: libraryStub.externalLibrary1.id });
+      const response = await sut.handleQueueSyncAssets({ id: library.id });
 
       expect(response).toBe(JobStatus.SUCCESS);
       expect(mocks.asset.detectOfflineExternalAssets).toHaveBeenCalledWith(
-        libraryStub.externalLibrary1.id,
-        libraryStub.externalLibrary1.importPaths,
-        libraryStub.externalLibrary1.exclusionPatterns,
+        library.id,
+        library.importPaths,
+        library.exclusionPatterns,
       );
     });
 
     it('should skip an empty library', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.storage.walk.mockImplementation(async function* generator() {});
       mocks.asset.getAll.mockResolvedValue({ items: [assetStub.external], hasNextPage: false });
       mocks.asset.getLibraryAssetCount.mockResolvedValue(0);
       mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(1) });
 
-      const response = await sut.handleQueueSyncAssets({ id: libraryStub.externalLibrary1.id });
+      const response = await sut.handleQueueSyncAssets({ id: library.id });
 
       expect(response).toBe(JobStatus.SUCCESS);
       expect(mocks.asset.detectOfflineExternalAssets).not.toHaveBeenCalled();
     });
 
     it('should queue asset sync', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.storage.walk.mockImplementation(async function* generator() {});
       mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.external]));
       mocks.asset.getLibraryAssetCount.mockResolvedValue(1);
       mocks.asset.detectOfflineExternalAssets.mockResolvedValue({ numUpdatedRows: BigInt(0) });
       mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.external]));
 
-      const response = await sut.handleQueueSyncAssets({ id: libraryStub.externalLibraryWithImportPaths1.id });
+      const response = await sut.handleQueueSyncAssets({ id: library.id });
 
       expect(mocks.job.queue).toBeCalledWith({
         name: JobName.LIBRARY_SYNC_ASSETS,
         data: {
-          libraryId: libraryStub.externalLibraryWithImportPaths1.id,
-          importPaths: libraryStub.externalLibraryWithImportPaths1.importPaths,
-          exclusionPatterns: libraryStub.externalLibraryWithImportPaths1.exclusionPatterns,
+          libraryId: library.id,
+          importPaths: library.importPaths,
+          exclusionPatterns: library.exclusionPatterns,
           assetIds: [assetStub.external.id],
           progressCounter: 1,
           totalAssets: 1,
@@ -308,14 +314,14 @@ describe(LibraryService.name, () => {
 
       expect(response).toBe(JobStatus.SUCCESS);
       expect(mocks.asset.detectOfflineExternalAssets).toHaveBeenCalledWith(
-        libraryStub.externalLibraryWithImportPaths1.id,
-        libraryStub.externalLibraryWithImportPaths1.importPaths,
-        libraryStub.externalLibraryWithImportPaths1.exclusionPatterns,
+        library.id,
+        library.importPaths,
+        library.exclusionPatterns,
       );
     });
 
     it("should fail if library can't be found", async () => {
-      await expect(sut.handleQueueSyncAssets({ id: libraryStub.externalLibrary1.id })).resolves.toBe(JobStatus.SKIPPED);
+      await expect(sut.handleQueueSyncAssets({ id: newUuid() })).resolves.toBe(JobStatus.SKIPPED);
     });
   });
 
@@ -323,7 +329,7 @@ describe(LibraryService.name, () => {
     it('should offline assets no longer on disk', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.external.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -344,7 +350,7 @@ describe(LibraryService.name, () => {
     it('should set assets deleted from disk as offline', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.external.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/data/user2'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -365,7 +371,7 @@ describe(LibraryService.name, () => {
     it('should do nothing with offline assets deleted from disk', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.trashedOffline.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/data/user2'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -383,7 +389,7 @@ describe(LibraryService.name, () => {
     it('should un-trash an asset previously marked as offline', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.trashedOffline.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/original/'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -404,7 +410,7 @@ describe(LibraryService.name, () => {
     it('should do nothing with offline asset if covered by exclusion pattern', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.trashedOffline.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/original/'],
         exclusionPatterns: ['**/path.jpg'],
         totalAssets: 1,
@@ -424,7 +430,7 @@ describe(LibraryService.name, () => {
     it('should do nothing with offline asset if not in import path', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.trashedOffline.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/import/'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -444,7 +450,7 @@ describe(LibraryService.name, () => {
     it('should do nothing with unchanged online assets', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.external.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -462,7 +468,7 @@ describe(LibraryService.name, () => {
     it('should not touch fileCreatedAt when un-trashing an asset previously marked as offline', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.trashedOffline.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -485,7 +491,7 @@ describe(LibraryService.name, () => {
     it('should update with online assets that have changed', async () => {
       const mockAssetJob: ILibraryBulkIdsJob = {
         assetIds: [assetStub.external.id],
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: newUuid(),
         importPaths: ['/'],
         exclusionPatterns: [],
         totalAssets: 1,
@@ -516,11 +522,7 @@ describe(LibraryService.name, () => {
   });
 
   describe('handleSyncFiles', () => {
-    let mockUser: UserEntity;
-
     beforeEach(() => {
-      mockUser = userStub.admin;
-
       mocks.storage.stat.mockResolvedValue({
         size: 100,
         mtime: new Date('2023-01-01'),
@@ -529,54 +531,50 @@ describe(LibraryService.name, () => {
     });
 
     it('should import a new asset', async () => {
+      const library = factory.library();
+
       const mockLibraryJob: ILibraryFileJob = {
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: library.id,
         paths: ['/data/user1/photo.jpg'],
       };
 
       mocks.asset.createAll.mockResolvedValue([assetStub.image]);
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      mocks.library.get.mockResolvedValue(library);
 
       await expect(sut.handleSyncFiles(mockLibraryJob)).resolves.toBe(JobStatus.SUCCESS);
 
-      expect(mocks.asset.createAll.mock.calls).toEqual([
-        [
-          [
-            expect.objectContaining({
-              ownerId: mockUser.id,
-              libraryId: libraryStub.externalLibrary1.id,
-              originalPath: '/data/user1/photo.jpg',
-              deviceId: 'Library Import',
-              type: AssetType.IMAGE,
-              originalFileName: 'photo.jpg',
-              isExternal: true,
-            }),
-          ],
-        ],
+      expect(mocks.asset.createAll).toHaveBeenCalledWith([
+        expect.objectContaining({
+          ownerId: library.ownerId,
+          libraryId: library.id,
+          originalPath: '/data/user1/photo.jpg',
+          deviceId: 'Library Import',
+          type: AssetType.IMAGE,
+          originalFileName: 'photo.jpg',
+          isExternal: true,
+        }),
       ]);
 
-      expect(mocks.job.queueAll.mock.calls).toEqual([
-        [
-          [
-            {
-              name: JobName.SIDECAR_DISCOVERY,
-              data: {
-                id: assetStub.image.id,
-                source: 'upload',
-              },
-            },
-          ],
-        ],
+      expect(mocks.job.queueAll).toHaveBeenCalledWith([
+        {
+          name: JobName.SIDECAR_DISCOVERY,
+          data: {
+            id: assetStub.image.id,
+            source: 'upload',
+          },
+        },
       ]);
     });
 
     it('should not import an asset to a soft deleted library', async () => {
+      const library = factory.library({ deletedAt: new Date() });
+
       const mockLibraryJob: ILibraryFileJob = {
-        libraryId: libraryStub.externalLibrary1.id,
+        libraryId: library.id,
         paths: ['/data/user1/photo.jpg'],
       };
 
-      mocks.library.get.mockResolvedValue({ ...libraryStub.externalLibrary1, deletedAt: new Date() });
+      mocks.library.get.mockResolvedValue(library);
 
       await expect(sut.handleSyncFiles(mockLibraryJob)).resolves.toBe(JobStatus.FAILED);
 
@@ -586,43 +584,45 @@ describe(LibraryService.name, () => {
 
   describe('delete', () => {
     it('should delete a library', async () => {
+      const library = factory.library();
+
       mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      mocks.library.get.mockResolvedValue(library);
 
-      await sut.delete(libraryStub.externalLibrary1.id);
+      await sut.delete(library.id);
 
-      expect(mocks.job.queue).toHaveBeenCalledWith({
-        name: JobName.LIBRARY_DELETE,
-        data: { id: libraryStub.externalLibrary1.id },
-      });
-
-      expect(mocks.library.softDelete).toHaveBeenCalledWith(libraryStub.externalLibrary1.id);
+      expect(mocks.job.queue).toHaveBeenCalledWith({ name: JobName.LIBRARY_DELETE, data: { id: library.id } });
+      expect(mocks.library.softDelete).toHaveBeenCalledWith(library.id);
     });
 
     it('should allow an external library to be deleted', async () => {
-      mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
 
-      await sut.delete(libraryStub.externalLibrary1.id);
+      mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
+      mocks.library.get.mockResolvedValue(library);
+
+      await sut.delete(library.id);
 
       expect(mocks.job.queue).toHaveBeenCalledWith({
         name: JobName.LIBRARY_DELETE,
-        data: { id: libraryStub.externalLibrary1.id },
+        data: { id: library.id },
       });
 
-      expect(mocks.library.softDelete).toHaveBeenCalledWith(libraryStub.externalLibrary1.id);
+      expect(mocks.library.softDelete).toHaveBeenCalledWith(library.id);
     });
 
     it('should unwatch an external library when deleted', async () => {
+      const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
       mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-      mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+      mocks.library.get.mockResolvedValue(library);
+      mocks.library.getAll.mockResolvedValue([library]);
 
       const mockClose = vitest.fn();
       mocks.storage.watch.mockImplementation(makeMockWatcher({ close: mockClose }));
 
       await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
-      await sut.delete(libraryStub.externalLibraryWithImportPaths1.id);
+      await sut.delete(library.id);
 
       expect(mockClose).toHaveBeenCalled();
     });
@@ -630,52 +630,62 @@ describe(LibraryService.name, () => {
 
   describe('get', () => {
     it('should return a library', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
-      await expect(sut.get(libraryStub.externalLibrary1.id)).resolves.toEqual(
+      const library = factory.library();
+
+      mocks.library.get.mockResolvedValue(library);
+
+      await expect(sut.get(library.id)).resolves.toEqual(
         expect.objectContaining({
-          id: libraryStub.externalLibrary1.id,
-          name: libraryStub.externalLibrary1.name,
-          ownerId: libraryStub.externalLibrary1.ownerId,
+          id: library.id,
+          name: library.name,
+          ownerId: library.ownerId,
         }),
       );
 
-      expect(mocks.library.get).toHaveBeenCalledWith(libraryStub.externalLibrary1.id);
+      expect(mocks.library.get).toHaveBeenCalledWith(library.id);
     });
 
     it('should throw an error when a library is not found', async () => {
-      await expect(sut.get(libraryStub.externalLibrary1.id)).rejects.toBeInstanceOf(BadRequestException);
-      expect(mocks.library.get).toHaveBeenCalledWith(libraryStub.externalLibrary1.id);
+      const library = factory.library();
+
+      await expect(sut.get(library.id)).rejects.toBeInstanceOf(BadRequestException);
+
+      expect(mocks.library.get).toHaveBeenCalledWith(library.id);
     });
   });
 
   describe('getStatistics', () => {
     it('should return library statistics', async () => {
+      const library = factory.library();
+
       mocks.library.getStatistics.mockResolvedValue({ photos: 10, videos: 0, total: 10, usage: 1337 });
-      await expect(sut.getStatistics(libraryStub.externalLibrary1.id)).resolves.toEqual({
+      await expect(sut.getStatistics(library.id)).resolves.toEqual({
         photos: 10,
         videos: 0,
         total: 10,
         usage: 1337,
       });
 
-      expect(mocks.library.getStatistics).toHaveBeenCalledWith(libraryStub.externalLibrary1.id);
+      expect(mocks.library.getStatistics).toHaveBeenCalledWith(library.id);
     });
   });
 
   describe('create', () => {
     describe('external library', () => {
       it('should create with default settings', async () => {
-        mocks.library.create.mockResolvedValue(libraryStub.externalLibrary1);
+        const library = factory.library();
+
+        mocks.library.create.mockResolvedValue(library);
         await expect(sut.create({ ownerId: authStub.admin.user.id })).resolves.toEqual(
           expect.objectContaining({
-            id: libraryStub.externalLibrary1.id,
-            name: libraryStub.externalLibrary1.name,
-            ownerId: libraryStub.externalLibrary1.ownerId,
+            id: library.id,
+            name: library.name,
+            ownerId: library.ownerId,
             assetCount: 0,
             importPaths: [],
             exclusionPatterns: [],
-            createdAt: libraryStub.externalLibrary1.createdAt,
-            updatedAt: libraryStub.externalLibrary1.updatedAt,
+            createdAt: library.createdAt,
+            updatedAt: library.updatedAt,
             refreshedAt: null,
           }),
         );
@@ -690,17 +700,20 @@ describe(LibraryService.name, () => {
       });
 
       it('should create with name', async () => {
-        mocks.library.create.mockResolvedValue(libraryStub.externalLibrary1);
+        const library = factory.library();
+
+        mocks.library.create.mockResolvedValue(library);
+
         await expect(sut.create({ ownerId: authStub.admin.user.id, name: 'My Awesome Library' })).resolves.toEqual(
           expect.objectContaining({
-            id: libraryStub.externalLibrary1.id,
-            name: libraryStub.externalLibrary1.name,
-            ownerId: libraryStub.externalLibrary1.ownerId,
+            id: library.id,
+            name: library.name,
+            ownerId: library.ownerId,
             assetCount: 0,
             importPaths: [],
             exclusionPatterns: [],
-            createdAt: libraryStub.externalLibrary1.createdAt,
-            updatedAt: libraryStub.externalLibrary1.updatedAt,
+            createdAt: library.createdAt,
+            updatedAt: library.updatedAt,
             refreshedAt: null,
           }),
         );
@@ -715,7 +728,9 @@ describe(LibraryService.name, () => {
       });
 
       it('should create with import paths', async () => {
-        mocks.library.create.mockResolvedValue(libraryStub.externalLibrary1);
+        const library = factory.library();
+
+        mocks.library.create.mockResolvedValue(library);
         await expect(
           sut.create({
             ownerId: authStub.admin.user.id,
@@ -723,14 +738,14 @@ describe(LibraryService.name, () => {
           }),
         ).resolves.toEqual(
           expect.objectContaining({
-            id: libraryStub.externalLibrary1.id,
-            name: libraryStub.externalLibrary1.name,
-            ownerId: libraryStub.externalLibrary1.ownerId,
+            id: library.id,
+            name: library.name,
+            ownerId: library.ownerId,
             assetCount: 0,
             importPaths: [],
             exclusionPatterns: [],
-            createdAt: libraryStub.externalLibrary1.createdAt,
-            updatedAt: libraryStub.externalLibrary1.updatedAt,
+            createdAt: library.createdAt,
+            updatedAt: library.updatedAt,
             refreshedAt: null,
           }),
         );
@@ -745,19 +760,20 @@ describe(LibraryService.name, () => {
       });
 
       it('should create watched with import paths', async () => {
-        mocks.library.create.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.create.mockResolvedValue(library);
+        mocks.library.get.mockResolvedValue(library);
         mocks.library.getAll.mockResolvedValue([]);
 
         await sut.onConfigInit({ newConfig: systemConfigStub.libraryWatchEnabled as SystemConfig });
-        await sut.create({
-          ownerId: authStub.admin.user.id,
-          importPaths: libraryStub.externalLibraryWithImportPaths1.importPaths,
-        });
+        await sut.create({ ownerId: authStub.admin.user.id, importPaths: library.importPaths });
       });
 
       it('should create with exclusion patterns', async () => {
-        mocks.library.create.mockResolvedValue(libraryStub.externalLibrary1);
+        const library = factory.library();
+
+        mocks.library.create.mockResolvedValue(library);
         await expect(
           sut.create({
             ownerId: authStub.admin.user.id,
@@ -765,14 +781,14 @@ describe(LibraryService.name, () => {
           }),
         ).resolves.toEqual(
           expect.objectContaining({
-            id: libraryStub.externalLibrary1.id,
-            name: libraryStub.externalLibrary1.name,
-            ownerId: libraryStub.externalLibrary1.ownerId,
+            id: library.id,
+            name: library.name,
+            ownerId: library.ownerId,
             assetCount: 0,
             importPaths: [],
             exclusionPatterns: [],
-            createdAt: libraryStub.externalLibrary1.createdAt,
-            updatedAt: libraryStub.externalLibrary1.updatedAt,
+            createdAt: library.createdAt,
+            updatedAt: library.updatedAt,
             refreshedAt: null,
           }),
         );
@@ -790,19 +806,25 @@ describe(LibraryService.name, () => {
 
   describe('getAll', () => {
     it('should get all libraries', async () => {
-      mocks.library.getAll.mockResolvedValue([libraryStub.externalLibrary1]);
-      await expect(sut.getAll()).resolves.toEqual([expect.objectContaining({ id: libraryStub.externalLibrary1.id })]);
+      const library = factory.library();
+
+      mocks.library.getAll.mockResolvedValue([library]);
+
+      await expect(sut.getAll()).resolves.toEqual([expect.objectContaining({ id: library.id })]);
     });
   });
 
   describe('handleQueueCleanup', () => {
     it('should queue cleanup jobs', async () => {
-      mocks.library.getAllDeleted.mockResolvedValue([libraryStub.externalLibrary1, libraryStub.externalLibrary2]);
+      const library1 = factory.library({ deletedAt: new Date() });
+      const library2 = factory.library({ deletedAt: new Date() });
+
+      mocks.library.getAllDeleted.mockResolvedValue([library1, library2]);
       await expect(sut.handleQueueCleanup()).resolves.toBe(JobStatus.SUCCESS);
 
       expect(mocks.job.queueAll).toHaveBeenCalledWith([
-        { name: JobName.LIBRARY_DELETE, data: { id: libraryStub.externalLibrary1.id } },
-        { name: JobName.LIBRARY_DELETE, data: { id: libraryStub.externalLibrary2.id } },
+        { name: JobName.LIBRARY_DELETE, data: { id: library1.id } },
+        { name: JobName.LIBRARY_DELETE, data: { id: library2.id } },
       ]);
     });
   });
@@ -815,24 +837,27 @@ describe(LibraryService.name, () => {
     });
 
     it('should throw an error if an import path is invalid', async () => {
-      mocks.library.update.mockResolvedValue(libraryStub.externalLibrary1);
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
+
+      mocks.library.update.mockResolvedValue(library);
+      mocks.library.get.mockResolvedValue(library);
 
       await expect(sut.update('library-id', { importPaths: ['foo/bar'] })).rejects.toBeInstanceOf(BadRequestException);
+
       expect(mocks.library.update).not.toHaveBeenCalled();
     });
 
     it('should update library', async () => {
-      mocks.library.update.mockResolvedValue(libraryStub.externalLibrary1);
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
+
+      mocks.library.update.mockResolvedValue(library);
+      mocks.library.get.mockResolvedValue(library);
       mocks.storage.stat.mockResolvedValue({ isDirectory: () => true } as Stats);
       mocks.storage.checkFileExists.mockResolvedValue(true);
 
       const cwd = process.cwd();
 
-      await expect(sut.update('library-id', { importPaths: [`${cwd}/foo/bar`] })).resolves.toEqual(
-        mapLibrary(libraryStub.externalLibrary1),
-      );
+      await expect(sut.update('library-id', { importPaths: [`${cwd}/foo/bar`] })).resolves.toEqual(mapLibrary(library));
       expect(mocks.library.update).toHaveBeenCalledWith(
         'library-id',
         expect.objectContaining({ importPaths: [`${cwd}/foo/bar`] }),
@@ -857,7 +882,9 @@ describe(LibraryService.name, () => {
       });
 
       it('should not watch library', async () => {
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.getAll.mockResolvedValue([library]);
 
         await sut.watchAll();
 
@@ -872,33 +899,35 @@ describe(LibraryService.name, () => {
       });
 
       it('should watch library', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
 
         await sut.watchAll();
 
-        expect(mocks.storage.watch).toHaveBeenCalledWith(
-          libraryStub.externalLibraryWithImportPaths1.importPaths,
-          expect.anything(),
-          expect.anything(),
-        );
+        expect(mocks.storage.watch).toHaveBeenCalledWith(library.importPaths, expect.anything(), expect.anything());
       });
 
       it('should watch and unwatch library', async () => {
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.getAll.mockResolvedValue([library]);
+        mocks.library.get.mockResolvedValue(library);
         const mockClose = vitest.fn();
         mocks.storage.watch.mockImplementation(makeMockWatcher({ close: mockClose }));
 
         await sut.watchAll();
-        await sut.unwatch(libraryStub.externalLibraryWithImportPaths1.id);
+        await sut.unwatch(library.id);
 
         expect(mockClose).toHaveBeenCalled();
       });
 
       it('should not watch library without import paths', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibrary1]);
+        const library = factory.library();
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
 
         await sut.watchAll();
 
@@ -906,8 +935,10 @@ describe(LibraryService.name, () => {
       });
 
       it('should handle a new file event', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
         mocks.storage.watch.mockImplementation(makeMockWatcher({ items: [{ event: 'add', value: '/foo/photo.jpg' }] }));
 
@@ -916,15 +947,17 @@ describe(LibraryService.name, () => {
         expect(mocks.job.queue).toHaveBeenCalledWith({
           name: JobName.LIBRARY_SYNC_FILES,
           data: {
-            libraryId: libraryStub.externalLibraryWithImportPaths1.id,
+            libraryId: library.id,
             paths: ['/foo/photo.jpg'],
           },
         });
       });
 
       it('should handle a file change event', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
         mocks.storage.watch.mockImplementation(
           makeMockWatcher({ items: [{ event: 'change', value: '/foo/photo.jpg' }] }),
@@ -935,15 +968,17 @@ describe(LibraryService.name, () => {
         expect(mocks.job.queue).toHaveBeenCalledWith({
           name: JobName.LIBRARY_SYNC_FILES,
           data: {
-            libraryId: libraryStub.externalLibraryWithImportPaths1.id,
+            libraryId: library.id,
             paths: ['/foo/photo.jpg'],
           },
         });
       });
 
       it('should handle a file unlink event', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.image);
         mocks.storage.watch.mockImplementation(
           makeMockWatcher({ items: [{ event: 'unlink', value: assetStub.image.originalPath }] }),
@@ -954,16 +989,18 @@ describe(LibraryService.name, () => {
         expect(mocks.job.queue).toHaveBeenCalledWith({
           name: JobName.LIBRARY_ASSET_REMOVAL,
           data: {
-            libraryId: libraryStub.externalLibraryWithImportPaths1.id,
+            libraryId: library.id,
             paths: [assetStub.image.originalPath],
           },
         });
       });
 
       it('should handle an error event', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.get.mockResolvedValue(library);
         mocks.asset.getByLibraryIdAndOriginalPath.mockResolvedValue(assetStub.external);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.storage.watch.mockImplementation(
           makeMockWatcher({
             items: [{ event: 'error', value: 'Error!' }],
@@ -974,8 +1011,10 @@ describe(LibraryService.name, () => {
       });
 
       it('should not import a file with unknown extension', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.externalLibraryWithImportPaths1);
-        mocks.library.getAll.mockResolvedValue([libraryStub.externalLibraryWithImportPaths1]);
+        const library = factory.library({ importPaths: ['/foo', '/bar'] });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.storage.watch.mockImplementation(makeMockWatcher({ items: [{ event: 'add', value: '/foo/photo.xyz' }] }));
 
         await sut.watchAll();
@@ -984,8 +1023,10 @@ describe(LibraryService.name, () => {
       });
 
       it('should ignore excluded paths', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.patternPath);
-        mocks.library.getAll.mockResolvedValue([libraryStub.patternPath]);
+        const library = factory.library({ importPaths: ['/xyz', '/asdf'], exclusionPatterns: ['**/dir1/**'] });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.storage.watch.mockImplementation(
           makeMockWatcher({ items: [{ event: 'add', value: '/dir1/photo.txt' }] }),
         );
@@ -996,8 +1037,13 @@ describe(LibraryService.name, () => {
       });
 
       it('should ignore excluded paths without case sensitivity', async () => {
-        mocks.library.get.mockResolvedValue(libraryStub.patternPath);
-        mocks.library.getAll.mockResolvedValue([libraryStub.patternPath]);
+        const library = factory.library({
+          importPaths: ['/xyz', '/asdf'],
+          exclusionPatterns: ['**/dir1/**'],
+        });
+
+        mocks.library.get.mockResolvedValue(library);
+        mocks.library.getAll.mockResolvedValue([library]);
         mocks.storage.watch.mockImplementation(
           makeMockWatcher({ items: [{ event: 'add', value: '/DIR1/photo.txt' }] }),
         );
@@ -1011,19 +1057,12 @@ describe(LibraryService.name, () => {
 
   describe('teardown', () => {
     it('should tear down all watchers', async () => {
-      mocks.library.getAll.mockResolvedValue([
-        libraryStub.externalLibraryWithImportPaths1,
-        libraryStub.externalLibraryWithImportPaths2,
-      ]);
-
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library1 = factory.library({ importPaths: ['/foo', '/bar'] });
+      const library2 = factory.library({ importPaths: ['/xyz', '/asdf'] });
 
+      mocks.library.getAll.mockResolvedValue([library1, library2]);
       mocks.library.get.mockImplementation((id) =>
-        Promise.resolve(
-          [libraryStub.externalLibraryWithImportPaths1, libraryStub.externalLibraryWithImportPaths2].find(
-            (library) => library.id === id,
-          ),
-        ),
+        Promise.resolve([library1, library2].find((library) => library.id === id)),
       );
 
       const mockClose = vitest.fn();
@@ -1038,71 +1077,62 @@ describe(LibraryService.name, () => {
 
   describe('handleDeleteLibrary', () => {
     it('should delete an empty library', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.library.streamAssetIds.mockReturnValue(makeStream([]));
 
-      await expect(sut.handleDeleteLibrary({ id: libraryStub.externalLibrary1.id })).resolves.toBe(JobStatus.SUCCESS);
+      await expect(sut.handleDeleteLibrary({ id: library.id })).resolves.toBe(JobStatus.SUCCESS);
+
       expect(mocks.library.delete).toHaveBeenCalled();
     });
 
     it('should delete all assets in a library', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
+
+      mocks.library.get.mockResolvedValue(library);
       mocks.library.streamAssetIds.mockReturnValue(makeStream([assetStub.image1]));
 
       mocks.asset.getById.mockResolvedValue(assetStub.image1);
 
-      await expect(sut.handleDeleteLibrary({ id: libraryStub.externalLibrary1.id })).resolves.toBe(JobStatus.SUCCESS);
+      await expect(sut.handleDeleteLibrary({ id: library.id })).resolves.toBe(JobStatus.SUCCESS);
     });
   });
 
   describe('queueScan', () => {
     it('should queue a library scan', async () => {
-      mocks.library.get.mockResolvedValue(libraryStub.externalLibrary1);
+      const library = factory.library();
 
-      await sut.queueScan(libraryStub.externalLibrary1.id);
+      mocks.library.get.mockResolvedValue(library);
 
-      expect(mocks.job.queue.mock.calls).toEqual([
-        [
-          {
-            name: JobName.LIBRARY_QUEUE_SYNC_FILES,
-            data: {
-              id: libraryStub.externalLibrary1.id,
-            },
-          },
-        ],
-        [
-          {
-            name: JobName.LIBRARY_QUEUE_SYNC_ASSETS,
-            data: {
-              id: libraryStub.externalLibrary1.id,
-            },
-          },
-        ],
-      ]);
+      await sut.queueScan(library.id);
+
+      expect(mocks.job.queue).toHaveBeenCalledTimes(2);
+      expect(mocks.job.queue).toHaveBeenCalledWith({
+        name: JobName.LIBRARY_QUEUE_SYNC_FILES,
+        data: { id: library.id },
+      });
+      expect(mocks.job.queue).toHaveBeenCalledWith({
+        name: JobName.LIBRARY_QUEUE_SYNC_ASSETS,
+        data: { id: library.id },
+      });
     });
   });
 
   describe('handleQueueAllScan', () => {
     it('should queue the refresh job', async () => {
-      mocks.library.getAll.mockResolvedValue([libraryStub.externalLibrary1]);
+      const library = factory.library();
+
+      mocks.library.getAll.mockResolvedValue([library]);
 
       await expect(sut.handleQueueScanAll()).resolves.toBe(JobStatus.SUCCESS);
 
-      expect(mocks.job.queue.mock.calls).toEqual([
-        [
-          {
-            name: JobName.LIBRARY_QUEUE_CLEANUP,
-            data: {},
-          },
-        ],
-      ]);
+      expect(mocks.job.queue).toHaveBeenCalledWith({
+        name: JobName.LIBRARY_QUEUE_CLEANUP,
+        data: {},
+      });
       expect(mocks.job.queueAll).toHaveBeenCalledWith([
-        {
-          name: JobName.LIBRARY_QUEUE_SYNC_FILES,
-          data: {
-            id: libraryStub.externalLibrary1.id,
-          },
-        },
+        { name: JobName.LIBRARY_QUEUE_SYNC_FILES, data: { id: library.id } },
       ]);
     });
   });
@@ -1212,28 +1242,26 @@ describe(LibraryService.name, () => {
     });
 
     it('should detect when import path is in immich media folder', async () => {
+      const importPaths = ['upload/thumbs', `${process.cwd()}/xyz`, 'upload/library'];
+      const library = factory.library({ importPaths });
+
       mocks.storage.stat.mockResolvedValue({ isDirectory: () => true } as Stats);
-      const cwd = process.cwd();
 
-      const validImport = `${cwd}/${libraryStub.hasImmichPaths.importPaths[1]}`;
-      mocks.storage.checkFileExists.mockImplementation((importPath) => Promise.resolve(importPath === validImport));
+      mocks.storage.checkFileExists.mockImplementation((importPath) => Promise.resolve(importPath === importPaths[1]));
 
-      const pathStubs = libraryStub.hasImmichPaths.importPaths;
-      const importPaths = [pathStubs[0], validImport, pathStubs[2]];
-
-      await expect(sut.validate('library-id', { importPaths })).resolves.toEqual({
+      await expect(sut.validate(library.id, { importPaths })).resolves.toEqual({
         importPaths: [
           {
-            importPath: libraryStub.hasImmichPaths.importPaths[0],
+            importPath: importPaths[0],
             isValid: false,
             message: 'Cannot use media upload folder for external libraries',
           },
           {
-            importPath: validImport,
+            importPath: importPaths[1],
             isValid: true,
           },
           {
-            importPath: libraryStub.hasImmichPaths.importPaths[2],
+            importPath: importPaths[2],
             isValid: false,
             message: 'Cannot use media upload folder for external libraries',
           },
diff --git a/server/test/fixtures/asset.stub.ts b/server/test/fixtures/asset.stub.ts
index b7a8686b1f..c0902dddb3 100644
--- a/server/test/fixtures/asset.stub.ts
+++ b/server/test/fixtures/asset.stub.ts
@@ -6,7 +6,6 @@ import { AssetFileType, AssetStatus, AssetType } from 'src/enum';
 import { StorageAsset } from 'src/types';
 import { authStub } from 'test/fixtures/auth.stub';
 import { fileStub } from 'test/fixtures/file.stub';
-import { libraryStub } from 'test/fixtures/library.stub';
 import { userStub } from 'test/fixtures/user.stub';
 
 const previewFile: AssetFileEntity = {
@@ -396,7 +395,6 @@ export const assetStub = {
     livePhotoVideo: null,
     livePhotoVideoId: null,
     libraryId: 'library-id',
-    library: libraryStub.externalLibrary1,
     tags: [],
     sharedLinks: [],
     originalFileName: 'asset-id.jpg',
@@ -751,7 +749,6 @@ export const assetStub = {
     livePhotoVideo: null,
     livePhotoVideoId: null,
     libraryId: 'library-id',
-    library: libraryStub.externalLibrary1,
     tags: [],
     sharedLinks: [],
     originalFileName: 'photo.jpg',
diff --git a/server/test/fixtures/library.stub.ts b/server/test/fixtures/library.stub.ts
deleted file mode 100644
index bb40035dcc..0000000000
--- a/server/test/fixtures/library.stub.ts
+++ /dev/null
@@ -1,77 +0,0 @@
-import { LibraryEntity } from 'src/entities/library.entity';
-import { userStub } from 'test/fixtures/user.stub';
-
-export const libraryStub = {
-  externalLibrary1: Object.freeze<LibraryEntity>({
-    id: 'library-id',
-    name: 'test_library',
-    assets: [],
-    owner: userStub.admin,
-    ownerId: 'admin_id',
-    importPaths: [],
-    createdAt: new Date('2023-01-01'),
-    updatedAt: new Date('2023-01-01'),
-    refreshedAt: null,
-    exclusionPatterns: [],
-  }),
-  externalLibrary2: Object.freeze<LibraryEntity>({
-    id: 'library-id2',
-    name: 'test_library2',
-    assets: [],
-    owner: userStub.admin,
-    ownerId: 'admin_id',
-    importPaths: [],
-    createdAt: new Date('2021-01-01'),
-    updatedAt: new Date('2022-01-01'),
-    refreshedAt: null,
-    exclusionPatterns: [],
-  }),
-  externalLibraryWithImportPaths1: Object.freeze<LibraryEntity>({
-    id: 'library-id-with-paths1',
-    name: 'library-with-import-paths1',
-    assets: [],
-    owner: userStub.admin,
-    ownerId: 'admin_id',
-    importPaths: ['/foo', '/bar'],
-    createdAt: new Date('2023-01-01'),
-    updatedAt: new Date('2023-01-01'),
-    refreshedAt: null,
-    exclusionPatterns: [],
-  }),
-  externalLibraryWithImportPaths2: Object.freeze<LibraryEntity>({
-    id: 'library-id-with-paths2',
-    name: 'library-with-import-paths2',
-    assets: [],
-    owner: userStub.admin,
-    ownerId: 'admin_id',
-    importPaths: ['/xyz', '/asdf'],
-    createdAt: new Date('2023-01-01'),
-    updatedAt: new Date('2023-01-01'),
-    refreshedAt: null,
-    exclusionPatterns: [],
-  }),
-  patternPath: Object.freeze<LibraryEntity>({
-    id: 'library-id1337',
-    name: 'importpath-exclusion-library1',
-    assets: [],
-    owner: userStub.admin,
-    ownerId: 'user-id',
-    importPaths: ['/xyz', '/asdf'],
-    createdAt: new Date('2023-01-01'),
-    updatedAt: new Date('2023-01-01'),
-    refreshedAt: null,
-    exclusionPatterns: ['**/dir1/**'],
-  }),
-  hasImmichPaths: Object.freeze<LibraryEntity>({
-    id: 'library-id1337',
-    name: 'importpath-exclusion-library1',
-    assets: [],
-    owner: userStub.admin,
-    ownerId: 'user-id',
-    importPaths: ['upload/thumbs', 'xyz', 'upload/library'],
-    createdAt: new Date('2023-01-01'),
-    updatedAt: new Date('2023-01-01'),
-    refreshedAt: null,
-    exclusionPatterns: ['**/dir1/**'],
-  }),
-};
diff --git a/server/test/small.factory.ts b/server/test/small.factory.ts
index c3455660ce..d93056713a 100644
--- a/server/test/small.factory.ts
+++ b/server/test/small.factory.ts
@@ -1,5 +1,5 @@
 import { randomUUID } from 'node:crypto';
-import { Asset, AuthUser, User } from 'src/database';
+import { Asset, AuthUser, Library, User } from 'src/database';
 import { OnThisDayData } from 'src/entities/memory.entity';
 import { AssetStatus, AssetType, MemoryType } from 'src/enum';
 import { ActivityItem, MemoryItem } from 'src/types';
@@ -13,7 +13,11 @@ export const newDate = () => new Date();
 export const newUpdateId = () => 'uuid-v7';
 export const newSha1 = () => Buffer.from('this is a fake hash');
 
-const authUser = (authUser: Partial<AuthUser>) => ({
+const authFactory = (user: Partial<AuthUser> = {}) => ({
+  user: authUserFactory(user),
+});
+
+const authUserFactory = (authUser: Partial<AuthUser>) => ({
   id: newUuid(),
   isAdmin: false,
   name: 'Test User',
@@ -23,7 +27,7 @@ const authUser = (authUser: Partial<AuthUser>) => ({
   ...authUser,
 });
 
-const user = (user: Partial<User>) => ({
+const userFactory = (user: Partial<User> = {}) => ({
   id: newUuid(),
   name: 'Test User',
   email: 'test@immich.cloud',
@@ -32,75 +36,95 @@ const user = (user: Partial<User>) => ({
   ...user,
 });
 
-export const factory = {
-  auth: (user: Partial<AuthUser> = {}) => ({
-    user: authUser(user),
-  }),
-  authUser,
-  user,
-  asset: (asset: Partial<Asset> = {}) => ({
-    id: newUuid(),
-    createdAt: newDate(),
-    updatedAt: newDate(),
-    deletedAt: null,
-    updateId: newUpdateId(),
-    status: AssetStatus.ACTIVE,
-    checksum: newSha1(),
-    deviceAssetId: '',
-    deviceId: '',
-    duplicateId: null,
-    duration: null,
-    encodedVideoPath: null,
-    fileCreatedAt: newDate(),
-    fileModifiedAt: newDate(),
-    isArchived: false,
-    isExternal: false,
-    isFavorite: false,
-    isOffline: false,
-    isVisible: true,
-    libraryId: null,
-    livePhotoVideoId: null,
-    localDateTime: newDate(),
-    originalFileName: 'IMG_123.jpg',
-    originalPath: `upload/12/34/IMG_123.jpg`,
-    ownerId: newUuid(),
-    sidecarPath: null,
-    stackId: null,
-    thumbhash: null,
-    type: AssetType.IMAGE,
-    ...asset,
-  }),
-  activity: (activity: Partial<ActivityItem> = {}) => {
-    const userId = activity.userId || newUuid();
-    return {
-      id: newUuid(),
-      comment: null,
-      isLiked: false,
-      userId,
-      user: user({ id: userId }),
-      assetId: newUuid(),
-      albumId: newUuid(),
-      createdAt: newDate(),
-      updatedAt: newDate(),
-      updateId: newUpdateId(),
-      ...activity,
-    };
-  },
-  memory: (memory: Partial<MemoryItem> = {}) => ({
+const assetFactory = (asset: Partial<Asset> = {}) => ({
+  id: newUuid(),
+  createdAt: newDate(),
+  updatedAt: newDate(),
+  deletedAt: null,
+  updateId: newUpdateId(),
+  status: AssetStatus.ACTIVE,
+  checksum: newSha1(),
+  deviceAssetId: '',
+  deviceId: '',
+  duplicateId: null,
+  duration: null,
+  encodedVideoPath: null,
+  fileCreatedAt: newDate(),
+  fileModifiedAt: newDate(),
+  isArchived: false,
+  isExternal: false,
+  isFavorite: false,
+  isOffline: false,
+  isVisible: true,
+  libraryId: null,
+  livePhotoVideoId: null,
+  localDateTime: newDate(),
+  originalFileName: 'IMG_123.jpg',
+  originalPath: `upload/12/34/IMG_123.jpg`,
+  ownerId: newUuid(),
+  sidecarPath: null,
+  stackId: null,
+  thumbhash: null,
+  type: AssetType.IMAGE,
+  ...asset,
+});
+
+const activityFactory = (activity: Partial<ActivityItem> = {}) => {
+  const userId = activity.userId || newUuid();
+  return {
     id: newUuid(),
+    comment: null,
+    isLiked: false,
+    userId,
+    user: userFactory({ id: userId }),
+    assetId: newUuid(),
+    albumId: newUuid(),
     createdAt: newDate(),
     updatedAt: newDate(),
     updateId: newUpdateId(),
-    deletedAt: null,
-    ownerId: newUuid(),
-    type: MemoryType.ON_THIS_DAY,
-    data: { year: 2024 } as OnThisDayData,
-    isSaved: false,
-    memoryAt: newDate(),
-    seenAt: null,
-    showAt: newDate(),
-    hideAt: newDate(),
-    assets: [],
-    ...memory,
-  }),
+    ...activity,
+  };
+};
+
+const libraryFactory = (library: Partial<Library> = {}) => ({
+  id: newUuid(),
+  createdAt: newDate(),
+  updatedAt: newDate(),
+  updateId: newUpdateId(),
+  deletedAt: null,
+  refreshedAt: null,
+  name: 'Library',
+  assets: [],
+  ownerId: newUuid(),
+  importPaths: [],
+  exclusionPatterns: [],
+  ...library,
+});
+
+const memoryFactory = (memory: Partial<MemoryItem> = {}) => ({
+  id: newUuid(),
+  createdAt: newDate(),
+  updatedAt: newDate(),
+  updateId: newUpdateId(),
+  deletedAt: null,
+  ownerId: newUuid(),
+  type: MemoryType.ON_THIS_DAY,
+  data: { year: 2024 } as OnThisDayData,
+  isSaved: false,
+  memoryAt: newDate(),
+  seenAt: null,
+  showAt: newDate(),
+  hideAt: newDate(),
+  assets: [],
+  ...memory,
+});
+
+export const factory = {
+  activity: activityFactory,
+  asset: assetFactory,
+  auth: authFactory,
+  authUser: authUserFactory,
+  library: libraryFactory,
+  memory: memoryFactory,
+  user: userFactory,
 };