10 KiB
DigitalTwin Frontend Developer Guide (fe-digitaltwin-v2)
[!IMPORTANT] Start here before creating or handing off frontend work
- 🎨 Design-system guideline: Open the public
/design-systempage to inspect the project’s tokens, typography, reusable shadcn-style components, MapCN examples, and AI development workbench. Also readprompts/design-system.md.- 🌿 Feature branch and developer handoff: Open the
Feature handoffsection for the visualmain → feature branch → developer → reviewworkflow, safe commands, and copyable handoff generator. Also readprompts/feature-branch-handoff.mdandGIT_BRANCHES.md.Reuse existing components and semantic tokens, create focused feature work from
main, and never hand-edit generatedclient/<slug>branches.
Welcome to the fe-digitaltwin-v2 project. This guide provides a clear and simple overview of our framework stack, development workflows, production build processes, and key benefits.
🚀 The Framework Stack
This project is built using a modern frontend stack designed for speed, type safety, and rich user interfaces:
- Core Framework: React 18 (with TypeScript for full type safety).
- Build Tool & Dev Server: Vite 6 (provides instantaneous hot module replacement and lightning-fast builds).
- Styling: Tailwind CSS combined with UI libraries like HeroUI and Mantine for rich, premium interfaces.
- State Management: Zustand (global state), Jotai (atomic state), and React Query (server cache / data fetching).
- Routing: React Router Dom v7.
🛠️ Development Flow & Process
1. Prerequisites
Ensure you have Node.js (v18+ recommended) and npm installed on your machine.
2. Install Dependencies
Run this command from the root of the project to install all required libraries:
npm install
3. Local Development Server
Start the local development server by running:
npm run dev
- Vite Advantage: This boots up almost instantly because it leverages native ES modules instead of pre-bundling the entire codebase.
- Hot Module Replacement (HMR): Changes you make in code are instantly reflected in the browser without losing application state.
- Vite Proxy: Any API requests made to
/api-proxyare automatically forwarded to the backend service (configured athttp://192.168.1.82:8000) to avoid CORS issues during development.
4. Code Conventions & Path Aliases
To avoid messy relative imports (e.g. ../../../../components), we use configured path aliases in vite.config.ts and tsconfig.json:
@/components➔ maps tosrc/shared/components@/lib/api-url➔ maps tosrc/shared/api-url@/lib/fetcher➔ maps tosrc/shared/fetcher@/lib/APIs/types➔ maps tosrc/shared/types@➔ maps tosrc
📦 Production Build Flow
Before deploying to production, the codebase must be compiled, type-checked, and bundled into optimized static assets.
1. Build for Production
Run the build script:
npm run build
Under the hood, this command executes:
tsc -b && vite build
tsc -b: Runs the TypeScript compiler in build mode to verify type correctness across the entire application. If there are any type mismatches, the build will fail, preventing runtime errors.vite build: Bundles, minifies, and optimizes your JavaScript, CSS, and asset files. Vite uses Rollup under the hood to perform tree-shaking (removing unused code) and code-splitting (splitting assets into smaller chunks for faster page loading).
2. Preview the Production Build Locally
To test the output of the production build locally before actual deployment, run:
npm run preview
This starts a local static file server hosting the contents of the built dist folder.
3. Docker Deployment
The production image (Dockerfile) builds the Vite bundle, then serves it
through nginx, which also reverse-proxies every backend API prefix
(/auth, /efficiency, /pfi, /lcca, /reliability, /risk-matrix,
/monitoring, /rbd, /ahm, /ops-dock, /optimumoh, /ircfa, /api)
to the real backend server-side (see nginx.conf).
This matters for tunneling: all VITE_*_APP_URL values are baked in as
relative paths by default, so the browser only ever calls the app's own
origin. When you tunnel this container's port (ngrok, cloudflared, etc.),
the browser never tries to reach the backend's local IP directly — nginx
inside the container forwards those calls to the backend for you.
docker compose up -d --build
The app is then available at http://localhost:8081 (configurable via
FRONTEND_PORT) — tunnel this port, not the backend's.
By default nginx forwards API calls to http://192.168.1.82:8000 (and
http://192.168.1.119:8000 for IRCFA, which runs on a separate host). To
point at a different backend without rebuilding the image, copy
.env.docker.example to .env.docker, adjust BACKEND_URL /
BACKEND_URL_IRCFA / FRONTEND_PORT, and run:
docker compose --env-file .env.docker up -d --build
SSO caveat: if you need SSO login to work for outside users, set the
VITE_AUTH_URLbuild arg (indocker-compose.yml) to the actual public tunnel URL and rebuild — it's baked in as the OAuthredirect_urisent to the identity provider, and PLN's IAM must have that exact URL allow-listed, or the login redirect will go nowhere.
📋 Summary of Key Commands
| Command | Purpose | When to Use |
|---|---|---|
npm install |
Installs all project dependencies | When setting up the project or after dependencies change |
npm run dev |
Starts the local interactive Vite development server | During active coding and daily feature development |
npm run build |
Compiles TypeScript and builds optimized production files | Before deploying code to production |
npm run preview |
Serves the production-built code locally for testing | To verify that the production bundle works correctly |
npm run lint |
Runs ESLint to check for code quality and styling errors | Before committing code or during CI/CD checks |
💎 Why Vite & This Stack? (Key Benefits)
- Instant Startup: Unlike traditional bundlers (like Webpack) which bundle the entire app before serving, Vite only processes the code requested by the browser on demand.
- Unmatched HMR Speed: Hot Module Replacement speed remains lightning fast regardless of the size of the application.
- Type Safety: TypeScript prevents standard runtime bugs during compilation.
- Optimized Assets: CSS and JS are split, minified, and bundled to ensure the end-user downloads only what they need, resulting in high performance and fast load times.
⚡ Why Vite + React is More Efficient Than Next.js (For This Project)
Source: This section is based on the official internal Frontend Refactor PRD — "Frontend Refactor: Next.js → Vite + React, Migration PRD & Implementation Guide, Version 1.0" (
ref/frontend_refactor_prd.pdf).
The previous frontend was built on Next.js (App Router). After analysis, it was decided to migrate to Vite + React. The core reason: this application uses zero Server-Side Rendering (SSR) or Static Site Generation (SSG) — meaning every single page was already marked 'use client'. Next.js was adding complexity with zero benefit.
Side-by-Side Comparison
| Concern | Next.js (Before) | Vite + React (Now) |
|---|---|---|
| Rendering | All pages were 'use client' — SSR was unused overhead |
Pure Client-Side Rendering by design, no wasted config |
| Routing | App Router conventions + layouts overhead | React Router v7 — explicit, simple, easy to read |
| Auth | NextAuth tightly coupled to Next.js internals | Custom useAuth hook, full control in ~80 lines |
| Data Fetching | SWR + manual token threading | React Query with centralized, clean config |
| Bundle Config | Next.js opinionated build pipeline | Vite — fast, transparent, fully flexible |
| Mental Model | Server/client boundary confusion | Pure React — no framework magic, simpler onboarding |
What Was Eliminated
- ❌ All
'use client'directive boilerplate — not needed in Vite. - ❌ NextAuth / Auth.js — replaced by a lightweight custom
AuthProvider + useAuthhook. - ❌ SWR — replaced by React Query (TanStack Query v5) with a single centralized config.
- ❌ Next.js file-based routing — replaced by an explicit, readable
router/index.tsxusing React Router v7. - ❌
NEXT_PUBLIC_env variable prefix — replaced by the simplerVITE_prefix viaimport.meta.env.
What Was Gained
- ✅ Faster HMR: Vite's dev server starts almost instantly and stays fast at any project scale.
- ✅ Simpler Mental Model: No server/client boundary confusion. Everything is pure React.
- ✅ Full Auth Control: The custom
AuthProviderreplicates everything NextAuth did in ~80 lines, with no external dependency lock-in. - ✅ Better DX (Developer Experience): Easier onboarding for new developers — no Next.js-specific conventions to learn.
- ✅ Transparent Build Pipeline:
vite buildis predictable and fully configurable, unlike Next.js's opinionated pipeline. - ✅ Feature-Based Architecture: A clean
features/folder structure (one folder per domain) replaces the mixedapp/directory convention.
Migration Goals (from PRD)
The refactor was driven by these official goals:
- Eliminate Next.js overhead (App Router, server/client split, SSR config).
- Adopt a clean, feature-based folder structure from scratch.
- Replace Auth.js (NextAuth) with a lightweight custom JWT auth layer.
- Replace SWR with React Query (TanStack Query) for data fetching.
- Maintain full feature parity — no regressions.
- Improve DX: faster HMR, simpler mental model, easier team onboarding.