mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	refactor(server): app init (#2638)
This commit is contained in:
		@@ -1,13 +0,0 @@
 | 
			
		||||
import { JobService } from '@app/domain';
 | 
			
		||||
import { Injectable } from '@nestjs/common';
 | 
			
		||||
import { Cron, CronExpression } from '@nestjs/schedule';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class AppCronJobs {
 | 
			
		||||
  constructor(private jobService: JobService) {}
 | 
			
		||||
 | 
			
		||||
  @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
 | 
			
		||||
  async onNightlyJob() {
 | 
			
		||||
    await this.jobService.handleNightlyJobs();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,29 +1,29 @@
 | 
			
		||||
import { Module, OnModuleInit } from '@nestjs/common';
 | 
			
		||||
import { AssetModule } from './api-v1/asset/asset.module';
 | 
			
		||||
import { AlbumModule } from './api-v1/album/album.module';
 | 
			
		||||
import { AppController } from './app.controller';
 | 
			
		||||
import { ScheduleModule } from '@nestjs/schedule';
 | 
			
		||||
import { DomainModule, SearchService } from '@app/domain';
 | 
			
		||||
import { DomainModule } from '@app/domain';
 | 
			
		||||
import { InfraModule } from '@app/infra';
 | 
			
		||||
import { Module } from '@nestjs/common';
 | 
			
		||||
import { APP_GUARD } from '@nestjs/core';
 | 
			
		||||
import { ScheduleModule } from '@nestjs/schedule';
 | 
			
		||||
import { AlbumModule } from './api-v1/album/album.module';
 | 
			
		||||
import { AssetModule } from './api-v1/asset/asset.module';
 | 
			
		||||
import { AppService } from './app.service';
 | 
			
		||||
import {
 | 
			
		||||
  AlbumController,
 | 
			
		||||
  APIKeyController,
 | 
			
		||||
  AppController,
 | 
			
		||||
  AssetController,
 | 
			
		||||
  AuthController,
 | 
			
		||||
  PersonController,
 | 
			
		||||
  JobController,
 | 
			
		||||
  OAuthController,
 | 
			
		||||
  PartnerController,
 | 
			
		||||
  PersonController,
 | 
			
		||||
  SearchController,
 | 
			
		||||
  ServerInfoController,
 | 
			
		||||
  SharedLinkController,
 | 
			
		||||
  SystemConfigController,
 | 
			
		||||
  UserController,
 | 
			
		||||
  TagController,
 | 
			
		||||
  UserController,
 | 
			
		||||
} from './controllers';
 | 
			
		||||
import { APP_GUARD } from '@nestjs/core';
 | 
			
		||||
import { AuthGuard } from './middlewares/auth.guard';
 | 
			
		||||
import { AppCronJobs } from './app.cron-jobs';
 | 
			
		||||
 | 
			
		||||
@Module({
 | 
			
		||||
  imports: [
 | 
			
		||||
@@ -54,12 +54,7 @@ import { AppCronJobs } from './app.cron-jobs';
 | 
			
		||||
    //
 | 
			
		||||
    { provide: APP_GUARD, useExisting: AuthGuard },
 | 
			
		||||
    AuthGuard,
 | 
			
		||||
    AppCronJobs,
 | 
			
		||||
    AppService,
 | 
			
		||||
  ],
 | 
			
		||||
})
 | 
			
		||||
export class AppModule implements OnModuleInit {
 | 
			
		||||
  constructor(private searchService: SearchService) {}
 | 
			
		||||
  async onModuleInit() {
 | 
			
		||||
    await this.searchService.bootstrap();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
export class AppModule {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								server/apps/immich/src/app.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								server/apps/immich/src/app.service.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { JobService, SearchService, StorageService } from '@app/domain';
 | 
			
		||||
import { Injectable } from '@nestjs/common';
 | 
			
		||||
import { Cron, CronExpression } from '@nestjs/schedule';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class AppService {
 | 
			
		||||
  constructor(
 | 
			
		||||
    private jobService: JobService,
 | 
			
		||||
    private searchService: SearchService,
 | 
			
		||||
    private storageService: StorageService,
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT)
 | 
			
		||||
  async onNightlyJob() {
 | 
			
		||||
    await this.jobService.handleNightlyJobs();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async init() {
 | 
			
		||||
    this.storageService.init();
 | 
			
		||||
    await this.searchService.init();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
export * from './album.controller';
 | 
			
		||||
export * from './api-key.controller';
 | 
			
		||||
export * from './app.controller';
 | 
			
		||||
export * from './asset.controller';
 | 
			
		||||
export * from './auth.controller';
 | 
			
		||||
export * from './job.controller';
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ import {
 | 
			
		||||
  MACHINE_LEARNING_ENABLED,
 | 
			
		||||
  SearchService,
 | 
			
		||||
  SERVER_VERSION,
 | 
			
		||||
  StorageService,
 | 
			
		||||
} from '@app/domain';
 | 
			
		||||
import { RedisIoAdapter } from '@app/infra';
 | 
			
		||||
import { Logger } from '@nestjs/common';
 | 
			
		||||
@@ -18,6 +17,7 @@ import cookieParser from 'cookie-parser';
 | 
			
		||||
import { writeFileSync } from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import { AppModule } from './app.module';
 | 
			
		||||
import { AppService } from './app.service';
 | 
			
		||||
import { patchOpenAPI } from './utils/patch-open-api.util';
 | 
			
		||||
 | 
			
		||||
const logger = new Logger('ImmichServer');
 | 
			
		||||
@@ -73,7 +73,7 @@ async function bootstrap() {
 | 
			
		||||
    customSiteTitle: 'Immich API Documentation',
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  app.get(StorageService).init();
 | 
			
		||||
  await app.get(AppService).init();
 | 
			
		||||
 | 
			
		||||
  await app.listen(serverPort, () => {
 | 
			
		||||
    if (process.env.NODE_ENV == 'development') {
 | 
			
		||||
 
 | 
			
		||||
@@ -110,11 +110,11 @@ describe(SearchService.name, () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe(`bootstrap`, () => {
 | 
			
		||||
  describe(`init`, () => {
 | 
			
		||||
    it('should skip when search is disabled', async () => {
 | 
			
		||||
      const sut = makeSut('false');
 | 
			
		||||
 | 
			
		||||
      await sut.bootstrap();
 | 
			
		||||
      await sut.init();
 | 
			
		||||
 | 
			
		||||
      expect(searchMock.setup).not.toHaveBeenCalled();
 | 
			
		||||
      expect(searchMock.checkMigrationStatus).not.toHaveBeenCalled();
 | 
			
		||||
@@ -125,7 +125,7 @@ describe(SearchService.name, () => {
 | 
			
		||||
 | 
			
		||||
    it('should skip schema migration if not needed', async () => {
 | 
			
		||||
      searchMock.checkMigrationStatus.mockResolvedValue({ assets: false, albums: false, faces: false });
 | 
			
		||||
      await sut.bootstrap();
 | 
			
		||||
      await sut.init();
 | 
			
		||||
 | 
			
		||||
      expect(searchMock.setup).toHaveBeenCalled();
 | 
			
		||||
      expect(jobMock.queue).not.toHaveBeenCalled();
 | 
			
		||||
@@ -133,7 +133,7 @@ describe(SearchService.name, () => {
 | 
			
		||||
 | 
			
		||||
    it('should do schema migration if needed', async () => {
 | 
			
		||||
      searchMock.checkMigrationStatus.mockResolvedValue({ assets: true, albums: true, faces: true });
 | 
			
		||||
      await sut.bootstrap();
 | 
			
		||||
      await sut.init();
 | 
			
		||||
 | 
			
		||||
      expect(searchMock.setup).toHaveBeenCalled();
 | 
			
		||||
      expect(jobMock.queue.mock.calls).toEqual([
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ export class SearchService {
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async bootstrap() {
 | 
			
		||||
  async init() {
 | 
			
		||||
    if (!this.enabled) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user