feat(backend): Fütterungen-Modul (Modul 9)

FeedingsModule mit Erfassung, Colony-Historie und
Mengensummen-Endpunkt je Einheit.
This commit is contained in:
Nick Szaunig committed 2026-08-22 00:14:41 +02:00
1 parent 1f71ac9e3c
commit cc0aaf0a31
9 files changed
+382 -1

No files matched your search

@@ -0,0 +1,63 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { AuditLogService } from '../audit/audit-log.service';
import { Feeding } from '../../generated/prisma';
import { CreateFeedingDto } from './dto/create-feeding.dto';
export interface FeedingSummaryEntry {
unit: string;
totalAmount: number;
}
@Injectable()
export class FeedingsService {
constructor(
private readonly prisma: PrismaService,
private readonly auditLog: AuditLogService,
) {}
async findAll(): Promise<Feeding[]> {
return this.prisma.feeding.findMany({ orderBy: { date: 'desc' } });
}
async findById(id: string): Promise<Feeding> {
const feeding = await this.prisma.feeding.findUnique({ where: { id } });
if (!feeding) {
throw new NotFoundException('Feeding not found');
}
return feeding;
}
async findByColony(colonyId: string): Promise<Feeding[]> {
return this.prisma.feeding.findMany({
where: { colonyId },
orderBy: { date: 'asc' },
});
}
async summaryByColony(colonyId: string): Promise<FeedingSummaryEntry[]> {
const grouped = await this.prisma.feeding.groupBy({
by: ['unit'],
where: { colonyId },
_sum: { amount: true },
});
return grouped.map((entry) => ({
unit: entry.unit,
totalAmount: entry._sum.amount ?? 0,
}));
}
async create(dto: CreateFeedingDto, actingUserId: string): Promise<Feeding> {
const feeding = await this.prisma.feeding.create({
data: { ...dto, date: new Date(dto.date), userId: actingUserId },
});
await this.auditLog.record({
entityType: 'Feeding',
entityId: feeding.id,
action: 'CREATE',
userId: actingUserId,
afterData: feeding,
});
return feeding;
}
}