Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .cursor/skills/ode-custom-app-form-validation/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: ode-custom-app-form-validation
description: >-
Helps validate ODE custom app form definitions (JSON Schema draft-07 + UI schema)
and CI integration. Use when the user asks to validate forms, add validate-forms
scripts, or check schema/ui consistency for Synkronus bundles. Prefer official docs
at opendataensemble.org and the custom-app template repo on GitHub.
---

# ODE custom app — form validation

## When to use

- Adding or maintaining **`schema.json`** / **`ui.json`** for ODE custom apps.
- Setting up **CI** to fail on invalid forms.
- Explaining **draft-07**, `scope` references, or ODE-specific **`format`** rules.

## What to do

1. Point to **[Form specifications](https://opendataensemble.org/docs/reference/form-specifications)** as the normative reference for question types and UI structure.
2. Ensure **UI `scope`** paths match **JSON Schema** properties; **`required`** arrays align with product intent.
3. For automation, describe a **Node** (or other) script pattern: load each form folder, `JSON.parse`, validate schema with a draft-07 validator, and check structural rules (both files present, cross-references). Link **[custom_app](https://github.com/OpenDataEnsemble/custom_app)** for AI context, not as a code dependency.
4. Do **not** invent Synkronus-specific validation rules beyond public docs.

## Official links

- [Form specifications](https://opendataensemble.org/docs/reference/form-specifications)
- [Custom applications](https://opendataensemble.org/docs/guides/custom-applications)
26 changes: 26 additions & 0 deletions .cursor/skills/ode-custom-jsonforms-extension/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: ode-custom-jsonforms-extension
description: >-
Guides adding ODE custom JSON Forms extensions (custom renderers, testers, ext.json,
dynamic functions). Use when extending forms with non-standard controls or wiring
extension manifests. Official behavior is documented on opendataensemble.org.
---

# ODE custom JSON Forms extensions

## When to use

- Custom **control** rendering (tester + renderer pattern).
- **`ext.json`** (or app-level extension manifest) and module paths.
- **Dynamic choice lists** or helper **functions** referenced from the UI schema.

## What to do

1. Read **[Custom extensions](https://opendataensemble.org/docs/guides/custom-extensions)** and **[Dynamic choice lists](https://opendataensemble.org/docs/guides/dynamic-choice-lists)** on the docs site.
2. Keep **bundled JS** compatible with the Formulus WebView (no Node-only APIs in runtime code).
3. Align **`format`** in schema with the renderer contract described in docs.
4. For AI-only context summaries, **[CONTEXT_ODE_FORMS.md](https://github.com/OpenDataEnsemble/custom_app/blob/main/CONTEXT_ODE_FORMS.md)** in **custom_app** may help — still verify against **opendataensemble.org**.

## Do not

- Assume vanilla **jsonforms.io** examples work without checking ODE’s registered renderers and extension loading rules.
27 changes: 27 additions & 0 deletions .cursor/skills/ode-synk-bundle-publish/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: ode-synk-bundle-publish
description: >-
Guides publishing and managing ODE app bundles with the Synkronus CLI (synk):
config, auth, upload, versions. Use when deploying custom app zips or automating
bundle uploads. Official reference is opendataensemble.org and OpenDataEnsemble/ode docs.
---

# Synkronus CLI — app bundle publish

## When to use

- Uploading a **custom app** ZIP to Synkronus.
- Managing **bundle versions** or scripting **CI** upload steps.
- Configuring **`synk`** (`~/.synkronus.yaml`, `synk config use`, etc.).

## What to do

1. Use **[Synkronus CLI](https://opendataensemble.org/docs/reference/synkronus-cli)** as the primary command reference.
2. Ensure the ZIP matches **[App bundle format](https://opendataensemble.org/docs/reference/app-bundle-format)** before upload.
3. Store **API URLs and tokens** in CI secrets; never embed production credentials in source.
4. For bundle structure reminders, see **[CONTEXT_BUNDLE_AND_CI.md](https://github.com/OpenDataEnsemble/custom_app/blob/main/CONTEXT_BUNDLE_AND_CI.md)** in **custom_app** (summary only).

## Related

- [App bundles (using)](https://opendataensemble.org/docs/using/app-bundles)
- [Deployment](https://opendataensemble.org/docs/guides/deployment)
91 changes: 91 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Open Data Ensemble (ODE) — AI and developer guide

This monorepo contains the core platform for **offline-first data collection** and **synchronization**. Use this file when you work across packages or need the big picture. For deep dives, open the **`AGENTS.md`** in the package you are changing.

**Published architecture (users and external readers):** [Architecture overview](https://opendataensemble.org/docs/getting-started/architecture-overview) on [opendataensemble.org](https://opendataensemble.org/).

---

## Ecosystem map

ODE is a **clearinghouse** model: data is collected on devices, synchronized through **Synkronus**, and is intended to **flow through** the system for local analysis and stewardship—not to live only on the server.

- **Formulus** — React Native mobile app: runs forms (JSON Forms) and **custom app bundles** in WebViews, offline-first, syncs with Synkronus.
- **Formulus Formplayer** — React web app embedded in Formulus: renders forms inside a WebView; shares the same bridge contract as custom apps.
- **Synkronus** — Go backend: auth, sync, app bundle distribution, export, shared HTTP API.
- **Synkronus Portal** — Web admin UI (React + Vite): same API as other clients; no privileged backend channel.
- **Synkronus CLI** — `synk` command-line client: automation, bundles, sync, export.

```mermaid
flowchart LR
Formulus[Formulus_RN]
Formplayer[Formulus_Formplayer]
Synkronus[Synkronus_API]
Portal[Portal]
CLI[CLI]
Formulus -->|sync| Synkronus
Portal -->|same_API| Synkronus
CLI -->|same_API| Synkronus
Formulus -->|hosts_WebView| Formplayer
```

**Design principle:** [One backend, many clients](https://opendataensemble.org/docs/getting-started/architecture-overview) — prefer the public API for all user-facing tools.

---

## User profiles (what to optimize for)

| Profile | Typical focus | Where to work |
|--------|----------------|---------------|
| **Platform developer** | You are editing **this repo**: RN, Go, React, shared packages, CI. | Package `AGENTS.md` below. |
| **Custom app author** | You ship an **HTML/JS/CSS** app bundle and JSON forms for Formulus; you may **not** clone this monorepo. | [Custom app template (AI + author context)](https://github.com/OpenDataEnsemble/custom_app) and [documentation](https://opendataensemble.org/docs/). |

Do not assume custom app authors have local checkouts of **ODE** or internal example repos.

---

## Monorepo layout

| Package | Role | Stack | Agent guide |
|---------|------|-------|-------------|
| [formulus](formulus/) | Mobile runtime, WebViews, native bridge | React Native | [formulus/AGENTS.md](formulus/AGENTS.md) |
| [formulus-formplayer](formulus-formplayer/) | Form UI in WebView | React, Vite, JSON Forms | [formulus-formplayer/AGENTS.md](formulus-formplayer/AGENTS.md) |
| [synkronus](synkronus/) | Sync API and coordination | Go | [synkronus/AGENTS.md](synkronus/AGENTS.md) |
| [synkronus-cli](synkronus-cli/) | CLI for API operations | Go | [synkronus-cli/AGENTS.md](synkronus-cli/AGENTS.md) |
| [synkronus-portal](synkronus-portal/) | Web administration | React, TypeScript, Vite | [synkronus-portal/AGENTS.md](synkronus-portal/AGENTS.md) |
| [packages/tokens](packages/tokens/) | Design tokens (`@ode/tokens`) | Style Dictionary | [packages/tokens/AGENTS.md](packages/tokens/AGENTS.md) |
| [packages/components](packages/components/) | Shared UI (`@ode/components`) | React | [packages/components/AGENTS.md](packages/components/AGENTS.md) |

---

## Cross-cutting contracts

- **Formulus ↔ WebView (custom apps + formplayer):** [`formulus/src/webview/FormulusInterfaceDefinition.ts`](formulus/src/webview/FormulusInterfaceDefinition.ts) is the **source of truth** for the injected JavaScript API. Formplayer copies a synced TypeScript snapshot via `npm run sync-interface` in `formulus-formplayer` (see [formulus-formplayer/AGENTS.md](formulus-formplayer/AGENTS.md)).
- **Shared UI tokens:** Install **tokens** before **components** / **formplayer** where the docs require it (see package READMEs and formplayer AGENTS).

---

## CI and code quality

- **Pipelines:** [.github/CICD.md](.github/CICD.md).
- **Lint/format:** Run the relevant scripts in the **package you touch** (see root [README.md](README.md) and each package).
- **Commits/PRs:** Conventional Commits and PR expectations are documented in [formulus-formplayer/AGENTS.md](formulus-formplayer/AGENTS.md) (project-wide convention).

---

## Planned (not shipped here)

Do **not** implement or assume APIs for these as if they were in-repo unless issues/specs say otherwise:

- **ODE Custodian** — local data stewardship and correction workflows (roadmap; often CLI-first).
- **ODE Workshop** — desktop dev environment for bundles/forms (roadmap).

See [product roadmap context](https://opendataensemble.org/docs/) and organization roadmaps on [GitHub](https://github.com/OpenDataEnsemble).

---

## Custom app authors (pointer)

Authoritative **public** documentation: [opendataensemble.org](https://opendataensemble.org/docs/).

Optional **AI-focused** context (no ODE clone required): [custom_app](https://github.com/OpenDataEnsemble/custom_app) on GitHub (`README.md`, `AGENTS.md`, `CONTEXT_*.md`).
2 changes: 2 additions & 0 deletions formulus-formplayer/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Formulus Formplayer — AI & Developer Guide

**Monorepo:** See also [../AGENTS.md](../AGENTS.md) for the full ODE map and cross-package contracts.

This file gives AI assistants and developers enough context to work effectively in this repo. For user-facing docs, see [README.md](./README.md).

## What this project is
Expand Down
46 changes: 46 additions & 0 deletions formulus/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Formulus — AI & developer guide

**When to use this doc:** You are changing the **React Native** mobile app: navigation, screens, WebViews, native modules, or the JavaScript bridge injected into custom apps and the formplayer.

**See also:** [../AGENTS.md](../AGENTS.md) (monorepo overview), [../formulus-formplayer/AGENTS.md](../formulus-formplayer/AGENTS.md) (form UI bundle and WebView constraints).

**User-facing docs:** [Formulus](https://opendataensemble.org/docs/reference/formulus) on [opendataensemble.org](https://opendataensemble.org/).

---

## What this package is

- **Formulus** is the **offline-first** mobile client for ODE: it renders **JSON Forms** via the embedded **formplayer** WebView, runs **custom application** bundles in separate WebViews, and synchronizes with **Synkronus**.
- It is **not** the admin console (that is **Portal**) and not the sync server (that is **Synkronus**).

---

## Layout (where to look)

| Area | Purpose |
|------|---------|
| `src/webview/` | **Bridge contract** — [`FormulusInterfaceDefinition.ts`](src/webview/FormulusInterfaceDefinition.ts) (source of truth for `window.formulus` / injected API). [`FormulusMessageHandlers.ts`](src/webview/FormulusMessageHandlers.ts), [`FormulusWebViewHandler.ts`](src/webview/FormulusWebViewHandler.ts). |
| `scripts/generateInjectionScript.ts` | Generates injection / loader script from the interface definition. |
| `src/screens/`, `src/navigation/` | App screens and routing. |
| Android / iOS | Native projects; **formplayer** static assets: `android/app/src/main/assets/formplayer_dist/`, `ios/formplayer_dist/` (see formplayer AGENTS for `build:rn`). |

---

## Custom apps and formplayer

- **Custom apps** are HTML/JS/CSS bundles loaded from Synkronus; they receive the **Formulus** injected API (see interface definition). Authors do not need this monorepo — public docs and [custom_app](https://github.com/OpenDataEnsemble/custom_app) describe usage.
- **Formplayer** is a sibling package; after changing `FormulusInterfaceDefinition.ts`, run **`npm run sync-interface`** (or build) in **formulus-formplayer** so its copy stays aligned.

---

## Changing the bridge

1. Edit [`FormulusInterfaceDefinition.ts`](src/webview/FormulusInterfaceDefinition.ts).
2. Implement **native** handling in the WebView message pipeline.
3. **Sync** the formplayer copy and update any consumers (see [formulus-formplayer/AGENTS.md](../formulus-formplayer/AGENTS.md)).

---

## Build and run

See [README.md](README.md): Metro, `npm run android` / `ios`, Android **Notifee** vendor step, iOS **Pods**. For CI and formatting, see root [README.md](../README.md) and [.github/CICD.md](../.github/CICD.md).
26 changes: 26 additions & 0 deletions packages/components/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# @ode/components — AI & developer guide

**When to use this doc:** You are changing **shared React UI** consumed by Portal or other ODE frontends.

**See also:** [../../AGENTS.md](../../AGENTS.md). **Tokens:** [../tokens/AGENTS.md](../tokens/AGENTS.md).

**User-facing docs:** [Components](https://opendataensemble.org/docs/reference/components) on [opendataensemble.org](https://opendataensemble.org/).

---

## What this package is

- **`@ode/components`** is shared UI built on **React** and **@ode/tokens** (and related styling patterns). Prefer **tokens** over hard-coded colors/spacing where a token exists.

---

## Scope

- **Change here** when the component is **reusable** across apps (Portal, future web UIs).
- **Change in Portal only** when the UI is **Portal-specific** (single-app layout, admin-only flows).

---

## Build / dev

See [README.md](README.md): `npm install`, storybook or dev commands as documented. Keep **lint/format** consistent with the rest of the monorepo (see root [README.md](../../README.md)).
26 changes: 26 additions & 0 deletions packages/tokens/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# @ode/tokens — AI & developer guide

**When to use this doc:** You are changing **design tokens** (colors, spacing, typography) built with **Style Dictionary**, or fixing build issues for downstream packages.

**See also:** [../../AGENTS.md](../../AGENTS.md). **Consumers:** [formulus-formplayer](../../formulus-formplayer/AGENTS.md), [components](../components/README.md).

**User-facing docs:** [Components](https://opendataensemble.org/docs/reference/components) (tokens usage appears in the broader UI system).

---

## What this package is

- **`@ode/tokens`** outputs token artifacts used by **formulus-formplayer** (theme) and **@ode/components** (shared UI).

---

## Build

- From `packages/tokens/`: `npm install`, then `npm run build` (or the `prepare` script as invoked by npm).
- **Order:** Other packages **depend on tokens built** — install tokens before formplayer/components when setting up a fresh clone (see formplayer AGENTS).

---

## Changing tokens

- Edit tokens in `src/` (see [README.md](README.md) for structure), rebuild, then verify consumers (formplayer theme, components) for visual regressions.
32 changes: 32 additions & 0 deletions synkronus-cli/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Synkronus CLI — AI & developer guide

**When to use this doc:** You are changing the **`synk`** command-line tool (Go) or its packaging.

**See also:** [../AGENTS.md](../AGENTS.md).

**User-facing docs:** [Synkronus CLI](https://opendataensemble.org/docs/reference/synkronus-cli) on [opendataensemble.org](https://opendataensemble.org/).

---

## What this package is

- **synkronus-cli** provides **`synk`** — scriptable access to the same Synkronus **HTTP API** as Portal and Formulus: login, sync, app bundle upload/download, export (e.g. Parquet), config.

---

## Layout

- **Entry:** `cmd/synkronus/` (or as structured in this repo — see `README.md`).
- **Config:** `~/.synkronus.yaml` by default; `synk config use` for multiple profiles (see [README.md](README.md)).

---

## License note

The CLI may be **GPL-2.0-or-later** until the QR dependency cleanup described in the root [README.md](../README.md) and [FOLLOWUP-custom-qrcode-writer.md](FOLLOWUP-custom-qrcode-writer.md). **Do not** change license without maintainer intent.

---

## Install / build

From [README.md](README.md): `go install`, or build from source. Installation scripts are linked from the root [README.md](../README.md).
27 changes: 27 additions & 0 deletions synkronus-portal/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Synkronus Portal — AI & developer guide

**When to use this doc:** You are changing the **React + TypeScript + Vite** web UI that administers Synkronus (users, bundles, exports, observations).

**See also:** [../AGENTS.md](../AGENTS.md) (monorepo map). **Backend:** [../synkronus/AGENTS.md](../synkronus/AGENTS.md).

**User-facing docs:** [Synkronus Portal](https://opendataensemble.org/docs/reference/synkronus-portal) on [opendataensemble.org](https://opendataensemble.org/).

---

## What this package is

- **Portal** is a **standard API client** of Synkronus — same REST surface as the CLI; no special server-side shortcuts.
- **Dev:** Vite dev server with hot reload; **prod:** static build served (often via Docker/nginx in this repo’s compose setup).

---

## Operational details

- **Setup, Docker vs dockerless, ports, troubleshooting:** See [README.md](README.md) — it is the canonical long-form guide (this file avoids duplicating it).
- **API proxy:** Dev typically proxies `/api` to the Go backend (see `vite.config.ts`).

---

## Quick commands

From `synkronus-portal/`: `npm install`, `npm run dev`, `npm run lint`, `npm run format` — align with root [README.md](../README.md) and CI.
40 changes: 40 additions & 0 deletions synkronus/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Synkronus — AI & developer guide

**When to use this doc:** You are working on the **Go** HTTP API: sync, auth, app bundles, export, attachments, or database layer.

**See also:** [../AGENTS.md](../AGENTS.md).

**User-facing docs:** [Synkronus server](https://opendataensemble.org/docs/reference/synkronus-server), [REST API](https://opendataensemble.org/docs/reference/rest-api/overview), deployment guides linked from the docs site.

---

## What this package is

- **Synkronus** is the **central synchronization and coordination service** for ODE: JWT auth, pull/push sync, app bundle storage, exports, attachments.
- **Clients** (Formulus, Portal, CLI) all use the **same** public API — no hidden admin-only backdoors.

---

## Layout

```
cmd/synkronus/ # Entry point
internal/ # api, handlers, models, repository, services
pkg/ # Shared libraries (auth, database, middleware, openapi, ...)
```

- **OpenAPI / Swagger:** typically served under `/openapi` (see running server and [README.md](README.md)).

---

## Local development

- **Prerequisites:** Go 1.22+, PostgreSQL, configured env (see [README.md](README.md) and [DOCKER.md](DOCKER.md)).
- **Run:** `go run cmd/synkronus/main.go` (or build from `cmd/synkronus`) with a valid `DB_CONNECTION` and secrets.
- **Docker:** [DOCKER.md](DOCKER.md); production patterns in [DEPLOYMENT.md](DEPLOYMENT.md).

---

## Related repos

- **Synkronus Portal** and **CLI** live in this monorepo as **clients** of this API — see their `AGENTS.md` files.
Loading