diff --git a/gerbil-manager-web/e2e/tiere.spec.ts b/gerbil-manager-web/e2e/tiere.spec.ts
index 469edc9..30f7a02 100644
--- a/gerbil-manager-web/e2e/tiere.spec.ts
+++ b/gerbil-manager-web/e2e/tiere.spec.ts
@@ -149,3 +149,26 @@ test('Tier bearbeiten — Notizen ändern', async ({ page }) => {
await expect(page.getByRole('heading', { name: 'Krümel' })).toBeVisible()
await expect(page.getByText('Sehr zutraulich.')).toBeVisible()
})
+
+test('Tier bearbeiten — originBreeder Freitext round-trip (FORM-FIELDS-1)', async ({ page }) => {
+ skipUnlessMock()
+ // Fridolin hat originBreeder='Zoohandlung Meier', kein originContactId → Freitext-Feld vorbelegt
+ await page.goto('/rennmaeuse/fridolin/bearbeiten')
+ await expect(page.getByLabel(t.fields.originBreeder)).toHaveValue('Zoohandlung Meier')
+ await page.getByLabel(t.fields.originBreeder).fill('Neue Musterzucht')
+ await page.getByRole('button', { name: t.form.save, exact: true }).click()
+ // Detailseite: Herkunft zeigt den neuen Wert (kein Contact → originBreeder-Text)
+ await expect(page.getByText('Neue Musterzucht')).toBeVisible()
+})
+
+test('Tier bearbeiten — isDeaf Tristate round-trip (FORM-FIELDS-1)', async ({ page }) => {
+ skipUnlessMock()
+ await page.goto('/rennmaeuse/kruemel/bearbeiten')
+ // Standard: Unbekannt (null → value='')
+ await expect(page.getByLabel(t.fields.isDeaf)).toHaveValue('')
+ await page.getByLabel(t.fields.isDeaf).selectOption({ label: t.form.isDeafYes })
+ await page.getByRole('button', { name: t.form.save, exact: true }).click()
+ // Zurück zur Bearbeiten-Seite: Wert muss erhalten sein
+ await page.goto('/rennmaeuse/kruemel/bearbeiten')
+ await expect(page.getByLabel(t.fields.isDeaf)).toHaveValue('true')
+})
diff --git a/gerbil-manager-web/src/api/types.ts b/gerbil-manager-web/src/api/types.ts
index 40024b2..e9b75f9 100644
--- a/gerbil-manager-web/src/api/types.ts
+++ b/gerbil-manager-web/src/api/types.ts
@@ -54,6 +54,8 @@ export interface Gerbil {
* as resident (backend default true).
*/
isResident?: boolean
+ /** FORM-FIELDS-1: true=gehörlos, false=hörend, null=unbekannt. */
+ isDeaf?: boolean | null
}
/** Payload for POST /gerbils. */
@@ -76,6 +78,7 @@ export interface CreateGerbil {
characterTraits?: string[] | null
characterNote?: string | null
isResident?: boolean
+ isDeaf?: boolean | null
}
/** Payload for PUT /gerbils/{id} (all optional / partial update). */
diff --git a/gerbil-manager-web/src/pages/GerbilFormPage.tsx b/gerbil-manager-web/src/pages/GerbilFormPage.tsx
index f3eea99..7d38582 100644
--- a/gerbil-manager-web/src/pages/GerbilFormPage.tsx
+++ b/gerbil-manager-web/src/pages/GerbilFormPage.tsx
@@ -21,10 +21,12 @@ interface FormState {
enclosureId: string
litterId: string
originContactId: string
+ originBreeder: string
receiverContactId: string
genotype: string
notes: string
isResident: boolean
+ isDeaf: boolean | null
}
const EMPTY: FormState = {
@@ -39,10 +41,12 @@ const EMPTY: FormState = {
enclosureId: '',
litterId: '',
originContactId: '',
+ originBreeder: '',
receiverContactId: '',
genotype: '',
notes: '',
isResident: true,
+ isDeaf: null,
}
function formFromGerbil(g: {
@@ -57,10 +61,12 @@ function formFromGerbil(g: {
enclosureId: string | null
litterId: string | null
originContactId: string | null
+ originBreeder?: string | null
receiverContactId: string | null
genotype: string | null
notes: string | null
isResident?: boolean | null
+ isDeaf?: boolean | null
}): FormState {
return {
name: g.name,
@@ -74,10 +80,12 @@ function formFromGerbil(g: {
enclosureId: g.enclosureId ?? '',
litterId: g.litterId ?? '',
originContactId: g.originContactId ?? '',
+ originBreeder: g.originBreeder ?? '',
receiverContactId: g.receiverContactId ?? '',
genotype: g.genotype ?? '',
notes: g.notes ?? '',
isResident: g.isResident ?? true,
+ isDeaf: g.isDeaf ?? null,
}
}
@@ -167,10 +175,12 @@ export default function GerbilFormPage() {
enclosureId: nn(form.enclosureId),
litterId: nn(form.litterId),
originContactId: nn(form.originContactId),
+ originBreeder: nn(form.originBreeder),
receiverContactId: nn(form.receiverContactId),
genotype: nn(form.genotype),
notes: nn(form.notes),
isResident: form.isResident,
+ isDeaf: form.isDeaf,
}
const result = await mutation.run(body)
if (result.ok) navigate(`/rennmaeuse/${result.value.id}`)
@@ -326,6 +336,16 @@ export default function GerbilFormPage() {
+
+
+
+