Skip to content

Atomic pattern

Frontend uses Astro, DaisyUI, and atomic design.

Components live in atomic layers. Pages compose atomic layers. Frontend does not own feature slices.

src/features/** is target-architecture debt. It exists only as a temporary migration holding area for older frontend worker output. No new file, import, or route dependency may be added there. Existing feature code must be moved into atomic UI, Nanostores UI stores, or backend API client wrappers.

All interactive client state goes through Nanostores. Stores may hold backend projection state, command progress, conflict status, retry state, and client-only conversational flow state. Stores must not derive backend-owned payment, reservation, document, workflow, RBAC, pricing, or settlement decisions locally.

Security rule: UI affordances are advisory only. Backend checks remain the only authority. Frontend must render can*, status, amount, and readiness fields received from backend contracts, not recompute them from raw rows or hidden DOM state.

E2E rule: a reservation/payment/settlement browser scenario is not migration proof if the page imports src/features/** or fills missing backend decisions with UI logic. The browser can prove contract consumption; backend facts prove authority.

*.feature-ui.tsx files are no longer allowed. The ESLint boundary treats src/features/**/*.tsx as non-UI and blocks React local/context state hooks for business state, including useState, useReducer, useContext, useActionState, and useOptimistic.

Reusable navigation controls belong in atoms. Repeated DaisyUI anchor buttons use the LinkButton atom instead of duplicating class="btn ..." in organisms or templates.