feat: T6 wave 3 – treatment books from lot, label print lock, restricted zone, authority notices
- Treatments book their dose from a medicine lot (delta booking on edit, bulk all-or-nothing, idempotent); Bestandsbuch columns from the lot, FEHLT exactly where treatmentLogGaps reports a gap; Bestandsbuch export needs veterinary-medicines:read. - Label printing: 409 LABEL_PARTICULARS_MISSING on gaps, proof print with watermark, PRINT audit before the PDF, check endpoints; digit rules only from the seeded ComplianceSettings row (fail closed). - Restricted zone (Berlin day): create, update, move, merge and CSV import blocked inside an active restriction; override with reason and compliance:manage, audited, never stored on the colony; split, harvest and dissolve stay free; restriction details only with compliance:read. - Authority notices: settings, herd snapshot, registration/herd change/TSK notices with one open draft per kind under the settings lock. - Label check refinements (geometric reading order, number|unit pairs). - ARCHITECTURE.md §12.6–12.8, Annahmen 71–77; spec §5.6 Berlin day. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
c18860c75c
commit
edc193f128
73 files changed
+9470
-171
No files matched your search
@@ -0,0 +1,71 @@
|
||||
import { AuthorityNotice, ComplianceSettings } from '../../generated/prisma';
|
||||
import { DbClient } from '../prisma/db-client';
|
||||
import {
|
||||
buildHerdSnapshot,
|
||||
herdDeviation,
|
||||
HerdDeviation,
|
||||
HerdSnapshot,
|
||||
loadHerdApiaryRows,
|
||||
} from './herd-snapshot';
|
||||
|
||||
export const COMPLIANCE_SETTINGS_ID = 'singleton';
|
||||
|
||||
export interface HerdStatus {
|
||||
settings: ComplianceSettings;
|
||||
baseline: AuthorityNotice | null;
|
||||
current: HerdSnapshot;
|
||||
/** null without a baseline: there is nothing to deviate from. */
|
||||
deviation: HerdDeviation | null;
|
||||
}
|
||||
|
||||
/** The settings row, created with its defaults when it does not exist yet. */
|
||||
export async function complianceSettingsIn(
|
||||
db: DbClient,
|
||||
): Promise<ComplianceSettings> {
|
||||
const existing = await db.complianceSettings.findUnique({
|
||||
where: { id: COMPLIANCE_SETTINGS_ID },
|
||||
});
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
return db.complianceSettings.upsert({
|
||||
where: { id: COMPLIANCE_SETTINGS_ID },
|
||||
update: {},
|
||||
create: { id: COMPLIANCE_SETTINGS_ID },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The baseline is the newest SENT registration or herd change (by sentOn);
|
||||
* TSK reports go to another recipient and do not count.
|
||||
*/
|
||||
export function findBaselineIn(db: DbClient): Promise<AuthorityNotice | null> {
|
||||
return db.authorityNotice.findFirst({
|
||||
where: { status: 'SENT', kind: { in: ['REGISTRATION', 'HERD_CHANGE'] } },
|
||||
orderBy: [{ sentOn: 'desc' }, { createdAt: 'desc' }, { id: 'desc' }],
|
||||
});
|
||||
}
|
||||
|
||||
export async function herdStatusIn(
|
||||
db: DbClient,
|
||||
now: Date,
|
||||
): Promise<HerdStatus> {
|
||||
const settings = await complianceSettingsIn(db);
|
||||
const baseline = await findBaselineIn(db);
|
||||
const current = buildHerdSnapshot(await loadHerdApiaryRows(db), now);
|
||||
return {
|
||||
settings,
|
||||
baseline,
|
||||
current,
|
||||
deviation: baseline
|
||||
? herdDeviation(
|
||||
{
|
||||
snapshot: baseline.snapshot as unknown as HerdSnapshot,
|
||||
totalColonies: baseline.totalColonies,
|
||||
},
|
||||
current,
|
||||
settings,
|
||||
)
|
||||
: null,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user