feat(deploy): TrueNAS Custom-App + Auto-Deploy, plus aufgelaufene Arbeit
Deployment: - custom-app.compose.yaml: self-contained Compose fuer TrueNAS "Custom App" (absolute Host-Bind-Pfade, postgres:18, pull_policy always, Port 8090) - scripts/truenas-deploy.sh: Host-Skript create/redeploy via midclt (App bleibt unter Apps sichtbar) inkl. Image-Pull + Health-Check - ci.yml Deploy-Job: laeuft auf ubuntu-latest-Runner, kopiert Deploy-Dateien per SSH auf den NAS-Host und triggert truenas-deploy.sh (statt runs-on goldeye) - compose.yaml/.env.example: postgres:18 (Locale-Match zur Quell-DB), Port 8090 - .gitignore: .agents/, tools/rag/, deploy/truenas/.env (Secrets/Scratch) Aufgelaufene Feature-Arbeit (verified/Freeze, Migrationen, Import-Triage): - GerbilOverride/VerifiedGerbil-Endpoints + GerbilSnapshotService + Tests - EF-Migrationen (ShowInChronicle, Stillborn, BirthOrder, ManualFlag, DSGVO) - Frontend VerifizierteTierePage + verified-API + e2e-Spec - diverse Import-/Triage-Skripte und -Tests Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -133,6 +133,12 @@ export const de = {
|
||||
parentLittersEmpty: 'Keine Würfe als Elternteil erfasst.',
|
||||
parentLittersRoleVater: 'Vater',
|
||||
parentLittersRoleMutter: 'Mutter',
|
||||
// WURFCHRONIK-FILTER: Wurf ist nicht in der Wurfchronik (showInChronicle=false),
|
||||
// wird daher nur hier (am Elterntier) gezeigt, nicht in der Wurf-Liste.
|
||||
parentLittersNotInChronicle: 'Nicht in der Wurfchronik',
|
||||
offspringInBreedingTitle: 'Nachzucht in der Zucht',
|
||||
offspringInBreedingEmpty: 'Keine Nachkommen dieses Tiers sind in die Zucht gegangen.',
|
||||
|
||||
// Hinweis: Eltern dieses Tiers sind Vollgeschwister (gleicher Wurf).
|
||||
siblingPairing: 'Geschwisterverpaarung',
|
||||
siblingPairingTitle:
|
||||
@@ -141,6 +147,13 @@ export const de = {
|
||||
// ausgeblendet, da das Tier nie im eigenen Bestand war.
|
||||
nonResidentNote:
|
||||
'Externes Tier — nur als Vorfahre erfasst. Würfe und Charakter werden nicht angezeigt, da es nie im eigenen Bestand war.',
|
||||
// Vorfahren-Nachzucht-Zeile: statt Wurf-Karten nur ein Hinweis auf die Nachzucht.
|
||||
nonResidentOffspringLabel: 'Nachzucht dieses Vorfahren:',
|
||||
// Positives „Zuchttier“-Kennzeichen (Tier hatte eigene Würfe in der Zucht).
|
||||
zuchttierBadge: '★ Zuchttier',
|
||||
zuchttierBadgeTitle: 'Dieses Tier wurde bei dir in der Zucht eingesetzt (hatte eigene Würfe).',
|
||||
// Zeile „Zuchtpartner“ in den Stammdaten (bisherige Verpaarungspartner).
|
||||
zuchtpartner: 'Zuchtpartner',
|
||||
},
|
||||
// Formular (anlegen/bearbeiten)
|
||||
form: {
|
||||
@@ -151,9 +164,9 @@ export const de = {
|
||||
ownBreeding: 'Eigene Zucht',
|
||||
genotypeHint:
|
||||
'Optional. Format z. B. „Aa CC Dd EE GG Pp Spsp rere“. Unbekannte Allele als „-“.',
|
||||
// BESTAND-FILTER: Zugehörigkeit zum eigenen Bestand (sonst externe Ahne)
|
||||
isResidentLabel: 'Gehört zum eigenen Bestand',
|
||||
isResidentHint: 'Abwählen für externe Ahnen, die nur für den Stammbaum erfasst sind.',
|
||||
// BESTAND-FILTER: Zuchtanwärter/in (eigenes Zuchttier) vs. reine Ahne
|
||||
isResidentLabel: 'Zuchtanwärter/innen',
|
||||
isResidentHint: 'Abwählen für reine Vorfahren, die nur für den Stammbaum erfasst sind und keine eigenen Zuchttiere waren.',
|
||||
isDeafUnknown: 'Unbekannt',
|
||||
isDeafYes: 'Ja',
|
||||
isDeafNo: 'Nein',
|
||||
@@ -218,6 +231,8 @@ export const de = {
|
||||
sort: {
|
||||
dateDesc: 'Wurfdatum (neueste)',
|
||||
dateAsc: 'Wurfdatum (älteste)',
|
||||
nameAsc: 'Alphabetisch (A-Z)',
|
||||
nameDesc: 'Alphabetisch (Z-A)',
|
||||
},
|
||||
// Felder
|
||||
fields: {
|
||||
@@ -227,7 +242,10 @@ export const de = {
|
||||
mother: 'Mutter',
|
||||
totalBorn: 'Wurfstärke',
|
||||
deathsWithin8Weeks: 'In den ersten 8 Wochen verstorben',
|
||||
stillborn: 'Totgeburten',
|
||||
expectedGoHomeDate: 'Voraussichtliches Abgabedatum',
|
||||
socializeDate: 'Vergesellschaftung (ab 8 Wochen)',
|
||||
groupGoHomeDate: 'Abgabe als Gruppe (ab 10 Wochen)',
|
||||
notes: 'Notizen',
|
||||
},
|
||||
// Detail / Arbeitsbereich
|
||||
@@ -1164,6 +1182,92 @@ export const de = {
|
||||
button: 'Zum RennmausPro-Import',
|
||||
},
|
||||
},
|
||||
// ── GEPRÜFTE TIERE: „vollständig korrekt"-Markierung + Schutz manueller Änderungen ──
|
||||
// Ziel laienverständlich erklären: eine geprüfte Maus wird vom automatischen Import
|
||||
// nicht mehr verändert; so wird der Bestand Tier für Tier sauber.
|
||||
verified: {
|
||||
// Karte auf der Rennmausakte
|
||||
sectionTitle: 'Prüfstatus & Schutz',
|
||||
explainIntro:
|
||||
'Wenn bei dieser Maus alle Angaben stimmen, markiere sie als „vollständig korrekt". ' +
|
||||
'Der automatische Import verändert sie dann nicht mehr — deine geprüften Angaben bleiben erhalten. ' +
|
||||
'So wird dein Bestand nach und nach sauber, ohne dass der Import raten muss.',
|
||||
explainProtected:
|
||||
'Diese Maus enthält von dir geänderte Angaben. Diese sind vor dem Import geschützt und bleiben erhalten. ' +
|
||||
'Felder, die du nicht angefasst hast, werden weiterhin automatisch aus dem Import verbessert.',
|
||||
verifiedBadge: '✓ Vollständig korrekt',
|
||||
verifiedBadgeTitle: 'Geprüft — der automatische Import verändert diese Maus nicht mehr.',
|
||||
protectedBadge: '🔒 Geschützte Änderungen',
|
||||
protectedBadgeTitle: 'Enthält von dir geänderte Angaben, die der Import nicht überschreibt.',
|
||||
driftBadge: '⚠ Weicht vom Import ab',
|
||||
driftBadgeTitle: 'Der automatische Import liefert für einige Felder andere Werte als dein geprüfter Stand.',
|
||||
markAction: 'Als vollständig korrekt markieren',
|
||||
unmarkAction: 'Markierung entfernen',
|
||||
releaseAction: 'Schutz aufheben (wieder aus Import)',
|
||||
marking: 'Wird gespeichert …',
|
||||
markSuccess: 'Als vollständig korrekt markiert. Der Import verändert diese Maus nicht mehr.',
|
||||
unmarkSuccess: 'Markierung entfernt. Beim nächsten Import wird die Maus wieder automatisch aktualisiert.',
|
||||
error: 'Konnte nicht gespeichert werden.',
|
||||
unmarkConfirm:
|
||||
'Markierung wirklich entfernen? Die aktuellen Werte bleiben stehen; beim nächsten Import wird diese Maus wieder automatisch aktualisiert.',
|
||||
releaseConfirm:
|
||||
'Schutz wirklich aufheben? Beim nächsten Import wird diese Maus wieder komplett aus dem Import übernommen — deine Änderungen gehen dann verloren.',
|
||||
statusUnchanged: 'Der Import stimmt mit deinem geprüften Stand überein.',
|
||||
driftHeading: 'Abweichungen zum automatischen Import',
|
||||
driftHint:
|
||||
'So sieht es der Import gerade. Ist dein Stand richtig, kannst du das ignorieren — oder Julian passt den Import an. Deine geprüften Werte bleiben so oder so erhalten.',
|
||||
colField: 'Feld',
|
||||
colGolden: 'Dein geprüfter Stand',
|
||||
colImport: 'Automatischer Import',
|
||||
// Übersichtsseite (/hilfe/verifizierte-tiere)
|
||||
pageTitle: 'Geprüfte Tiere',
|
||||
pageSubtitle: 'Alle Mäuse, die du als „vollständig korrekt" markiert oder von Hand geändert hast.',
|
||||
pageIntro1:
|
||||
'Hier siehst du alle Mäuse, deren Angaben du geprüft und markiert hast. Diese werden vom automatischen Import nicht mehr verändert — dein Bestand wird so Tier für Tier sauber.',
|
||||
pageIntro2:
|
||||
'„Weicht vom Import ab" heißt: der Import liefert inzwischen andere Werte als dein geprüfter Stand — ein Hinweis, dass am Import noch etwas zu korrigieren ist. Deine Angaben bleiben trotzdem erhalten.',
|
||||
empty: 'Noch keine Mäuse als vollständig korrekt markiert.',
|
||||
loadError: 'Die geprüften Tiere konnten nicht geladen werden.',
|
||||
sectionVerified: 'Vollständig korrekt',
|
||||
sectionProtected: 'Geschützte Änderungen (von Hand bearbeitet)',
|
||||
openAkte: 'Zur Akte',
|
||||
protectedFieldsLabel: 'Geschützte Felder:',
|
||||
warningsHeading: 'Hinweise',
|
||||
statusLabels: {
|
||||
unchanged: 'Unverändert',
|
||||
drifted: 'Weicht vom Import ab',
|
||||
missing: 'Im Import nicht mehr vorhanden',
|
||||
} as Record<string, string>,
|
||||
// Link auf der Hilfe-Seite
|
||||
hilfeLink: 'Geprüfte Tiere (vollständig korrekt)',
|
||||
// Feld-Bezeichnungen für Diff-/Schutz-Anzeige (Schlüssel = Backend-Feldnamen).
|
||||
fieldLabels: {
|
||||
name: 'Name',
|
||||
gender: 'Geschlecht',
|
||||
dateOfBirth: 'Geburtsdatum',
|
||||
dateOfDeath: 'Todesdatum',
|
||||
causeOfDeath: 'Todesursache',
|
||||
goHomeDate: 'Abgabedatum',
|
||||
genotype: 'Genotyp',
|
||||
spottingType: 'Scheckung',
|
||||
colorName: 'Farbschlag',
|
||||
colorVarietyId: 'Farbschlag',
|
||||
isResident: 'Zuchtanwärter/in',
|
||||
isDeaf: 'Gehörlos',
|
||||
isCastrated: 'Kastrat',
|
||||
originBreeder: 'Herkunft (Zucht)',
|
||||
originContact: 'Herkunft (Kontakt)',
|
||||
originContactId: 'Herkunft (Kontakt)',
|
||||
receiverContact: 'Abnehmer',
|
||||
receiverContactId: 'Abnehmer',
|
||||
notes: 'Notizen',
|
||||
characterTraits: 'Charakter-Merkmale',
|
||||
characterNote: 'Charakter-Notiz',
|
||||
birthLitter: 'Geburtswurf',
|
||||
father: 'Vater',
|
||||
mother: 'Mutter',
|
||||
} as Record<string, string>,
|
||||
},
|
||||
api: {
|
||||
errors: {
|
||||
network: 'Verbindung zum Server fehlgeschlagen. Bitte später erneut versuchen.',
|
||||
|
||||
Reference in New Issue
Block a user