Skip to content

Commit 1b380bc

Browse files
authored
Merge pull request #18 from OpenDataEnsemble/feature/corrections
feat: correct some mistakes, add ai section
2 parents 7e7f5b5 + 991613f commit 1b380bc

File tree

5 files changed

+96
-72
lines changed

5 files changed

+96
-72
lines changed

docs/developer/developer-index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ This section is designed for:
1717
- Architects evaluating ODE architecture
1818
- Contributors wanting to improve the codebase
1919

20+
:::tip AI coding assistants
21+
Building **custom applications** (HTML, JS, CSS bundles and JSON forms) without cloning the ODE monorepo? Use the **[custom_app](https://github.com/OpenDataEnsemble/custom_app)** repository on GitHub (`AGENTS.md` and `CONTEXT_*.md` for assistants and authors), together with the main **[documentation](https://opendataensemble.org/docs/)** site.
22+
:::
23+
2024
:::info Not developing?
2125
If you're collecting data, see the [Data Collector Guide](/docs/collector/collector-index).
2226
If you're designing forms, see the [Implementer Guide](/docs/implementer/implementer-index).

docs/guides/custom-applications.md

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,39 +10,42 @@ Complete guide to building and deploying custom applications that integrate with
1010
1111
## Overview
1212

13-
Custom applications are React applications 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.
13+
Custom applications are **web applications** (HTML, CSS, and JavaScript) that run inside the Formulus mobile app’s WebView. You may author them with **any** stack—plain static files, **Vite**, **React**, **Vue**, **Svelte**, or another bundler—**as long as the build output** can be packaged as described in the [app bundle format](/docs/reference/app-bundle-format) (entry HTML, assets, and `forms/` layout). They provide specialized workflows, custom navigation, integration with the ODE form system, and interfaces tailored to your use case.
14+
15+
## Scaffolding
16+
17+
ODE does **not** require a special installer: start from a **standard** project scaffold (for example **`npm create vite@latest`** with React, Svelte, or Solid templates) and then align the **folder layout** with the app bundle spec. Copy-paste commands, a **Vite `outDir` example**, and a post-scaffold checklist are maintained in the **[custom_app](https://github.com/OpenDataEnsemble/custom_app)** repository README on GitHub (AI and author context for the Formulus API and forms live in that repo as well).
1418

1519
## Application Structure
1620

17-
Custom applications follow a standardized structure for consistency and maintainability:
21+
There is **no single mandatory** project layout. The tree below is **one** common pattern (React + Vite + optional `app.config.json` for theming). You can use a simpler folder tree if you prefer hand-written HTML/JS or a different framework, provided the **zip** you upload matches the [bundle format](/docs/reference/app-bundle-format).
1822

1923
```
2024
my-app/
21-
├── app.config.json # App configuration and theme
22-
├── forms/ # Form definitions
23-
│ ├── survey/
25+
├── app.config.json # Optional: app metadata and theme (if your template uses it)
26+
├── forms/ # Form definitions (see bundle format)
27+
│ ├── survey/ # One folder per form type (form name)
2428
│ │ ├── schema.json # JSON Schema (draft-07)
25-
│ │ └── ui.json # Formulus UI schema
26-
│ └── forms-manifest.json # Form registry
27-
├── src/
28-
│ ├── components/ # Reusable components
29-
│ ├── screens/ # Main screens
30-
│ ├── utils/ # Utility functions
31-
│ └── theme.js # Theme generation
32-
├── scripts/ # Build and validation scripts
33-
├── package.json
34-
└── vite.config.js
29+
│ │ └── ui.json # JSON Forms UI schema (ODE rules)
30+
│ └── forms-manifest.json # Form registry (if used by your project)
31+
├── src/ # Optional: only if you use a bundler (e.g. React)
32+
│ ├── components/
33+
│ ├── screens/
34+
│ ├── utils/
35+
│ └── theme.js
36+
├── scripts/
37+
├── package.json # Optional: if you use npm tooling
38+
└── vite.config.js # Optional: example bundler config
3539
```
3640

3741
## Configuration System
3842

3943
### app.config.json
4044

41-
The `app.config.json` file is the single source of truth for your application's configuration:
45+
If your template uses **`app.config.json`** (common in React-based examples), it can hold application metadata and theme. Plain HTML apps may omit it and configure styling in CSS/JS instead. When present, it is typically the single place for those settings:
4246

4347
```json
4448
{
45-
"$schema": "https://ode.dev/schemas/app-config-v1.json",
4649
"name": "My Application",
4750
"version": "1.0.0",
4851
"navigation": {
@@ -108,10 +111,12 @@ export function buildTheme(mode = 'light') {
108111
109112
### Form Structure
110113
111-
Each form consists of two files:
114+
Each form is a **directory** named with the **form type** (for example `survey/`). Inside it, two files are required:
115+
116+
1. **`schema.json`**: [JSON Schema](https://json-schema.org/) (draft-07) defining data shape, validation, and question types (including ODE `format` values). See [Form specifications](/docs/reference/form-specifications).
117+
2. **`ui.json`**: [JSON Forms](https://jsonforms.io/) **UI schema** defining layout (`VerticalLayout`, `Control`, `scope`, rules). ODE follows JSON Forms with project-specific rules—see [Form specifications](/docs/reference/form-specifications). The [app bundle format](/docs/reference/app-bundle-format) describes how these files sit inside the zip.
112118
113-
1. **schema.json**: JSON Schema (draft-07) defining data structure
114-
2. **ui.json**: Formulus UI schema defining form layout and behavior
119+
Synkronus accepts **`forms/<formType>/schema.json`** and **`ui.json`** at the **bundle root** (with **`forms/`** as a **sibling** of **`app/`**), or the alternate path **`app/forms/<formType>/...`** where **`forms`** sits **inside** **`app`**. See [App bundle format](/docs/reference/app-bundle-format).
115120
116121
### Example Form
117122

docs/guides/quick-start-custom-app.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ my-app/
5050

5151
```json
5252
{
53-
"$schema": "https://ode.dev/schemas/app-config-v1.json",
5453
"name": "My First App",
5554
"version": "1.0.0",
5655
"navigation": {

docs/implementer/implementer-index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ This section is designed for users who:
1717
- Need guidance on deployment and data management
1818
- Are responsible for project outcomes
1919

20+
:::tip AI coding assistants
21+
If you use an AI assistant to build **custom applications** (bundles and JSON forms) for ODE, see **[custom_app](https://github.com/OpenDataEnsemble/custom_app)** on GitHub and the **[documentation](https://opendataensemble.org/docs/)** site—no need to clone the full ODE monorepo.
22+
:::
23+
2024
:::info Not collecting data?
2125
If you're collecting data with Formulus, see the [Data Collector Guide](/docs/collector/collector-index).
2226
If you're developing or extending ODE, see the [Developer Guide](/docs/developer/developer-index).

docs/reference/app-bundle-format.md

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,35 @@ App bundles are ZIP archives containing custom application files, form specifica
1212

1313
## Bundle Structure
1414

15-
An app bundle is a ZIP file with the following structure:
15+
Synkronus validates bundles that use **top-level** folders **`app/`**, **`forms/`**, and optionally **`renderers/`**. The **`app`** directory (your HTML/JS/CSS) and the **`forms`** directory (JSON Forms) are **siblings** at the root of the ZIP—they are **not** nested inside each other in the default layout.
1616

1717
```
1818
app-bundle.zip
19-
├── index.html # Main entry point (required)
2019
├── manifest.json # Bundle metadata (required)
21-
├── assets/
22-
│ ├── css/
23-
│ │ └── styles.css
24-
│ ├── js/
25-
│ │ ├── app.js
26-
│ │ └── formulus-load.js
27-
│ └── images/
28-
│ └── logo.png
29-
├── forms/ # Form specifications (optional)
30-
│ ├── survey-v1.json
31-
│ └── health-v1.json
32-
└── config/ # Configuration files (optional)
33-
└── settings.json
20+
├── app/ # Web UI (required): sibling of forms/, not parent of it
21+
│ ├── index.html # Main entry point (required)
22+
│ ├── assets/
23+
│ │ ├── css/
24+
│ │ ├── js/
25+
│ │ │ ├── app.js
26+
│ │ │ └── formulus-load.js
27+
│ │ └── images/
28+
│ └── public/ # Optional: e.g. app.config.json copied into build
29+
├── forms/ # Form specs (optional; see Form specifications)
30+
│ ├── survey/ # Folder name = form type id
31+
│ │ ├── schema.json
32+
│ │ └── ui.json
33+
│ └── health/
34+
│ ├── schema.json
35+
│ └── ui.json
36+
├── forms/ext.json # Optional: app-level extensions config
37+
└── renderers/ # Optional: custom JSON Forms renderers
38+
└── myRenderer/
39+
└── renderer.jsx
3440
```
3541

42+
**Alternate layout (nested forms):** Some projects put form folders under **`app/forms/<formType>/`** instead of top-level **`forms/<formType>/`**. In that case **`forms`** is a **subdirectory inside `app`** (path `app/forms/...`). That is **different** from having **`app/`** and **`forms/`** as **two separate top-level folders**. Synkronus accepts both; use one style consistently in a given bundle.
43+
3644
## Manifest Format
3745

3846
The `manifest.json` file defines bundle metadata:
@@ -42,7 +50,7 @@ The `manifest.json` file defines bundle metadata:
4250
"version": "20250114-123456",
4351
"name": "My Custom App",
4452
"description": "Description of the custom application",
45-
"entryPoint": "index.html",
53+
"entryPoint": "app/index.html",
4654
"createdAt": "2025-01-14T10:00:00Z"
4755
}
4856
```
@@ -59,13 +67,13 @@ The `manifest.json` file defines bundle metadata:
5967

6068
## Entry Point
6169

62-
The entry point (`index.html` by default) is the main HTML file loaded when the app bundle is opened. It should:
70+
Validated bundles include **`app/index.html`** (path from the **ZIP root**). The manifest **`entryPoint`** should reference that file (commonly `app/index.html`). The entry HTML should:
6371

6472
1. Include the Formulus load script
6573
2. Initialize the application
6674
3. Use the Formulus JavaScript interface
6775

68-
**Example:**
76+
**Example** (paths below assume assets live under `app/assets/`):
6977

7078
```html
7179
<!DOCTYPE html>
@@ -84,38 +92,40 @@ The entry point (`index.html` by default) is the main HTML file loaded when the
8492

8593
## Form Specifications
8694

87-
Form specifications can be included in the `forms/` directory. Each form file should contain:
95+
Use a **one-folder-per-form** layout. The **folder name** is the **form type** identifier (for example `survey`, `registration`). Synkronus validates that each form directory contains both required files.
8896

89-
- Schema definition
90-
- UI schema definition
91-
- Form metadata
97+
**Folder structure:** **`forms/<formType>/`** at the **root** of the ZIP, as a **sibling** of **`app/`**.
9298

93-
**Example form file:**
99+
### Required files per form
100+
101+
| File | Role |
102+
|------|------|
103+
| **`schema.json`** | **[JSON Schema](https://json-schema.org/)** (draft-07 in ODE) for the observation payload: properties, types, validation, and ODE-specific **`format`** values for question types. Defines *what* is collected. |
104+
| **`ui.json`** | **[JSON Forms UI schema](https://jsonforms.io/docs/uischema/)** for layout: `VerticalLayout`, `Control` elements, `scope` pointers into the schema, rules, etc. Defines *how* the form is shown. ODE follows JSON Forms with additional rules documented in [Form specifications](/docs/reference/form-specifications). |
105+
106+
Upstream JSON Forms concepts and UI schema structure are described at **[jsonforms.io](https://jsonforms.io/)**. Always cross-check ODE-specific behavior in [Form specifications](/docs/reference/form-specifications)—not every JSON Forms feature is available in Formulus.
107+
108+
**Example paths (two files per form, not one combined JSON) — top-level `forms/` (sibling of `app/`):**
94109

95-
```json
96-
{
97-
"formType": "survey",
98-
"version": "1.0.0",
99-
"schema": {
100-
"type": "object",
101-
"properties": {
102-
"name": {
103-
"type": "string",
104-
"title": "Name"
105-
}
106-
}
107-
},
108-
"uischema": {
109-
"type": "VerticalLayout",
110-
"elements": [
111-
{
112-
"type": "Control",
113-
"scope": "#/properties/name"
114-
}
115-
]
116-
}
117-
}
118110
```
111+
forms/
112+
└── survey/
113+
├── schema.json
114+
└── ui.json
115+
```
116+
117+
**Same form type using nested `app/forms/` instead:**
118+
119+
```
120+
app/
121+
├── index.html
122+
└── forms/
123+
└── survey/
124+
├── schema.json
125+
└── ui.json
126+
```
127+
128+
See [Form specifications](/docs/reference/form-specifications) and [Form design](/docs/guides/form-design) for complete examples of `schema.json` and `ui.json` pairs.
119129

120130
## Versioning
121131

@@ -143,21 +153,22 @@ synk app-bundle switch 20250114-123456
143153
### Required Files
144154

145155
- `manifest.json`: Bundle metadata
146-
- `index.html`: Main entry point (or file specified in `entryPoint`)
156+
- `app/index.html`: Main entry point (or path given by `entryPoint`)
147157

148158
### Optional Files
149159

150-
- `assets/`: CSS, JavaScript, images, and other assets
151-
- `forms/`: Form specification files
152-
- `config/`: Configuration files
160+
- `app/assets/` (or similar under `app/`): CSS, JavaScript, images, and other assets for the web UI
161+
- `forms/<formType>/`: Form specifications at **ZIP root** (sibling of `app/`), **or** `app/forms/<formType>/` if you use the nested layout
162+
- `forms/ext.json`: Optional extensions manifest
163+
- `renderers/`: Optional custom JSON Forms renderers
153164

154165
## File Size Limits
155166

156167
| Component | Limit | Notes |
157168
|-----------|-------|-------|
158169
| **Total bundle size** | 100 MB | Maximum ZIP file size |
159170
| **Individual file** | 50 MB | Maximum size per file |
160-
| **Form specification** | 1 MB | Maximum size per form file |
171+
| **Form specification** | 1 MB | Maximum size per form file (`schema.json` / `ui.json`) |
161172

162173
## Upload Process
163174

@@ -213,3 +224,4 @@ Mobile devices download app bundles during synchronization:
213224
- [Custom Applications Guide](/docs/guides/custom-applications)
214225
- [API Reference](/docs/reference/rest-api/overview)
215226
- [Form Design Guide](/docs/guides/form-design)
227+
- [custom_app on GitHub](https://github.com/OpenDataEnsemble/custom_app) — AI/agent context (`AGENTS.md`, `CONTEXT_*.md`) and **scaffolding** recipes (`npm create vite@latest`, post-build checklist)

0 commit comments

Comments
 (0)