refactor: split integrity out of maintenance controller/service

This commit is contained in:
izzy
2025-12-17 14:55:38 +00:00
parent 7d71f99783
commit 21c26dd65f
14 changed files with 283 additions and 244 deletions
+2
View File
@@ -9,6 +9,7 @@ import { AuthController } from 'src/controllers/auth.controller';
import { DownloadController } from 'src/controllers/download.controller';
import { DuplicateController } from 'src/controllers/duplicate.controller';
import { FaceController } from 'src/controllers/face.controller';
import { IntegrityController } from 'src/controllers/integrity.controller';
import { JobController } from 'src/controllers/job.controller';
import { LibraryController } from 'src/controllers/library.controller';
import { MaintenanceController } from 'src/controllers/maintenance.controller';
@@ -49,6 +50,7 @@ export const controllers = [
DownloadController,
DuplicateController,
FaceController,
IntegrityController,
JobController,
LibraryController,
MaintenanceController,
@@ -0,0 +1,90 @@
import { Body, Controller, Delete, Get, Next, Param, Post, Res } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { NextFunction, Response } from 'express';
import { Endpoint, HistoryBuilder } from 'src/decorators';
import { AuthDto } from 'src/dtos/auth.dto';
import {
MaintenanceGetIntegrityReportDto,
MaintenanceIntegrityReportResponseDto,
MaintenanceIntegrityReportSummaryResponseDto,
} from 'src/dtos/maintenance.dto';
import { ApiTag, Permission } from 'src/enum';
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { IntegrityService } from 'src/services/integrity.service';
import { sendFile } from 'src/utils/file';
import { IntegrityReportTypeParamDto, UUIDParamDto } from 'src/validation';
@ApiTags(ApiTag.Maintenance)
@Controller('admin/integrity')
export class IntegrityController {
constructor(
private logger: LoggingRepository,
private service: IntegrityService,
) {}
@Get('summary')
@Endpoint({
summary: 'Get integrity report summary',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@Authenticated({ permission: Permission.Maintenance, admin: true })
getIntegrityReportSummary(): Promise<MaintenanceIntegrityReportSummaryResponseDto> {
return this.service.getIntegrityReportSummary();
}
@Post('report')
@Endpoint({
summary: 'Get integrity report by type',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@Authenticated({ permission: Permission.Maintenance, admin: true })
getIntegrityReport(@Body() dto: MaintenanceGetIntegrityReportDto): Promise<MaintenanceIntegrityReportResponseDto> {
return this.service.getIntegrityReport(dto);
}
@Delete('report/:id')
@Endpoint({
summary: 'Delete report entry and perform corresponding deletion action',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@Authenticated({ permission: Permission.Maintenance, admin: true })
async deleteIntegrityReport(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
await this.service.deleteIntegrityReport(auth, id);
}
@Get('report/:type/csv')
@Endpoint({
summary: 'Export integrity report by type as CSV',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@FileResponse()
@Authenticated({ permission: Permission.Maintenance, admin: true })
getIntegrityReportCsv(@Param() { type }: IntegrityReportTypeParamDto, @Res() res: Response): void {
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Cache-Control', 'private, no-cache, no-transform');
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(`${Date.now()}-${type}.csv`)}"`);
this.service.getIntegrityReportCsv(type).pipe(res);
}
@Get('report/:id/file')
@Endpoint({
summary: 'Download the orphan/broken file if one exists',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@FileResponse()
@Authenticated({ permission: Permission.Maintenance, admin: true })
async getIntegrityReportFile(
@Param() { id }: UUIDParamDto,
@Res() res: Response,
@Next() next: NextFunction,
): Promise<void> {
await sendFile(res, next, () => this.service.getIntegrityReportFile(id), this.logger);
}
}
@@ -1,32 +1,19 @@
import { BadRequestException, Body, Controller, Delete, Get, Next, Param, Post, Res } from '@nestjs/common';
import { BadRequestException, Body, Controller, Post, Res } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { NextFunction, Response } from 'express';
import { Response } from 'express';
import { Endpoint, HistoryBuilder } from 'src/decorators';
import { AuthDto } from 'src/dtos/auth.dto';
import {
MaintenanceAuthDto,
MaintenanceGetIntegrityReportDto,
MaintenanceIntegrityReportResponseDto,
MaintenanceIntegrityReportSummaryResponseDto,
MaintenanceLoginDto,
SetMaintenanceModeDto,
} from 'src/dtos/maintenance.dto';
import { MaintenanceAuthDto, MaintenanceLoginDto, SetMaintenanceModeDto } from 'src/dtos/maintenance.dto';
import { ApiTag, ImmichCookie, MaintenanceAction, Permission } from 'src/enum';
import { Auth, Authenticated, FileResponse, GetLoginDetails } from 'src/middleware/auth.guard';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { Auth, Authenticated, GetLoginDetails } from 'src/middleware/auth.guard';
import { LoginDetails } from 'src/services/auth.service';
import { MaintenanceService } from 'src/services/maintenance.service';
import { sendFile } from 'src/utils/file';
import { respondWithCookie } from 'src/utils/response';
import { IntegrityReportTypeParamDto, UUIDParamDto } from 'src/validation';
@ApiTags(ApiTag.Maintenance)
@Controller('admin/maintenance')
export class MaintenanceController {
constructor(
private logger: LoggingRepository,
private service: MaintenanceService,
) {}
constructor(private service: MaintenanceService) {}
@Post('login')
@Endpoint({
@@ -59,69 +46,4 @@ export class MaintenanceController {
});
}
}
@Get('integrity/summary')
@Endpoint({
summary: 'Get integrity report summary',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@Authenticated({ permission: Permission.Maintenance, admin: true })
getIntegrityReportSummary(): Promise<MaintenanceIntegrityReportSummaryResponseDto> {
return this.service.getIntegrityReportSummary();
}
@Post('integrity/report')
@Endpoint({
summary: 'Get integrity report by type',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@Authenticated({ permission: Permission.Maintenance, admin: true })
getIntegrityReport(@Body() dto: MaintenanceGetIntegrityReportDto): Promise<MaintenanceIntegrityReportResponseDto> {
return this.service.getIntegrityReport(dto);
}
@Delete('integrity/report/:id')
@Endpoint({
summary: 'Delete report entry and perform corresponding deletion action',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@Authenticated({ permission: Permission.Maintenance, admin: true })
async deleteIntegrityReport(@Auth() auth: AuthDto, @Param() { id }: UUIDParamDto): Promise<void> {
await this.service.deleteIntegrityReport(auth, id);
}
@Get('integrity/report/:type/csv')
@Endpoint({
summary: 'Export integrity report by type as CSV',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@FileResponse()
@Authenticated({ permission: Permission.Maintenance, admin: true })
getIntegrityReportCsv(@Param() { type }: IntegrityReportTypeParamDto, @Res() res: Response): void {
res.setHeader('Content-Type', 'text/csv');
res.setHeader('Cache-Control', 'private, no-cache, no-transform');
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(`${Date.now()}-${type}.csv`)}"`);
this.service.getIntegrityReportCsv(type).pipe(res);
}
@Get('integrity/report/:id/file')
@Endpoint({
summary: 'Download the orphan/broken file if one exists',
description: '...',
history: new HistoryBuilder().added('v9.9.9').alpha('v9.9.9'),
})
@FileResponse()
@Authenticated({ permission: Permission.Maintenance, admin: true })
async getIntegrityReportFile(
@Param() { id }: UUIDParamDto,
@Res() res: Response,
@Next() next: NextFunction,
): Promise<void> {
await sendFile(res, next, () => this.service.getIntegrityReportFile(id), this.logger);
}
}