AquaX Frontend Architecture

Owner: Frontend & Architecture
Reviewers: Backend, Product Design, QA, Security, DevOps
Status: Draft - Current-Code Baseline
Version: 0.1
Last Updated: 2026-09-17
Review Cycle: Per frontend routing, state, API, layout or deployment change

1. Purpose And Scope

This document describes the current AquaX web frontend architecture as implemented in web/. It focuses on runtime composition, routing, layout, state management, API integration, authentication, page boundaries, design-system usage, build behavior and known frontend risks.

This document covers the web admin portal only. Mobile architecture is documented separately in docs/current/architecture/mobile-architecture.md.

Sources reviewed:

2. High-Level Frontend Context

The AquaX web app is a React dashboard for admin and owner workflows. It consumes the backend REST API through Axios service wrappers and TanStack Query hooks.

Current stack:

Area Current implementation
Framework React 19
Build tool Vite 8
Language TypeScript
UI library Ant Design 6
Styling Tailwind CSS 4, CSS variables, Sass/global CSS
Routing React Router DOM 7
Server state TanStack Query 5
Client state Redux Toolkit
HTTP client Axios
Charts Recharts
Icons lucide-react and Ant Design icons
Validation Yup in selected feature forms

Primary runtime flow:

Route
  -> page/view component
  -> domain hook
  -> domain API service
  -> httpClient
  -> backend /api

3. Source Layout

Current source layout:

web/src/
  assets/
    brand/
    images/
    styles/
  core/
    components/
    config/
    constants/
    hooks/
    interfaces/
    layouts/
    libs/
    locales/
    redux/
    routes/
    services/
  pages/
  main.scss
  main.tsx
  router.tsx

Boundaries:

Folder Responsibility
assets/ Brand assets, images and global style files
core/components/ Shared reusable UI components such as AppShell, AquaTable, StatsGrid
core/config/ Runtime env, app config and Axios client
core/constants/ Route paths, API paths, storage keys, query keys and UI constants
core/hooks/ Domain hooks and cross-cutting hooks
core/interfaces/ TypeScript request/response/domain interfaces
core/layouts/ Main layout composition
core/libs/ Utility/helper functions
core/redux/ Redux store and slices
core/routes/ Public/private route registration and route guards
core/services/ Domain API service wrappers
pages/ Feature pages, feature components, schemas and views

4. Application Bootstrap

web/src/main.tsx builds the provider tree.

Provider order:

StrictMode
  -> ReduxProvider
    -> QueryClientProvider
      -> AntD ConfigProvider
        -> AntD App
          -> RouterProvider

Confirmed configuration:

Concern Current code
Query defaults From appConfig.query
Query retry 1
Query stale time 60_000ms
Refetch on window focus true
AntD locale vi_VN
AntD primary color #006b5f
AntD border radius 8
Font family Inter/system stack
Router createBrowserRouter

5. Build And Runtime Configuration

Vite configuration:

