docs

Architecture

Complete architecture documentation for ODE, including sync protocol, database design, and extension points.

:::tip Audience Hosting / IT? See Server Architecture for IT.
Product overview? See Architecture Overview. :::

System Overview

ODE follows a client-server architecture designed for offline-first data collection. High-level component relationships are documented in Architecture Overview. Server installation layout is in Server Architecture for IT.

Components

Formulus

React Native mobile application providing:

Technology Stack:

Synkronus

Go backend server providing:

Technology Stack:

Formplayer

React web application providing:

Technology Stack:

Synkronus CLI

Go command-line utility providing:

Technology Stack:

ODE Desktop

Tauri desktop application providing:

Technology Stack:

See ODE Desktop Development.

Data Flow

Observation Creation

  1. User fills out form in Formplayer (WebView)
  2. Formplayer validates and submits to Formulus
  3. Formulus creates observation in local database (WatermelonDB)
  4. Observation is marked for synchronization

Synchronization

  1. Pull Phase: Formulus requests changes from server
    • Server returns records with change_id > client_last_seen
    • Client applies changes to local database
  2. Push Phase: Formulus sends local changes to server
    • Client sends records with transmission ID for idempotency
    • Server validates and stores records
    • Server returns success/failure for each record
  3. Attachment Sync: Separate phase for binary files
    • Upload: Client uploads attachments referenced in observations
    • Download: Client downloads attachments referenced in new observations

Conflict Resolution

Conflicts are detected using hash comparison:

Sync Protocol

Change Detection

Uses cursor-based approach with change_id:

Advantages:

Record Model

Each form submission is an entity:

Attachment Handling

Attachments are managed separately:

See the Synchronization guide for more details.

Database Design

Observations Table

Column Type Description
id UUID Primary key
schema_type String Form type identifier
schema_version String Form version
data JSONB Form data
hash String Computed hash
change_id Integer Strictly increasing change ID
last_modified Timestamp Last modification time
last_modified_by String Username
deleted Boolean Soft delete flag
origin_client_id String Creating client ID
created_at Timestamp Creation time

Attachments Table

Column Type Description
id String Attachment ID (UUID)
hash String SHA-256 hash
size Integer File size in bytes
mime_type String MIME type
change_id Integer Change ID for sync
last_modified Timestamp Last modification time
sync_state String Sync state

Security Architecture

Authentication

Authorization

Data Security

See Security reference for deployment checklist and mobile storage details.

Performance Considerations

Client-Side

Server-Side

Extension Points

Custom Renderers

Create custom question type renderers:

  1. Define result interface in FormulusInterfaceDefinition.ts
  2. Add interface method
  3. Implement React component
  4. Register renderer
  5. Add mock implementation

Custom Applications

Build custom web applications:

  1. Create HTML/CSS/JavaScript files
  2. Include Formulus load script
  3. Use Formulus JavaScript interface
  4. Package as app bundle
  5. Upload to server

Plugins

ODE’s plugin system allows for extending functionality without modifying core code. The plugin architecture is under active development and will be documented as it evolves.

Current extension points: