refactor: migrate docs-dev from storybook to vitepress config and update devcontainer configuration

This commit is contained in:
Firman Ramdhani
2026-06-24 13:14:44 +07:00
parent 385452bf36
commit ecb16c759d
26 changed files with 1892 additions and 1414 deletions
+9 -4
View File
@@ -14,14 +14,19 @@
},
// ─── Port Topology ──────────────────────────────────────────────────────────
// 6006: Storybook (Docs)
// 6060: VitePress Docs (Development)
// 4173: VitePress Docs (Preview)
// 5173: Web App (Must be strictly 5173 for Electron IPC compatibility)
// 3000: Landing App (Isolated from Vite's default 517x blast radius)
"forwardPorts": [6006, 5173, 3000],
"forwardPorts": [6060, 4173, 5173, 3000],
"portsAttributes": {
"6006": {
"label": "Storybook",
"6060": {
"label": "VitePress Docs",
"onAutoForward": "notify"
},
"4173": {
"label": "VitePress Preview",
"onAutoForward": "notify"
},
"5173": {
+5 -1
View File
@@ -43,4 +43,8 @@ release/
web-dist/
# Legacy Code (if applicable)
legacy/
legacy/
# VitePress
**/.vitepress/cache/
**/.vitepress/dist/
+12 -305
View File
@@ -10,324 +10,31 @@
![Vitest](https://img.shields.io/badge/Vitest-Testing-green?style=flat\&logo=vitest)
A **scalable, enterprise-ready Web & Desktop monorepo** built with **Turborepo**, **pnpm**, **Vite**, and **Electron**.
This repository is designed for long-term maintainability, featuring:
* Shared logic and UI libraries
* Centralized tooling configuration
* Turbo-powered task orchestration and caching
* Native desktop distribution with auto-updates
* Dedicated documentation & component playground using Storybook
This repository is designed for long-term maintainability, featuring shared logic and UI libraries, centralized tooling configuration, turbo-powered task orchestration, and native desktop distribution with auto-updates.
---
## 📂 Repository Structure
## 🌍 Global Context
The monorepo is organized into **Apps** (deployable applications) and **Packages** (shared libraries).
This repository utilizes a monorepo architecture to seamlessly share core systems, business logic, and UI components across multiple distribution targets (Web, Desktop, and Landing Page).
```text
.
├── apps/
│ ├── web/ # Main React Application (Vite + TypeScript)
│ ├── landing/ # Public Promotional SPA (Vite + TypeScript)
│ ├── desktop/ # Electron Desktop Wrapper (electron-vite)
│ └── docs-dev/ # Component Documentation & Playground (Storybook)
├── packages/
│ ├── core-api/ # Shared HTTP Client, Observability & Data Services Engine
│ ├── core-storage/ # Enterprise Storage Engine (IndexedDB/localStorage + Encryption)
│ ├── core-i18n/ # Enterprise Internationalization Architecture
│ ├── ui/ # Shared UI Component Library
│ ├── utils/ # Shared Utilities (Date, Encryption, Core Logic, etc)
│ └── configs/ # Shared Tooling Configurations
│ ├── eslint/ # Shared ESLint rules
│ └── typescript/ # Shared TypeScript (tsconfig) bases
├── package.json # Root scripts and dependencies
├── pnpm-workspace.yaml # pnpm workspace definition
└── turbo.json # Turborepo pipeline configuration
```
### Topology Overview
* **`apps/`**: Deployable applications (`web`, `desktop`, `landing`, `docs-dev`).
* **`packages/`**: Shared libraries and core engines (`core-api`, `core-storage`, `ui`, `utils`, `configs`, etc.).
---
## 🚀 Getting Started
### Prerequisites
Ensure your local environment matches the following versions to avoid compatibility issues:
* **Node.js**: `v20+` (tested with `v24.11.1`) — required for the `--import tsx` flag used by the desktop prebuild script
* **pnpm**: `v8.15.6`
(Enforced via the `packageManager` field in `package.json`)
### Installation
Install all dependencies from the **root directory**:
```bash
pnpm install
```
---
## 🛠 Usage & Scripts
This repository uses **Turborepo** to orchestrate tasks efficiently. All commands are executed from the root.
### Development
| Command | Description |
| -------------------- | ---------------------------------------------------------------------------------- |
| `pnpm dev` | Start **all applications** (`web` and `docs-dev`) in parallel |
| `pnpm dev:web` | Start only the **Main Web App** (strictly at `http://localhost:5173`) |
| `pnpm dev:landing` | Start the **Public Landing App** (strictly at `http://localhost:3000`) |
| `pnpm dev:docs-dev` | Start **Storybook** for UI development (strictly at `http://localhost:6006`) |
| `pnpm dev:desktop` | Start the **Web App + Electron** in parallel for desktop development |
> [!NOTE]
> **Port Topology**: `electron-vite` dynamically allocates a background port (usually `5174`) for its internal renderer shell during `pnpm dev:desktop`. We strictly isolate `web` (`5173`) and `landing` (`3000`) onto separate port ranges to prevent race conditions during parallel execution.
### Building & Quality
| Command | Description |
| --------------------- | ------------------------------------------------------- |
| `pnpm build` | Build all apps and packages using Turbo cache |
| `pnpm build:web` | Build only the web application |
| `pnpm build:landing` | Build only the landing page |
| `pnpm build:docs-dev` | Build only the docs-dev application |
| `pnpm build:desktop` | Build the web app, then compile the Electron app |
| `pnpm test` | Run unit tests (Vitest) across all packages |
| `pnpm lint` | Run ESLint across the workspace |
| `pnpm format` | Format code using Prettier |
### 🚀 Desktop Packaging & Distribution
To package the application into a production-ready installer, use the following commands from the **root directory**:
| Command | Platform | Output Artifact |
| ---------------------- | ----------- | ------------------------------------------ |
| `pnpm package:desktop` | Current OS | Detects host OS and builds accordingly |
| `pnpm package:mac` | macOS | `.dmg` and `.zip` (supports x64 & arm64) |
| `pnpm package:win` | Windows | `.exe` (NSIS Installer) |
| `pnpm package:linux` | Linux | `.AppImage` |
## 📚 Single Source of Truth
> [!IMPORTANT]
> **Build Sequence**: All `package:*` commands execute the following pipeline automatically:
>
> 1. **`turbo run build --filter=web`** — Compiles the React SPA into `apps/web/dist/`.
> 2. **`prebuild` hook** — Runs `node --import tsx scripts/copy-web-dist.ts`, which copies `apps/web/dist/` → `apps/desktop/web-dist/`.
> 3. **`electron-builder`** — Bundles `web-dist/` into the packaged app via the `files` and `extraResources` blocks in `electron-builder.yml`.
>
> You do not need to run these steps manually — they are chained via npm scripts.
> **Internal Documentation Hub**
> All documentation, installation guides, architectural deep-dives, and API references are hosted internally via our VitePress application.
> [!WARNING]
> **macOS Code Signing**: To build a distributable macOS app with Auto-Update support, you **must** have an Apple Developer Certificate and provide `CSC_LINK` and `CSC_KEY_PASSWORD` in your environment. Without code signing, macOS Gatekeeper will block the app and auto-updates will fail. See [AUTO_UPDATER.md](apps/desktop/docs/AUTO_UPDATER.md) for details.
> [!NOTE]
> **Cross-Compilation**: It is highly recommended to build for Windows on a Windows machine and for macOS on a Mac. Cross-compilation (e.g., building `.dmg` on Linux) may fail due to platform-specific toolchain dependencies. Use a CI matrix strategy (e.g., GitHub Actions with `runs-on: [macos-latest, windows-latest, ubuntu-latest]`) for multi-platform releases.
---
## 📦 Packages Overview
### 1. `apps/web`
The main consumer-facing application.
* Imports business logic from `@repo/utils`
* Uses shared UI components from `@repo/ui`
**Tech Stack**:
* React
* Vite
* TypeScript
* Tailwind CSS
---
### 2. `apps/desktop`
The **Electron desktop wrapper** that embeds `apps/web` for native desktop experiences.
* In **development**: loads the Vite dev server with full hot reload
* In **production**: serves the static web build via a secure custom `app://` protocol
* Configurable target app via `.env` (can wrap `apps/web`, `apps/docs-dev`, or any future app)
**Tech Stack**:
* Electron 33.x
* electron-vite
* electron-builder
* electron-updater
**Key Capabilities**:
| Feature | Description |
|---|---|
| 🖨️ Native Printing | Silent and direct printing via secure IPC bridge |
| 🔄 Auto-Updates | Background downloads via GitHub Releases (switchable to S3) |
| 🔒 Secure IPC Bridge | `contextIsolation: true`, `nodeIntegration: false`, `sandbox: true` |
| 🌐 Custom Protocol | `app://` serves static files with SPA routing fallback to `index.html` |
| 🛡️ CORS Bypass | Transparent Origin header rewriting for cloud API calls |
**Desktop Documentation**:
| Document | Contents |
|---|---|
| [CONFIGURATION.md](apps/desktop/docs/CONFIGURATION.md) | Target app switching, `app://` protocol internals, HashRouter fallback |
| [AUTO_UPDATER.md](apps/desktop/docs/AUTO_UPDATER.md) | Release workflow, CI/CD variables, provider switching, code signing |
| [IPC_ARCHITECTURE.md](apps/desktop/docs/IPC_ARCHITECTURE.md) | Security model, Three-Step Bridge pattern, extending native features |
---
### 3. `apps/landing`
The **public promotional website** — a standalone SPA for the company profile and marketing pages.
* Deployed independently to the web (e.g., Vercel) — no interaction with Electron
* Consumes shared UI components from `@repo/ui` and utilities from `@repo/utils`
* Locked to port **3000** (`strictPort: true`) — evacuated from the `517x` range to avoid `electron-vite` port collisions
**Tech Stack**:
* React
* Vite
* TypeScript
* Tailwind CSS v4
---
### 4. `apps/docs-dev` (Storybook)
An isolated environment for developing and documenting UI components.
* Ensures components in `@repo/ui` are built and tested independently
* Acts as a living design system and playground
---
### 5. `packages/core-api`
The **platform-agnostic API engine** for the monorepo. Provides an isolated HTTP client factory, a unified observability pipeline (Grafana Faro + OpenTelemetry), and a generic data services engine.
* Consumed by `apps/web`, `apps/landing`, and any future workspace
* Centralizes all `@grafana/faro-*` and `@opentelemetry/*` dependencies
* Provides plug-and-play telemetry via `initTelemetry()` + `faroAdapter`
**Tech Stack**:
* Axios (isolated instances, zero singleton pollution)
* Grafana Faro (RUM, Logs, Error tracking)
* OpenTelemetry (custom spans, distributed tracing)
* TypeScript (strict types, module augmentation)
**Key Capabilities**:
| Feature | Description |
|---|---|
| 🏭 HTTP Client Factory | `createHttpClient()` — per-app isolated Axios instances with interceptor hooks |
| 📡 Faro/Loki Baseline | Every request automatically pushes structured logs with `module.key` and `module.action` |
| 🎯 Custom Spans (Opt-In) | `telemetryContext.customSpanName` creates explicit OTel spans visible in Grafana Tempo |
| 🛡️ Error Normalization | `ApiError.fromAxiosError()` — structured, serializable error codes for all failure modes |
| 📦 Data Services Engine | `CommonRemoteDataServices` — full CRUD + lifecycle operations with zero boilerplate |
**Documentation**:
| Document | Contents |
|---|---|
| [README.md](packages/core-api/README.md) | Architecture, HTTP client setup, observability strategy, data services, app integration guide |
---
### 6. `packages/core-storage`
The **Enterprise-grade storage engine** for the monorepo.
Provides a unified, Promise-based interface for interacting with browser storage (`localStorage` and `IndexedDB`). Enforces strict type safety, prevents key collisions via a centralized registry, and automatically provides **AES encryption at rest** for sensitive payloads using `@repo/utils`.
**Documentation**: [README.md](packages/core-storage/README.md)
---
### 7. `packages/core-i18n`
The **Enterprise Internationalization Architecture** for the monorepo.
Provides a Hybrid Namespace Architecture combining a centralized i18n engine with decentralized, lazy-loaded feature dictionaries. Features strict TypeScript typings (including nested keys), optional backend synchronization with automatic error rollbacks, and a deep-merge mechanism for dynamic tenant-specific vocabulary overrides.
**Key Capabilities**:
| Feature | Description |
|---|---|
| 🌐 Hybrid Namespaces | Centralized `common` corpus + lazy-loaded feature dictionaries. |
| 🛡️ Strict Typings | Native TS autocomplete for nested paths (e.g., `header.title`) via module augmentation. |
| 🔄 Safe Backend Sync | `changeLanguage` accepts a `syncCallback` with built-in rollback if the API fails. |
| 🏢 Tenant Overrides | `applyTenantOverrides` performs a partial deep-merge to selectively override terminology. |
**Documentation**: [README.md](packages/core-i18n/README.md)
---
### 8. `packages/core-events`
The **decoupled Nervous System** for the monorepo.
Provides a highly performant, strictly typed Event Bus (Pub/Sub) powered by `mitt`. It allows independent modules to communicate seamlessly without tightly coupling their codebases or triggering expensive global React tree re-renders.
**Key Capabilities**:
| Feature | Description |
|---|---|
| 🧩 Zero Coupling | Publishers and subscribers interact via blind events, eliminating direct module imports and circular dependencies. |
| ⚡ Extreme Performance | Enables targeted DOM updates for high-frequency data streams (e.g., WebSockets) without re-rendering parent components. |
| 🧹 Memory Safety | Native `useAppEvent` hook automatically unsubscribes on component unmount, preventing SPA memory leaks. |
| 🛡️ Strict Contracts | Centralized `events.registry.ts` enforces payload shapes via TypeScript, ensuring cross-module data safety. |
**Documentation**: [README.md](packages/core-events/README.md)
---
### 9. `packages/utils`
Shared business logic and reusable utility modules that can be consumed across multiple applications. Fully tested using Vitest.
This package is intended to hold non-UI, cross-cutting logic such as date/time handling, security helpers, and other common utilities. It is designed to be framework-agnostic, predictable, and easy to extend as the system evolves.
---
### 10. `packages/ui`
Shared UI component library (Buttons, Inputs, Cards, Layouts) with a comprehensive **Form UI Library**.
* Ensures consistent design across all applications
* Designed to be consumed by both web apps and Storybook
* **Form UI Library**: 22 RHF-connected Mantine form components with Zod validation and i18n error translation, built via a `withRHF()` HOC factory with `useController` micro-subscriptions and `React.memo` optimization for ERP-scale forms
**Documentation**: [README.md](packages/ui/README.md) · [Form Components Guide](packages/ui/docs/FORM-COMPONENTS.md)
---
### 11. `packages/configs`
Single source of truth for tooling configuration.
* **eslint-config**: Shared ESLint rules (React, libraries, Storybook)
* **typescript-config**: Shared `tsconfig.json` base configurations
---
## ⚙️ Configuration & Environment
### Turborepo Caching
This repository uses **Turborepo caching** for builds, tests, and other artifacts.
To fully clean the workspace (dependencies, build outputs, and Turbo cache):
**To access the documentation and get started, run:**
```bash
rm -rf node_modules **/*/node_modules .turbo **/*/.turbo dist **/*/dist out **/*/out web-dist **/*/web-dist release **/*/release
pnpm --filter docs-dev dev
```
---
-29
View File
@@ -1,29 +0,0 @@
**Role:** You are a Staff Level React Engineer and Architect managing a highly scalable Enterprise ERP monorepo.
**Context:**
We have successfully established our Form UI library in `packages/ui/src/components/Form/fields` featuring 22 Mantine form components wrapped with React Hook Form (e.g., `FieldTextInput`, `FieldSelect`, `FieldColorPicker`, etc.). We also have a Zod validation layer at `packages/ui/src/validators` that uses JSON-stringified payloads for i18n translation.
We now need to build a showcase/demo page in the main web application to test and demonstrate these components in a real-world ERP form scenario.
**Pre-Execution Analysis (READ THESE FIRST):**
Before writing any code, you MUST read and analyze:
1. The component signatures and exports in `packages/ui/src/components/Form/index.ts`.
2. The Zod validator pattern in `packages/ui/src/validators` (specifically how the JSON i18n payloads are structured).
3. The existing layout and routing patterns in `apps/web/src/apps/showcase/showcase-view.tsx` to understand how to correctly inject and mount new showcase features.
**Task Requirements:**
**Phase 1: Create the Form Showcase Component**
1. Create a new comprehensive demo component inside `apps/web/src/apps/showcase/example/features/`. Follow the existing file naming convention found in that directory.
2. The component should implement a realistic ERP form (e.g., Textile Production Order, Inventory Bulk Update, or User Registration) using `useForm`, `zodResolver`, and a custom Zod schema.
3. The Zod schema MUST utilize the JSON-stringified i18n message pattern for validation errors.
4. Utilize a diverse set of our generated UI components (text input, select, number input, color input/picker, etc.) to prove they function correctly in a unified form.
5. Include a visual output panel (e.g., using Mantine's `Code` or `Pre` component) that displays the validated JSON payload upon successful submission.
**Phase 2: Connect to Showcase View**
1. Update `apps/web/src/apps/showcase/showcase-view.tsx` to import and render the newly created Form Showcase component.
2. Integrate it seamlessly into the existing UI layout of the showcase view (e.g., adding a new Tab, Accordion, or Section dedicated to the Form UI & Validation Layer).
**Execution Rules:**
- Do not rely on hardcoded assumptions. Let your code be guided completely by the patterns, styles, and typings you discover during the Pre-Execution Analysis.
- Ensure all TypeScript typings are strict.
- Output the newly created files and the modified files cleanly.
-38
View File
@@ -1,38 +0,0 @@
import { dirname, join, resolve } from 'path';
function getAbsolutePath(value) {
return dirname(require.resolve(join(value, 'package.json')));
}
const config = {
stories: ['../stories/*.stories.tsx', '../stories/**/*.stories.tsx'],
addons: [getAbsolutePath('@storybook/addon-links'), getAbsolutePath('@storybook/addon-essentials')],
framework: {
name: getAbsolutePath('@storybook/react-vite'),
options: {},
},
core: {},
async viteFinal(config, { configType }) {
// customize the Vite config here
return {
...config,
define: { 'process.env': {} },
resolve: {
alias: [
{
find: 'ui',
replacement: resolve(__dirname, '../../../packages/ui/'),
},
],
},
};
},
docs: {
autodocs: true,
},
};
export default config;
+10 -15
View File
@@ -1,33 +1,28 @@
{
"name": "docs-dev",
"name": "@repo/docs-dev",
"version": "0.0.0",
"type": "module",
"private": true,
"scripts": {
"dev": "storybook dev -p 6006",
"build": "storybook build --docs",
"preview-storybook": "serve storybook-static",
"clean": "rm -rf .turbo node_modules",
"lint": "eslint ./stories/*.stories.tsx --max-warnings 0"
"dev": "vitepress dev src --port 6060",
"build": "vitepress build src",
"serve": "vitepress serve src --port 6060",
"clean": "rm -rf .turbo node_modules src/.vitepress/dist src/.vitepress/cache"
},
"dependencies": {
"@repo/ui": "workspace:*",
"dayjs": "^1.11.19",
"react": "^19.2.3",
"react-dom": "^19.2.3"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@storybook/addon-actions": "^8.2.6",
"@storybook/addon-essentials": "^8.2.6",
"@storybook/addon-links": "^8.2.6",
"@storybook/react": "^8.2.6",
"@storybook/react-vite": "^8.2.6",
"@vitejs/plugin-react": "^5.1.2",
"eslint": "^8.57.0",
"serve": "^14.2.1",
"storybook": "^8.2.6",
"mermaid": "^11.15.0",
"typescript": "5.5.4",
"vite": "^5.1.4"
"vitepress": "^1.6.4",
"vitepress-plugin-mermaid": "^2.0.17",
"vue": "^3.5.38"
}
}
+84
View File
@@ -0,0 +1,84 @@
import { defineConfig } from 'vitepress'
import { withMermaid } from 'vitepress-plugin-mermaid'
const config = withMermaid(
defineConfig({
title: "Frontend Monorepo Docs",
description: "Centralized documentation for the Enterprise Frontend Monorepo",
themeConfig: {
nav: [
{ text: 'Docs', link: '/overview' },
],
sidebar: [
{
text: 'Introduction',
items: [
{ text: 'Overview', link: '/overview' },
{ text: 'Local Setup', link: '/setup' },
],
},
{
text: 'Core Architecture & State',
collapsed: false,
items: [
{ text: 'Core API Engine', link: '/packages/core-api/' },
{ text: 'Core Events', link: '/packages/core-events/' },
{ text: 'Core Storage', link: '/packages/core-storage/' },
{ text: 'Core Internationalization', link: '/packages/core-i18n/' },
{ text: 'IPC Architecture', link: '/apps/desktop/IPC_ARCHITECTURE' },
],
},
{
text: 'UI System & Layouts',
collapsed: false,
items: [
{ text: 'UI Components Overview', link: '/packages/ui/' },
{ text: 'Core App Shell', link: '/packages/ui/CORE-APP-SHELL' },
{ text: 'Form Components', link: '/packages/ui/FORM-COMPONENTS' },
],
},
{
text: 'Applications & Configuration',
collapsed: false,
items: [
{ text: 'Desktop Application', link: '/apps/desktop/' },
{ text: 'Desktop Configuration', link: '/apps/desktop/CONFIGURATION' },
{ text: 'Desktop Auto Updater', link: '/apps/desktop/AUTO_UPDATER' },
],
},
],
outline: { level: [2, 3] },
socialLinks: [],
},
// Mermaid configuration
mermaid: {
theme: 'default',
},
// Fix cascading CJS/ESM SyntaxErrors caused by Vite dynamically discovering mermaid
vite: {
optimizeDeps: {
include: [
'mermaid'
]
}
}
})
);
// Pnpm strict workspace workaround:
// vitepress-plugin-mermaid aggressively injects sub-dependencies into optimizeDeps.include.
// Because pnpm uses strict symlinks, Vite fails to resolve these sub-dependencies from the project root,
// causing pre-bundling to fail and cascading CJS/ESM SyntaxErrors in the browser.
// We strip them out so esbuild can naturally inline them into the 'mermaid' chunk instead.
if (config.vite?.optimizeDeps?.include) {
config.vite.optimizeDeps.include = config.vite.optimizeDeps.include.filter(
(dep) => !['@braintree/sanitize-url', 'debug', 'cytoscape-cose-bilkent', 'cytoscape'].includes(dep)
);
}
export default config;
@@ -1,4 +1,3 @@
[← Back to Root](../../../README.md)
# Desktop Auto-Update System
@@ -110,7 +109,8 @@ pnpm run prebuild
GH_TOKEN=your_token electron-builder --publish always --config electron-builder.yml
```
> [!CAUTION] > **Treat `GH_TOKEN` as a critical secret.** It grants write access to your repository's release assets. Never commit it to version control, never log it in CI output, and always inject it via encrypted secrets or a vault.
> [!CAUTION]
> **Treat `GH_TOKEN` as a critical secret.** It grants write access to your repository's release assets. Never commit it to version control, never log it in CI output, and always inject it via encrypted secrets or a vault.
### Automated Release (GitHub Actions)
@@ -172,7 +172,7 @@ jobs:
1. Navigate to **Settings → Secrets and variables → Actions** in your GitHub repository.
2. Add each variable as a **Repository secret**.
3. Reference them in workflow files as `${{ secrets.VARIABLE_NAME }}`.
3. Reference them in workflow files as <code v-pre>${{ secrets.VARIABLE_NAME }}</code>.
---
@@ -228,7 +228,8 @@ publish:
Your server must host the same directory structure as the S3 layout above.
> [!IMPORTANT] > **MIME Type Configuration**: Ensure your file server correctly serves `.yml` files with `text/yaml` and installer binaries with `application/octet-stream`. Incorrect MIME types will cause download corruption or silent update failures.
> [!IMPORTANT]
> **MIME Type Configuration**: Ensure your file server correctly serves `.yml` files with `text/yaml` and installer binaries with `application/octet-stream`. Incorrect MIME types will cause download corruption or silent update failures.
**Nginx reference:**
@@ -255,7 +256,8 @@ server {
## 🛡️ Code Signing: The Trust Boundary
> [!WARNING] > **Code signing is not merely a requirement — it is the Trust Boundary established by the operating system.** macOS Gatekeeper will explicitly terminate unsigned applications or refuse background updates to maintain system integrity. Windows SmartScreen will display alarming warnings to users. Without valid signatures, `electron-updater` will **reject update payloads entirely**.
> [!WARNING]
> **Code signing is not merely a requirement — it is the Trust Boundary established by the operating system.** macOS Gatekeeper will explicitly terminate unsigned applications or refuse background updates to maintain system integrity. Windows SmartScreen will display alarming warnings to users. Without valid signatures, `electron-updater` will **reject update payloads entirely**.
### macOS
@@ -1,4 +1,3 @@
[← Back to Root](../../../README.md)
# Desktop Configuration Guide
@@ -1,10 +1,21 @@
[← Back to Root](../../../README.md)
---
outline: [2, 3]
---
# IPC Architecture & Security Model
The Secure Communication Blueprint.
> **Scope**: Electron Main ↔ Renderer process communication
> **Enforcement Level**: Mandatory — deviations constitute security violations
> This document defines the **Hardened Security Perimeter** and communication topology governing the Desktop Wrapper. Every native capability exposed to the renderer is mediated through a **Non-Bypassable IPC Bridge**, ensuring that the Node.js Main Process remains cryptographically and logically isolated from untrusted web content. Adherence to this document is **mandatory** — deviations constitute security violations subject to immediate remediation.
This document defines the **hardened security perimeter** and communication topology governing the Desktop Wrapper. Every native capability exposed to the Renderer is mediated through a **non-bypassable IPC bridge**, enforcing strict privilege separation between the Node.js Main Process and untrusted web content.
The architecture operates on three invariants:
| Invariant | Guarantee |
|---|---|
| **Context Encapsulation** | The Preload Script executes in a hermetically sealed V8 context, isolated from both Main Process globals and the Renderer DOM. |
| **Interface Narrowing** | Only explicitly declared, type-safe API surfaces are exposed via `contextBridge`. No wildcard access patterns exist. |
| **Deterministic Lifecycle** | All IPC subscriptions are paired with unsubscribe functions, tying native event listeners to React's component lifecycle to prevent memory leaks. |
---
@@ -96,7 +107,8 @@ These settings are declared in `BrowserWindow.webPreferences` and are **non-nego
Every native feature in this architecture **must** follow the Three-Step Bridge — a Standard Operating Procedure (SOP) that ensures traceability, type-safety, and auditability across the entire IPC surface.
> [!IMPORTANT] > **Deterministic Synchronization**: Maintaining parity between the Main Process handler, the Preload Gateway exposure, and the TypeScript interface declaration is **mandatory**. A mismatch between any two of the three layers will result in either a **Type-Safety Gap** (silent failures in development) or a **Runtime Regression** (crashes in production).
> [!IMPORTANT]
> **Deterministic Synchronization**: Maintaining parity between the Main Process handler, the Preload Gateway exposure, and the TypeScript interface declaration is **mandatory**. A mismatch between any two of the three layers will result in either a **Type-Safety Gap** (silent failures in development) or a **Runtime Regression** (crashes in production).
### Step 1: Register the Handler — Main Process
@@ -102,7 +102,7 @@ All artifacts are emitted to the `release/` directory.
> APPLE_APP_SPECIFIC_PASSWORD=<app-specific password>
> APPLE_TEAM_ID=<team id>
> ```
> Without valid code signing, macOS Gatekeeper will quarantine the application and `electron-updater` will reject update payloads. See [docs/AUTO_UPDATER.md](docs/AUTO_UPDATER.md) for the complete requirements.
> Without valid code signing, macOS Gatekeeper will quarantine the application and `electron-updater` will reject update payloads. See [AUTO_UPDATER.md](./AUTO_UPDATER.md) for the complete requirements.
> [!NOTE]
> **Cross-Compilation Advisory**: It is strongly recommended to build for each platform on its native OS. Cross-compilation (e.g., producing `.dmg` on Linux) may fail due to platform-specific toolchain dependencies. For CI, leverage a matrix strategy:
@@ -124,7 +124,7 @@ DESKTOP_TARGET_APP=web
DESKTOP_DEV_SERVER_URL=http://localhost:5173
```
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for comprehensive guidance on target app switching, protocol internals, and the HashRouter fallback procedure.
See [CONFIGURATION.md](./CONFIGURATION.md) for comprehensive guidance on target app switching, protocol internals, and the HashRouter fallback procedure.
---
@@ -140,7 +140,7 @@ Enables granular control over system peripherals — such as printers — throug
### 🔄 Auto-Update Engine
A fully managed update lifecycle powered by `electron-updater`. Background download progress is forwarded in real-time to the React UI via IPC event subscriptions, enabling rich notification experiences. See [docs/AUTO_UPDATER.md](docs/AUTO_UPDATER.md).
A fully managed update lifecycle powered by `electron-updater`. Background download progress is forwarded in real-time to the React UI via IPC event subscriptions, enabling rich notification experiences. See [AUTO_UPDATER.md](./AUTO_UPDATER.md).
### 🛡️ CORS Bypass Proxy
@@ -173,7 +173,7 @@ The Desktop Wrapper enforces a **hardened security perimeter**, strictly isolati
- **Origin Sanitization**`session.defaultSession.webRequest` intercepts all outgoing requests, stripping `app://` / `file://` Origin headers to prevent backend CORS rejections.
- **Navigation Guard** — The `will-navigate` event intercepts and blocks all navigation attempts to URLs outside the `app://` protocol and the authorized dev server origin.
See [docs/IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) for the full security model, the Three-Step Bridge pattern, and guidance on safely extending the app with new native features.
See [IPC_ARCHITECTURE.md](./IPC_ARCHITECTURE.md) for the full security model, the Three-Step Bridge pattern, and guidance on safely extending the app with new native features.
---
@@ -181,6 +181,6 @@ See [docs/IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) for the full security m
| Document | Scope |
|---|---|
| [CONFIGURATION.md](docs/CONFIGURATION.md) | Target app switching, `app://` protocol internals, HashRouter fallback procedure |
| [AUTO_UPDATER.md](docs/AUTO_UPDATER.md) | Release lifecycle, CI/CD variables, provider switching, code signing |
| [IPC_ARCHITECTURE.md](docs/IPC_ARCHITECTURE.md) | Security model, Three-Step Bridge pattern, existing IPC channels, extensibility guide |
| [CONFIGURATION.md](./CONFIGURATION.md) | Target app switching, `app://` protocol internals, HashRouter fallback procedure |
| [AUTO_UPDATER.md](./AUTO_UPDATER.md) | Release lifecycle, CI/CD variables, provider switching, code signing |
| [IPC_ARCHITECTURE.md](./IPC_ARCHITECTURE.md) | Security model, Three-Step Bridge pattern, existing IPC channels, extensibility guide |
+21
View File
@@ -0,0 +1,21 @@
---
layout: home
hero:
name: "Frontend Monorepo Template Docs"
text: "Centralized Documentation Engine"
tagline: "Enterprise-ready Web & Desktop architecture documentation."
actions:
- theme: brand
text: Get Started
link: /packages/core-api/
- theme: alt
text: UI Components
link: /packages/ui/
features:
- title: Centralized Source of Truth
details: All documentation for apps and packages is unified here.
- title: Markdown Powered
details: Simple to maintain and read.
- title: Built with VitePress
details: Fast, responsive, and reliable documentation engine.
---
+95
View File
@@ -0,0 +1,95 @@
# Monorepo Architecture Overview
## 📂 Repository Structure
The monorepo is organized into **Apps** (deployable applications) and **Packages** (shared libraries).
```text
.
├── apps/
│ ├── web/ # Main React Application (Vite + TypeScript)
│ ├── landing/ # Public Promotional SPA (Vite + TypeScript)
│ ├── desktop/ # Electron Desktop Wrapper (electron-vite)
│ └── docs-dev/ # Component Documentation & Playground (VitePress)
├── packages/
│ ├── core-api/ # Shared HTTP Client, Observability & Data Services Engine
│ ├── core-storage/ # Enterprise Storage Engine (IndexedDB/localStorage + Encryption)
│ ├── core-i18n/ # Enterprise Internationalization Architecture
│ ├── ui/ # Shared UI Component Library
│ ├── utils/ # Shared Utilities (Date, Encryption, Core Logic, etc)
│ └── configs/ # Shared Tooling Configurations
│ ├── eslint/ # Shared ESLint rules
│ └── typescript/ # Shared TypeScript (tsconfig) bases
├── package.json # Root scripts and dependencies
├── pnpm-workspace.yaml # pnpm workspace definition
└── turbo.json # Turborepo pipeline configuration
```
## 📦 Packages Overview
### 1. `apps/web`
The main consumer-facing application.
* Imports business logic from `@repo/utils`
* Uses shared UI components from `@repo/ui`
**Tech Stack**: React, Vite, TypeScript, Tailwind CSS
### 2. `apps/desktop`
The **Electron desktop wrapper** that embeds `apps/web` for native desktop experiences.
* In **development**: loads the Vite dev server with full hot reload
* In **production**: serves the static web build via a secure custom `app://` protocol
* Configurable target app via `.env` (can wrap `apps/web`, `apps/docs-dev`, or any future app)
**Tech Stack**: Electron 33.x, electron-vite, electron-builder, electron-updater
### 3. `apps/landing`
The **public promotional website** — a standalone SPA for the company profile and marketing pages.
* Deployed independently to the web (e.g., Vercel) — no interaction with Electron
* Consumes shared UI components from `@repo/ui` and utilities from `@repo/utils`
* Locked to port **3000** (`strictPort: true`) — evacuated from the `517x` range to avoid `electron-vite` port collisions
### 4. `apps/docs-dev`
An isolated environment for developing and documenting UI components.
* Ensures components in `@repo/ui` are built and tested independently
* Acts as a living design system and playground
* Built with **VitePress**
### 5. `packages/core-api`
The **platform-agnostic API engine** for the monorepo. Provides an isolated HTTP client factory, a unified observability pipeline (Grafana Faro + OpenTelemetry), and a generic data services engine.
### 6. `packages/core-storage`
The **Enterprise-grade storage engine** for the monorepo.
Provides a unified, Promise-based interface for interacting with browser storage (`localStorage` and `IndexedDB`). Enforces strict type safety, prevents key collisions via a centralized registry, and automatically provides **AES encryption at rest** for sensitive payloads using `@repo/utils`.
### 7. `packages/core-i18n`
The **Enterprise Internationalization Architecture** for the monorepo.
Provides a Hybrid Namespace Architecture combining a centralized i18n engine with decentralized, lazy-loaded feature dictionaries. Features strict TypeScript typings (including nested keys), optional backend synchronization with automatic error rollbacks, and a deep-merge mechanism for dynamic tenant-specific vocabulary overrides.
### 8. `packages/core-events`
The **decoupled Nervous System** for the monorepo.
Provides a highly performant, strictly typed Event Bus (Pub/Sub) powered by `mitt`. It allows independent modules to communicate seamlessly without tightly coupling their codebases or triggering expensive global React tree re-renders.
### 9. `packages/utils`
Shared business logic and reusable utility modules that can be consumed across multiple applications. Fully tested using Vitest.
### 10. `packages/ui`
Shared UI component library (Buttons, Inputs, Cards, Layouts) with a comprehensive **Form UI Library**.
* Ensures consistent design across all applications
* Designed to be consumed by both web apps and docs
* **Form UI Library**: 22 RHF-connected Mantine form components with Zod validation and i18n error translation, built via a `withRHF()` HOC factory with `useController` micro-subscriptions and `React.memo` optimization for ERP-scale forms
### 11. `packages/configs`
Single source of truth for tooling configuration.
* **eslint-config**: Shared ESLint rules
* **typescript-config**: Shared `tsconfig.json` base configurations
## ⚙️ Configuration & Environment
### Turborepo Caching
This repository uses **Turborepo caching** for builds, tests, and other artifacts.
To fully clean the workspace (dependencies, build outputs, and Turbo cache):
```bash
rm -rf node_modules **/*/node_modules .turbo **/*/.turbo dist **/*/dist out **/*/out web-dist **/*/web-dist release **/*/release
```
@@ -1,4 +1,3 @@
[← Back to Root](../../README.md)
# Enterprise API Engine (`@repo/core-api`)
@@ -1,4 +1,3 @@
[← Back to Root](../../README.md)
# Event Bus (`@repo/core-events`)
@@ -1,4 +1,3 @@
[← Back to Root](../../README.md)
# i18n Architecture (`@repo/core-i18n`)
@@ -1,4 +1,3 @@
[← Back to Root](../../README.md)
# Storage Engine (`@repo/core-storage`)
@@ -1,4 +1,8 @@
# Core App Shell — Layout Engine Architecture & Usage Guide
---
outline: [2, 3]
---
# Core App Shell — Layout Engine
> **Package**: `@repo/ui` · **Module Path**: `@repo/ui/components`
> **Dependencies**: React 18+, Mantine v8 (`AppShell`), `@mantine/hooks`
@@ -74,7 +78,7 @@ packages/ui/src/components/core-app-shell/
└── index.ts # Barrel exports
```
**Source**: [`core-app-shell/`](../src/components/core-app-shell/)
**Source**: `packages/ui/src/components/core-app-shell/`
---
@@ -1,4 +1,8 @@
# Form UI Library — Architecture & Usage Guide
---
outline: [2, 3]
---
# Form UI Library
> **Package**: `@repo/ui` · **Module Path**: `@repo/ui/form`
> **Dependencies**: React Hook Form v7, Zod v3, Mantine v8, `@repo/core-i18n`
@@ -56,7 +60,7 @@ withRHF<MantineComponentProps>(displayName, MantineComponent, options?)
└── Preserves full Mantine TypeScript generics
```
**Source**: [`withRHF.tsx`](../src/components/Form/withRHF.tsx)
**Source**: `packages/ui/src/components/Form/withRHF.tsx`
The factory accepts three arguments:
@@ -22,7 +22,7 @@ The centralized UI component library for the monorepo. Provides consistent desig
## 📋 Form UI Library
> **Full Documentation**: [docs/FORM-COMPONENTS.md](docs/FORM-COMPONENTS.md)
> **Full Documentation**: [FORM-COMPONENTS.md](./FORM-COMPONENTS.md)
The Form UI Library wraps **all 22 applicable Mantine form components** with React Hook Form via a single `withRHF()` HOC factory. Key features:
+75
View File
@@ -0,0 +1,75 @@
# Local Development Setup
## 🚀 Getting Started
### Prerequisites
Ensure your local environment matches the following versions to avoid compatibility issues:
* **Node.js**: `v20+` (tested with `v24.11.1`) — required for the `--import tsx` flag used by the desktop prebuild script
* **pnpm**: `v8.15.6`
(Enforced via the `packageManager` field in `package.json`)
### Installation
Install all dependencies from the **root directory**:
```bash
pnpm install
```
## 🛠 Usage & Scripts
This repository uses **Turborepo** to orchestrate tasks efficiently. All commands are executed from the root.
### Development
| Command | Description |
| -------------------- | ---------------------------------------------------------------------------------- |
| `pnpm dev` | Start **all applications** (`web` and `docs-dev`) in parallel |
| `pnpm dev:web` | Start only the **Main Web App** (strictly at `http://localhost:5173`) |
| `pnpm dev:landing` | Start the **Public Landing App** (strictly at `http://localhost:3000`) |
| `pnpm dev:docs-dev` | Start **VitePress** for documentation development (strictly at `http://localhost:6060`) |
| `pnpm dev:desktop` | Start the **Web App + Electron** in parallel for desktop development |
> [!NOTE]
> **Port Topology**: `electron-vite` dynamically allocates a background port (usually `5174`) for its internal renderer shell during `pnpm dev:desktop`. We strictly isolate `web` (`5173`) and `landing` (`3000`) onto separate port ranges to prevent race conditions during parallel execution.
### Building & Quality
| Command | Description |
| --------------------- | ------------------------------------------------------- |
| `pnpm build` | Build all apps and packages using Turbo cache |
| `pnpm build:web` | Build only the web application |
| `pnpm build:landing` | Build only the landing page |
| `pnpm build:docs-dev` | Build only the docs-dev application |
| `pnpm build:desktop` | Build the web app, then compile the Electron app |
| `pnpm test` | Run unit tests (Vitest) across all packages |
| `pnpm lint` | Run ESLint across the workspace |
| `pnpm format` | Format code using Prettier |
### 🚀 Desktop Packaging & Distribution
To package the application into a production-ready installer, use the following commands from the **root directory**:
| Command | Platform | Output Artifact |
| ---------------------- | ----------- | ------------------------------------------ |
| `pnpm package:desktop` | Current OS | Detects host OS and builds accordingly |
| `pnpm package:mac` | macOS | `.dmg` and `.zip` (supports x64 & arm64) |
| `pnpm package:win` | Windows | `.exe` (NSIS Installer) |
| `pnpm package:linux` | Linux | `.AppImage` |
> [!IMPORTANT]
> **Build Sequence**: All `package:*` commands execute the following pipeline automatically:
>
> 1. **`turbo run build --filter=web`** — Compiles the React SPA into `apps/web/dist/`.
> 2. **`prebuild` hook** — Runs `node --import tsx scripts/copy-web-dist.ts`, which copies `apps/web/dist/` → `apps/desktop/web-dist/`.
> 3. **`electron-builder`** — Bundles `web-dist/` into the packaged app via the `files` and `extraResources` blocks in `electron-builder.yml`.
>
> You do not need to run these steps manually — they are chained via npm scripts.
> [!WARNING]
> **macOS Code Signing**: To build a distributable macOS app with Auto-Update support, you **must** have an Apple Developer Certificate and provide `CSC_LINK` and `CSC_KEY_PASSWORD` in your environment. Without code signing, macOS Gatekeeper will block the app and auto-updates will fail. See the Desktop documentation for details.
> [!NOTE]
> **Cross-Compilation**: It is highly recommended to build for Windows on a Windows machine and for macOS on a Mac. Cross-compilation (e.g., building `.dmg` on Linux) may fail due to platform-specific toolchain dependencies. Use a CI matrix strategy (e.g., GitHub Actions with `runs-on: [macos-latest, windows-latest, ubuntu-latest]`) for multi-platform releases.
-46
View File
@@ -1,46 +0,0 @@
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from '@repo/ui';
const meta: Meta<typeof Button> = {
component: Button,
argTypes: {
type: {
control: { type: 'radio' },
options: ['button', 'submit', 'reset'],
},
},
};
export default meta;
type Story = StoryObj<typeof Button>;
/*
*👇 Render functions are a framework specific feature to allow you control on how the component renders.
* See https://storybook.js.org/docs/react/api/csf
* to learn how to use render functions.
*/
export const Primary: Story = {
render: (props) => (
<Button
{...props}
onClick={(): void => {
// eslint-disable-next-line no-alert -- alert for demo
alert('Hello from Turborepo!');
}}
>
Hello
</Button>
),
name: 'Button',
args: {
children: 'Hello',
type: 'submit',
style: {
color: 'blue',
border: '1px solid gray',
padding: 10,
borderRadius: 10,
},
},
};
+7
View File
@@ -0,0 +1,7 @@
export default {
vite: {
optimizeDeps: {
include: ['@repo/ui', 'mermaid', 'dayjs']
}
}
}
+14
View File
@@ -0,0 +1,14 @@
import { defineConfig } from 'vitepress'
import { withMermaid } from 'vitepress-plugin-mermaid'
const baseConfig = withMermaid(
defineConfig({
title: "Test",
})
);
console.log("Before:", baseConfig.vite.optimizeDeps.include);
baseConfig.vite.optimizeDeps.include = baseConfig.vite.optimizeDeps.include.filter(
(dep) => !['@braintree/sanitize-url', 'debug', 'cytoscape-cose-bilkent', 'cytoscape'].includes(dep)
);
console.log("After:", baseConfig.vite.optimizeDeps.include);
-4
View File
@@ -1,4 +0,0 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({ plugins: [react()] });
+1517 -946
View File
File diff suppressed because it is too large Load Diff