feat: T6 wave 5 – readiness checks and report, compliance and medicine UI, label UI
Backend Image / build-and-push (push) Successful in 6m45s
Frontend Image / build-and-push (push) Failing after 9m30s

- Readiness: all 18 checks (medicine lots, treatment log gaps, labels,
  harvest withdrawal), medicine subjects masked without
  veterinary-medicines:read, report PDF (counts only), summary cached 60 s,
  409 codes READINESS_*.
- Frontend: /compliance page with acknowledge/revoke, dashboard line and
  nav; veterinary medicine catalogue, lots, movement book with inventory
  and disposal; label designer check panel, print card with gap list and
  proof print, food business master data, product legal name.
- Service worker: cacheability is path-based (the backend sends no-store
  on every answer); compliance, medicine, restriction, notice and label
  check/print paths and restricted document kinds are never cached.
- ARCHITECTURE.md §2, §12.10–12.11, Annahmen 86–90.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-10-15 15:59:08 +02:00
1 parent b912d29166
commit b4746a2b17
149 files changed
+11869 -320

No files matched your search

+51 -1
View File
@@ -68,8 +68,30 @@
/\/api\/v1\/colonies\/?$/i,
/\/api\/v1\/colonies\/[^/]+\/inspections\/?$/i,
/\/api\/v1\/apiaries\/[^/]+\/(colony-overview|offline-pack)\/?$/i,
// Prüfbereitschaft and authority data: file numbers, addresses, notices,
// restricted zones around an apiary, medicine packs with receipts and
// suppliers, and the label check and print (they carry the food business address)
/\/api\/v1\/compliance(\/|$)/i,
/\/api\/v1\/authority-notices(\/|$)/i,
/\/api\/v1\/apiary-restrictions(\/|$)/i,
/\/api\/v1\/apiaries\/[^/]+\/restrictions\/?$/i,
/\/api\/v1\/veterinary-medicines(\/|$)/i,
/\/api\/v1\/veterinary-medicine-lots(\/|$)/i,
/\/api\/v1\/label-templates\/check(\/|$)/i,
/\/api\/v1\/label-templates\/[^/]+\/(print|check)(\/|$)/i,
// One single document (metadata): its kind is not in the path, and it may
// belong to a pack, a notice or a restriction. The lists (with the kind
// in the query, see below) and the photo downloads use other routes.
/\/api\/v1\/documents\/[^/]+\/?$/i,
];
// The document list of these records is never kept either (attachments of a
// pack, a notice or a restriction). The list is /documents?entityType=...,
// so the query decides; documents of inspections (photos) stay available
// offline. Downloads are blobs and never kept anyway.
var DOCUMENTS_PATH = /\/api\/v1\/documents\/?$/i;
var NEVER_CACHED_DOCUMENT_TYPES = ["MEDICINE_LOT", "AUTHORITY_NOTICE", "APIARY_RESTRICTION"];
// A root-relative build asset, in an attribute or in the inline RSC data
// (where quotes are escaped). The leading character keeps absolute URLs of
// other hosts out.
@@ -174,9 +196,35 @@
return true;
}
function isNeverCachedDocumentList(url) {
if (!DOCUMENTS_PATH.test(url.pathname)) {
return false;
}
var entityType = (url.searchParams.get("entityType") || "").toUpperCase();
return NEVER_CACHED_DOCUMENT_TYPES.indexOf(entityType) !== -1;
}
/** The path rules plus the document lists, which only the query tells apart. */
function isCacheableApiUrl(url) {
return isCacheableApiPath(url.pathname) && !isNeverCachedDocumentList(url);
}
/** Only answers of the backend named by the runtime config are kept. */
function shouldCacheApi(url, apiOrigin) {
return Boolean(apiOrigin) && url.origin === apiOrigin && isCacheableApiPath(url.pathname);
return Boolean(apiOrigin) && url.origin === apiOrigin && isCacheableApiUrl(url);
}
/**
* Whether a backend answer may be stored: a successful JSON record. The
* backend marks EVERY answer `Cache-Control: no-store`, so that header says
* nothing about one record; what must not stay on the device is decided by
* the path rules above. Never downloads, photos, PDFs.
*/
function isKeepableApiAnswer(answer) {
return (
Boolean(answer.ok) &&
String(answer.contentType || "").toLowerCase().indexOf("application/json") !== -1
);
}
/** The backend's origin from /api/runtime-config ({ apiUrl }), or null. */
@@ -242,7 +290,9 @@
isShellRoute: isShellRoute,
extractAssetUrls: extractAssetUrls,
isCacheableApiPath: isCacheableApiPath,
isCacheableApiUrl: isCacheableApiUrl,
shouldCacheApi: shouldCacheApi,
isKeepableApiAnswer: isKeepableApiAnswer,
apiOriginFrom: apiOriginFrom,
isRoutePayload: isRoutePayload,
buildAssetsToPrune: buildAssetsToPrune,