diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 56ff59f..d88f4a2 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -20,7 +20,7 @@ jobs:
- uses: actions/setup-node@v4
with:
- node-version: 18
+ node-version: 20
cache: npm
- name: Install dependencies
@@ -45,7 +45,7 @@ jobs:
- uses: actions/setup-node@v4
with:
- node-version: 18
+ node-version: 20
cache: npm
- name: Install dependencies
diff --git a/.gitignore b/.gitignore
index b2d6de3..ded26b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,20 +1,41 @@
# Dependencies
-/node_modules
+node_modules/
-# Production
-/build
+# Production build
+build/
+.docusaurus/
+.cache-loader/
# Generated files
-.docusaurus
-.cache-loader
+.docusaurus/
+.cache/
# Misc
.DS_Store
+.env
.env.local
.env.development.local
.env.test.local
.env.production.local
+# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+lerna-debug.log*
+
+# Editor directories and files
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+.project
+.classpath
+.settings/
+*.sublime-workspace
+
+# OS
+.DS_Store
+Thumbs.db
+
diff --git a/README.md b/README.md
index 4793827..4cdab0f 100644
--- a/README.md
+++ b/README.md
@@ -62,4 +62,4 @@ The website is deployed automatically using GitHub Actions when changes are push
2. Runs full Docusaurus build
3. Deploys to GitHub Pages (only if all checks pass)
-Broken links or validation errors will prevent deployment.
\ No newline at end of file
+Broken links or validation errors will prevent deployment.
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..c0097fc
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,4 @@
+module.exports = {
+ presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
+};
+
diff --git a/create-placeholders.sh b/create-placeholders.sh
new file mode 100755
index 0000000..4237b74
--- /dev/null
+++ b/create-placeholders.sh
@@ -0,0 +1,89 @@
+#!/bin/bash
+# Create placeholder markdown files for all documentation pages
+
+# Guides - Forms
+echo "---\nsidebar_position: 2\n---\n\n# Schema Definition\n\n[Placeholder: Content will be added]" > docs/guides/forms/schema-definition.md
+echo "---\nsidebar_position: 3\n---\n\n# UI Schema\n\n[Placeholder: Content will be added]" > docs/guides/forms/ui-schema.md
+echo "---\nsidebar_position: 4\n---\n\n# Validation\n\n[Placeholder: Content will be added]" > docs/guides/forms/validation.md
+echo "---\nsidebar_position: 5\n---\n\n# Conditional Logic\n\n[Placeholder: Content will be added]" > docs/guides/forms/advanced-features.md
+
+# Guides - Custom Apps
+echo "---\nsidebar_position: 1\n---\n\n# Custom Applications Overview\n\n[Placeholder: Content will be added]" > docs/guides/custom-apps/overview.md
+echo "---\nsidebar_position: 2\n---\n\n# Building Custom Applications\n\n[Placeholder: Content will be added]" > docs/guides/custom-apps/building.md
+echo "---\nsidebar_position: 3\n---\n\n# App Bundle Structure\n\n[Placeholder: Content will be added]" > docs/guides/custom-apps/app-bundle-structure.md
+echo "---\nsidebar_position: 4\n---\n\n# Deployment\n\n[Placeholder: Content will be added]" > docs/guides/custom-apps/deployment.md
+echo "---\nsidebar_position: 5\n---\n\n# Custom Renderers\n\n[Placeholder: Content will be added]" > docs/guides/custom-apps/custom-renderers.md
+
+# Guides - Deployment
+echo "---\nsidebar_position: 1\n---\n\n# Deployment Overview\n\n[Placeholder: Content will be added]" > docs/guides/deployment/overview.md
+echo "---\nsidebar_position: 2\n---\n\n# Docker Deployment\n\n[Placeholder: Content will be added]" > docs/guides/deployment/docker.md
+echo "---\nsidebar_position: 3\n---\n\n# Production Deployment\n\n[Placeholder: Content will be added]" > docs/guides/deployment/production.md
+echo "---\nsidebar_position: 4\n---\n\n# Monitoring\n\n[Placeholder: Content will be added]" > docs/guides/deployment/monitoring.md
+
+# Guides - Other
+echo "---\nsidebar_position: 5\n---\n\n# User Management\n\n[Placeholder: Content will be added]" > docs/guides/user-management.md
+echo "---\nsidebar_position: 6\n---\n\n# Branding\n\n[Placeholder: Content will be added]" > docs/guides/branding.md
+echo "---\nsidebar_position: 7\n---\n\n# Translations\n\n[Placeholder: Content will be added]" > docs/guides/translations.md
+
+# Reference - API
+echo "---\nsidebar_position: 1\n---\n\n# API Overview\n\n[Placeholder: Content will be added]" > docs/reference/api/overview.md
+echo "---\nsidebar_position: 2\n---\n\n# Authentication\n\n[Placeholder: Content will be added]" > docs/reference/api/authentication.md
+echo "---\nsidebar_position: 3\n---\n\n# API Endpoints\n\n[Placeholder: Content will be added]" > docs/reference/api/endpoints.md
+
+# Reference - Configuration
+echo "---\nsidebar_position: 1\n---\n\n# Server Configuration\n\n[Placeholder: Content will be added]" > docs/reference/configuration/server.md
+echo "---\nsidebar_position: 2\n---\n\n# Client Configuration\n\n[Placeholder: Content will be added]" > docs/reference/configuration/client.md
+
+# Reference - Other
+echo "---\nsidebar_position: 2\n---\n\n# Form Specifications\n\n[Placeholder: Content will be added]" > docs/reference/form-specifications.md
+echo "---\nsidebar_position: 3\n---\n\n# App Bundle Format\n\n[Placeholder: Content will be added]" > docs/reference/app-bundle-format.md
+
+# Reference - Components
+echo "---\nsidebar_position: 1\n---\n\n# Formulus\n\n[Placeholder: Content will be added]" > docs/reference/components/formulus.md
+echo "---\nsidebar_position: 2\n---\n\n# Synkronus\n\n[Placeholder: Content will be added]" > docs/reference/components/synkronus.md
+echo "---\nsidebar_position: 3\n---\n\n# Synkronus CLI\n\n[Placeholder: Content will be added]" > docs/reference/components/synkronus-cli.md
+echo "---\nsidebar_position: 4\n---\n\n# Formplayer\n\n[Placeholder: Content will be added]" > docs/reference/components/formplayer.md
+
+# Development - Getting Started
+echo "---\nsidebar_position: 1\n---\n\n# Development Setup\n\n[Placeholder: Content will be added]" > docs/development/getting-started/setup.md
+echo "---\nsidebar_position: 2\n---\n\n# Architecture Overview\n\n[Placeholder: Content will be added]" > docs/development/getting-started/architecture.md
+echo "---\nsidebar_position: 3\n---\n\n# Codebase Overview\n\n[Placeholder: Content will be added]" > docs/development/getting-started/codebase-overview.md
+
+# Development - Architecture
+echo "---\nsidebar_position: 1\n---\n\n# Architecture Overview\n\n[Placeholder: Content will be added]" > docs/development/architecture/overview.md
+echo "---\nsidebar_position: 2\n---\n\n# Components\n\n[Placeholder: Content will be added]" > docs/development/architecture/components.md
+echo "---\nsidebar_position: 3\n---\n\n# Data Flow\n\n[Placeholder: Content will be added]" > docs/development/architecture/data-flow.md
+echo "---\nsidebar_position: 4\n---\n\n# Sync Protocol\n\n[Placeholder: Content will be added]" > docs/development/architecture/sync-protocol.md
+echo "---\nsidebar_position: 5\n---\n\n# Database\n\n[Placeholder: Content will be added]" > docs/development/architecture/database.md
+
+# Development - Contributing
+echo "---\nsidebar_position: 1\n---\n\n# Contributing Guide\n\n[Placeholder: Content will be added]" > docs/development/contributing/guide.md
+echo "---\nsidebar_position: 2\n---\n\n# Code of Conduct\n\n[Placeholder: Content will be added]" > docs/development/contributing/code-of-conduct.md
+echo "---\nsidebar_position: 3\n---\n\n# First Contribution\n\n[Placeholder: Content will be added]" > docs/development/contributing/first-contribution.md
+echo "---\nsidebar_position: 4\n---\n\n# Coding Standards\n\n[Placeholder: Content will be added]" > docs/development/contributing/coding-standards.md
+
+# Development - Building
+echo "---\nsidebar_position: 1\n---\n\n# Building from Source\n\n[Placeholder: Content will be added]" > docs/development/building/from-source.md
+echo "---\nsidebar_position: 2\n---\n\n# Building Components\n\n[Placeholder: Content will be added]" > docs/development/building/components.md
+echo "---\nsidebar_position: 3\n---\n\n# Testing\n\n[Placeholder: Content will be added]" > docs/development/building/testing.md
+echo "---\nsidebar_position: 4\n---\n\n# CI/CD Pipeline\n\n[Placeholder: Content will be added]" > docs/development/building/ci-cd.md
+
+# Development - Extending
+echo "---\nsidebar_position: 1\n---\n\n# Extending ODE Overview\n\n[Placeholder: Content will be added]" > docs/development/extending/overview.md
+echo "---\nsidebar_position: 2\n---\n\n# Custom Renderers\n\n[Placeholder: Content will be added]" > docs/development/extending/custom-renderers.md
+echo "---\nsidebar_position: 3\n---\n\n# Plugins\n\n[Placeholder: Content will be added]" > docs/development/extending/plugins.md
+echo "---\nsidebar_position: 4\n---\n\n# Internal APIs\n\n[Placeholder: Content will be added]" > docs/development/extending/internal-apis.md
+
+# Development - Technical
+echo "---\nsidebar_position: 1\n---\n\n# Database Schema\n\n[Placeholder: Content will be added]" > docs/development/technical/database-schema.md
+echo "---\nsidebar_position: 2\n---\n\n# Sync Protocol\n\n[Placeholder: Content will be added]" > docs/development/technical/sync-protocol.md
+echo "---\nsidebar_position: 3\n---\n\n# Security\n\n[Placeholder: Content will be added]" > docs/development/technical/security.md
+echo "---\nsidebar_position: 4\n---\n\n# Performance\n\n[Placeholder: Content will be added]" > docs/development/technical/performance.md
+
+# Community
+echo "---\nsidebar_position: 2\n---\n\n# Getting Help\n\n[Placeholder: Content will be added]" > docs/community/getting-help.md
+echo "---\nsidebar_position: 3\n---\n\n# Reporting Issues\n\n[Placeholder: Content will be added]" > docs/community/reporting-issues.md
+echo "---\nsidebar_position: 4\n---\n\n# Examples\n\n[Placeholder: Content will be added]" > docs/community/examples.md
+echo "---\nsidebar_position: 5\n---\n\n# Projects\n\n[Placeholder: Content will be added]" > docs/community/projects.md
+
+echo "Placeholder files created successfully"
diff --git a/docs/.gitkeep b/docs/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/build/_category_.json b/docs/build/_category_.json
deleted file mode 100644
index d651fe1..0000000
--- a/docs/build/_category_.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "label": "Build",
- "position": 3
-}
-
diff --git a/docs/build/branding.md b/docs/build/branding.md
deleted file mode 100644
index 851db66..0000000
--- a/docs/build/branding.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-sidebar_position: 7
----
-
-# Branding
-
-Customize the appearance of your ODE application.
-
-## Overview
-
-[Description placeholder]
-
-## Application Branding
-
-[Description placeholder]
-
-## Custom Themes
-
-[Description placeholder]
-
-## Logo & Assets
-
-[Description placeholder]
-
-## Related Content
-
-- [Custom Applications](/docs/build/custom-applications/overview)
-- [Formulus Configuration](/docs/components/formulus/configuration)
-
diff --git a/docs/build/custom-applications/app-bundle-structure.md b/docs/build/custom-applications/app-bundle-structure.md
deleted file mode 100644
index 579b76e..0000000
--- a/docs/build/custom-applications/app-bundle-structure.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 3
----
-
-# App Bundle Structure
-
-Structure of ODE app bundles.
-
-## Overview
-
-[Description placeholder]
-
-## Directory Structure
-
-[Description placeholder]
-
-## Required Files
-
-[Description placeholder]
-
-## Related Content
-
-- [App Bundle API](/docs/reference/rest-api/app-bundle)
-- [Deployment](/docs/build/custom-applications/deployment)
-
diff --git a/docs/build/custom-applications/custom-renderers.md b/docs/build/custom-applications/custom-renderers.md
deleted file mode 100644
index 6e5a20a..0000000
--- a/docs/build/custom-applications/custom-renderers.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 5
----
-
-# Custom Renderers
-
-Create custom form renderers for JSON Forms.
-
-## Overview
-
-[Description placeholder]
-
-## Renderer Development
-
-[Description placeholder]
-
-## Integration
-
-[Description placeholder]
-
-## Related Content
-
-- [JSON Forms](/docs/technical-overview/concepts/json-forms)
-- [Form Design](/docs/build/forms/design/ui-schema)
-
diff --git a/docs/build/custom-applications/deployment.md b/docs/build/custom-applications/deployment.md
deleted file mode 100644
index aee95ff..0000000
--- a/docs/build/custom-applications/deployment.md
+++ /dev/null
@@ -1,376 +0,0 @@
----
-sidebar_position: 4
----
-
-# Deployment
-
-Deploy custom applications to ODE by creating and uploading app bundles.
-
-## What is an App Bundle?
-
-An **app bundle** is a ZIP file containing:
-
-- **`app/`** - Custom web application (HTML, JS, CSS)
-- **`forms/`** - JSON form definitions (schema + UI)
-- **`APP_INFO.json`** - Generated manifest (created by server)
-
-The Formulus mobile app downloads and runs the app bundle, enabling customized data collection workflows.
-
-## App Bundle Structure
-
-```
-bundle.zip
-├── app/
-│ ├── index.html # Entry point
-│ ├── config.json # App configuration
-│ ├── formulus-load.js # Formulus bridge script
-│ └── assets/
-│ └── *.js, *.css # Built assets
-└── forms/
- ├── registration/
- │ ├── schema.json # JSON Schema (draft-07)
- │ └── ui.json # UI layout definition
- ├── visit/
- │ ├── schema.json
- │ └── ui.json
- └── result/
- ├── schema.json
- └── ui.json
-```
-
-## Prerequisites
-
-- [ ] Synkronus CLI configured and logged in (see [CLI Installation](/docs/components/synkronus-cli/installation))
-- [ ] Node.js installed (for building apps)
-- [ ] Demo app or custom app ready
-
-## Building an App Bundle
-
-### Using the Demo Malaria Screening App
-
-Navigate to the demo app:
-
-```bash
-cd /path/to/demos/demo_malaria_screening
-```
-
-#### Step 1: Install Dependencies
-
-```bash
-cd app
-npm install
-```
-
-#### Step 2: Build the App
-
-```bash
-npm run build
-```
-
-**Output:** Built files in `../app-bundles/app/`
-
-#### Step 3: Validate Forms (Optional)
-
-```bash
-npm run validate:forms
-```
-
-Checks:
-- JSON Schema syntax
-- UI schema format
-- Field references
-
-#### Step 4: Create the Bundle ZIP
-
-```bash
-npm run zip
-```
-
-**Output:**
-
-```
-Created zip: /path/to/demo_malaria_screening/app-bundles/bundle-v1.0.6.zip
-```
-
-### Bundle Contents Verification
-
-Check what's in the bundle:
-
-```bash
-unzip -l app-bundles/bundle-v1.0.6.zip
-```
-
-**Expected output:**
-
-```
-Archive: bundle-v1.0.6.zip
- Length Date Time Name
---------- ---------- ----- ----
- 0 2025-12-11 19:39 app/assets/
- 443314 2025-12-11 19:39 app/assets/index-f2c34314.js
- 494 2025-12-11 19:39 app/config.json
- 3327 2025-12-11 19:39 app/formulus-load.js
- 470 2025-12-11 19:39 app/index.html
- 0 2025-12-11 19:39 forms/registration/
- 3371 2025-12-11 19:39 forms/registration/schema.json
- 2430 2025-12-11 19:39 forms/registration/ui.json
- ...
-```
-
-## Uploading an App Bundle
-
-### Basic Upload
-
-```bash
-cd synkronus-cli
-./bin/synk app-bundle upload /path/to/bundle-v1.0.6.zip
-```
-
-### Upload with Auto-Activation
-
-```bash
-./bin/synk app-bundle upload /path/to/bundle-v1.0.6.zip --activate
-```
-
-### Upload with Verbose Output
-
-```bash
-./bin/synk app-bundle upload /path/to/bundle-v1.0.6.zip --activate --verbose
-```
-
-**Expected output:**
-
-```
-Validating bundle structure...
-✓ Bundle structure is valid
-
-Bundle Information:
- Size: 148328 bytes
- Files: 10
- Forms: 3
- Renderers: 0
-
-Uploading bundle...
-✓ App bundle uploaded successfully!
-Version: 0001
-
-Manifest:
- Version: 0001
- Hash: b0494d5cc7164221f1c6dd957b9e61ff...
-
-Activating version 0001...
-✓ Version 0001 activated successfully!
-```
-
-### Skip Validation (Not Recommended)
-
-```bash
-./bin/synk app-bundle upload bundle.zip --skip-validation
-```
-
-## Managing App Bundle Versions
-
-### List Available Versions
-
-```bash
-./bin/synk app-bundle versions
-```
-
-**Output:**
-
-```
-Available App Bundle Versions:
-- 0001 *
-- 0002
-```
-
-The `*` indicates the currently active version.
-
-### View Current Manifest
-
-```bash
-./bin/synk app-bundle manifest
-```
-
-**Output:**
-
-```
-App Bundle Manifest:
-Version: 0001
-Generated At: 2025-12-11T16:41:19Z
-Hash: b0494d5cc7164221f1c6dd957b9e61ff...
-Files: 11
- - APP_INFO.json (10640 bytes)
- - app/assets/index-f2c34314.js (443314 bytes)
- - app/config.json (494 bytes)
- - app/formulus-load.js (3327 bytes)
- - app/index.html (470 bytes)
-... and 6 more files (use --all to show all)
-```
-
-### Show All Files
-
-```bash
-./bin/synk app-bundle manifest --all
-```
-
-### Switch Active Version
-
-```bash
-./bin/synk app-bundle switch 0002
-```
-
-**Output:**
-
-```
-✓ Version 0002 activated successfully!
-```
-
-### View Version Changes
-
-```bash
-./bin/synk app-bundle changes 0001 0002
-```
-
-## Downloading App Bundles
-
-### Download Current Bundle
-
-```bash
-./bin/synk app-bundle download --output ./downloaded-bundle/
-```
-
-### Download Specific File
-
-```bash
-./bin/synk app-bundle download app/index.html
-```
-
-## Creating a Custom App Bundle
-
-### Minimal Structure
-
-```
-my-bundle/
-├── app/
-│ ├── index.html
-│ └── formulus-load.js
-└── forms/
- └── myform/
- ├── schema.json
- └── ui.json
-```
-
-### Minimal index.html
-
-```html
-
-
-
-
-
- My App
-
-
-
-
My Custom App
-
-
-
-```
-
-### Create ZIP
-
-```bash
-cd my-bundle
-zip -r ../my-bundle.zip app/ forms/
-```
-
-### Upload
-
-```bash
-./bin/synk app-bundle upload my-bundle.zip --activate
-```
-
-## Best Practices
-
-### Version Control
-
-- Use semantic versioning in `package.json`
-- Tag releases in Git
-- Keep changelog of form changes
-
-### Testing
-
-- Test locally before uploading
-- Validate forms: `npm run validate:forms`
-- Test on actual device before production
-
-### Deployment
-
-- Upload to staging first
-- Test with sample data
-- Switch versions atomically
-- Keep previous versions for rollback
-
-### Form Design
-
-- Keep forms focused and simple
-- Use clear field labels
-- Add validation rules
-- Test on mobile devices
-
-## Troubleshooting
-
-### Issue: "Bundle structure is invalid"
-
-**Check:**
-- Bundle has `app/` directory
-- Bundle has `forms/` directory (if using forms)
-- `app/index.html` exists
-
-### Issue: Upload fails with auth error
-
-**Solution:**
-
-```bash
-./bin/synk status # Check if logged in
-./bin/synk login -u admin # Re-login if needed
-```
-
-### Issue: Forms don't appear in app
-
-**Check:**
-- Form schema is valid JSON Schema draft-07
-- UI schema references correct property paths
-- Bundle was uploaded and activated
-
-### Issue: App shows blank screen
-
-**Check:**
-- Use `HashRouter` not `BrowserRouter` (React apps)
-- `formulus-load.js` is included
-- No JavaScript errors (check device logs)
-
-## Command Reference
-
-| Command | Description |
-|---------|-------------|
-| `synk app-bundle upload FILE` | Upload bundle |
-| `synk app-bundle upload FILE --activate` | Upload and activate |
-| `synk app-bundle versions` | List versions |
-| `synk app-bundle manifest` | Show manifest |
-| `synk app-bundle switch VERSION` | Change active version |
-| `synk app-bundle download` | Download bundle |
-| `synk app-bundle changes V1 V2` | Compare versions |
-
-## Related Content
-
-- [Synkronus CLI Installation](/docs/components/synkronus-cli/installation)
-- [Synkronus CLI Commands](/docs/components/synkronus-cli/commands-reference)
-- [App Bundle API](/docs/reference/rest-api/app-bundle)
-- [App Bundle Structure](/docs/build/custom-applications/app-bundle-structure)
-- [Building Custom Apps](/docs/build/custom-applications/building)
diff --git a/docs/build/custom-applications/overview.md b/docs/build/custom-applications/overview.md
deleted file mode 100644
index 0500217..0000000
--- a/docs/build/custom-applications/overview.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-sidebar_position: 1
----
-
-# Custom Applications Overview
-
-Build custom web applications that integrate with ODE.
-
-## Overview
-
-ODE allows you to build custom web applications that run within Formulus and integrate with the ODE platform.
-
-## Getting Started
-
-- [Building Custom Apps](/docs/build/custom-applications/building)
-- [App Bundle Structure](/docs/build/custom-applications/app-bundle-structure)
-- [Deployment](/docs/build/custom-applications/deployment)
-
-## Integration
-
-[Description placeholder]
-
-## Related Content
-
-- [Formulus Integration](/docs/components/formulus/integration)
-- [App Bundles](/docs/technical-overview/concepts/app-bundles)
-
diff --git a/docs/build/data-management/attachments.md b/docs/build/data-management/attachments.md
deleted file mode 100644
index e9f2d60..0000000
--- a/docs/build/data-management/attachments.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 3
----
-
-# Attachments
-
-Manage file attachments in ODE.
-
-## Overview
-
-[Description placeholder]
-
-## Attachment Storage
-
-[Description placeholder]
-
-## Attachment Sync
-
-[Description placeholder]
-
-## Related Content
-
-- [Multimedia in Forms](/docs/build/forms/advanced-features/multimedia)
-- [Synchronization](/docs/build/synchronization/overview)
-
diff --git a/docs/build/data-management/export.md b/docs/build/data-management/export.md
deleted file mode 100644
index b584ca8..0000000
--- a/docs/build/data-management/export.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 4
----
-
-# Data Export
-
-Export data from ODE for analysis.
-
-## Overview
-
-[Description placeholder]
-
-## Export Formats
-
-[Description placeholder]
-
-## Using Synkronus CLI
-
-[Description placeholder]
-
-## Related Content
-
-- [Synkronus CLI](/docs/components/synkronus-cli/commands-reference)
-- [Observations](/docs/build/data-management/observations)
-
diff --git a/docs/build/data-management/import.md b/docs/build/data-management/import.md
deleted file mode 100644
index af8de9e..0000000
--- a/docs/build/data-management/import.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 5
----
-
-# Data Import
-
-Import data into ODE.
-
-## Overview
-
-[Description placeholder]
-
-## Import Formats
-
-[Description placeholder]
-
-## Import Process
-
-[Description placeholder]
-
-## Related Content
-
-- [Data Export](/docs/build/data-management/export)
-- [Observations](/docs/build/data-management/observations)
-
diff --git a/docs/build/data-management/observations.md b/docs/build/data-management/observations.md
deleted file mode 100644
index 9205e8c..0000000
--- a/docs/build/data-management/observations.md
+++ /dev/null
@@ -1,290 +0,0 @@
----
-sidebar_position: 2
----
-
-# Observations
-
-Manage form submission data (observations) in ODE.
-
-## Overview
-
-An **observation** is a single data record:
-- Created when user fills out a form
-- Contains answers to form questions
-- Includes metadata (who, when, where)
-- May have attachments (photos, etc.)
-
-## Observation Structure
-
-When a user submits a form, an observation is created:
-
-```json
-{
- "id": "uuid-generated-on-device",
- "formId": "registration",
- "schemaType": "registration",
- "data": {
- "firstName": "John",
- "lastName": "Doe",
- "dateOfBirth": "1990-05-15",
- "gender": "male",
- "phoneNumber": "0712345678",
- "email": "john.doe@example.com",
- "consent": true
- },
- "metadata": {
- "createdAt": "2025-12-11T10:30:00Z",
- "updatedAt": "2025-12-11T10:35:00Z",
- "createdBy": "fieldworker1",
- "deviceId": "device-uuid",
- "appVersion": "1.0.0",
- "location": {
- "latitude": -1.2921,
- "longitude": 36.8219,
- "accuracy": 10
- }
- },
- "attachments": [
- {
- "id": "attachment-uuid",
- "field": "patientPhoto",
- "filename": "photo_123.jpg",
- "mimeType": "image/jpeg",
- "size": 245678
- }
- ],
- "status": "pending",
- "syncedAt": null
-}
-```
-
-## Observation Lifecycle
-
-```
-┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
-│ Draft │────▶│ Pending │────▶│ Syncing │────▶│ Synced │
-└─────────┘ └─────────┘ └─────────┘ └─────────┘
- │ │ │
- │ │ │
- ▼ ▼ ▼
-┌─────────┐ ┌─────────┐ ┌─────────┐
-│ Deleted │ │ Error │────▶│ Retry │
-└─────────┘ └─────────┘ └─────────┘
-```
-
-### States
-
-| State | Description | Actions |
-|-------|-------------|---------|
-| **Draft** | Incomplete, saved locally | Edit, Delete, Submit |
-| **Pending** | Complete, awaiting sync | Edit (maybe), Delete |
-| **Syncing** | Currently uploading | Wait |
-| **Synced** | Successfully uploaded | View |
-| **Error** | Sync failed | Retry, View error |
-
-## Managing Observations
-
-### Viewing Observations
-
-In the Formulus app:
-
-1. **Go to Observations screen**
-2. **See list of all saved observations**
-3. **Each entry shows:**
- - Form name
- - Date/time created
- - Status (draft, pending, synced)
- - Key data fields
-
-### Filtering and Search
-
-- **Filter by form type** - Dropdown or tabs
-- **Filter by status** - Draft, pending, synced
-- **Search** - Find by keyword
-- **Sort** - By date, form name, status
-
-### Editing Observations
-
-#### Edit Draft
-
-1. **Tap on draft observation**
-2. **Form opens with saved data**
-3. **Make changes**
-4. **Save or Submit**
-
-#### Edit Pending (if allowed)
-
-1. **Tap on pending observation**
-2. **May need to "Unlock" for editing**
-3. **Make changes**
-4. **Re-submit**
-
-### Deleting Observations
-
-1. **Long-press on observation** or tap menu (⋮)
-2. **Select "Delete"**
-3. **Confirm deletion**
-
-**Note:** Synced observations may not be deletable locally.
-
-## Sync Protocol
-
-### Pull (Server → Device)
-
-```json
-// Request
-GET /sync/pull?since=1702300000&schemaTypes=registration,visit
-
-// Response
-{
- "observations": [...],
- "lastChangeId": 12345,
- "hasMore": false
-}
-```
-
-### Push (Device → Server)
-
-```json
-// Request
-POST /sync/push
-{
- "clientId": "device-uuid",
- "observations": [
- {
- "id": "local-uuid",
- "schemaType": "registration",
- "data": {...},
- "createdAt": "2025-12-11T10:30:00Z"
- }
- ]
-}
-
-// Response
-{
- "accepted": ["local-uuid"],
- "rejected": [],
- "warnings": []
-}
-```
-
-### Attachment Sync
-
-Attachments sync separately:
-
-```
-1. Observation syncs first (with attachment references)
-2. Attachments queue for upload
-3. Each attachment uploads individually
-4. Server confirms receipt
-```
-
-## Querying Observations
-
-### Via API
-
-```bash
-# Get all observations
-curl http://localhost/api/v1.0.0/observations \
- -H "Authorization: Bearer $TOKEN"
-
-# Filter by schema type
-curl "http://localhost/api/v1.0.0/observations?schemaType=registration" \
- -H "Authorization: Bearer $TOKEN"
-
-# Filter by date range
-curl "http://localhost/api/v1.0.0/observations?since=2025-12-01&until=2025-12-31" \
- -H "Authorization: Bearer $TOKEN"
-```
-
-### Via CLI
-
-```bash
-# Export observations
-./bin/synk data export observations.zip
-
-# Export with filters (if supported)
-./bin/synk data export --schema-type registration output.zip
-```
-
-## Data Export
-
-### Export Format
-
-The export creates a ZIP containing Parquet files:
-
-```
-export.zip
-├── observations.parquet
-├── attachments.parquet
-└── metadata.json
-```
-
-### Export via CLI
-
-```bash
-# Export all observations as Parquet
-./bin/synk data export observations.zip
-
-# Export with filters (if supported)
-./bin/synk data export --schema-type registration output.zip
-```
-
-## Best Practices
-
-### Data Quality
-
-1. **Validate early** - Client-side validation
-2. **Require key fields** - Don't allow empty
-3. **Use formats** - date, email, etc.
-4. **Capture metadata** - Who, when, where
-5. **Handle offline** - Graceful sync
-
-### Sync Management
-
-1. **Sync before fieldwork** - Get latest forms
-2. **Save frequently** - Avoid data loss
-3. **Check pending count** - Before leaving field
-4. **Sync immediately** - When back online
-
-## Troubleshooting
-
-### Issue: Observations stuck as "Pending"
-
-**Try:**
-
-1. Check network connection
-2. Manual sync from Sync screen
-3. Check for sync errors
-4. Verify server is running
-
-### Issue: Sync fails with error
-
-**Check logs:**
-
-1. Open app developer menu
-2. Check sync error message
-3. Review server logs
-
-**Common causes:**
-
-- Network timeout
-- Server error
-- Authentication expired
-- File too large
-
-### Issue: Attachments won't upload
-
-**Check:**
-
-1. File size (may be too large)
-2. Network connection
-3. Server storage space
-4. Retry from Sync screen
-
-## Related Content
-
-- [Forms Overview](/docs/build/forms/overview)
-- [Data Export](/docs/build/data-management/export)
-- [Synchronization](/docs/build/synchronization/overview)
-- [Database Schema](/docs/technical-overview/database/schema)
diff --git a/docs/build/data-management/overview.md b/docs/build/data-management/overview.md
deleted file mode 100644
index 18e3857..0000000
--- a/docs/build/data-management/overview.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-sidebar_position: 1
----
-
-# Data Management Overview
-
-Manage observations, attachments, and other data in ODE.
-
-## Overview
-
-[Description placeholder]
-
-## Key Topics
-
-- [Observations](/docs/build/data-management/observations)
-- [Attachments](/docs/build/data-management/attachments)
-- [Data Export](/docs/build/data-management/export)
-- [Data Import](/docs/build/data-management/import)
-
-## Related Content
-
-- [Database Schema](/docs/technical-overview/database/schema)
-- [Synchronization](/docs/build/synchronization/overview)
-
diff --git a/docs/build/forms/advanced-features/attachments.md b/docs/build/forms/advanced-features/attachments.md
deleted file mode 100644
index 22dc832..0000000
--- a/docs/build/forms/advanced-features/attachments.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 3
----
-
-# File Attachments
-
-Handle file attachments in forms.
-
-## Overview
-
-[Description placeholder]
-
-## Supported Formats
-
-[Description placeholder]
-
-## Attachment Management
-
-[Description placeholder]
-
-## Related Content
-
-- [Multimedia in Forms](/docs/build/forms/advanced-features/multimedia)
-- [Data Management](/docs/build/data-management/attachments)
-
diff --git a/docs/build/forms/advanced-features/location.md b/docs/build/forms/advanced-features/location.md
deleted file mode 100644
index e9288ab..0000000
--- a/docs/build/forms/advanced-features/location.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 2
----
-
-# GPS & Location
-
-Capture and use location data in forms.
-
-## Overview
-
-[Description placeholder]
-
-## GPS Capture
-
-[Description placeholder]
-
-## Location Display
-
-[Description placeholder]
-
-## Related Content
-
-- [Form Design](/docs/build/forms/design/schema-definition)
-- [Formulus Features](/docs/components/formulus/features)
-
diff --git a/docs/build/forms/design/conditional-logic.md b/docs/build/forms/design/conditional-logic.md
deleted file mode 100644
index 8248765..0000000
--- a/docs/build/forms/design/conditional-logic.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 4
----
-
-# Conditional Logic
-
-Implement conditional logic in forms.
-
-## Overview
-
-[Description placeholder]
-
-## Conditional Display
-
-[Description placeholder]
-
-## Conditional Validation
-
-[Description placeholder]
-
-## Related Content
-
-- [UI Schema Configuration](/docs/build/forms/design/ui-schema)
-- [Validation Rules](/docs/build/forms/design/validation)
-
diff --git a/docs/build/forms/design/schema-definition.md b/docs/build/forms/design/schema-definition.md
deleted file mode 100644
index 2877163..0000000
--- a/docs/build/forms/design/schema-definition.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-sidebar_position: 1
----
-
-# Schema Definition
-
-Define form data structure using JSON Schema.
-
-## Overview
-
-[Description placeholder]
-
-## Basic Schema
-
-[Description placeholder]
-
-## Field Types
-
-[Description placeholder]
-
-## Validation
-
-[Description placeholder]
-
-## Related Content
-
-- [UI Schema Configuration](/docs/build/forms/design/ui-schema)
-- [Validation Rules](/docs/build/forms/design/validation)
-
diff --git a/docs/build/forms/design/ui-schema.md b/docs/build/forms/design/ui-schema.md
deleted file mode 100644
index 9d15f78..0000000
--- a/docs/build/forms/design/ui-schema.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 2
----
-
-# UI Schema Configuration
-
-Configure form layout using JSON Forms UI Schema.
-
-## Overview
-
-[Description placeholder]
-
-## Layout Options
-
-[Description placeholder]
-
-## Custom Renderers
-
-[Description placeholder]
-
-## Related Content
-
-- [Schema Definition](/docs/build/forms/design/schema-definition)
-- [JSON Forms UI Schema](https://jsonforms.io/docs/uischema)
-
diff --git a/docs/build/forms/design/validation.md b/docs/build/forms/design/validation.md
deleted file mode 100644
index 9ccd31e..0000000
--- a/docs/build/forms/design/validation.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 3
----
-
-# Validation Rules
-
-Define validation rules for form fields.
-
-## Overview
-
-[Description placeholder]
-
-## Built-in Validators
-
-[Description placeholder]
-
-## Custom Validators
-
-[Description placeholder]
-
-## Related Content
-
-- [Schema Definition](/docs/build/forms/design/schema-definition)
-- [Conditional Logic](/docs/build/forms/design/conditional-logic)
-
diff --git a/docs/build/forms/overview.md b/docs/build/forms/overview.md
deleted file mode 100644
index 6ee8841..0000000
--- a/docs/build/forms/overview.md
+++ /dev/null
@@ -1,178 +0,0 @@
----
-sidebar_position: 1
----
-
-# Forms Overview
-
-Create and configure data collection forms in ODE.
-
-## Understanding Forms
-
-Forms in ODE are defined using **JSON Schema** for data structure and **JSON Forms UI Schema** for layout.
-
-A **form** is a template that defines:
-- What data to collect (schema)
-- How to display it (UI)
-- Validation rules
-- Conditional logic
-
-## Form Structure
-
-### Required Files
-
-Each form requires two files:
-
-```
-forms/
-└── myform/
- ├── schema.json # Data structure (JSON Schema)
- └── ui.json # Display layout (UI Schema)
-```
-
-### schema.json
-
-Defines the data structure using JSON Schema draft-07:
-
-```json
-{
- "$schema": "http://json-schema.org/draft-07/schema#",
- "type": "object",
- "title": "Patient Registration",
- "description": "Register a new patient",
- "properties": {
- "firstName": {
- "type": "string",
- "title": "First Name",
- "minLength": 1,
- "maxLength": 100
- },
- "lastName": {
- "type": "string",
- "title": "Last Name",
- "minLength": 1,
- "maxLength": 100
- },
- "dateOfBirth": {
- "type": "string",
- "format": "date",
- "title": "Date of Birth"
- },
- "gender": {
- "type": "string",
- "title": "Gender",
- "enum": ["male", "female", "other"]
- }
- },
- "required": ["firstName", "lastName", "dateOfBirth", "gender"]
-}
-```
-
-### ui.json
-
-Defines how the form is displayed:
-
-```json
-{
- "type": "Layout",
- "layout": "vertical",
- "elements": [
- {
- "type": "Label",
- "text": "Patient Information",
- "variant": "h5"
- },
- {
- "type": "Control",
- "scope": "#/properties/firstName"
- },
- {
- "type": "Control",
- "scope": "#/properties/lastName"
- },
- {
- "type": "Control",
- "scope": "#/properties/dateOfBirth"
- },
- {
- "type": "Control",
- "scope": "#/properties/gender",
- "options": {
- "format": "radio"
- }
- }
- ]
-}
-```
-
-## Data Flow
-
-```
-┌─────────────┐ ┌─────────────┐ ┌─────────────┐
-│ Forms │────▶│ User │────▶│ Observations│
-│ (Schema) │ │ (Mobile) │ │ (Data) │
-└─────────────┘ └─────────────┘ └──────┬──────┘
- │
- │ Sync
- ▼
- ┌─────────────┐
- │ Synkronus │
- │ (Server) │
- └─────────────┘
-```
-
-## Field Types
-
-Forms support various field types:
-
-| Field Type | Description | Schema Type |
-|------------|-------------|-------------|
-| **Text** | Single/multi-line text | `string` |
-| **Number** | Numeric values | `number`, `integer` |
-| **Date/Time** | Date and time selection | `string` with `format` |
-| **Select** | Single choice | `string` with `enum` |
-| **Multi-select** | Multiple choices | `array` |
-| **Boolean** | Checkbox/toggle | `boolean` |
-| **Photo** | Camera capture | `string` with `formulus:type: "photo"` |
-| **GPS** | Location capture | `object` with `formulus:type: "gps"` |
-| **Signature** | Digital signature | `string` with `formulus:type: "signature"` |
-| **Audio** | Voice recording | `string` with `formulus:type: "audio"` |
-| **QR Code** | Scan QR/barcode | `string` with `formulus:type: "qrcode"` |
-
-## Form Design
-
-- [Schema Definition](/docs/build/forms/design/schema-definition) - Define data structure
-- [UI Schema Configuration](/docs/build/forms/design/ui-schema) - Configure layout
-- [Validation Rules](/docs/build/forms/design/validation) - Add validation
-- [Conditional Logic](/docs/build/forms/design/conditional-logic) - Show/hide fields
-
-## Advanced Features
-
-- [Multimedia in Forms](/docs/build/forms/advanced-features/multimedia) - Photos, audio, video
-- [GPS & Location](/docs/build/forms/advanced-features/location) - Location capture
-- [File Attachments](/docs/build/forms/advanced-features/attachments) - File uploads
-
-## Best Practices
-
-### Form Design
-
-1. **Keep forms focused** - One purpose per form
-2. **Use clear labels** - Avoid jargon
-3. **Group related fields** - Use sections
-4. **Mark required fields** - Use schema `required`
-5. **Add help text** - Guide users
-6. **Test on device** - Verify usability
-
-### Schema Design
-
-1. **Use appropriate types** - String, number, boolean
-2. **Add validation** - minLength, maximum, pattern
-3. **Use enums** - For fixed choices
-4. **Document fields** - Use `description`
-5. **Version schemas** - Track changes
-
-## Related Content
-
-- [Form Versioning](/docs/build/forms/versioning)
-- [Observations](/docs/build/data-management/observations)
-- [JSON Forms Documentation](https://jsonforms.io)
-- [JSON Schema Documentation](https://json-schema.org)
diff --git a/docs/build/forms/versioning.md b/docs/build/forms/versioning.md
deleted file mode 100644
index ef53548..0000000
--- a/docs/build/forms/versioning.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 5
----
-
-# Form Versioning
-
-Manage form versions and updates.
-
-## Overview
-
-[Description placeholder]
-
-## Version Strategy
-
-[Description placeholder]
-
-## Migration
-
-[Description placeholder]
-
-## Related Content
-
-- [App Bundle Versioning](/docs/technical-overview/concepts/app-bundles)
-- [Custom Applications](/docs/build/custom-applications/deployment)
-
diff --git a/docs/build/index.md b/docs/build/index.md
deleted file mode 100644
index 5201715..0000000
--- a/docs/build/index.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-sidebar_position: 1
----
-
-# Build
-
-Build ODE applications and forms.
-
-## Overview
-
-This section provides guides for building ODE applications, creating forms, and managing data.
-
-ODE applications are built using JSON Schema for form definitions, JSON Forms for UI layouts, and custom web applications that integrate with the ODE platform. All ODE applications share the same foundation, providing consistent capabilities across different implementations.
-
-
-
-
-
-
-
-
diff --git a/docs/build/synchronization/conflict-resolution.md b/docs/build/synchronization/conflict-resolution.md
deleted file mode 100644
index bfa595a..0000000
--- a/docs/build/synchronization/conflict-resolution.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 3
----
-
-# Conflict Resolution
-
-How ODE handles synchronization conflicts.
-
-## Overview
-
-[Description placeholder]
-
-## Conflict Types
-
-[Description placeholder]
-
-## Resolution Strategies
-
-[Description placeholder]
-
-## Related Content
-
-- [Sync Protocol](/docs/build/synchronization/sync-protocol)
-- [Offline-First Architecture](/docs/technical-overview/concepts/offline-first)
-
diff --git a/docs/build/synchronization/overview.md b/docs/build/synchronization/overview.md
deleted file mode 100644
index d8cbca4..0000000
--- a/docs/build/synchronization/overview.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 1
----
-
-# Synchronization Overview
-
-How data synchronization works in ODE.
-
-## Overview
-
-[Description placeholder]
-
-## Sync Protocol
-
-[Description placeholder]
-
-## Conflict Resolution
-
-[Description placeholder]
-
-## Related Content
-
-- [Sync Protocol Details](/docs/build/synchronization/sync-protocol)
-- [Conflict Resolution](/docs/build/synchronization/conflict-resolution)
-
diff --git a/docs/build/synchronization/sync-protocol.md b/docs/build/synchronization/sync-protocol.md
deleted file mode 100644
index f912fb8..0000000
--- a/docs/build/synchronization/sync-protocol.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 2
----
-
-# Sync Protocol
-
-Technical details of the ODE synchronization protocol.
-
-## Overview
-
-[Description placeholder]
-
-## Pull Operations
-
-[Description placeholder]
-
-## Push Operations
-
-[Description placeholder]
-
-## Related Content
-
-- [Conflict Resolution](/docs/build/synchronization/conflict-resolution)
-- [Data Flow](/docs/technical-overview/architecture/data-flow)
-
diff --git a/docs/build/synchronization/troubleshooting.md b/docs/build/synchronization/troubleshooting.md
deleted file mode 100644
index 07ef091..0000000
--- a/docs/build/synchronization/troubleshooting.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 4
----
-
-# Troubleshooting Synchronization
-
-Common synchronization issues and solutions.
-
-## Overview
-
-[Description placeholder]
-
-## Common Issues
-
-[Description placeholder]
-
-## Debugging
-
-[Description placeholder]
-
-## Related Content
-
-- [Sync Protocol](/docs/build/synchronization/sync-protocol)
-- [Formulus Troubleshooting](/docs/components/formulus/troubleshooting)
-
diff --git a/docs/build/translations.md b/docs/build/translations.md
deleted file mode 100644
index b35f7bb..0000000
--- a/docs/build/translations.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-sidebar_position: 6
----
-
-# Translations
-
-Configure translations and multi-language support.
-
-## Overview
-
-[Description placeholder]
-
-## Translation Files
-
-[Description placeholder]
-
-## Configuration
-
-[Description placeholder]
-
-## Related Content
-
-- [Form Design](/docs/build/forms/design/schema-definition)
-- [Custom Applications](/docs/build/custom-applications/overview)
-
diff --git a/docs/build/users-authentication.md b/docs/build/users-authentication.md
deleted file mode 100644
index 0366505..0000000
--- a/docs/build/users-authentication.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-sidebar_position: 5
----
-
-# Users & Authentication
-
-Manage users and authentication in ODE.
-
-## Overview
-
-[Description placeholder]
-
-## User Management
-
-[Description placeholder]
-
-## Authentication
-
-[Description placeholder]
-
-## Permissions
-
-[Description placeholder]
-
-## Related Content
-
-- [Synkronus API](/docs/reference/rest-api/authentication)
-- [Hosting Security](/docs/host/security)
-
diff --git a/docs/community/.gitkeep b/docs/community/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/community/examples.md b/docs/community/examples.md
new file mode 100644
index 0000000..46819f4
--- /dev/null
+++ b/docs/community/examples.md
@@ -0,0 +1,344 @@
+---
+sidebar_position: 2
+---
+
+# Examples
+
+Example ODE applications, forms, and configurations to help you get started.
+
+## Form Examples
+
+### Basic Survey Form
+
+A simple form collecting name and age:
+
+```json
+{
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Full Name"
+ },
+ "age": {
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+ }
+ },
+ "required": ["name", "age"]
+}
+```
+
+### Health Survey Form
+
+Example health survey form collecting patient information:
+
+```json
+{
+ "type": "object",
+ "properties": {
+ "patientId": {
+ "type": "string",
+ "title": "Patient ID"
+ },
+ "visitDate": {
+ "type": "string",
+ "format": "date",
+ "title": "Visit Date"
+ },
+ "symptoms": {
+ "type": "array",
+ "title": "Symptoms",
+ "items": {
+ "type": "string",
+ "enum": ["fever", "cough", "headache", "fatigue"]
+ }
+ },
+ "temperature": {
+ "type": "number",
+ "title": "Temperature (°C)",
+ "minimum": 35,
+ "maximum": 42
+ },
+ "notes": {
+ "type": "string",
+ "title": "Clinical Notes"
+ }
+ },
+ "required": ["patientId", "visitDate"]
+}
+```
+
+### Research Data Collection Form
+
+Example research form for field data collection:
+
+```json
+{
+ "type": "object",
+ "properties": {
+ "siteId": {
+ "type": "string",
+ "title": "Site ID"
+ },
+ "location": {
+ "type": "string",
+ "format": "gps",
+ "title": "Site Location"
+ },
+ "sitePhoto": {
+ "type": "object",
+ "format": "photo",
+ "title": "Site Photo"
+ },
+ "observations": {
+ "type": "string",
+ "title": "Field Observations"
+ },
+ "timestamp": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Observation Time"
+ }
+ },
+ "required": ["siteId", "location"]
+}
+```
+
+## Custom Application Examples
+
+### Basic Custom App
+
+Simple custom application that lists available forms:
+
+```html
+
+
+
+ Form Selector
+
+
+
+
+
Available Forms
+
+
+
+
+
+```
+
+### Advanced Custom App
+
+Advanced custom applications can include complex workflows, custom navigation, and integration with external systems. Examples of advanced patterns will be added as they become available. For now, see the [Custom Applications guide](/guides/custom-applications) for detailed implementation guidance.
+
+## Configuration Examples
+
+### Server Configuration
+
+Example server configuration for development:
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=debug
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+```
+
+### Docker Compose Configuration
+
+Example Docker Compose configuration for production:
+
+```yaml
+version: '3.8'
+
+services:
+ postgres:
+ image: postgres:15
+ environment:
+ POSTGRES_PASSWORD: ${DB_ROOT_PASSWORD}
+ volumes:
+ - postgres-data:/var/lib/postgresql/data
+
+ synkronus:
+ image: ghcr.io/opendataensemble/synkronus:latest
+ environment:
+ DB_CONNECTION: postgres://synkronus:${DB_PASSWORD}@postgres:5432/synkronus?sslmode=disable
+ JWT_SECRET: ${JWT_SECRET}
+ LOG_LEVEL: info
+ depends_on:
+ - postgres
+ volumes:
+ - app-bundles:/app/data/app-bundles
+
+ nginx:
+ image: nginx:alpine
+ ports:
+ - "80:80"
+ volumes:
+ - ./nginx.conf:/etc/nginx/nginx.conf
+ depends_on:
+ - synkronus
+
+volumes:
+ postgres-data:
+ app-bundles:
+```
+
+## Integration Examples
+
+### API Integration
+
+Example API integration using different methods:
+
+
+
+
+```bash
+# Authenticate
+TOKEN=$(curl -X POST http://your-server:8080/auth/login \
+ -H "Content-Type: application/json" \
+ -d '{"username":"user","password":"pass"}' \
+ | jq -r '.token')
+
+# Pull data
+curl -X POST http://your-server:8080/sync/pull \
+ -H "Authorization: Bearer $TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"client_id":"my-client","since_change_id":0}'
+
+# Push data
+curl -X POST http://your-server:8080/sync/push \
+ -H "Authorization: Bearer $TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "transmission_id": "550e8400-e29b-41d4-a716-446655440000",
+ "client_id": "my-client",
+ "records": [...]
+ }'
+```
+
+
+
+
+```bash
+# Login (stores token automatically)
+synk login --username user
+
+# Pull data
+synk sync pull data.json --client-id my-client
+
+# Push data
+synk sync push data.json
+```
+
+
+
+
+```python
+import requests
+
+# Authenticate
+response = requests.post(
+ 'http://your-server:8080/auth/login',
+ json={'username': 'user', 'password': 'pass'}
+)
+token = response.json()['token']
+
+# Pull data
+response = requests.post(
+ 'http://your-server:8080/sync/pull',
+ headers={'Authorization': f'Bearer {token}'},
+ json={'client_id': 'my-client', 'since_change_id': 0}
+)
+data = response.json()
+```
+
+
+
+
+### Data Export Examples
+
+Export observations using different methods:
+
+
+
+
+```bash
+# Export all observations
+synk data export observations.zip
+
+# Export to specific directory
+synk data export ./backups/observations_$(date +%Y%m%d).zip
+
+# Export to JSON
+synk data export observations.json --format json
+```
+
+
+
+
+```bash
+# Export to Parquet ZIP
+curl -X GET http://your-server:8080/api/dataexport/parquet \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -o observations.zip
+```
+
+
+
+
+1. Navigate to the Portal
+2. Go to "Data Export"
+3. Select format (Parquet, JSON, CSV)
+4. Click "Export" to download
+
+
+
+
+The exported ZIP contains Parquet files organized by schema type, suitable for analysis in tools like Python pandas, R, or data analysis platforms.
+
+## Community Projects
+
+Projects built by the ODE community will be showcased here as they become available.
+
+## Contributing Examples
+
+If you have examples you'd like to share, please:
+
+1. Create a pull request with your example
+2. Include clear documentation
+3. Follow the existing example format
+4. Ensure examples are tested and working
+
+## Related Resources
+
+- [Form Design Guide](/guides/form-design)
+- [Custom Applications Guide](/guides/custom-applications)
+- [API Reference](/reference/api)
+- [Getting Help](/community/getting-help)
diff --git a/docs/community/getting-help.md b/docs/community/getting-help.md
new file mode 100644
index 0000000..20f08b9
--- /dev/null
+++ b/docs/community/getting-help.md
@@ -0,0 +1,74 @@
+---
+sidebar_position: 1
+---
+
+# Getting Help
+
+Resources and channels for getting help with ODE.
+
+## Support Channels
+
+### Documentation
+
+The first place to look for help is this documentation site. It covers:
+
+- Installation and setup guides
+- Usage instructions
+- API reference
+- Troubleshooting guides
+- FAQ section
+
+### GitHub
+
+- **Issues**: Report bugs, request features, or ask questions on [GitHub Issues](https://github.com/OpenDataEnsemble/ode/issues)
+- **Discussions**: Join discussions on [GitHub Discussions](https://github.com/OpenDataEnsemble/ode/discussions)
+- **Repository**: Browse the source code at [GitHub Repository](https://github.com/OpenDataEnsemble/ode)
+
+### Email
+
+For general inquiries or to get involved:
+
+- **Email**: [hello@opendataensemble.org](mailto:hello@opendataensemble.org)
+
+## Before Asking for Help
+
+To get the most effective help, please:
+
+1. **Search existing resources**: Check the documentation, FAQ, and existing GitHub issues
+2. **Provide context**: Include relevant information about your setup, error messages, and what you've tried
+3. **Be specific**: Describe the problem clearly and include steps to reproduce if applicable
+
+## Common Issues
+
+Many common issues are covered in the [Troubleshooting guide](/using/troubleshooting). Check there first for:
+
+- Connection issues
+- Synchronization problems
+- Form-related errors
+- Data management issues
+- Performance problems
+
+## Reporting Issues
+
+When reporting issues on GitHub, please include:
+
+- **Description**: Clear description of the problem
+- **Steps to reproduce**: If applicable, steps to reproduce the issue
+- **Expected behavior**: What you expected to happen
+- **Actual behavior**: What actually happened
+- **Environment**: Operating system, ODE version, component versions
+- **Error messages**: Any error messages or logs
+- **Screenshots**: If applicable, screenshots showing the issue
+
+See [Reporting Issues on GitHub](https://github.com/OpenDataEnsemble/ode/issues/new) to create a new issue.
+
+## Contributing
+
+If you'd like to contribute to ODE, see the [Contributing guide](/development/contributing) for information on how to get started.
+
+## Related Resources
+
+- [FAQ](/getting-started/faq)
+- [Troubleshooting Guide](/using/troubleshooting)
+- [GitHub Issues](https://github.com/OpenDataEnsemble/ode/issues)
+- [Examples](/community/examples)
diff --git a/docs/community/index.md b/docs/community/index.md
index 795a41a..e590363 100644
--- a/docs/community/index.md
+++ b/docs/community/index.md
@@ -1,35 +1,40 @@
---
-sidebar_position: 1
+sidebar_position: 0
---
# Community
-Get involved with the ODE community.
+Connect with the ODE community, get help, and share your experiences.
-## Overview
+## Get Help & Support
-Join the ODE community to contribute, get help, and stay updated.
+
diff --git a/docs/development/installing-formulus-dev.md b/docs/development/installing-formulus-dev.md
new file mode 100644
index 0000000..0156b8e
--- /dev/null
+++ b/docs/development/installing-formulus-dev.md
@@ -0,0 +1,510 @@
+---
+sidebar_position: 2
+---
+
+# Installing Formulus for Development
+
+Complete guide for developers to install Formulus on physical devices or emulators using ADB or development builds.
+
+## Overview
+
+Developers can install Formulus on Android devices or emulators using several methods:
+
+- **ADB Installation** - Install APK directly via Android Debug Bridge
+- **Android Emulator** - Run and test on virtual devices
+- **Development Build** - Build and run from source with hot reload
+
+This guide covers cross-platform commands for Linux, macOS, and Windows.
+
+## Prerequisites
+
+Before installing, ensure you have:
+
+| Requirement | Description |
+|-------------|-------------|
+| **Android SDK** | Android SDK Platform Tools (includes ADB) |
+| **ADB** | Android Debug Bridge (part of SDK Platform Tools) |
+| **USB Drivers** | Device-specific USB drivers (for physical devices) |
+| **Developer Options** | Enabled on Android device (for physical devices) |
+| **USB Debugging** | Enabled on Android device (for physical devices) |
+
+### Installing Android SDK Platform Tools
+
+
+
+
+```bash
+# Ubuntu/Debian
+sudo apt-get update
+sudo apt-get install android-tools-adb android-tools-fastboot
+
+# Fedora
+sudo dnf install android-tools
+
+# Arch Linux
+sudo pacman -S android-tools
+
+# Verify installation
+adb version
+```
+
+
+
+
+```bash
+# Using Homebrew
+brew install android-platform-tools
+
+# Verify installation
+adb version
+```
+
+
+
+
+1. **Download Android SDK Platform Tools** from [developer.android.com](https://developer.android.com/studio/releases/platform-tools)
+2. **Extract the ZIP file** to a location like `C:\platform-tools`
+3. **Add to PATH**:
+ - Open System Properties → Environment Variables
+ - Add `C:\platform-tools` to the PATH variable
+4. **Verify installation**:
+ ```powershell
+ adb version
+ ```
+
+
+
+
+## Method 1: ADB Installation on Physical Device
+
+### Step 1: Enable Developer Options
+
+1. **Open Settings** on your Android device
+2. **Navigate to About Phone** (or About Device)
+3. **Find "Build Number"** (usually at the bottom)
+4. **Tap "Build Number" 7 times** until you see "You are now a developer!"
+
+### Step 2: Enable USB Debugging
+
+1. **Go back to Settings**
+2. **Open Developer Options** (now visible in Settings)
+3. **Enable "USB Debugging"**
+4. **Accept the warning** about USB debugging
+
+### Step 3: Connect Device
+
+1. **Connect your device** to your computer via USB cable
+2. **On your device**, you may see a prompt: "Allow USB debugging?"
+3. **Check "Always allow from this computer"** (optional but recommended)
+4. **Tap "Allow"**
+
+### Step 4: Verify Device Connection
+
+
+
+
+```bash
+adb devices
+```
+
+
+
+
+```powershell
+adb devices
+```
+
+
+
+
+**Expected output:**
+```
+List of devices attached
+ABC123XYZ456 device
+```
+
+If you see "unauthorized", check your device and accept the USB debugging prompt.
+
+### Step 5: Install Formulus APK
+
+#### Option A: Install from Local APK File
+
+
+
+
+```bash
+# Navigate to directory containing APK
+cd /path/to/formulus/android/app/build/outputs/apk/debug
+
+# Install APK
+adb install app-debug.apk
+```
+
+
+
+
+```powershell
+# Navigate to directory containing APK
+cd C:\path\to\formulus\android\app\build\outputs\apk\debug
+
+# Install APK
+adb install app-debug.apk
+```
+
+
+
+
+#### Option B: Install from Remote URL
+
+
+
+
+```bash
+# Download and install in one command
+curl -L https://github.com/OpenDataEnsemble/ode/releases/download/v1.0.0/formulus.apk -o /tmp/formulus.apk
+adb install /tmp/formulus.apk
+```
+
+
+
+
+```powershell
+# Download and install
+Invoke-WebRequest -Uri "https://github.com/OpenDataEnsemble/ode/releases/download/v1.0.0/formulus.apk" -OutFile "$env:TEMP\formulus.apk"
+adb install "$env:TEMP\formulus.apk"
+```
+
+
+
+
+### Step 6: Verify Installation
+
+
+
+
+```bash
+# Check if app is installed
+adb shell pm list packages | grep formulus
+
+# Launch the app
+adb shell am start -n com.opendataensemble.formulus/.MainActivity
+```
+
+
+
+
+```powershell
+# Check if app is installed
+adb shell pm list packages | Select-String formulus
+
+# Launch the app
+adb shell am start -n com.opendataensemble.formulus/.MainActivity
+```
+
+
+
+
+## Method 2: Android Emulator Installation
+
+### Step 1: Set Up Android Emulator
+
+#### Using Android Studio
+
+1. **Install Android Studio** from [developer.android.com](https://developer.android.com/studio)
+2. **Open Android Studio** → **Tools** → **Device Manager**
+3. **Create Virtual Device** → Select a device (e.g., Pixel 5)
+4. **Select System Image** (e.g., Android 11, API 30)
+5. **Finish** and start the emulator
+
+#### Using Command Line (Linux/macOS)
+
+```bash
+# Install emulator via SDK Manager
+sdkmanager "emulator" "platform-tools" "platforms;android-30"
+
+# List available system images
+sdkmanager --list | grep system-images
+
+# Create AVD (Android Virtual Device)
+avdmanager create avd -n formulus_emulator -k "system-images;android-30;google_apis;x86_64"
+
+# Start emulator
+emulator -avd formulus_emulator &
+```
+
+### Step 2: Verify Emulator Connection
+
+
+
+
+```bash
+# Wait for emulator to boot (may take 1-2 minutes)
+adb devices
+
+# Should show emulator
+List of devices attached
+emulator-5554 device
+```
+
+
+
+
+```powershell
+adb devices
+```
+
+
+
+
+### Step 3: Install Formulus on Emulator
+
+
+
+
+```bash
+# Build APK first (if not already built)
+cd formulus
+npm run android
+
+# Install on emulator
+adb -s emulator-5554 install android/app/build/outputs/apk/debug/app-debug.apk
+```
+
+
+
+
+```powershell
+# Build APK first
+cd formulus
+npm run android
+
+# Install on emulator
+adb -s emulator-5554 install android\app\build\outputs\apk\debug\app-debug.apk
+```
+
+
+
+
+### Step 4: Important Notes for Emulator
+
+When configuring Formulus on an emulator to connect to a local server:
+
+- **Use `10.0.2.2` instead of `localhost`** - This is the special IP that the emulator uses to access the host machine
+- **Example server URL**: `http://10.0.2.2:8080`
+- **For network servers**: Use the actual IP address or domain name
+
+## Method 3: Development Build with Hot Reload
+
+### Prerequisites
+
+- **Node.js** 18+ and npm
+- **React Native CLI** or **Expo CLI**
+- **Java Development Kit (JDK)** 11 or higher
+- **Android Studio** with Android SDK
+
+### Step 1: Install Dependencies
+
+
+
+
+```bash
+cd formulus
+npm install
+```
+
+
+
+
+### Step 2: Start Metro Bundler
+
+
+
+
+```bash
+# In formulus directory
+npm start
+```
+
+Keep this terminal open. Metro is the JavaScript bundler for React Native.
+
+
+
+
+### Step 3: Build and Run on Device/Emulator
+
+
+
+
+```bash
+# For Android device (connected via USB)
+npm run android
+
+# For Android emulator (must be running)
+npm run android
+```
+
+
+
+
+This command will:
+1. Build the Android app
+2. Install it on your device/emulator
+3. Start the app
+4. Connect to Metro bundler for hot reload
+
+### Step 4: Development Features
+
+With development build, you get:
+
+- **Hot Reload** - Changes reflect immediately
+- **Fast Refresh** - React components update without losing state
+- **Debug Menu** - Shake device or press `Ctrl+M` (Windows/Linux) or `Cmd+M` (macOS)
+- **React Native Debugger** - Debug JavaScript code in Chrome DevTools
+
+## Common ADB Commands
+
+### Useful Commands for Development
+
+**List connected devices:**
+```bash
+adb devices
+```
+
+**Install APK:**
+```bash
+adb install path/to/app.apk
+```
+
+**Uninstall app:**
+```bash
+adb uninstall com.opendataensemble.formulus
+```
+
+**Reinstall app (uninstall + install):**
+```bash
+adb install -r path/to/app.apk
+```
+
+**View app logs:**
+```bash
+# All logs
+adb logcat
+
+# Filter for Formulus only
+adb logcat | grep -i formulus
+
+# Clear logs
+adb logcat -c
+```
+
+**Pull file from device:**
+```bash
+adb pull /path/on/device /path/on/computer
+```
+
+**Push file to device:**
+```bash
+adb push /path/on/computer /path/on/device
+```
+
+**Open app:**
+```bash
+adb shell am start -n com.opendataensemble.formulus/.MainActivity
+```
+
+**Stop app:**
+```bash
+adb shell am force-stop com.opendataensemble.formulus
+```
+
+**Clear app data:**
+```bash
+adb shell pm clear com.opendataensemble.formulus
+```
+
+## Troubleshooting
+
+### Device Not Detected
+
+**Problem**: `adb devices` shows no devices.
+
+**Solutions**:
+- Check USB cable connection
+- Try a different USB port
+- Install device-specific USB drivers (Windows)
+- Enable USB debugging on device
+- Accept USB debugging prompt on device
+- Restart ADB server: `adb kill-server && adb start-server`
+
+### Installation Fails
+
+**Problem**: `adb install` fails with error.
+
+**Solutions**:
+- Uninstall existing version first: `adb uninstall com.opendataensemble.formulus`
+- Use `-r` flag to reinstall: `adb install -r app.apk`
+- Check device has enough storage
+- Verify APK is not corrupted
+- Check device is in file transfer mode (not charging only)
+
+### Emulator Connection Issues
+
+**Problem**: Cannot connect to local server from emulator.
+
+**Solutions**:
+- Use `10.0.2.2` instead of `localhost` for server URL
+- Check firewall isn't blocking connections
+- Verify server is running and accessible
+- Use actual IP address instead of localhost
+
+### Permission Denied Errors
+
+**Problem**: ADB commands fail with permission errors.
+
+
+
+
+```bash
+# Add user to plugdev group
+sudo usermod -a -G plugdev $USER
+
+# Create udev rules
+sudo nano /etc/udev/rules.d/51-android.rules
+# Add: SUBSYSTEM=="usb", ATTR{idVendor}=="####", MODE="0664", GROUP="plugdev"
+
+# Reload udev rules
+sudo udevadm control --reload-rules
+sudo udevadm trigger
+
+# Log out and log back in
+```
+
+
+
+
+macOS typically doesn't require special permissions for ADB. If you encounter permission issues:
+
+1. Check USB cable connection
+2. Try a different USB port
+3. Restart ADB: `adb kill-server && adb start-server`
+4. Check System Preferences → Security & Privacy for blocked apps
+
+
+
+
+Windows typically handles USB device permissions automatically. If you encounter issues:
+
+1. Install device-specific USB drivers from manufacturer
+2. Check Device Manager for unrecognized devices
+3. Try different USB port or cable
+4. Restart ADB: `adb kill-server && adb start-server`
+
+
+
+
+## Related Documentation
+
+- [Formulus Development Setup](/development/formulus-development) - Complete development environment setup
+- [Formulus Component Reference](/reference/formulus) - Detailed component documentation
+- [Building and Testing](/development/building-testing) - Build and test procedures
+
diff --git a/docs/development/setup.md b/docs/development/setup.md
new file mode 100644
index 0000000..1a7c1fc
--- /dev/null
+++ b/docs/development/setup.md
@@ -0,0 +1,306 @@
+---
+sidebar_position: 1
+---
+
+# Development Setup
+
+Complete guide to setting up a development environment for ODE.
+
+## Prerequisites
+
+Before setting up the development environment, ensure you have:
+
+- **Node.js** 18.0 or higher
+- **npm** 9.0 or higher
+- **Go** 1.22 or higher (for server and CLI development)
+- **PostgreSQL** 13.0 or higher (for server development)
+- **Git** for version control
+- **Docker** and **Docker Compose** (optional, for containerized development)
+
+## Repository Structure
+
+ODE is a monorepo containing multiple components:
+
+```
+ode/
+├── formulus/ # React Native mobile app
+├── formulus-formplayer/ # React web form renderer
+├── synkronus/ # Go backend server
+├── synkronus-cli/ # Go command-line utility
+├── synkronus-portal/ # React web portal
+└── packages/
+ └── tokens/ # Design tokens package
+```
+
+## Clone the Repository
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode
+```
+
+## Formulus Development
+
+### Setup
+
+```bash
+cd formulus
+npm install
+```
+
+### Running
+
+```bash
+# Start Metro bundler
+npm start
+
+# Run on Android
+npm run android
+
+# Run on iOS (macOS only)
+npm run ios
+```
+
+### Code Quality
+
+ODE enforces consistent formatting and linting:
+
+```bash
+# Run linting
+npm run lint
+
+# Run linting with auto-fix
+npm run lint:fix
+
+# Format code
+npm run format
+
+# Check formatting (no writes)
+npm run format:check
+```
+
+### Generating Files
+
+```bash
+# Generate WebView injection script
+npm run generate
+
+# Generate API client from OpenAPI spec
+npm run generate:api
+```
+
+## Formplayer Development
+
+### Setup
+
+```bash
+cd formulus-formplayer
+npm install
+```
+
+### Running
+
+```bash
+# Development server
+npm start
+
+# Build for React Native
+npm run build:rn
+```
+
+### Code Quality
+
+```bash
+# Run linting
+npm run lint
+
+# Run linting with auto-fix
+npm run lint:fix
+
+# Format code
+npm run format
+
+# Check formatting (no writes)
+npm run format:check
+```
+
+## Synkronus Development
+
+### Setup
+
+```bash
+cd synkronus
+go mod download
+```
+
+### Configuration
+
+Create a `.env` file:
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-for-development
+LOG_LEVEL=debug
+APP_BUNDLE_PATH=./data/app-bundles
+```
+
+### Running
+
+```bash
+# Build
+go build -o bin/synkronus cmd/synkronus/main.go
+
+# Run
+./bin/synkronus
+
+# Or run directly
+go run cmd/synkronus/main.go
+```
+
+### Database Setup
+
+Ensure PostgreSQL is running and create a database:
+
+```sql
+CREATE DATABASE synkronus;
+```
+
+The schema will be created automatically on first run.
+
+## Synkronus CLI Development
+
+### Setup
+
+```bash
+cd synkronus-cli
+go mod download
+```
+
+### Building
+
+```bash
+# Build
+go build -o bin/synk ./cmd/synkronus
+
+# Run
+./bin/synk
+```
+
+## Development Workflow
+
+### 1. Create a Feature Branch
+
+```bash
+git checkout -b feature/your-feature-name
+```
+
+### 2. Make Changes
+
+Make your code changes following the coding standards.
+
+### 3. Test Locally
+
+```bash
+# Run tests
+npm test # For frontend projects
+go test ./... # For Go projects
+
+# Check code quality
+npm run lint
+npm run format:check
+```
+
+### 4. Commit Changes
+
+```bash
+git add .
+git commit -m "Description of changes"
+```
+
+### 5. Push and Create Pull Request
+
+```bash
+git push origin feature/your-feature-name
+```
+
+Create a pull request on GitHub.
+
+## Code Quality Standards
+
+### Frontend (React/React Native)
+
+- **Linting**: ESLint with project-specific rules
+- **Formatting**: Prettier with consistent configuration
+- **TypeScript**: Strict type checking enabled
+- **Testing**: Jest for unit tests
+
+### Backend (Go)
+
+- **Formatting**: `gofmt` or `goimports`
+- **Linting**: `golangci-lint` (if configured)
+- **Testing**: Standard Go testing package
+- **Documentation**: Godoc comments for exported functions
+
+### CI/CD
+
+The CI pipeline automatically:
+
+- Runs linting and formatting checks
+- Runs tests
+- Builds components
+- Publishes Docker images (for synkronus)
+
+## Development Tools
+
+### Recommended IDE Setup
+
+- **VS Code**: With extensions for TypeScript, Go, and React
+- **IntelliJ IDEA**: With Go and JavaScript plugins
+- **Android Studio**: For Android development
+- **Xcode**: For iOS development (macOS only)
+
+### Useful Commands
+
+```bash
+# Check all components
+cd formulus && npm run lint && cd ..
+cd formulus-formplayer && npm run lint && cd ..
+cd synkronus && go test ./... && cd ..
+
+# Format all code
+cd formulus && npm run format && cd ..
+cd formulus-formplayer && npm run format && cd ..
+cd synkronus && go fmt ./... && cd ..
+```
+
+## Troubleshooting
+
+### Node Modules Issues
+
+```bash
+# Clear and reinstall
+rm -rf node_modules package-lock.json
+npm install
+```
+
+### Go Module Issues
+
+```bash
+# Clean module cache
+go clean -modcache
+go mod download
+```
+
+### Database Connection Issues
+
+- Verify PostgreSQL is running
+- Check connection string format
+- Ensure database exists
+- Verify user permissions
+
+## Related Documentation
+
+- [Architecture Overview](/development/architecture)
+- [Contributing Guide](/development/contributing)
+- [Building & Testing](/development/building-testing)
diff --git a/docs/development/synkronus-development.md b/docs/development/synkronus-development.md
new file mode 100644
index 0000000..ce542d4
--- /dev/null
+++ b/docs/development/synkronus-development.md
@@ -0,0 +1,183 @@
+---
+sidebar_position: 5
+---
+
+# Synkronus Server Development
+
+Complete guide for developing the Synkronus server component.
+
+## Prerequisites
+
+- **Go** 1.22+
+- **PostgreSQL** 12+
+- **Git**
+
+## Local Development Setup
+
+### Step 1: Clone Repository
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+```
+
+### Step 2: Install Dependencies
+
+```bash
+go mod download
+```
+
+### Step 3: Set Up Database
+
+
+
+
+```bash
+# Create database
+createdb synkronus
+
+# Or using psql
+psql -U postgres -c "CREATE DATABASE synkronus;"
+```
+
+
+
+
+Using PowerShell or Command Prompt:
+
+```powershell
+# Using psql
+psql -U postgres -c "CREATE DATABASE synkronus;"
+```
+
+Or using Git Bash/WSL:
+
+```bash
+# Create database
+createdb synkronus
+
+# Or using psql
+psql -U postgres -c "CREATE DATABASE synkronus;"
+```
+
+
+
+
+### Step 4: Configure Environment
+
+Create `.env` file:
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://user:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=dev-secret-change-in-production
+LOG_LEVEL=debug
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+ADMIN_USERNAME=admin
+ADMIN_PASSWORD=admin
+```
+
+### Step 5: Create Directories
+
+```bash
+mkdir -p data/app-bundles
+```
+
+### Step 6: Run Server
+
+```bash
+go run cmd/synkronus/main.go
+```
+
+Or build and run:
+
+```bash
+go build -o bin/synkronus cmd/synkronus/main.go
+./bin/synkronus
+```
+
+## Development Workflow
+
+### Hot Reload
+
+Use tools like `air` for hot reload:
+
+```bash
+go install github.com/cosmtrek/air@latest
+air
+```
+
+### Testing
+
+```bash
+go test ./...
+```
+
+### API Documentation
+
+View OpenAPI docs:
+
+```bash
+# Server must be running
+open http://localhost:8080/openapi/swagger-ui.html
+```
+
+## Building for Production
+
+### Build Binary
+
+```bash
+go build -o bin/synkronus cmd/synkronus/main.go
+```
+
+### Cross-Platform Builds
+
+
+
+
+```bash
+GOOS=linux GOARCH=amd64 go build -o bin/synkronus-linux cmd/synkronus/main.go
+```
+
+
+
+
+```powershell
+$env:GOOS="windows"; $env:GOARCH="amd64"; go build -o bin/synkronus.exe cmd/synkronus/main.go
+```
+
+Or using bash (Git Bash/WSL):
+
+```bash
+GOOS=windows GOARCH=amd64 go build -o bin/synkronus.exe cmd/synkronus/main.go
+```
+
+
+
+
+```bash
+GOOS=darwin GOARCH=amd64 go build -o bin/synkronus-macos cmd/synkronus/main.go
+```
+
+
+
+
+## Docker Development
+
+### Using Docker Compose
+
+```bash
+docker compose up -d
+```
+
+### Development with Hot Reload
+
+Mount source code for live updates.
+
+## Related Documentation
+
+- [Synkronus Server Reference](/reference/synkronus-server) - Component reference
+- [Deployment Guide](/guides/deployment) - Production deployment
+- [Configuration Guide](/guides/configuration) - Configuration options
+
diff --git a/docs/development/synkronus-portal-development.md b/docs/development/synkronus-portal-development.md
new file mode 100644
index 0000000..fbfe969
--- /dev/null
+++ b/docs/development/synkronus-portal-development.md
@@ -0,0 +1,100 @@
+---
+sidebar_position: 6
+---
+
+# Synkronus Portal Development
+
+Complete guide for developing the Synkronus Portal web interface.
+
+## Prerequisites
+
+- **Node.js** 20+ and npm
+- **Go** 1.22+ (for backend)
+- **PostgreSQL** 17+ (for backend)
+
+## Local Development Setup
+
+
+
+
+#### Step 1: Set Up Backend
+
+See [Synkronus Development](/development/synkronus-development) for backend setup.
+
+#### Step 2: Set Up Frontend
+
+```bash
+cd synkronus-portal
+npm install
+```
+
+#### Step 3: Start Development Server
+
+```bash
+npm run dev
+```
+
+Portal available at http://localhost:5174
+
+
+
+
+#### Start Backend Services
+
+```bash
+docker compose up -d postgres synkronus
+```
+
+#### Start Frontend
+
+```bash
+cd synkronus-portal
+npm install
+npm run dev
+```
+
+Portal available at http://localhost:5174
+
+
+
+
+## Development Features
+
+- **Hot Module Replacement**: Instant code updates
+- **Fast Refresh**: React components update without losing state
+- **Source Maps**: Debug in browser DevTools
+- **Error Overlay**: Errors shown in browser
+
+## Building for Production
+
+### Build
+
+```bash
+npm run build
+```
+
+Output in `dist/` directory.
+
+### Docker Production Build
+
+```bash
+docker compose up -d --build
+```
+
+## Project Structure
+
+- `src/`: React source code
+- `src/components/`: Reusable components
+- `src/pages/`: Page components
+- `src/services/`: API service
+- `src/contexts/`: React contexts
+
+## Adding Features
+
+See [Synkronus Portal Reference](/reference/synkronus-portal) for detailed patterns.
+
+## Related Documentation
+
+- [Synkronus Portal Reference](/reference/synkronus-portal) - Component reference
+- [Deployment Guide](/guides/deployment) - Production deployment
+
diff --git a/docs/getting-started/.gitkeep b/docs/getting-started/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/getting-started/faq.md b/docs/getting-started/faq.md
new file mode 100644
index 0000000..36a25c1
--- /dev/null
+++ b/docs/getting-started/faq.md
@@ -0,0 +1,110 @@
+---
+sidebar_position: 5
+---
+
+# Frequently Asked Questions
+
+Common questions about ODE installation, usage, and development.
+
+## General Questions
+
+### What is ODE?
+
+Open Data Ensemble (ODE) is a platform for mobile data collection and synchronization. It provides tools for creating forms, collecting data offline, and synchronizing data across devices and servers.
+
+### Is ODE free to use?
+
+Yes, ODE is open source and free to use. The code is available under the MIT license.
+
+### What platforms does ODE support?
+
+ODE supports Android and iOS mobile devices. The server component runs on Linux, macOS, and Windows.
+
+### Do I need internet connectivity to use ODE?
+
+No, ODE is designed to work offline. Data is stored locally and synchronized when connectivity is available.
+
+## Installation Questions
+
+### What are the system requirements?
+
+See the [Prerequisites](/getting-started/installation/prerequisites) page for detailed system requirements.
+
+### Can I run ODE in the cloud?
+
+Yes, ODE can be deployed to cloud platforms such as AWS, Google Cloud, or Azure. See the [Deployment guide](/guides/deployment/production) for details.
+
+### Do I need a database?
+
+Yes, ODE requires PostgreSQL for data storage. The database schema is created automatically on first run.
+
+## Usage Questions
+
+### How do I create forms?
+
+Forms are defined using JSON schema. See the [Form Design guide](/guides/forms/overview) for details.
+
+### Can I customize the user interface?
+
+Yes, ODE supports custom applications and renderers. See [Custom Applications](/guides/custom-apps/overview) for details.
+
+### How does synchronization work?
+
+ODE uses a bidirectional sync protocol that pushes local data to the server and pulls new data from the server. See [Synchronization](/using/synchronization) for details.
+
+### What happens if two devices modify the same data?
+
+ODE automatically resolves conflicts using a version-based approach. The most recent version takes precedence.
+
+## Development Questions
+
+### How do I contribute to ODE?
+
+See the [Contributing guide](/development/contributing/guide) for information on how to contribute.
+
+### Can I extend ODE functionality?
+
+Yes, ODE is designed to be extensible. See [Extending ODE](/development/extending/overview) for details.
+
+### What programming languages are used?
+
+ODE uses React Native for mobile apps, React for web components, and Go for the server.
+
+## Troubleshooting
+
+### The app won't connect to the server
+
+- Verify the server is running and accessible
+- Check the server URL in app settings
+- Verify firewall and network settings
+- For Android emulator, use `10.0.2.2` instead of `localhost`
+
+### Forms are not appearing
+
+- Verify forms were uploaded to the server
+- Check that the app has synchronized
+- Review server logs for errors
+
+### Data is not synchronizing
+
+- Check network connectivity
+- Verify authentication credentials
+- Review server logs for sync errors
+- Ensure observations were saved locally
+
+### Build errors
+
+- Ensure all prerequisites are installed
+- Check that dependencies are up to date
+- Review error messages for specific issues
+- See component-specific documentation for build instructions
+
+## Getting Help
+
+If you cannot find an answer to your question:
+
+- Check the [Troubleshooting guide](/using/troubleshooting)
+- Review the [API Reference](/reference/api/overview)
+- Search [GitHub Issues](https://github.com/OpenDataEnsemble/ode/issues)
+- Ask questions in the [Community section](/community/getting-help)
+
diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md
new file mode 100644
index 0000000..329389c
--- /dev/null
+++ b/docs/getting-started/index.md
@@ -0,0 +1,85 @@
+---
+sidebar_position: 0
+---
+
+# Getting Started
+
+Welcome to ODE! This section will help you understand what ODE is, why you should use it, and how to get up and running quickly.
+
+## What You'll Learn
+
+Whether you're a researcher, developer, or data practitioner, these guides will help you get started with ODE and start collecting data efficiently.
+
+
+
+
+
+
What is ODE?
+
+
+
Learn about the Open Data Ensemble platform and its architecture.
+
+## Next Steps
+
+Once you've completed the getting started guides, explore the [Using ODE](/docs/using/your-first-form) section to learn how to create forms and manage data.
+
diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md
new file mode 100644
index 0000000..197d762
--- /dev/null
+++ b/docs/getting-started/installation.md
@@ -0,0 +1,420 @@
+---
+sidebar_position: 4
+---
+
+# Installation
+
+Complete installation guide for all ODE components. This guide covers prerequisites, server setup, and mobile app installation.
+
+## Prerequisites
+
+Before installing ODE components, ensure your system meets the following requirements.
+
+### System Requirements
+
+#### For Mobile Development (Formulus)
+
+| Requirement | Minimum | Recommended |
+|-------------|---------|-------------|
+| **Operating System** | macOS 10.15, Windows 10, or Linux | Latest stable version |
+| **Node.js** | 18.0 or higher | 20.0 or higher |
+| **npm** | 9.0 or higher | 10.0 or higher |
+| **Android Studio** | Latest stable | Latest stable |
+| **Xcode** | 14.0 or higher (macOS only) | Latest stable |
+| **Java Development Kit** | JDK 17 | JDK 17 or higher |
+
+#### For Server Deployment (Synkronus)
+
+| Requirement | Minimum | Recommended |
+|-------------|---------|-------------|
+| **Operating System** | Linux, macOS, or Windows | Linux |
+| **Go** | 1.22 or higher | Latest stable |
+| **PostgreSQL** | 13.0 or higher | 15.0 or higher |
+| **Docker** | 20.10 or higher (optional) | Latest stable |
+| **Memory** | 2 GB RAM | 4 GB RAM or more |
+| **Storage** | 10 GB free space | 50 GB or more |
+
+### Development Tools
+
+**Required Tools:**
+- Git: Version control system
+- Code Editor: Visual Studio Code, IntelliJ IDEA, or similar
+- Terminal: Command-line interface for running commands
+
+**Recommended Tools:**
+- Postman or curl: For testing API endpoints
+- pgAdmin or DBeaver: For database management
+- Docker Desktop: For containerized development
+
+### Verification
+
+Verify your installation by running:
+
+
+
+
+```bash
+# Check Node.js version
+node --version
+
+# Check npm version
+npm --version
+
+# Check Go version
+go version
+
+# Check PostgreSQL version
+psql --version
+
+# Check Docker version (if using)
+docker --version
+```
+
+
+
+
+Using PowerShell:
+
+```powershell
+# Check Node.js version
+node --version
+
+# Check npm version
+npm --version
+
+# Check Go version
+go version
+
+# Check PostgreSQL version
+psql --version
+
+# Check Docker version (if using)
+docker --version
+```
+
+Or using Git Bash/WSL (same commands as Linux/macOS):
+
+```bash
+node --version
+npm --version
+go version
+psql --version
+docker --version
+```
+
+
+
+
+## Installing Synkronus Server
+
+Synkronus is the backend server component of ODE, responsible for data synchronization, storage, and API services.
+
+
+
+
+The easiest way to run Synkronus is using Docker:
+
+```bash
+# Pull the latest image
+docker pull ghcr.io/opendataensemble/synkronus:latest
+
+# Run the container
+docker run -d \
+ --name synkronus \
+ -p 8080:8080 \
+ -e DB_CONNECTION="postgres://user:password@host:5432/synkronus" \
+ -e JWT_SECRET="your-secret-key-here" \
+ -v synkronus-bundles:/app/data/app-bundles \
+ ghcr.io/opendataensemble/synkronus:latest
+```
+
+
+
+
+For a complete setup with PostgreSQL:
+
+```bash
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Copy the example configuration
+cp docker-compose.example.yml docker-compose.yml
+
+# Edit docker-compose.yml with your configuration
+# Then start the services
+docker compose up -d
+```
+
+
+
+
+Build and run Synkronus from source:
+
+
+
+
+```bash
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Build the application
+go build -o bin/synkronus cmd/synkronus/main.go
+
+# Run the application
+./bin/synkronus
+```
+
+
+
+
+Using PowerShell:
+
+```powershell
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Build the application
+go build -o bin/synkronus.exe cmd/synkronus/main.go
+
+# Run the application
+.\bin\synkronus.exe
+```
+
+Or using Git Bash/WSL (same as Linux/macOS):
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+go build -o bin/synkronus cmd/synkronus/main.go
+./bin/synkronus
+```
+
+
+
+
+
+
+
+### Configuration
+
+Synkronus is configured using environment variables. Create a `.env` file or set environment variables:
+
+| Variable | Description | Default | Required |
+|----------|-------------|---------|----------|
+| `PORT` | HTTP server port | `8080` | No |
+| `DB_CONNECTION` | PostgreSQL connection string | - | Yes |
+| `JWT_SECRET` | Secret key for JWT signing | - | Yes |
+| `LOG_LEVEL` | Logging level (debug, info, warn, error) | `info` | No |
+| `APP_BUNDLE_PATH` | Directory for app bundles | `./data/app-bundles` | No |
+| `MAX_VERSIONS_KEPT` | Maximum app bundle versions to keep | `5` | No |
+
+**Example Configuration:**
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=info
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+```
+
+### Database Setup
+
+Before running Synkronus, set up a PostgreSQL database:
+
+
+
+
+```bash
+# Connect to PostgreSQL
+psql -U postgres
+```
+
+Then run SQL commands:
+
+```sql
+-- Create database
+CREATE DATABASE synkronus;
+
+-- Create user (optional)
+CREATE USER synkronus WITH PASSWORD 'your-password';
+GRANT ALL PRIVILEGES ON DATABASE synkronus TO synkronus;
+```
+
+
+
+
+Using PowerShell or Command Prompt:
+
+```powershell
+# Connect to PostgreSQL
+psql -U postgres
+```
+
+Then run SQL commands:
+
+```sql
+-- Create database
+CREATE DATABASE synkronus;
+
+-- Create user (optional)
+CREATE USER synkronus WITH PASSWORD 'your-password';
+GRANT ALL PRIVILEGES ON DATABASE synkronus TO synkronus;
+```
+
+Or using Git Bash/WSL (same as Linux/macOS):
+
+```bash
+psql -U postgres
+```
+
+
+
+
+```bash
+# Connect to PostgreSQL container
+docker compose exec postgres psql -U postgres
+```
+
+Then run SQL commands:
+
+```sql
+CREATE DATABASE synkronus;
+CREATE USER synkronus WITH PASSWORD 'your-password';
+GRANT ALL PRIVILEGES ON DATABASE synkronus TO synkronus;
+```
+
+
+
+
+The database schema will be created automatically on first run.
+
+### Verification
+
+Verify the installation:
+
+1. Check that the server is running:
+ ```bash
+ curl http://localhost:8080/health
+ ```
+
+2. Check the API documentation:
+ ```bash
+ curl http://localhost:8080/api/docs
+ ```
+
+## Installing Formulus App
+
+Formulus is the mobile application component of ODE, available for Android and iOS devices.
+
+For detailed installation instructions, see the [Installing Formulus guide](/getting-started/installing-formulus) which covers:
+
+- F-Droid installation (recommended for end users)
+- Direct APK installation
+- System requirements
+- Post-installation setup
+
+For developers who want to install via ADB or emulator, see the [Development Installation guide](/development/installing-formulus-dev).
+
+### Quick Installation Summary
+
+#### For End Users
+
+1. **F-Droid** (Recommended): Install via F-Droid app store
+2. **Direct APK**: Download and install APK file directly
+
+See [Installing Formulus](/getting-started/installing-formulus) for complete instructions.
+
+#### For Developers
+
+1. **ADB Installation**: Install via Android Debug Bridge
+2. **Emulator**: Run on Android emulator
+3. **Development Build**: Build from source with hot reload
+
+See [Installing Formulus for Development](/development/installing-formulus-dev) for complete instructions.
+
+### App Configuration
+
+After installation, configure the app to connect to your Synkronus server:
+
+1. Open the Formulus app
+2. Navigate to Settings
+3. Enter your server URL (e.g., `https://your-server.com`)
+4. Enter your authentication credentials
+5. Save the configuration
+
+## Installing Synkronus CLI
+
+The Synkronus CLI is a command-line utility for interacting with the Synkronus server.
+
+### Installation
+
+```bash
+go install github.com/OpenDataEnsemble/ode/synkronus-cli/cmd/synkronus@latest
+```
+
+Or build from source:
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode/synkronus-cli.git
+cd synkronus-cli
+go build -o bin/synk ./cmd/synkronus
+```
+
+### Configuration
+
+By default, the CLI uses a configuration file located at `$HOME/.synkronus.yaml`.
+
+**Example configuration file:**
+
+```yaml
+api:
+ url: http://localhost:8080
+ version: 1.0.0
+```
+
+You can override this per-command with `--config ` or use `synk config use ` to set a persistent default.
+
+## Troubleshooting
+
+### Server Not Accessible
+
+If the mobile app cannot connect to the server:
+
+- Verify the server is running: `curl http://localhost:8080/health`
+- Check firewall settings
+- For Android emulator, use `10.0.2.2` instead of `localhost`
+- For iOS simulator, use `localhost` or your machine's IP address
+
+### Database Connection Issues
+
+**Problem**: Cannot connect to database
+
+**Solution**: Verify the `DB_CONNECTION` string format and ensure PostgreSQL is running and accessible.
+
+### Port Already in Use
+
+**Problem**: Port 8080 is already in use
+
+**Solution**: Change the `PORT` environment variable to use a different port.
+
+### Build Errors
+
+**Problem**: Build fails with errors
+
+**Solution**:
+- Ensure all prerequisites are installed
+- Check that dependencies are up to date
+- Review error messages for specific issues
+- See component-specific documentation for build instructions
+
+## Next Steps
+
+- Follow the [Quick Start guide](/getting-started/quick-start) for a complete setup
+- Learn how to [use the app](/using/your-first-form) for data collection
+- Review the [Deployment guide](/guides/deployment) for production setup
+
diff --git a/docs/getting-started/installation/.gitkeep b/docs/getting-started/installation/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/getting-started/installing-formulus.md b/docs/getting-started/installing-formulus.md
new file mode 100644
index 0000000..29d0297
--- /dev/null
+++ b/docs/getting-started/installing-formulus.md
@@ -0,0 +1,232 @@
+---
+sidebar_position: 4
+---
+
+# Installing Formulus App
+
+Complete guide for installing the Formulus mobile application on Android devices.
+
+## Overview
+
+Formulus is available for Android devices through multiple installation methods. Choose the method that best fits your needs:
+
+- **F-Droid** (Recommended for end users) - Official app store for free and open source Android apps
+- **Direct APK** - Download and install the APK file directly
+- **Development Build** - For developers who want to build from source
+
+## System Requirements
+
+Before installing, ensure your device meets these requirements:
+
+| Requirement | Minimum |
+|-------------|---------|
+| **Android Version** | Android 7.0 (API level 24) or higher |
+| **Storage Space** | 50 MB free space |
+| **Internet Connection** | Required for initial setup and synchronization |
+| **Permissions** | Camera, Storage, Location (for form features) |
+
+## Installation Methods
+
+### Method 1: F-Droid (Recommended)
+
+F-Droid is the recommended installation method for end users. It provides automatic updates and ensures you're installing the official version.
+
+#### Step 1: Install F-Droid
+
+If you don't have F-Droid installed:
+
+1. **Download F-Droid** from [f-droid.org](https://f-droid.org/)
+2. **Enable installation from unknown sources**:
+ - Go to Settings → Security → Unknown Sources
+ - Enable the option for your browser or file manager
+3. **Install F-Droid** by opening the downloaded APK file
+
+#### Step 2: Add Formulus Repository
+
+1. **Open F-Droid** on your device
+2. **Navigate to Settings** → **Repositories**
+3. **Tap the "+" button** to add a new repository
+4. **Enter the Formulus repository URL** (provided by your organization)
+5. **Tap "Add"** to save the repository
+
+#### Step 3: Install Formulus
+
+1. **Open F-Droid** on your device
+2. **Navigate to the Updates tab** or search for "Formulus"
+3. **Find Formulus** in the app list
+4. **Tap on Formulus** to open the app details
+5. **Tap "Install"** to begin installation
+6. **Wait for installation** to complete
+7. **Tap "Open"** to launch the app
+
+#### Automatic Updates
+
+Once installed via F-Droid, Formulus will automatically update when new versions are available:
+
+1. **F-Droid checks for updates** periodically
+2. **Notifications appear** when updates are available
+3. **Tap the notification** or open F-Droid to update
+4. **Updates install automatically** through F-Droid
+
+### Method 2: Direct APK Installation
+
+If F-Droid is not available or you prefer direct installation:
+
+#### Step 1: Download the APK
+
+1. **Download the latest APK** from the [releases page](https://github.com/OpenDataEnsemble/ode/releases)
+2. **Save the file** to your device's Downloads folder
+
+#### Step 2: Enable Unknown Sources
+
+1. **Go to Settings** → **Security** (or **Apps** on newer Android versions)
+2. **Enable "Install unknown apps"** or **"Unknown Sources"**
+3. **Select your browser or file manager** and enable installation
+
+#### Step 3: Install the APK
+
+1. **Open your file manager** or Downloads app
+2. **Navigate to the Downloads folder**
+3. **Tap on the Formulus APK file**
+4. **Review the permissions** requested by the app
+5. **Tap "Install"** to begin installation
+6. **Wait for installation** to complete
+7. **Tap "Open"** to launch the app
+
+### Method 3: Development Build
+
+For developers who want to build and install from source, see the [Development Installation Guide](/development/formulus-development).
+
+## Post-Installation Setup
+
+After installing Formulus, you need to configure it to connect to your Synkronus server:
+
+### Initial Configuration
+
+1. **Open Formulus** on your device
+2. **You'll see the welcome screen** with configuration options
+3. **Choose your configuration method**:
+ - **QR Code Scan** (Recommended) - Scan a QR code with server details
+ - **Manual Entry** - Enter server URL and credentials manually
+
+### QR Code Configuration
+
+1. **Tap "Scan QR Code"** on the welcome screen
+2. **Grant camera permission** if prompted
+3. **Point the camera** at the QR code provided by your administrator
+4. **Settings auto-populate** with server URL, username, and password
+5. **Tap "Connect"** to verify and save the configuration
+
+### Manual Configuration
+
+1. **Tap "Manual Configuration"** on the welcome screen
+2. **Enter Server URL**: `http://your-server-ip:8080` or `https://your-server-domain`
+3. **Enter Username**: Your username provided by your administrator
+4. **Enter Password**: Your password
+5. **Tap "Test Connection"** to verify connectivity
+6. **Tap "Save"** to store the configuration
+
+### First Login
+
+1. **After configuration**, you'll be prompted to log in
+2. **Credentials should be pre-filled** (if using QR code)
+3. **Tap "Login"** to authenticate
+4. **Wait for authentication** - A token is stored locally for future sessions
+5. **You'll be redirected** to the main app interface
+
+## Verification
+
+To verify that Formulus is installed correctly:
+
+1. **Check app icon** appears in your app drawer
+2. **Open the app** and verify it launches without errors
+3. **Check Settings** to confirm server configuration is saved
+4. **Test connection** by tapping "Test Connection" in Settings
+5. **Verify login** by logging in with your credentials
+
+## Troubleshooting Installation
+
+### Installation Fails
+
+**Problem**: APK installation fails with "App not installed" error.
+
+**Solutions**:
+- Ensure you have enough storage space (at least 50 MB free)
+- Check that "Unknown Sources" is enabled for your file manager
+- Try downloading the APK again (file may be corrupted)
+- Ensure your device meets minimum Android version requirements (7.0+)
+
+### App Crashes on Launch
+
+**Problem**: Formulus crashes immediately after opening.
+
+**Solutions**:
+- Restart your device
+- Clear app data: Settings → Apps → Formulus → Storage → Clear Data
+- Uninstall and reinstall the app
+- Check that your device has sufficient RAM available
+
+### Cannot Connect to Server
+
+**Problem**: App cannot connect to the Synkronus server.
+
+**Solutions**:
+- Verify server URL is correct (check for typos)
+- Ensure device has internet connection
+- Check that server is running and accessible
+- Verify firewall settings aren't blocking the connection
+- For local development, use `10.0.2.2` instead of `localhost` on Android emulator
+
+### F-Droid Not Finding Updates
+
+**Problem**: F-Droid doesn't show Formulus updates.
+
+**Solutions**:
+- Ensure the Formulus repository is added correctly
+- Refresh F-Droid repositories: Settings → Repositories → Tap refresh
+- Check that F-Droid has internet connection
+- Verify repository URL is correct and accessible
+
+## Updating Formulus
+
+### Via F-Droid
+
+Updates are automatic when using F-Droid:
+
+1. **F-Droid checks for updates** automatically
+2. **Notification appears** when updates are available
+3. **Open F-Droid** and navigate to Updates tab
+4. **Tap "Update"** next to Formulus
+5. **Wait for download and installation**
+
+### Via Direct APK
+
+1. **Download the latest APK** from the releases page
+2. **Install over existing installation** (no need to uninstall)
+3. **App data is preserved** during update
+
+## Uninstalling Formulus
+
+To uninstall Formulus:
+
+1. **Go to Settings** → **Apps** (or **Application Manager**)
+2. **Find Formulus** in the app list
+3. **Tap on Formulus**
+4. **Tap "Uninstall"**
+5. **Confirm uninstallation**
+
+**Note**: Uninstalling will remove all local data, including:
+- Saved observations (not yet synced)
+- App configuration
+- Cached app bundles
+- Local database
+
+**Important**: Ensure all data is synced to the server before uninstalling.
+
+## Related Documentation
+
+- [Formulus Features](/using/formulus-features) - Learn about app features and usage
+- [Your First Form](/using/your-first-form) - Get started with data collection
+- [Synchronization](/using/synchronization) - Understand how data syncs work
+- [Development Installation](/development/formulus-development) - For developers building from source
+
diff --git a/docs/getting-started/key-concepts.md b/docs/getting-started/key-concepts.md
new file mode 100644
index 0000000..4a96564
--- /dev/null
+++ b/docs/getting-started/key-concepts.md
@@ -0,0 +1,102 @@
+---
+sidebar_position: 3
+---
+
+# Key Concepts
+
+Understanding these core concepts will help you work effectively with ODE.
+
+## Core Concepts
+
+### Forms
+
+Forms are the primary mechanism for data collection in ODE. A form consists of:
+
+- **Schema**: Defines the data structure and validation rules
+- **UI Schema**: Defines how the form is presented to users
+- **Question Types**: Define the input methods available (text, number, date, etc.)
+
+Forms are defined using JSON and follow the JSON Forms specification. See the [Form Design guide](/guides/forms/overview) for details.
+
+### Observations
+
+An observation is a single data record collected through a form. Each observation contains:
+
+- A unique identifier
+- The form type used to collect it
+- The data values entered by the user
+- Metadata such as creation time and last modification time
+- A sync status indicating whether it has been synchronized with the server
+
+### Synchronization
+
+Synchronization is the process of exchanging data between mobile devices and the server. ODE uses a bidirectional sync protocol that:
+
+- Pushes local observations to the server
+- Pulls new or updated observations from the server
+- Resolves conflicts when the same observation is modified on multiple devices
+- Handles attachments separately from observation metadata
+
+See [Synchronization](/using/synchronization) for more details.
+
+### App Bundles
+
+An app bundle is a collection of resources that define a custom application. It includes:
+
+- Custom HTML, CSS, and JavaScript files
+- Form specifications
+- Custom renderers for question types
+- Configuration files
+
+App bundles are uploaded to the server and downloaded by mobile devices during synchronization. See [Custom Applications](/guides/custom-apps/overview) for details.
+
+### Custom Applications
+
+Custom applications are web-based interfaces that run within the Formulus mobile app. They provide:
+
+- Custom navigation and user interfaces
+- Integration with the ODE form system
+- Access to observation data through the Formulus JavaScript interface
+
+Custom applications are defined in app bundles and can be tailored to specific use cases.
+
+## Data Flow
+
+The following diagram illustrates how data flows through the ODE system:
+
+```
+User Input → Form → Observation (Local) → Sync → Server → Database
+ ↓
+ Sync → Other Devices
+```
+
+1. User fills out a form on a mobile device
+2. An observation is created and stored locally
+3. When connectivity is available, the observation is synchronized to the server
+4. The server stores the observation in the database
+5. Other devices can pull the observation during their sync operations
+
+## Terminology
+
+| Term | Definition |
+|------|------------|
+| **Form** | A data collection interface defined by schema and UI schema |
+| **Observation** | A single data record collected through a form |
+| **Schema** | JSON schema defining the structure and validation rules for a form |
+| **UI Schema** | JSON schema defining the presentation of form fields |
+| **Question Type** | A component that handles a specific type of input (text, number, etc.) |
+| **Renderer** | A component that renders a question type in the form |
+| **Sync** | The process of exchanging data between devices and server |
+| **App Bundle** | A collection of resources defining a custom application |
+| **Custom App** | A web-based application that runs within Formulus |
+| **Formulus** | The mobile application component of ODE |
+| **Synkronus** | The server component of ODE |
+| **Formplayer** | The web-based form rendering component |
+
+## Related Documentation
+
+- [Form Design Guide](/guides/forms/overview)
+- [Synchronization Details](/using/synchronization)
+- [Custom Applications](/guides/custom-apps/overview)
+- [Architecture Overview](/development/architecture/overview)
+
diff --git a/docs/getting-started/quick-start.md b/docs/getting-started/quick-start.md
new file mode 100644
index 0000000..ede1381
--- /dev/null
+++ b/docs/getting-started/quick-start.md
@@ -0,0 +1,195 @@
+---
+sidebar_position: 5
+---
+
+# Quick Start
+
+Get up and running with ODE in approximately 15 minutes.
+
+## Overview
+
+This guide walks you through setting up a complete ODE environment and creating your first form.
+
+## Step 1: Start Synkronus Server
+
+Using Docker Compose is the fastest method:
+
+```bash
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Start the server with Docker Compose
+docker compose up -d
+```
+
+The server will be available at `http://localhost:8080`.
+
+## Step 2: Install Formulus App
+
+
+
+
+Download and install the APK from the [releases page](https://github.com/OpenDataEnsemble/ode/releases), or build from source:
+
+```bash
+cd ode/formulus
+npm install
+npm run android
+```
+
+
+
+
+Build from source (requires macOS and Xcode):
+
+```bash
+cd ode/formulus
+npm install
+cd ios && bundle install && bundle exec pod install && cd ..
+npm run ios
+```
+
+
+
+
+## Step 3: Configure the App
+
+1. Open the Formulus app
+2. Navigate to Settings
+3. Enter server URL: `http://your-server-ip:8080` (or `http://localhost:8080` for emulator)
+4. Enter your credentials (create a user account first if needed)
+5. Save the configuration
+
+## Step 4: Create Your First Form
+
+Forms are defined using JSON schema. Create a simple form:
+
+```json
+{
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "age": {
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+ }
+ },
+ "required": ["name", "age"]
+}
+```
+
+Upload this form to your Synkronus server using the API or CLI tool.
+
+## Step 5: Collect Data
+
+1. Open the Formulus app
+2. Navigate to your form
+3. Fill out the form fields
+4. Submit the observation
+5. The data will be stored locally and synchronized to the server
+
+## Step 6: Verify Data Collection
+
+Check that your observation was created:
+
+
+
+
+```bash
+curl http://localhost:8080/api/observations \
+ -H "Authorization: Bearer YOUR_TOKEN"
+```
+
+
+
+
+```bash
+synk observations list
+```
+
+
+
+
+1. Navigate to the Portal
+2. Go to "Observations"
+3. View your submitted observations
+
+
+
+
+## Next Steps
+
+Now that you have a working setup:
+
+- Learn about [form design](/guides/form-design) to create more complex forms
+- Explore [custom applications](/guides/custom-applications) for specialized workflows
+- Review the [API reference](/reference/api) for integration options
+- Read about [synchronization](/using/synchronization) to understand data flow
+
+## Troubleshooting
+
+### Server Not Accessible
+
+If the mobile app cannot connect to the server:
+
+
+
+
+Verify the server is running: `curl http://localhost:8080/health`
+
+Check firewall settings
+
+Use your machine's IP address: `http://192.168.1.100:8080`
+
+Ensure device and server are on the same network
+
+
+
+
+Use `10.0.2.2` instead of `localhost`: `http://10.0.2.2:8080`
+
+Verify the server is running on the host machine
+
+Check that port 8080 is accessible
+
+
+
+
+Use `localhost` or your machine's IP address: `http://localhost:8080`
+
+Verify the server is running
+
+Check firewall settings
+
+
+
+
+### Forms Not Appearing
+
+If forms don't appear in the app:
+
+- Verify the form was uploaded correctly
+- Check that the app has synchronized with the server
+- Review server logs for errors
+
+### Synchronization Issues
+
+If data is not synchronizing:
+
+- Check network connectivity
+- Verify authentication credentials
+- Review server logs for sync errors
+- Ensure the observation was saved locally before sync
+
+## Related Documentation
+
+- [Installation Guide](/getting-started/installation)
+- [Your First Form](/using/your-first-form)
+- [Form Design Guide](/guides/form-design)
+
diff --git a/docs/getting-started/what-is-ode.md b/docs/getting-started/what-is-ode.md
new file mode 100644
index 0000000..01fea78
--- /dev/null
+++ b/docs/getting-started/what-is-ode.md
@@ -0,0 +1,92 @@
+---
+sidebar_position: 1
+---
+
+# What is ODE?
+
+Open Data Ensemble (ODE) is a platform designed to simplify mobile data collection and management. It provides tools and infrastructure for creating forms, collecting data in the field, and synchronizing information across devices and servers.
+
+## Overview
+
+ODE addresses the challenges of data collection in environments where connectivity is unreliable or intermittent. The platform is built with an offline-first architecture, ensuring that data collection continues regardless of network availability.
+
+## Problem Statement
+
+Traditional data collection solutions often require constant internet connectivity, making them unsuitable for field work in remote areas. ODE solves this by:
+
+- Storing data locally on mobile devices
+- Synchronizing data when connectivity is available
+- Resolving conflicts automatically when multiple devices modify the same data
+- Providing a flexible form design system that adapts to various use cases
+
+## Key Features
+
+### Offline-First Design
+
+All data is stored locally on the device using WatermelonDB, a reactive database optimized for React Native. This ensures that data collection continues even when the device is offline.
+
+### Flexible Form System
+
+Forms are defined using JSON schema, following the JSON Forms specification. This allows for complex validation rules, conditional logic, and custom question types.
+
+### Reliable Synchronization
+
+The synchronization protocol handles conflicts, ensures data integrity, and supports incremental updates to minimize bandwidth usage.
+
+### Cross-Platform Support
+
+ODE applications run on Android and iOS devices, with a web-based form player for preview and testing.
+
+### Extensible Architecture
+
+The platform supports custom applications and renderers, allowing organizations to tailor the user experience to their specific needs.
+
+## Use Cases
+
+ODE is suitable for various data collection scenarios:
+
+| Use Case | Description |
+|----------|-------------|
+| **Health Surveys** | Collect patient data, medical records, and health indicators |
+| **Research Studies** | Gather research data in field conditions |
+| **Monitoring & Evaluation** | Track program outcomes and indicators |
+| **Asset Management** | Inventory and track assets in the field |
+| **Quality Assurance** | Conduct inspections and quality checks |
+
+## Architecture Overview
+
+ODE follows a client-server architecture:
+
+```
+┌─────────────┐ ┌──────────────┐ ┌─────────────┐
+│ Formulus │◄───────►│ Synkronus │◄───────►│ Formulus │
+│ (Mobile) │ Sync │ (Server) │ Sync │ (Mobile) │
+└─────────────┘ └──────────────┘ └─────────────┘
+ │ │ │
+ │ │ │
+ ▼ ▼ ▼
+┌─────────────┐ ┌──────────────┐ ┌─────────────┐
+│ Formplayer │ │ Database │ │ Formplayer │
+│ (WebView) │ │ (PostgreSQL) │ │ (WebView) │
+└─────────────┘ └──────────────┘ └─────────────┘
+```
+
+The mobile application (Formulus) communicates with the server (Synkronus) to synchronize data. Forms are rendered using the Formplayer component, which can be embedded in custom applications.
+
+## Technology Stack
+
+ODE is built using modern, open-source technologies:
+
+- **React Native** for mobile applications
+- **React** for web-based form rendering
+- **Go** for the backend server
+- **PostgreSQL** for data storage
+- **WatermelonDB** for local data storage on mobile devices
+- **JSON Forms** for form rendering and validation
+
+## Next Steps
+
+- Learn about [Why ODE?](/getting-started/why-ode) to understand the benefits
+- Review [Key Concepts](/getting-started/key-concepts) to understand the terminology
+- Follow the [Installation guide](/getting-started/installation/prerequisites) to set up your environment
+
diff --git a/docs/getting-started/why-ode.md b/docs/getting-started/why-ode.md
new file mode 100644
index 0000000..ca3d2de
--- /dev/null
+++ b/docs/getting-started/why-ode.md
@@ -0,0 +1,70 @@
+---
+sidebar_position: 2
+---
+
+# Why ODE?
+
+ODE provides several advantages over traditional data collection solutions, particularly for organizations working in challenging environments with unreliable connectivity.
+
+## Advantages
+
+### Offline-First Architecture
+
+Unlike many data collection platforms that require constant connectivity, ODE is designed to work offline. Data is stored locally and synchronized when connectivity is available, ensuring that field work is never interrupted by network issues.
+
+### Conflict Resolution
+
+When multiple devices modify the same data, ODE automatically resolves conflicts using a version-based approach. This ensures data integrity without requiring manual intervention.
+
+### Flexible Form Design
+
+The JSON-based form system allows for complex validation rules, conditional logic, and custom question types. Forms can be updated without requiring application updates, enabling rapid iteration and adaptation.
+
+### Open Source
+
+ODE is fully open source, allowing organizations to audit the code, customize the platform, and contribute improvements. This transparency builds trust and enables community-driven development.
+
+### Cross-Platform Support
+
+Applications built with ODE run on both Android and iOS devices, reducing the need to maintain separate codebases for different platforms.
+
+### Extensible
+
+The platform supports custom applications and renderers, allowing organizations to create specialized workflows and user interfaces that match their specific needs.
+
+## Comparison with Alternatives
+
+| Feature | ODE | Traditional Solutions |
+|--------|-----|----------------------|
+| Offline Support | Full offline functionality | Limited or none |
+| Conflict Resolution | Automatic | Manual or none |
+| Form Updates | Without app updates | Requires app updates |
+| Customization | High flexibility | Limited |
+| Open Source | Yes | Often proprietary |
+| Cost | Free and open source | Licensing fees |
+
+## When to Use ODE
+
+ODE is particularly well-suited for:
+
+- Organizations conducting field research or data collection in remote areas
+- Projects requiring complex forms with validation and conditional logic
+- Teams needing to customize the user experience
+- Organizations prioritizing data privacy and security
+- Projects requiring offline functionality
+
+## When to Consider Alternatives
+
+ODE may not be the best fit if:
+
+- Your use case requires real-time collaboration features
+- You need extensive third-party integrations out of the box
+- Your team lacks technical resources for deployment and maintenance
+- Your data collection needs are very simple and don't require offline support
+
+## Next Steps
+
+- Review [Key Concepts](/getting-started/key-concepts) to understand ODE terminology
+- Check [Prerequisites](/getting-started/installation/prerequisites) for system requirements
+- Follow the [Installation guide](/getting-started/installation/quick-start) to get started
+
diff --git a/docs/guides/.gitkeep b/docs/guides/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/guides/configuration.md b/docs/guides/configuration.md
new file mode 100644
index 0000000..cc29d14
--- /dev/null
+++ b/docs/guides/configuration.md
@@ -0,0 +1,360 @@
+---
+sidebar_position: 4
+---
+
+# Configuration
+
+Complete configuration guide for ODE components including server settings, client settings, and environment variables.
+
+## Server Configuration (Synkronus)
+
+Synkronus is configured using environment variables. You can use either environment variables directly or a `.env` file for local development.
+
+### Configuration File Locations
+
+For local development, create a `.env` file in one of these locations (searched in order):
+
+1. Current working directory (where you run the command from)
+2. Same directory as the executable
+3. Parent directory of the executable
+
+### Required Configuration
+
+| Variable | Description | Example |
+|----------|-------------|---------|
+| `DB_CONNECTION` | PostgreSQL connection string | `postgres://user:password@localhost:5432/synkronus?sslmode=disable` |
+| `JWT_SECRET` | Secret key for JWT token signing (minimum 32 characters) | Generate with `openssl rand -base64 32` |
+
+### Optional Configuration
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `PORT` | `8080` | HTTP server port |
+| `LOG_LEVEL` | `info` | Logging level: `debug`, `info`, `warn`, or `error` |
+| `APP_BUNDLE_PATH` | `./data/app-bundles` | Directory path for app bundle storage |
+| `MAX_VERSIONS_KEPT` | `5` | Maximum number of app bundle versions to retain |
+| `ADMIN_USERNAME` | `admin` | Initial admin username |
+| `ADMIN_PASSWORD` | `admin` | Initial admin password (must be changed in production) |
+
+### Example Configuration File
+
+```bash
+# Server Configuration
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=info
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+
+# Admin Configuration
+ADMIN_USERNAME=admin
+ADMIN_PASSWORD=change-this-password
+```
+
+### Database Connection String Format
+
+The `DB_CONNECTION` string follows PostgreSQL connection URI format:
+
+```
+postgres://[user[:password]@][host][:port][/database][?param1=value1&...]
+```
+
+**Components:**
+- `user`: Database username
+- `password`: Database password
+- `host`: Database hostname or IP address
+- `port`: Database port (default: 5432)
+- `database`: Database name
+- `sslmode`: SSL mode (`disable`, `require`, `verify-full`, etc.)
+
+**Examples:**
+
+```bash
+# Local development
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+
+# Remote database
+DB_CONNECTION=postgres://synkronus:password@db.example.com:5432/synkronus?sslmode=require
+
+# Docker Compose
+DB_CONNECTION=postgres://synkronus:password@postgres:5432/synkronus?sslmode=disable
+```
+
+## Client Configuration (Formulus)
+
+The Formulus mobile app is configured through the app settings interface.
+
+### Server URL
+
+Enter the URL of your Synkronus server:
+
+
+
+
+**Physical Device**: `http://192.168.1.100:8080` (your machine's IP address)
+
+**Android Emulator**: `http://10.0.2.2:8080` (special IP for emulator)
+
+**iOS Simulator**: `http://localhost:8080` or your machine's IP address
+
+
+
+
+**HTTPS URL**: `https://synkronus.your-domain.com`
+
+**Custom Port**: `https://synkronus.your-domain.com:8443` (if using non-standard port)
+
+
+
+
+### Authentication
+
+Configure authentication credentials:
+
+1. **Username**: Your user account username
+2. **Password**: Your user account password
+3. **Server URL**: As described above
+
+The app stores credentials securely and uses them for API authentication.
+
+### Sync Settings
+
+Configure synchronization behavior:
+
+- **Auto-sync**: Enable automatic synchronization when connectivity is available
+- **Sync interval**: How often to check for sync (default: every 15 minutes)
+- **Sync on app start**: Automatically sync when the app is opened
+- **Sync on observation save**: Sync immediately after saving an observation
+
+## Synkronus CLI Configuration
+
+The Synkronus CLI uses a configuration file located at `$HOME/.synkronus.yaml` by default.
+
+### Configuration File Format
+
+```yaml
+api:
+ url: http://localhost:8080
+ version: 1.0.0
+```
+
+### Multiple Endpoints
+
+You can manage multiple endpoint configurations:
+
+```bash
+# Create separate config files
+synk config init -o ~/.synkronus-dev.yaml
+synk config init -o ~/.synkronus-prod.yaml
+
+# Point CLI at dev by default
+synk config use ~/.synkronus-dev.yaml
+
+# Point CLI at prod by default
+synk config use ~/.synkronus-prod.yaml
+
+# Temporarily override for a single command
+synk --config ~/.synkronus-dev.yaml status
+```
+
+### Authentication
+
+The CLI stores authentication tokens in the configuration file after login:
+
+```bash
+# Login to the API
+synk login --username your-username
+
+# Check authentication status
+synk status
+
+# Logout
+synk logout
+```
+
+## Docker Configuration
+
+### Docker Compose Configuration
+
+When using Docker Compose, configuration is set in the `docker-compose.yml` file:
+
+```yaml
+services:
+ synkronus:
+ image: ghcr.io/opendataensemble/synkronus:latest
+ environment:
+ PORT: 8080
+ DB_CONNECTION: postgres://synkronus:password@postgres:5432/synkronus?sslmode=disable
+ JWT_SECRET: your-secret-key
+ LOG_LEVEL: info
+ APP_BUNDLE_PATH: /app/data/app-bundles
+ MAX_VERSIONS_KEPT: 5
+ volumes:
+ - app-bundles:/app/data/app-bundles
+ depends_on:
+ - postgres
+```
+
+### Environment File
+
+You can also use a `.env` file with Docker Compose:
+
+```bash
+# .env file
+DB_CONNECTION=postgres://synkronus:password@postgres:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key
+LOG_LEVEL=info
+```
+
+Reference in `docker-compose.yml`:
+
+```yaml
+services:
+ synkronus:
+ env_file:
+ - .env
+```
+
+## Security Configuration
+
+### JWT Secret
+
+Generate a strong JWT secret:
+
+```bash
+# Using OpenSSL
+openssl rand -base64 32
+
+# Using PowerShell (Windows)
+[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 }))
+```
+
+**Important:** Use a different secret for each environment (development, staging, production).
+
+### Database Passwords
+
+Generate strong database passwords:
+
+```bash
+# Generate random password
+openssl rand -base64 24
+```
+
+### Admin Password
+
+Change the default admin password immediately after deployment:
+
+```bash
+# Via API
+curl -X POST https://your-server.com/users/change-password \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"current_password":"admin","new_password":"new-secure-password"}'
+```
+
+## Logging Configuration
+
+### Log Levels
+
+| Level | Description | Use Case |
+|-------|-------------|----------|
+| `debug` | Detailed diagnostic information | Development, troubleshooting |
+| `info` | General informational messages | Production (default) |
+| `warn` | Warning messages | Production |
+| `error` | Error messages only | Production (minimal logging) |
+
+### Log Output
+
+Logs are written to standard output (stdout) and can be captured by:
+
+- Docker logging drivers
+- Systemd journal
+- Log aggregation services (e.g., Fluentd, Logstash)
+
+### Docker Logging
+
+Configure Docker logging in `docker-compose.yml`:
+
+```yaml
+services:
+ synkronus:
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "10m"
+ max-file: "3"
+```
+
+## Performance Configuration
+
+### PostgreSQL Settings
+
+Optimize PostgreSQL for your workload:
+
+```yaml
+services:
+ postgres:
+ command:
+ - "postgres"
+ - "-c"
+ - "max_connections=100"
+ - "-c"
+ - "shared_buffers=256MB"
+ - "-c"
+ - "effective_cache_size=1GB"
+```
+
+### Resource Limits
+
+Set resource limits in Docker Compose:
+
+```yaml
+services:
+ synkronus:
+ deploy:
+ resources:
+ limits:
+ cpus: '1.0'
+ memory: 512M
+ reservations:
+ cpus: '0.5'
+ memory: 256M
+```
+
+## Configuration Validation
+
+### Verify Configuration
+
+Test your configuration:
+
+```bash
+# Check environment variables are set
+docker compose config
+
+# Test database connection
+docker compose exec synkronus sh -c 'apk add postgresql-client && psql "$DB_CONNECTION"'
+
+# Check server health
+curl http://localhost:8080/health
+```
+
+### Common Configuration Issues
+
+**Problem**: Database connection fails
+
+**Solution**: Verify `DB_CONNECTION` string format and database accessibility.
+
+**Problem**: JWT authentication fails
+
+**Solution**: Ensure `JWT_SECRET` is at least 32 characters and matches across all instances.
+
+**Problem**: App bundles not persisting
+
+**Solution**: Verify `APP_BUNDLE_PATH` is set and volume is properly mounted.
+
+## Related Documentation
+
+- [Installation Guide](/getting-started/installation)
+- [Deployment Guide](/guides/deployment)
+- [API Reference](/reference/api)
diff --git a/docs/guides/custom-applications.md b/docs/guides/custom-applications.md
new file mode 100644
index 0000000..9055a4d
--- /dev/null
+++ b/docs/guides/custom-applications.md
@@ -0,0 +1,196 @@
+---
+sidebar_position: 2
+---
+
+# Custom Applications
+
+Complete guide to building and deploying custom applications that integrate with ODE.
+
+## Overview
+
+Custom applications are web-based interfaces that run within the Formulus mobile app, providing specialized workflows and user experiences. They allow you to create custom navigation, integrate with the ODE form system, and build specialized interfaces for specific use cases.
+
+## How Custom Applications Work
+
+Custom applications are defined in app bundles, which include:
+
+- HTML, CSS, and JavaScript files
+- Form specifications
+- Custom renderers for question types
+- Configuration files
+
+The app bundle is uploaded to the Synkronus server and downloaded by mobile devices during synchronization. When a user opens a custom application, it runs in a WebView within the Formulus app.
+
+## Formulus JavaScript Interface
+
+Custom applications interact with Formulus through a JavaScript interface. The API is injected automatically when your app loads.
+
+### Getting the Formulus API
+
+Always use the `getFormulus()` helper function to ensure the API is ready:
+
+```html
+
+
+
+
+```
+
+### Available Methods
+
+The Formulus interface provides methods for:
+
+- **Form Operations**: Create, edit, and delete observations
+- **Data Access**: Query observations and form specifications
+- **Device Features**: Access camera, GPS, file system, etc.
+- **Synchronization**: Trigger sync operations
+
+### Creating Observations
+
+```javascript
+// Create a new observation
+await formulus.addObservation(formType, initializationData);
+```
+
+### Editing Observations
+
+```javascript
+// Edit an existing observation
+await formulus.editObservation(formType, observationId);
+```
+
+### Deleting Observations
+
+```javascript
+// Delete an observation
+await formulus.deleteObservation(formType, observationId);
+```
+
+## App Bundle Structure
+
+An app bundle is a ZIP file containing:
+
+```
+app-bundle/
+├── index.html # Main entry point
+├── assets/
+│ ├── css/
+│ ├── js/
+│ └── images/
+├── forms/ # Form specifications (optional)
+└── manifest.json # Bundle metadata
+```
+
+### Manifest File
+
+The manifest defines bundle metadata:
+
+```json
+{
+ "version": "1.0.0",
+ "name": "My Custom App",
+ "description": "Description of the app",
+ "entryPoint": "index.html"
+}
+```
+
+## Building Custom Applications
+
+### Development Setup
+
+1. **Reference the API**: Copy `formulus-api.js` into your project for autocompletion
+2. **Include the Load Script**: Add `formulus-load.js` to your HTML
+3. **Use getFormulus()**: Always await the API before using it
+
+### Example Application
+
+```html
+
+
+
+ My Custom App
+
+
+
+
My Custom App
+
+
+
+
+
+```
+
+## Deployment
+
+### Uploading App Bundles
+
+Upload app bundles using the Synkronus CLI:
+
+```bash
+synk app-bundle upload bundle.zip --activate
+```
+
+Or use the API:
+
+```bash
+curl -X POST http://your-server:8080/api/app-bundle/upload \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -F "bundle=@bundle.zip"
+```
+
+### Version Management
+
+App bundles support versioning:
+
+- Each upload creates a new version
+- Versions are identified by timestamp
+- Switch between versions using the CLI or API
+- Mobile devices download the active version during sync
+
+## Custom Renderers
+
+Custom applications can include custom renderers for question types. See the [Form Design guide](/guides/form-design) for details on creating custom renderers.
+
+## Best Practices
+
+1. **Wait for API**: Always use `getFormulus()` before accessing the API
+2. **Error Handling**: Implement proper error handling for all API calls
+3. **Offline Support**: Design apps to work gracefully when offline
+4. **Performance**: Optimize for mobile devices and slower networks
+5. **Testing**: Test thoroughly in both development and production environments
+
+## Related Documentation
+
+- [Form Design Guide](/guides/form-design)
+- [Formulus Interface Documentation](https://github.com/OpenDataEnsemble/ode/tree/main/formulus/src/webview)
+- [App Bundle Format Reference](/reference/app-bundle-format)
+
diff --git a/docs/guides/deployment.md b/docs/guides/deployment.md
new file mode 100644
index 0000000..b72d7e0
--- /dev/null
+++ b/docs/guides/deployment.md
@@ -0,0 +1,560 @@
+---
+sidebar_position: 3
+---
+
+# Deployment
+
+Complete guide to deploying ODE in production environments using Docker and Docker Compose.
+
+## Overview
+
+ODE can be deployed using Docker containers, which simplifies deployment and ensures consistency across environments. This guide covers production deployment with Docker Compose, including PostgreSQL, Nginx reverse proxy, and optional Cloudflared tunnel for secure external access.
+
+## Recommended Production Setup
+
+For production deployment, we recommend:
+
+- **Clean Linux server** (Ubuntu 22.04 LTS or Debian 12)
+- **Docker & Docker Compose** installed
+- **Cloudflared tunnel** for secure external access (no port forwarding needed)
+- **PostgreSQL** database (dockerized via docker-compose)
+- **Nginx** reverse proxy (included in docker-compose)
+- **Persistent volumes** for data storage
+
+## Quick Start
+
+### Server Preparation
+
+
+
+
+```bash
+# Update system
+sudo apt update && sudo apt upgrade -y
+
+# Install Docker
+curl -fsSL https://get.docker.com -o get-docker.sh
+sudo sh get-docker.sh
+
+# Install Docker Compose
+sudo apt install docker-compose-plugin -y
+
+# Verify installation
+docker --version
+docker compose version
+```
+
+
+
+
+```bash
+# Install Docker Desktop from https://www.docker.com/products/docker-desktop
+# Or use Homebrew:
+brew install --cask docker
+
+# Docker Compose is included with Docker Desktop
+# Verify installation
+docker --version
+docker compose version
+```
+
+
+
+
+1. **Install Docker Desktop** from [docker.com/products/docker-desktop](https://www.docker.com/products/docker-desktop)
+2. **Docker Compose is included** with Docker Desktop
+3. **Verify installation** (PowerShell):
+ ```powershell
+ docker --version
+ docker compose version
+ ```
+
+
+
+
+### Deploy Synkronus
+
+```bash
+# Create deployment directory
+mkdir -p ~/synkronus
+cd ~/synkronus
+
+# Download configuration files
+wget https://raw.githubusercontent.com/opendataensemble/ode/main/synkronus/docker-compose.example.yml -O docker-compose.yml
+wget https://raw.githubusercontent.com/opendataensemble/ode/main/synkronus/nginx.conf
+
+# Generate secure secrets
+JWT_SECRET=$(openssl rand -base64 32)
+DB_ROOT_PASSWORD=$(openssl rand -base64 24)
+ADMIN_PASSWORD=$(openssl rand -base64 16)
+
+# Update docker-compose.yml with secrets
+sed -i "s/CHANGE_THIS_PASSWORD/$DB_ROOT_PASSWORD/g" docker-compose.yml
+sed -i "s/CHANGE_THIS_TO_RANDOM_32_CHAR_STRING/$JWT_SECRET/g" docker-compose.yml
+sed -i "s/CHANGE_THIS_ADMIN_PASSWORD/$ADMIN_PASSWORD/g" docker-compose.yml
+
+# Start the stack
+docker compose up -d
+
+# Verify it's running
+curl http://localhost/health
+```
+
+### Database Setup
+
+Create a database and user for Synkronus:
+
+
+
+
+```bash
+# Open a psql shell into the Postgres container
+docker compose exec postgres psql -U postgres
+```
+
+From the `psql` prompt:
+
+```sql
+-- Create role and database
+CREATE ROLE synkronus_user LOGIN PASSWORD 'CHANGE_THIS_APP_PASSWORD';
+CREATE DATABASE synkronus OWNER synkronus_user;
+```
+
+
+
+
+```bash
+# Connect to local PostgreSQL
+psql -U postgres
+```
+
+From the `psql` prompt:
+
+```sql
+-- Create role and database
+CREATE ROLE synkronus_user LOGIN PASSWORD 'CHANGE_THIS_APP_PASSWORD';
+CREATE DATABASE synkronus OWNER synkronus_user;
+```
+
+
+
+
+Update the `synkronus` service `DB_CONNECTION` in `docker-compose.yml`:
+
+```yaml
+services:
+ synkronus:
+ environment:
+ DB_CONNECTION: "postgres://synkronus_user:CHANGE_THIS_APP_PASSWORD@postgres:5432/synkronus?sslmode=disable"
+```
+
+## Using Pre-built Images
+
+Pre-built images are automatically published to GitHub Container Registry (GHCR) via CI/CD.
+
+### Pull the Latest Image
+
+```bash
+docker pull ghcr.io/opendataensemble/synkronus:latest
+```
+
+### Available Tags
+
+| Tag | Description |
+|-----|-------------|
+| `latest` | Latest stable release from main branch |
+| `v1.0.0` | Specific version tags |
+| `develop` | Development branch (pre-release) |
+| `feature-xyz` | Feature branches (pre-release) |
+
+### Run Pre-built Image
+
+```bash
+docker run -d \
+ --name synkronus \
+ -p 8080:8080 \
+ -e DB_CONNECTION="postgres://user:password@host:5432/synkronus" \
+ -e JWT_SECRET="your-secret-key" \
+ -e APP_BUNDLE_PATH="/app/data/app-bundles" \
+ -v synkronus-bundles:/app/data/app-bundles \
+ ghcr.io/opendataensemble/synkronus:latest
+```
+
+## Cloudflared Tunnel Setup
+
+Cloudflared provides secure external access without exposing ports or managing SSL certificates.
+
+### Install Cloudflared
+
+```bash
+# Download and install
+wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
+sudo dpkg -i cloudflared-linux-amd64.deb
+
+# Verify installation
+cloudflared --version
+```
+
+### Create Tunnel
+
+```bash
+# Login to Cloudflare
+cloudflared tunnel login
+
+# Create tunnel
+cloudflared tunnel create synkronus
+
+# Note the tunnel ID from the output
+```
+
+### Configure Tunnel
+
+Create `~/.cloudflared/config.yml`:
+
+```yaml
+tunnel:
+credentials-file: /root/.cloudflared/.json
+
+ingress:
+ - hostname: synkronus.your-domain.com
+ service: http://localhost:80
+ - service: http_status:404
+```
+
+### Route DNS
+
+```bash
+# Route your domain to the tunnel
+cloudflared tunnel route dns synkronus synkronus.your-domain.com
+```
+
+### Run Tunnel as Service
+
+```bash
+# Install as systemd service
+sudo cloudflared service install
+
+# Start service
+sudo systemctl start cloudflared
+sudo systemctl enable cloudflared
+
+# Check status
+sudo systemctl status cloudflared
+```
+
+Your Synkronus instance is now accessible at `https://synkronus.your-domain.com` with automatic SSL.
+
+## Environment Variables
+
+### Required Variables
+
+| Variable | Description | Example |
+|----------|-------------|---------|
+| `DB_CONNECTION` | PostgreSQL connection string | `postgres://user:pass@postgres:5432/synkronus` |
+| `JWT_SECRET` | Secret key for JWT token signing | Generate with `openssl rand -base64 32` |
+
+### Optional Variables
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `PORT` | `8080` | HTTP server port |
+| `LOG_LEVEL` | `info` | Logging level (`debug`, `info`, `warn`, `error`) |
+| `APP_BUNDLE_PATH` | `/app/data/app-bundles` | Path for app bundle storage |
+| `MAX_VERSIONS_KEPT` | `5` | Number of app bundle versions to retain |
+| `ADMIN_USERNAME` | `admin` | Initial admin username |
+| `ADMIN_PASSWORD` | `admin` | Initial admin password (CHANGE THIS!) |
+
+## Volume Management
+
+### Persistent Volumes
+
+The docker-compose setup creates persistent volumes:
+
+1. **postgres-data**: PostgreSQL database files
+2. **app-bundles**: Uploaded application bundles
+
+```bash
+# List volumes
+docker volume ls
+
+# Inspect volume
+docker volume inspect synkronus_postgres-data
+
+# Backup volume
+docker run --rm -v synkronus_postgres-data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz /data
+
+# Restore volume
+docker run --rm -v synkronus_postgres-data:/data -v $(pwd):/backup alpine tar xzf /backup/postgres-backup.tar.gz -C /
+```
+
+### App Bundle Directory Permissions
+
+When bind-mounting a host directory for `app-bundles`, ensure proper permissions. The container runs as user `synkronus` with `uid=1000` and `gid=1000`:
+
+```bash
+# Fix permissions on host directory
+sudo chown -R 1000:1000 ~/server/app-bundles
+
+# Restart after fixing permissions
+docker compose restart synkronus
+```
+
+## Monitoring and Maintenance
+
+### View Logs
+
+```bash
+# All services
+docker compose logs -f
+
+# Specific service
+docker compose logs -f synkronus
+docker compose logs -f postgres
+docker compose logs -f nginx
+
+# Last 100 lines
+docker compose logs --tail=100 synkronus
+```
+
+### Health Checks
+
+```bash
+# Check service status
+docker compose ps
+
+# Test health endpoint
+curl http://localhost/health
+
+# Via cloudflared tunnel
+curl https://synkronus.your-domain.com/health
+```
+
+### Restart Services
+
+```bash
+# Restart all services
+docker compose restart
+
+# Restart specific service
+docker compose restart synkronus
+
+# Reload nginx configuration
+docker compose exec nginx nginx -s reload
+```
+
+### Update to Latest Version
+
+```bash
+# Pull latest image
+docker compose pull
+
+# Recreate containers with new image
+docker compose up -d
+
+# Remove old images
+docker image prune -f
+```
+
+## Backup and Restore
+
+### Database Backup
+
+```bash
+# Create backup
+docker compose exec postgres pg_dump -U synkronus_user synkronus > backup-$(date +%Y%m%d).sql
+
+# Automated daily backups (add to crontab)
+0 2 * * * cd ~/synkronus && docker compose exec -T postgres pg_dump -U synkronus_user synkronus > /backups/synkronus-$(date +\%Y\%m\%d).sql
+```
+
+### Database Restore
+
+```bash
+# Restore from backup
+docker compose exec -T postgres psql -U synkronus_user synkronus < backup-20250114.sql
+```
+
+### Full System Backup
+
+```bash
+# Backup everything
+tar czf synkronus-full-backup-$(date +%Y%m%d).tar.gz \
+ docker-compose.yml \
+ nginx.conf \
+ $(docker volume inspect synkronus_postgres-data --format '{{ .Mountpoint }}') \
+ $(docker volume inspect synkronus_app-bundles --format '{{ .Mountpoint }}')
+```
+
+## Security Best Practices
+
+### 1. Use Strong Secrets
+
+```bash
+# Generate strong JWT secret
+openssl rand -base64 32
+
+# Generate strong passwords
+openssl rand -base64 24
+```
+
+### 2. Change Default Admin Password
+
+After first deployment, change the admin password via API or CLI.
+
+### 3. Regular Updates
+
+```bash
+# Update system packages
+sudo apt update && sudo apt upgrade -y
+
+# Update Docker images
+docker compose pull
+docker compose up -d
+```
+
+### 4. Firewall Configuration
+
+If not using Cloudflared, configure firewall:
+
+```bash
+sudo ufw allow 80/tcp
+sudo ufw allow 443/tcp
+sudo ufw enable
+```
+
+## Performance Tuning
+
+### PostgreSQL Optimization
+
+Add to `docker-compose.yml` under postgres service:
+
+```yaml
+command:
+ - "postgres"
+ - "-c"
+ - "max_connections=100"
+ - "-c"
+ - "shared_buffers=256MB"
+ - "-c"
+ - "effective_cache_size=1GB"
+```
+
+### Resource Limits
+
+Add to `docker-compose.yml` under each service:
+
+```yaml
+deploy:
+ resources:
+ limits:
+ cpus: '1.0'
+ memory: 512M
+ reservations:
+ cpus: '0.5'
+ memory: 256M
+```
+
+## Architecture
+
+The deployment architecture includes:
+
+```
+┌─────────────────────────────────────────┐
+│ Cloudflared Tunnel │
+│ (Optional - Cloudflare) │
+│ Automatic SSL/TLS │
+└──────────────┬──────────────────────────┘
+ │ HTTPS
+ ▼
+┌─────────────────────────────────────────┐
+│ Nginx Reverse Proxy │
+│ Port 80/443 │
+│ - Load balancing │
+│ - Request routing │
+│ - Compression │
+└──────────────┬──────────────────────────┘
+ │ HTTP
+ ▼
+┌─────────────────────────────────────────┐
+│ Synkronus Container │
+│ Port 8080 (internal) │
+│ - API endpoints │
+│ - Business logic │
+│ - File storage │
+└──────────────┬──────────────────────────┘
+ │ PostgreSQL protocol
+ ▼
+┌─────────────────────────────────────────┐
+│ PostgreSQL Database │
+│ Port 5432 (internal) │
+│ - Data persistence │
+│ - Transactions │
+└─────────────────────────────────────────┘
+```
+
+## Troubleshooting
+
+### Service Won't Start
+
+```bash
+# Check logs
+docker compose logs synkronus
+
+# Check environment variables
+docker compose config
+
+# Verify database connection
+docker compose exec synkronus sh
+# Inside container:
+apk add postgresql-client
+psql "$DB_CONNECTION"
+```
+
+### Database Connection Issues
+
+```bash
+# Check PostgreSQL is running
+docker compose ps postgres
+
+# Check PostgreSQL logs
+docker compose logs postgres
+
+# Test connection from synkronus container
+docker compose exec synkronus sh -c 'apk add postgresql-client && psql "$DB_CONNECTION"'
+```
+
+### Nginx Issues
+
+```bash
+# Test nginx configuration
+docker compose exec nginx nginx -t
+
+# Reload nginx
+docker compose exec nginx nginx -s reload
+
+# Check nginx logs
+docker compose logs nginx
+```
+
+## Production Checklist
+
+Before going live:
+
+- [ ] Strong JWT secret generated
+- [ ] Strong database password set
+- [ ] Admin password changed from default
+- [ ] Cloudflared tunnel configured (or SSL certificates installed)
+- [ ] Backup strategy implemented
+- [ ] Monitoring configured
+- [ ] Health checks passing
+- [ ] Firewall configured (if not using Cloudflared)
+- [ ] Resource limits set
+- [ ] Log rotation configured
+- [ ] Documentation reviewed
+- [ ] Test deployment verified
+
+## Related Documentation
+
+- [Installation Guide](/getting-started/installation)
+- [Configuration Guide](/guides/configuration)
+- [API Reference](/reference/api)
diff --git a/docs/guides/form-design.md b/docs/guides/form-design.md
new file mode 100644
index 0000000..0672c88
--- /dev/null
+++ b/docs/guides/form-design.md
@@ -0,0 +1,1362 @@
+---
+sidebar_position: 1
+---
+
+# Form Design
+
+Complete guide to designing forms in ODE using JSON schema and JSON Forms.
+
+## Overview
+
+Forms in ODE are defined using JSON schema, following the JSON Forms specification. A form consists of two main components:
+
+1. **Schema**: Defines the data structure and validation rules
+2. **UI Schema**: Defines how the form is presented to users
+
+## How Forms Work in ODE
+
+Understanding the mental model of forms in ODE is essential for effective form design.
+
+### What is a "Form" in ODE?
+
+A form in ODE is a structured data collection interface that consists of:
+
+- **JSON Schema**: Defines what data can be collected, its structure, types, and validation rules
+- **UI Schema**: Defines how the form is presented to users, including layout, field ordering, and conditional visibility
+- **Formplayer**: The rendering engine that interprets these schemas and creates the interactive form interface
+
+### The Role of JSON Schema
+
+JSON Schema serves as the **data contract** for your form:
+
+- **Structure Definition**: Defines the shape of data (properties, types, nesting)
+- **Validation Rules**: Enforces data quality (required fields, ranges, formats)
+- **Type Safety**: Ensures data types match expectations (string, number, boolean, etc.)
+
+JSON Schema follows the [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7) specification, but ODE Formplayer intentionally supports a **safe, predictable subset** of JSON Schema features.
+
+### The Role of UI Schema
+
+UI Schema (JSON Forms UI Schema) controls the **presentation layer**:
+
+- **Layout**: How fields are arranged (vertical, horizontal, grouped, paginated)
+- **Ordering**: The sequence in which fields appear
+- **Conditional Logic**: When fields are shown or hidden
+- **Field Configuration**: Labels, placeholders, and display options
+
+### The Role of Formplayer
+
+Formplayer is the React-based rendering engine that:
+
+- **Interprets Schemas**: Reads JSON Schema and UI Schema to understand form structure
+- **Renders Components**: Creates interactive form elements (inputs, selects, media capture, etc.)
+- **Validates Input**: Enforces schema validation rules in real-time
+- **Manages State**: Tracks form data, validation errors, and user interactions
+
+### Why ODE Supports a Subset of JSON Schema
+
+**Key Message**: ODE Formplayer intentionally supports a safe, predictable subset of JSON Schema and JSON Forms to ensure:
+
+1. **Reliability**: Forms work consistently across all devices and scenarios
+2. **Performance**: Complex schema features don't slow down form rendering
+3. **Predictability**: Form behavior is deterministic and easy to reason about
+4. **Mobile Optimization**: Features work well in resource-constrained mobile environments
+
+**Important**: Forms that use unsupported JSON Schema features may load but are **not guaranteed to work**. Always refer to the [Formplayer Supported Schema & UI Profile](/reference/formplayer#supported-schema--ui-profile) for the definitive list of supported features.
+
+## Basic Form Structure
+
+Here's a simple form example:
+
+```json
+{
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "age": {
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+ }
+ },
+ "required": ["name", "age"]
+ },
+ "uischema": {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/name"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/age"
+ }
+ ]
+ }
+}
+```
+
+## Schema Definition
+
+The schema defines the data structure and validation rules for your form. It follows the JSON Schema specification.
+
+### Property Types
+
+ODE supports various property types:
+
+| Type | Description | Example |
+|------|-------------|---------|
+| `string` | Text input | Name, description |
+| `integer` | Whole number | Age, count |
+| `number` | Decimal number | Weight, temperature |
+| `boolean` | True/false value | Consent, agreement |
+| `array` | List of items | Multiple selections |
+| `object` | Nested object | Complex data structures |
+
+### Validation Rules
+
+You can add validation rules to properties:
+
+```json
+{
+ "type": "string",
+ "title": "Email",
+ "format": "email",
+ "minLength": 5,
+ "maxLength": 100
+}
+```
+
+Common validation rules:
+
+- `minimum` / `maximum`: For numbers
+- `minLength` / `maxLength`: For strings
+- `pattern`: Regular expression pattern
+- `format`: Predefined formats (email, date, etc.)
+- `enum`: List of allowed values
+
+## Designing UI Schemas for ODE Formplayer
+
+The UI schema defines how form fields are presented to users. It controls layout, ordering, and presentation. ODE Formplayer has specific requirements and best practices for UI schema design.
+
+### Required Layout Structure
+
+**All ODE forms must use `SwipeLayout` as the root element.** This enables pagination and swipe navigation between form sections.
+
+#### SwipeLayout (Required Root)
+
+`SwipeLayout` is the root layout type that enables multi-page forms with swipe navigation. It automatically wraps other layout types if not explicitly specified.
+
+**Required Structure:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ // Each element becomes a swipeable page
+ ]
+}
+```
+
+**Key Characteristics:**
+- **Root Element**: Must be the top-level element in your UI schema
+- **Pagination**: Each element in `elements[]` becomes a separate page
+- **Swipe Navigation**: Users can swipe left/right to navigate between pages
+- **Progress Tracking**: Shows progress bar indicating current page
+- **Auto-wrapping**: If root is not SwipeLayout, Formplayer automatically wraps it
+
+**Safe Example:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/name"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/age"
+ }
+ ]
+ },
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/email"
+ }
+ ]
+ }
+ ]
+}
+```
+
+**Unsafe Example:**
+```json
+{
+ "type": "VerticalLayout", // ❌ Not SwipeLayout - will be auto-wrapped
+ "elements": [...]
+}
+```
+
+### Layout Types
+
+#### VerticalLayout
+
+Fields arranged vertically in a single column.
+
+**Required Fields:**
+- `type`: `"VerticalLayout"`
+- `elements`: Array of UI schema elements
+
+**Usage:**
+```json
+{
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/field1"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/field2"
+ }
+ ]
+}
+```
+
+#### HorizontalLayout
+
+Fields arranged horizontally in a row.
+
+**Required Fields:**
+- `type`: `"HorizontalLayout"`
+- `elements`: Array of UI schema elements
+
+**Usage:**
+```json
+{
+ "type": "HorizontalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/firstName"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/lastName"
+ }
+ ]
+}
+```
+
+#### Group
+
+Groups related fields together with a label.
+
+**Required Fields:**
+- `type`: `"Group"`
+- `label`: Group title (required)
+- `elements`: Array of UI schema elements
+
+**Usage:**
+```json
+{
+ "type": "Group",
+ "label": "Personal Information",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/name"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/email"
+ }
+ ]
+}
+```
+
+**Note**: Groups can be used as pages within SwipeLayout. Each Group element in a SwipeLayout's `elements[]` becomes a separate page.
+
+### Control Configuration
+
+Controls bind UI elements to schema properties.
+
+**Required Fields:**
+- `type`: `"Control"`
+- `scope`: JSON pointer to schema property (must exist in schema)
+
+**Optional Fields:**
+- `label`: Override field label
+- `options`: Additional configuration
+
+**Safe Example:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/name", // ✅ Scope exists in schema
+ "label": "Full Name",
+ "options": {
+ "placeholder": "Enter your name"
+ }
+}
+```
+
+**Unsafe Example:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/nonexistent" // ❌ Scope doesn't exist - will cause error
+}
+```
+
+### Label Element
+
+Displays text labels within forms.
+
+**Required Fields:**
+- `type`: `"Label"`
+- `text`: Label text content
+
+**Usage:**
+```json
+{
+ "type": "Label",
+ "text": "Section Introduction"
+}
+```
+
+### UI Schema Best Practices
+
+#### Pagination Patterns
+
+**Recommended**: Use SwipeLayout with VerticalLayout pages for multi-step forms:
+
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ { "type": "Label", "text": "Step 1: Basic Info" },
+ { "type": "Control", "scope": "#/properties/name" },
+ { "type": "Control", "scope": "#/properties/age" }
+ ]
+ },
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ { "type": "Label", "text": "Step 2: Contact" },
+ { "type": "Control", "scope": "#/properties/email" }
+ ]
+ }
+ ]
+}
+```
+
+#### Grouping Best Practices
+
+**Use Groups for logical organization:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "Group",
+ "label": "Demographics",
+ "elements": [
+ { "type": "Control", "scope": "#/properties/age" },
+ { "type": "Control", "scope": "#/properties/gender" }
+ ]
+ },
+ {
+ "type": "Group",
+ "label": "Health Information",
+ "elements": [
+ { "type": "Control", "scope": "#/properties/height" },
+ { "type": "Control", "scope": "#/properties/weight" }
+ ]
+ }
+ ]
+}
+```
+
+#### Common Pitfalls
+
+**❌ Missing elements array:**
+```json
+{
+ "type": "SwipeLayout"
+ // ❌ Missing elements - will cause error
+}
+```
+
+**✅ Always include elements:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [] // ✅ Empty array is safe
+}
+```
+
+**❌ Invalid scope paths:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/missingField" // ❌ Field doesn't exist in schema
+}
+```
+
+**✅ Verify scope exists:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/existingField" // ✅ Field exists in schema
+}
+```
+
+**❌ Nested SwipeLayout:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "SwipeLayout", // ❌ Nested SwipeLayout not supported
+ "elements": [...]
+ }
+ ]
+}
+```
+
+**✅ Use VerticalLayout or Group inside SwipeLayout:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout", // ✅ Use VerticalLayout for pages
+ "elements": [...]
+ }
+ ]
+}
+```
+
+## Question Types
+
+ODE supports various question types through the Formplayer component. Question types are specified using the `format` property in the schema.
+
+### Basic Input Types
+
+**Text Input:**
+```json
+{
+ "type": "string",
+ "title": "Name",
+ "format": "text"
+}
+```
+
+**Number Input:**
+```json
+{
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+}
+```
+
+**Date and Time:**
+```json
+{
+ "type": "string",
+ "title": "Date",
+ "format": "date"
+}
+```
+
+**Selection:**
+```json
+{
+ "type": "string",
+ "title": "Choice",
+ "enum": ["option1", "option2"],
+ "enumNames": ["Option 1", "Option 2"]
+}
+```
+
+**Boolean:**
+```json
+{
+ "type": "boolean",
+ "title": "Consent"
+}
+```
+
+## Working with Media & Special Field Types
+
+ODE Formplayer supports specialized field types for capturing media, location, signatures, and scanning codes. Each type has specific schema requirements and platform constraints.
+
+### Photo Capture
+
+Captures photos using device camera or gallery selection.
+
+**Expected Schema:**
+```json
+{
+ "type": "object",
+ "format": "photo",
+ "title": "Profile Photo",
+ "properties": {
+ "filename": { "type": "string" },
+ "uri": { "type": "string" },
+ "width": { "type": "integer" },
+ "height": { "type": "integer" },
+ "timestamp": { "type": "string", "format": "date-time" }
+ }
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/photo"
+}
+```
+
+**Renderer Behavior:**
+- Opens device camera or gallery picker
+- Stores photo as attachment (synchronized separately)
+- Returns metadata object with filename, URI, dimensions, timestamp
+
+**Platform Constraints:**
+- Requires camera permission on mobile devices
+- Photo files are stored locally and synced as attachments
+- Large photos may be compressed automatically
+
+### GPS Location
+
+Captures GPS coordinates with accuracy information.
+
+**Expected Schema:**
+```json
+{
+ "type": "object",
+ "format": "gps",
+ "title": "Current Location",
+ "properties": {
+ "latitude": { "type": "number" },
+ "longitude": { "type": "number" },
+ "altitude": { "type": "number" },
+ "accuracy": { "type": "number" },
+ "timestamp": { "type": "string", "format": "date-time" }
+ }
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/location"
+}
+```
+
+**Renderer Behavior:**
+- Requests location permission (first time)
+- Captures current GPS coordinates
+- Shows accuracy indicator
+- May display map preview (platform dependent)
+
+**Platform Constraints:**
+- Requires location permission
+- GPS accuracy depends on device capabilities and environment
+- Indoor locations may have poor accuracy
+- Battery impact: GPS usage drains battery faster
+
+### Signature Capture
+
+Captures digital signatures using touch input.
+
+**Expected Schema:**
+```json
+{
+ "type": "object",
+ "format": "signature",
+ "title": "Customer Signature",
+ "properties": {
+ "data": { "type": "string" }, // Base64 encoded image
+ "timestamp": { "type": "string", "format": "date-time" }
+ }
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/signature"
+}
+```
+
+**Renderer Behavior:**
+- Opens signature pad interface
+- User draws signature with finger/stylus
+- Stores as base64-encoded image
+- Provides clear/retry functionality
+
+**Platform Constraints:**
+- Works best on touch-enabled devices
+- Signature quality depends on screen size and resolution
+- Stored as image data (may be large)
+
+### Audio Recording
+
+Records audio using device microphone.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "audio",
+ "title": "Voice Note"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/audio"
+}
+```
+
+**Renderer Behavior:**
+- Opens audio recording interface
+- Records audio using device microphone
+- Stores audio file with metadata (duration, format, file size)
+- Provides playback preview
+
+**Platform Constraints:**
+- Requires microphone permission
+- Audio files are stored as attachments
+- File size depends on recording duration and quality
+- Format: Platform-dependent (typically MP3, M4A, or WAV)
+
+### Video Recording
+
+Records video using device camera.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "video",
+ "title": "Instructional Video"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/video"
+}
+```
+
+**Renderer Behavior:**
+- Opens video recording interface
+- Records video using device camera
+- Stores video file with metadata (duration, resolution, format)
+- Provides playback preview
+
+**Platform Constraints:**
+- Requires camera permission
+- Video files are large (stored as attachments)
+- File size depends on duration and resolution
+- Format: Platform-dependent (typically MP4)
+- Battery and storage intensive
+
+### File Selection
+
+Allows users to select files from device storage.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "select_file",
+ "title": "Upload Document"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/document"
+}
+```
+
+**Renderer Behavior:**
+- Opens device file picker
+- User selects file from storage
+- Stores file reference and metadata
+- File is uploaded as attachment
+
+**Platform Constraints:**
+- File type restrictions depend on platform
+- Large files may take time to upload
+- Storage permissions required
+
+### QR Code / Barcode Scanner
+
+Scans QR codes and barcodes using device camera.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "qrcode",
+ "title": "QR Code Scanner"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/qrCode"
+}
+```
+
+**Renderer Behavior:**
+- Opens camera scanner interface
+- Automatically detects and scans codes
+- Returns scanned data as string
+- Supports multiple barcode formats
+
+**Supported Formats:**
+- QR Code
+- Code 128
+- Code 39
+- EAN-13
+- UPC-A
+- Data Matrix
+- PDF417
+- Aztec
+
+**Platform Constraints:**
+- Requires camera permission
+- Requires good lighting for reliable scanning
+- Some formats may not be supported on all platforms
+
+### Best Practices for Media Fields
+
+1. **Consider File Sizes**: Media files are large - be mindful of storage and sync bandwidth
+2. **Request Permissions Early**: Request camera/microphone/location permissions before users need them
+3. **Provide Clear Instructions**: Users may not understand how to use specialized field types
+4. **Handle Offline Scenarios**: Media capture works offline, but upload requires connectivity
+5. **Test on Real Devices**: Media features behave differently on different devices
+6. **Compress When Possible**: Large photos/videos should be compressed before storage
+7. **Validate File Types**: Ensure selected files match expected formats
+
+## Conditional Logic in ODE Forms
+
+Conditional logic allows you to show or hide fields based on other field values. This is essential for creating dynamic, context-aware forms.
+
+### How Rules Work
+
+Rules are defined in the UI schema using the `rule` property on Control elements. Rules evaluate conditions and apply effects (SHOW or HIDE) based on the result.
+
+**Basic Rule Structure:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/targetField",
+ "rule": {
+ "effect": "SHOW", // or "HIDE"
+ "condition": {
+ "scope": "#/properties/sourceField",
+ "schema": {
+ // Condition schema
+ }
+ }
+ }
+}
+```
+
+### Scope Resolution Rules
+
+**Critical Rule**: Rule condition scopes **must exist in the schema at all times**, even when the field is hidden. The scope is evaluated against the current form data.
+
+**Safe Pattern:**
+```json
+{
+ "schema": {
+ "type": "object",
+ "properties": {
+ "contactMethod": {
+ "type": "string",
+ "enum": ["email", "phone"]
+ },
+ "email": {
+ "type": "string",
+ "format": "email"
+ },
+ "phone": {
+ "type": "string"
+ }
+ }
+ },
+ "uischema": {
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/contactMethod"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/email",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/contactMethod", // ✅ Scope exists in schema
+ "schema": {
+ "const": "email"
+ }
+ }
+ }
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/phone",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/contactMethod", // ✅ Scope exists in schema
+ "schema": {
+ "const": "phone"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Safe Patterns
+
+#### Equality Check
+
+Show field when another field equals a specific value:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/email",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/contactMethod",
+ "schema": {
+ "const": "email"
+ }
+ }
+ }
+}
+```
+
+#### Enum Value Check
+
+Show field when another field is one of several values:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/otherDetails",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/category",
+ "schema": {
+ "enum": ["category1", "category2"]
+ }
+ }
+ }
+}
+```
+
+#### Boolean Check
+
+Show field when boolean is true:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/consentDetails",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/hasConsent",
+ "schema": {
+ "const": true
+ }
+ }
+ }
+}
+```
+
+### Unsafe Patterns
+
+#### ❌ Rule Referencing Missing Field
+
+**Problem**: Rule condition scope doesn't exist in schema.
+
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" }
+ // field2 doesn't exist
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field2", // ❌ Field doesn't exist - will crash
+ "schema": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Fix**: Ensure all fields referenced in rules exist in the schema.
+
+#### ❌ Using $data References
+
+**Problem**: `$data` references are not supported and will cause errors.
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field2",
+ "schema": {
+ "minimum": { "$data": "#/properties/minValue" } // ❌ $data not supported
+ }
+ }
+ }
+}
+```
+
+**Fix**: Use literal values only:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field2",
+ "schema": {
+ "minimum": 0 // ✅ Literal value
+ }
+ }
+ }
+}
+```
+
+#### ❌ Using if/then/else
+
+**Problem**: JSON Schema `if/then/else` is not supported in rule conditions.
+
+```json
+{
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field",
+ "schema": {
+ "if": { "type": "string" }, // ❌ Not supported
+ "then": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Fix**: Use simple const or enum checks instead.
+
+### Best Practices for Conditional Logic
+
+1. **Always Define Referenced Fields**: Every field referenced in a rule condition must exist in the schema
+2. **Use Simple Conditions**: Prefer `const` and `enum` over complex schema conditions
+3. **Test All Conditions**: Verify rules work for all possible field values
+4. **Avoid Circular Dependencies**: Don't create rules that depend on each other
+5. **Document Complex Logic**: Comment complex conditional logic in your form specifications
+
+## Advanced Features
+
+### Multimedia Capture
+
+Forms can include fields for capturing photos, audio, and video. These are handled as attachments and synchronized separately from observation metadata.
+
+### Location Capture
+
+GPS coordinates can be captured automatically or manually entered.
+
+### File Attachments
+
+Files can be attached to observations and are synchronized separately from the observation data.
+
+## Form Versioning
+
+Forms support versioning to allow updates while maintaining compatibility with existing observations. When editing an observation, the form version used to create it is used.
+
+## Form Design Best Practices by Application Type
+
+Different application types have different requirements and constraints. Follow these best practices for your specific use case.
+
+### Research Data Collection
+
+**Characteristics**: Structured data collection, often longitudinal, requires high data quality.
+
+**Best Practices:**
+1. **Use Clear Field Names**: Use descriptive, research-standard field names (e.g., `participant_id`, `visit_date`)
+2. **Implement Validation**: Strict validation rules to ensure data quality
+3. **Version Control**: Carefully version forms to maintain data consistency
+4. **Minimize Required Fields**: Only require essential fields to reduce data entry burden
+5. **Use Conditional Logic**: Show relevant fields based on participant characteristics
+6. **Document Changes**: Maintain detailed changelog for form versions
+
+**Example Pattern:**
+```json
+{
+ "schema": {
+ "properties": {
+ "participant_id": {
+ "type": "string",
+ "title": "Participant ID",
+ "pattern": "^P-[0-9]{4}$"
+ },
+ "visit_number": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 10
+ }
+ },
+ "required": ["participant_id", "visit_number"]
+ }
+}
+```
+
+### Medical / Clinical Records
+
+**Characteristics**: Sensitive data, regulatory compliance, complex workflows.
+
+**Best Practices:**
+1. **Consent Management**: Always include consent fields with clear labels
+2. **Date/Time Precision**: Use precise date-time fields for clinical events
+3. **Signature Requirements**: Use signature fields for consent and approvals
+4. **Photo Documentation**: Use photo fields for wound tracking, skin conditions, etc.
+5. **Structured Data**: Use enums for standardized values (e.g., diagnosis codes)
+6. **Audit Trail**: Forms should capture who, what, when for audit purposes
+7. **HIPAA/GDPR Compliance**: Ensure forms comply with data protection regulations
+
+**Example Pattern:**
+```json
+{
+ "schema": {
+ "properties": {
+ "consent_obtained": {
+ "type": "boolean",
+ "title": "Patient consent obtained"
+ },
+ "consent_signature": {
+ "type": "object",
+ "format": "signature",
+ "title": "Patient signature"
+ },
+ "visit_date": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Visit date and time"
+ }
+ },
+ "required": ["consent_obtained", "consent_signature", "visit_date"]
+ }
+}
+```
+
+### Surveys with Consent
+
+**Characteristics**: User-facing, requires clear consent, may be anonymous.
+
+**Best Practices:**
+1. **Consent First**: Place consent fields at the beginning of the form
+2. **Clear Language**: Use plain language, avoid jargon
+3. **Progress Indicators**: Show progress to encourage completion
+4. **Optional Fields**: Mark optional fields clearly
+5. **Privacy Notice**: Include privacy information if collecting personal data
+6. **Thank You Message**: Provide confirmation after submission
+
+**Example Pattern:**
+```json
+{
+ "uischema": {
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Label",
+ "text": "Consent and Privacy"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/consent_read",
+ "label": "I have read and understood the consent form"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/consent_agreed",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/consent_read",
+ "schema": { "const": true }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Longitudinal Forms
+
+**Characteristics**: Same form used multiple times, data comparison over time.
+
+**Best Practices:**
+1. **Consistent Structure**: Maintain consistent field structure across versions
+2. **Version Tracking**: Track which version was used for each observation
+3. **Baseline Data**: Include baseline measurement fields
+4. **Change Detection**: Use conditional logic to highlight changes
+5. **Date Tracking**: Always include date/time fields for temporal analysis
+6. **Backward Compatibility**: Ensure new versions don't break existing data
+
+**Example Pattern:**
+```json
+{
+ "schema": {
+ "properties": {
+ "measurement_date": {
+ "type": "string",
+ "format": "date",
+ "title": "Measurement Date"
+ },
+ "baseline_value": {
+ "type": "number",
+ "title": "Baseline Value"
+ },
+ "current_value": {
+ "type": "number",
+ "title": "Current Value"
+ },
+ "change_from_baseline": {
+ "type": "number",
+ "title": "Change from Baseline",
+ "readOnly": true // Calculated field
+ }
+ }
+ }
+}
+```
+
+### General Best Practices
+
+**Form Structure:**
+1. **Keep Forms Focused**: Each form should have a clear, single purpose
+2. **Logical Grouping**: Group related fields together using Groups or separate pages
+3. **Progressive Disclosure**: Use conditional logic to show fields only when relevant
+4. **Clear Navigation**: Use SwipeLayout for multi-step forms with clear progress indicators
+
+**Field Design:**
+1. **Use Clear Labels**: Field labels should be descriptive and unambiguous
+2. **Provide Help Text**: Use descriptions or placeholders to guide users
+3. **Validate Input**: Use validation rules to catch errors early
+4. **Use Appropriate Types**: Choose the right field type for the data (date picker for dates, not text)
+
+**Data Quality:**
+1. **Required Fields**: Only require truly essential fields
+2. **Default Values**: Provide sensible defaults when appropriate
+3. **Enum Constraints**: Use enums for fields with limited valid values
+4. **Format Validation**: Use format validation (email, date, etc.) when applicable
+
+**Testing:**
+1. **Test All Paths**: Test all conditional logic branches
+2. **Test Validation**: Verify validation rules work correctly
+3. **Test on Devices**: Test on actual mobile devices, not just emulators
+4. **Test Offline**: Verify forms work correctly in offline mode
+5. **User Testing**: Get feedback from actual users before deployment
+
+## Validating Forms Before Deployment
+
+Validating forms before deployment prevents errors and ensures forms work correctly in production. This section covers validation tools and workflows.
+
+### Validation Tools
+
+#### Form Validation Script
+
+ODE provides a validation script (`validate-forms.js`) that checks forms for common issues:
+
+**Usage:**
+```bash
+npm run validate:forms
+```
+
+**Checks Performed:**
+- JSON Schema syntax validation
+- UI Schema format validation
+- Field reference validation (scope paths exist in schema)
+- Required field validation
+- Conditional logic validation (rule scopes exist)
+- SwipeLayout structure validation
+
+**Common Validation Failures:**
+
+1. **Invalid JSON Schema:**
+ ```
+ Error: Schema validation failed
+ - Property "minimum" must be a number
+ ```
+ **Fix**: Ensure `minimum`/`maximum` use literal numbers, not `$data` references
+
+2. **Missing Scope:**
+ ```
+ Error: Scope "#/properties/missingField" not found in schema
+ ```
+ **Fix**: Add the referenced field to the schema or correct the scope path
+
+3. **Invalid UI Schema Structure:**
+ ```
+ Error: SwipeLayout missing required "elements" array
+ ```
+ **Fix**: Ensure SwipeLayout has an `elements` array (can be empty)
+
+4. **Rule Scope Error:**
+ ```
+ Error: Rule condition scope "#/properties/field" not found
+ ```
+ **Fix**: Ensure all fields referenced in rules exist in the schema
+
+### CI Integration
+
+Integrate form validation into your CI/CD pipeline:
+
+**GitHub Actions Example:**
+```yaml
+name: Validate Forms
+
+on: [push, pull_request]
+
+jobs:
+ validate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v2
+ with:
+ node-version: '18'
+ - run: npm install
+ - run: npm run validate:forms
+```
+
+**GitLab CI Example:**
+```yaml
+validate_forms:
+ script:
+ - npm install
+ - npm run validate:forms
+```
+
+### Recommended Workflow
+
+1. **Local Validation**: Run validation script before committing changes
+2. **Pre-commit Hooks**: Set up git hooks to validate forms automatically
+3. **CI Validation**: Include validation in CI pipeline to catch errors early
+4. **Manual Testing**: Test forms on actual devices before deployment
+5. **Staging Deployment**: Deploy to staging environment and test thoroughly
+6. **Production Deployment**: Only deploy validated, tested forms
+
+### Validation Checklist
+
+Before deploying a form, verify:
+
+- [ ] JSON Schema is valid JSON Schema Draft 7
+- [ ] All scope paths in UI schema exist in JSON schema
+- [ ] SwipeLayout is root element (or will be auto-wrapped)
+- [ ] All rule condition scopes exist in schema
+- [ ] No `$data` references used
+- [ ] No `if/then/else` in rule conditions
+- [ ] All required fields are clearly marked
+- [ ] Validation rules use literal values (not dynamic)
+- [ ] Media field types have correct schema structure
+- [ ] Form tested on actual mobile devices
+- [ ] Form tested in offline mode
+- [ ] All conditional logic paths tested
+
+### Troubleshooting Validation Errors
+
+**"minimum value must be ['number']"**
+- **Cause**: Using `$data` or non-numeric value in `minimum`
+- **Fix**: Use literal number: `"minimum": 0`
+
+**"Cannot read properties of undefined (reading 'find')"**
+- **Cause**: Layout missing `elements` array, invalid scope, or rule referencing missing field
+- **Fix**:
+ - Add `elements: []` to layouts
+ - Validate all scope paths exist
+ - Ensure rule scopes reference existing fields
+
+**"Rule condition scope not found"**
+- **Cause**: Rule references field that doesn't exist in schema
+- **Fix**: Add the referenced field to schema or correct the scope path
+
+## Related Documentation
+
+- [Form Specifications Reference](/reference/form-specifications)
+- [Formplayer Supported Schema & UI Profile](/reference/formplayer#supported-schema--ui-profile)
+- [Formplayer Errors Explained](/using/troubleshooting#formplayer-errors)
+- [Your First Form](/using/your-first-form)
+- [Custom Applications](/guides/custom-applications)
+
diff --git a/docs/guides/index.md b/docs/guides/index.md
new file mode 100644
index 0000000..159b8f1
--- /dev/null
+++ b/docs/guides/index.md
@@ -0,0 +1,61 @@
+---
+sidebar_position: 0
+---
+
+# Guides
+
+Step-by-step guides for common tasks and workflows in ODE.
+
+## Form Design & Configuration
+
+
+
+
+
+
Form Design
+
+
+
Complete guide to designing forms, including schema definitions and validation rules.
+}
+```
+
+### AuthContext Methods
+
+- `login(credentials)`: Authenticate user
+- `logout()`: Clear authentication
+- `refreshAuth()`: Refresh expired tokens
+
+## Styling
+
+### Design Tokens
+
+The portal uses ODE design tokens:
+
+- **Primary Color**: Green (#4F7F4E)
+- **Secondary Color**: Gold (#E9B85B)
+- **Typography**: Noto Sans
+- **Spacing**: Consistent spacing scale
+
+### CSS Structure
+
+- **Global Styles**: `src/index.css`
+- **Component Styles**: Component-specific CSS files
+- **No Framework**: Plain CSS (can extend with CSS modules)
+
+## Best Practices
+
+### Code Organization
+
+1. **Types First**: Define TypeScript types
+2. **API Service**: Centralize API calls
+3. **Context for State**: Use Context for global state
+4. **Component Separation**: Separate components and pages
+
+### Error Handling
+
+1. **Try-Catch Blocks**: Wrap API calls
+2. **User-Friendly Messages**: Show clear error messages
+3. **Error Logging**: Log errors for debugging
+4. **Graceful Degradation**: Handle errors gracefully
+
+### Performance
+
+1. **Code Splitting**: Lazy load components
+2. **Memoization**: Memoize expensive computations
+3. **Optimistic Updates**: Update UI before server response
+4. **Debouncing**: Debounce search and filter inputs
+
+## Troubleshooting
+
+### Common Issues
+
+**Portal Won't Load:**
+- Check backend is running
+- Verify API URL configuration
+- Check browser console for errors
+
+**Authentication Fails:**
+- Verify credentials
+- Check JWT_SECRET on server
+- Clear localStorage and retry
+
+**API Calls Fail:**
+- Check network connectivity
+- Verify CORS configuration
+- Check server logs
+
+## Related Documentation
+
+- [Synkronus Server Reference](/reference/synkronus-server) - Backend API
+- [Deployment Guide](/guides/deployment) - Production deployment
+- [Configuration Guide](/guides/configuration) - Configuration options
+- [API Reference](/reference/api) - Complete API documentation
+
diff --git a/docs/reference/synkronus-server.md b/docs/reference/synkronus-server.md
new file mode 100644
index 0000000..5d8398c
--- /dev/null
+++ b/docs/reference/synkronus-server.md
@@ -0,0 +1,484 @@
+---
+sidebar_position: 8
+---
+
+# Synkronus Server Reference
+
+Complete technical reference for the Synkronus server component.
+
+## Overview
+
+Synkronus is a robust synchronization API server built with Go. It provides RESTful endpoints for data synchronization, app bundle management, attachment handling, user management, and form specifications. The server uses PostgreSQL for data storage and JWT for authentication.
+
+## Architecture
+
+### Technology Stack
+
+- **Language**: Go 1.22+
+- **Database**: PostgreSQL 12+
+- **Authentication**: JWT (JSON Web Tokens)
+- **API**: RESTful HTTP API
+- **Documentation**: OpenAPI 3.0 specification
+
+### Project Structure
+
+```
+synkronus/
+├── cmd/synkronus/ # Application entry point
+├── internal/ # Private application code
+│ ├── api/ # API definition and OpenAPI integration
+│ ├── handlers/ # HTTP request handlers
+│ ├── models/ # Domain models
+│ ├── repository/ # Data access layer
+│ └── services/ # Business logic
+└── pkg/ # Public libraries
+ ├── auth/ # Authentication utilities
+ ├── database/ # Database connection and migrations
+ ├── logger/ # Structured logging
+ ├── middleware/ # HTTP middleware
+ └── openapi/ # OpenAPI generated code
+```
+
+## Core Features
+
+### Data Synchronization
+
+- **Bidirectional Sync**: Push and pull operations
+- **Incremental Updates**: Only sync changed data
+- **Conflict Resolution**: Version-based conflict handling
+- **Client Tracking**: Track client sync state
+
+### App Bundle Management
+
+- **Version Control**: Multiple bundle versions
+- **Activation**: Switch active bundle version
+- **File Serving**: Serve bundle files to clients
+- **Manifest Generation**: Automatic manifest creation
+
+### Attachment Handling
+
+- **Binary Storage**: Store attachments separately from observations
+- **Immutable Attachments**: Once uploaded, cannot be modified
+- **Efficient Transfer**: Optimized for large files
+- **Manifest System**: Track attachment changes
+
+### User Management
+
+- **JWT Authentication**: Secure token-based auth
+- **Role-Based Access**: read-only, read-write, admin roles
+- **User CRUD**: Create, read, update, delete users
+- **Password Management**: Secure password handling
+
+### Form Specifications
+
+- **Versioned Forms**: Multiple versions per form type
+- **Schema Storage**: Store JSON schemas
+- **UI Schema Support**: Store UI layout definitions
+- **Version Negotiation**: Client requests specific versions
+
+## API Endpoints
+
+### Authentication
+
+#### POST /auth/login
+
+Authenticate user and receive JWT token.
+
+**Request:**
+```json
+{
+ "username": "user",
+ "password": "password"
+}
+```
+
+**Response:**
+```json
+{
+ "token": "eyJhbGciOiJIUzI1NiIs...",
+ "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
+ "expiresIn": 3600
+}
+```
+
+#### POST /auth/refresh
+
+Refresh expired JWT token.
+
+**Request:**
+```json
+{
+ "refreshToken": "eyJhbGciOiJIUzI1NiIs..."
+}
+```
+
+### Synchronization
+
+#### POST /sync/pull
+
+Pull changes from server.
+
+**Request:**
+```json
+{
+ "clientId": "client-123",
+ "currentVersion": 100,
+ "schemaTypes": ["survey", "visit"]
+}
+```
+
+**Response:**
+```json
+{
+ "changes": {
+ "observations": [...]
+ },
+ "timestamp": 150
+}
+```
+
+#### POST /sync/push
+
+Push changes to server.
+
+**Request:**
+```json
+{
+ "clientId": "client-123",
+ "changes": {
+ "observations": [...]
+ }
+}
+```
+
+**Response:**
+```json
+{
+ "timestamp": 150,
+ "conflicts": []
+}
+```
+
+### App Bundles
+
+#### GET /app-bundle/manifest
+
+Get current app bundle manifest.
+
+**Response:**
+```json
+{
+ "version": "20250114-123456",
+ "files": [...],
+ "hash": "abc123..."
+}
+```
+
+#### GET `/app-bundle/download/{path}`
+
+Download app bundle file.
+
+**Path Parameters:**
+- `path`: File path within bundle
+
+#### POST /app-bundle/push
+
+Upload new app bundle (admin only).
+
+**Request:** Multipart form with `bundle` file
+
+**Response:**
+```json
+{
+ "version": "20250114-123456",
+ "manifest": {...}
+}
+```
+
+#### GET /app-bundle/versions
+
+List all app bundle versions.
+
+#### POST /app-bundle/switch
+
+Switch active bundle version (admin only).
+
+### Attachments
+
+#### GET /attachments/manifest
+
+Get attachment manifest.
+
+**Query Parameters:**
+- `since`: Timestamp to get changes since
+
+#### GET `/attachments/{id}`
+
+Download attachment file.
+
+#### POST /attachments
+
+Upload attachment (multipart form).
+
+### Form Specifications
+
+#### GET `/formspecs/{formType}/{version}`
+
+Get form specification.
+
+**Path Parameters:**
+- `formType`: Form type identifier
+- `version`: Form version
+
+#### POST /formspecs
+
+Create form specification (admin only).
+
+### Users
+
+#### GET /users
+
+List all users (admin only).
+
+#### POST /users/create
+
+Create new user (admin only).
+
+#### GET `/users/{username}`
+
+Get user details.
+
+#### PUT `/users/{username}`
+
+Update user (admin only).
+
+#### DELETE `/users/{username}`
+
+Delete user (admin only).
+
+### Data Export
+
+#### GET /data/export
+
+Export observations as Parquet ZIP.
+
+**Query Parameters:**
+- `format`: Export format (parquet, json, csv)
+
+## Configuration
+
+### Environment Variables
+
+| Variable | Description | Default | Required |
+|----------|-------------|---------|----------|
+| `PORT` | HTTP server port | `8080` | No |
+| `DB_CONNECTION` | PostgreSQL connection string | - | Yes |
+| `JWT_SECRET` | Secret for JWT signing | - | Yes |
+| `LOG_LEVEL` | Logging level (debug, info, warn, error) | `info` | No |
+| `APP_BUNDLE_PATH` | Directory for app bundles | `./data/app-bundles` | No |
+| `MAX_VERSIONS_KEPT` | Maximum bundle versions to keep | `5` | No |
+| `ADMIN_USERNAME` | Initial admin username | `admin` | No |
+| `ADMIN_PASSWORD` | Initial admin password | `admin` | No |
+
+### Example Configuration
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://user:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=info
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+ADMIN_USERNAME=admin
+ADMIN_PASSWORD=admin
+```
+
+## Database Schema
+
+### Observations Table
+
+| Column | Type | Description |
+|--------|------|-------------|
+| `id` | UUID | Primary key |
+| `form_type` | VARCHAR | Form type identifier |
+| `data` | JSONB | Observation data |
+| `created_at` | TIMESTAMP | Creation timestamp |
+| `updated_at` | TIMESTAMP | Last update timestamp |
+| `deleted` | BOOLEAN | Soft delete flag |
+| `version` | INTEGER | Version number (auto-increment) |
+
+### Users Table
+
+| Column | Type | Description |
+|--------|------|-------------|
+| `id` | UUID | Primary key |
+| `username` | VARCHAR | Unique username |
+| `password_hash` | VARCHAR | Hashed password |
+| `role` | VARCHAR | User role (read-only, read-write, admin) |
+| `created_at` | TIMESTAMP | Creation timestamp |
+
+### App Bundle Versions Table
+
+| Column | Type | Description |
+|--------|------|-------------|
+| `version` | VARCHAR | Version identifier |
+| `is_active` | BOOLEAN | Active version flag |
+| `created_at` | TIMESTAMP | Creation timestamp |
+
+## Synchronization Protocol
+
+### Two-Phase Sync
+
+#### Phase 1: Observation Sync
+
+1. Client requests changes via `/sync/pull`
+2. Server returns observations changed since client's version
+3. Client applies changes locally
+4. Client pushes local changes via `/sync/push`
+5. Server applies changes and returns new version
+
+#### Phase 2: Attachment Sync
+
+1. Client requests attachment manifest
+2. Server returns list of attachments to download
+3. Client downloads missing attachments
+4. Client uploads pending attachments
+5. Server confirms receipt
+
+### Conflict Resolution
+
+Conflicts are detected when:
+
+- Same observation modified on multiple clients
+- Observation deleted on one client, modified on another
+
+Resolution strategy:
+
+- **Last Write Wins**: Most recent change wins
+- **Version Tracking**: Version numbers prevent conflicts
+- **Client Responsibility**: Clients handle conflict resolution
+
+## Security
+
+### Authentication
+
+- **JWT Tokens**: Secure token-based authentication
+- **Token Expiration**: Tokens expire after configured time
+- **Refresh Tokens**: Long-lived refresh tokens
+- **Password Hashing**: bcrypt password hashing
+
+### Authorization
+
+- **Role-Based Access**: Three roles (read-only, read-write, admin)
+- **Endpoint Protection**: Middleware protects admin endpoints
+- **Token Validation**: All requests validate JWT tokens
+
+### Data Protection
+
+- **HTTPS**: Recommended for production
+- **Input Validation**: All inputs validated
+- **SQL Injection Prevention**: Parameterized queries
+- **XSS Protection**: Input sanitization
+
+## Deployment
+
+### Docker Deployment
+
+See [Deployment Guide](/guides/deployment) for complete deployment instructions.
+
+### Quick Start
+
+```bash
+docker compose up -d
+```
+
+### Production Setup
+
+1. Configure environment variables
+2. Set up PostgreSQL database
+3. Configure reverse proxy (Nginx)
+4. Set up SSL/TLS certificates
+5. Configure monitoring and logging
+
+## Monitoring
+
+### Health Check
+
+```bash
+curl http://localhost:8080/health
+```
+
+Returns `OK` if server is healthy.
+
+### Logging
+
+Structured logging with levels:
+
+- **Debug**: Detailed debugging information
+- **Info**: General informational messages
+- **Warn**: Warning messages
+- **Error**: Error messages
+
+### Metrics
+
+Key metrics to monitor:
+
+- Request rate
+- Response times
+- Error rates
+- Database connection pool
+- Active sync operations
+
+## Performance
+
+### Optimization Strategies
+
+- **Connection Pooling**: PostgreSQL connection pool
+- **Query Optimization**: Indexed database queries
+- **Caching**: Cache app bundle manifests
+- **Compression**: Compress responses when possible
+
+### Scaling
+
+- **Horizontal Scaling**: Multiple server instances
+- **Load Balancing**: Distribute requests across instances
+- **Database Replication**: Read replicas for database
+- **CDN**: Serve static files via CDN
+
+## Troubleshooting
+
+### Common Issues
+
+**Database Connection Errors:**
+- Verify PostgreSQL is running
+- Check connection string format
+- Verify database exists
+- Check user permissions
+
+**Authentication Failures:**
+- Verify JWT_SECRET is set
+- Check token expiration
+- Verify user credentials
+
+**Sync Failures:**
+- Check database connectivity
+- Verify client version tracking
+- Review server logs
+
+## API Versioning
+
+The API supports versioning via the `x-api-version` header:
+
+```http
+x-api-version: 1.0.0
+```
+
+Version negotiation allows clients to request specific API versions.
+
+## Related Documentation
+
+- [API Reference](/reference/api) - Complete API documentation
+- [Deployment Guide](/guides/deployment) - Production deployment
+- [Configuration Guide](/guides/configuration) - Configuration options
+- [Synkronus CLI Reference](/reference/synkronus-cli) - CLI tool
+
diff --git a/docs/using/.gitkeep b/docs/using/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docs/using/app-bundles.md b/docs/using/app-bundles.md
new file mode 100644
index 0000000..ef90524
--- /dev/null
+++ b/docs/using/app-bundles.md
@@ -0,0 +1,176 @@
+---
+sidebar_position: 4
+---
+
+# Understanding App Bundles
+
+Learn how app bundles work in ODE and how they enable custom applications and forms.
+
+## What Are App Bundles?
+
+App bundles are packaged collections of files that define custom applications for ODE. They contain everything needed to run a custom data collection application within the Formulus mobile app:
+
+- **Custom web application** - HTML, CSS, and JavaScript files
+- **Form specifications** - JSON schemas defining data collection forms
+- **Configuration files** - Settings and metadata for the application
+- **Assets** - Images, fonts, and other resources
+
+When you open Formulus and connect to a Synkronus server, the app automatically downloads the current app bundle. This bundle determines what forms are available, how they look, and what workflows you can use.
+
+## How App Bundles Work
+
+### Download Process
+
+1. **Initial Sync**: When you first log in to Formulus, the app checks the server for the current app bundle version
+2. **Version Check**: The app compares the server's version with the version stored locally
+3. **Download**: If a new version is available, the app downloads the bundle files
+4. **Extraction**: The bundle is extracted and stored locally on your device
+5. **Activation**: The new bundle becomes active, and you can use the updated forms and features
+
+### Automatic Updates
+
+App bundles update automatically:
+
+- **On Login**: When you log in, the app checks for updates
+- **On Manual Sync**: When you tap "Sync Now" in the app
+- **Periodically**: The app may check for updates in the background (if configured)
+
+### Version Management
+
+Each app bundle has a version identifier (typically a timestamp). This ensures:
+
+- **Consistency**: All devices use the same version of forms and workflows
+- **Rollback**: Administrators can switch back to previous versions if needed
+- **Tracking**: You can see which version of the app bundle you're using
+
+## What's Inside an App Bundle
+
+### Custom Application
+
+The main component is a custom web application that runs inside Formulus. This application:
+
+- **Provides Navigation**: Custom menus and screens for your workflow
+- **Displays Forms**: Shows available forms and allows you to start data collection
+- **Manages Data**: Lets you view, edit, and manage your observations
+- **Custom Branding**: Can include your organization's logo and styling
+
+### Form Specifications
+
+App bundles include form definitions that specify:
+
+- **Data Fields**: What information to collect (name, age, location, etc.)
+- **Field Types**: How to input data (text, number, date, photo, GPS, etc.)
+- **Validation Rules**: Requirements for data entry (required fields, value ranges, etc.)
+- **Layout**: How the form is organized and presented
+
+### Configuration
+
+Bundles may include configuration files that:
+
+- **Define Settings**: Application-specific settings and preferences
+- **Specify Behavior**: How the application should behave in different scenarios
+- **Set Permissions**: What features and data access the application needs
+
+## Using App Bundles
+
+### Accessing Your Application
+
+1. **Open Formulus** on your device
+2. **Log in** to your account
+3. **Wait for sync** to complete (if first time or after update)
+4. **Your custom application** loads automatically as the main interface
+
+### Working with Forms
+
+Once the app bundle is loaded:
+
+1. **Navigate** through your custom application's interface
+2. **Select a form** from the available forms list
+3. **Fill out the form** with the required information
+4. **Submit** the form to create an observation
+5. **View observations** in your data management section
+
+### Updating App Bundles
+
+App bundles update automatically, but you can also manually trigger an update:
+
+1. **Open Formulus** → **Settings** → **Sync**
+2. **Tap "Sync Now"** or **"Force Download"**
+3. **Wait for download** to complete
+4. **App restarts** or refreshes with the new bundle
+
+## Troubleshooting App Bundles
+
+### Bundle Not Downloading
+
+**Problem**: App bundle fails to download or sync.
+
+**Solutions**:
+- Check internet connection
+- Verify server is accessible
+- Try manual sync: Settings → Sync → Sync Now
+- Clear app cache: Settings → Storage → Clear Cache
+- Restart the app
+
+### Forms Not Appearing
+
+**Problem**: After sync, forms don't appear in the app.
+
+**Solutions**:
+- Verify bundle downloaded successfully (check Sync screen)
+- Check bundle version matches server version
+- Try force refresh: Settings → Sync → Force Download
+- Clear app data and re-login (warning: deletes local data)
+
+### Outdated Forms
+
+**Problem**: Forms show old fields or structure.
+
+**Solutions**:
+- Check if bundle update is available: Settings → Sync
+- Force download latest bundle: Settings → Sync → Force Download
+- Verify server has the latest bundle version
+- Contact administrator if issue persists
+
+### Bundle Version Mismatch
+
+**Problem**: App shows different version than expected.
+
+**Solutions**:
+- Force sync to get latest version
+- Check server is serving the correct active version
+- Verify you're connected to the correct server
+- Contact administrator to verify bundle version
+
+## App Bundle Best Practices
+
+### For Users
+
+1. **Sync Regularly**: Keep your app bundle up to date by syncing regularly
+2. **Check Version**: Verify you're using the latest bundle version
+3. **Report Issues**: If forms or features don't work, report to your administrator
+4. **Backup Data**: Ensure observations are synced before major updates
+
+### For Administrators
+
+1. **Test Before Deploy**: Test new bundles thoroughly before activating
+2. **Version Control**: Use clear version identifiers (timestamps recommended)
+3. **Rollback Plan**: Keep previous versions available for quick rollback
+4. **Notify Users**: Inform users when major updates are deployed
+5. **Monitor Usage**: Track which versions are in use across devices
+
+## Technical Details
+
+For technical information about app bundle structure, format, and development, see:
+
+- [App Bundle Format Reference](/reference/app-bundle-format) - Technical specification
+- [Custom Applications Guide](/guides/custom-applications) - Building custom applications
+- [Form Design Guide](/guides/form-design) - Creating form specifications
+
+## Related Documentation
+
+- [Your First Form](/using/your-first-form) - Get started with data collection
+- [Synchronization](/using/synchronization) - Understand how data syncs
+- [Formulus Features](/using/formulus-features) - Complete app feature guide
+- [Working Offline](/using/working-offline) - Offline capabilities
+
diff --git a/docs/using/custom-applications.md b/docs/using/custom-applications.md
new file mode 100644
index 0000000..13c208a
--- /dev/null
+++ b/docs/using/custom-applications.md
@@ -0,0 +1,115 @@
+---
+sidebar_position: 3
+---
+
+# Custom Applications
+
+Custom applications are web-based interfaces that run within the Formulus mobile app, providing specialized workflows and user experiences.
+
+## Overview
+
+Custom applications allow you to:
+
+- Create custom navigation and user interfaces
+- Integrate with the ODE form system
+- Access observation data through the Formulus JavaScript interface
+- Build specialized workflows for specific use cases
+
+## How Custom Applications Work
+
+Custom applications are defined in app bundles, which include:
+
+- HTML, CSS, and JavaScript files
+- Form specifications
+- Custom renderers
+- Configuration files
+
+The app bundle is uploaded to the Synkronus server and downloaded by mobile devices during synchronization. When a user opens a custom application, it runs in a WebView within the Formulus app.
+
+## Formulus JavaScript Interface
+
+Custom applications interact with Formulus through a JavaScript interface:
+
+```javascript
+// Create a new observation
+window.formulus.addObservation(formType, initializationData);
+
+// Edit an existing observation
+window.formulus.editObservation(formType, observationId);
+
+// Delete an observation
+window.formulus.deleteObservation(formType, observationId);
+```
+
+## Creating a Custom Application
+
+Custom applications are web-based interfaces that run within the Formulus mobile app. They integrate with ODE through the Formulus JavaScript interface.
+
+### Basic Structure
+
+A custom application consists of:
+
+1. **HTML file**: Main entry point (typically `index.html`)
+2. **JavaScript**: Application logic using the Formulus API
+3. **CSS**: Styling for the application
+4. **Manifest**: Bundle metadata
+
+### Getting Started
+
+1. **Include Formulus Load Script**:
+
+```html
+
+```
+
+2. **Initialize the API**:
+
+```javascript
+async function init() {
+ const api = await getFormulus();
+ // Use the API
+}
+```
+
+3. **Use Formulus Methods**:
+
+```javascript
+// Create observation
+await api.addObservation('form-type', {});
+
+// Edit observation
+await api.editObservation('form-type', 'observation-id');
+```
+
+### Packaging
+
+Package your application as a ZIP file with:
+- `index.html` (or your entry point)
+- `manifest.json`
+- All assets (CSS, JS, images)
+
+### Deployment
+
+Upload the bundle to your Synkronus server:
+
+```bash
+synk app-bundle upload bundle.zip --activate
+```
+
+See the [Custom Applications guide](/guides/custom-applications) for detailed instructions on building and deploying custom applications.
+
+## Use Cases
+
+Custom applications are suitable for:
+
+- Specialized data collection workflows
+- Custom user interfaces that match organizational branding
+- Integration with external systems
+- Complex navigation requirements
+
+## Next Steps
+
+- Read the [Custom Applications guide](/guides/custom-apps/overview) for detailed information
+- Learn about [app bundle structure](/guides/custom-apps/app-bundle-structure)
+- Explore [custom renderers](/guides/custom-apps/custom-renderers)
+
diff --git a/docs/using/data-management.md b/docs/using/data-management.md
new file mode 100644
index 0000000..75be39f
--- /dev/null
+++ b/docs/using/data-management.md
@@ -0,0 +1,105 @@
+---
+sidebar_position: 4
+---
+
+# Data Management
+
+This guide covers viewing, editing, and managing observations in ODE.
+
+## Viewing Observations
+
+Observations can be viewed in the Formulus app:
+
+1. Navigate to the observations list
+2. Filter observations by form type, date, or sync status
+3. Select an observation to view details
+4. Review the form data and metadata
+
+## Editing Observations
+
+To edit an observation:
+
+1. Open the observation from the list
+2. Select the edit option
+3. Modify the form fields as needed
+4. Save your changes
+
+Edited observations are marked for synchronization and will be updated on the server during the next sync operation.
+
+## Deleting Observations
+
+Observations can be deleted:
+
+1. Open the observation
+2. Select the delete option
+3. Confirm the deletion
+
+Deleted observations are marked as deleted locally and synchronized to the server. The server maintains a record of deleted observations for audit purposes.
+
+## Filtering and Searching
+
+The observations list supports filtering by:
+
+- Form type
+- Date range
+- Sync status (synced, pending, error)
+- Custom criteria based on form data
+
+## Exporting Data
+
+Data can be exported from the server using multiple methods:
+
+
+
+
+Export all observations as a Parquet ZIP archive:
+
+```bash
+synk data export exports.zip
+```
+
+Export to different formats:
+
+```bash
+# Parquet (default)
+synk data export observations.zip
+
+# JSON
+synk data export observations.json --format json
+
+# CSV
+synk data export observations.csv --format csv
+```
+
+
+
+
+```bash
+curl -X GET http://your-server:8080/api/dataexport/parquet \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -o observations.zip
+```
+
+
+
+
+1. Navigate to the Portal
+2. Go to the "Data Export" section
+3. Select export format (Parquet, JSON, CSV)
+4. Click "Export" to download
+
+
+
+
+The export includes all observations in the selected format, organized by schema type. See the [API Reference](/reference/api) for details.
+
+## Data Synchronization
+
+Observations are synchronized between devices and the server automatically. See [Synchronization](/using/synchronization) for details on how synchronization works.
+
+## Next Steps
+
+- Learn about [synchronization](/using/synchronization) in detail
+- Review the [API Reference](/reference/api/endpoints) for programmatic access
+- Explore [data export options](/reference/api/endpoints) for analysis
+
diff --git a/docs/using/formulus-features.md b/docs/using/formulus-features.md
new file mode 100644
index 0000000..eda4e64
--- /dev/null
+++ b/docs/using/formulus-features.md
@@ -0,0 +1,374 @@
+---
+sidebar_position: 5
+---
+
+# Formulus Features
+
+Complete user guide for the Formulus mobile application features and capabilities.
+
+## Overview
+
+Formulus is an offline-first mobile data collection application that enables field workers to collect structured data in environments with limited or no connectivity. The app works seamlessly with custom applications and provides comprehensive data collection capabilities.
+
+## Core Features
+
+### Offline-First Architecture
+
+Formulus is designed to work completely offline:
+
+- **Local Storage**: All data is stored locally on your device using WatermelonDB
+- **Offline Forms**: Fill out forms without internet connection
+- **Automatic Sync**: Data syncs automatically when connectivity is restored
+- **No Data Loss**: Observations are saved locally even if sync fails
+
+### Custom Application Support
+
+Formulus can host custom web applications:
+
+- **Custom Interfaces**: Run specialized workflows and user interfaces
+- **Branded Experience**: Display your organization's branding and styling
+- **Flexible Navigation**: Custom menus and navigation structures
+- **Integrated Forms**: Seamless integration with the form system
+
+### Rich Data Collection
+
+Support for various data types:
+
+- **Text Input**: Single and multi-line text fields
+- **Numbers**: Integer and decimal numeric values
+- **Dates and Times**: Date pickers, time selectors, and datetime fields
+- **Selections**: Single choice dropdowns and multi-select checkboxes
+- **Media Capture**: Photos, audio recordings, and video
+- **Location**: GPS coordinates with accuracy information
+- **Signatures**: Digital signature capture
+- **Files**: File attachments and document uploads
+- **Barcodes**: QR code and barcode scanning
+
+### Synchronization
+
+Bidirectional data synchronization:
+
+- **Automatic Sync**: Syncs when network becomes available
+- **Manual Sync**: Trigger sync on demand
+- **Incremental Updates**: Only syncs changed data
+- **Conflict Resolution**: Automatically handles sync conflicts
+- **Attachment Handling**: Separate sync for binary files
+
+## App Navigation
+
+### Main Screens
+
+| Screen | Description | Access |
+|--------|-------------|--------|
+| **Home/Dashboard** | Overview and quick actions | Default screen after login |
+| **Forms** | List of available forms | Bottom tab or menu |
+| **Observations** | Saved data records | Bottom tab or menu |
+| **Sync** | Sync status and actions | Bottom tab or menu |
+| **Settings** | App configuration | Menu or gear icon |
+
+### Navigation Elements
+
+- **Bottom Tabs**: Quick access to main sections
+- **Menu Drawer**: Swipe from left or tap hamburger icon (☰)
+- **Back Button**: Return to previous screen
+- **Floating Action Button**: Quick actions (+ button)
+
+## Working with Forms
+
+### Viewing Available Forms
+
+1. Navigate to the **Forms** screen
+2. View the list of available forms from the current app bundle
+3. Each form displays:
+ - Form name/title
+ - Description (if available)
+ - Icon (if configured)
+
+### Starting a New Form
+
+1. Tap on a form from the list
+2. Form opens in the form player
+3. Fill in fields as required
+4. Navigate through form sections using Next/Previous buttons or swiping
+
+### Form Field Types
+
+| Field Type | Description | Input Method |
+|------------|-------------|--------------|
+| **Text** | Single/multi-line text | Keyboard input |
+| **Number** | Numeric values | Number keyboard |
+| **Date** | Date selection | Date picker |
+| **Time** | Time selection | Time picker |
+| **Select** | Single choice | Dropdown/radio buttons |
+| **Multi-select** | Multiple choices | Checkboxes |
+| **Photo** | Camera capture | Camera interface |
+| **GPS** | Location capture | GPS sensor |
+| **Signature** | Digital signature | Touch drawing |
+| **Audio** | Voice recording | Microphone |
+| **Video** | Video recording | Camera |
+| **File** | File attachment | File picker |
+| **QR Code** | Scan QR/barcode | Camera scanner |
+
+### Form Navigation
+
+- **Swipe Left/Right**: Navigate between form sections
+- **Next/Previous Buttons**: Move through form step by step
+- **Progress Bar**: Shows completion status
+- **Section Tabs**: Jump to specific sections (if enabled)
+
+### Saving Forms
+
+#### Save as Draft
+
+1. Tap **"Save Draft"** at any time while filling the form
+2. Form is saved locally with current data
+3. Resume later from the Observations screen
+4. Draft status is shown in the observation list
+
+#### Submit/Finalize
+
+1. Complete all required fields
+2. Tap **"Submit"** or **"Finalize"**
+3. Validation runs automatically - errors shown if any
+4. Observation saved as pending upload
+5. Will sync when connection is available
+
+### Form Validation
+
+Forms may include validation rules:
+
+- **Required Fields**: Must be filled before submission
+- **Format Validation**: Email, phone number, and other format checks
+- **Range Validation**: Minimum and maximum values
+- **Conditional Logic**: Fields shown based on other answers
+
+**Validation Errors:**
+- Red highlight on invalid fields
+- Error messages displayed below fields
+- Cannot submit until all errors are resolved
+
+## Managing Observations
+
+### Viewing Observations
+
+1. Navigate to the **Observations** screen
+2. View list of all saved observations
+3. Each entry shows:
+ - Form name
+ - Date/time created
+ - Status (draft, pending, synced)
+ - Key data fields
+
+### Observation Status
+
+| Status | Description |
+|--------|-------------|
+| **Draft** | Incomplete, can be edited |
+| **Pending** | Complete, awaiting sync |
+| **Syncing** | Currently uploading to server |
+| **Synced** | Successfully uploaded to server |
+| **Error** | Sync failed, retry needed |
+
+### Editing Observations
+
+#### Edit Draft
+
+1. Tap on a draft observation
+2. Form opens with saved data
+3. Make changes as needed
+4. Save or Submit
+
+#### Edit Pending (if allowed)
+
+1. Tap on a pending observation
+2. May need to "Unlock" for editing
+3. Make changes
+4. Re-submit
+
+### Deleting Observations
+
+1. Long-press on observation or tap menu (⋮)
+2. Select **"Delete"**
+3. Confirm deletion
+
+**Note**: Synced observations may not be deletable locally depending on configuration.
+
+## Synchronization
+
+### Automatic Sync
+
+The app automatically syncs when:
+
+- Network connection becomes available
+- App is opened (background sync)
+- Periodically (if configured in settings)
+
+### Manual Sync
+
+1. Navigate to **Sync** screen
+2. Tap **"Sync Now"**
+3. Watch progress - upload count and status
+4. Check results - success/failure messages
+
+### Sync Process
+
+1. **Pull**: Download new forms and server data
+2. **Push**: Upload pending observations
+3. **Attachments**: Upload photos, audio, and other files
+4. **Confirmation**: Server acknowledges receipt
+
+### Sync Indicators
+
+- **Sync Icon**: Appears in status bar when syncing
+- **Badge on Sync Tab**: Shows pending upload count
+- **Last Sync Time**: Displayed on sync screen
+- **Individual Status**: Each observation shows its sync status
+
+### Offline Mode
+
+When offline, you can:
+
+- ✅ Fill out forms
+- ✅ Save observations locally
+- ✅ View previously synced data
+- ❌ Cannot upload new data
+- ❌ Cannot download new forms
+
+Data syncs automatically when connection returns.
+
+## Attachments
+
+### Capturing Photos
+
+1. Tap photo field in form
+2. Camera opens automatically
+3. Take photo or select from gallery
+4. Review and confirm
+5. Photo is attached to observation
+
+### Capturing GPS Location
+
+1. Tap GPS field in form
+2. Location permission requested (first time only)
+3. Wait for GPS fix
+4. Coordinates captured (latitude, longitude, accuracy)
+5. May show map preview
+
+### Recording Audio
+
+1. Tap audio field in form
+2. Microphone permission requested (first time only)
+3. Tap record to start
+4. Speak clearly
+5. Tap stop when done
+6. Review and confirm
+
+### Capturing Signatures
+
+1. Tap signature field in form
+2. Signature pad opens
+3. Sign with finger on screen
+4. Tap "Done" to save
+5. Tap "Clear" to retry
+
+### Recording Video
+
+1. Tap video field in form
+2. Camera opens in video mode
+3. Tap record to start
+4. Tap stop when done
+5. Review and confirm
+
+### Scanning QR Codes
+
+1. Tap QR code field in form
+2. Camera opens in scanner mode
+3. Point camera at QR code
+4. Code is automatically scanned
+5. Data is populated in the field
+
+## Settings
+
+### Server Settings
+
+- **Server URL**: Synkronus server address
+- **Test Connection**: Verify connectivity to server
+- **Auto-login**: Automatically log in on app start
+
+### User Settings
+
+- **Username**: Current logged-in user
+- **Change Password**: Update account password
+- **Logout**: Clear session and return to login
+
+### Sync Settings
+
+- **Auto-sync**: Enable/disable automatic synchronization
+- **Sync on WiFi Only**: Save mobile data by syncing only on WiFi
+- **Sync Interval**: How often to check for sync (if auto-sync enabled)
+
+### App Settings
+
+- **Notifications**: Enable/disable push notifications
+- **Theme**: Light or dark mode
+- **Language**: App language selection
+- **Clear Cache**: Free up storage space
+- **Storage Info**: View storage usage
+
+## Best Practices
+
+### Data Collection
+
+1. **Sync Before Fieldwork**: Get latest forms and updates
+2. **Check Battery**: Ensure sufficient charge for field work
+3. **Test GPS Outdoors**: Better accuracy in open areas
+4. **Save Frequently**: Avoid data loss from app crashes
+5. **Sync When Possible**: Don't wait too long between syncs
+
+### Offline Work
+
+1. **Sync Before Going Offline**: Download latest forms and data
+2. **Save Observations as You Go**: Don't wait until the end
+3. **Check Pending Count**: Verify all data before leaving field
+4. **Sync Immediately**: When back online, sync right away
+
+### Data Quality
+
+1. **Fill All Required Fields**: Complete forms fully
+2. **Double-Check Entries**: Verify accuracy before submitting
+3. **Take Clear Photos**: Ensure photos are in focus and well-lit
+4. **Verify GPS Accuracy**: Check location accuracy before submitting
+5. **Review Before Submitting**: Review all data before final submission
+
+## Troubleshooting
+
+### Forms Not Loading
+
+- Check internet connection
+- Verify server is accessible
+- Try manual sync: Settings → Sync → Sync Now
+- Clear app cache: Settings → Storage → Clear Cache
+
+### Sync Failures
+
+- Check internet connection
+- Verify server URL is correct
+- Check server status
+- Try manual sync
+- Review error messages in Sync screen
+
+### App Crashes
+
+- Restart the app
+- Clear app cache
+- Update to latest version
+- Reinstall if issues persist
+
+## Related Documentation
+
+- [Installing Formulus](/getting-started/installing-formulus) - Installation guide
+- [Your First Form](/using/your-first-form) - Getting started with forms
+- [Synchronization](/using/synchronization) - Detailed sync information
+- [Working Offline](/using/working-offline) - Offline capabilities
+- [App Bundles](/using/app-bundles) - Understanding app bundles
+
diff --git a/docs/using/index.md b/docs/using/index.md
new file mode 100644
index 0000000..53a3102
--- /dev/null
+++ b/docs/using/index.md
@@ -0,0 +1,100 @@
+---
+sidebar_position: 0
+---
+
+# Using ODE
+
+Learn how to use ODE to create forms, manage data, and build custom applications.
+
+## Core Workflows
+
+
+
+
+
+
Your First Form
+
+
+
Create your first data collection form and learn the basics.
diff --git a/versioned_docs/version-1.0/development/installing-formulus-dev.md b/versioned_docs/version-1.0/development/installing-formulus-dev.md
new file mode 100644
index 0000000..0156b8e
--- /dev/null
+++ b/versioned_docs/version-1.0/development/installing-formulus-dev.md
@@ -0,0 +1,510 @@
+---
+sidebar_position: 2
+---
+
+# Installing Formulus for Development
+
+Complete guide for developers to install Formulus on physical devices or emulators using ADB or development builds.
+
+## Overview
+
+Developers can install Formulus on Android devices or emulators using several methods:
+
+- **ADB Installation** - Install APK directly via Android Debug Bridge
+- **Android Emulator** - Run and test on virtual devices
+- **Development Build** - Build and run from source with hot reload
+
+This guide covers cross-platform commands for Linux, macOS, and Windows.
+
+## Prerequisites
+
+Before installing, ensure you have:
+
+| Requirement | Description |
+|-------------|-------------|
+| **Android SDK** | Android SDK Platform Tools (includes ADB) |
+| **ADB** | Android Debug Bridge (part of SDK Platform Tools) |
+| **USB Drivers** | Device-specific USB drivers (for physical devices) |
+| **Developer Options** | Enabled on Android device (for physical devices) |
+| **USB Debugging** | Enabled on Android device (for physical devices) |
+
+### Installing Android SDK Platform Tools
+
+
+
+
+```bash
+# Ubuntu/Debian
+sudo apt-get update
+sudo apt-get install android-tools-adb android-tools-fastboot
+
+# Fedora
+sudo dnf install android-tools
+
+# Arch Linux
+sudo pacman -S android-tools
+
+# Verify installation
+adb version
+```
+
+
+
+
+```bash
+# Using Homebrew
+brew install android-platform-tools
+
+# Verify installation
+adb version
+```
+
+
+
+
+1. **Download Android SDK Platform Tools** from [developer.android.com](https://developer.android.com/studio/releases/platform-tools)
+2. **Extract the ZIP file** to a location like `C:\platform-tools`
+3. **Add to PATH**:
+ - Open System Properties → Environment Variables
+ - Add `C:\platform-tools` to the PATH variable
+4. **Verify installation**:
+ ```powershell
+ adb version
+ ```
+
+
+
+
+## Method 1: ADB Installation on Physical Device
+
+### Step 1: Enable Developer Options
+
+1. **Open Settings** on your Android device
+2. **Navigate to About Phone** (or About Device)
+3. **Find "Build Number"** (usually at the bottom)
+4. **Tap "Build Number" 7 times** until you see "You are now a developer!"
+
+### Step 2: Enable USB Debugging
+
+1. **Go back to Settings**
+2. **Open Developer Options** (now visible in Settings)
+3. **Enable "USB Debugging"**
+4. **Accept the warning** about USB debugging
+
+### Step 3: Connect Device
+
+1. **Connect your device** to your computer via USB cable
+2. **On your device**, you may see a prompt: "Allow USB debugging?"
+3. **Check "Always allow from this computer"** (optional but recommended)
+4. **Tap "Allow"**
+
+### Step 4: Verify Device Connection
+
+
+
+
+```bash
+adb devices
+```
+
+
+
+
+```powershell
+adb devices
+```
+
+
+
+
+**Expected output:**
+```
+List of devices attached
+ABC123XYZ456 device
+```
+
+If you see "unauthorized", check your device and accept the USB debugging prompt.
+
+### Step 5: Install Formulus APK
+
+#### Option A: Install from Local APK File
+
+
+
+
+```bash
+# Navigate to directory containing APK
+cd /path/to/formulus/android/app/build/outputs/apk/debug
+
+# Install APK
+adb install app-debug.apk
+```
+
+
+
+
+```powershell
+# Navigate to directory containing APK
+cd C:\path\to\formulus\android\app\build\outputs\apk\debug
+
+# Install APK
+adb install app-debug.apk
+```
+
+
+
+
+#### Option B: Install from Remote URL
+
+
+
+
+```bash
+# Download and install in one command
+curl -L https://github.com/OpenDataEnsemble/ode/releases/download/v1.0.0/formulus.apk -o /tmp/formulus.apk
+adb install /tmp/formulus.apk
+```
+
+
+
+
+```powershell
+# Download and install
+Invoke-WebRequest -Uri "https://github.com/OpenDataEnsemble/ode/releases/download/v1.0.0/formulus.apk" -OutFile "$env:TEMP\formulus.apk"
+adb install "$env:TEMP\formulus.apk"
+```
+
+
+
+
+### Step 6: Verify Installation
+
+
+
+
+```bash
+# Check if app is installed
+adb shell pm list packages | grep formulus
+
+# Launch the app
+adb shell am start -n com.opendataensemble.formulus/.MainActivity
+```
+
+
+
+
+```powershell
+# Check if app is installed
+adb shell pm list packages | Select-String formulus
+
+# Launch the app
+adb shell am start -n com.opendataensemble.formulus/.MainActivity
+```
+
+
+
+
+## Method 2: Android Emulator Installation
+
+### Step 1: Set Up Android Emulator
+
+#### Using Android Studio
+
+1. **Install Android Studio** from [developer.android.com](https://developer.android.com/studio)
+2. **Open Android Studio** → **Tools** → **Device Manager**
+3. **Create Virtual Device** → Select a device (e.g., Pixel 5)
+4. **Select System Image** (e.g., Android 11, API 30)
+5. **Finish** and start the emulator
+
+#### Using Command Line (Linux/macOS)
+
+```bash
+# Install emulator via SDK Manager
+sdkmanager "emulator" "platform-tools" "platforms;android-30"
+
+# List available system images
+sdkmanager --list | grep system-images
+
+# Create AVD (Android Virtual Device)
+avdmanager create avd -n formulus_emulator -k "system-images;android-30;google_apis;x86_64"
+
+# Start emulator
+emulator -avd formulus_emulator &
+```
+
+### Step 2: Verify Emulator Connection
+
+
+
+
+```bash
+# Wait for emulator to boot (may take 1-2 minutes)
+adb devices
+
+# Should show emulator
+List of devices attached
+emulator-5554 device
+```
+
+
+
+
+```powershell
+adb devices
+```
+
+
+
+
+### Step 3: Install Formulus on Emulator
+
+
+
+
+```bash
+# Build APK first (if not already built)
+cd formulus
+npm run android
+
+# Install on emulator
+adb -s emulator-5554 install android/app/build/outputs/apk/debug/app-debug.apk
+```
+
+
+
+
+```powershell
+# Build APK first
+cd formulus
+npm run android
+
+# Install on emulator
+adb -s emulator-5554 install android\app\build\outputs\apk\debug\app-debug.apk
+```
+
+
+
+
+### Step 4: Important Notes for Emulator
+
+When configuring Formulus on an emulator to connect to a local server:
+
+- **Use `10.0.2.2` instead of `localhost`** - This is the special IP that the emulator uses to access the host machine
+- **Example server URL**: `http://10.0.2.2:8080`
+- **For network servers**: Use the actual IP address or domain name
+
+## Method 3: Development Build with Hot Reload
+
+### Prerequisites
+
+- **Node.js** 18+ and npm
+- **React Native CLI** or **Expo CLI**
+- **Java Development Kit (JDK)** 11 or higher
+- **Android Studio** with Android SDK
+
+### Step 1: Install Dependencies
+
+
+
+
+```bash
+cd formulus
+npm install
+```
+
+
+
+
+### Step 2: Start Metro Bundler
+
+
+
+
+```bash
+# In formulus directory
+npm start
+```
+
+Keep this terminal open. Metro is the JavaScript bundler for React Native.
+
+
+
+
+### Step 3: Build and Run on Device/Emulator
+
+
+
+
+```bash
+# For Android device (connected via USB)
+npm run android
+
+# For Android emulator (must be running)
+npm run android
+```
+
+
+
+
+This command will:
+1. Build the Android app
+2. Install it on your device/emulator
+3. Start the app
+4. Connect to Metro bundler for hot reload
+
+### Step 4: Development Features
+
+With development build, you get:
+
+- **Hot Reload** - Changes reflect immediately
+- **Fast Refresh** - React components update without losing state
+- **Debug Menu** - Shake device or press `Ctrl+M` (Windows/Linux) or `Cmd+M` (macOS)
+- **React Native Debugger** - Debug JavaScript code in Chrome DevTools
+
+## Common ADB Commands
+
+### Useful Commands for Development
+
+**List connected devices:**
+```bash
+adb devices
+```
+
+**Install APK:**
+```bash
+adb install path/to/app.apk
+```
+
+**Uninstall app:**
+```bash
+adb uninstall com.opendataensemble.formulus
+```
+
+**Reinstall app (uninstall + install):**
+```bash
+adb install -r path/to/app.apk
+```
+
+**View app logs:**
+```bash
+# All logs
+adb logcat
+
+# Filter for Formulus only
+adb logcat | grep -i formulus
+
+# Clear logs
+adb logcat -c
+```
+
+**Pull file from device:**
+```bash
+adb pull /path/on/device /path/on/computer
+```
+
+**Push file to device:**
+```bash
+adb push /path/on/computer /path/on/device
+```
+
+**Open app:**
+```bash
+adb shell am start -n com.opendataensemble.formulus/.MainActivity
+```
+
+**Stop app:**
+```bash
+adb shell am force-stop com.opendataensemble.formulus
+```
+
+**Clear app data:**
+```bash
+adb shell pm clear com.opendataensemble.formulus
+```
+
+## Troubleshooting
+
+### Device Not Detected
+
+**Problem**: `adb devices` shows no devices.
+
+**Solutions**:
+- Check USB cable connection
+- Try a different USB port
+- Install device-specific USB drivers (Windows)
+- Enable USB debugging on device
+- Accept USB debugging prompt on device
+- Restart ADB server: `adb kill-server && adb start-server`
+
+### Installation Fails
+
+**Problem**: `adb install` fails with error.
+
+**Solutions**:
+- Uninstall existing version first: `adb uninstall com.opendataensemble.formulus`
+- Use `-r` flag to reinstall: `adb install -r app.apk`
+- Check device has enough storage
+- Verify APK is not corrupted
+- Check device is in file transfer mode (not charging only)
+
+### Emulator Connection Issues
+
+**Problem**: Cannot connect to local server from emulator.
+
+**Solutions**:
+- Use `10.0.2.2` instead of `localhost` for server URL
+- Check firewall isn't blocking connections
+- Verify server is running and accessible
+- Use actual IP address instead of localhost
+
+### Permission Denied Errors
+
+**Problem**: ADB commands fail with permission errors.
+
+
+
+
+```bash
+# Add user to plugdev group
+sudo usermod -a -G plugdev $USER
+
+# Create udev rules
+sudo nano /etc/udev/rules.d/51-android.rules
+# Add: SUBSYSTEM=="usb", ATTR{idVendor}=="####", MODE="0664", GROUP="plugdev"
+
+# Reload udev rules
+sudo udevadm control --reload-rules
+sudo udevadm trigger
+
+# Log out and log back in
+```
+
+
+
+
+macOS typically doesn't require special permissions for ADB. If you encounter permission issues:
+
+1. Check USB cable connection
+2. Try a different USB port
+3. Restart ADB: `adb kill-server && adb start-server`
+4. Check System Preferences → Security & Privacy for blocked apps
+
+
+
+
+Windows typically handles USB device permissions automatically. If you encounter issues:
+
+1. Install device-specific USB drivers from manufacturer
+2. Check Device Manager for unrecognized devices
+3. Try different USB port or cable
+4. Restart ADB: `adb kill-server && adb start-server`
+
+
+
+
+## Related Documentation
+
+- [Formulus Development Setup](/development/formulus-development) - Complete development environment setup
+- [Formulus Component Reference](/reference/formulus) - Detailed component documentation
+- [Building and Testing](/development/building-testing) - Build and test procedures
+
diff --git a/versioned_docs/version-1.0/development/setup.md b/versioned_docs/version-1.0/development/setup.md
new file mode 100644
index 0000000..1a7c1fc
--- /dev/null
+++ b/versioned_docs/version-1.0/development/setup.md
@@ -0,0 +1,306 @@
+---
+sidebar_position: 1
+---
+
+# Development Setup
+
+Complete guide to setting up a development environment for ODE.
+
+## Prerequisites
+
+Before setting up the development environment, ensure you have:
+
+- **Node.js** 18.0 or higher
+- **npm** 9.0 or higher
+- **Go** 1.22 or higher (for server and CLI development)
+- **PostgreSQL** 13.0 or higher (for server development)
+- **Git** for version control
+- **Docker** and **Docker Compose** (optional, for containerized development)
+
+## Repository Structure
+
+ODE is a monorepo containing multiple components:
+
+```
+ode/
+├── formulus/ # React Native mobile app
+├── formulus-formplayer/ # React web form renderer
+├── synkronus/ # Go backend server
+├── synkronus-cli/ # Go command-line utility
+├── synkronus-portal/ # React web portal
+└── packages/
+ └── tokens/ # Design tokens package
+```
+
+## Clone the Repository
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode
+```
+
+## Formulus Development
+
+### Setup
+
+```bash
+cd formulus
+npm install
+```
+
+### Running
+
+```bash
+# Start Metro bundler
+npm start
+
+# Run on Android
+npm run android
+
+# Run on iOS (macOS only)
+npm run ios
+```
+
+### Code Quality
+
+ODE enforces consistent formatting and linting:
+
+```bash
+# Run linting
+npm run lint
+
+# Run linting with auto-fix
+npm run lint:fix
+
+# Format code
+npm run format
+
+# Check formatting (no writes)
+npm run format:check
+```
+
+### Generating Files
+
+```bash
+# Generate WebView injection script
+npm run generate
+
+# Generate API client from OpenAPI spec
+npm run generate:api
+```
+
+## Formplayer Development
+
+### Setup
+
+```bash
+cd formulus-formplayer
+npm install
+```
+
+### Running
+
+```bash
+# Development server
+npm start
+
+# Build for React Native
+npm run build:rn
+```
+
+### Code Quality
+
+```bash
+# Run linting
+npm run lint
+
+# Run linting with auto-fix
+npm run lint:fix
+
+# Format code
+npm run format
+
+# Check formatting (no writes)
+npm run format:check
+```
+
+## Synkronus Development
+
+### Setup
+
+```bash
+cd synkronus
+go mod download
+```
+
+### Configuration
+
+Create a `.env` file:
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-for-development
+LOG_LEVEL=debug
+APP_BUNDLE_PATH=./data/app-bundles
+```
+
+### Running
+
+```bash
+# Build
+go build -o bin/synkronus cmd/synkronus/main.go
+
+# Run
+./bin/synkronus
+
+# Or run directly
+go run cmd/synkronus/main.go
+```
+
+### Database Setup
+
+Ensure PostgreSQL is running and create a database:
+
+```sql
+CREATE DATABASE synkronus;
+```
+
+The schema will be created automatically on first run.
+
+## Synkronus CLI Development
+
+### Setup
+
+```bash
+cd synkronus-cli
+go mod download
+```
+
+### Building
+
+```bash
+# Build
+go build -o bin/synk ./cmd/synkronus
+
+# Run
+./bin/synk
+```
+
+## Development Workflow
+
+### 1. Create a Feature Branch
+
+```bash
+git checkout -b feature/your-feature-name
+```
+
+### 2. Make Changes
+
+Make your code changes following the coding standards.
+
+### 3. Test Locally
+
+```bash
+# Run tests
+npm test # For frontend projects
+go test ./... # For Go projects
+
+# Check code quality
+npm run lint
+npm run format:check
+```
+
+### 4. Commit Changes
+
+```bash
+git add .
+git commit -m "Description of changes"
+```
+
+### 5. Push and Create Pull Request
+
+```bash
+git push origin feature/your-feature-name
+```
+
+Create a pull request on GitHub.
+
+## Code Quality Standards
+
+### Frontend (React/React Native)
+
+- **Linting**: ESLint with project-specific rules
+- **Formatting**: Prettier with consistent configuration
+- **TypeScript**: Strict type checking enabled
+- **Testing**: Jest for unit tests
+
+### Backend (Go)
+
+- **Formatting**: `gofmt` or `goimports`
+- **Linting**: `golangci-lint` (if configured)
+- **Testing**: Standard Go testing package
+- **Documentation**: Godoc comments for exported functions
+
+### CI/CD
+
+The CI pipeline automatically:
+
+- Runs linting and formatting checks
+- Runs tests
+- Builds components
+- Publishes Docker images (for synkronus)
+
+## Development Tools
+
+### Recommended IDE Setup
+
+- **VS Code**: With extensions for TypeScript, Go, and React
+- **IntelliJ IDEA**: With Go and JavaScript plugins
+- **Android Studio**: For Android development
+- **Xcode**: For iOS development (macOS only)
+
+### Useful Commands
+
+```bash
+# Check all components
+cd formulus && npm run lint && cd ..
+cd formulus-formplayer && npm run lint && cd ..
+cd synkronus && go test ./... && cd ..
+
+# Format all code
+cd formulus && npm run format && cd ..
+cd formulus-formplayer && npm run format && cd ..
+cd synkronus && go fmt ./... && cd ..
+```
+
+## Troubleshooting
+
+### Node Modules Issues
+
+```bash
+# Clear and reinstall
+rm -rf node_modules package-lock.json
+npm install
+```
+
+### Go Module Issues
+
+```bash
+# Clean module cache
+go clean -modcache
+go mod download
+```
+
+### Database Connection Issues
+
+- Verify PostgreSQL is running
+- Check connection string format
+- Ensure database exists
+- Verify user permissions
+
+## Related Documentation
+
+- [Architecture Overview](/development/architecture)
+- [Contributing Guide](/development/contributing)
+- [Building & Testing](/development/building-testing)
diff --git a/versioned_docs/version-1.0/development/synkronus-development.md b/versioned_docs/version-1.0/development/synkronus-development.md
new file mode 100644
index 0000000..ce542d4
--- /dev/null
+++ b/versioned_docs/version-1.0/development/synkronus-development.md
@@ -0,0 +1,183 @@
+---
+sidebar_position: 5
+---
+
+# Synkronus Server Development
+
+Complete guide for developing the Synkronus server component.
+
+## Prerequisites
+
+- **Go** 1.22+
+- **PostgreSQL** 12+
+- **Git**
+
+## Local Development Setup
+
+### Step 1: Clone Repository
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+```
+
+### Step 2: Install Dependencies
+
+```bash
+go mod download
+```
+
+### Step 3: Set Up Database
+
+
+
+
+```bash
+# Create database
+createdb synkronus
+
+# Or using psql
+psql -U postgres -c "CREATE DATABASE synkronus;"
+```
+
+
+
+
+Using PowerShell or Command Prompt:
+
+```powershell
+# Using psql
+psql -U postgres -c "CREATE DATABASE synkronus;"
+```
+
+Or using Git Bash/WSL:
+
+```bash
+# Create database
+createdb synkronus
+
+# Or using psql
+psql -U postgres -c "CREATE DATABASE synkronus;"
+```
+
+
+
+
+### Step 4: Configure Environment
+
+Create `.env` file:
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://user:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=dev-secret-change-in-production
+LOG_LEVEL=debug
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+ADMIN_USERNAME=admin
+ADMIN_PASSWORD=admin
+```
+
+### Step 5: Create Directories
+
+```bash
+mkdir -p data/app-bundles
+```
+
+### Step 6: Run Server
+
+```bash
+go run cmd/synkronus/main.go
+```
+
+Or build and run:
+
+```bash
+go build -o bin/synkronus cmd/synkronus/main.go
+./bin/synkronus
+```
+
+## Development Workflow
+
+### Hot Reload
+
+Use tools like `air` for hot reload:
+
+```bash
+go install github.com/cosmtrek/air@latest
+air
+```
+
+### Testing
+
+```bash
+go test ./...
+```
+
+### API Documentation
+
+View OpenAPI docs:
+
+```bash
+# Server must be running
+open http://localhost:8080/openapi/swagger-ui.html
+```
+
+## Building for Production
+
+### Build Binary
+
+```bash
+go build -o bin/synkronus cmd/synkronus/main.go
+```
+
+### Cross-Platform Builds
+
+
+
+
+```bash
+GOOS=linux GOARCH=amd64 go build -o bin/synkronus-linux cmd/synkronus/main.go
+```
+
+
+
+
+```powershell
+$env:GOOS="windows"; $env:GOARCH="amd64"; go build -o bin/synkronus.exe cmd/synkronus/main.go
+```
+
+Or using bash (Git Bash/WSL):
+
+```bash
+GOOS=windows GOARCH=amd64 go build -o bin/synkronus.exe cmd/synkronus/main.go
+```
+
+
+
+
+```bash
+GOOS=darwin GOARCH=amd64 go build -o bin/synkronus-macos cmd/synkronus/main.go
+```
+
+
+
+
+## Docker Development
+
+### Using Docker Compose
+
+```bash
+docker compose up -d
+```
+
+### Development with Hot Reload
+
+Mount source code for live updates.
+
+## Related Documentation
+
+- [Synkronus Server Reference](/reference/synkronus-server) - Component reference
+- [Deployment Guide](/guides/deployment) - Production deployment
+- [Configuration Guide](/guides/configuration) - Configuration options
+
diff --git a/versioned_docs/version-1.0/development/synkronus-portal-development.md b/versioned_docs/version-1.0/development/synkronus-portal-development.md
new file mode 100644
index 0000000..fbfe969
--- /dev/null
+++ b/versioned_docs/version-1.0/development/synkronus-portal-development.md
@@ -0,0 +1,100 @@
+---
+sidebar_position: 6
+---
+
+# Synkronus Portal Development
+
+Complete guide for developing the Synkronus Portal web interface.
+
+## Prerequisites
+
+- **Node.js** 20+ and npm
+- **Go** 1.22+ (for backend)
+- **PostgreSQL** 17+ (for backend)
+
+## Local Development Setup
+
+
+
+
+#### Step 1: Set Up Backend
+
+See [Synkronus Development](/development/synkronus-development) for backend setup.
+
+#### Step 2: Set Up Frontend
+
+```bash
+cd synkronus-portal
+npm install
+```
+
+#### Step 3: Start Development Server
+
+```bash
+npm run dev
+```
+
+Portal available at http://localhost:5174
+
+
+
+
+#### Start Backend Services
+
+```bash
+docker compose up -d postgres synkronus
+```
+
+#### Start Frontend
+
+```bash
+cd synkronus-portal
+npm install
+npm run dev
+```
+
+Portal available at http://localhost:5174
+
+
+
+
+## Development Features
+
+- **Hot Module Replacement**: Instant code updates
+- **Fast Refresh**: React components update without losing state
+- **Source Maps**: Debug in browser DevTools
+- **Error Overlay**: Errors shown in browser
+
+## Building for Production
+
+### Build
+
+```bash
+npm run build
+```
+
+Output in `dist/` directory.
+
+### Docker Production Build
+
+```bash
+docker compose up -d --build
+```
+
+## Project Structure
+
+- `src/`: React source code
+- `src/components/`: Reusable components
+- `src/pages/`: Page components
+- `src/services/`: API service
+- `src/contexts/`: React contexts
+
+## Adding Features
+
+See [Synkronus Portal Reference](/reference/synkronus-portal) for detailed patterns.
+
+## Related Documentation
+
+- [Synkronus Portal Reference](/reference/synkronus-portal) - Component reference
+- [Deployment Guide](/guides/deployment) - Production deployment
+
diff --git a/docs/documentation/formulus/formulus.md b/versioned_docs/version-1.0/documentation/formulus/formulus.md
similarity index 100%
rename from docs/documentation/formulus/formulus.md
rename to versioned_docs/version-1.0/documentation/formulus/formulus.md
diff --git a/docs/documentation/synkronus-cli/cli.md b/versioned_docs/version-1.0/documentation/synkronus-cli/cli.md
similarity index 100%
rename from docs/documentation/synkronus-cli/cli.md
rename to versioned_docs/version-1.0/documentation/synkronus-cli/cli.md
diff --git a/docs/documentation/synkronus/_category_.json b/versioned_docs/version-1.0/documentation/synkronus/_category_.json
similarity index 100%
rename from docs/documentation/synkronus/_category_.json
rename to versioned_docs/version-1.0/documentation/synkronus/_category_.json
diff --git a/docs/documentation/synkronus/app-bundle.md b/versioned_docs/version-1.0/documentation/synkronus/app-bundle.md
similarity index 100%
rename from docs/documentation/synkronus/app-bundle.md
rename to versioned_docs/version-1.0/documentation/synkronus/app-bundle.md
diff --git a/docs/documentation/synkronus/synkronus.md b/versioned_docs/version-1.0/documentation/synkronus/synkronus.md
similarity index 100%
rename from docs/documentation/synkronus/synkronus.md
rename to versioned_docs/version-1.0/documentation/synkronus/synkronus.md
diff --git a/versioned_docs/version-1.0/getting-started/.gitkeep b/versioned_docs/version-1.0/getting-started/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/versioned_docs/version-1.0/getting-started/faq.md b/versioned_docs/version-1.0/getting-started/faq.md
new file mode 100644
index 0000000..36a25c1
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/faq.md
@@ -0,0 +1,110 @@
+---
+sidebar_position: 5
+---
+
+# Frequently Asked Questions
+
+Common questions about ODE installation, usage, and development.
+
+## General Questions
+
+### What is ODE?
+
+Open Data Ensemble (ODE) is a platform for mobile data collection and synchronization. It provides tools for creating forms, collecting data offline, and synchronizing data across devices and servers.
+
+### Is ODE free to use?
+
+Yes, ODE is open source and free to use. The code is available under the MIT license.
+
+### What platforms does ODE support?
+
+ODE supports Android and iOS mobile devices. The server component runs on Linux, macOS, and Windows.
+
+### Do I need internet connectivity to use ODE?
+
+No, ODE is designed to work offline. Data is stored locally and synchronized when connectivity is available.
+
+## Installation Questions
+
+### What are the system requirements?
+
+See the [Prerequisites](/getting-started/installation/prerequisites) page for detailed system requirements.
+
+### Can I run ODE in the cloud?
+
+Yes, ODE can be deployed to cloud platforms such as AWS, Google Cloud, or Azure. See the [Deployment guide](/guides/deployment/production) for details.
+
+### Do I need a database?
+
+Yes, ODE requires PostgreSQL for data storage. The database schema is created automatically on first run.
+
+## Usage Questions
+
+### How do I create forms?
+
+Forms are defined using JSON schema. See the [Form Design guide](/guides/forms/overview) for details.
+
+### Can I customize the user interface?
+
+Yes, ODE supports custom applications and renderers. See [Custom Applications](/guides/custom-apps/overview) for details.
+
+### How does synchronization work?
+
+ODE uses a bidirectional sync protocol that pushes local data to the server and pulls new data from the server. See [Synchronization](/using/synchronization) for details.
+
+### What happens if two devices modify the same data?
+
+ODE automatically resolves conflicts using a version-based approach. The most recent version takes precedence.
+
+## Development Questions
+
+### How do I contribute to ODE?
+
+See the [Contributing guide](/development/contributing/guide) for information on how to contribute.
+
+### Can I extend ODE functionality?
+
+Yes, ODE is designed to be extensible. See [Extending ODE](/development/extending/overview) for details.
+
+### What programming languages are used?
+
+ODE uses React Native for mobile apps, React for web components, and Go for the server.
+
+## Troubleshooting
+
+### The app won't connect to the server
+
+- Verify the server is running and accessible
+- Check the server URL in app settings
+- Verify firewall and network settings
+- For Android emulator, use `10.0.2.2` instead of `localhost`
+
+### Forms are not appearing
+
+- Verify forms were uploaded to the server
+- Check that the app has synchronized
+- Review server logs for errors
+
+### Data is not synchronizing
+
+- Check network connectivity
+- Verify authentication credentials
+- Review server logs for sync errors
+- Ensure observations were saved locally
+
+### Build errors
+
+- Ensure all prerequisites are installed
+- Check that dependencies are up to date
+- Review error messages for specific issues
+- See component-specific documentation for build instructions
+
+## Getting Help
+
+If you cannot find an answer to your question:
+
+- Check the [Troubleshooting guide](/using/troubleshooting)
+- Review the [API Reference](/reference/api/overview)
+- Search [GitHub Issues](https://github.com/OpenDataEnsemble/ode/issues)
+- Ask questions in the [Community section](/community/getting-help)
+
diff --git a/versioned_docs/version-1.0/getting-started/index.md b/versioned_docs/version-1.0/getting-started/index.md
new file mode 100644
index 0000000..329389c
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/index.md
@@ -0,0 +1,85 @@
+---
+sidebar_position: 0
+---
+
+# Getting Started
+
+Welcome to ODE! This section will help you understand what ODE is, why you should use it, and how to get up and running quickly.
+
+## What You'll Learn
+
+Whether you're a researcher, developer, or data practitioner, these guides will help you get started with ODE and start collecting data efficiently.
+
+
+
+
+
+
What is ODE?
+
+
+
Learn about the Open Data Ensemble platform and its architecture.
+
+## Next Steps
+
+Once you've completed the getting started guides, explore the [Using ODE](/docs/using/your-first-form) section to learn how to create forms and manage data.
+
diff --git a/versioned_docs/version-1.0/getting-started/installation.md b/versioned_docs/version-1.0/getting-started/installation.md
new file mode 100644
index 0000000..197d762
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/installation.md
@@ -0,0 +1,420 @@
+---
+sidebar_position: 4
+---
+
+# Installation
+
+Complete installation guide for all ODE components. This guide covers prerequisites, server setup, and mobile app installation.
+
+## Prerequisites
+
+Before installing ODE components, ensure your system meets the following requirements.
+
+### System Requirements
+
+#### For Mobile Development (Formulus)
+
+| Requirement | Minimum | Recommended |
+|-------------|---------|-------------|
+| **Operating System** | macOS 10.15, Windows 10, or Linux | Latest stable version |
+| **Node.js** | 18.0 or higher | 20.0 or higher |
+| **npm** | 9.0 or higher | 10.0 or higher |
+| **Android Studio** | Latest stable | Latest stable |
+| **Xcode** | 14.0 or higher (macOS only) | Latest stable |
+| **Java Development Kit** | JDK 17 | JDK 17 or higher |
+
+#### For Server Deployment (Synkronus)
+
+| Requirement | Minimum | Recommended |
+|-------------|---------|-------------|
+| **Operating System** | Linux, macOS, or Windows | Linux |
+| **Go** | 1.22 or higher | Latest stable |
+| **PostgreSQL** | 13.0 or higher | 15.0 or higher |
+| **Docker** | 20.10 or higher (optional) | Latest stable |
+| **Memory** | 2 GB RAM | 4 GB RAM or more |
+| **Storage** | 10 GB free space | 50 GB or more |
+
+### Development Tools
+
+**Required Tools:**
+- Git: Version control system
+- Code Editor: Visual Studio Code, IntelliJ IDEA, or similar
+- Terminal: Command-line interface for running commands
+
+**Recommended Tools:**
+- Postman or curl: For testing API endpoints
+- pgAdmin or DBeaver: For database management
+- Docker Desktop: For containerized development
+
+### Verification
+
+Verify your installation by running:
+
+
+
+
+```bash
+# Check Node.js version
+node --version
+
+# Check npm version
+npm --version
+
+# Check Go version
+go version
+
+# Check PostgreSQL version
+psql --version
+
+# Check Docker version (if using)
+docker --version
+```
+
+
+
+
+Using PowerShell:
+
+```powershell
+# Check Node.js version
+node --version
+
+# Check npm version
+npm --version
+
+# Check Go version
+go version
+
+# Check PostgreSQL version
+psql --version
+
+# Check Docker version (if using)
+docker --version
+```
+
+Or using Git Bash/WSL (same commands as Linux/macOS):
+
+```bash
+node --version
+npm --version
+go version
+psql --version
+docker --version
+```
+
+
+
+
+## Installing Synkronus Server
+
+Synkronus is the backend server component of ODE, responsible for data synchronization, storage, and API services.
+
+
+
+
+The easiest way to run Synkronus is using Docker:
+
+```bash
+# Pull the latest image
+docker pull ghcr.io/opendataensemble/synkronus:latest
+
+# Run the container
+docker run -d \
+ --name synkronus \
+ -p 8080:8080 \
+ -e DB_CONNECTION="postgres://user:password@host:5432/synkronus" \
+ -e JWT_SECRET="your-secret-key-here" \
+ -v synkronus-bundles:/app/data/app-bundles \
+ ghcr.io/opendataensemble/synkronus:latest
+```
+
+
+
+
+For a complete setup with PostgreSQL:
+
+```bash
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Copy the example configuration
+cp docker-compose.example.yml docker-compose.yml
+
+# Edit docker-compose.yml with your configuration
+# Then start the services
+docker compose up -d
+```
+
+
+
+
+Build and run Synkronus from source:
+
+
+
+
+```bash
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Build the application
+go build -o bin/synkronus cmd/synkronus/main.go
+
+# Run the application
+./bin/synkronus
+```
+
+
+
+
+Using PowerShell:
+
+```powershell
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Build the application
+go build -o bin/synkronus.exe cmd/synkronus/main.go
+
+# Run the application
+.\bin\synkronus.exe
+```
+
+Or using Git Bash/WSL (same as Linux/macOS):
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+go build -o bin/synkronus cmd/synkronus/main.go
+./bin/synkronus
+```
+
+
+
+
+
+
+
+### Configuration
+
+Synkronus is configured using environment variables. Create a `.env` file or set environment variables:
+
+| Variable | Description | Default | Required |
+|----------|-------------|---------|----------|
+| `PORT` | HTTP server port | `8080` | No |
+| `DB_CONNECTION` | PostgreSQL connection string | - | Yes |
+| `JWT_SECRET` | Secret key for JWT signing | - | Yes |
+| `LOG_LEVEL` | Logging level (debug, info, warn, error) | `info` | No |
+| `APP_BUNDLE_PATH` | Directory for app bundles | `./data/app-bundles` | No |
+| `MAX_VERSIONS_KEPT` | Maximum app bundle versions to keep | `5` | No |
+
+**Example Configuration:**
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=info
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+```
+
+### Database Setup
+
+Before running Synkronus, set up a PostgreSQL database:
+
+
+
+
+```bash
+# Connect to PostgreSQL
+psql -U postgres
+```
+
+Then run SQL commands:
+
+```sql
+-- Create database
+CREATE DATABASE synkronus;
+
+-- Create user (optional)
+CREATE USER synkronus WITH PASSWORD 'your-password';
+GRANT ALL PRIVILEGES ON DATABASE synkronus TO synkronus;
+```
+
+
+
+
+Using PowerShell or Command Prompt:
+
+```powershell
+# Connect to PostgreSQL
+psql -U postgres
+```
+
+Then run SQL commands:
+
+```sql
+-- Create database
+CREATE DATABASE synkronus;
+
+-- Create user (optional)
+CREATE USER synkronus WITH PASSWORD 'your-password';
+GRANT ALL PRIVILEGES ON DATABASE synkronus TO synkronus;
+```
+
+Or using Git Bash/WSL (same as Linux/macOS):
+
+```bash
+psql -U postgres
+```
+
+
+
+
+```bash
+# Connect to PostgreSQL container
+docker compose exec postgres psql -U postgres
+```
+
+Then run SQL commands:
+
+```sql
+CREATE DATABASE synkronus;
+CREATE USER synkronus WITH PASSWORD 'your-password';
+GRANT ALL PRIVILEGES ON DATABASE synkronus TO synkronus;
+```
+
+
+
+
+The database schema will be created automatically on first run.
+
+### Verification
+
+Verify the installation:
+
+1. Check that the server is running:
+ ```bash
+ curl http://localhost:8080/health
+ ```
+
+2. Check the API documentation:
+ ```bash
+ curl http://localhost:8080/api/docs
+ ```
+
+## Installing Formulus App
+
+Formulus is the mobile application component of ODE, available for Android and iOS devices.
+
+For detailed installation instructions, see the [Installing Formulus guide](/getting-started/installing-formulus) which covers:
+
+- F-Droid installation (recommended for end users)
+- Direct APK installation
+- System requirements
+- Post-installation setup
+
+For developers who want to install via ADB or emulator, see the [Development Installation guide](/development/installing-formulus-dev).
+
+### Quick Installation Summary
+
+#### For End Users
+
+1. **F-Droid** (Recommended): Install via F-Droid app store
+2. **Direct APK**: Download and install APK file directly
+
+See [Installing Formulus](/getting-started/installing-formulus) for complete instructions.
+
+#### For Developers
+
+1. **ADB Installation**: Install via Android Debug Bridge
+2. **Emulator**: Run on Android emulator
+3. **Development Build**: Build from source with hot reload
+
+See [Installing Formulus for Development](/development/installing-formulus-dev) for complete instructions.
+
+### App Configuration
+
+After installation, configure the app to connect to your Synkronus server:
+
+1. Open the Formulus app
+2. Navigate to Settings
+3. Enter your server URL (e.g., `https://your-server.com`)
+4. Enter your authentication credentials
+5. Save the configuration
+
+## Installing Synkronus CLI
+
+The Synkronus CLI is a command-line utility for interacting with the Synkronus server.
+
+### Installation
+
+```bash
+go install github.com/OpenDataEnsemble/ode/synkronus-cli/cmd/synkronus@latest
+```
+
+Or build from source:
+
+```bash
+git clone https://github.com/OpenDataEnsemble/ode/synkronus-cli.git
+cd synkronus-cli
+go build -o bin/synk ./cmd/synkronus
+```
+
+### Configuration
+
+By default, the CLI uses a configuration file located at `$HOME/.synkronus.yaml`.
+
+**Example configuration file:**
+
+```yaml
+api:
+ url: http://localhost:8080
+ version: 1.0.0
+```
+
+You can override this per-command with `--config ` or use `synk config use ` to set a persistent default.
+
+## Troubleshooting
+
+### Server Not Accessible
+
+If the mobile app cannot connect to the server:
+
+- Verify the server is running: `curl http://localhost:8080/health`
+- Check firewall settings
+- For Android emulator, use `10.0.2.2` instead of `localhost`
+- For iOS simulator, use `localhost` or your machine's IP address
+
+### Database Connection Issues
+
+**Problem**: Cannot connect to database
+
+**Solution**: Verify the `DB_CONNECTION` string format and ensure PostgreSQL is running and accessible.
+
+### Port Already in Use
+
+**Problem**: Port 8080 is already in use
+
+**Solution**: Change the `PORT` environment variable to use a different port.
+
+### Build Errors
+
+**Problem**: Build fails with errors
+
+**Solution**:
+- Ensure all prerequisites are installed
+- Check that dependencies are up to date
+- Review error messages for specific issues
+- See component-specific documentation for build instructions
+
+## Next Steps
+
+- Follow the [Quick Start guide](/getting-started/quick-start) for a complete setup
+- Learn how to [use the app](/using/your-first-form) for data collection
+- Review the [Deployment guide](/guides/deployment) for production setup
+
diff --git a/versioned_docs/version-1.0/getting-started/installation/.gitkeep b/versioned_docs/version-1.0/getting-started/installation/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/versioned_docs/version-1.0/getting-started/installing-formulus.md b/versioned_docs/version-1.0/getting-started/installing-formulus.md
new file mode 100644
index 0000000..29d0297
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/installing-formulus.md
@@ -0,0 +1,232 @@
+---
+sidebar_position: 4
+---
+
+# Installing Formulus App
+
+Complete guide for installing the Formulus mobile application on Android devices.
+
+## Overview
+
+Formulus is available for Android devices through multiple installation methods. Choose the method that best fits your needs:
+
+- **F-Droid** (Recommended for end users) - Official app store for free and open source Android apps
+- **Direct APK** - Download and install the APK file directly
+- **Development Build** - For developers who want to build from source
+
+## System Requirements
+
+Before installing, ensure your device meets these requirements:
+
+| Requirement | Minimum |
+|-------------|---------|
+| **Android Version** | Android 7.0 (API level 24) or higher |
+| **Storage Space** | 50 MB free space |
+| **Internet Connection** | Required for initial setup and synchronization |
+| **Permissions** | Camera, Storage, Location (for form features) |
+
+## Installation Methods
+
+### Method 1: F-Droid (Recommended)
+
+F-Droid is the recommended installation method for end users. It provides automatic updates and ensures you're installing the official version.
+
+#### Step 1: Install F-Droid
+
+If you don't have F-Droid installed:
+
+1. **Download F-Droid** from [f-droid.org](https://f-droid.org/)
+2. **Enable installation from unknown sources**:
+ - Go to Settings → Security → Unknown Sources
+ - Enable the option for your browser or file manager
+3. **Install F-Droid** by opening the downloaded APK file
+
+#### Step 2: Add Formulus Repository
+
+1. **Open F-Droid** on your device
+2. **Navigate to Settings** → **Repositories**
+3. **Tap the "+" button** to add a new repository
+4. **Enter the Formulus repository URL** (provided by your organization)
+5. **Tap "Add"** to save the repository
+
+#### Step 3: Install Formulus
+
+1. **Open F-Droid** on your device
+2. **Navigate to the Updates tab** or search for "Formulus"
+3. **Find Formulus** in the app list
+4. **Tap on Formulus** to open the app details
+5. **Tap "Install"** to begin installation
+6. **Wait for installation** to complete
+7. **Tap "Open"** to launch the app
+
+#### Automatic Updates
+
+Once installed via F-Droid, Formulus will automatically update when new versions are available:
+
+1. **F-Droid checks for updates** periodically
+2. **Notifications appear** when updates are available
+3. **Tap the notification** or open F-Droid to update
+4. **Updates install automatically** through F-Droid
+
+### Method 2: Direct APK Installation
+
+If F-Droid is not available or you prefer direct installation:
+
+#### Step 1: Download the APK
+
+1. **Download the latest APK** from the [releases page](https://github.com/OpenDataEnsemble/ode/releases)
+2. **Save the file** to your device's Downloads folder
+
+#### Step 2: Enable Unknown Sources
+
+1. **Go to Settings** → **Security** (or **Apps** on newer Android versions)
+2. **Enable "Install unknown apps"** or **"Unknown Sources"**
+3. **Select your browser or file manager** and enable installation
+
+#### Step 3: Install the APK
+
+1. **Open your file manager** or Downloads app
+2. **Navigate to the Downloads folder**
+3. **Tap on the Formulus APK file**
+4. **Review the permissions** requested by the app
+5. **Tap "Install"** to begin installation
+6. **Wait for installation** to complete
+7. **Tap "Open"** to launch the app
+
+### Method 3: Development Build
+
+For developers who want to build and install from source, see the [Development Installation Guide](/development/formulus-development).
+
+## Post-Installation Setup
+
+After installing Formulus, you need to configure it to connect to your Synkronus server:
+
+### Initial Configuration
+
+1. **Open Formulus** on your device
+2. **You'll see the welcome screen** with configuration options
+3. **Choose your configuration method**:
+ - **QR Code Scan** (Recommended) - Scan a QR code with server details
+ - **Manual Entry** - Enter server URL and credentials manually
+
+### QR Code Configuration
+
+1. **Tap "Scan QR Code"** on the welcome screen
+2. **Grant camera permission** if prompted
+3. **Point the camera** at the QR code provided by your administrator
+4. **Settings auto-populate** with server URL, username, and password
+5. **Tap "Connect"** to verify and save the configuration
+
+### Manual Configuration
+
+1. **Tap "Manual Configuration"** on the welcome screen
+2. **Enter Server URL**: `http://your-server-ip:8080` or `https://your-server-domain`
+3. **Enter Username**: Your username provided by your administrator
+4. **Enter Password**: Your password
+5. **Tap "Test Connection"** to verify connectivity
+6. **Tap "Save"** to store the configuration
+
+### First Login
+
+1. **After configuration**, you'll be prompted to log in
+2. **Credentials should be pre-filled** (if using QR code)
+3. **Tap "Login"** to authenticate
+4. **Wait for authentication** - A token is stored locally for future sessions
+5. **You'll be redirected** to the main app interface
+
+## Verification
+
+To verify that Formulus is installed correctly:
+
+1. **Check app icon** appears in your app drawer
+2. **Open the app** and verify it launches without errors
+3. **Check Settings** to confirm server configuration is saved
+4. **Test connection** by tapping "Test Connection" in Settings
+5. **Verify login** by logging in with your credentials
+
+## Troubleshooting Installation
+
+### Installation Fails
+
+**Problem**: APK installation fails with "App not installed" error.
+
+**Solutions**:
+- Ensure you have enough storage space (at least 50 MB free)
+- Check that "Unknown Sources" is enabled for your file manager
+- Try downloading the APK again (file may be corrupted)
+- Ensure your device meets minimum Android version requirements (7.0+)
+
+### App Crashes on Launch
+
+**Problem**: Formulus crashes immediately after opening.
+
+**Solutions**:
+- Restart your device
+- Clear app data: Settings → Apps → Formulus → Storage → Clear Data
+- Uninstall and reinstall the app
+- Check that your device has sufficient RAM available
+
+### Cannot Connect to Server
+
+**Problem**: App cannot connect to the Synkronus server.
+
+**Solutions**:
+- Verify server URL is correct (check for typos)
+- Ensure device has internet connection
+- Check that server is running and accessible
+- Verify firewall settings aren't blocking the connection
+- For local development, use `10.0.2.2` instead of `localhost` on Android emulator
+
+### F-Droid Not Finding Updates
+
+**Problem**: F-Droid doesn't show Formulus updates.
+
+**Solutions**:
+- Ensure the Formulus repository is added correctly
+- Refresh F-Droid repositories: Settings → Repositories → Tap refresh
+- Check that F-Droid has internet connection
+- Verify repository URL is correct and accessible
+
+## Updating Formulus
+
+### Via F-Droid
+
+Updates are automatic when using F-Droid:
+
+1. **F-Droid checks for updates** automatically
+2. **Notification appears** when updates are available
+3. **Open F-Droid** and navigate to Updates tab
+4. **Tap "Update"** next to Formulus
+5. **Wait for download and installation**
+
+### Via Direct APK
+
+1. **Download the latest APK** from the releases page
+2. **Install over existing installation** (no need to uninstall)
+3. **App data is preserved** during update
+
+## Uninstalling Formulus
+
+To uninstall Formulus:
+
+1. **Go to Settings** → **Apps** (or **Application Manager**)
+2. **Find Formulus** in the app list
+3. **Tap on Formulus**
+4. **Tap "Uninstall"**
+5. **Confirm uninstallation**
+
+**Note**: Uninstalling will remove all local data, including:
+- Saved observations (not yet synced)
+- App configuration
+- Cached app bundles
+- Local database
+
+**Important**: Ensure all data is synced to the server before uninstalling.
+
+## Related Documentation
+
+- [Formulus Features](/using/formulus-features) - Learn about app features and usage
+- [Your First Form](/using/your-first-form) - Get started with data collection
+- [Synchronization](/using/synchronization) - Understand how data syncs work
+- [Development Installation](/development/formulus-development) - For developers building from source
+
diff --git a/versioned_docs/version-1.0/getting-started/key-concepts.md b/versioned_docs/version-1.0/getting-started/key-concepts.md
new file mode 100644
index 0000000..4a96564
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/key-concepts.md
@@ -0,0 +1,102 @@
+---
+sidebar_position: 3
+---
+
+# Key Concepts
+
+Understanding these core concepts will help you work effectively with ODE.
+
+## Core Concepts
+
+### Forms
+
+Forms are the primary mechanism for data collection in ODE. A form consists of:
+
+- **Schema**: Defines the data structure and validation rules
+- **UI Schema**: Defines how the form is presented to users
+- **Question Types**: Define the input methods available (text, number, date, etc.)
+
+Forms are defined using JSON and follow the JSON Forms specification. See the [Form Design guide](/guides/forms/overview) for details.
+
+### Observations
+
+An observation is a single data record collected through a form. Each observation contains:
+
+- A unique identifier
+- The form type used to collect it
+- The data values entered by the user
+- Metadata such as creation time and last modification time
+- A sync status indicating whether it has been synchronized with the server
+
+### Synchronization
+
+Synchronization is the process of exchanging data between mobile devices and the server. ODE uses a bidirectional sync protocol that:
+
+- Pushes local observations to the server
+- Pulls new or updated observations from the server
+- Resolves conflicts when the same observation is modified on multiple devices
+- Handles attachments separately from observation metadata
+
+See [Synchronization](/using/synchronization) for more details.
+
+### App Bundles
+
+An app bundle is a collection of resources that define a custom application. It includes:
+
+- Custom HTML, CSS, and JavaScript files
+- Form specifications
+- Custom renderers for question types
+- Configuration files
+
+App bundles are uploaded to the server and downloaded by mobile devices during synchronization. See [Custom Applications](/guides/custom-apps/overview) for details.
+
+### Custom Applications
+
+Custom applications are web-based interfaces that run within the Formulus mobile app. They provide:
+
+- Custom navigation and user interfaces
+- Integration with the ODE form system
+- Access to observation data through the Formulus JavaScript interface
+
+Custom applications are defined in app bundles and can be tailored to specific use cases.
+
+## Data Flow
+
+The following diagram illustrates how data flows through the ODE system:
+
+```
+User Input → Form → Observation (Local) → Sync → Server → Database
+ ↓
+ Sync → Other Devices
+```
+
+1. User fills out a form on a mobile device
+2. An observation is created and stored locally
+3. When connectivity is available, the observation is synchronized to the server
+4. The server stores the observation in the database
+5. Other devices can pull the observation during their sync operations
+
+## Terminology
+
+| Term | Definition |
+|------|------------|
+| **Form** | A data collection interface defined by schema and UI schema |
+| **Observation** | A single data record collected through a form |
+| **Schema** | JSON schema defining the structure and validation rules for a form |
+| **UI Schema** | JSON schema defining the presentation of form fields |
+| **Question Type** | A component that handles a specific type of input (text, number, etc.) |
+| **Renderer** | A component that renders a question type in the form |
+| **Sync** | The process of exchanging data between devices and server |
+| **App Bundle** | A collection of resources defining a custom application |
+| **Custom App** | A web-based application that runs within Formulus |
+| **Formulus** | The mobile application component of ODE |
+| **Synkronus** | The server component of ODE |
+| **Formplayer** | The web-based form rendering component |
+
+## Related Documentation
+
+- [Form Design Guide](/guides/forms/overview)
+- [Synchronization Details](/using/synchronization)
+- [Custom Applications](/guides/custom-apps/overview)
+- [Architecture Overview](/development/architecture/overview)
+
diff --git a/versioned_docs/version-1.0/getting-started/quick-start.md b/versioned_docs/version-1.0/getting-started/quick-start.md
new file mode 100644
index 0000000..ede1381
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/quick-start.md
@@ -0,0 +1,195 @@
+---
+sidebar_position: 5
+---
+
+# Quick Start
+
+Get up and running with ODE in approximately 15 minutes.
+
+## Overview
+
+This guide walks you through setting up a complete ODE environment and creating your first form.
+
+## Step 1: Start Synkronus Server
+
+Using Docker Compose is the fastest method:
+
+```bash
+# Clone the repository
+git clone https://github.com/OpenDataEnsemble/ode.git
+cd ode/synkronus
+
+# Start the server with Docker Compose
+docker compose up -d
+```
+
+The server will be available at `http://localhost:8080`.
+
+## Step 2: Install Formulus App
+
+
+
+
+Download and install the APK from the [releases page](https://github.com/OpenDataEnsemble/ode/releases), or build from source:
+
+```bash
+cd ode/formulus
+npm install
+npm run android
+```
+
+
+
+
+Build from source (requires macOS and Xcode):
+
+```bash
+cd ode/formulus
+npm install
+cd ios && bundle install && bundle exec pod install && cd ..
+npm run ios
+```
+
+
+
+
+## Step 3: Configure the App
+
+1. Open the Formulus app
+2. Navigate to Settings
+3. Enter server URL: `http://your-server-ip:8080` (or `http://localhost:8080` for emulator)
+4. Enter your credentials (create a user account first if needed)
+5. Save the configuration
+
+## Step 4: Create Your First Form
+
+Forms are defined using JSON schema. Create a simple form:
+
+```json
+{
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "age": {
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+ }
+ },
+ "required": ["name", "age"]
+}
+```
+
+Upload this form to your Synkronus server using the API or CLI tool.
+
+## Step 5: Collect Data
+
+1. Open the Formulus app
+2. Navigate to your form
+3. Fill out the form fields
+4. Submit the observation
+5. The data will be stored locally and synchronized to the server
+
+## Step 6: Verify Data Collection
+
+Check that your observation was created:
+
+
+
+
+```bash
+curl http://localhost:8080/api/observations \
+ -H "Authorization: Bearer YOUR_TOKEN"
+```
+
+
+
+
+```bash
+synk observations list
+```
+
+
+
+
+1. Navigate to the Portal
+2. Go to "Observations"
+3. View your submitted observations
+
+
+
+
+## Next Steps
+
+Now that you have a working setup:
+
+- Learn about [form design](/guides/form-design) to create more complex forms
+- Explore [custom applications](/guides/custom-applications) for specialized workflows
+- Review the [API reference](/reference/api) for integration options
+- Read about [synchronization](/using/synchronization) to understand data flow
+
+## Troubleshooting
+
+### Server Not Accessible
+
+If the mobile app cannot connect to the server:
+
+
+
+
+Verify the server is running: `curl http://localhost:8080/health`
+
+Check firewall settings
+
+Use your machine's IP address: `http://192.168.1.100:8080`
+
+Ensure device and server are on the same network
+
+
+
+
+Use `10.0.2.2` instead of `localhost`: `http://10.0.2.2:8080`
+
+Verify the server is running on the host machine
+
+Check that port 8080 is accessible
+
+
+
+
+Use `localhost` or your machine's IP address: `http://localhost:8080`
+
+Verify the server is running
+
+Check firewall settings
+
+
+
+
+### Forms Not Appearing
+
+If forms don't appear in the app:
+
+- Verify the form was uploaded correctly
+- Check that the app has synchronized with the server
+- Review server logs for errors
+
+### Synchronization Issues
+
+If data is not synchronizing:
+
+- Check network connectivity
+- Verify authentication credentials
+- Review server logs for sync errors
+- Ensure the observation was saved locally before sync
+
+## Related Documentation
+
+- [Installation Guide](/getting-started/installation)
+- [Your First Form](/using/your-first-form)
+- [Form Design Guide](/guides/form-design)
+
diff --git a/versioned_docs/version-1.0/getting-started/what-is-ode.md b/versioned_docs/version-1.0/getting-started/what-is-ode.md
new file mode 100644
index 0000000..01fea78
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/what-is-ode.md
@@ -0,0 +1,92 @@
+---
+sidebar_position: 1
+---
+
+# What is ODE?
+
+Open Data Ensemble (ODE) is a platform designed to simplify mobile data collection and management. It provides tools and infrastructure for creating forms, collecting data in the field, and synchronizing information across devices and servers.
+
+## Overview
+
+ODE addresses the challenges of data collection in environments where connectivity is unreliable or intermittent. The platform is built with an offline-first architecture, ensuring that data collection continues regardless of network availability.
+
+## Problem Statement
+
+Traditional data collection solutions often require constant internet connectivity, making them unsuitable for field work in remote areas. ODE solves this by:
+
+- Storing data locally on mobile devices
+- Synchronizing data when connectivity is available
+- Resolving conflicts automatically when multiple devices modify the same data
+- Providing a flexible form design system that adapts to various use cases
+
+## Key Features
+
+### Offline-First Design
+
+All data is stored locally on the device using WatermelonDB, a reactive database optimized for React Native. This ensures that data collection continues even when the device is offline.
+
+### Flexible Form System
+
+Forms are defined using JSON schema, following the JSON Forms specification. This allows for complex validation rules, conditional logic, and custom question types.
+
+### Reliable Synchronization
+
+The synchronization protocol handles conflicts, ensures data integrity, and supports incremental updates to minimize bandwidth usage.
+
+### Cross-Platform Support
+
+ODE applications run on Android and iOS devices, with a web-based form player for preview and testing.
+
+### Extensible Architecture
+
+The platform supports custom applications and renderers, allowing organizations to tailor the user experience to their specific needs.
+
+## Use Cases
+
+ODE is suitable for various data collection scenarios:
+
+| Use Case | Description |
+|----------|-------------|
+| **Health Surveys** | Collect patient data, medical records, and health indicators |
+| **Research Studies** | Gather research data in field conditions |
+| **Monitoring & Evaluation** | Track program outcomes and indicators |
+| **Asset Management** | Inventory and track assets in the field |
+| **Quality Assurance** | Conduct inspections and quality checks |
+
+## Architecture Overview
+
+ODE follows a client-server architecture:
+
+```
+┌─────────────┐ ┌──────────────┐ ┌─────────────┐
+│ Formulus │◄───────►│ Synkronus │◄───────►│ Formulus │
+│ (Mobile) │ Sync │ (Server) │ Sync │ (Mobile) │
+└─────────────┘ └──────────────┘ └─────────────┘
+ │ │ │
+ │ │ │
+ ▼ ▼ ▼
+┌─────────────┐ ┌──────────────┐ ┌─────────────┐
+│ Formplayer │ │ Database │ │ Formplayer │
+│ (WebView) │ │ (PostgreSQL) │ │ (WebView) │
+└─────────────┘ └──────────────┘ └─────────────┘
+```
+
+The mobile application (Formulus) communicates with the server (Synkronus) to synchronize data. Forms are rendered using the Formplayer component, which can be embedded in custom applications.
+
+## Technology Stack
+
+ODE is built using modern, open-source technologies:
+
+- **React Native** for mobile applications
+- **React** for web-based form rendering
+- **Go** for the backend server
+- **PostgreSQL** for data storage
+- **WatermelonDB** for local data storage on mobile devices
+- **JSON Forms** for form rendering and validation
+
+## Next Steps
+
+- Learn about [Why ODE?](/getting-started/why-ode) to understand the benefits
+- Review [Key Concepts](/getting-started/key-concepts) to understand the terminology
+- Follow the [Installation guide](/getting-started/installation/prerequisites) to set up your environment
+
diff --git a/versioned_docs/version-1.0/getting-started/why-ode.md b/versioned_docs/version-1.0/getting-started/why-ode.md
new file mode 100644
index 0000000..ca3d2de
--- /dev/null
+++ b/versioned_docs/version-1.0/getting-started/why-ode.md
@@ -0,0 +1,70 @@
+---
+sidebar_position: 2
+---
+
+# Why ODE?
+
+ODE provides several advantages over traditional data collection solutions, particularly for organizations working in challenging environments with unreliable connectivity.
+
+## Advantages
+
+### Offline-First Architecture
+
+Unlike many data collection platforms that require constant connectivity, ODE is designed to work offline. Data is stored locally and synchronized when connectivity is available, ensuring that field work is never interrupted by network issues.
+
+### Conflict Resolution
+
+When multiple devices modify the same data, ODE automatically resolves conflicts using a version-based approach. This ensures data integrity without requiring manual intervention.
+
+### Flexible Form Design
+
+The JSON-based form system allows for complex validation rules, conditional logic, and custom question types. Forms can be updated without requiring application updates, enabling rapid iteration and adaptation.
+
+### Open Source
+
+ODE is fully open source, allowing organizations to audit the code, customize the platform, and contribute improvements. This transparency builds trust and enables community-driven development.
+
+### Cross-Platform Support
+
+Applications built with ODE run on both Android and iOS devices, reducing the need to maintain separate codebases for different platforms.
+
+### Extensible
+
+The platform supports custom applications and renderers, allowing organizations to create specialized workflows and user interfaces that match their specific needs.
+
+## Comparison with Alternatives
+
+| Feature | ODE | Traditional Solutions |
+|--------|-----|----------------------|
+| Offline Support | Full offline functionality | Limited or none |
+| Conflict Resolution | Automatic | Manual or none |
+| Form Updates | Without app updates | Requires app updates |
+| Customization | High flexibility | Limited |
+| Open Source | Yes | Often proprietary |
+| Cost | Free and open source | Licensing fees |
+
+## When to Use ODE
+
+ODE is particularly well-suited for:
+
+- Organizations conducting field research or data collection in remote areas
+- Projects requiring complex forms with validation and conditional logic
+- Teams needing to customize the user experience
+- Organizations prioritizing data privacy and security
+- Projects requiring offline functionality
+
+## When to Consider Alternatives
+
+ODE may not be the best fit if:
+
+- Your use case requires real-time collaboration features
+- You need extensive third-party integrations out of the box
+- Your team lacks technical resources for deployment and maintenance
+- Your data collection needs are very simple and don't require offline support
+
+## Next Steps
+
+- Review [Key Concepts](/getting-started/key-concepts) to understand ODE terminology
+- Check [Prerequisites](/getting-started/installation/prerequisites) for system requirements
+- Follow the [Installation guide](/getting-started/installation/quick-start) to get started
+
diff --git a/versioned_docs/version-1.0/guides/.gitkeep b/versioned_docs/version-1.0/guides/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/versioned_docs/version-1.0/guides/configuration.md b/versioned_docs/version-1.0/guides/configuration.md
new file mode 100644
index 0000000..cc29d14
--- /dev/null
+++ b/versioned_docs/version-1.0/guides/configuration.md
@@ -0,0 +1,360 @@
+---
+sidebar_position: 4
+---
+
+# Configuration
+
+Complete configuration guide for ODE components including server settings, client settings, and environment variables.
+
+## Server Configuration (Synkronus)
+
+Synkronus is configured using environment variables. You can use either environment variables directly or a `.env` file for local development.
+
+### Configuration File Locations
+
+For local development, create a `.env` file in one of these locations (searched in order):
+
+1. Current working directory (where you run the command from)
+2. Same directory as the executable
+3. Parent directory of the executable
+
+### Required Configuration
+
+| Variable | Description | Example |
+|----------|-------------|---------|
+| `DB_CONNECTION` | PostgreSQL connection string | `postgres://user:password@localhost:5432/synkronus?sslmode=disable` |
+| `JWT_SECRET` | Secret key for JWT token signing (minimum 32 characters) | Generate with `openssl rand -base64 32` |
+
+### Optional Configuration
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `PORT` | `8080` | HTTP server port |
+| `LOG_LEVEL` | `info` | Logging level: `debug`, `info`, `warn`, or `error` |
+| `APP_BUNDLE_PATH` | `./data/app-bundles` | Directory path for app bundle storage |
+| `MAX_VERSIONS_KEPT` | `5` | Maximum number of app bundle versions to retain |
+| `ADMIN_USERNAME` | `admin` | Initial admin username |
+| `ADMIN_PASSWORD` | `admin` | Initial admin password (must be changed in production) |
+
+### Example Configuration File
+
+```bash
+# Server Configuration
+PORT=8080
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=info
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+
+# Admin Configuration
+ADMIN_USERNAME=admin
+ADMIN_PASSWORD=change-this-password
+```
+
+### Database Connection String Format
+
+The `DB_CONNECTION` string follows PostgreSQL connection URI format:
+
+```
+postgres://[user[:password]@][host][:port][/database][?param1=value1&...]
+```
+
+**Components:**
+- `user`: Database username
+- `password`: Database password
+- `host`: Database hostname or IP address
+- `port`: Database port (default: 5432)
+- `database`: Database name
+- `sslmode`: SSL mode (`disable`, `require`, `verify-full`, etc.)
+
+**Examples:**
+
+```bash
+# Local development
+DB_CONNECTION=postgres://synkronus:password@localhost:5432/synkronus?sslmode=disable
+
+# Remote database
+DB_CONNECTION=postgres://synkronus:password@db.example.com:5432/synkronus?sslmode=require
+
+# Docker Compose
+DB_CONNECTION=postgres://synkronus:password@postgres:5432/synkronus?sslmode=disable
+```
+
+## Client Configuration (Formulus)
+
+The Formulus mobile app is configured through the app settings interface.
+
+### Server URL
+
+Enter the URL of your Synkronus server:
+
+
+
+
+**Physical Device**: `http://192.168.1.100:8080` (your machine's IP address)
+
+**Android Emulator**: `http://10.0.2.2:8080` (special IP for emulator)
+
+**iOS Simulator**: `http://localhost:8080` or your machine's IP address
+
+
+
+
+**HTTPS URL**: `https://synkronus.your-domain.com`
+
+**Custom Port**: `https://synkronus.your-domain.com:8443` (if using non-standard port)
+
+
+
+
+### Authentication
+
+Configure authentication credentials:
+
+1. **Username**: Your user account username
+2. **Password**: Your user account password
+3. **Server URL**: As described above
+
+The app stores credentials securely and uses them for API authentication.
+
+### Sync Settings
+
+Configure synchronization behavior:
+
+- **Auto-sync**: Enable automatic synchronization when connectivity is available
+- **Sync interval**: How often to check for sync (default: every 15 minutes)
+- **Sync on app start**: Automatically sync when the app is opened
+- **Sync on observation save**: Sync immediately after saving an observation
+
+## Synkronus CLI Configuration
+
+The Synkronus CLI uses a configuration file located at `$HOME/.synkronus.yaml` by default.
+
+### Configuration File Format
+
+```yaml
+api:
+ url: http://localhost:8080
+ version: 1.0.0
+```
+
+### Multiple Endpoints
+
+You can manage multiple endpoint configurations:
+
+```bash
+# Create separate config files
+synk config init -o ~/.synkronus-dev.yaml
+synk config init -o ~/.synkronus-prod.yaml
+
+# Point CLI at dev by default
+synk config use ~/.synkronus-dev.yaml
+
+# Point CLI at prod by default
+synk config use ~/.synkronus-prod.yaml
+
+# Temporarily override for a single command
+synk --config ~/.synkronus-dev.yaml status
+```
+
+### Authentication
+
+The CLI stores authentication tokens in the configuration file after login:
+
+```bash
+# Login to the API
+synk login --username your-username
+
+# Check authentication status
+synk status
+
+# Logout
+synk logout
+```
+
+## Docker Configuration
+
+### Docker Compose Configuration
+
+When using Docker Compose, configuration is set in the `docker-compose.yml` file:
+
+```yaml
+services:
+ synkronus:
+ image: ghcr.io/opendataensemble/synkronus:latest
+ environment:
+ PORT: 8080
+ DB_CONNECTION: postgres://synkronus:password@postgres:5432/synkronus?sslmode=disable
+ JWT_SECRET: your-secret-key
+ LOG_LEVEL: info
+ APP_BUNDLE_PATH: /app/data/app-bundles
+ MAX_VERSIONS_KEPT: 5
+ volumes:
+ - app-bundles:/app/data/app-bundles
+ depends_on:
+ - postgres
+```
+
+### Environment File
+
+You can also use a `.env` file with Docker Compose:
+
+```bash
+# .env file
+DB_CONNECTION=postgres://synkronus:password@postgres:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key
+LOG_LEVEL=info
+```
+
+Reference in `docker-compose.yml`:
+
+```yaml
+services:
+ synkronus:
+ env_file:
+ - .env
+```
+
+## Security Configuration
+
+### JWT Secret
+
+Generate a strong JWT secret:
+
+```bash
+# Using OpenSSL
+openssl rand -base64 32
+
+# Using PowerShell (Windows)
+[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 }))
+```
+
+**Important:** Use a different secret for each environment (development, staging, production).
+
+### Database Passwords
+
+Generate strong database passwords:
+
+```bash
+# Generate random password
+openssl rand -base64 24
+```
+
+### Admin Password
+
+Change the default admin password immediately after deployment:
+
+```bash
+# Via API
+curl -X POST https://your-server.com/users/change-password \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -H "Content-Type: application/json" \
+ -d '{"current_password":"admin","new_password":"new-secure-password"}'
+```
+
+## Logging Configuration
+
+### Log Levels
+
+| Level | Description | Use Case |
+|-------|-------------|----------|
+| `debug` | Detailed diagnostic information | Development, troubleshooting |
+| `info` | General informational messages | Production (default) |
+| `warn` | Warning messages | Production |
+| `error` | Error messages only | Production (minimal logging) |
+
+### Log Output
+
+Logs are written to standard output (stdout) and can be captured by:
+
+- Docker logging drivers
+- Systemd journal
+- Log aggregation services (e.g., Fluentd, Logstash)
+
+### Docker Logging
+
+Configure Docker logging in `docker-compose.yml`:
+
+```yaml
+services:
+ synkronus:
+ logging:
+ driver: "json-file"
+ options:
+ max-size: "10m"
+ max-file: "3"
+```
+
+## Performance Configuration
+
+### PostgreSQL Settings
+
+Optimize PostgreSQL for your workload:
+
+```yaml
+services:
+ postgres:
+ command:
+ - "postgres"
+ - "-c"
+ - "max_connections=100"
+ - "-c"
+ - "shared_buffers=256MB"
+ - "-c"
+ - "effective_cache_size=1GB"
+```
+
+### Resource Limits
+
+Set resource limits in Docker Compose:
+
+```yaml
+services:
+ synkronus:
+ deploy:
+ resources:
+ limits:
+ cpus: '1.0'
+ memory: 512M
+ reservations:
+ cpus: '0.5'
+ memory: 256M
+```
+
+## Configuration Validation
+
+### Verify Configuration
+
+Test your configuration:
+
+```bash
+# Check environment variables are set
+docker compose config
+
+# Test database connection
+docker compose exec synkronus sh -c 'apk add postgresql-client && psql "$DB_CONNECTION"'
+
+# Check server health
+curl http://localhost:8080/health
+```
+
+### Common Configuration Issues
+
+**Problem**: Database connection fails
+
+**Solution**: Verify `DB_CONNECTION` string format and database accessibility.
+
+**Problem**: JWT authentication fails
+
+**Solution**: Ensure `JWT_SECRET` is at least 32 characters and matches across all instances.
+
+**Problem**: App bundles not persisting
+
+**Solution**: Verify `APP_BUNDLE_PATH` is set and volume is properly mounted.
+
+## Related Documentation
+
+- [Installation Guide](/getting-started/installation)
+- [Deployment Guide](/guides/deployment)
+- [API Reference](/reference/api)
diff --git a/versioned_docs/version-1.0/guides/custom-applications.md b/versioned_docs/version-1.0/guides/custom-applications.md
new file mode 100644
index 0000000..9055a4d
--- /dev/null
+++ b/versioned_docs/version-1.0/guides/custom-applications.md
@@ -0,0 +1,196 @@
+---
+sidebar_position: 2
+---
+
+# Custom Applications
+
+Complete guide to building and deploying custom applications that integrate with ODE.
+
+## Overview
+
+Custom applications are web-based interfaces that run within the Formulus mobile app, providing specialized workflows and user experiences. They allow you to create custom navigation, integrate with the ODE form system, and build specialized interfaces for specific use cases.
+
+## How Custom Applications Work
+
+Custom applications are defined in app bundles, which include:
+
+- HTML, CSS, and JavaScript files
+- Form specifications
+- Custom renderers for question types
+- Configuration files
+
+The app bundle is uploaded to the Synkronus server and downloaded by mobile devices during synchronization. When a user opens a custom application, it runs in a WebView within the Formulus app.
+
+## Formulus JavaScript Interface
+
+Custom applications interact with Formulus through a JavaScript interface. The API is injected automatically when your app loads.
+
+### Getting the Formulus API
+
+Always use the `getFormulus()` helper function to ensure the API is ready:
+
+```html
+
+
+
+
+```
+
+### Available Methods
+
+The Formulus interface provides methods for:
+
+- **Form Operations**: Create, edit, and delete observations
+- **Data Access**: Query observations and form specifications
+- **Device Features**: Access camera, GPS, file system, etc.
+- **Synchronization**: Trigger sync operations
+
+### Creating Observations
+
+```javascript
+// Create a new observation
+await formulus.addObservation(formType, initializationData);
+```
+
+### Editing Observations
+
+```javascript
+// Edit an existing observation
+await formulus.editObservation(formType, observationId);
+```
+
+### Deleting Observations
+
+```javascript
+// Delete an observation
+await formulus.deleteObservation(formType, observationId);
+```
+
+## App Bundle Structure
+
+An app bundle is a ZIP file containing:
+
+```
+app-bundle/
+├── index.html # Main entry point
+├── assets/
+│ ├── css/
+│ ├── js/
+│ └── images/
+├── forms/ # Form specifications (optional)
+└── manifest.json # Bundle metadata
+```
+
+### Manifest File
+
+The manifest defines bundle metadata:
+
+```json
+{
+ "version": "1.0.0",
+ "name": "My Custom App",
+ "description": "Description of the app",
+ "entryPoint": "index.html"
+}
+```
+
+## Building Custom Applications
+
+### Development Setup
+
+1. **Reference the API**: Copy `formulus-api.js` into your project for autocompletion
+2. **Include the Load Script**: Add `formulus-load.js` to your HTML
+3. **Use getFormulus()**: Always await the API before using it
+
+### Example Application
+
+```html
+
+
+
+ My Custom App
+
+
+
+
My Custom App
+
+
+
+
+
+```
+
+## Deployment
+
+### Uploading App Bundles
+
+Upload app bundles using the Synkronus CLI:
+
+```bash
+synk app-bundle upload bundle.zip --activate
+```
+
+Or use the API:
+
+```bash
+curl -X POST http://your-server:8080/api/app-bundle/upload \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -F "bundle=@bundle.zip"
+```
+
+### Version Management
+
+App bundles support versioning:
+
+- Each upload creates a new version
+- Versions are identified by timestamp
+- Switch between versions using the CLI or API
+- Mobile devices download the active version during sync
+
+## Custom Renderers
+
+Custom applications can include custom renderers for question types. See the [Form Design guide](/guides/form-design) for details on creating custom renderers.
+
+## Best Practices
+
+1. **Wait for API**: Always use `getFormulus()` before accessing the API
+2. **Error Handling**: Implement proper error handling for all API calls
+3. **Offline Support**: Design apps to work gracefully when offline
+4. **Performance**: Optimize for mobile devices and slower networks
+5. **Testing**: Test thoroughly in both development and production environments
+
+## Related Documentation
+
+- [Form Design Guide](/guides/form-design)
+- [Formulus Interface Documentation](https://github.com/OpenDataEnsemble/ode/tree/main/formulus/src/webview)
+- [App Bundle Format Reference](/reference/app-bundle-format)
+
diff --git a/versioned_docs/version-1.0/guides/deployment.md b/versioned_docs/version-1.0/guides/deployment.md
new file mode 100644
index 0000000..b72d7e0
--- /dev/null
+++ b/versioned_docs/version-1.0/guides/deployment.md
@@ -0,0 +1,560 @@
+---
+sidebar_position: 3
+---
+
+# Deployment
+
+Complete guide to deploying ODE in production environments using Docker and Docker Compose.
+
+## Overview
+
+ODE can be deployed using Docker containers, which simplifies deployment and ensures consistency across environments. This guide covers production deployment with Docker Compose, including PostgreSQL, Nginx reverse proxy, and optional Cloudflared tunnel for secure external access.
+
+## Recommended Production Setup
+
+For production deployment, we recommend:
+
+- **Clean Linux server** (Ubuntu 22.04 LTS or Debian 12)
+- **Docker & Docker Compose** installed
+- **Cloudflared tunnel** for secure external access (no port forwarding needed)
+- **PostgreSQL** database (dockerized via docker-compose)
+- **Nginx** reverse proxy (included in docker-compose)
+- **Persistent volumes** for data storage
+
+## Quick Start
+
+### Server Preparation
+
+
+
+
+```bash
+# Update system
+sudo apt update && sudo apt upgrade -y
+
+# Install Docker
+curl -fsSL https://get.docker.com -o get-docker.sh
+sudo sh get-docker.sh
+
+# Install Docker Compose
+sudo apt install docker-compose-plugin -y
+
+# Verify installation
+docker --version
+docker compose version
+```
+
+
+
+
+```bash
+# Install Docker Desktop from https://www.docker.com/products/docker-desktop
+# Or use Homebrew:
+brew install --cask docker
+
+# Docker Compose is included with Docker Desktop
+# Verify installation
+docker --version
+docker compose version
+```
+
+
+
+
+1. **Install Docker Desktop** from [docker.com/products/docker-desktop](https://www.docker.com/products/docker-desktop)
+2. **Docker Compose is included** with Docker Desktop
+3. **Verify installation** (PowerShell):
+ ```powershell
+ docker --version
+ docker compose version
+ ```
+
+
+
+
+### Deploy Synkronus
+
+```bash
+# Create deployment directory
+mkdir -p ~/synkronus
+cd ~/synkronus
+
+# Download configuration files
+wget https://raw.githubusercontent.com/opendataensemble/ode/main/synkronus/docker-compose.example.yml -O docker-compose.yml
+wget https://raw.githubusercontent.com/opendataensemble/ode/main/synkronus/nginx.conf
+
+# Generate secure secrets
+JWT_SECRET=$(openssl rand -base64 32)
+DB_ROOT_PASSWORD=$(openssl rand -base64 24)
+ADMIN_PASSWORD=$(openssl rand -base64 16)
+
+# Update docker-compose.yml with secrets
+sed -i "s/CHANGE_THIS_PASSWORD/$DB_ROOT_PASSWORD/g" docker-compose.yml
+sed -i "s/CHANGE_THIS_TO_RANDOM_32_CHAR_STRING/$JWT_SECRET/g" docker-compose.yml
+sed -i "s/CHANGE_THIS_ADMIN_PASSWORD/$ADMIN_PASSWORD/g" docker-compose.yml
+
+# Start the stack
+docker compose up -d
+
+# Verify it's running
+curl http://localhost/health
+```
+
+### Database Setup
+
+Create a database and user for Synkronus:
+
+
+
+
+```bash
+# Open a psql shell into the Postgres container
+docker compose exec postgres psql -U postgres
+```
+
+From the `psql` prompt:
+
+```sql
+-- Create role and database
+CREATE ROLE synkronus_user LOGIN PASSWORD 'CHANGE_THIS_APP_PASSWORD';
+CREATE DATABASE synkronus OWNER synkronus_user;
+```
+
+
+
+
+```bash
+# Connect to local PostgreSQL
+psql -U postgres
+```
+
+From the `psql` prompt:
+
+```sql
+-- Create role and database
+CREATE ROLE synkronus_user LOGIN PASSWORD 'CHANGE_THIS_APP_PASSWORD';
+CREATE DATABASE synkronus OWNER synkronus_user;
+```
+
+
+
+
+Update the `synkronus` service `DB_CONNECTION` in `docker-compose.yml`:
+
+```yaml
+services:
+ synkronus:
+ environment:
+ DB_CONNECTION: "postgres://synkronus_user:CHANGE_THIS_APP_PASSWORD@postgres:5432/synkronus?sslmode=disable"
+```
+
+## Using Pre-built Images
+
+Pre-built images are automatically published to GitHub Container Registry (GHCR) via CI/CD.
+
+### Pull the Latest Image
+
+```bash
+docker pull ghcr.io/opendataensemble/synkronus:latest
+```
+
+### Available Tags
+
+| Tag | Description |
+|-----|-------------|
+| `latest` | Latest stable release from main branch |
+| `v1.0.0` | Specific version tags |
+| `develop` | Development branch (pre-release) |
+| `feature-xyz` | Feature branches (pre-release) |
+
+### Run Pre-built Image
+
+```bash
+docker run -d \
+ --name synkronus \
+ -p 8080:8080 \
+ -e DB_CONNECTION="postgres://user:password@host:5432/synkronus" \
+ -e JWT_SECRET="your-secret-key" \
+ -e APP_BUNDLE_PATH="/app/data/app-bundles" \
+ -v synkronus-bundles:/app/data/app-bundles \
+ ghcr.io/opendataensemble/synkronus:latest
+```
+
+## Cloudflared Tunnel Setup
+
+Cloudflared provides secure external access without exposing ports or managing SSL certificates.
+
+### Install Cloudflared
+
+```bash
+# Download and install
+wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
+sudo dpkg -i cloudflared-linux-amd64.deb
+
+# Verify installation
+cloudflared --version
+```
+
+### Create Tunnel
+
+```bash
+# Login to Cloudflare
+cloudflared tunnel login
+
+# Create tunnel
+cloudflared tunnel create synkronus
+
+# Note the tunnel ID from the output
+```
+
+### Configure Tunnel
+
+Create `~/.cloudflared/config.yml`:
+
+```yaml
+tunnel:
+credentials-file: /root/.cloudflared/.json
+
+ingress:
+ - hostname: synkronus.your-domain.com
+ service: http://localhost:80
+ - service: http_status:404
+```
+
+### Route DNS
+
+```bash
+# Route your domain to the tunnel
+cloudflared tunnel route dns synkronus synkronus.your-domain.com
+```
+
+### Run Tunnel as Service
+
+```bash
+# Install as systemd service
+sudo cloudflared service install
+
+# Start service
+sudo systemctl start cloudflared
+sudo systemctl enable cloudflared
+
+# Check status
+sudo systemctl status cloudflared
+```
+
+Your Synkronus instance is now accessible at `https://synkronus.your-domain.com` with automatic SSL.
+
+## Environment Variables
+
+### Required Variables
+
+| Variable | Description | Example |
+|----------|-------------|---------|
+| `DB_CONNECTION` | PostgreSQL connection string | `postgres://user:pass@postgres:5432/synkronus` |
+| `JWT_SECRET` | Secret key for JWT token signing | Generate with `openssl rand -base64 32` |
+
+### Optional Variables
+
+| Variable | Default | Description |
+|----------|---------|-------------|
+| `PORT` | `8080` | HTTP server port |
+| `LOG_LEVEL` | `info` | Logging level (`debug`, `info`, `warn`, `error`) |
+| `APP_BUNDLE_PATH` | `/app/data/app-bundles` | Path for app bundle storage |
+| `MAX_VERSIONS_KEPT` | `5` | Number of app bundle versions to retain |
+| `ADMIN_USERNAME` | `admin` | Initial admin username |
+| `ADMIN_PASSWORD` | `admin` | Initial admin password (CHANGE THIS!) |
+
+## Volume Management
+
+### Persistent Volumes
+
+The docker-compose setup creates persistent volumes:
+
+1. **postgres-data**: PostgreSQL database files
+2. **app-bundles**: Uploaded application bundles
+
+```bash
+# List volumes
+docker volume ls
+
+# Inspect volume
+docker volume inspect synkronus_postgres-data
+
+# Backup volume
+docker run --rm -v synkronus_postgres-data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz /data
+
+# Restore volume
+docker run --rm -v synkronus_postgres-data:/data -v $(pwd):/backup alpine tar xzf /backup/postgres-backup.tar.gz -C /
+```
+
+### App Bundle Directory Permissions
+
+When bind-mounting a host directory for `app-bundles`, ensure proper permissions. The container runs as user `synkronus` with `uid=1000` and `gid=1000`:
+
+```bash
+# Fix permissions on host directory
+sudo chown -R 1000:1000 ~/server/app-bundles
+
+# Restart after fixing permissions
+docker compose restart synkronus
+```
+
+## Monitoring and Maintenance
+
+### View Logs
+
+```bash
+# All services
+docker compose logs -f
+
+# Specific service
+docker compose logs -f synkronus
+docker compose logs -f postgres
+docker compose logs -f nginx
+
+# Last 100 lines
+docker compose logs --tail=100 synkronus
+```
+
+### Health Checks
+
+```bash
+# Check service status
+docker compose ps
+
+# Test health endpoint
+curl http://localhost/health
+
+# Via cloudflared tunnel
+curl https://synkronus.your-domain.com/health
+```
+
+### Restart Services
+
+```bash
+# Restart all services
+docker compose restart
+
+# Restart specific service
+docker compose restart synkronus
+
+# Reload nginx configuration
+docker compose exec nginx nginx -s reload
+```
+
+### Update to Latest Version
+
+```bash
+# Pull latest image
+docker compose pull
+
+# Recreate containers with new image
+docker compose up -d
+
+# Remove old images
+docker image prune -f
+```
+
+## Backup and Restore
+
+### Database Backup
+
+```bash
+# Create backup
+docker compose exec postgres pg_dump -U synkronus_user synkronus > backup-$(date +%Y%m%d).sql
+
+# Automated daily backups (add to crontab)
+0 2 * * * cd ~/synkronus && docker compose exec -T postgres pg_dump -U synkronus_user synkronus > /backups/synkronus-$(date +\%Y\%m\%d).sql
+```
+
+### Database Restore
+
+```bash
+# Restore from backup
+docker compose exec -T postgres psql -U synkronus_user synkronus < backup-20250114.sql
+```
+
+### Full System Backup
+
+```bash
+# Backup everything
+tar czf synkronus-full-backup-$(date +%Y%m%d).tar.gz \
+ docker-compose.yml \
+ nginx.conf \
+ $(docker volume inspect synkronus_postgres-data --format '{{ .Mountpoint }}') \
+ $(docker volume inspect synkronus_app-bundles --format '{{ .Mountpoint }}')
+```
+
+## Security Best Practices
+
+### 1. Use Strong Secrets
+
+```bash
+# Generate strong JWT secret
+openssl rand -base64 32
+
+# Generate strong passwords
+openssl rand -base64 24
+```
+
+### 2. Change Default Admin Password
+
+After first deployment, change the admin password via API or CLI.
+
+### 3. Regular Updates
+
+```bash
+# Update system packages
+sudo apt update && sudo apt upgrade -y
+
+# Update Docker images
+docker compose pull
+docker compose up -d
+```
+
+### 4. Firewall Configuration
+
+If not using Cloudflared, configure firewall:
+
+```bash
+sudo ufw allow 80/tcp
+sudo ufw allow 443/tcp
+sudo ufw enable
+```
+
+## Performance Tuning
+
+### PostgreSQL Optimization
+
+Add to `docker-compose.yml` under postgres service:
+
+```yaml
+command:
+ - "postgres"
+ - "-c"
+ - "max_connections=100"
+ - "-c"
+ - "shared_buffers=256MB"
+ - "-c"
+ - "effective_cache_size=1GB"
+```
+
+### Resource Limits
+
+Add to `docker-compose.yml` under each service:
+
+```yaml
+deploy:
+ resources:
+ limits:
+ cpus: '1.0'
+ memory: 512M
+ reservations:
+ cpus: '0.5'
+ memory: 256M
+```
+
+## Architecture
+
+The deployment architecture includes:
+
+```
+┌─────────────────────────────────────────┐
+│ Cloudflared Tunnel │
+│ (Optional - Cloudflare) │
+│ Automatic SSL/TLS │
+└──────────────┬──────────────────────────┘
+ │ HTTPS
+ ▼
+┌─────────────────────────────────────────┐
+│ Nginx Reverse Proxy │
+│ Port 80/443 │
+│ - Load balancing │
+│ - Request routing │
+│ - Compression │
+└──────────────┬──────────────────────────┘
+ │ HTTP
+ ▼
+┌─────────────────────────────────────────┐
+│ Synkronus Container │
+│ Port 8080 (internal) │
+│ - API endpoints │
+│ - Business logic │
+│ - File storage │
+└──────────────┬──────────────────────────┘
+ │ PostgreSQL protocol
+ ▼
+┌─────────────────────────────────────────┐
+│ PostgreSQL Database │
+│ Port 5432 (internal) │
+│ - Data persistence │
+│ - Transactions │
+└─────────────────────────────────────────┘
+```
+
+## Troubleshooting
+
+### Service Won't Start
+
+```bash
+# Check logs
+docker compose logs synkronus
+
+# Check environment variables
+docker compose config
+
+# Verify database connection
+docker compose exec synkronus sh
+# Inside container:
+apk add postgresql-client
+psql "$DB_CONNECTION"
+```
+
+### Database Connection Issues
+
+```bash
+# Check PostgreSQL is running
+docker compose ps postgres
+
+# Check PostgreSQL logs
+docker compose logs postgres
+
+# Test connection from synkronus container
+docker compose exec synkronus sh -c 'apk add postgresql-client && psql "$DB_CONNECTION"'
+```
+
+### Nginx Issues
+
+```bash
+# Test nginx configuration
+docker compose exec nginx nginx -t
+
+# Reload nginx
+docker compose exec nginx nginx -s reload
+
+# Check nginx logs
+docker compose logs nginx
+```
+
+## Production Checklist
+
+Before going live:
+
+- [ ] Strong JWT secret generated
+- [ ] Strong database password set
+- [ ] Admin password changed from default
+- [ ] Cloudflared tunnel configured (or SSL certificates installed)
+- [ ] Backup strategy implemented
+- [ ] Monitoring configured
+- [ ] Health checks passing
+- [ ] Firewall configured (if not using Cloudflared)
+- [ ] Resource limits set
+- [ ] Log rotation configured
+- [ ] Documentation reviewed
+- [ ] Test deployment verified
+
+## Related Documentation
+
+- [Installation Guide](/getting-started/installation)
+- [Configuration Guide](/guides/configuration)
+- [API Reference](/reference/api)
diff --git a/versioned_docs/version-1.0/guides/form-design.md b/versioned_docs/version-1.0/guides/form-design.md
new file mode 100644
index 0000000..0672c88
--- /dev/null
+++ b/versioned_docs/version-1.0/guides/form-design.md
@@ -0,0 +1,1362 @@
+---
+sidebar_position: 1
+---
+
+# Form Design
+
+Complete guide to designing forms in ODE using JSON schema and JSON Forms.
+
+## Overview
+
+Forms in ODE are defined using JSON schema, following the JSON Forms specification. A form consists of two main components:
+
+1. **Schema**: Defines the data structure and validation rules
+2. **UI Schema**: Defines how the form is presented to users
+
+## How Forms Work in ODE
+
+Understanding the mental model of forms in ODE is essential for effective form design.
+
+### What is a "Form" in ODE?
+
+A form in ODE is a structured data collection interface that consists of:
+
+- **JSON Schema**: Defines what data can be collected, its structure, types, and validation rules
+- **UI Schema**: Defines how the form is presented to users, including layout, field ordering, and conditional visibility
+- **Formplayer**: The rendering engine that interprets these schemas and creates the interactive form interface
+
+### The Role of JSON Schema
+
+JSON Schema serves as the **data contract** for your form:
+
+- **Structure Definition**: Defines the shape of data (properties, types, nesting)
+- **Validation Rules**: Enforces data quality (required fields, ranges, formats)
+- **Type Safety**: Ensures data types match expectations (string, number, boolean, etc.)
+
+JSON Schema follows the [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7) specification, but ODE Formplayer intentionally supports a **safe, predictable subset** of JSON Schema features.
+
+### The Role of UI Schema
+
+UI Schema (JSON Forms UI Schema) controls the **presentation layer**:
+
+- **Layout**: How fields are arranged (vertical, horizontal, grouped, paginated)
+- **Ordering**: The sequence in which fields appear
+- **Conditional Logic**: When fields are shown or hidden
+- **Field Configuration**: Labels, placeholders, and display options
+
+### The Role of Formplayer
+
+Formplayer is the React-based rendering engine that:
+
+- **Interprets Schemas**: Reads JSON Schema and UI Schema to understand form structure
+- **Renders Components**: Creates interactive form elements (inputs, selects, media capture, etc.)
+- **Validates Input**: Enforces schema validation rules in real-time
+- **Manages State**: Tracks form data, validation errors, and user interactions
+
+### Why ODE Supports a Subset of JSON Schema
+
+**Key Message**: ODE Formplayer intentionally supports a safe, predictable subset of JSON Schema and JSON Forms to ensure:
+
+1. **Reliability**: Forms work consistently across all devices and scenarios
+2. **Performance**: Complex schema features don't slow down form rendering
+3. **Predictability**: Form behavior is deterministic and easy to reason about
+4. **Mobile Optimization**: Features work well in resource-constrained mobile environments
+
+**Important**: Forms that use unsupported JSON Schema features may load but are **not guaranteed to work**. Always refer to the [Formplayer Supported Schema & UI Profile](/reference/formplayer#supported-schema--ui-profile) for the definitive list of supported features.
+
+## Basic Form Structure
+
+Here's a simple form example:
+
+```json
+{
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Name"
+ },
+ "age": {
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+ }
+ },
+ "required": ["name", "age"]
+ },
+ "uischema": {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/name"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/age"
+ }
+ ]
+ }
+}
+```
+
+## Schema Definition
+
+The schema defines the data structure and validation rules for your form. It follows the JSON Schema specification.
+
+### Property Types
+
+ODE supports various property types:
+
+| Type | Description | Example |
+|------|-------------|---------|
+| `string` | Text input | Name, description |
+| `integer` | Whole number | Age, count |
+| `number` | Decimal number | Weight, temperature |
+| `boolean` | True/false value | Consent, agreement |
+| `array` | List of items | Multiple selections |
+| `object` | Nested object | Complex data structures |
+
+### Validation Rules
+
+You can add validation rules to properties:
+
+```json
+{
+ "type": "string",
+ "title": "Email",
+ "format": "email",
+ "minLength": 5,
+ "maxLength": 100
+}
+```
+
+Common validation rules:
+
+- `minimum` / `maximum`: For numbers
+- `minLength` / `maxLength`: For strings
+- `pattern`: Regular expression pattern
+- `format`: Predefined formats (email, date, etc.)
+- `enum`: List of allowed values
+
+## Designing UI Schemas for ODE Formplayer
+
+The UI schema defines how form fields are presented to users. It controls layout, ordering, and presentation. ODE Formplayer has specific requirements and best practices for UI schema design.
+
+### Required Layout Structure
+
+**All ODE forms must use `SwipeLayout` as the root element.** This enables pagination and swipe navigation between form sections.
+
+#### SwipeLayout (Required Root)
+
+`SwipeLayout` is the root layout type that enables multi-page forms with swipe navigation. It automatically wraps other layout types if not explicitly specified.
+
+**Required Structure:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ // Each element becomes a swipeable page
+ ]
+}
+```
+
+**Key Characteristics:**
+- **Root Element**: Must be the top-level element in your UI schema
+- **Pagination**: Each element in `elements[]` becomes a separate page
+- **Swipe Navigation**: Users can swipe left/right to navigate between pages
+- **Progress Tracking**: Shows progress bar indicating current page
+- **Auto-wrapping**: If root is not SwipeLayout, Formplayer automatically wraps it
+
+**Safe Example:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/name"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/age"
+ }
+ ]
+ },
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/email"
+ }
+ ]
+ }
+ ]
+}
+```
+
+**Unsafe Example:**
+```json
+{
+ "type": "VerticalLayout", // ❌ Not SwipeLayout - will be auto-wrapped
+ "elements": [...]
+}
+```
+
+### Layout Types
+
+#### VerticalLayout
+
+Fields arranged vertically in a single column.
+
+**Required Fields:**
+- `type`: `"VerticalLayout"`
+- `elements`: Array of UI schema elements
+
+**Usage:**
+```json
+{
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/field1"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/field2"
+ }
+ ]
+}
+```
+
+#### HorizontalLayout
+
+Fields arranged horizontally in a row.
+
+**Required Fields:**
+- `type`: `"HorizontalLayout"`
+- `elements`: Array of UI schema elements
+
+**Usage:**
+```json
+{
+ "type": "HorizontalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/firstName"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/lastName"
+ }
+ ]
+}
+```
+
+#### Group
+
+Groups related fields together with a label.
+
+**Required Fields:**
+- `type`: `"Group"`
+- `label`: Group title (required)
+- `elements`: Array of UI schema elements
+
+**Usage:**
+```json
+{
+ "type": "Group",
+ "label": "Personal Information",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/name"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/email"
+ }
+ ]
+}
+```
+
+**Note**: Groups can be used as pages within SwipeLayout. Each Group element in a SwipeLayout's `elements[]` becomes a separate page.
+
+### Control Configuration
+
+Controls bind UI elements to schema properties.
+
+**Required Fields:**
+- `type`: `"Control"`
+- `scope`: JSON pointer to schema property (must exist in schema)
+
+**Optional Fields:**
+- `label`: Override field label
+- `options`: Additional configuration
+
+**Safe Example:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/name", // ✅ Scope exists in schema
+ "label": "Full Name",
+ "options": {
+ "placeholder": "Enter your name"
+ }
+}
+```
+
+**Unsafe Example:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/nonexistent" // ❌ Scope doesn't exist - will cause error
+}
+```
+
+### Label Element
+
+Displays text labels within forms.
+
+**Required Fields:**
+- `type`: `"Label"`
+- `text`: Label text content
+
+**Usage:**
+```json
+{
+ "type": "Label",
+ "text": "Section Introduction"
+}
+```
+
+### UI Schema Best Practices
+
+#### Pagination Patterns
+
+**Recommended**: Use SwipeLayout with VerticalLayout pages for multi-step forms:
+
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ { "type": "Label", "text": "Step 1: Basic Info" },
+ { "type": "Control", "scope": "#/properties/name" },
+ { "type": "Control", "scope": "#/properties/age" }
+ ]
+ },
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ { "type": "Label", "text": "Step 2: Contact" },
+ { "type": "Control", "scope": "#/properties/email" }
+ ]
+ }
+ ]
+}
+```
+
+#### Grouping Best Practices
+
+**Use Groups for logical organization:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "Group",
+ "label": "Demographics",
+ "elements": [
+ { "type": "Control", "scope": "#/properties/age" },
+ { "type": "Control", "scope": "#/properties/gender" }
+ ]
+ },
+ {
+ "type": "Group",
+ "label": "Health Information",
+ "elements": [
+ { "type": "Control", "scope": "#/properties/height" },
+ { "type": "Control", "scope": "#/properties/weight" }
+ ]
+ }
+ ]
+}
+```
+
+#### Common Pitfalls
+
+**❌ Missing elements array:**
+```json
+{
+ "type": "SwipeLayout"
+ // ❌ Missing elements - will cause error
+}
+```
+
+**✅ Always include elements:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [] // ✅ Empty array is safe
+}
+```
+
+**❌ Invalid scope paths:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/missingField" // ❌ Field doesn't exist in schema
+}
+```
+
+**✅ Verify scope exists:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/existingField" // ✅ Field exists in schema
+}
+```
+
+**❌ Nested SwipeLayout:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "SwipeLayout", // ❌ Nested SwipeLayout not supported
+ "elements": [...]
+ }
+ ]
+}
+```
+
+**✅ Use VerticalLayout or Group inside SwipeLayout:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout", // ✅ Use VerticalLayout for pages
+ "elements": [...]
+ }
+ ]
+}
+```
+
+## Question Types
+
+ODE supports various question types through the Formplayer component. Question types are specified using the `format` property in the schema.
+
+### Basic Input Types
+
+**Text Input:**
+```json
+{
+ "type": "string",
+ "title": "Name",
+ "format": "text"
+}
+```
+
+**Number Input:**
+```json
+{
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+}
+```
+
+**Date and Time:**
+```json
+{
+ "type": "string",
+ "title": "Date",
+ "format": "date"
+}
+```
+
+**Selection:**
+```json
+{
+ "type": "string",
+ "title": "Choice",
+ "enum": ["option1", "option2"],
+ "enumNames": ["Option 1", "Option 2"]
+}
+```
+
+**Boolean:**
+```json
+{
+ "type": "boolean",
+ "title": "Consent"
+}
+```
+
+## Working with Media & Special Field Types
+
+ODE Formplayer supports specialized field types for capturing media, location, signatures, and scanning codes. Each type has specific schema requirements and platform constraints.
+
+### Photo Capture
+
+Captures photos using device camera or gallery selection.
+
+**Expected Schema:**
+```json
+{
+ "type": "object",
+ "format": "photo",
+ "title": "Profile Photo",
+ "properties": {
+ "filename": { "type": "string" },
+ "uri": { "type": "string" },
+ "width": { "type": "integer" },
+ "height": { "type": "integer" },
+ "timestamp": { "type": "string", "format": "date-time" }
+ }
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/photo"
+}
+```
+
+**Renderer Behavior:**
+- Opens device camera or gallery picker
+- Stores photo as attachment (synchronized separately)
+- Returns metadata object with filename, URI, dimensions, timestamp
+
+**Platform Constraints:**
+- Requires camera permission on mobile devices
+- Photo files are stored locally and synced as attachments
+- Large photos may be compressed automatically
+
+### GPS Location
+
+Captures GPS coordinates with accuracy information.
+
+**Expected Schema:**
+```json
+{
+ "type": "object",
+ "format": "gps",
+ "title": "Current Location",
+ "properties": {
+ "latitude": { "type": "number" },
+ "longitude": { "type": "number" },
+ "altitude": { "type": "number" },
+ "accuracy": { "type": "number" },
+ "timestamp": { "type": "string", "format": "date-time" }
+ }
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/location"
+}
+```
+
+**Renderer Behavior:**
+- Requests location permission (first time)
+- Captures current GPS coordinates
+- Shows accuracy indicator
+- May display map preview (platform dependent)
+
+**Platform Constraints:**
+- Requires location permission
+- GPS accuracy depends on device capabilities and environment
+- Indoor locations may have poor accuracy
+- Battery impact: GPS usage drains battery faster
+
+### Signature Capture
+
+Captures digital signatures using touch input.
+
+**Expected Schema:**
+```json
+{
+ "type": "object",
+ "format": "signature",
+ "title": "Customer Signature",
+ "properties": {
+ "data": { "type": "string" }, // Base64 encoded image
+ "timestamp": { "type": "string", "format": "date-time" }
+ }
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/signature"
+}
+```
+
+**Renderer Behavior:**
+- Opens signature pad interface
+- User draws signature with finger/stylus
+- Stores as base64-encoded image
+- Provides clear/retry functionality
+
+**Platform Constraints:**
+- Works best on touch-enabled devices
+- Signature quality depends on screen size and resolution
+- Stored as image data (may be large)
+
+### Audio Recording
+
+Records audio using device microphone.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "audio",
+ "title": "Voice Note"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/audio"
+}
+```
+
+**Renderer Behavior:**
+- Opens audio recording interface
+- Records audio using device microphone
+- Stores audio file with metadata (duration, format, file size)
+- Provides playback preview
+
+**Platform Constraints:**
+- Requires microphone permission
+- Audio files are stored as attachments
+- File size depends on recording duration and quality
+- Format: Platform-dependent (typically MP3, M4A, or WAV)
+
+### Video Recording
+
+Records video using device camera.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "video",
+ "title": "Instructional Video"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/video"
+}
+```
+
+**Renderer Behavior:**
+- Opens video recording interface
+- Records video using device camera
+- Stores video file with metadata (duration, resolution, format)
+- Provides playback preview
+
+**Platform Constraints:**
+- Requires camera permission
+- Video files are large (stored as attachments)
+- File size depends on duration and resolution
+- Format: Platform-dependent (typically MP4)
+- Battery and storage intensive
+
+### File Selection
+
+Allows users to select files from device storage.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "select_file",
+ "title": "Upload Document"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/document"
+}
+```
+
+**Renderer Behavior:**
+- Opens device file picker
+- User selects file from storage
+- Stores file reference and metadata
+- File is uploaded as attachment
+
+**Platform Constraints:**
+- File type restrictions depend on platform
+- Large files may take time to upload
+- Storage permissions required
+
+### QR Code / Barcode Scanner
+
+Scans QR codes and barcodes using device camera.
+
+**Expected Schema:**
+```json
+{
+ "type": "string",
+ "format": "qrcode",
+ "title": "QR Code Scanner"
+}
+```
+
+**Required UI Schema:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/qrCode"
+}
+```
+
+**Renderer Behavior:**
+- Opens camera scanner interface
+- Automatically detects and scans codes
+- Returns scanned data as string
+- Supports multiple barcode formats
+
+**Supported Formats:**
+- QR Code
+- Code 128
+- Code 39
+- EAN-13
+- UPC-A
+- Data Matrix
+- PDF417
+- Aztec
+
+**Platform Constraints:**
+- Requires camera permission
+- Requires good lighting for reliable scanning
+- Some formats may not be supported on all platforms
+
+### Best Practices for Media Fields
+
+1. **Consider File Sizes**: Media files are large - be mindful of storage and sync bandwidth
+2. **Request Permissions Early**: Request camera/microphone/location permissions before users need them
+3. **Provide Clear Instructions**: Users may not understand how to use specialized field types
+4. **Handle Offline Scenarios**: Media capture works offline, but upload requires connectivity
+5. **Test on Real Devices**: Media features behave differently on different devices
+6. **Compress When Possible**: Large photos/videos should be compressed before storage
+7. **Validate File Types**: Ensure selected files match expected formats
+
+## Conditional Logic in ODE Forms
+
+Conditional logic allows you to show or hide fields based on other field values. This is essential for creating dynamic, context-aware forms.
+
+### How Rules Work
+
+Rules are defined in the UI schema using the `rule` property on Control elements. Rules evaluate conditions and apply effects (SHOW or HIDE) based on the result.
+
+**Basic Rule Structure:**
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/targetField",
+ "rule": {
+ "effect": "SHOW", // or "HIDE"
+ "condition": {
+ "scope": "#/properties/sourceField",
+ "schema": {
+ // Condition schema
+ }
+ }
+ }
+}
+```
+
+### Scope Resolution Rules
+
+**Critical Rule**: Rule condition scopes **must exist in the schema at all times**, even when the field is hidden. The scope is evaluated against the current form data.
+
+**Safe Pattern:**
+```json
+{
+ "schema": {
+ "type": "object",
+ "properties": {
+ "contactMethod": {
+ "type": "string",
+ "enum": ["email", "phone"]
+ },
+ "email": {
+ "type": "string",
+ "format": "email"
+ },
+ "phone": {
+ "type": "string"
+ }
+ }
+ },
+ "uischema": {
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Control",
+ "scope": "#/properties/contactMethod"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/email",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/contactMethod", // ✅ Scope exists in schema
+ "schema": {
+ "const": "email"
+ }
+ }
+ }
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/phone",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/contactMethod", // ✅ Scope exists in schema
+ "schema": {
+ "const": "phone"
+ }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Safe Patterns
+
+#### Equality Check
+
+Show field when another field equals a specific value:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/email",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/contactMethod",
+ "schema": {
+ "const": "email"
+ }
+ }
+ }
+}
+```
+
+#### Enum Value Check
+
+Show field when another field is one of several values:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/otherDetails",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/category",
+ "schema": {
+ "enum": ["category1", "category2"]
+ }
+ }
+ }
+}
+```
+
+#### Boolean Check
+
+Show field when boolean is true:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/consentDetails",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/hasConsent",
+ "schema": {
+ "const": true
+ }
+ }
+ }
+}
+```
+
+### Unsafe Patterns
+
+#### ❌ Rule Referencing Missing Field
+
+**Problem**: Rule condition scope doesn't exist in schema.
+
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" }
+ // field2 doesn't exist
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field2", // ❌ Field doesn't exist - will crash
+ "schema": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Fix**: Ensure all fields referenced in rules exist in the schema.
+
+#### ❌ Using $data References
+
+**Problem**: `$data` references are not supported and will cause errors.
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field2",
+ "schema": {
+ "minimum": { "$data": "#/properties/minValue" } // ❌ $data not supported
+ }
+ }
+ }
+}
+```
+
+**Fix**: Use literal values only:
+
+```json
+{
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field2",
+ "schema": {
+ "minimum": 0 // ✅ Literal value
+ }
+ }
+ }
+}
+```
+
+#### ❌ Using if/then/else
+
+**Problem**: JSON Schema `if/then/else` is not supported in rule conditions.
+
+```json
+{
+ "rule": {
+ "condition": {
+ "scope": "#/properties/field",
+ "schema": {
+ "if": { "type": "string" }, // ❌ Not supported
+ "then": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Fix**: Use simple const or enum checks instead.
+
+### Best Practices for Conditional Logic
+
+1. **Always Define Referenced Fields**: Every field referenced in a rule condition must exist in the schema
+2. **Use Simple Conditions**: Prefer `const` and `enum` over complex schema conditions
+3. **Test All Conditions**: Verify rules work for all possible field values
+4. **Avoid Circular Dependencies**: Don't create rules that depend on each other
+5. **Document Complex Logic**: Comment complex conditional logic in your form specifications
+
+## Advanced Features
+
+### Multimedia Capture
+
+Forms can include fields for capturing photos, audio, and video. These are handled as attachments and synchronized separately from observation metadata.
+
+### Location Capture
+
+GPS coordinates can be captured automatically or manually entered.
+
+### File Attachments
+
+Files can be attached to observations and are synchronized separately from the observation data.
+
+## Form Versioning
+
+Forms support versioning to allow updates while maintaining compatibility with existing observations. When editing an observation, the form version used to create it is used.
+
+## Form Design Best Practices by Application Type
+
+Different application types have different requirements and constraints. Follow these best practices for your specific use case.
+
+### Research Data Collection
+
+**Characteristics**: Structured data collection, often longitudinal, requires high data quality.
+
+**Best Practices:**
+1. **Use Clear Field Names**: Use descriptive, research-standard field names (e.g., `participant_id`, `visit_date`)
+2. **Implement Validation**: Strict validation rules to ensure data quality
+3. **Version Control**: Carefully version forms to maintain data consistency
+4. **Minimize Required Fields**: Only require essential fields to reduce data entry burden
+5. **Use Conditional Logic**: Show relevant fields based on participant characteristics
+6. **Document Changes**: Maintain detailed changelog for form versions
+
+**Example Pattern:**
+```json
+{
+ "schema": {
+ "properties": {
+ "participant_id": {
+ "type": "string",
+ "title": "Participant ID",
+ "pattern": "^P-[0-9]{4}$"
+ },
+ "visit_number": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 10
+ }
+ },
+ "required": ["participant_id", "visit_number"]
+ }
+}
+```
+
+### Medical / Clinical Records
+
+**Characteristics**: Sensitive data, regulatory compliance, complex workflows.
+
+**Best Practices:**
+1. **Consent Management**: Always include consent fields with clear labels
+2. **Date/Time Precision**: Use precise date-time fields for clinical events
+3. **Signature Requirements**: Use signature fields for consent and approvals
+4. **Photo Documentation**: Use photo fields for wound tracking, skin conditions, etc.
+5. **Structured Data**: Use enums for standardized values (e.g., diagnosis codes)
+6. **Audit Trail**: Forms should capture who, what, when for audit purposes
+7. **HIPAA/GDPR Compliance**: Ensure forms comply with data protection regulations
+
+**Example Pattern:**
+```json
+{
+ "schema": {
+ "properties": {
+ "consent_obtained": {
+ "type": "boolean",
+ "title": "Patient consent obtained"
+ },
+ "consent_signature": {
+ "type": "object",
+ "format": "signature",
+ "title": "Patient signature"
+ },
+ "visit_date": {
+ "type": "string",
+ "format": "date-time",
+ "title": "Visit date and time"
+ }
+ },
+ "required": ["consent_obtained", "consent_signature", "visit_date"]
+ }
+}
+```
+
+### Surveys with Consent
+
+**Characteristics**: User-facing, requires clear consent, may be anonymous.
+
+**Best Practices:**
+1. **Consent First**: Place consent fields at the beginning of the form
+2. **Clear Language**: Use plain language, avoid jargon
+3. **Progress Indicators**: Show progress to encourage completion
+4. **Optional Fields**: Mark optional fields clearly
+5. **Privacy Notice**: Include privacy information if collecting personal data
+6. **Thank You Message**: Provide confirmation after submission
+
+**Example Pattern:**
+```json
+{
+ "uischema": {
+ "type": "SwipeLayout",
+ "elements": [
+ {
+ "type": "VerticalLayout",
+ "elements": [
+ {
+ "type": "Label",
+ "text": "Consent and Privacy"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/consent_read",
+ "label": "I have read and understood the consent form"
+ },
+ {
+ "type": "Control",
+ "scope": "#/properties/consent_agreed",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/consent_read",
+ "schema": { "const": true }
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+}
+```
+
+### Longitudinal Forms
+
+**Characteristics**: Same form used multiple times, data comparison over time.
+
+**Best Practices:**
+1. **Consistent Structure**: Maintain consistent field structure across versions
+2. **Version Tracking**: Track which version was used for each observation
+3. **Baseline Data**: Include baseline measurement fields
+4. **Change Detection**: Use conditional logic to highlight changes
+5. **Date Tracking**: Always include date/time fields for temporal analysis
+6. **Backward Compatibility**: Ensure new versions don't break existing data
+
+**Example Pattern:**
+```json
+{
+ "schema": {
+ "properties": {
+ "measurement_date": {
+ "type": "string",
+ "format": "date",
+ "title": "Measurement Date"
+ },
+ "baseline_value": {
+ "type": "number",
+ "title": "Baseline Value"
+ },
+ "current_value": {
+ "type": "number",
+ "title": "Current Value"
+ },
+ "change_from_baseline": {
+ "type": "number",
+ "title": "Change from Baseline",
+ "readOnly": true // Calculated field
+ }
+ }
+ }
+}
+```
+
+### General Best Practices
+
+**Form Structure:**
+1. **Keep Forms Focused**: Each form should have a clear, single purpose
+2. **Logical Grouping**: Group related fields together using Groups or separate pages
+3. **Progressive Disclosure**: Use conditional logic to show fields only when relevant
+4. **Clear Navigation**: Use SwipeLayout for multi-step forms with clear progress indicators
+
+**Field Design:**
+1. **Use Clear Labels**: Field labels should be descriptive and unambiguous
+2. **Provide Help Text**: Use descriptions or placeholders to guide users
+3. **Validate Input**: Use validation rules to catch errors early
+4. **Use Appropriate Types**: Choose the right field type for the data (date picker for dates, not text)
+
+**Data Quality:**
+1. **Required Fields**: Only require truly essential fields
+2. **Default Values**: Provide sensible defaults when appropriate
+3. **Enum Constraints**: Use enums for fields with limited valid values
+4. **Format Validation**: Use format validation (email, date, etc.) when applicable
+
+**Testing:**
+1. **Test All Paths**: Test all conditional logic branches
+2. **Test Validation**: Verify validation rules work correctly
+3. **Test on Devices**: Test on actual mobile devices, not just emulators
+4. **Test Offline**: Verify forms work correctly in offline mode
+5. **User Testing**: Get feedback from actual users before deployment
+
+## Validating Forms Before Deployment
+
+Validating forms before deployment prevents errors and ensures forms work correctly in production. This section covers validation tools and workflows.
+
+### Validation Tools
+
+#### Form Validation Script
+
+ODE provides a validation script (`validate-forms.js`) that checks forms for common issues:
+
+**Usage:**
+```bash
+npm run validate:forms
+```
+
+**Checks Performed:**
+- JSON Schema syntax validation
+- UI Schema format validation
+- Field reference validation (scope paths exist in schema)
+- Required field validation
+- Conditional logic validation (rule scopes exist)
+- SwipeLayout structure validation
+
+**Common Validation Failures:**
+
+1. **Invalid JSON Schema:**
+ ```
+ Error: Schema validation failed
+ - Property "minimum" must be a number
+ ```
+ **Fix**: Ensure `minimum`/`maximum` use literal numbers, not `$data` references
+
+2. **Missing Scope:**
+ ```
+ Error: Scope "#/properties/missingField" not found in schema
+ ```
+ **Fix**: Add the referenced field to the schema or correct the scope path
+
+3. **Invalid UI Schema Structure:**
+ ```
+ Error: SwipeLayout missing required "elements" array
+ ```
+ **Fix**: Ensure SwipeLayout has an `elements` array (can be empty)
+
+4. **Rule Scope Error:**
+ ```
+ Error: Rule condition scope "#/properties/field" not found
+ ```
+ **Fix**: Ensure all fields referenced in rules exist in the schema
+
+### CI Integration
+
+Integrate form validation into your CI/CD pipeline:
+
+**GitHub Actions Example:**
+```yaml
+name: Validate Forms
+
+on: [push, pull_request]
+
+jobs:
+ validate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v2
+ with:
+ node-version: '18'
+ - run: npm install
+ - run: npm run validate:forms
+```
+
+**GitLab CI Example:**
+```yaml
+validate_forms:
+ script:
+ - npm install
+ - npm run validate:forms
+```
+
+### Recommended Workflow
+
+1. **Local Validation**: Run validation script before committing changes
+2. **Pre-commit Hooks**: Set up git hooks to validate forms automatically
+3. **CI Validation**: Include validation in CI pipeline to catch errors early
+4. **Manual Testing**: Test forms on actual devices before deployment
+5. **Staging Deployment**: Deploy to staging environment and test thoroughly
+6. **Production Deployment**: Only deploy validated, tested forms
+
+### Validation Checklist
+
+Before deploying a form, verify:
+
+- [ ] JSON Schema is valid JSON Schema Draft 7
+- [ ] All scope paths in UI schema exist in JSON schema
+- [ ] SwipeLayout is root element (or will be auto-wrapped)
+- [ ] All rule condition scopes exist in schema
+- [ ] No `$data` references used
+- [ ] No `if/then/else` in rule conditions
+- [ ] All required fields are clearly marked
+- [ ] Validation rules use literal values (not dynamic)
+- [ ] Media field types have correct schema structure
+- [ ] Form tested on actual mobile devices
+- [ ] Form tested in offline mode
+- [ ] All conditional logic paths tested
+
+### Troubleshooting Validation Errors
+
+**"minimum value must be ['number']"**
+- **Cause**: Using `$data` or non-numeric value in `minimum`
+- **Fix**: Use literal number: `"minimum": 0`
+
+**"Cannot read properties of undefined (reading 'find')"**
+- **Cause**: Layout missing `elements` array, invalid scope, or rule referencing missing field
+- **Fix**:
+ - Add `elements: []` to layouts
+ - Validate all scope paths exist
+ - Ensure rule scopes reference existing fields
+
+**"Rule condition scope not found"**
+- **Cause**: Rule references field that doesn't exist in schema
+- **Fix**: Add the referenced field to schema or correct the scope path
+
+## Related Documentation
+
+- [Form Specifications Reference](/reference/form-specifications)
+- [Formplayer Supported Schema & UI Profile](/reference/formplayer#supported-schema--ui-profile)
+- [Formplayer Errors Explained](/using/troubleshooting#formplayer-errors)
+- [Your First Form](/using/your-first-form)
+- [Custom Applications](/guides/custom-applications)
+
diff --git a/versioned_docs/version-1.0/guides/index.md b/versioned_docs/version-1.0/guides/index.md
new file mode 100644
index 0000000..159b8f1
--- /dev/null
+++ b/versioned_docs/version-1.0/guides/index.md
@@ -0,0 +1,61 @@
+---
+sidebar_position: 0
+---
+
+# Guides
+
+Step-by-step guides for common tasks and workflows in ODE.
+
+## Form Design & Configuration
+
+
+
+
+
+
Form Design
+
+
+
Complete guide to designing forms, including schema definitions and validation rules.
+}
+```
+
+### AuthContext Methods
+
+- `login(credentials)`: Authenticate user
+- `logout()`: Clear authentication
+- `refreshAuth()`: Refresh expired tokens
+
+## Styling
+
+### Design Tokens
+
+The portal uses ODE design tokens:
+
+- **Primary Color**: Green (#4F7F4E)
+- **Secondary Color**: Gold (#E9B85B)
+- **Typography**: Noto Sans
+- **Spacing**: Consistent spacing scale
+
+### CSS Structure
+
+- **Global Styles**: `src/index.css`
+- **Component Styles**: Component-specific CSS files
+- **No Framework**: Plain CSS (can extend with CSS modules)
+
+## Best Practices
+
+### Code Organization
+
+1. **Types First**: Define TypeScript types
+2. **API Service**: Centralize API calls
+3. **Context for State**: Use Context for global state
+4. **Component Separation**: Separate components and pages
+
+### Error Handling
+
+1. **Try-Catch Blocks**: Wrap API calls
+2. **User-Friendly Messages**: Show clear error messages
+3. **Error Logging**: Log errors for debugging
+4. **Graceful Degradation**: Handle errors gracefully
+
+### Performance
+
+1. **Code Splitting**: Lazy load components
+2. **Memoization**: Memoize expensive computations
+3. **Optimistic Updates**: Update UI before server response
+4. **Debouncing**: Debounce search and filter inputs
+
+## Troubleshooting
+
+### Common Issues
+
+**Portal Won't Load:**
+- Check backend is running
+- Verify API URL configuration
+- Check browser console for errors
+
+**Authentication Fails:**
+- Verify credentials
+- Check JWT_SECRET on server
+- Clear localStorage and retry
+
+**API Calls Fail:**
+- Check network connectivity
+- Verify CORS configuration
+- Check server logs
+
+## Related Documentation
+
+- [Synkronus Server Reference](/reference/synkronus-server) - Backend API
+- [Deployment Guide](/guides/deployment) - Production deployment
+- [Configuration Guide](/guides/configuration) - Configuration options
+- [API Reference](/reference/api) - Complete API documentation
+
diff --git a/versioned_docs/version-1.0/reference/synkronus-server.md b/versioned_docs/version-1.0/reference/synkronus-server.md
new file mode 100644
index 0000000..5d8398c
--- /dev/null
+++ b/versioned_docs/version-1.0/reference/synkronus-server.md
@@ -0,0 +1,484 @@
+---
+sidebar_position: 8
+---
+
+# Synkronus Server Reference
+
+Complete technical reference for the Synkronus server component.
+
+## Overview
+
+Synkronus is a robust synchronization API server built with Go. It provides RESTful endpoints for data synchronization, app bundle management, attachment handling, user management, and form specifications. The server uses PostgreSQL for data storage and JWT for authentication.
+
+## Architecture
+
+### Technology Stack
+
+- **Language**: Go 1.22+
+- **Database**: PostgreSQL 12+
+- **Authentication**: JWT (JSON Web Tokens)
+- **API**: RESTful HTTP API
+- **Documentation**: OpenAPI 3.0 specification
+
+### Project Structure
+
+```
+synkronus/
+├── cmd/synkronus/ # Application entry point
+├── internal/ # Private application code
+│ ├── api/ # API definition and OpenAPI integration
+│ ├── handlers/ # HTTP request handlers
+│ ├── models/ # Domain models
+│ ├── repository/ # Data access layer
+│ └── services/ # Business logic
+└── pkg/ # Public libraries
+ ├── auth/ # Authentication utilities
+ ├── database/ # Database connection and migrations
+ ├── logger/ # Structured logging
+ ├── middleware/ # HTTP middleware
+ └── openapi/ # OpenAPI generated code
+```
+
+## Core Features
+
+### Data Synchronization
+
+- **Bidirectional Sync**: Push and pull operations
+- **Incremental Updates**: Only sync changed data
+- **Conflict Resolution**: Version-based conflict handling
+- **Client Tracking**: Track client sync state
+
+### App Bundle Management
+
+- **Version Control**: Multiple bundle versions
+- **Activation**: Switch active bundle version
+- **File Serving**: Serve bundle files to clients
+- **Manifest Generation**: Automatic manifest creation
+
+### Attachment Handling
+
+- **Binary Storage**: Store attachments separately from observations
+- **Immutable Attachments**: Once uploaded, cannot be modified
+- **Efficient Transfer**: Optimized for large files
+- **Manifest System**: Track attachment changes
+
+### User Management
+
+- **JWT Authentication**: Secure token-based auth
+- **Role-Based Access**: read-only, read-write, admin roles
+- **User CRUD**: Create, read, update, delete users
+- **Password Management**: Secure password handling
+
+### Form Specifications
+
+- **Versioned Forms**: Multiple versions per form type
+- **Schema Storage**: Store JSON schemas
+- **UI Schema Support**: Store UI layout definitions
+- **Version Negotiation**: Client requests specific versions
+
+## API Endpoints
+
+### Authentication
+
+#### POST /auth/login
+
+Authenticate user and receive JWT token.
+
+**Request:**
+```json
+{
+ "username": "user",
+ "password": "password"
+}
+```
+
+**Response:**
+```json
+{
+ "token": "eyJhbGciOiJIUzI1NiIs...",
+ "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
+ "expiresIn": 3600
+}
+```
+
+#### POST /auth/refresh
+
+Refresh expired JWT token.
+
+**Request:**
+```json
+{
+ "refreshToken": "eyJhbGciOiJIUzI1NiIs..."
+}
+```
+
+### Synchronization
+
+#### POST /sync/pull
+
+Pull changes from server.
+
+**Request:**
+```json
+{
+ "clientId": "client-123",
+ "currentVersion": 100,
+ "schemaTypes": ["survey", "visit"]
+}
+```
+
+**Response:**
+```json
+{
+ "changes": {
+ "observations": [...]
+ },
+ "timestamp": 150
+}
+```
+
+#### POST /sync/push
+
+Push changes to server.
+
+**Request:**
+```json
+{
+ "clientId": "client-123",
+ "changes": {
+ "observations": [...]
+ }
+}
+```
+
+**Response:**
+```json
+{
+ "timestamp": 150,
+ "conflicts": []
+}
+```
+
+### App Bundles
+
+#### GET /app-bundle/manifest
+
+Get current app bundle manifest.
+
+**Response:**
+```json
+{
+ "version": "20250114-123456",
+ "files": [...],
+ "hash": "abc123..."
+}
+```
+
+#### GET `/app-bundle/download/{path}`
+
+Download app bundle file.
+
+**Path Parameters:**
+- `path`: File path within bundle
+
+#### POST /app-bundle/push
+
+Upload new app bundle (admin only).
+
+**Request:** Multipart form with `bundle` file
+
+**Response:**
+```json
+{
+ "version": "20250114-123456",
+ "manifest": {...}
+}
+```
+
+#### GET /app-bundle/versions
+
+List all app bundle versions.
+
+#### POST /app-bundle/switch
+
+Switch active bundle version (admin only).
+
+### Attachments
+
+#### GET /attachments/manifest
+
+Get attachment manifest.
+
+**Query Parameters:**
+- `since`: Timestamp to get changes since
+
+#### GET `/attachments/{id}`
+
+Download attachment file.
+
+#### POST /attachments
+
+Upload attachment (multipart form).
+
+### Form Specifications
+
+#### GET `/formspecs/{formType}/{version}`
+
+Get form specification.
+
+**Path Parameters:**
+- `formType`: Form type identifier
+- `version`: Form version
+
+#### POST /formspecs
+
+Create form specification (admin only).
+
+### Users
+
+#### GET /users
+
+List all users (admin only).
+
+#### POST /users/create
+
+Create new user (admin only).
+
+#### GET `/users/{username}`
+
+Get user details.
+
+#### PUT `/users/{username}`
+
+Update user (admin only).
+
+#### DELETE `/users/{username}`
+
+Delete user (admin only).
+
+### Data Export
+
+#### GET /data/export
+
+Export observations as Parquet ZIP.
+
+**Query Parameters:**
+- `format`: Export format (parquet, json, csv)
+
+## Configuration
+
+### Environment Variables
+
+| Variable | Description | Default | Required |
+|----------|-------------|---------|----------|
+| `PORT` | HTTP server port | `8080` | No |
+| `DB_CONNECTION` | PostgreSQL connection string | - | Yes |
+| `JWT_SECRET` | Secret for JWT signing | - | Yes |
+| `LOG_LEVEL` | Logging level (debug, info, warn, error) | `info` | No |
+| `APP_BUNDLE_PATH` | Directory for app bundles | `./data/app-bundles` | No |
+| `MAX_VERSIONS_KEPT` | Maximum bundle versions to keep | `5` | No |
+| `ADMIN_USERNAME` | Initial admin username | `admin` | No |
+| `ADMIN_PASSWORD` | Initial admin password | `admin` | No |
+
+### Example Configuration
+
+```bash
+PORT=8080
+DB_CONNECTION=postgres://user:password@localhost:5432/synkronus?sslmode=disable
+JWT_SECRET=your-secret-key-change-this-in-production
+LOG_LEVEL=info
+APP_BUNDLE_PATH=./data/app-bundles
+MAX_VERSIONS_KEPT=5
+ADMIN_USERNAME=admin
+ADMIN_PASSWORD=admin
+```
+
+## Database Schema
+
+### Observations Table
+
+| Column | Type | Description |
+|--------|------|-------------|
+| `id` | UUID | Primary key |
+| `form_type` | VARCHAR | Form type identifier |
+| `data` | JSONB | Observation data |
+| `created_at` | TIMESTAMP | Creation timestamp |
+| `updated_at` | TIMESTAMP | Last update timestamp |
+| `deleted` | BOOLEAN | Soft delete flag |
+| `version` | INTEGER | Version number (auto-increment) |
+
+### Users Table
+
+| Column | Type | Description |
+|--------|------|-------------|
+| `id` | UUID | Primary key |
+| `username` | VARCHAR | Unique username |
+| `password_hash` | VARCHAR | Hashed password |
+| `role` | VARCHAR | User role (read-only, read-write, admin) |
+| `created_at` | TIMESTAMP | Creation timestamp |
+
+### App Bundle Versions Table
+
+| Column | Type | Description |
+|--------|------|-------------|
+| `version` | VARCHAR | Version identifier |
+| `is_active` | BOOLEAN | Active version flag |
+| `created_at` | TIMESTAMP | Creation timestamp |
+
+## Synchronization Protocol
+
+### Two-Phase Sync
+
+#### Phase 1: Observation Sync
+
+1. Client requests changes via `/sync/pull`
+2. Server returns observations changed since client's version
+3. Client applies changes locally
+4. Client pushes local changes via `/sync/push`
+5. Server applies changes and returns new version
+
+#### Phase 2: Attachment Sync
+
+1. Client requests attachment manifest
+2. Server returns list of attachments to download
+3. Client downloads missing attachments
+4. Client uploads pending attachments
+5. Server confirms receipt
+
+### Conflict Resolution
+
+Conflicts are detected when:
+
+- Same observation modified on multiple clients
+- Observation deleted on one client, modified on another
+
+Resolution strategy:
+
+- **Last Write Wins**: Most recent change wins
+- **Version Tracking**: Version numbers prevent conflicts
+- **Client Responsibility**: Clients handle conflict resolution
+
+## Security
+
+### Authentication
+
+- **JWT Tokens**: Secure token-based authentication
+- **Token Expiration**: Tokens expire after configured time
+- **Refresh Tokens**: Long-lived refresh tokens
+- **Password Hashing**: bcrypt password hashing
+
+### Authorization
+
+- **Role-Based Access**: Three roles (read-only, read-write, admin)
+- **Endpoint Protection**: Middleware protects admin endpoints
+- **Token Validation**: All requests validate JWT tokens
+
+### Data Protection
+
+- **HTTPS**: Recommended for production
+- **Input Validation**: All inputs validated
+- **SQL Injection Prevention**: Parameterized queries
+- **XSS Protection**: Input sanitization
+
+## Deployment
+
+### Docker Deployment
+
+See [Deployment Guide](/guides/deployment) for complete deployment instructions.
+
+### Quick Start
+
+```bash
+docker compose up -d
+```
+
+### Production Setup
+
+1. Configure environment variables
+2. Set up PostgreSQL database
+3. Configure reverse proxy (Nginx)
+4. Set up SSL/TLS certificates
+5. Configure monitoring and logging
+
+## Monitoring
+
+### Health Check
+
+```bash
+curl http://localhost:8080/health
+```
+
+Returns `OK` if server is healthy.
+
+### Logging
+
+Structured logging with levels:
+
+- **Debug**: Detailed debugging information
+- **Info**: General informational messages
+- **Warn**: Warning messages
+- **Error**: Error messages
+
+### Metrics
+
+Key metrics to monitor:
+
+- Request rate
+- Response times
+- Error rates
+- Database connection pool
+- Active sync operations
+
+## Performance
+
+### Optimization Strategies
+
+- **Connection Pooling**: PostgreSQL connection pool
+- **Query Optimization**: Indexed database queries
+- **Caching**: Cache app bundle manifests
+- **Compression**: Compress responses when possible
+
+### Scaling
+
+- **Horizontal Scaling**: Multiple server instances
+- **Load Balancing**: Distribute requests across instances
+- **Database Replication**: Read replicas for database
+- **CDN**: Serve static files via CDN
+
+## Troubleshooting
+
+### Common Issues
+
+**Database Connection Errors:**
+- Verify PostgreSQL is running
+- Check connection string format
+- Verify database exists
+- Check user permissions
+
+**Authentication Failures:**
+- Verify JWT_SECRET is set
+- Check token expiration
+- Verify user credentials
+
+**Sync Failures:**
+- Check database connectivity
+- Verify client version tracking
+- Review server logs
+
+## API Versioning
+
+The API supports versioning via the `x-api-version` header:
+
+```http
+x-api-version: 1.0.0
+```
+
+Version negotiation allows clients to request specific API versions.
+
+## Related Documentation
+
+- [API Reference](/reference/api) - Complete API documentation
+- [Deployment Guide](/guides/deployment) - Production deployment
+- [Configuration Guide](/guides/configuration) - Configuration options
+- [Synkronus CLI Reference](/reference/synkronus-cli) - CLI tool
+
diff --git a/docs/technical-overview/_category_.json b/versioned_docs/version-1.0/technical-overview/_category_.json
similarity index 100%
rename from docs/technical-overview/_category_.json
rename to versioned_docs/version-1.0/technical-overview/_category_.json
diff --git a/docs/technical-overview/architecture/components.md b/versioned_docs/version-1.0/technical-overview/architecture/components.md
similarity index 100%
rename from docs/technical-overview/architecture/components.md
rename to versioned_docs/version-1.0/technical-overview/architecture/components.md
diff --git a/docs/technical-overview/architecture/data-flow.md b/versioned_docs/version-1.0/technical-overview/architecture/data-flow.md
similarity index 100%
rename from docs/technical-overview/architecture/data-flow.md
rename to versioned_docs/version-1.0/technical-overview/architecture/data-flow.md
diff --git a/docs/technical-overview/architecture/overview.md b/versioned_docs/version-1.0/technical-overview/architecture/overview.md
similarity index 100%
rename from docs/technical-overview/architecture/overview.md
rename to versioned_docs/version-1.0/technical-overview/architecture/overview.md
diff --git a/docs/technical-overview/concepts/app-bundles.md b/versioned_docs/version-1.0/technical-overview/concepts/app-bundles.md
similarity index 100%
rename from docs/technical-overview/concepts/app-bundles.md
rename to versioned_docs/version-1.0/technical-overview/concepts/app-bundles.md
diff --git a/docs/technical-overview/concepts/custom-apps.md b/versioned_docs/version-1.0/technical-overview/concepts/custom-apps.md
similarity index 100%
rename from docs/technical-overview/concepts/custom-apps.md
rename to versioned_docs/version-1.0/technical-overview/concepts/custom-apps.md
diff --git a/docs/technical-overview/concepts/json-forms.md b/versioned_docs/version-1.0/technical-overview/concepts/json-forms.md
similarity index 100%
rename from docs/technical-overview/concepts/json-forms.md
rename to versioned_docs/version-1.0/technical-overview/concepts/json-forms.md
diff --git a/docs/technical-overview/concepts/offline-first.md b/versioned_docs/version-1.0/technical-overview/concepts/offline-first.md
similarity index 100%
rename from docs/technical-overview/concepts/offline-first.md
rename to versioned_docs/version-1.0/technical-overview/concepts/offline-first.md
diff --git a/docs/technical-overview/concepts/overview.md b/versioned_docs/version-1.0/technical-overview/concepts/overview.md
similarity index 100%
rename from docs/technical-overview/concepts/overview.md
rename to versioned_docs/version-1.0/technical-overview/concepts/overview.md
diff --git a/docs/technical-overview/database/overview.md b/versioned_docs/version-1.0/technical-overview/database/overview.md
similarity index 100%
rename from docs/technical-overview/database/overview.md
rename to versioned_docs/version-1.0/technical-overview/database/overview.md
diff --git a/docs/technical-overview/database/schema.md b/versioned_docs/version-1.0/technical-overview/database/schema.md
similarity index 100%
rename from docs/technical-overview/database/schema.md
rename to versioned_docs/version-1.0/technical-overview/database/schema.md
diff --git a/docs/technical-overview/index.md b/versioned_docs/version-1.0/technical-overview/index.md
similarity index 74%
rename from docs/technical-overview/index.md
rename to versioned_docs/version-1.0/technical-overview/index.md
index 13ce79e..d261f30 100644
--- a/docs/technical-overview/index.md
+++ b/versioned_docs/version-1.0/technical-overview/index.md
@@ -8,19 +8,18 @@ Overview and architecture of ODE components.
-
diff --git a/docs/tutorials/_category_.json b/versioned_docs/version-1.0/tutorials/_category_.json
similarity index 100%
rename from docs/tutorials/_category_.json
rename to versioned_docs/version-1.0/tutorials/_category_.json
diff --git a/docs/tutorials/advanced/complex-forms.md b/versioned_docs/version-1.0/tutorials/advanced/complex-forms.md
similarity index 100%
rename from docs/tutorials/advanced/complex-forms.md
rename to versioned_docs/version-1.0/tutorials/advanced/complex-forms.md
diff --git a/docs/tutorials/advanced/custom-renderers.md b/versioned_docs/version-1.0/tutorials/advanced/custom-renderers.md
similarity index 100%
rename from docs/tutorials/advanced/custom-renderers.md
rename to versioned_docs/version-1.0/tutorials/advanced/custom-renderers.md
diff --git a/docs/tutorials/advanced/performance.md b/versioned_docs/version-1.0/tutorials/advanced/performance.md
similarity index 100%
rename from docs/tutorials/advanced/performance.md
rename to versioned_docs/version-1.0/tutorials/advanced/performance.md
diff --git a/docs/tutorials/getting-started/connecting-everything.md b/versioned_docs/version-1.0/tutorials/getting-started/connecting-everything.md
similarity index 100%
rename from docs/tutorials/getting-started/connecting-everything.md
rename to versioned_docs/version-1.0/tutorials/getting-started/connecting-everything.md
diff --git a/docs/tutorials/getting-started/first-custom-app.md b/versioned_docs/version-1.0/tutorials/getting-started/first-custom-app.md
similarity index 100%
rename from docs/tutorials/getting-started/first-custom-app.md
rename to versioned_docs/version-1.0/tutorials/getting-started/first-custom-app.md
diff --git a/docs/tutorials/getting-started/first-form.md b/versioned_docs/version-1.0/tutorials/getting-started/first-form.md
similarity index 100%
rename from docs/tutorials/getting-started/first-form.md
rename to versioned_docs/version-1.0/tutorials/getting-started/first-form.md
diff --git a/docs/tutorials/index.md b/versioned_docs/version-1.0/tutorials/index.md
similarity index 70%
rename from docs/tutorials/index.md
rename to versioned_docs/version-1.0/tutorials/index.md
index 824afd1..da77fb9 100644
--- a/docs/tutorials/index.md
+++ b/versioned_docs/version-1.0/tutorials/index.md
@@ -12,34 +12,33 @@ Learn ODE through hands-on tutorials.
-
diff --git a/versioned_docs/version-1.0/using/.gitkeep b/versioned_docs/version-1.0/using/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/versioned_docs/version-1.0/using/app-bundles.md b/versioned_docs/version-1.0/using/app-bundles.md
new file mode 100644
index 0000000..ef90524
--- /dev/null
+++ b/versioned_docs/version-1.0/using/app-bundles.md
@@ -0,0 +1,176 @@
+---
+sidebar_position: 4
+---
+
+# Understanding App Bundles
+
+Learn how app bundles work in ODE and how they enable custom applications and forms.
+
+## What Are App Bundles?
+
+App bundles are packaged collections of files that define custom applications for ODE. They contain everything needed to run a custom data collection application within the Formulus mobile app:
+
+- **Custom web application** - HTML, CSS, and JavaScript files
+- **Form specifications** - JSON schemas defining data collection forms
+- **Configuration files** - Settings and metadata for the application
+- **Assets** - Images, fonts, and other resources
+
+When you open Formulus and connect to a Synkronus server, the app automatically downloads the current app bundle. This bundle determines what forms are available, how they look, and what workflows you can use.
+
+## How App Bundles Work
+
+### Download Process
+
+1. **Initial Sync**: When you first log in to Formulus, the app checks the server for the current app bundle version
+2. **Version Check**: The app compares the server's version with the version stored locally
+3. **Download**: If a new version is available, the app downloads the bundle files
+4. **Extraction**: The bundle is extracted and stored locally on your device
+5. **Activation**: The new bundle becomes active, and you can use the updated forms and features
+
+### Automatic Updates
+
+App bundles update automatically:
+
+- **On Login**: When you log in, the app checks for updates
+- **On Manual Sync**: When you tap "Sync Now" in the app
+- **Periodically**: The app may check for updates in the background (if configured)
+
+### Version Management
+
+Each app bundle has a version identifier (typically a timestamp). This ensures:
+
+- **Consistency**: All devices use the same version of forms and workflows
+- **Rollback**: Administrators can switch back to previous versions if needed
+- **Tracking**: You can see which version of the app bundle you're using
+
+## What's Inside an App Bundle
+
+### Custom Application
+
+The main component is a custom web application that runs inside Formulus. This application:
+
+- **Provides Navigation**: Custom menus and screens for your workflow
+- **Displays Forms**: Shows available forms and allows you to start data collection
+- **Manages Data**: Lets you view, edit, and manage your observations
+- **Custom Branding**: Can include your organization's logo and styling
+
+### Form Specifications
+
+App bundles include form definitions that specify:
+
+- **Data Fields**: What information to collect (name, age, location, etc.)
+- **Field Types**: How to input data (text, number, date, photo, GPS, etc.)
+- **Validation Rules**: Requirements for data entry (required fields, value ranges, etc.)
+- **Layout**: How the form is organized and presented
+
+### Configuration
+
+Bundles may include configuration files that:
+
+- **Define Settings**: Application-specific settings and preferences
+- **Specify Behavior**: How the application should behave in different scenarios
+- **Set Permissions**: What features and data access the application needs
+
+## Using App Bundles
+
+### Accessing Your Application
+
+1. **Open Formulus** on your device
+2. **Log in** to your account
+3. **Wait for sync** to complete (if first time or after update)
+4. **Your custom application** loads automatically as the main interface
+
+### Working with Forms
+
+Once the app bundle is loaded:
+
+1. **Navigate** through your custom application's interface
+2. **Select a form** from the available forms list
+3. **Fill out the form** with the required information
+4. **Submit** the form to create an observation
+5. **View observations** in your data management section
+
+### Updating App Bundles
+
+App bundles update automatically, but you can also manually trigger an update:
+
+1. **Open Formulus** → **Settings** → **Sync**
+2. **Tap "Sync Now"** or **"Force Download"**
+3. **Wait for download** to complete
+4. **App restarts** or refreshes with the new bundle
+
+## Troubleshooting App Bundles
+
+### Bundle Not Downloading
+
+**Problem**: App bundle fails to download or sync.
+
+**Solutions**:
+- Check internet connection
+- Verify server is accessible
+- Try manual sync: Settings → Sync → Sync Now
+- Clear app cache: Settings → Storage → Clear Cache
+- Restart the app
+
+### Forms Not Appearing
+
+**Problem**: After sync, forms don't appear in the app.
+
+**Solutions**:
+- Verify bundle downloaded successfully (check Sync screen)
+- Check bundle version matches server version
+- Try force refresh: Settings → Sync → Force Download
+- Clear app data and re-login (warning: deletes local data)
+
+### Outdated Forms
+
+**Problem**: Forms show old fields or structure.
+
+**Solutions**:
+- Check if bundle update is available: Settings → Sync
+- Force download latest bundle: Settings → Sync → Force Download
+- Verify server has the latest bundle version
+- Contact administrator if issue persists
+
+### Bundle Version Mismatch
+
+**Problem**: App shows different version than expected.
+
+**Solutions**:
+- Force sync to get latest version
+- Check server is serving the correct active version
+- Verify you're connected to the correct server
+- Contact administrator to verify bundle version
+
+## App Bundle Best Practices
+
+### For Users
+
+1. **Sync Regularly**: Keep your app bundle up to date by syncing regularly
+2. **Check Version**: Verify you're using the latest bundle version
+3. **Report Issues**: If forms or features don't work, report to your administrator
+4. **Backup Data**: Ensure observations are synced before major updates
+
+### For Administrators
+
+1. **Test Before Deploy**: Test new bundles thoroughly before activating
+2. **Version Control**: Use clear version identifiers (timestamps recommended)
+3. **Rollback Plan**: Keep previous versions available for quick rollback
+4. **Notify Users**: Inform users when major updates are deployed
+5. **Monitor Usage**: Track which versions are in use across devices
+
+## Technical Details
+
+For technical information about app bundle structure, format, and development, see:
+
+- [App Bundle Format Reference](/reference/app-bundle-format) - Technical specification
+- [Custom Applications Guide](/guides/custom-applications) - Building custom applications
+- [Form Design Guide](/guides/form-design) - Creating form specifications
+
+## Related Documentation
+
+- [Your First Form](/using/your-first-form) - Get started with data collection
+- [Synchronization](/using/synchronization) - Understand how data syncs
+- [Formulus Features](/using/formulus-features) - Complete app feature guide
+- [Working Offline](/using/working-offline) - Offline capabilities
+
diff --git a/versioned_docs/version-1.0/using/custom-applications.md b/versioned_docs/version-1.0/using/custom-applications.md
new file mode 100644
index 0000000..13c208a
--- /dev/null
+++ b/versioned_docs/version-1.0/using/custom-applications.md
@@ -0,0 +1,115 @@
+---
+sidebar_position: 3
+---
+
+# Custom Applications
+
+Custom applications are web-based interfaces that run within the Formulus mobile app, providing specialized workflows and user experiences.
+
+## Overview
+
+Custom applications allow you to:
+
+- Create custom navigation and user interfaces
+- Integrate with the ODE form system
+- Access observation data through the Formulus JavaScript interface
+- Build specialized workflows for specific use cases
+
+## How Custom Applications Work
+
+Custom applications are defined in app bundles, which include:
+
+- HTML, CSS, and JavaScript files
+- Form specifications
+- Custom renderers
+- Configuration files
+
+The app bundle is uploaded to the Synkronus server and downloaded by mobile devices during synchronization. When a user opens a custom application, it runs in a WebView within the Formulus app.
+
+## Formulus JavaScript Interface
+
+Custom applications interact with Formulus through a JavaScript interface:
+
+```javascript
+// Create a new observation
+window.formulus.addObservation(formType, initializationData);
+
+// Edit an existing observation
+window.formulus.editObservation(formType, observationId);
+
+// Delete an observation
+window.formulus.deleteObservation(formType, observationId);
+```
+
+## Creating a Custom Application
+
+Custom applications are web-based interfaces that run within the Formulus mobile app. They integrate with ODE through the Formulus JavaScript interface.
+
+### Basic Structure
+
+A custom application consists of:
+
+1. **HTML file**: Main entry point (typically `index.html`)
+2. **JavaScript**: Application logic using the Formulus API
+3. **CSS**: Styling for the application
+4. **Manifest**: Bundle metadata
+
+### Getting Started
+
+1. **Include Formulus Load Script**:
+
+```html
+
+```
+
+2. **Initialize the API**:
+
+```javascript
+async function init() {
+ const api = await getFormulus();
+ // Use the API
+}
+```
+
+3. **Use Formulus Methods**:
+
+```javascript
+// Create observation
+await api.addObservation('form-type', {});
+
+// Edit observation
+await api.editObservation('form-type', 'observation-id');
+```
+
+### Packaging
+
+Package your application as a ZIP file with:
+- `index.html` (or your entry point)
+- `manifest.json`
+- All assets (CSS, JS, images)
+
+### Deployment
+
+Upload the bundle to your Synkronus server:
+
+```bash
+synk app-bundle upload bundle.zip --activate
+```
+
+See the [Custom Applications guide](/guides/custom-applications) for detailed instructions on building and deploying custom applications.
+
+## Use Cases
+
+Custom applications are suitable for:
+
+- Specialized data collection workflows
+- Custom user interfaces that match organizational branding
+- Integration with external systems
+- Complex navigation requirements
+
+## Next Steps
+
+- Read the [Custom Applications guide](/guides/custom-apps/overview) for detailed information
+- Learn about [app bundle structure](/guides/custom-apps/app-bundle-structure)
+- Explore [custom renderers](/guides/custom-apps/custom-renderers)
+
diff --git a/versioned_docs/version-1.0/using/data-management.md b/versioned_docs/version-1.0/using/data-management.md
new file mode 100644
index 0000000..75be39f
--- /dev/null
+++ b/versioned_docs/version-1.0/using/data-management.md
@@ -0,0 +1,105 @@
+---
+sidebar_position: 4
+---
+
+# Data Management
+
+This guide covers viewing, editing, and managing observations in ODE.
+
+## Viewing Observations
+
+Observations can be viewed in the Formulus app:
+
+1. Navigate to the observations list
+2. Filter observations by form type, date, or sync status
+3. Select an observation to view details
+4. Review the form data and metadata
+
+## Editing Observations
+
+To edit an observation:
+
+1. Open the observation from the list
+2. Select the edit option
+3. Modify the form fields as needed
+4. Save your changes
+
+Edited observations are marked for synchronization and will be updated on the server during the next sync operation.
+
+## Deleting Observations
+
+Observations can be deleted:
+
+1. Open the observation
+2. Select the delete option
+3. Confirm the deletion
+
+Deleted observations are marked as deleted locally and synchronized to the server. The server maintains a record of deleted observations for audit purposes.
+
+## Filtering and Searching
+
+The observations list supports filtering by:
+
+- Form type
+- Date range
+- Sync status (synced, pending, error)
+- Custom criteria based on form data
+
+## Exporting Data
+
+Data can be exported from the server using multiple methods:
+
+
+
+
+Export all observations as a Parquet ZIP archive:
+
+```bash
+synk data export exports.zip
+```
+
+Export to different formats:
+
+```bash
+# Parquet (default)
+synk data export observations.zip
+
+# JSON
+synk data export observations.json --format json
+
+# CSV
+synk data export observations.csv --format csv
+```
+
+
+
+
+```bash
+curl -X GET http://your-server:8080/api/dataexport/parquet \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -o observations.zip
+```
+
+
+
+
+1. Navigate to the Portal
+2. Go to the "Data Export" section
+3. Select export format (Parquet, JSON, CSV)
+4. Click "Export" to download
+
+
+
+
+The export includes all observations in the selected format, organized by schema type. See the [API Reference](/reference/api) for details.
+
+## Data Synchronization
+
+Observations are synchronized between devices and the server automatically. See [Synchronization](/using/synchronization) for details on how synchronization works.
+
+## Next Steps
+
+- Learn about [synchronization](/using/synchronization) in detail
+- Review the [API Reference](/reference/api/endpoints) for programmatic access
+- Explore [data export options](/reference/api/endpoints) for analysis
+
diff --git a/versioned_docs/version-1.0/using/formulus-features.md b/versioned_docs/version-1.0/using/formulus-features.md
new file mode 100644
index 0000000..eda4e64
--- /dev/null
+++ b/versioned_docs/version-1.0/using/formulus-features.md
@@ -0,0 +1,374 @@
+---
+sidebar_position: 5
+---
+
+# Formulus Features
+
+Complete user guide for the Formulus mobile application features and capabilities.
+
+## Overview
+
+Formulus is an offline-first mobile data collection application that enables field workers to collect structured data in environments with limited or no connectivity. The app works seamlessly with custom applications and provides comprehensive data collection capabilities.
+
+## Core Features
+
+### Offline-First Architecture
+
+Formulus is designed to work completely offline:
+
+- **Local Storage**: All data is stored locally on your device using WatermelonDB
+- **Offline Forms**: Fill out forms without internet connection
+- **Automatic Sync**: Data syncs automatically when connectivity is restored
+- **No Data Loss**: Observations are saved locally even if sync fails
+
+### Custom Application Support
+
+Formulus can host custom web applications:
+
+- **Custom Interfaces**: Run specialized workflows and user interfaces
+- **Branded Experience**: Display your organization's branding and styling
+- **Flexible Navigation**: Custom menus and navigation structures
+- **Integrated Forms**: Seamless integration with the form system
+
+### Rich Data Collection
+
+Support for various data types:
+
+- **Text Input**: Single and multi-line text fields
+- **Numbers**: Integer and decimal numeric values
+- **Dates and Times**: Date pickers, time selectors, and datetime fields
+- **Selections**: Single choice dropdowns and multi-select checkboxes
+- **Media Capture**: Photos, audio recordings, and video
+- **Location**: GPS coordinates with accuracy information
+- **Signatures**: Digital signature capture
+- **Files**: File attachments and document uploads
+- **Barcodes**: QR code and barcode scanning
+
+### Synchronization
+
+Bidirectional data synchronization:
+
+- **Automatic Sync**: Syncs when network becomes available
+- **Manual Sync**: Trigger sync on demand
+- **Incremental Updates**: Only syncs changed data
+- **Conflict Resolution**: Automatically handles sync conflicts
+- **Attachment Handling**: Separate sync for binary files
+
+## App Navigation
+
+### Main Screens
+
+| Screen | Description | Access |
+|--------|-------------|--------|
+| **Home/Dashboard** | Overview and quick actions | Default screen after login |
+| **Forms** | List of available forms | Bottom tab or menu |
+| **Observations** | Saved data records | Bottom tab or menu |
+| **Sync** | Sync status and actions | Bottom tab or menu |
+| **Settings** | App configuration | Menu or gear icon |
+
+### Navigation Elements
+
+- **Bottom Tabs**: Quick access to main sections
+- **Menu Drawer**: Swipe from left or tap hamburger icon (☰)
+- **Back Button**: Return to previous screen
+- **Floating Action Button**: Quick actions (+ button)
+
+## Working with Forms
+
+### Viewing Available Forms
+
+1. Navigate to the **Forms** screen
+2. View the list of available forms from the current app bundle
+3. Each form displays:
+ - Form name/title
+ - Description (if available)
+ - Icon (if configured)
+
+### Starting a New Form
+
+1. Tap on a form from the list
+2. Form opens in the form player
+3. Fill in fields as required
+4. Navigate through form sections using Next/Previous buttons or swiping
+
+### Form Field Types
+
+| Field Type | Description | Input Method |
+|------------|-------------|--------------|
+| **Text** | Single/multi-line text | Keyboard input |
+| **Number** | Numeric values | Number keyboard |
+| **Date** | Date selection | Date picker |
+| **Time** | Time selection | Time picker |
+| **Select** | Single choice | Dropdown/radio buttons |
+| **Multi-select** | Multiple choices | Checkboxes |
+| **Photo** | Camera capture | Camera interface |
+| **GPS** | Location capture | GPS sensor |
+| **Signature** | Digital signature | Touch drawing |
+| **Audio** | Voice recording | Microphone |
+| **Video** | Video recording | Camera |
+| **File** | File attachment | File picker |
+| **QR Code** | Scan QR/barcode | Camera scanner |
+
+### Form Navigation
+
+- **Swipe Left/Right**: Navigate between form sections
+- **Next/Previous Buttons**: Move through form step by step
+- **Progress Bar**: Shows completion status
+- **Section Tabs**: Jump to specific sections (if enabled)
+
+### Saving Forms
+
+#### Save as Draft
+
+1. Tap **"Save Draft"** at any time while filling the form
+2. Form is saved locally with current data
+3. Resume later from the Observations screen
+4. Draft status is shown in the observation list
+
+#### Submit/Finalize
+
+1. Complete all required fields
+2. Tap **"Submit"** or **"Finalize"**
+3. Validation runs automatically - errors shown if any
+4. Observation saved as pending upload
+5. Will sync when connection is available
+
+### Form Validation
+
+Forms may include validation rules:
+
+- **Required Fields**: Must be filled before submission
+- **Format Validation**: Email, phone number, and other format checks
+- **Range Validation**: Minimum and maximum values
+- **Conditional Logic**: Fields shown based on other answers
+
+**Validation Errors:**
+- Red highlight on invalid fields
+- Error messages displayed below fields
+- Cannot submit until all errors are resolved
+
+## Managing Observations
+
+### Viewing Observations
+
+1. Navigate to the **Observations** screen
+2. View list of all saved observations
+3. Each entry shows:
+ - Form name
+ - Date/time created
+ - Status (draft, pending, synced)
+ - Key data fields
+
+### Observation Status
+
+| Status | Description |
+|--------|-------------|
+| **Draft** | Incomplete, can be edited |
+| **Pending** | Complete, awaiting sync |
+| **Syncing** | Currently uploading to server |
+| **Synced** | Successfully uploaded to server |
+| **Error** | Sync failed, retry needed |
+
+### Editing Observations
+
+#### Edit Draft
+
+1. Tap on a draft observation
+2. Form opens with saved data
+3. Make changes as needed
+4. Save or Submit
+
+#### Edit Pending (if allowed)
+
+1. Tap on a pending observation
+2. May need to "Unlock" for editing
+3. Make changes
+4. Re-submit
+
+### Deleting Observations
+
+1. Long-press on observation or tap menu (⋮)
+2. Select **"Delete"**
+3. Confirm deletion
+
+**Note**: Synced observations may not be deletable locally depending on configuration.
+
+## Synchronization
+
+### Automatic Sync
+
+The app automatically syncs when:
+
+- Network connection becomes available
+- App is opened (background sync)
+- Periodically (if configured in settings)
+
+### Manual Sync
+
+1. Navigate to **Sync** screen
+2. Tap **"Sync Now"**
+3. Watch progress - upload count and status
+4. Check results - success/failure messages
+
+### Sync Process
+
+1. **Pull**: Download new forms and server data
+2. **Push**: Upload pending observations
+3. **Attachments**: Upload photos, audio, and other files
+4. **Confirmation**: Server acknowledges receipt
+
+### Sync Indicators
+
+- **Sync Icon**: Appears in status bar when syncing
+- **Badge on Sync Tab**: Shows pending upload count
+- **Last Sync Time**: Displayed on sync screen
+- **Individual Status**: Each observation shows its sync status
+
+### Offline Mode
+
+When offline, you can:
+
+- ✅ Fill out forms
+- ✅ Save observations locally
+- ✅ View previously synced data
+- ❌ Cannot upload new data
+- ❌ Cannot download new forms
+
+Data syncs automatically when connection returns.
+
+## Attachments
+
+### Capturing Photos
+
+1. Tap photo field in form
+2. Camera opens automatically
+3. Take photo or select from gallery
+4. Review and confirm
+5. Photo is attached to observation
+
+### Capturing GPS Location
+
+1. Tap GPS field in form
+2. Location permission requested (first time only)
+3. Wait for GPS fix
+4. Coordinates captured (latitude, longitude, accuracy)
+5. May show map preview
+
+### Recording Audio
+
+1. Tap audio field in form
+2. Microphone permission requested (first time only)
+3. Tap record to start
+4. Speak clearly
+5. Tap stop when done
+6. Review and confirm
+
+### Capturing Signatures
+
+1. Tap signature field in form
+2. Signature pad opens
+3. Sign with finger on screen
+4. Tap "Done" to save
+5. Tap "Clear" to retry
+
+### Recording Video
+
+1. Tap video field in form
+2. Camera opens in video mode
+3. Tap record to start
+4. Tap stop when done
+5. Review and confirm
+
+### Scanning QR Codes
+
+1. Tap QR code field in form
+2. Camera opens in scanner mode
+3. Point camera at QR code
+4. Code is automatically scanned
+5. Data is populated in the field
+
+## Settings
+
+### Server Settings
+
+- **Server URL**: Synkronus server address
+- **Test Connection**: Verify connectivity to server
+- **Auto-login**: Automatically log in on app start
+
+### User Settings
+
+- **Username**: Current logged-in user
+- **Change Password**: Update account password
+- **Logout**: Clear session and return to login
+
+### Sync Settings
+
+- **Auto-sync**: Enable/disable automatic synchronization
+- **Sync on WiFi Only**: Save mobile data by syncing only on WiFi
+- **Sync Interval**: How often to check for sync (if auto-sync enabled)
+
+### App Settings
+
+- **Notifications**: Enable/disable push notifications
+- **Theme**: Light or dark mode
+- **Language**: App language selection
+- **Clear Cache**: Free up storage space
+- **Storage Info**: View storage usage
+
+## Best Practices
+
+### Data Collection
+
+1. **Sync Before Fieldwork**: Get latest forms and updates
+2. **Check Battery**: Ensure sufficient charge for field work
+3. **Test GPS Outdoors**: Better accuracy in open areas
+4. **Save Frequently**: Avoid data loss from app crashes
+5. **Sync When Possible**: Don't wait too long between syncs
+
+### Offline Work
+
+1. **Sync Before Going Offline**: Download latest forms and data
+2. **Save Observations as You Go**: Don't wait until the end
+3. **Check Pending Count**: Verify all data before leaving field
+4. **Sync Immediately**: When back online, sync right away
+
+### Data Quality
+
+1. **Fill All Required Fields**: Complete forms fully
+2. **Double-Check Entries**: Verify accuracy before submitting
+3. **Take Clear Photos**: Ensure photos are in focus and well-lit
+4. **Verify GPS Accuracy**: Check location accuracy before submitting
+5. **Review Before Submitting**: Review all data before final submission
+
+## Troubleshooting
+
+### Forms Not Loading
+
+- Check internet connection
+- Verify server is accessible
+- Try manual sync: Settings → Sync → Sync Now
+- Clear app cache: Settings → Storage → Clear Cache
+
+### Sync Failures
+
+- Check internet connection
+- Verify server URL is correct
+- Check server status
+- Try manual sync
+- Review error messages in Sync screen
+
+### App Crashes
+
+- Restart the app
+- Clear app cache
+- Update to latest version
+- Reinstall if issues persist
+
+## Related Documentation
+
+- [Installing Formulus](/getting-started/installing-formulus) - Installation guide
+- [Your First Form](/using/your-first-form) - Getting started with forms
+- [Synchronization](/using/synchronization) - Detailed sync information
+- [Working Offline](/using/working-offline) - Offline capabilities
+- [App Bundles](/using/app-bundles) - Understanding app bundles
+
diff --git a/versioned_docs/version-1.0/using/index.md b/versioned_docs/version-1.0/using/index.md
new file mode 100644
index 0000000..53a3102
--- /dev/null
+++ b/versioned_docs/version-1.0/using/index.md
@@ -0,0 +1,100 @@
+---
+sidebar_position: 0
+---
+
+# Using ODE
+
+Learn how to use ODE to create forms, manage data, and build custom applications.
+
+## Core Workflows
+
+
+
+
+
+
Your First Form
+
+
+
Create your first data collection form and learn the basics.
diff --git a/versioned_docs/version-1.0/using/synchronization.md b/versioned_docs/version-1.0/using/synchronization.md
new file mode 100644
index 0000000..ab56cf3
--- /dev/null
+++ b/versioned_docs/version-1.0/using/synchronization.md
@@ -0,0 +1,82 @@
+---
+sidebar_position: 5
+---
+
+# Synchronization
+
+Synchronization is the process of exchanging data between mobile devices and the Synkronus server.
+
+## How Synchronization Works
+
+ODE uses a bidirectional synchronization protocol:
+
+1. **Push**: Local observations are sent to the server
+2. **Pull**: New or updated observations are retrieved from the server
+3. **Conflict Resolution**: Conflicts are resolved automatically using version numbers
+
+## Synchronization Process
+
+### Automatic Synchronization
+
+Synchronization occurs automatically when:
+
+- The app is opened and network connectivity is available
+- A new observation is created or modified
+- A manual sync is triggered by the user
+- A scheduled sync interval elapses
+
+### Manual Synchronization
+
+Users can trigger manual synchronization:
+
+1. Open the app settings
+2. Navigate to synchronization options
+3. Select "Sync Now"
+4. Wait for the sync to complete
+
+## Conflict Resolution
+
+When the same observation is modified on multiple devices, ODE resolves conflicts automatically:
+
+- Each observation has a version number
+- The version number is incremented on each modification
+- During sync, the observation with the highest version number is kept
+- If versions are equal, the most recent modification timestamp is used
+
+## Sync Status
+
+Observations have a sync status that indicates their synchronization state:
+
+| Status | Description |
+|--------|-------------|
+| **Pending** | Observation is waiting to be synchronized |
+| **Syncing** | Synchronization is in progress |
+| **Synced** | Observation has been successfully synchronized |
+| **Error** | Synchronization failed (will be retried) |
+
+## Attachment Synchronization
+
+Attachments (photos, audio, files) are synchronized separately from observation metadata:
+
+1. Observation metadata is synchronized first
+2. Attachments are uploaded or downloaded in a separate phase
+3. Attachment sync status is tracked independently
+
+See the [Technical Details](/development/technical/sync-protocol) section for more information on the sync protocol.
+
+## Troubleshooting Sync Issues
+
+If synchronization is not working:
+
+1. Check network connectivity
+2. Verify server accessibility
+3. Review authentication credentials
+4. Check server logs for errors
+5. Review the [Troubleshooting guide](/using/troubleshooting)
+
+## Next Steps
+
+- Learn about [working offline](/using/working-offline)
+- Review [technical sync details](/development/technical/sync-protocol)
+- Explore [API endpoints](/reference/api/endpoints) for sync operations
+
diff --git a/versioned_docs/version-1.0/using/troubleshooting.md b/versioned_docs/version-1.0/using/troubleshooting.md
new file mode 100644
index 0000000..3df75bf
--- /dev/null
+++ b/versioned_docs/version-1.0/using/troubleshooting.md
@@ -0,0 +1,502 @@
+---
+sidebar_position: 7
+---
+
+# Troubleshooting
+
+Common issues and solutions when using ODE.
+
+## Connection Issues
+
+### App Cannot Connect to Server
+
+**Symptoms**: App shows connection error, cannot sync data
+
+**Solutions**:
+- Verify server is running and accessible
+- Check server URL in app settings
+- Verify network connectivity
+- Check firewall settings
+- For Android emulator, use `10.0.2.2` instead of `localhost`
+- For iOS simulator, use `localhost` or your machine's IP address
+
+### Authentication Failures
+
+**Symptoms**: Login fails, authentication errors
+
+**Solutions**:
+- Verify username and password are correct
+- Check that user account exists on server
+- Verify JWT secret is configured correctly on server
+- Review server logs for authentication errors
+
+## Synchronization Issues
+
+### Observations Not Syncing
+
+**Symptoms**: Observations remain in "pending" status
+
+**Solutions**:
+- Check network connectivity
+- Verify server is accessible
+- Review authentication credentials
+- Check server logs for sync errors
+- Ensure observations were saved locally before sync attempt
+- Try manual sync from app settings
+
+### Sync Conflicts
+
+**Symptoms**: Data conflicts during synchronization
+
+**Solutions**:
+- ODE automatically resolves conflicts using version numbers
+- Review conflict resolution in [Synchronization](/using/synchronization)
+- Check that devices are using the same server
+- Verify system clocks are synchronized
+
+## Form Issues
+
+### Forms Not Appearing
+
+**Symptoms**: Forms don't appear in app
+
+**Solutions**:
+- Verify forms were uploaded to server
+- Check that app has synchronized with server
+- Review server logs for form upload errors
+- Ensure form specifications are valid JSON
+- Check form type and version match
+
+### Form Validation Errors
+
+**Symptoms**: Cannot submit form, validation errors
+
+**Solutions**:
+- Review form schema for required fields
+- Check that data types match schema definitions
+- Verify validation rules are correctly defined
+- Review error messages for specific issues
+
+## Formplayer Errors Explained
+
+Common Formplayer errors, their causes, and fixes.
+
+### ❌ "minimum value must be ['number']"
+
+**Error Message:**
+```
+minimum value must be ['number']
+```
+
+**Cause:**
+Using `$data` reference or non-numeric value in `minimum` or `maximum` property.
+
+**Example (Unsafe):**
+```json
+{
+ "type": "number",
+ "minimum": { "$data": "#/properties/minValue" } // ❌ $data not supported
+}
+```
+
+**Fix:**
+Use literal numeric values only:
+
+```json
+{
+ "type": "number",
+ "minimum": 0, // ✅ Literal number
+ "maximum": 100
+}
+```
+
+**Prevention:**
+- Always use literal numbers for `minimum` and `maximum`
+- Never use `$data` references in validation constraints
+- Validate schema before deployment
+
+### ❌ "Cannot read properties of undefined (reading 'find')"
+
+**Error Message:**
+```
+Cannot read properties of undefined (reading 'find')
+TypeError: Cannot read properties of undefined (reading 'find')
+```
+
+**Cause:**
+One of several issues:
+1. Layout missing `elements` array
+2. Invalid `scope` path (field doesn't exist in schema)
+3. Rule referencing missing field
+
+**Example 1 - Missing elements:**
+```json
+{
+ "type": "SwipeLayout"
+ // ❌ Missing elements array
+}
+```
+
+**Fix:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [] // ✅ Always include elements array
+}
+```
+
+**Example 2 - Invalid scope:**
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" }
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/missingField" // ❌ Field doesn't exist
+ }
+}
+```
+
+**Fix:**
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" },
+ "missingField": { "type": "string" } // ✅ Add field to schema
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/missingField"
+ }
+}
+```
+
+**Example 3 - Rule referencing missing field:**
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" }
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/missingField", // ❌ Field doesn't exist
+ "schema": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Fix:**
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" },
+ "missingField": { "type": "string" } // ✅ Add referenced field
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "condition": {
+ "scope": "#/properties/missingField",
+ "schema": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Prevention:**
+- Always include `elements: []` in layouts (can be empty)
+- Validate all `scope` paths exist in schema
+- Ensure all fields referenced in rules exist in schema
+- Use form validation script before deployment
+
+### ❌ "Rule condition scope not found"
+
+**Error Message:**
+```
+Rule condition scope "#/properties/field" not found in schema
+```
+
+**Cause:**
+Rule condition references a field that doesn't exist in the JSON schema.
+
+**Example:**
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" }
+ // field2 doesn't exist
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/field2", // ❌ Field doesn't exist
+ "schema": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Fix:**
+Add the referenced field to the schema:
+
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" },
+ "field2": { "type": "string" } // ✅ Add referenced field
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/field1",
+ "rule": {
+ "effect": "SHOW",
+ "condition": {
+ "scope": "#/properties/field2",
+ "schema": { "const": "value" }
+ }
+ }
+ }
+}
+```
+
+**Prevention:**
+- Always define all fields referenced in rules in the schema
+- Use form validation script to catch these errors
+- Test all conditional logic paths
+
+### ❌ "SwipeLayout missing required elements array"
+
+**Error Message:**
+```
+SwipeLayout missing required "elements" array
+```
+
+**Cause:**
+SwipeLayout (or other layout) is missing the `elements` property.
+
+**Example:**
+```json
+{
+ "type": "SwipeLayout"
+ // ❌ Missing elements
+}
+```
+
+**Fix:**
+```json
+{
+ "type": "SwipeLayout",
+ "elements": [] // ✅ Always include elements array
+}
+```
+
+**Prevention:**
+- Always include `elements` array in layouts
+- Use form validation script
+- Test forms before deployment
+
+### ❌ "Invalid scope path"
+
+**Error Message:**
+```
+Invalid scope path: "#/properties/nonexistent"
+Scope does not exist in schema
+```
+
+**Cause:**
+Control `scope` references a property that doesn't exist in the JSON schema.
+
+**Example:**
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" }
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/nonexistent" // ❌ Field doesn't exist
+ }
+}
+```
+
+**Fix:**
+Either add the field to schema or correct the scope:
+
+```json
+{
+ "schema": {
+ "properties": {
+ "field1": { "type": "string" },
+ "nonexistent": { "type": "string" } // ✅ Add field
+ }
+ },
+ "uischema": {
+ "type": "Control",
+ "scope": "#/properties/nonexistent"
+ }
+}
+```
+
+**Prevention:**
+- Validate all scope paths before deployment
+- Use form validation script
+- Keep schema and UI schema in sync
+
+### ❌ "$data is not supported"
+
+**Error Message:**
+```
+$data is not supported in Formplayer
+```
+
+**Cause:**
+Using `$data` references in schema (e.g., in `minimum`, `maximum`, or validation rules).
+
+**Example:**
+```json
+{
+ "type": "number",
+ "minimum": { "$data": "#/properties/minValue" } // ❌ Not supported
+}
+```
+
+**Fix:**
+Use literal values only:
+
+```json
+{
+ "type": "number",
+ "minimum": 0 // ✅ Literal value
+}
+```
+
+**Prevention:**
+- Never use `$data` references
+- Use literal values for all constraints
+- Refer to [Supported Schema Profile](/reference/formplayer#supported-schema--ui-profile)
+
+### ❌ "Form failed to render"
+
+**Symptoms:**
+Form doesn't display, blank screen, or error in console.
+
+**Common Causes:**
+1. Invalid JSON syntax
+2. Missing required schema properties
+3. Unsupported schema features
+4. Invalid UI schema structure
+
+**Solutions:**
+1. Validate JSON syntax
+2. Check schema follows supported profile
+3. Verify UI schema structure (SwipeLayout root, elements arrays)
+4. Review browser console for specific errors
+5. Test with form validation script
+
+### General Error Prevention
+
+1. **Use Validation Script**: Run `npm run validate:forms` before deployment
+2. **Check Supported Features**: Refer to [Supported Schema Profile](/reference/formplayer#supported-schema--ui-profile)
+3. **Test on Devices**: Test forms on actual mobile devices
+4. **Review Error Messages**: Error messages often indicate the specific issue
+5. **Validate Scope Paths**: Ensure all scope paths exist in schema
+6. **Avoid Unsupported Features**: Don't use `$data`, `if/then/else`, etc.
+
+### Getting Help with Errors
+
+If you encounter errors not covered here:
+
+1. Check [Form Design Guide](/guides/form-design) for best practices
+2. Review [Formplayer Reference](/reference/formplayer) for supported features
+3. Validate your form using the validation script
+4. Check browser/device console for detailed error messages
+5. Report issues following [guidelines](/community/getting-help)
+
+## Data Issues
+
+### Observations Not Saving
+
+**Symptoms**: Observations disappear after creation
+
+**Solutions**:
+- Check device storage space
+- Verify database is accessible
+- Review app logs for database errors
+- Ensure app has necessary permissions
+
+### Data Loss
+
+**Symptoms**: Observations are missing
+
+**Solutions**:
+- Check sync status to see if data is on server
+- Review server logs for deletion records
+- Verify backups are configured
+- Check that observations weren't accidentally deleted
+
+## Performance Issues
+
+### Slow App Performance
+
+**Symptoms**: App is slow, forms take time to load
+
+**Solutions**:
+- Check device storage space
+- Review number of observations stored locally
+- Clear app cache if needed
+- Ensure app is updated to latest version
+- Check device memory usage
+
+### Slow Synchronization
+
+**Symptoms**: Sync takes a long time
+
+**Solutions**:
+- Check network speed and stability
+- Review number of observations to sync
+- Check server performance and load
+- Verify attachment sizes are reasonable
+- Consider syncing during off-peak hours
+
+## Getting Additional Help
+
+If you cannot resolve an issue:
+
+1. Review relevant documentation sections
+2. Check [GitHub Issues](https://github.com/OpenDataEnsemble/ode/issues) for similar problems
+3. Search the [Community section](/community/getting-help) for solutions
+4. Review [API Reference](/reference/api/overview) for technical details
+5. Report issues following the [guidelines](/community/reporting-issues)
+
+## Next Steps
+
+- Review [Synchronization](/using/synchronization) for sync-related issues
+- Check [Installation guides](/getting-started/installation/prerequisites) for setup problems
+- Explore [API Reference](/reference/api/overview) for integration issues
+
diff --git a/versioned_docs/version-1.0/using/working-offline.md b/versioned_docs/version-1.0/using/working-offline.md
new file mode 100644
index 0000000..426dffa
--- /dev/null
+++ b/versioned_docs/version-1.0/using/working-offline.md
@@ -0,0 +1,71 @@
+---
+sidebar_position: 6
+---
+
+# Working Offline
+
+ODE is designed to work seamlessly in offline conditions, allowing data collection to continue regardless of network connectivity.
+
+## Offline Capabilities
+
+When offline, you can:
+
+- Create new observations
+- Edit existing observations
+- Delete observations
+- View all locally stored observations
+- Fill out forms completely
+
+All changes are stored locally and synchronized when connectivity is restored.
+
+## Local Storage
+
+Observations are stored locally on the device using WatermelonDB, a reactive database optimized for React Native. This ensures:
+
+- Fast access to data
+- Reliable storage
+- Efficient querying
+- Automatic conflict resolution
+
+## Synchronization When Online
+
+When network connectivity is restored:
+
+1. The app automatically detects connectivity
+2. Synchronization begins automatically
+3. Local changes are pushed to the server
+4. New data is pulled from the server
+5. Conflicts are resolved automatically
+
+## Offline Indicators
+
+The app provides visual indicators for offline status:
+
+- Connection status in the app header
+- Sync status for individual observations
+- Notification when sync completes
+
+## Best Practices
+
+When working offline:
+
+- Ensure sufficient device storage for observations
+- Regularly sync when connectivity is available
+- Monitor sync status to identify any issues
+- Keep the app updated to ensure optimal offline performance
+
+## Limitations
+
+While offline, you cannot:
+
+- Access server-side features
+- Download new forms (unless previously cached)
+- Access real-time collaboration features
+- View server-side analytics
+
+## Next Steps
+
+- Learn about [synchronization](/using/synchronization) in detail
+- Review [troubleshooting](/using/troubleshooting) for offline issues
+- Explore [data management](/using/data-management) features
+
diff --git a/versioned_docs/version-1.0/using/your-first-form.md b/versioned_docs/version-1.0/using/your-first-form.md
new file mode 100644
index 0000000..41a2ff5
--- /dev/null
+++ b/versioned_docs/version-1.0/using/your-first-form.md
@@ -0,0 +1,123 @@
+---
+sidebar_position: 2
+---
+
+# Your First Form
+
+This guide walks you through creating and submitting your first form using ODE.
+
+## Prerequisites
+
+Before starting, ensure you have:
+
+- Formulus app installed and configured
+- Synkronus server running and accessible
+- App connected to the server
+
+## Creating a Form
+
+Forms in ODE are defined using JSON schema. A basic form consists of a schema definition and optionally a UI schema.
+
+### Basic Form Example
+
+Here's a simple form that collects a name and age:
+
+```json
+{
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "Full Name"
+ },
+ "age": {
+ "type": "integer",
+ "title": "Age",
+ "minimum": 0,
+ "maximum": 120
+ }
+ },
+ "required": ["name", "age"]
+}
+```
+
+### Uploading the Form
+
+Upload the form to your Synkronus server using one of these methods:
+
+
+
+
+```bash
+curl -X POST http://your-server:8080/api/formspecs \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer YOUR_TOKEN" \
+ -d '{
+ "formType": "basic-survey",
+ "version": "1.0.0",
+ "schema": {
+ "type": "object",
+ "properties": {
+ "name": {"type": "string", "title": "Full Name"},
+ "age": {"type": "integer", "title": "Age", "minimum": 0, "maximum": 120}
+ },
+ "required": ["name", "age"]
+ }
+ }'
+```
+
+
+
+
+```bash
+# Create a form specification file (form.json)
+synk formspec create form.json --form-type basic-survey --version 1.0.0
+```
+
+
+
+
+1. Navigate to the Portal
+2. Go to "Form Specifications"
+3. Click "Create New Form"
+4. Enter form type and version
+5. Paste or upload your JSON schema
+6. Click "Save"
+
+
+
+
+## Filling Out the Form
+
+1. Open the Formulus app on your device
+2. Navigate to the forms list
+3. Select your form from the list
+4. Fill out the form fields
+5. Review your entries
+6. Submit the form
+
+## Submitting Observations
+
+When you submit a form, an observation is created. The observation contains:
+
+- The form data you entered
+- Metadata such as creation timestamp
+- A unique identifier
+- Sync status
+
+Observations are stored locally on your device and synchronized to the server when connectivity is available.
+
+## Verifying Submission
+
+To verify that your observation was created:
+
+1. Check the app's observation list
+2. Verify the observation appears with a "synced" status after synchronization
+3. Query the server API to confirm the observation was received
+
+## Next Steps
+
+- Learn about [form design](/guides/forms/overview) to create more complex forms
+- Explore [data management](/using/data-management) features
+- Understand [synchronization](/using/synchronization) in detail
+
diff --git a/versioned_sidebars/version-1.0-sidebars.json b/versioned_sidebars/version-1.0-sidebars.json
new file mode 100644
index 0000000..f7f5a82
--- /dev/null
+++ b/versioned_sidebars/version-1.0-sidebars.json
@@ -0,0 +1,110 @@
+{
+ "docs": [
+ {
+ "type": "doc",
+ "id": "index",
+ "label": "Introduction"
+ },
+ {
+ "type": "category",
+ "label": "Getting Started",
+ "link": {
+ "type": "doc",
+ "id": "getting-started/index"
+ },
+ "items": [
+ "getting-started/what-is-ode",
+ "getting-started/why-ode",
+ "getting-started/key-concepts",
+ "getting-started/installation",
+ "getting-started/installing-formulus",
+ "getting-started/quick-start",
+ "getting-started/faq"
+ ]
+ },
+ {
+ "type": "category",
+ "label": "Using ODE",
+ "link": {
+ "type": "doc",
+ "id": "using/index"
+ },
+ "items": [
+ "using/your-first-form",
+ "using/formulus-features",
+ "using/app-bundles",
+ "using/data-management",
+ "using/synchronization",
+ "using/custom-applications",
+ "using/working-offline",
+ "using/troubleshooting"
+ ]
+ },
+ {
+ "type": "category",
+ "label": "Guides",
+ "link": {
+ "type": "doc",
+ "id": "guides/index"
+ },
+ "items": [
+ "guides/form-design",
+ "guides/custom-applications",
+ "guides/deployment",
+ "guides/configuration"
+ ]
+ },
+ {
+ "type": "category",
+ "label": "Reference",
+ "link": {
+ "type": "doc",
+ "id": "reference/index"
+ },
+ "items": [
+ "reference/api",
+ "reference/components",
+ "reference/formulus",
+ "reference/formplayer",
+ "reference/formplayer-contract",
+ "reference/synkronus-cli",
+ "reference/synkronus-server",
+ "reference/synkronus-portal",
+ "reference/form-specifications",
+ "reference/app-bundle-format"
+ ]
+ },
+ {
+ "type": "category",
+ "label": "Development",
+ "link": {
+ "type": "doc",
+ "id": "development/index"
+ },
+ "items": [
+ "development/setup",
+ "development/installing-formulus-dev",
+ "development/architecture",
+ "development/formulus-development",
+ "development/formplayer-development",
+ "development/synkronus-development",
+ "development/synkronus-portal-development",
+ "development/contributing",
+ "development/building-testing",
+ "development/extending"
+ ]
+ },
+ {
+ "type": "category",
+ "label": "Community",
+ "link": {
+ "type": "doc",
+ "id": "community/index"
+ },
+ "items": [
+ "community/getting-help",
+ "community/examples"
+ ]
+ }
+ ]
+}
diff --git a/versions.json b/versions.json
new file mode 100644
index 0000000..9a369ed
--- /dev/null
+++ b/versions.json
@@ -0,0 +1,3 @@
+[
+ "1.0"
+]