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