Allow medications with only a generic name (no commercial name required) (#311)

* Initial plan

* feat: allow generic name only for medications (frontend changes)

- Add getMedDisplayName() helper for consistent name display
- Update validation to require either commercial or generic name
- Update all display locations to use display name fallback
- Add i18n keys for nameOrGenericRequired in en.json and de.json
- Remove required attribute from commercial name field
- Update FIELD_LIMITS.name.min from 1 to 0

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* feat: allow generic name only for medications (backend changes)

- Update Zod schema to allow empty name with cross-field refinement
- Update reminder scheduler to use name || genericName for display
- Update planner routes to match medications by display name
- Update existing tests to match new validation behavior

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

* fix: update placeholder text and fix FIELD_LIMITS test

- Remove "(optional)" from generic name placeholder in en/de
- Update types.test.ts to expect FIELD_LIMITS.name.min = 0

Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
This commit is contained in:
Copilot
2026-02-25 21:29:25 +01:00
committed by GitHub
parent 691550fb33
commit 2a9ca39c24
23 changed files with 151 additions and 114 deletions
@@ -123,7 +123,7 @@ describe("useMedicationForm", () => {
expect(result.current.formChanged).toBe(false);
await waitFor(() => {
expect(result.current.fieldErrors.name).toBe("common.validation.required");
expect(result.current.fieldErrors.name).toBe("common.validation.nameOrGenericRequired");
expect(result.current.hasValidationErrors).toBe(true);
});
});
@@ -131,7 +131,8 @@ describe("useMedicationForm", () => {
it("validates name required and max length fields", () => {
const { result } = renderHook(() => useMedicationForm());
expect(result.current.validateField("name", "")).toBe("common.validation.required");
// Cross-field validation: empty name alone returns no per-field error
expect(result.current.validateField("name", "")).toBeUndefined();
expect(result.current.validateField("takenBy", ["Alice"])).toBeUndefined();
const tooLongGeneric = "a".repeat(101);
+1 -1
View File
@@ -152,7 +152,7 @@ describe("getPackageSize", () => {
describe("FIELD_LIMITS", () => {
it("has correct limits for name field", () => {
expect(FIELD_LIMITS.name.min).toBe(1);
expect(FIELD_LIMITS.name.min).toBe(0);
expect(FIELD_LIMITS.name.max).toBe(100);
});