Skip to content

Commit

Permalink
refactor: last repository (#16042)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrasm91 authored Feb 11, 2025
1 parent 5f3a42a commit fa5aeaf
Show file tree
Hide file tree
Showing 71 changed files with 574 additions and 603 deletions.
10 changes: 5 additions & 5 deletions server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ import { IWorker } from 'src/constants';
import { controllers } from 'src/controllers';
import { entities } from 'src/entities';
import { ImmichWorker } from 'src/enum';
import { IJobRepository } from 'src/interfaces/job.interface';
import { AuthGuard } from 'src/middleware/auth.guard';
import { ErrorInterceptor } from 'src/middleware/error.interceptor';
import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor';
import { GlobalExceptionFilter } from 'src/middleware/global-exception.filter';
import { LoggingInterceptor } from 'src/middleware/logging.interceptor';
import { providers, repositories } from 'src/repositories';
import { repositories } from 'src/repositories';
import { ConfigRepository } from 'src/repositories/config.repository';
import { EventRepository } from 'src/repositories/event.repository';
import { JobRepository } from 'src/repositories/job.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { teardownTelemetry, TelemetryRepository } from 'src/repositories/telemetry.repository';
import { services } from 'src/services';
import { AuthService } from 'src/services/auth.service';
import { CliService } from 'src/services/cli.service';
import { DatabaseService } from 'src/services/database.service';

const common = [...services, ...providers, ...repositories];
const common = [...repositories, ...services];

const middleware = [
FileUploadInterceptor,
Expand Down Expand Up @@ -80,15 +80,15 @@ class BaseModule implements OnModuleInit, OnModuleDestroy {
@Inject(IWorker) private worker: ImmichWorker,
logger: LoggingRepository,
private eventRepository: EventRepository,
@Inject(IJobRepository) private jobRepository: IJobRepository,
private jobRepository: JobRepository,
private telemetryRepository: TelemetryRepository,
private authService: AuthService,
) {
logger.setAppName(this.worker);
}

async onModuleInit() {
this.telemetryRepository.setup({ repositories: [...providers.map(({ useClass }) => useClass), ...repositories] });
this.telemetryRepository.setup({ repositories });

this.jobRepository.setup({ services });
if (this.worker === ImmichWorker.MICROSERVICES) {
Expand Down
22 changes: 9 additions & 13 deletions server/src/bin/sync-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Reflector } from '@nestjs/core';
import { SchedulerRegistry } from '@nestjs/schedule';
import { Test } from '@nestjs/testing';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ClassConstructor } from 'class-transformer';
import { PostgresJSDialect } from 'kysely-postgres-js';
import { KyselyModule } from 'nestjs-kysely';
import { OpenTelemetryModule } from 'nestjs-otel';
Expand All @@ -13,7 +14,7 @@ import postgres from 'postgres';
import { format } from 'sql-formatter';
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
import { entities } from 'src/entities';
import { providers, repositories } from 'src/repositories';
import { repositories } from 'src/repositories';
import { AccessRepository } from 'src/repositories/access.repository';
import { ConfigRepository } from 'src/repositories/config.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
Expand Down Expand Up @@ -45,8 +46,7 @@ export class SqlLogger implements Logger {

const reflector = new Reflector();

type Repository = (typeof providers)[0]['useClass'];
type Provider = { provide: any; useClass: Repository };
type Repository = ClassConstructor<any>;
type SqlGeneratorOptions = { targetDir: string };

class SqlGenerator {
Expand All @@ -59,15 +59,11 @@ class SqlGenerator {
async run() {
try {
await this.setup();
const targets = [
...providers,
...repositories.map((repository) => ({ provide: repository, useClass: repository as any })),
];
for (const repository of targets) {
if (repository.provide === LoggingRepository) {
for (const Repository of repositories) {
if (Repository === LoggingRepository) {
continue;
}
await this.process(repository);
await this.process(Repository);
}
await this.write();
this.stats();
Expand Down Expand Up @@ -105,19 +101,19 @@ class SqlGenerator {
TypeOrmModule.forFeature(entities),
OpenTelemetryModule.forRoot(otel),
],
providers: [...providers, ...repositories, AuthService, SchedulerRegistry],
providers: [...repositories, AuthService, SchedulerRegistry],
}).compile();

this.app = await moduleFixture.createNestApplication().init();
}

async process({ provide: token, useClass: Repository }: Provider) {
async process(Repository: Repository) {
if (!this.app) {
throw new Error('Not initialized');
}

const data: string[] = [`-- NOTE: This file is auto generated by ./sql-generator`];
const instance = this.app.get<Repository>(token);
const instance = this.app.get<Repository>(Repository);

// normal repositories
data.push(...(await this.runTargets(instance, `${Repository.name}`)));
Expand Down
4 changes: 2 additions & 2 deletions server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import {
CQMode,
ImageFormat,
LogLevel,
QueueName,
ToneMapping,
TranscodeHWAccel,
TranscodePolicy,
VideoCodec,
VideoContainer,
} from 'src/enum';
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
import { ImageOptions } from 'src/types';
import { ConcurrentQueueName, ImageOptions } from 'src/types';

export interface SystemConfig {
backup: {
Expand Down
12 changes: 11 additions & 1 deletion server/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Duration } from 'luxon';
import { readFileSync } from 'node:fs';
import { SemVer } from 'semver';
import { ExifOrientation } from 'src/enum';
import { DatabaseExtension, ExifOrientation } from 'src/enum';

export const POSTGRES_VERSION_RANGE = '>=14.0.0';
export const VECTORS_VERSION_RANGE = '>=0.2 <0.4';
Expand All @@ -16,6 +16,16 @@ export const LIFECYCLE_EXTENSION = 'x-immich-lifecycle';
export const DEPRECATED_IN_PREFIX = 'This property was deprecated in ';
export const ADDED_IN_PREFIX = 'This property was added in ';

export const JOBS_ASSET_PAGINATION_SIZE = 1000;
export const JOBS_LIBRARY_PAGINATION_SIZE = 10_000;

export const EXTENSION_NAMES: Record<DatabaseExtension, string> = {
cube: 'cube',
earthdistance: 'earthdistance',
vector: 'pgvector',
vectors: 'pgvecto.rs',
} as const;

export const SALT_ROUNDS = 10;

export const IWorker = 'IWorker';
Expand Down
3 changes: 2 additions & 1 deletion server/src/controllers/asset-media.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ import { AuthDto } from 'src/dtos/auth.dto';
import { ImmichHeader, RouteKey } from 'src/enum';
import { AssetUploadInterceptor } from 'src/middleware/asset-upload.interceptor';
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { FileUploadInterceptor, UploadFiles, getFiles } from 'src/middleware/file-upload.interceptor';
import { FileUploadInterceptor, getFiles } from 'src/middleware/file-upload.interceptor';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { AssetMediaService } from 'src/services/asset-media.service';
import { UploadFiles } from 'src/types';
import { sendFile } from 'src/utils/file';
import { FileNotEmptyValidator, UUIDParamDto } from 'src/validation';

Expand Down
3 changes: 1 addition & 2 deletions server/src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { SetMetadata, applyDecorators } from '@nestjs/common';
import { ApiExtension, ApiOperation, ApiProperty, ApiTags } from '@nestjs/swagger';
import _ from 'lodash';
import { ADDED_IN_PREFIX, DEPRECATED_IN_PREFIX, LIFECYCLE_EXTENSION } from 'src/constants';
import { ImmichWorker, MetadataKey } from 'src/enum';
import { JobName, QueueName } from 'src/interfaces/job.interface';
import { ImmichWorker, JobName, MetadataKey, QueueName } from 'src/enum';
import { EmitEvent } from 'src/repositories/event.repository';
import { setUnion } from 'src/utils/set';

Expand Down
3 changes: 1 addition & 2 deletions server/src/dtos/job.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum, IsNotEmpty } from 'class-validator';
import { ManualJobName } from 'src/enum';
import { JobCommand, QueueName } from 'src/interfaces/job.interface';
import { JobCommand, ManualJobName, QueueName } from 'src/enum';
import { ValidateBoolean } from 'src/validation';

export class JobIdParamDto {
Expand Down
3 changes: 2 additions & 1 deletion server/src/dtos/system-config.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ import {
Colorspace,
ImageFormat,
LogLevel,
QueueName,
ToneMapping,
TranscodeHWAccel,
TranscodePolicy,
VideoCodec,
VideoContainer,
} from 'src/enum';
import { ConcurrentQueueName, QueueName } from 'src/interfaces/job.interface';
import { ConcurrentQueueName } from 'src/types';
import { IsCronExpression, ValidateBoolean } from 'src/validation';

const isLibraryScanEnabled = (config: SystemConfigLibraryScanDto) => config.enabled;
Expand Down
139 changes: 139 additions & 0 deletions server/src/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,142 @@ export enum BootstrapEventPriority {
// Initialise config after other bootstrap services, stop other services from using config on bootstrap
SystemConfig = 100,
}

export enum QueueName {
THUMBNAIL_GENERATION = 'thumbnailGeneration',
METADATA_EXTRACTION = 'metadataExtraction',
VIDEO_CONVERSION = 'videoConversion',
FACE_DETECTION = 'faceDetection',
FACIAL_RECOGNITION = 'facialRecognition',
SMART_SEARCH = 'smartSearch',
DUPLICATE_DETECTION = 'duplicateDetection',
BACKGROUND_TASK = 'backgroundTask',
STORAGE_TEMPLATE_MIGRATION = 'storageTemplateMigration',
MIGRATION = 'migration',
SEARCH = 'search',
SIDECAR = 'sidecar',
LIBRARY = 'library',
NOTIFICATION = 'notifications',
BACKUP_DATABASE = 'backupDatabase',
}

export enum JobName {
//backups
BACKUP_DATABASE = 'database-backup',

// conversion
QUEUE_VIDEO_CONVERSION = 'queue-video-conversion',
VIDEO_CONVERSION = 'video-conversion',

// thumbnails
QUEUE_GENERATE_THUMBNAILS = 'queue-generate-thumbnails',
GENERATE_THUMBNAILS = 'generate-thumbnails',
GENERATE_PERSON_THUMBNAIL = 'generate-person-thumbnail',

// metadata
QUEUE_METADATA_EXTRACTION = 'queue-metadata-extraction',
METADATA_EXTRACTION = 'metadata-extraction',
LINK_LIVE_PHOTOS = 'link-live-photos',

// user
USER_DELETION = 'user-deletion',
USER_DELETE_CHECK = 'user-delete-check',
USER_SYNC_USAGE = 'user-sync-usage',

// asset
ASSET_DELETION = 'asset-deletion',
ASSET_DELETION_CHECK = 'asset-deletion-check',

// storage template
STORAGE_TEMPLATE_MIGRATION = 'storage-template-migration',
STORAGE_TEMPLATE_MIGRATION_SINGLE = 'storage-template-migration-single',

// tags
TAG_CLEANUP = 'tag-cleanup',

// migration
QUEUE_MIGRATION = 'queue-migration',
MIGRATE_ASSET = 'migrate-asset',
MIGRATE_PERSON = 'migrate-person',

// facial recognition
PERSON_CLEANUP = 'person-cleanup',
QUEUE_FACE_DETECTION = 'queue-face-detection',
FACE_DETECTION = 'face-detection',
QUEUE_FACIAL_RECOGNITION = 'queue-facial-recognition',
FACIAL_RECOGNITION = 'facial-recognition',

// library management
LIBRARY_QUEUE_SYNC_FILES = 'library-queue-sync-files',
LIBRARY_QUEUE_SYNC_ASSETS = 'library-queue-sync-assets',
LIBRARY_SYNC_FILE = 'library-sync-file',
LIBRARY_SYNC_ASSET = 'library-sync-asset',
LIBRARY_DELETE = 'library-delete',
LIBRARY_QUEUE_SYNC_ALL = 'library-queue-sync-all',
LIBRARY_QUEUE_CLEANUP = 'library-queue-cleanup',

// cleanup
DELETE_FILES = 'delete-files',
CLEAN_OLD_AUDIT_LOGS = 'clean-old-audit-logs',
CLEAN_OLD_SESSION_TOKENS = 'clean-old-session-tokens',

// smart search
QUEUE_SMART_SEARCH = 'queue-smart-search',
SMART_SEARCH = 'smart-search',

QUEUE_TRASH_EMPTY = 'queue-trash-empty',

// duplicate detection
QUEUE_DUPLICATE_DETECTION = 'queue-duplicate-detection',
DUPLICATE_DETECTION = 'duplicate-detection',

// XMP sidecars
QUEUE_SIDECAR = 'queue-sidecar',
SIDECAR_DISCOVERY = 'sidecar-discovery',
SIDECAR_SYNC = 'sidecar-sync',
SIDECAR_WRITE = 'sidecar-write',

// Notification
NOTIFY_SIGNUP = 'notify-signup',
NOTIFY_ALBUM_INVITE = 'notify-album-invite',
NOTIFY_ALBUM_UPDATE = 'notify-album-update',
SEND_EMAIL = 'notification-send-email',

// Version check
VERSION_CHECK = 'version-check',
}

export enum JobCommand {
START = 'start',
PAUSE = 'pause',
RESUME = 'resume',
EMPTY = 'empty',
CLEAR_FAILED = 'clear-failed',
}

export enum JobStatus {
SUCCESS = 'success',
FAILED = 'failed',
SKIPPED = 'skipped',
}

export enum QueueCleanType {
FAILED = 'failed',
}

export enum VectorIndex {
CLIP = 'clip_index',
FACE = 'face_index',
}

export enum DatabaseLock {
GeodataImport = 100,
Migrations = 200,
SystemFileMounts = 300,
StorageTemplateMigration = 420,
VersionHistory = 500,
CLIPDimSize = 512,
Library = 1337,
GetSystemConfig = 69,
BackupDatabase = 42,
}
Loading

0 comments on commit fa5aeaf

Please sign in to comment.