|
| 1 | +--- |
| 2 | +title: System Design |
| 3 | +description: Complete system design document for ObjectDocs — architecture, technical decisions, and component overview. |
| 4 | +--- |
| 5 | + |
| 6 | +import { FileJson, Layers, Cpu, Zap, GitBranch, Package, Globe, Code } from 'lucide-react'; |
| 7 | + |
| 8 | +# System Design Document |
| 9 | + |
| 10 | +This document provides a comprehensive technical design overview of ObjectDocs, covering the system architecture, package structure, data flow, and key design decisions. |
| 11 | + |
| 12 | +**Version**: v0.2.12 | **Last Updated**: 2026-02-08 |
| 13 | + |
| 14 | +## 1. System Overview |
| 15 | + |
| 16 | +ObjectDocs is a **metadata-driven documentation engine** built on Next.js and Fumadocs, designed for the ObjectStack low-code ecosystem. It follows a strict **Configuration as Code** philosophy where documentation structure is defined by data (JSON), not code (React). |
| 17 | + |
| 18 | +### Design Goals |
| 19 | + |
| 20 | +<Cards> |
| 21 | +<Card icon={<FileJson />} title="Metadata-Driven"> |
| 22 | +Navigation, sidebars, and page ordering are defined entirely through `meta.json` files and `docs.site.json` configuration. Content creators never need to touch React code. |
| 23 | +</Card> |
| 24 | +<Card icon={<Layers />} title="Separation of Concerns"> |
| 25 | +The system strictly separates three layers: **Presentation** (React/Next.js site engine), **Configuration** (JSON files), and **Content** (MDX documents). |
| 26 | +</Card> |
| 27 | +<Card icon={<Package />} title="Monorepo Architecture"> |
| 28 | +The project is organized as a pnpm workspace monorepo with two core packages (`@objectdocs/cli` and `@objectdocs/site`) plus a shared content layer. |
| 29 | +</Card> |
| 30 | +<Card icon={<Globe />} title="i18n-First"> |
| 31 | +Multi-language support is built into the core architecture, with language-specific MDX files and pre-built UI translations for 6 languages. |
| 32 | +</Card> |
| 33 | +</Cards> |
| 34 | + |
| 35 | +## 2. Architecture Overview |
| 36 | + |
| 37 | +### 2.1 High-Level Architecture |
| 38 | + |
| 39 | +```text |
| 40 | +┌─────────────────────────────────────────────────────────┐ |
| 41 | +│ ObjectDocs System │ |
| 42 | +├──────────────┬──────────────────┬───────────────────────┤ |
| 43 | +│ @objectdocs │ @objectdocs │ Content Layer │ |
| 44 | +│ /cli │ /site │ │ |
| 45 | +│ │ │ │ |
| 46 | +│ Commands: │ Next.js 16 + │ content/ │ |
| 47 | +│ • init │ Fumadocs 16 │ ├── docs.site.json │ |
| 48 | +│ • dev │ │ ├── docs/ │ |
| 49 | +│ • build │ App Router │ │ ├── meta.json │ |
| 50 | +│ • start │ React Server │ │ ├── index.mdx │ |
| 51 | +│ • translate │ Components │ │ └── ... │ |
| 52 | +│ │ │ └── public/ │ |
| 53 | +├──────────────┼──────────────────┼───────────────────────┤ |
| 54 | +│ CLI Layer │ Presentation │ Data Layer │ |
| 55 | +│ (Tooling) │ Layer │ (Configuration + │ |
| 56 | +│ │ (Rendering) │ Content) │ |
| 57 | +└──────────────┴──────────────────┴───────────────────────┘ |
| 58 | +``` |
| 59 | + |
| 60 | +### 2.2 Package Dependency Graph |
| 61 | + |
| 62 | +```text |
| 63 | +Root Workspace (objectdocs v1.0.0) |
| 64 | +├── @objectdocs/cli (v0.2.12) |
| 65 | +│ ├── depends on: @objectdocs/site (workspace:*) |
| 66 | +│ ├── cac (CLI framework) |
| 67 | +│ ├── openai (AI translation) |
| 68 | +│ └── dotenv (environment config) |
| 69 | +└── @objectdocs/site (v0.2.12) |
| 70 | + ├── next (^16.1.2) |
| 71 | + ├── fumadocs-core (^16.4.7) |
| 72 | + ├── fumadocs-ui (^16.4.7) |
| 73 | + ├── fumadocs-mdx (^14.2.5) |
| 74 | + ├── react (^19.2.3) |
| 75 | + ├── tailwindcss (^4.1.18) |
| 76 | + └── typescript (^5.9.3) |
| 77 | +``` |
| 78 | + |
| 79 | +## 3. Core Components |
| 80 | + |
| 81 | +### 3.1 CLI Package (`@objectdocs/cli`) |
| 82 | + |
| 83 | +The CLI is the primary developer interface for ObjectDocs. Built with the [CAC](https://github.com/cacjs/cac) framework, it provides 5 commands: |
| 84 | + |
| 85 | +| Command | Purpose | Key Behavior | |
| 86 | +|---------|---------|-------------| |
| 87 | +| `init` | Initialize a new docs project | Copies `@objectdocs/site` to `content/.fumadocs`, installs deps, updates `.gitignore` | |
| 88 | +| `dev` | Start development server | Runs on port 7777, watches `docs.site.json` for changes, syncs public assets | |
| 89 | +| `build` | Build for production | Supports both static export (`out/`) and dynamic standalone (`.next/`) modes | |
| 90 | +| `start` | Start production server | Static mode uses `serve`, dynamic mode uses Next.js server | |
| 91 | +| `translate` | AI-powered translation | Uses OpenAI API, supports `--all` flag, generates language-specific `.mdx` files | |
| 92 | + |
| 93 | +**Design Decision**: The CLI copies the entire `@objectdocs/site` package into `content/.fumadocs` during init rather than using it as a runtime dependency. This ensures complete isolation between the documentation engine and user content, and allows the site to be customized without affecting the package. |
| 94 | + |
| 95 | +### 3.2 Site Package (`@objectdocs/site`) |
| 96 | + |
| 97 | +The site package is a complete Next.js application template that serves as the documentation rendering engine. |
| 98 | + |
| 99 | +**Key Components**: |
| 100 | + |
| 101 | +| Component | File | Responsibility | |
| 102 | +|-----------|------|---------------| |
| 103 | +| Root Layout | `app/layout.tsx` | HTML shell, providers, global styles | |
| 104 | +| Language Router | `app/[lang]/layout.tsx` | i18n layout with Fumadocs provider | |
| 105 | +| Docs Pages | `app/[lang]/docs/[[...slug]]/page.tsx` | MDX rendering, TOC, navigation | |
| 106 | +| Search API | `app/api/search/route.ts` | Full-text search endpoint | |
| 107 | +| i18n Config | `lib/i18n.ts` | Language definitions and UI translations | |
| 108 | +| Site Config | `lib/config.ts` | Loads and merges `docs.site.json` | |
| 109 | +| Source Loader | `lib/source.ts` | Fumadocs content source with i18n | |
| 110 | + |
| 111 | +### 3.3 Content Layer |
| 112 | + |
| 113 | +The content layer is the user-facing data that defines the documentation site: |
| 114 | + |
| 115 | +```text |
| 116 | +content/ |
| 117 | +├── docs.site.json # Global site configuration |
| 118 | +│ ├── branding # Logo, name, theme colors |
| 119 | +│ ├── links # Navbar navigation links |
| 120 | +│ ├── sidebar # Sidebar behavior config |
| 121 | +│ ├── toc # Table of contents settings |
| 122 | +│ ├── footer # Footer copyright text |
| 123 | +│ ├── page # Per-page features (edit link, last update) |
| 124 | +│ ├── content # Content features (math, code theme) |
| 125 | +│ ├── i18n # Language configuration |
| 126 | +│ └── build # Build mode (export/standalone) |
| 127 | +├── public/ # Static assets (images, fonts) |
| 128 | +└── docs/ |
| 129 | + ├── meta.json # Root navigation structure |
| 130 | + ├── index.mdx # Homepage (English) |
| 131 | + ├── index.cn.mdx # Homepage (Chinese) |
| 132 | + └── getting-started/ |
| 133 | + ├── meta.json # Section page ordering |
| 134 | + ├── index.mdx # Section landing page |
| 135 | + └── ... |
| 136 | +``` |
| 137 | + |
| 138 | +## 4. Data Flow |
| 139 | + |
| 140 | +### 4.1 Build-Time Data Flow |
| 141 | + |
| 142 | +<Steps> |
| 143 | + |
| 144 | +### Content Discovery |
| 145 | +Fumadocs MDX source loader scans the `DOCS_DIR` directory for all `.mdx` files and `meta.json` files. Files are organized by language suffix (e.g., `.cn.mdx` for Chinese). |
| 146 | + |
| 147 | +### Configuration Merge |
| 148 | +The site reads `docs.site.json` from the content directory and merges it with default configuration values in `lib/config.ts`. This produces the complete site configuration. |
| 149 | + |
| 150 | +### Navigation Tree Construction |
| 151 | +`meta.json` files in each directory define the page ordering and section titles. Fumadocs builds a hierarchical navigation tree from these files. |
| 152 | + |
| 153 | +### MDX Compilation |
| 154 | +Each `.mdx` file is compiled through the Fumadocs MDX pipeline with remark/rehype plugins, producing React Server Components. |
| 155 | + |
| 156 | +### Static Generation |
| 157 | +Next.js App Router generates static pages for each route. In standalone mode, pages can be server-rendered with ISR support. |
| 158 | + |
| 159 | +</Steps> |
| 160 | + |
| 161 | +### 4.2 Runtime Data Flow |
| 162 | + |
| 163 | +```text |
| 164 | +User Request → Next.js Router → Language Detection → Page Resolution |
| 165 | + → MDX Content Rendering (RSC) → Fumadocs UI Layout → HTML Response |
| 166 | +``` |
| 167 | + |
| 168 | +### 4.3 Translation Data Flow |
| 169 | + |
| 170 | +```text |
| 171 | +Source MDX → CLI translate command → OpenAI API → Translated MDX |
| 172 | + → Language-specific file (e.g., .cn.mdx) → Content Discovery |
| 173 | +``` |
| 174 | + |
| 175 | +## 5. Configuration System Design |
| 176 | + |
| 177 | +### 5.1 `docs.site.json` Schema |
| 178 | + |
| 179 | +The site configuration file supports the following sections: |
| 180 | + |
| 181 | +```json |
| 182 | +{ |
| 183 | + "site": { |
| 184 | + "title": "Site title", |
| 185 | + "description": "Site description", |
| 186 | + "url": "https://example.com", |
| 187 | + "favicon": "/favicon.ico" |
| 188 | + }, |
| 189 | + "branding": { |
| 190 | + "name": "Brand Name", |
| 191 | + "logo": { "light": "/logo-light.svg", "dark": "/logo-dark.svg" }, |
| 192 | + "themeColor": "#7c3aed", |
| 193 | + "borderRadius": "0.5rem" |
| 194 | + }, |
| 195 | + "links": [{ "text": "Home", "url": "/" }], |
| 196 | + "sidebar": { "collapsible": true, "defaultOpenLevel": 1 }, |
| 197 | + "toc": { "enabled": true, "depth": 3 }, |
| 198 | + "footer": { "copyright": "© 2026" }, |
| 199 | + "page": { |
| 200 | + "lastUpdate": true, |
| 201 | + "editOnGithub": { "owner": "org", "repo": "repo" } |
| 202 | + }, |
| 203 | + "content": { "codeTheme": "vesper", "imageZoom": true }, |
| 204 | + "i18n": { |
| 205 | + "defaultLanguage": "en", |
| 206 | + "languages": ["en", "cn"] |
| 207 | + }, |
| 208 | + "build": { "mode": "export" } |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +### 5.2 `meta.json` Schema |
| 213 | + |
| 214 | +Each directory can contain a `meta.json` to control navigation: |
| 215 | + |
| 216 | +```json |
| 217 | +{ |
| 218 | + "title": "Section Title", |
| 219 | + "pages": ["page-a", "page-b", "sub-directory"] |
| 220 | +} |
| 221 | +``` |
| 222 | + |
| 223 | +**Key Rule**: Sidebar navigation is **never** defined in React components. All navigation structure changes go through `meta.json` files. |
| 224 | + |
| 225 | +## 6. i18n Architecture |
| 226 | + |
| 227 | +### 6.1 Supported Languages |
| 228 | + |
| 229 | +| Code | Language | UI Translations | |
| 230 | +|------|----------|----------------| |
| 231 | +| `en` | English | ✅ Complete | |
| 232 | +| `cn` | 中文 (Chinese) | ✅ Complete | |
| 233 | +| `ja` | 日本語 (Japanese) | ✅ Complete | |
| 234 | +| `fr` | Français (French) | ✅ Complete | |
| 235 | +| `de` | Deutsch (German) | ✅ Complete | |
| 236 | +| `es` | Español (Spanish) | ✅ Complete | |
| 237 | + |
| 238 | +### 6.2 Content Translation Strategy |
| 239 | + |
| 240 | +- **File-based**: Each language has its own MDX file (e.g., `index.mdx` for English, `index.cn.mdx` for Chinese) |
| 241 | +- **Fallback**: If a translated file doesn't exist, the default language version is used |
| 242 | +- **AI Translation**: The `translate` CLI command uses OpenAI to generate translations automatically |
| 243 | +- **URL Routing**: Language prefix in URL path (`/en/docs/...`, `/cn/docs/...`) |
| 244 | + |
| 245 | +## 7. Deployment Design |
| 246 | + |
| 247 | +### 7.1 Build Modes |
| 248 | + |
| 249 | +| Mode | Output | Use Case | |
| 250 | +|------|--------|----------| |
| 251 | +| `export` (Static) | `out/` directory with HTML/CSS/JS | CDN hosting, GitHub Pages, Vercel static | |
| 252 | +| `standalone` (Dynamic) | `.next/` with Node.js server | ISR, SSR, API routes, Vercel serverless | |
| 253 | + |
| 254 | +### 7.2 Vercel Deployment |
| 255 | + |
| 256 | +```text |
| 257 | +GitHub Push → Vercel Build Hook → pnpm build → Next.js Build |
| 258 | + → Static Assets + Serverless Functions → Edge CDN Distribution |
| 259 | +``` |
| 260 | + |
| 261 | +**Key Design Decisions**: |
| 262 | +- Standalone output mode for optimal Vercel serverless support |
| 263 | +- Symlink-aware artifact copying to handle monorepo structures |
| 264 | +- `vercel.json` routing configuration for clean URLs |
| 265 | +- Preview deployments via GitHub Actions workflow |
| 266 | + |
| 267 | +### 7.3 CI/CD Pipeline |
| 268 | + |
| 269 | +| Workflow | Trigger | Purpose | |
| 270 | +|----------|---------|---------| |
| 271 | +| `ci.yml` | Push/PR | Build validation | |
| 272 | +| `release.yml` | Push to main | Changesets NPM publishing | |
| 273 | +| `preview.yml` | PR | Vercel preview deployment | |
| 274 | +| `test-lifecycle.yml` | Push/PR | Full lifecycle testing | |
| 275 | +| `link-check.yml` | PR | Content link validation | |
| 276 | + |
| 277 | +## 8. Technology Stack |
| 278 | + |
| 279 | +| Layer | Technology | Version | |
| 280 | +|-------|-----------|---------| |
| 281 | +| Runtime | Next.js (App Router) | ^16.1.2 | |
| 282 | +| UI Framework | React (Server Components) | ^19.2.3 | |
| 283 | +| Documentation Engine | Fumadocs | ^16.4.7 | |
| 284 | +| Styling | Tailwind CSS | ^4.1.18 | |
| 285 | +| Language | TypeScript | ^5.9.3 | |
| 286 | +| Package Manager | pnpm | Workspace monorepo | |
| 287 | +| AI Integration | OpenAI API | ^4.0.0 | |
| 288 | +| CLI Framework | CAC | ^6.7.14 | |
| 289 | +| Content Format | MDX | Via fumadocs-mdx | |
| 290 | +| Deployment | Vercel | Serverless/Edge | |
| 291 | + |
| 292 | +## 9. Security Considerations |
| 293 | + |
| 294 | +- **No hardcoded secrets**: All API keys (e.g., OpenAI) are loaded via environment variables |
| 295 | +- **Server Components by default**: Minimizes client-side JavaScript exposure |
| 296 | +- **Content isolation**: Documentation content is separated from the rendering engine |
| 297 | +- **Dependency management**: Automated via Changesets with locked versions |
| 298 | + |
| 299 | +<Callout type="info"> |
| 300 | +This design document reflects the current state of ObjectDocs v0.2.12. It will be updated as the system evolves. For the feature roadmap, see the [Development Roadmap](/docs/development-plan). |
| 301 | +</Callout> |
0 commit comments