feat(export): Bestandsbuch für Tierarzneimittel nach Art. 108 VO (EU) 2019/6

- Treatment records supplier, purchase proof and prescribing vet, and
  keeps the apiary the colony stood at on the treatment day.
- Holder name and address in site settings (never in public output;
  regression test in public.service.spec).
- treatment-log.pdf: one sheet per apiary, identical treatments grouped,
  missing mandatory fields printed as FEHLT, uncertain locations marked.
- Shared PDF table helpers extracted from the record card.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-09-28 11:10:07 +02:00
1 parent f263ec79f2
commit 0d23963f07
24 files changed
+941 -113

No files matched your search

@@ -106,4 +106,33 @@ describe('PublicService', () => {
tiktok: null,
});
});
it('never exposes the holder name or address kept for the Bestandsbuch', async () => {
siteSettings.get.mockResolvedValue({
youtubeUrl: null,
instagramUrl: null,
tiktokUrl: null,
websiteUrl: null,
holderName: 'Nick Muster',
holderAddress: 'Musterweg 3, 86450 Altenmünster',
});
prisma.bottlingBatch.findUnique.mockResolvedValueOnce({
lotNumber: 'WH-2026-001',
date: new Date('2026-08-20'),
bestBeforeDate: new Date('2028-08-20'),
jarSize: 500,
product: null,
honeyBatch: {
honeyType: null,
waterContent: null,
extraction: { date: null, harvests: [] },
},
});
const result = await service.findBatchByLot('WH-2026-001');
const serialized = JSON.stringify(result);
expect(serialized).not.toContain('Nick Muster');
expect(serialized).not.toContain('Musterweg');
});
});