Platform backbone (plan 2026-10-13-plattform-rueckgrat), all tasks reviewed: - webhooks with delivery table, retries and stable delivery id - calendar handlers; a finished task removes its Outlook event - tasks, automations, inspections, varroa, treatments, feedings, harvests, colonies, wintering, stock and bottling record domain events in the same transaction; legacy post-commit calls removed - row locks through one helper (lockRowForUpdate, lockRowsForShare, lockRowsForUpdate) - job framework with JobRun, cli exit codes, cleanup, task templates, daily evaluation, hourly app-backup and the rekey job - system API and page "Verwaltung > System" with retry - @nestjs/schedule removed, guard tests against in-process schedulers Field capture T3 (plan 2026-10-13-t3-erfassung-am-stand), all tasks reviewed: - inspection photo offline without metadata - bulk capture for treatments, feedings and varroa (backend + frontend) - offline stand mode with service worker, offline pages and packs - offline session, cold start and logout on shared devices Docs: ARCHITECTURE.md assumptions and sections updated, TASKS.md. Gates: backend lint, typecheck, 1770 unit, 420 e2e, build, no schema drift; frontend lint, typecheck, 913 tests, build. Not rolled out. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
// German counts for the offline queue: "1 Eintrag wartet", "2 Einträge warten".
|
||
|
||
function count(n: number, one: string, many: string): string {
|
||
return n === 1 ? `1 ${one}` : `${n} ${many}`;
|
||
}
|
||
|
||
export function entriesWaiting(n: number): string {
|
||
return count(n, "Eintrag wartet", "Einträge warten");
|
||
}
|
||
|
||
export function entriesRejected(n: number): string {
|
||
return count(n, "Eintrag abgelehnt", "Einträge abgelehnt");
|
||
}
|
||
|
||
export function foreignEntriesWaiting(n: number): string {
|
||
return count(n, "Eintrag eines anderen Kontos wartet", "Einträge eines anderen Kontos warten");
|
||
}
|
||
|
||
export function entriesSynced(n: number): string {
|
||
return count(n, "Eintrag synchronisiert", "Einträge synchronisiert");
|
||
}
|
||
|
||
/** Photos that wait together with a queued inspection: "+ 2 Fotos". */
|
||
export function photosAttached(n: number): string {
|
||
return `+ ${count(n, "Foto", "Fotos")}`;
|
||
}
|
||
|
||
/** Photos of a fresh form that did not fit into a restored draft and were deleted. */
|
||
export function photosNotTakenOver(n: number): string {
|
||
return `${count(n, "Foto wurde", "Fotos wurden")} nicht übernommen und verworfen`;
|
||
}
|
||
|
||
/** Sign-out dialog: "3 Einträge sind noch nicht gesendet." */
|
||
export function entriesNotSent(n: number): string {
|
||
return n === 1 ? "1 Eintrag ist noch nicht gesendet." : `${n} Einträge sind noch nicht gesendet.`;
|
||
}
|
||
|
||
/** The refresh found the session over: the entries wait for the next sign-in. */
|
||
export function sessionExpiredWithEntries(n: number): string {
|
||
const expired = "Sitzung abgelaufen – bitte neu anmelden.";
|
||
if (n === 0) {
|
||
return expired;
|
||
}
|
||
const rest = n === 1 ? "1 Eintrag wartet und wird danach gesendet." : `${n} Einträge warten und werden danach gesendet.`;
|
||
return `${expired} ${rest}`;
|
||
}
|