Files
2026-06-30 23:23:50 +02:00

4.4 KiB

NFR Requirements — Unit 3: frontend-cms-page

Maintainability

ID Requirement Rationale
NFR-FE-01 All new components use react-hook-form + zodResolver + Zod schemas, consistent with InviteUserDialog and LoginPage patterns in this project. Single validation strategy across the entire frontend.
NFR-FE-02 All user-visible strings are externalised in src/i18n/locales/{lang}/translation.json under the cms.* namespace. No hardcoded UI text in components. Enables future language additions without code changes.
NFR-FE-03 Components follow the existing Shadcn/UI composition pattern: Dialog, Table, Select, Badge, DropdownMenu from @/components/ui/*. No third-party UI additions. Keeps the component surface consistent and avoids dependency sprawl.

Testability

ID Requirement Rationale
NFR-FE-04 Test scope: hooks + page integration + individual component tests (Q2: C). Required test files: useCmsInstances.test.ts, useAddCmsInstance.test.ts, useUpdateCmsInstanceStatus.test.ts, CmsPage.test.tsx, AddCmsInstanceDialog.test.tsx, SetStatusDialog.test.tsx. Matches precedent set by InviteUserDialog.test.tsx. Isolated component tests cover error states and conditional logic (DisableMessage) without needing a full page mount.
NFR-FE-05 MSW handlers cover all three API operations (GET list, POST create, PUT status) with at least one happy-path and one error variant per endpoint. Handlers must be registered in both src/mocks/browser.ts (dev) and src/mocks/server.ts (tests).
NFR-FE-06 All interactive elements receive data-testid attributes following the existing naming convention (cms-*, e.g. cms-add-button, cms-instance-row, cms-set-status-submit). Required for RTL getByTestId selectors in tests.

Security

ID Requirement Rationale
NFR-FE-07 The apiKey field in AddCmsInstanceDialog is rendered as type="password" using the existing PasswordField component (which includes a show/hide toggle). Prevents shoulder-surfing of infrastructure credentials during the add flow (Q3: A). Reuses existing PasswordField.tsx component.
NFR-FE-08 The apiKey value is sent once to the backend on form submit. It is not stored in React state beyond the form lifecycle and is not logged to the console. Credentials must not leak into browser DevTools' React state inspector or console logs.
NFR-FE-09 CmsPage relies on RoleGuard allowedRoles={['Owner']} at the route level. No additional role check is implemented inside the page or its components. Single point of access control; avoids partial/inconsistent guards. See BR-FE-20.

Reliability

ID Requirement Rationale
NFR-FE-10 Loading state for useCmsInstances is rendered as <p className="text-sm text-muted-foreground">{t('common.loading')}</p>, consistent with UsersPage. No skeleton component is introduced. Uniform loading UX without additional dependencies.
NFR-FE-11 Error state for useCmsInstances is rendered as <p className="text-sm text-destructive">{t('errors.generic')}</p>, consistent with UsersPage. No custom error component needed.
NFR-FE-12 TanStack Query stale time for useCmsInstances is 30 000 ms. Cache is invalidated on every successful mutation (add or status update). Balances freshness with network efficiency; avoids redundant refetches while dialogs are open.

Validation

ID Requirement Rationale
NFR-FE-13 URL field in AddCmsInstanceDialog uses z.string().url() (strict Zod URL validation). The user must supply a fully-qualified URL including protocol (e.g. http://192.168.1.5:8080). Q1: A. Backend validates anyway; client-side strict validation prevents protocol-less entries from ever reaching the API.
NFR-FE-14 react-hook-form mode is set to onTouched for all new dialogs, consistent with LoginPage. Validation messages appear after a field is touched, not on initial render. Avoids red errors appearing before the user has interacted with the form.
NFR-FE-15 Field-level validation errors are rendered using the existing <FieldError> component (src/components/ui/FieldError.tsx). Consistent error presentation across all forms.