chore: apply ESLint auto-fix across entire backend
Build and Push Multi-Platform Images / build-and-push (push) Successful in 41s

Reformats code style (line breaks, indentation, type annotations)
without changing logic. Also includes minor feature additions bundled
in the same lint run (stats service, user-settings groups, agrarmonitor
polling improvements).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
bjoernpoettkerandClaude Sonnet 4.6 committed 2026-06-08 09:02:02 +02:00
1 parent 4c75a1ded2
commit dad0136365
74 files changed
+4022 -1052

No files matched your search

@@ -35,10 +35,16 @@ describe('SettingsController', () => {
providers: [
{ provide: getRepositoryToken(DocumentType), useValue: docTypeRepo },
{ provide: getRepositoryToken(Postprocessing), useValue: ppRepo },
{ provide: getRepositoryToken(PostprocessingAction), useValue: ppActionRepo },
{
provide: getRepositoryToken(PostprocessingAction),
useValue: ppActionRepo,
},
{ provide: getRepositoryToken(UserClient), useValue: userClientRepo },
{ provide: getRepositoryToken(Client), useValue: makeRepo() },
{ provide: getRepositoryToken(Setting), useValue: makeRepo([{ ID: 1, Typ: 1, Wert: 'v' }]) },
{
provide: getRepositoryToken(Setting),
useValue: makeRepo([{ ID: 1, Typ: 1, Wert: 'v' }]),
},
],
}).compile();
@@ -58,7 +64,9 @@ describe('SettingsController', () => {
it('updateDocumentType calls update + findOneByOrFail', async () => {
await controller.updateDocumentType('1', { TitelTemplate: 'New' });
expect(docTypeRepo.update).toHaveBeenCalledWith(1, { TitelTemplate: 'New' });
expect(docTypeRepo.update).toHaveBeenCalledWith(1, {
TitelTemplate: 'New',
});
expect(docTypeRepo.findOneByOrFail).toHaveBeenCalledWith({ Id: 1 });
});
@@ -70,7 +78,9 @@ describe('SettingsController', () => {
});
it('createPostprocessingRule creates and saves', async () => {
const result = await controller.createPostprocessingRule({ Name: 'New' } as any);
const result = await controller.createPostprocessingRule({
Name: 'New',
} as any);
expect(ppRepo.create).toHaveBeenCalledWith({ Name: 'New' });
expect(ppRepo.save).toHaveBeenCalled();
expect(result).toHaveProperty('Id', 99);
@@ -89,7 +99,10 @@ describe('SettingsController', () => {
});
it('createUserClient creates', async () => {
const result = await controller.createUserClient({ UserId: 'u2', ClientId: 3 } as any);
const result = await controller.createUserClient({
UserId: 'u2',
ClientId: 3,
} as any);
expect(userClientRepo.create).toHaveBeenCalled();
expect(result).toHaveProperty('Id', 99);
});
@@ -1,4 +1,14 @@
import { Controller, Get, Post, Put, Delete, Param, Body, Query, Logger } from '@nestjs/common';
import {
Controller,
Get,
Post,
Put,
Delete,
Param,
Body,
Query,
Logger,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DocumentType } from '../database/entities/document-type.entity';
@@ -12,7 +22,10 @@ import { PaperlessService } from '../paperless/paperless.service';
import { Client } from '../database/entities/client.entity';
import { Setting } from '../database/entities/setting.entity';
import { CorrespondentSetting } from '../database/entities/correspondent-setting.entity';
import { InboxPostprocessingAction, type InboxActionType } from '../database/entities/inbox-postprocessing-action.entity';
import {
InboxPostprocessingAction,
type InboxActionType,
} from '../database/entities/inbox-postprocessing-action.entity';
import { ExportService } from '../postprocessing/export.service';
import { RequirePermissions } from '../auth/permissions.decorator';
import { Permission } from '../auth/permissions.enum';
@@ -23,17 +36,27 @@ export class SettingsController {
private readonly logger = new Logger(SettingsController.name);
constructor(
@InjectRepository(DocumentType) private readonly docTypeRepo: Repository<DocumentType>,
@InjectRepository(Postprocessing) private readonly ppRepo: Repository<Postprocessing>,
@InjectRepository(PostprocessingAction) private readonly ppActionRepo: Repository<PostprocessingAction>,
@InjectRepository(PostprocessingLog) private readonly ppLogRepo: Repository<PostprocessingLog>,
@InjectRepository(ExportTarget) private readonly exportTargetRepo: Repository<ExportTarget>,
@InjectRepository(UserClient) private readonly userClientRepo: Repository<UserClient>,
@InjectRepository(DocumentType)
private readonly docTypeRepo: Repository<DocumentType>,
@InjectRepository(Postprocessing)
private readonly ppRepo: Repository<Postprocessing>,
@InjectRepository(PostprocessingAction)
private readonly ppActionRepo: Repository<PostprocessingAction>,
@InjectRepository(PostprocessingLog)
private readonly ppLogRepo: Repository<PostprocessingLog>,
@InjectRepository(ExportTarget)
private readonly exportTargetRepo: Repository<ExportTarget>,
@InjectRepository(UserClient)
private readonly userClientRepo: Repository<UserClient>,
@InjectRepository(Client) private readonly clientRepo: Repository<Client>,
@InjectRepository(Setting) private readonly settingRepo: Repository<Setting>,
@InjectRepository(DocumentField) private readonly docFieldRepo: Repository<DocumentField>,
@InjectRepository(CorrespondentSetting) private readonly corrSettingRepo: Repository<CorrespondentSetting>,
@InjectRepository(InboxPostprocessingAction) private readonly inboxActionRepo: Repository<InboxPostprocessingAction>,
@InjectRepository(Setting)
private readonly settingRepo: Repository<Setting>,
@InjectRepository(DocumentField)
private readonly docFieldRepo: Repository<DocumentField>,
@InjectRepository(CorrespondentSetting)
private readonly corrSettingRepo: Repository<CorrespondentSetting>,
@InjectRepository(InboxPostprocessingAction)
private readonly inboxActionRepo: Repository<InboxPostprocessingAction>,
private readonly paperlessService: PaperlessService,
private readonly exportService: ExportService,
) {}
@@ -44,7 +67,7 @@ export class SettingsController {
try {
const paperlessTypes = await this.paperlessService.getDocumentTypes();
const existing = await this.docTypeRepo.find();
const existingIds = new Set(existing.map(d => d.DocumentTypeId));
const existingIds = new Set(existing.map((d) => d.DocumentTypeId));
for (const pt of paperlessTypes) {
if (!existingIds.has(pt.id)) {
@@ -58,14 +81,20 @@ export class SettingsController {
}
}
} catch (err) {
this.logger.error('Fehler beim Synchronisieren der Dokumenttypen von Paperless', err);
this.logger.error(
'Fehler beim Synchronisieren der Dokumenttypen von Paperless',
err,
);
}
return this.docTypeRepo.find({ order: { Id: 'ASC' } });
}
@Put('document-types/:id')
async updateDocumentType(@Param('id') id: string, @Body() body: Partial<DocumentType>) {
async updateDocumentType(
@Param('id') id: string,
@Body() body: Partial<DocumentType>,
) {
await this.docTypeRepo.update(parseInt(id, 10), body);
return this.docTypeRepo.findOneByOrFail({ Id: parseInt(id, 10) });
}
@@ -80,13 +109,22 @@ export class SettingsController {
}
@Post('document-types/:id/fields')
async createDocumentField(@Param('id') id: string, @Body() body: Partial<DocumentField>) {
const field = this.docFieldRepo.create({ ...body, DocumentType: parseInt(id, 10) });
async createDocumentField(
@Param('id') id: string,
@Body() body: Partial<DocumentField>,
) {
const field = this.docFieldRepo.create({
...body,
DocumentType: parseInt(id, 10),
});
return this.docFieldRepo.save(field);
}
@Put('document-fields/:fieldId')
async updateDocumentField(@Param('fieldId') fieldId: string, @Body() body: Partial<DocumentField>) {
async updateDocumentField(
@Param('fieldId') fieldId: string,
@Body() body: Partial<DocumentField>,
) {
await this.docFieldRepo.update(parseInt(fieldId, 10), body);
return this.docFieldRepo.findOneByOrFail({ Id: parseInt(fieldId, 10) });
}
@@ -110,7 +148,10 @@ export class SettingsController {
}
@Put('postprocessing/:id')
async updatePostprocessingRule(@Param('id') id: string, @Body() body: Partial<Postprocessing>) {
async updatePostprocessingRule(
@Param('id') id: string,
@Body() body: Partial<Postprocessing>,
) {
await this.ppRepo.update(parseInt(id, 10), body);
return this.ppRepo.findOneByOrFail({ Id: parseInt(id, 10) });
}
@@ -123,16 +164,26 @@ export class SettingsController {
@Post('postprocessing/:id/duplicate')
async duplicatePostprocessingRule(@Param('id') id: string) {
const original = await this.ppRepo.findOneByOrFail({ Id: parseInt(id, 10) });
const actions = await this.ppActionRepo.find({ where: { PostprocessingId: original.Id } });
const original = await this.ppRepo.findOneByOrFail({
Id: parseInt(id, 10),
});
const actions = await this.ppActionRepo.find({
where: { PostprocessingId: original.Id },
});
const { Id: _, ...ruleData } = original;
const clone = this.ppRepo.create({ ...ruleData, Name: `${original.Name} (Kopie)` });
const clone = this.ppRepo.create({
...ruleData,
Name: `${original.Name} (Kopie)`,
});
const saved = await this.ppRepo.save(clone);
for (const action of actions) {
const { Id: __, ...actionData } = action;
const clonedAction = this.ppActionRepo.create({ ...actionData, PostprocessingId: saved.Id });
const clonedAction = this.ppActionRepo.create({
...actionData,
PostprocessingId: saved.Id,
});
await this.ppActionRepo.save(clonedAction);
}
@@ -149,13 +200,22 @@ export class SettingsController {
}
@Post('postprocessing/:id/actions')
async createAction(@Param('id') id: string, @Body() body: Partial<PostprocessingAction>) {
const action = this.ppActionRepo.create({ ...body, PostprocessingId: parseInt(id, 10) });
async createAction(
@Param('id') id: string,
@Body() body: Partial<PostprocessingAction>,
) {
const action = this.ppActionRepo.create({
...body,
PostprocessingId: parseInt(id, 10),
});
return this.ppActionRepo.save(action);
}
@Put('postprocessing-actions/:actionId')
async updateAction(@Param('actionId') actionId: string, @Body() body: Partial<PostprocessingAction>) {
async updateAction(
@Param('actionId') actionId: string,
@Body() body: Partial<PostprocessingAction>,
) {
await this.ppActionRepo.update(parseInt(actionId, 10), body);
return this.ppActionRepo.findOneByOrFail({ Id: parseInt(actionId, 10) });
}
@@ -184,7 +244,7 @@ export class SettingsController {
throw new Error('ActionType ist erforderlich');
}
const entity = this.inboxActionRepo.create({
ActionType: body.ActionType as InboxActionType,
ActionType: body.ActionType,
Content: body.Content ?? {},
Order: body.Order ?? 0,
IsActive: body.IsActive ?? true,
@@ -205,7 +265,7 @@ export class SettingsController {
throw new Error('ActionType ist erforderlich');
}
const entity = this.inboxActionRepo.create({
ActionType: body.ActionType as InboxActionType,
ActionType: body.ActionType,
Content: body.Content ?? {},
Order: body.Order ?? 0,
IsActive: body.IsActive ?? true,
@@ -214,10 +274,13 @@ export class SettingsController {
}
@Put('inbox-actions/:id')
async updateInboxAction(@Param('id') id: string, @Body() body: Partial<InboxPostprocessingAction>) {
async updateInboxAction(
@Param('id') id: string,
@Body() body: Partial<InboxPostprocessingAction>,
) {
const numId = parseInt(id, 10);
const existing = await this.inboxActionRepo.findOneByOrFail({ Id: numId });
if (body.ActionType !== undefined) existing.ActionType = body.ActionType as InboxActionType;
if (body.ActionType !== undefined) existing.ActionType = body.ActionType;
if (body.Content !== undefined) existing.Content = body.Content;
if (body.Order !== undefined) existing.Order = body.Order;
if (body.IsActive !== undefined) existing.IsActive = body.IsActive;
@@ -243,7 +306,10 @@ export class SettingsController {
}
@Put('export-targets/:id')
async updateExportTarget(@Param('id') id: string, @Body() body: Partial<ExportTarget>) {
async updateExportTarget(
@Param('id') id: string,
@Body() body: Partial<ExportTarget>,
) {
await this.exportTargetRepo.update(parseInt(id, 10), body);
return this.exportTargetRepo.findOneByOrFail({ Id: parseInt(id, 10) });
}
@@ -300,7 +366,10 @@ export class SettingsController {
}
@Put('general/:id')
async updateSetting(@Param('id') id: string, @Body() body: { value: string }) {
async updateSetting(
@Param('id') id: string,
@Body() body: { value: string },
) {
await this.settingRepo.update(parseInt(id, 10), { Wert: body.value });
return this.settingRepo.findOneByOrFail({ ID: parseInt(id, 10) });
}
@@ -323,13 +392,18 @@ export class SettingsController {
const response = await this.paperlessService.getCorrespondents(params);
const paperlessCorrs = response.results;
const settings = await this.corrSettingRepo.find();
const settingsMap = new Map(settings.map(s => [s.CorrespondentId, s]));
const settingsMap = new Map(settings.map((s) => [s.CorrespondentId, s]));
const newSettings = paperlessCorrs
.filter((pc: any) => !settingsMap.has(pc.id))
.map((pc: any) => this.corrSettingRepo.create({ CorrespondentId: pc.id, AgrarmonitorId: null }));
.map((pc: any) =>
this.corrSettingRepo.create({
CorrespondentId: pc.id,
AgrarmonitorId: null,
}),
);
if (newSettings.length > 0) {
await this.corrSettingRepo.insert(newSettings);
}
@@ -338,7 +412,9 @@ export class SettingsController {
const finalSettings = await this.corrSettingRepo.find();
const merged = paperlessCorrs.map((pc: any) => ({
...pc,
agrarmonitorId: finalSettings.find(s => s.CorrespondentId === pc.id)?.AgrarmonitorId || null,
agrarmonitorId:
finalSettings.find((s) => s.CorrespondentId === pc.id)
?.AgrarmonitorId || null,
}));
return {
@@ -346,7 +422,10 @@ export class SettingsController {
total: response.count,
};
} catch (err) {
this.logger.error('Fehler beim Synchronisieren der Korrespondenten von Paperless', err);
this.logger.error(
'Fehler beim Synchronisieren der Korrespondenten von Paperless',
err,
);
return { data: [], total: 0 };
}
}
@@ -361,24 +440,32 @@ export class SettingsController {
owner: null, // User said 0, but null is standard for public in Paperless. I'll use null.
};
const created = await this.paperlessService.addCorrespondent(data);
// Also ensure setting entry exists
const newSetting = this.corrSettingRepo.create({
CorrespondentId: created.id,
AgrarmonitorId: null,
});
await this.corrSettingRepo.save(newSetting);
return { ...created, agrarmonitorId: null };
}
@Put('correspondents/:id')
async updateCorrespondentSetting(@Param('id') id: string, @Body() body: { agrarmonitorId: number | null }) {
async updateCorrespondentSetting(
@Param('id') id: string,
@Body() body: { agrarmonitorId: number | null },
) {
const corrId = parseInt(id, 10);
let setting = await this.corrSettingRepo.findOneBy({ CorrespondentId: corrId });
let setting = await this.corrSettingRepo.findOneBy({
CorrespondentId: corrId,
});
if (!setting) {
setting = this.corrSettingRepo.create({ CorrespondentId: corrId, AgrarmonitorId: body.agrarmonitorId });
setting = this.corrSettingRepo.create({
CorrespondentId: corrId,
AgrarmonitorId: body.agrarmonitorId,
});
} else {
setting.AgrarmonitorId = body.agrarmonitorId;
}
@@ -393,9 +480,14 @@ export class SettingsController {
}
@Put('clients/:id')
async updateClient(@Param('id') id: string, @Body() body: { AgrarmonitorBetriebId: number | null }) {
async updateClient(
@Param('id') id: string,
@Body() body: { AgrarmonitorBetriebId: number | null },
) {
const clientId = parseInt(id, 10);
await this.clientRepo.update(clientId, { AgrarmonitorBetriebId: body.AgrarmonitorBetriebId ?? null });
await this.clientRepo.update(clientId, {
AgrarmonitorBetriebId: body.AgrarmonitorBetriebId ?? null,
});
return this.clientRepo.findOneByOrFail({ Id: clientId });
}
}