cd client/
make dev # Starts Vite dev server on port 3001
make build # Production build
make test # Run tests in watch mode
make test:run # Single test run (CI)Vite with native ES modules during development for fast server startup and hot module replacement (HMR):
make dev # Dev server with HMR, source maps, full loggingRollup optimisation with tree shaking, minification, and hash-based filenames for cache invalidation:
make buildBuild output:
dist/
├── index.html # Entry point
├── assets/
│ ├── index-[hash].js # Bundled application code
│ └── index-[hash].css # Bundled styles
The test suite prioritises high-value regression protection with 108 tests running in ~900ms.
Tested: Authentication state, API layer, custom hooks, data transformers, secure storage
Not Tested: UI components, visual rendering, third-party libraries
Running Tests:
make test # Watch mode
make test:run # Single run (CI)
make test:ui # UI mode- ESLint: React rules, TypeScript rules, accessibility rules
- Prettier: Automated formatting
- TypeScript: Static type checking with
npx tsc --noEmit
Pre-commit Workflow:
make format && make lint && make test- Build Stage: Node.js 20 Alpine installs dependencies and builds
- Production Stage: Nginx 1.25 Alpine serves built artifacts (~40MB final image)
Serves built assets via Nginx with:
- Security headers (X-Frame-Options, X-Content-Type-Options, CSP)
- SPA routing via
try_files $uri $uri/ /index.html - 1-year cache expiration for hash-named assets
- API proxying to server container at
/api/*
Docker Compose manages the application:
# Development
docker compose up --build -d
# Production (pre-built images)
docker compose -f compose.prod.yml up -d
# View logs
docker compose logs -f clientHealth checks enable automatic recovery and rolling deployments.
Runtime Configuration: Fetched from /api/meta/environment, enabling the same build to run across environments by connecting to different server instances.
Development vs Production:
- Development: Source maps, full logging, HMR, no minification, Vite proxy to
localhost:5001 - Production: Minified code, generic error messages, security headers, Nginx proxy to server container
Build-Time:
- Tree shaking removes unused code
- Vite dependency optimisation (pre-bundling, CommonJS conversion)
Runtime:
- Debounced inputs for search/filter operations
- React Context for lightweight state management
- N+1 query elimination via bulk API fetches with component-level caching
- Client Architecture - Architecture decisions and design patterns
- API Integration - Server integration patterns
- Server Deployment - Server deployment procedures