You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

10 KiB

DigitalTwin Frontend Developer Guide (fe-digitaltwin-v2)

[!IMPORTANT] Start here before creating or handing off frontend work

Reuse existing components and semantic tokens, create focused feature work from main, and never hand-edit generated client/<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-proxy are automatically forwarded to the backend service (configured at http://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 to src/shared/components
  • @/lib/api-url ➔ maps to src/shared/api-url
  • @/lib/fetcher ➔ maps to src/shared/fetcher
  • @/lib/APIs/types ➔ maps to src/shared/types
  • @ ➔ maps to src

📦 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
  1. 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.
  2. 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_URL build arg (in docker-compose.yml) to the actual public tunnel URL and rebuild — it's baked in as the OAuth redirect_uri sent 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)

  1. 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.
  2. Unmatched HMR Speed: Hot Module Replacement speed remains lightning fast regardless of the size of the application.
  3. Type Safety: TypeScript prevents standard runtime bugs during compilation.
  4. 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 + useAuth hook.
  • ❌ 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.tsx using React Router v7.
  • ❌ NEXT_PUBLIC_ env variable prefix — replaced by the simpler VITE_ prefix via import.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 AuthProvider replicates 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 build is predictable and fully configurable, unlike Next.js's opinionated pipeline.
  • ✅ Feature-Based Architecture: A clean features/ folder structure (one folder per domain) replaces the mixed app/ directory convention.

Migration Goals (from PRD)

The refactor was driven by these official goals:

  1. Eliminate Next.js overhead (App Router, server/client split, SSR config).
  2. Adopt a clean, feature-based folder structure from scratch.
  3. Replace Auth.js (NextAuth) with a lightweight custom JWT auth layer.
  4. Replace SWR with React Query (TanStack Query) for data fetching.
  5. Maintain full feature parity — no regressions.
  6. Improve DX: faster HMR, simpler mental model, easier team onboarding.