2:I[7012,["4765","static/chunks/4765-f5afdf8061f456f3.js","9856","static/chunks/9856-3b185291364d9bef.js","6687","static/chunks/app/docs/%5B...slug%5D/page-e07536548216bee4.js"],"MarkdownRenderer"]
4:I[9856,["4765","static/chunks/4765-f5afdf8061f456f3.js","9856","static/chunks/9856-3b185291364d9bef.js","6687","static/chunks/app/docs/%5B...slug%5D/page-e07536548216bee4.js"],""]
5:I[4126,[],""]
7:I[9630,[],""]
8:I[4278,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"HeadingProvider"]
9:I[1476,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"Header"]
a:I[3167,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"Sidebar"]
b:I[7409,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"PageFrame"]
3:T1d11,
# Documentation Site Specifications
## Current Implementation (Canonical)
### Deployment
| Property | Value |
| ------------- | ---------------------------- |
| **Domain** | https://assistdocs.asimo.io |
| **Framework** | Next.js 14 with App Router |
| **Export** | Static site generation (SSG) |
| **Hosting** | Apache (static files) |
| **Source** | `apps/docs-site/` |
### Technology Stack
- **Framework:** Next.js 14 (app router) with static export
- **Styling:** Tailwind CSS + shadcn/ui components
- **Content:** MDX for markdown with React components
- **Search:** Fuse.js client-side with `/search-index.json`
- **Code Highlighting:** Shiki
- **Diagrams:** Mermaid
- **Theme:** next-themes for dark mode
### Search Implementation
Search is fully implemented using Fuse.js for client-side fuzzy search:
```
apps/docs-site/
├── public/
│ └── search-index.json # Pre-built search index (~248K lines)
├── scripts/
│ └── generate-search-index.js # Builds index at build time
└── src/components/
└── SearchDialog.tsx # Cmd+K search interface
```
**Features:**
- Full-text search across all documentation
- Keyboard shortcut (Cmd+K / Ctrl+K)
- Fuzzy matching with relevance scoring
- Section and category filtering
---
## Agent JSON API
The docs site exposes structured JSON endpoints for AI agents:
| Endpoint | Description |
| -------------------- | -------------------------------- |
| `/agent/index.json` | Metadata & endpoint discovery |
| `/agent/docs.json` | Full documentation index (110K+) |
| `/agent/tasks.json` | Common debugging tasks |
| `/agent/schema.json` | JSON Schema definitions |
### Usage Example
```bash
# Fetch documentation index
curl https://assistdocs.asimo.io/agent/docs.json | jq '.docs | length'
# Get specific debugging task
curl https://assistdocs.asimo.io/agent/tasks.json | jq '.tasks[] | select(.id == "check-backend-health")'
```
---
## AI Integration
### Qdrant Vector Search
Documentation is embedded for semantic search:
| Property | Value |
| ------------------- | ---------------------- |
| **Collection** | `platform_docs` |
| **Embedding Model** | text-embedding-3-small |
| **Dimensions** | 1536 |
| **Distance Metric** | Cosine |
### AI Tools
```python
# docs_search - Semantic search across documentation
docs_search(query: str, category: str = None, max_results: int = 5)
# docs_get_section - Retrieve full section content
docs_get_section(doc_path: str, section: str = None)
```
### Embedding Pipeline
```bash
# Re-embed all documentation
python scripts/embed-docs.py --force
# Embed only changed files
python scripts/embed-docs.py --incremental
```
---
## Automation Scripts
### API & Type Sync Pipeline
| Script | Purpose | Command |
| ---------------------------- | ----------------------------------- | ------------------------- |
| `sync-openapi.mjs` | Fetch OpenAPI spec from api-gateway | `pnpm sync:openapi` |
| `generate-api-types.mjs` | Generate TypeScript types | `pnpm generate:api-types` |
| `validate-api-sync.mjs` | Check for undocumented endpoints | `pnpm validate:api-sync` |
| `extract-component-docs.mjs` | Extract TSDoc from packages/ui | (manual) |
### Validation Pipeline
| Script | Purpose | Command |
| ----------------------- | -------------------- | ------------------------- |
| `validate-metadata.mjs` | Validate frontmatter | `pnpm validate:metadata` |
| `check-links.mjs` | Find broken links | `pnpm check:links` |
| `check-freshness.mjs` | Detect stale docs | `pnpm check:freshness` |
| `docs-smoke-test.mjs` | Test doc endpoints | `pnpm validate:endpoints` |
### Build Pipeline
```bash
# Full validation
pnpm validate:all
# Generate search index + agent JSON
pnpm generate-search-index
pnpm generate-agent-json
# Build static site
pnpm build
# Package for deployment
pnpm deploy # Creates artifacts/docs-site.tar.gz
```
---
## CI Integration
### Workflow: `.github/workflows/docs-validation.yml`
Triggers on PRs touching:
- `docs/**`
- `services/api-gateway/**`
- `packages/ui/**`
- `apps/docs-site/**`
**Steps:**
1. `validate:metadata` - Frontmatter validation
2. `validate:api-sync --strict` - API coverage check (fails on undocumented)
3. `check:links` - Broken link detection
4. `check:freshness` - Stale doc detection (warns if >30 days)
5. `build` - Full site build
---
## Contextual Help Components
### HelpButton
Links to relevant documentation from any page:
```tsx
// Location: packages/ui/src/components/HelpButton.tsx
```
### AskAIButton
Opens dialog to ask questions with page context:
```tsx
// Location: apps/admin-panel/src/components/shared/AskAIButton.tsx
```
**Flow:**
1. User clicks "Ask AI" button
2. Dialog opens with text input
3. Page context pre-filled
4. Calls `/api/ai/docs/ask` endpoint
5. Returns response with doc citations
---
## Content Organization
### Directory Structure
```
docs/
├── overview/ # Architecture, status, getting started
├── phases/ # Implementation phases (1-14)
├── operations/ # DevOps, deployment, monitoring
├── debugging/ # Troubleshooting guides
├── client-impl/ # Client implementations
├── archive/ # Deprecated/historical docs
└── *.md # Top-level specs and guides
```
### Frontmatter Requirements
Every doc must include:
```yaml
---
title: "Page Title"
slug: "url-slug"
summary: "Brief description for search and previews"
status: stable|draft|deprecated
stability: production|beta|alpha
owner: backend|frontend|docs|mixed
lastUpdated: "YYYY-MM-DD"
audience: ["human", "agent"]
tags: ["tag1", "tag2"]
category: overview|reference|guide|debugging
---
```
---
## Environment Variables
```bash
# apps/docs-site/.env
NEXT_PUBLIC_SITE_URL=https://assistdocs.asimo.io
NEXT_PUBLIC_APP_URL=https://dev.asimo.io
NEXT_PUBLIC_ADMIN_URL=https://admin.asimo.io
NEXT_PUBLIC_API_URL=https://assist.asimo.io
```
---
## Historical Considerations (Archived)
The following were evaluated during planning but not implemented:
### Framework Alternatives
- **Docusaurus** - Considered for out-of-box features, rejected for less customization flexibility
- **GitBook** - Considered for hosted solution, rejected for self-hosting requirement
### Search Alternatives
- **Algolia DocSearch** - Considered for hosted search, rejected for simplicity (Fuse.js sufficient for current scale)
- **Lunr.js** - Considered as Fuse.js alternative, Fuse.js chosen for better fuzzy matching
### Domain History
- Original proposal: `docs-voice.asimo.io`
- Current production: `assistdocs.asimo.io`
---
## Related Documentation
- [ARCHITECTURE_V2.md](ARCHITECTURE_V2.md) - System architecture
- [IMPLEMENTATION_STATUS.md](overview/IMPLEMENTATION_STATUS.md) - Component status
- [Debugging Index](debugging/DEBUGGING_INDEX.md) - Troubleshooting guides
6:["slug","DOCUMENTATION_SITE_SPECS","c"]
0:["X7oMT3VrOffzp0qvbeOas",[[["",{"children":["docs",{"children":[["slug","DOCUMENTATION_SITE_SPECS","c"],{"children":["__PAGE__?{\"slug\":[\"DOCUMENTATION_SITE_SPECS\"]}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["docs",{"children":[["slug","DOCUMENTATION_SITE_SPECS","c"],{"children":["__PAGE__",{},[["$L1",["$","div",null,{"children":[["$","div",null,{"className":"mb-6 flex items-center justify-between gap-4","children":[["$","div",null,{"children":[["$","p",null,{"className":"text-sm text-gray-500 dark:text-gray-400","children":"Docs / Raw"}],["$","h1",null,{"className":"text-3xl font-bold text-gray-900 dark:text-white","children":"Documentation Site Specs"}],["$","p",null,{"className":"text-sm text-gray-600 dark:text-gray-400","children":["Sourced from"," ",["$","code",null,{"className":"font-mono text-xs","children":["docs/","DOCUMENTATION_SITE_SPECS.md"]}]]}]]}],["$","a",null,{"href":"https://github.com/mohammednazmy/VoiceAssist/edit/main/docs/DOCUMENTATION_SITE_SPECS.md","target":"_blank","rel":"noreferrer","className":"inline-flex items-center gap-2 rounded-md border border-gray-200 dark:border-gray-700 px-3 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:border-primary-500 dark:hover:border-primary-400 hover:text-primary-700 dark:hover:text-primary-300","children":"Edit on GitHub"}]]}],["$","div",null,{"className":"rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-6","children":["$","$L2",null,{"content":"$3"}]}],["$","div",null,{"className":"mt-6 flex flex-wrap gap-2 text-sm","children":[["$","$L4",null,{"href":"/reference/all-docs","className":"inline-flex items-center gap-1 rounded-md bg-gray-100 px-3 py-1 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700","children":"← All documentation"}],["$","$L4",null,{"href":"/","className":"inline-flex items-center gap-1 rounded-md bg-gray-100 px-3 py-1 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700","children":"Home"}]]}]]}],null],null],null]},[null,["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","docs","children","$6","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","docs","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/7f586cdbbaa33ff7.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","className":"h-full","children":["$","body",null,{"className":"__className_f367f3 h-full bg-white dark:bg-gray-900","children":[["$","a",null,{"href":"#main-content","className":"skip-to-content","children":"Skip to main content"}],["$","$L8",null,{"children":[["$","$L9",null,{}],["$","$La",null,{}],["$","main",null,{"id":"main-content","className":"lg:pl-64","role":"main","aria-label":"Documentation content","children":["$","$Lb",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]]}]]}]}]],null],null],["$Lc",null]]]]
c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Documentation Site Specs | Docs | VoiceAssist Docs"}],["$","meta","3",{"name":"description","content":"VoiceAssist documentation site implementation details, automation pipelines, and AI integration."}],["$","meta","4",{"name":"keywords","content":"VoiceAssist,documentation,medical AI,voice assistant,healthcare,HIPAA,API"}],["$","meta","5",{"name":"robots","content":"index, follow"}],["$","meta","6",{"name":"googlebot","content":"index, follow"}],["$","link","7",{"rel":"canonical","href":"https://assistdocs.asimo.io"}],["$","meta","8",{"property":"og:title","content":"VoiceAssist Documentation"}],["$","meta","9",{"property":"og:description","content":"Comprehensive documentation for VoiceAssist - Enterprise Medical AI Assistant"}],["$","meta","10",{"property":"og:url","content":"https://assistdocs.asimo.io"}],["$","meta","11",{"property":"og:site_name","content":"VoiceAssist Docs"}],["$","meta","12",{"property":"og:type","content":"website"}],["$","meta","13",{"name":"twitter:card","content":"summary"}],["$","meta","14",{"name":"twitter:title","content":"VoiceAssist Documentation"}],["$","meta","15",{"name":"twitter:description","content":"Comprehensive documentation for VoiceAssist - Enterprise Medical AI Assistant"}],["$","meta","16",{"name":"next-size-adjust"}]]
1:null