Concern Current code
React plugin @vitejs/plugin-react
Tailwind plugin @tailwindcss/vite
Path alias @app/* -> src/*
Module resolution TypeScript bundler mode
JSX react-jsx

Environment config:

Variable Purpose Default
VITE_APP_NAME App display/config name AquaX Web
VITE_API_BASE_URL Axios base URL /

Production note:

6. Routing Architecture

Root router:

/
  -> RouteTitleOutlet
    -> publicRoutes
    -> privateRoutes

RouteTitleOutlet updates document.title based on route path.

6.1 Public Routes

Path Page Guard
/login LoginPage PublicOnlyRoute
/forgot-password ForgotPasswordPage PublicOnlyRoute
/reset-password ResetPasswordPage PublicOnlyRoute
/unauthorized Unauthorized RequireAuth

PublicOnlyRoute redirects authenticated users:

Role Redirect
ADMIN /
OWNER /dashboard
other authenticated role /unauthorized

6.2 Private Route Shell

Top-level private shell:

RequireAuth allowedRoles=[ADMIN, OWNER]
  -> MainLayout
    -> AppShell
    -> nested private routes

Role-specific private routes:

Role Current route area
OWNER /dashboard owner/viewer dashboard
ADMIN users, farms, ponds, IoT devices, reports, tickets, activity logs, notifications, settings

Index route:

6.3 Confirmed Admin Route Groups

Area Route examples
Users /users, /users/create, /users/:id, /users/:id/edit, /users/assign-technician
Farms /farms, /farms/create, /farms/:id, /farms/:id/edit
Ponds /ponds, /ponds/create, /ponds/:id, /ponds/:id/edit
IoT devices /iot-devices
Tickets /tickets, /tickets/create, /tickets/:id, /tickets/:id/assign, /tickets/:id/close
Reports /reports, /reports/export, /reports/water-quality, /reports/iot-devices, /reports/feeding, /reports/environment, /reports/incidents
Activity logs /activity-logs
Notifications /notifications
Settings /settings, /settings/incident-response

6.4 Placeholder Routes

Some private routes are registered but currently render Developing:

Route Current status
/water-monitoring Placeholder
/feeding Placeholder
/farming-logs Placeholder
/handbook Placeholder
/alerts Placeholder

7. Layout Architecture

MainLayout wraps authenticated pages and provides:

AppShell provides:

Navigation source:

core/constants/app-shell.ts

APP_SHELL_NAV_ITEMS filters by role. Current visible navigation:

Role Navigation
OWNER Dashboard
ADMIN Users, farms, ponds, IoT devices, reports, tickets, activity logs, notifications, settings

8. State Management Architecture

8.1 Redux

Redux is used for small, client-owned global state.

Current slices:

Slice State
auth accessToken, expiresAt, user
app locale

Auth initial state reads:

Redux rule:

8.2 TanStack Query

TanStack Query is the main server-state layer.

Current query defaults:

Domain hooks use useQuery, useMutation and query invalidation. Examples:

Query rule:

9. API Integration Architecture

9.1 Axios Client

core/config/axios.config.ts creates httpClient.

Current config:

Concern Current code
Base URL env.apiBaseUrl
Timeout 15_000ms
Content type application/json
Credentials withCredentials: true
Request auth Adds bearer token from STORAGE_KEYS.AUTH_TOKEN
Error normalization Extracts backend response.data.message

9.2 Refresh Queue

When a request returns 401:

  1. Login and refresh endpoints are excluded from auto-refresh.
  2. If refresh is already running, the failed request is queued.
  3. The client calls /auth/refresh with httpOnly cookie credentials.
  4. On success, the new access token and user are stored locally.
  5. Queued requests replay with the new token.
  6. On refresh failure, local auth is cleared and the browser redirects to /login.

Architecture risk:

9.3 Endpoint Constants And Services

Endpoint constants:

core/constants/api-url.ts

Service wrappers:

core/services/*API.ts

Current service domains:

Service Area
authAPI Login, refresh, logout, password reset
userAPI User management
farmAPI Farm management
pondAPI Pond management and tabs
cropAPI Crop lifecycle
ticketAPI Tickets
reportAPI Reports and export
locationAPI Provinces and wards
deviceAPI Device and auto-rule APIs
iotDeviceAPI IoT registration/control APIs
notificationAPI Notifications and device tokens
settingsAPI Incident response settings
activityLogAPI Activity logs and export
dashboardAPI Owner dashboard
parameterThresholdAPI Threshold configuration

Endpoint constants intentionally omit /api; VITE_API_BASE_URL is responsible for the backend prefix.

10. Authentication UX And Session Lifecycle

useAuth owns login/logout/reset-password UX.

Login success:

  1. Persist auth session in storage.
  2. Dispatch setAuthSession.
  3. Show AntD notification.
  4. Redirect by role:
    • ADMIN -> /
    • OWNER -> /dashboard
    • other -> /unauthorized

Logout:

  1. Calls backend logout when possible.
  2. Clears local auth storage.
  3. Dispatches clearAuthSession.
  4. Redirects to /login.

useSessionTimeout:

11. Notification Architecture

Notifications combine polling and server-sent events.

Confirmed behavior:

UI surfaces:

12. Page Architecture And Feature Status

Current implemented or partially implemented areas:

Area Status
Auth Login, forgot password, reset password, public/private guards
Owner dashboard Owner dashboard route and page
Users List, create, detail, edit, status, delete, audit log, farm scope, assign technician
Farms List, create, edit, detail, tabs and location data
Ponds List, create, edit, detail, crop drawer and pond tabs
IoT devices Registered page with device management UI
Tickets List, create, detail, assign, close and delete flows
Reports Landing, filters, export and report type pages
Activity logs Workspace-style log view
Notifications List/read state/device notification integration
Settings Settings landing and incident response settings

Placeholder or incomplete route areas:

Area Current status
Water monitoring Placeholder route
Feeding Placeholder route
Farming logs Placeholder route
Handbook Placeholder route
Alerts Placeholder route

13. Styling And Design System Integration

Current frontend styling layers:

Layer Files
CSS variables assets/styles/variables.css
Tailwind import and view transitions assets/styles/tailwind.css
Global base styles and animations main.scss
AntD theme tokens main.tsx ConfigProvider
Local feature styles Page/component class names and inline AntD style overrides

Primary design tokens:

Token Current value
Primary #006b5f
Primary container #008378
Secondary #006a63
Surface #f5faf8
Background #fff
Danger #b00000
Border subtle #dde7e3
Base radius 8px
Base font Inter/system sans

Architecture rule:

14. Type And Data Boundary

Types live under:

core/interfaces/

Current interface files are domain-oriented:

Rules:

15. Build, CI And Deployment Considerations

Package scripts:

Script Purpose
npm run dev Start Vite dev server with host binding
npm run build Run tsc -b and vite build
npm run lint Run ESLint
npm run preview Preview built output
npm run format Format source
npm run format:check Check formatting

CI:

Deployment gap:

16. Performance And UX Considerations

Current confirmed optimizations:

Current gaps:

17. Accessibility And Internationalization

Confirmed baseline:

Gaps:

18. Architecture Risks And Action Items

ID Risk Impact Required follow-up
FE-ARCH-01 Production hosting is not finalized; Dockerfile runs dev server Web deployment may be unsuitable for production Create production static build/serve plan
FE-ARCH-02 Placeholder routes exist for several product areas Users may see unfinished screens Keep backlog status visible and replace Developing with real pages when implemented
FE-ARCH-03 No route-level code splitting Bundle may grow as pages expand Add lazy route loading when build size requires it
FE-ARCH-04 API constants can drift from backend controllers Runtime 404/contract bugs Keep 08_API Specification.md, constants and services updated together
FE-ARCH-05 Auth role model currently exposes web routes mainly to ADMIN/OWNER Other roles may be unsupported on web Align with permission matrix before exposing MANAGER/TECHNICIAN/VIEWER web routes
FE-ARCH-06 Styling is split across tokens, Tailwind, AntD overrides and local page styles Inconsistent UI and maintenance cost Promote repeated patterns into shared components/tokens
FE-ARCH-07 Frontend metrics/error tracking not confirmed Production issues may be harder to diagnose Add logging/error monitoring provider when deployment hardens

19. Change Rules

When changing frontend architecture:

  1. Add route paths to core/constants/routes.ts.
  2. Register route in core/routes/public.tsx or private.tsx.
  3. Add sidebar item in core/constants/app-shell.ts only when it should be visible in navigation.
  4. Add/update API endpoint constants in core/constants/api-url.ts.
  5. Add/update service wrapper in core/services.
  6. Add/update domain hook in core/hooks.
  7. Keep server state in TanStack Query and small app/auth state in Redux.
  8. Update docs/08_API Specification.md and this file when contracts or architecture change.
  9. Run npm run lint and npm run build for frontend code changes.

20. Traceability

Source Architecture evidence
web/package.json Stack, dependencies and scripts
web/vite.config.ts Vite plugins and @app alias
web/tsconfig.app.json TypeScript compilation and alias configuration
web/src/main.tsx Provider tree, QueryClient, AntD theme
web/src/router.tsx Browser router root
web/src/core/routes/** Public/private routes, guards and role redirects
web/src/core/config/axios.config.ts HTTP client, token injection and refresh queue
web/src/core/config/env.ts Vite env boundary
web/src/core/redux/** Auth/app client state
web/src/core/hooks/** Domain server-state hooks
web/src/core/services/** Domain API service wrappers
web/src/core/components/AppShell/** Authenticated layout, navigation and notification UI
web/src/core/constants/** Route, API, query, nav and storage constants
web/src/pages/** Feature page implementation status
docs/current/architecture/web-architecture.md Existing web architecture snapshot
docs/07_Design System.md Current UI design baseline