669 lines
15 KiB
Markdown
669 lines
15 KiB
Markdown
# Milestone 12: Documentation Site
|
|
|
|
**Status**: Decided
|
|
**Goal**: Comprehensive documentation for Mosis app developers.
|
|
|
|
## Decision
|
|
|
|
**Hugo + Docsy theme** for self-hosted static documentation:
|
|
|
|
```
|
|
Framework: Hugo (Go-based static site generator)
|
|
Theme: Docsy (technical documentation theme)
|
|
Search: Pagefind (local, no external service)
|
|
Hosting: Synology NAS (nginx or Go static server)
|
|
```
|
|
|
|
### Rationale
|
|
|
|
1. **Go ecosystem** - Hugo is written in Go, consistent with Portal
|
|
2. **Fast builds** - Hugo compiles thousands of pages in seconds
|
|
3. **No runtime** - Generates static HTML, served directly from NAS
|
|
4. **Docsy theme** - Full-featured docs theme with versioning, search, i18n
|
|
5. **Self-contained** - Pagefind search works offline, no Algolia needed
|
|
|
|
### Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ Synology NAS │
|
|
│ ┌────────────────────────────────────────────────────────────┐ │
|
|
│ │ mosis-portal container │ │
|
|
│ │ ├── Go binary (API + Portal UI) │ │
|
|
│ │ ├── /static/docs/ → Hugo build output │ │
|
|
│ │ └── http.FileServer serves docs at /docs/* │ │
|
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ /volume1/mosis/ │
|
|
│ └── docs/ │
|
|
│ ├── content/ (Markdown source) │
|
|
│ ├── static/ (Images, assets) │
|
|
│ └── public/ (Hugo build output → served) │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
|
|
Build pipeline:
|
|
docs/ (Markdown) ──► hugo build ──► public/ ──► Deploy to NAS
|
|
```
|
|
|
|
### URL Structure
|
|
|
|
```
|
|
https://portal.mosis.dev/docs/ # Docs home
|
|
https://portal.mosis.dev/docs/quickstart/ # Getting started
|
|
https://portal.mosis.dev/docs/api/ # API reference
|
|
https://portal.mosis.dev/docs/cli/ # CLI reference
|
|
```
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The documentation site is the primary resource for developers learning to build Mosis apps. Must be clear, searchable, and up-to-date.
|
|
|
|
---
|
|
|
|
## Information Architecture
|
|
|
|
```
|
|
docs.mosis.dev/
|
|
├── Getting Started
|
|
│ ├── Introduction
|
|
│ ├── Quick Start (5 min)
|
|
│ ├── Your First App
|
|
│ └── Project Structure
|
|
├── Guides
|
|
│ ├── UI Design
|
|
│ │ ├── RML Basics
|
|
│ │ ├── Styling with RCSS
|
|
│ │ ├── Layouts
|
|
│ │ └── Components
|
|
│ ├── Lua Scripting
|
|
│ │ ├── Basics
|
|
│ │ ├── Event Handling
|
|
│ │ ├── State Management
|
|
│ │ └── Async Operations
|
|
│ ├── Data & Storage
|
|
│ │ ├── Local Storage
|
|
│ │ ├── SQLite Database
|
|
│ │ └── Files
|
|
│ ├── Networking
|
|
│ │ ├── HTTP Requests
|
|
│ │ └── WebSockets
|
|
│ ├── Hardware
|
|
│ │ ├── Camera
|
|
│ │ ├── Microphone
|
|
│ │ ├── Location
|
|
│ │ └── Sensors
|
|
│ ├── Permissions
|
|
│ │ ├── Permission Model
|
|
│ │ ├── Requesting Permissions
|
|
│ │ └── User Gestures
|
|
│ └── Publishing
|
|
│ ├── Preparing for Release
|
|
│ ├── App Signing
|
|
│ └── Store Guidelines
|
|
├── API Reference
|
|
│ ├── Lua APIs
|
|
│ │ ├── mosis.storage
|
|
│ │ ├── mosis.db
|
|
│ │ ├── mosis.http
|
|
│ │ ├── mosis.ws
|
|
│ │ ├── mosis.camera
|
|
│ │ ├── mosis.microphone
|
|
│ │ ├── mosis.location
|
|
│ │ ├── mosis.sensors
|
|
│ │ └── ...
|
|
│ ├── RML Elements
|
|
│ ├── RCSS Properties
|
|
│ └── Manifest Schema
|
|
├── CLI Reference
|
|
│ ├── mosis init
|
|
│ ├── mosis build
|
|
│ ├── mosis sign
|
|
│ ├── mosis publish
|
|
│ └── ...
|
|
├── Best Practices
|
|
│ ├── Performance
|
|
│ ├── Security
|
|
│ ├── UX Guidelines
|
|
│ └── Accessibility
|
|
├── Troubleshooting
|
|
│ ├── Common Errors
|
|
│ ├── Debugging Tips
|
|
│ └── FAQ
|
|
└── Changelog
|
|
```
|
|
|
|
---
|
|
|
|
## Content Types
|
|
|
|
### Tutorials (Step-by-step)
|
|
|
|
```markdown
|
|
# Build a Weather App
|
|
|
|
In this tutorial, you'll build a weather app that:
|
|
- Fetches weather data from an API
|
|
- Displays current conditions
|
|
- Shows a 5-day forecast
|
|
- Requests location permission
|
|
|
|
**Time:** 30 minutes
|
|
**Prerequisites:** Completed Quick Start
|
|
|
|
## Step 1: Create the Project
|
|
|
|
```bash
|
|
mosis init weather-app
|
|
cd weather-app
|
|
```
|
|
|
|
## Step 2: Design the UI
|
|
|
|
Open `assets/main.rml` and add...
|
|
```
|
|
|
|
### Guides (Conceptual)
|
|
|
|
```markdown
|
|
# Understanding Permissions
|
|
|
|
Mosis uses a permission system to protect user privacy.
|
|
Apps must declare permissions in their manifest and
|
|
request them at runtime.
|
|
|
|
## Permission Categories
|
|
|
|
| Category | Description | Examples |
|
|
|----------|-------------|----------|
|
|
| Normal | Low risk, auto-granted | storage, network |
|
|
| Dangerous | User data, requires prompt | camera, location |
|
|
| Signature | System only | app_management |
|
|
|
|
## When Permissions Are Checked
|
|
|
|
Permissions are checked when your app calls...
|
|
```
|
|
|
|
### API Reference (Technical)
|
|
|
|
```markdown
|
|
# mosis.http
|
|
|
|
HTTP client for making network requests.
|
|
|
|
## Functions
|
|
|
|
### `mosis.http.get(url, options)`
|
|
|
|
Make a GET request.
|
|
|
|
**Parameters:**
|
|
- `url` (string): The URL to fetch
|
|
- `options` (table, optional):
|
|
- `headers` (table): Request headers
|
|
- `timeout` (number): Timeout in ms (default: 30000)
|
|
|
|
**Returns:** Promise that resolves to Response
|
|
|
|
**Example:**
|
|
```lua
|
|
local response = mosis.http.get("https://api.example.com/data")
|
|
if response.ok then
|
|
local data = json.decode(response.body)
|
|
print(data.name)
|
|
end
|
|
```
|
|
|
|
**Errors:**
|
|
- `NETWORK_ERROR`: Network unavailable
|
|
- `TIMEOUT`: Request timed out
|
|
- `INVALID_URL`: Malformed URL
|
|
```
|
|
|
|
---
|
|
|
|
## Tech Stack Options
|
|
|
|
### Option A: Docusaurus
|
|
|
|
```
|
|
Framework: Docusaurus 3
|
|
Language: MDX (Markdown + React)
|
|
Search: Algolia DocSearch
|
|
Deploy: Vercel/Cloudflare Pages
|
|
```
|
|
|
|
| Pros | Cons |
|
|
|------|------|
|
|
| Versioning built-in | React knowledge needed |
|
|
| Great search | Can be heavy |
|
|
| Plugin ecosystem | |
|
|
| Used by many OSS | |
|
|
|
|
### Option B: VitePress
|
|
|
|
```
|
|
Framework: VitePress
|
|
Language: Markdown + Vue
|
|
Search: Built-in local search
|
|
Deploy: Any static host
|
|
```
|
|
|
|
| Pros | Cons |
|
|
|------|------|
|
|
| Very fast | Fewer features |
|
|
| Vue-powered | Less ecosystem |
|
|
| Simple setup | |
|
|
|
|
### Option C: Astro Starlight
|
|
|
|
```
|
|
Framework: Astro + Starlight
|
|
Language: MDX
|
|
Search: Pagefind (local)
|
|
Deploy: Any static host
|
|
```
|
|
|
|
| Pros | Cons |
|
|
|------|------|
|
|
| Very fast | Newer |
|
|
| Great defaults | Less customizable |
|
|
| Built-in i18n | |
|
|
|
|
### Option D: MkDocs Material
|
|
|
|
```
|
|
Framework: MkDocs
|
|
Language: Markdown
|
|
Search: Built-in
|
|
Deploy: Any static host
|
|
```
|
|
|
|
| Pros | Cons |
|
|
|------|------|
|
|
| Simple | Less interactive |
|
|
| Great theme | Python-based |
|
|
| Fast builds | |
|
|
|
|
---
|
|
|
|
## Features Required
|
|
|
|
### Must Have
|
|
|
|
- [ ] Full-text search
|
|
- [ ] Syntax highlighting
|
|
- [ ] Mobile responsive
|
|
- [ ] Dark mode
|
|
- [ ] Version selector
|
|
- [ ] Edit on GitHub links
|
|
- [ ] Copy code buttons
|
|
- [ ] Table of contents
|
|
- [ ] Previous/Next navigation
|
|
|
|
### Nice to Have
|
|
|
|
- [ ] API playground
|
|
- [ ] Interactive examples
|
|
- [ ] Video tutorials
|
|
- [ ] Community translations
|
|
- [ ] Feedback widget
|
|
|
|
---
|
|
|
|
## Code Examples
|
|
|
|
### Runnable Examples
|
|
|
|
```html
|
|
<!-- Interactive code block -->
|
|
<CodePlayground language="lua">
|
|
local greeting = "Hello, Mosis!"
|
|
print(greeting)
|
|
</CodePlayground>
|
|
```
|
|
|
|
### Multi-file Examples
|
|
|
|
```markdown
|
|
:::code-group
|
|
|
|
```rml [main.rml]
|
|
<div id="counter">
|
|
<span id="count">0</span>
|
|
<button onclick="increment()">+</button>
|
|
</div>
|
|
```
|
|
|
|
```lua [app.lua]
|
|
local count = 0
|
|
|
|
function increment()
|
|
count = count + 1
|
|
document:GetElementById("count").inner_rml = tostring(count)
|
|
end
|
|
```
|
|
|
|
```rcss [styles.rcss]
|
|
#counter {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
```
|
|
|
|
:::
|
|
```
|
|
|
|
---
|
|
|
|
## API Documentation Generation
|
|
|
|
### From Lua Annotations
|
|
|
|
```lua
|
|
--- Make an HTTP GET request.
|
|
--- @param url string The URL to fetch
|
|
--- @param options? HttpOptions Request options
|
|
--- @return HttpResponse response The response object
|
|
--- @example
|
|
--- local resp = mosis.http.get("https://api.example.com/data")
|
|
--- print(resp.body)
|
|
function mosis.http.get(url, options)
|
|
-- implementation
|
|
end
|
|
```
|
|
|
|
### Generated Output
|
|
|
|
```markdown
|
|
## `mosis.http.get(url, options?)`
|
|
|
|
Make an HTTP GET request.
|
|
|
|
### Parameters
|
|
|
|
| Name | Type | Description |
|
|
|------|------|-------------|
|
|
| url | string | The URL to fetch |
|
|
| options | HttpOptions? | Request options |
|
|
|
|
### Returns
|
|
|
|
`HttpResponse` - The response object
|
|
|
|
### Example
|
|
|
|
```lua
|
|
local resp = mosis.http.get("https://api.example.com/data")
|
|
print(resp.body)
|
|
```
|
|
```
|
|
|
|
---
|
|
|
|
## Versioning
|
|
|
|
### URL Structure
|
|
|
|
```
|
|
docs.mosis.dev/ # Latest stable
|
|
docs.mosis.dev/v1.0/ # Version 1.0
|
|
docs.mosis.dev/v1.1/ # Version 1.1
|
|
docs.mosis.dev/next/ # Development (unreleased)
|
|
```
|
|
|
|
### Version Dropdown
|
|
|
|
```
|
|
┌────────────────────┐
|
|
│ Version: 1.1 (latest) ▼ │
|
|
├────────────────────┤
|
|
│ 1.1 (latest) │
|
|
│ 1.0 │
|
|
│ next (unreleased) │
|
|
└────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Search
|
|
|
|
### Algolia DocSearch (Free for OSS)
|
|
|
|
```javascript
|
|
// docusaurus.config.js
|
|
themeConfig: {
|
|
algolia: {
|
|
appId: 'YOUR_APP_ID',
|
|
apiKey: 'YOUR_SEARCH_KEY',
|
|
indexName: 'mosis',
|
|
},
|
|
}
|
|
```
|
|
|
|
### Local Search (Pagefind)
|
|
|
|
```javascript
|
|
// For Astro/VitePress
|
|
// Indexes at build time, searches client-side
|
|
// No external service needed
|
|
```
|
|
|
|
---
|
|
|
|
## Internationalization
|
|
|
|
### Directory Structure
|
|
|
|
```
|
|
docs/
|
|
├── en/
|
|
│ ├── getting-started/
|
|
│ └── guides/
|
|
├── es/
|
|
│ ├── getting-started/
|
|
│ └── guides/
|
|
└── zh/
|
|
├── getting-started/
|
|
└── guides/
|
|
```
|
|
|
|
### Language Switcher
|
|
|
|
```
|
|
┌──────────┐
|
|
│ 🌐 EN ▼ │
|
|
├──────────┤
|
|
│ English │
|
|
│ Español │
|
|
│ 中文 │
|
|
└──────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Content Guidelines
|
|
|
|
### Writing Style
|
|
|
|
1. **Be concise** - Get to the point quickly
|
|
2. **Use active voice** - "The function returns..." not "A value is returned..."
|
|
3. **Show, don't tell** - Code examples over explanations
|
|
4. **Assume beginner** - Don't assume prior knowledge
|
|
5. **Test all examples** - Every code block must work
|
|
|
|
### Code Style
|
|
|
|
```lua
|
|
-- Good: Clear, commented
|
|
local response = mosis.http.get(API_URL)
|
|
if response.ok then
|
|
local data = json.decode(response.body)
|
|
updateUI(data)
|
|
else
|
|
showError("Failed to load data")
|
|
end
|
|
|
|
-- Bad: Unclear, no error handling
|
|
local d = json.decode(mosis.http.get(u).body)
|
|
```
|
|
|
|
### Screenshots
|
|
|
|
- Use consistent device frame
|
|
- Show relevant UI only
|
|
- Add callouts for important areas
|
|
- Keep file sizes small (WebP)
|
|
|
|
---
|
|
|
|
## Deployment
|
|
|
|
### CI/CD Pipeline
|
|
|
|
```yaml
|
|
# .github/workflows/docs.yml
|
|
name: Deploy Docs
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
- 'docs/**'
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: 20
|
|
|
|
- name: Install and Build
|
|
run: |
|
|
cd docs
|
|
npm install
|
|
npm run build
|
|
|
|
- name: Deploy to Cloudflare Pages
|
|
uses: cloudflare/pages-action@v1
|
|
with:
|
|
apiToken: ${{ secrets.CF_API_TOKEN }}
|
|
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
|
projectName: mosis-docs
|
|
directory: docs/build
|
|
```
|
|
|
|
---
|
|
|
|
## Analytics
|
|
|
|
### Track (Privacy-Friendly)
|
|
|
|
- Page views (which docs are popular)
|
|
- Search queries (what are people looking for)
|
|
- 404 pages (missing content)
|
|
- Time on page (engagement)
|
|
|
|
### Tools
|
|
|
|
- Plausible (privacy-focused)
|
|
- Simple Analytics
|
|
- Cloudflare Analytics (free)
|
|
|
|
---
|
|
|
|
## Feedback
|
|
|
|
### Per-Page Feedback
|
|
|
|
```
|
|
┌────────────────────────────────────┐
|
|
│ Was this page helpful? │
|
|
│ │
|
|
│ [👍 Yes] [👎 No] │
|
|
│ │
|
|
│ [Edit this page on GitHub] │
|
|
└────────────────────────────────────┘
|
|
```
|
|
|
|
### Feedback Collection
|
|
|
|
```javascript
|
|
// Send to analytics or issue tracker
|
|
function submitFeedback(page, helpful, comment) {
|
|
fetch('/api/feedback', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ page, helpful, comment })
|
|
})
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Deliverables
|
|
|
|
- [x] Framework selected (Hugo + Docsy)
|
|
- [x] Hosting decided (self-hosted on Synology NAS)
|
|
- [ ] Hugo project setup with Docsy theme
|
|
- [ ] Information architecture (directory structure)
|
|
- [ ] Getting Started content (Quick Start, First App)
|
|
- [ ] UI design guides (RML, RCSS)
|
|
- [ ] Lua scripting guides
|
|
- [ ] API reference (all namespaces)
|
|
- [ ] CLI reference (all commands)
|
|
- [ ] Best practices (performance, security)
|
|
- [ ] Pagefind search integration
|
|
- [ ] Deploy script (hugo build + copy to NAS)
|
|
|
|
---
|
|
|
|
## Content Prioritization
|
|
|
|
### Phase 1 (Launch)
|
|
|
|
1. Quick Start
|
|
2. Your First App
|
|
3. Project Structure
|
|
4. RML Basics
|
|
5. Lua Basics
|
|
6. API Reference (core APIs)
|
|
7. CLI Reference
|
|
|
|
### Phase 2
|
|
|
|
1. Complete API Reference
|
|
2. All hardware guides
|
|
3. Best practices
|
|
4. Troubleshooting
|
|
|
|
### Phase 3
|
|
|
|
1. Advanced guides
|
|
2. Video tutorials
|
|
3. Translations
|
|
4. Community contributions
|
|
|
|
---
|
|
|
|
## Open Questions
|
|
|
|
1. ~~Host docs separately or under main domain?~~ → Under main domain at /docs/
|
|
2. ~~Community wiki/contributions?~~ → Defer to post-MVP (GitHub PRs for docs)
|
|
3. Video tutorial platform (YouTube, embedded)? → Consider for v1.1
|
|
4. ~~Glossary/terminology page?~~ → Yes, include in Phase 2
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [Docusaurus](https://docusaurus.io/)
|
|
- [VitePress](https://vitepress.dev/)
|
|
- [Astro Starlight](https://starlight.astro.build/)
|
|
- [Divio Documentation System](https://documentation.divio.com/)
|