feat(backend): Honigchargen-Modul (Modul 11)

HoneyBatchesModule inkl. Honigmessungen und
Rückverfolgbarkeits-Endpunkt, der eine Charge über die Schleuderung
und Ernte bis zu den Ursprungsvölkern zurückverfolgt.
This commit is contained in:
Nick Szaunig committed 2026-08-22 00:37:09 +02:00
1 parent 5c2c0608d1
commit cf625552d1
9 files changed
+474 -1

No files matched your search

@@ -0,0 +1,109 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { AuditLogService } from '../audit/audit-log.service';
import { CreateHoneyBatchDto } from './dto/create-honey-batch.dto';
import { CreateHoneyMeasurementDto } from './dto/create-honey-measurement.dto';
const honeyBatchInclude = {
measurements: true,
extraction: {
include: {
harvests: {
include: {
harvest: { include: { colonies: { include: { colony: true } } } },
},
},
},
},
} as const;
@Injectable()
export class HoneyBatchesService {
constructor(
private readonly prisma: PrismaService,
private readonly auditLog: AuditLogService,
) {}
async findAll() {
return this.prisma.honeyBatch.findMany({
include: honeyBatchInclude,
orderBy: { createdAt: 'desc' },
});
}
async findById(id: string) {
const honeyBatch = await this.prisma.honeyBatch.findUnique({
where: { id },
include: honeyBatchInclude,
});
if (!honeyBatch) {
throw new NotFoundException('Honey batch not found');
}
return honeyBatch;
}
async create(dto: CreateHoneyBatchDto, actingUserId: string) {
const honeyBatch = await this.prisma.honeyBatch.create({
data: { ...dto },
});
await this.auditLog.record({
entityType: 'HoneyBatch',
entityId: honeyBatch.id,
action: 'CREATE',
userId: actingUserId,
afterData: honeyBatch,
});
return this.findById(honeyBatch.id);
}
async addMeasurement(
id: string,
dto: CreateHoneyMeasurementDto,
actingUserId: string,
) {
await this.findById(id);
const measurement = await this.prisma.honeyMeasurement.create({
data: {
...dto,
measuredAt: new Date(dto.measuredAt),
honeyBatchId: id,
userId: actingUserId,
},
});
await this.auditLog.record({
entityType: 'HoneyMeasurement',
entityId: measurement.id,
action: 'CREATE',
userId: actingUserId,
afterData: measurement,
});
return this.findById(id);
}
async traceability(id: string) {
const honeyBatch = await this.findById(id);
return {
honeyBatch: {
id: honeyBatch.id,
batchNumber: honeyBatch.batchNumber,
honeyType: honeyBatch.honeyType,
amount: honeyBatch.amount,
status: honeyBatch.status,
},
extraction: {
id: honeyBatch.extraction.id,
date: honeyBatch.extraction.date,
room: honeyBatch.extraction.room,
},
harvests: honeyBatch.extraction.harvests.map((entry) => ({
id: entry.harvest.id,
date: entry.harvest.date,
apiaryId: entry.harvest.apiaryId,
colonies: entry.harvest.colonies.map((hc) => ({
id: hc.colony.id,
code: hc.colony.code,
})),
})),
};
}
}