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.
- 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.
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.