# Coding Conventions

## Source Language

Use JavaScript for the new client.

Rules:

- Backend response validation lives in `src/api/schemas`.
- UI-facing normalized models are produced by mapper functions.
- Avoid passing raw backend envelopes deep into UI components.
- If a response shape is uncertain, validate it at the API/module boundary and
  return `invalid_response` on mismatch.

## File Naming

- Vue components: `PascalCase.vue`.
- Stores: `useXStore` exported from `stores/x.js`.
- Composables: `useThing.js`.
- API modules: lowercase domain names, e.g. `devices.js`.
- Runtime schemas: domain names, e.g. `devices.js`, `areas.js`.

## Component Rules

- Keep route components thin.
- Put reusable domain UI in `features/{domain}/components`.
- Put generic reusable UI in `components`.
- Do not pass raw backend DTO-like objects directly into deep UI components unless
  the component is API-specific by design.
- Use props/events for reusable components.
- Use stores for screen-level data and cross-component state.

## Store Rules

- Stores own fetch/mutation orchestration.
- Stores call API modules.
- Stores expose loading/error states.
- Stores should not know about toasts or router navigation.
- Components or page-level actions decide how to show feedback.

## API Rules

- All API methods return normalized `{ ok, data?, error?, meta }` results.
- API modules do not show UI feedback.
- API modules do not mutate stores directly.
- API mappers should be pure functions.
- Request cancellation should use `AbortController`.

## Error Handling

Use this UI policy:

- Route-level fetch failure: show route error state with retry.
- Per-row device status failure: show row-level error/offline state.
- Mutation failure: keep the modal/page open and show toast plus inline field
  errors when available.
- Validation failure: show field-level errors before submitting.

Do not:

- Treat component render errors as network errors.
- Hide backend `msg` when present.
- Swallow failed mutations silently.

## Formatting And Style

- Use tabs or spaces consistently after scaffold decision.
- Keep components small enough that template, script, and styles are easy to scan.
- Prefer explicit names over abbreviations.
- Avoid direct DOM manipulation except for integration boundaries.
- Avoid global singletons unless they are intentional app-level services.

## Icons

Current client uses Phosphor Icons.

New client options:

- Continue using Phosphor if `gnexus-ui-kit` supports it or does not provide an
  icon system.
- Prefer UI-kit icon primitives if they exist.

Do not mix several icon systems in the same screen.

## Dates And Formatting

Centralize formatting in `src/utils/format.js` and `src/utils/dates.js`.

Required helpers:

- `formatDate`
- `formatDateTime`
- `formatTimeAgo`
- `formatDeviceConnectionStatus`
- `formatScriptState`

## CSS And Styling

- Prefer UI-kit tokens/classes.
- Put app-specific layout styles in `src/styles`.
- Avoid copying old SCSS wholesale.
- If old styles are needed temporarily, isolate them under a legacy namespace.
- Do not override UI-kit internals with brittle selectors.
- Keep UI-kit compatibility wrappers thin enough that design updates from
  `gnexus-ui-kit` are visible without rewriting feature components.

## Accessibility Baseline

- Buttons must use real `<button>` elements.
- Modals must trap focus or rely on UI-kit dialog behavior.
- Inputs must have labels.
- Loading states must not remove context.
- Danger actions require confirmation.
