EventType V1

Overview

Events capture location, event time, who recorded the information, and structured data based on the event type. An Event Type is used to describe specific data to be collected using JSON Schema to specify the data capture format. A schema is defined in the “schema” field, and the UI layout is described in the “definition” field.

Architecture

The eventtype data description is defined using JSONSchema. Additionally, we developed our own definition system in JSON that defines the presentation of JSONSchema in our web UI.

Key Design Decisions

  • Template-based rendering: V1 uses Jinja2 templates to dynamically inject choice lists at render time

  • Dual structure: Separates data schema from UI layout definition

  • Runtime choice resolution: Choice lists are resolved from the database during schema rendering

  • Custom UI definition: Uses a proprietary format for UI layout specification

Limitations and Issues

Schema Validation Challenges

  • Pre-render validation impossible: Schemas cannot be validated as JSON until after template rendering

  • Template syntax errors: Invalid Jinja2 syntax in schemas causes runtime failures

  • Choice dependency: Schema validation requires database access to resolve choice lists

  • No static analysis: Tools cannot analyze schemas without database context

Template System Issues

  • Runtime rendering: Choice lists are injected at request time, causing performance overhead

  • Complex syntax: Template markers like {{enum___field___names}} are non-standard and error-prone

  • Debugging difficulty: Template errors are hard to trace and debug

  • Version control: Template variables make schema diffs difficult to review

UI Definition Problems

  • Proprietary format: Custom definition syntax is not standardized

  • Limited flexibility: UI layout options are constrained by the custom format

  • Maintenance burden: Custom UI system requires specialized knowledge

  • Inconsistent behavior: UI rendering can be unpredictable across different scenarios

Schema Section

The Schema section defines the data structure using JSON Schema with template variables for dynamic content.

Choice and Dynamic Choice Lists

Choice Lists

Choice lists populate dropdowns and checkbox groups from the Choice database table. Each choice has:

  • value: The actual value stored in the event data

  • display: The human-readable text shown in the UI (enables future localization)

Template Syntax:

  • {{enum___field_name___values}} - Array of choice values

  • {{enum___field_name___names}} - Array of display names

  • {{enum___field_name___map}} - Dictionary mapping values to display names

Example:

{
  "carcassrep_species": {
    "type": "string",
    "title": "Species",
    "enum": {{enum___carcassrep_species___values}},
    "enumNames": {{enum___carcassrep_species___names}}
  }
}

Dynamic Choice Lists

Dynamic choices are populated from custom database queries defined in the DynamicChoice model. These return “value”, “display” tuples where the value is typically a UUID reference to another database record.

Template Syntax:

  • {{query___field_name___values}} - Array of dynamic choice values

  • {{query___field_name___names}} - Array of dynamic choice display names

Use Cases:

  • Subject selection from active subjects

  • Location-based choices

  • User-specific options

  • Time-sensitive data

Definition Section

The Definition section controls how the UI renders the form fields. It uses a custom JSON format to specify:

  • Field ordering and grouping

  • Bootstrap CSS classes for responsive layout

  • Field-specific UI properties

Definition Structure

{
  "definition": [
    {
      "key": "field_name",
      "htmlClass": "col-lg-6"
    }
  ]
}

Available Properties

  • key: References a property from the schema section

  • htmlClass: Bootstrap CSS classes for responsive layout

    • col-lg-6: Half-width on large screens

    • col-lg-12: Full-width on large screens

    • col-md-4: One-third width on medium screens

  • title: Custom field title (overrides schema title)

  • description: Additional field description

  • readonly: Makes field read-only in the UI

Layout Examples

{
  "definition": [
    {
      "key": "species",
      "htmlClass": "col-lg-6",
      "title": "Animal Species"
    },
    {
      "key": "location",
      "htmlClass": "col-lg-12",
      "description": "Enter GPS coordinates or select from map"
    }
  ]
}

Complete Example Schema

Carcass Report EventType

This example shows a complete V1 eventtype for wildlife carcass reporting:

{
  "schema": {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Carcass Report (carcass_rep)",
    "type": "object",
    "properties": {
      "carcassrep_species": {
        "type": "string",
        "title": "Species",
        "enum": {{enum___carcassrep_species___values}},
        "enumNames": {{enum___carcassrep_species___names}}
      },
      "carcassrep_sex": {
        "type": "string",
        "title": "Sex of Animal",
        "enum": {{enum___carcassrep_sex___values}},
        "enumNames": {{enum___carcassrep_sex___names}}
      },
      "carcassrep_ageofanimal": {
        "type": "string",
        "title": "Age of Animal",
        "enum": {{enum___carcassrep_ageofanimal___values}},
        "enumNames": {{enum___carcassrep_ageofanimal___names}}
      },
      "carcassrep_ageofcarcass": {
        "type": "string",
        "title": "Age of Carcass",
        "enum": {{enum___carcassrep_ageofcarcass___values}},
        "enumNames": {{enum___carcassrep_ageofcarcass___names}}
      },
      "carcassrep_trophystatus": {
        "type": "string",
        "title": "Trophy Status",
        "enum": {{enum___carcassrep_trophystatus___values}},
        "enumNames": {{enum___carcassrep_trophystatus___names}}
      },
      "carcassrep_causeofdeath": {
        "type": "string",
        "title": "Cause of Death",
        "enum": {{enum___carcassrep_causeofdeath___values}},
        "enumNames": {{enum___carcassrep_causeofdeath___names}}
      }
    }
  },
  "definition": [
    {
      "key": "carcassrep_species",
      "htmlClass": "col-lg-6"
    },
    {
      "key": "carcassrep_sex",
      "htmlClass": "col-lg-6"
    },
    {
      "key": "carcassrep_ageofanimal",
      "htmlClass": "col-lg-6"
    },
    {
      "key": "carcassrep_ageofcarcass",
      "htmlClass": "col-lg-6"
    },
    {
      "key": "carcassrep_trophystatus",
      "htmlClass": "col-lg-6"
    },
    {
      "key": "carcassrep_causeofdeath",
      "htmlClass": "col-lg-6"
    }
  ]
}

Rendered Schema (After Template Processing)

After the Jinja2 template is processed with actual choice data, the schema becomes valid JSON:

{
  "schema": {
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title": "Carcass Report (carcass_rep)",
    "type": "object",
    "properties": {
      "carcassrep_species": {
        "type": "string",
        "title": "Species",
        "enum": ["elephant", "lion", "rhino"],
        "enumNames": ["African Elephant", "African Lion", "White Rhino"]
      }
    }
  }
}

Migration to V2

Why Migrate?

V2 eventtypes address the major limitations of V1:

  • Static validation: Schemas can be validated without database access

  • Standard references: Uses JSON Schema $ref instead of custom templates

  • Better UI system: Standardized UI definition format

  • Improved performance: No runtime template rendering

  • Tool compatibility: Works with standard JSON Schema tools

Migration Steps

  1. Convert template variables to $ref: Replace {{enum___field___values}} with $ref URLs

  2. Update UI definition: Convert custom definition format to V2 UI structure

  3. Test validation: Ensure schemas validate correctly before deployment

  4. Update version field: Set version = "2" in the EventType model

Example Migration

V1 Template:

{
  "enum": {{enum___carcassrep_species___values}},
  "enumNames": {{enum___carcassrep_species___names}}
}

V2 Reference:

{
  "anyOf": [
    {
      "$ref": "https://api.example.com/v2.0/schemas/choices.json?field=carcassrep_species"
    }
  ]
}

For detailed migration guidance, see EventType V2 Documentation.

Best Practices

Schema Design

  • Use descriptive field names: Follow consistent naming conventions (e.g., carcassrep_species)

  • Provide clear titles: Use human-readable titles for all fields

  • Group related fields: Use consistent prefixes for related fields

  • Validate template syntax: Test Jinja2 templates before deployment

Choice Management

  • Consistent choice values: Use stable, URL-safe values for choices

  • Meaningful display names: Provide clear, localized display text

  • Active choice management: Regularly review and update choice lists

  • Document choice dependencies: Keep track of which eventtypes use which choices

UI Layout

  • Responsive design: Use appropriate Bootstrap classes for different screen sizes

  • Logical field ordering: Arrange fields in a logical workflow order

  • Consistent spacing: Use consistent column widths for visual harmony

  • Accessibility: Ensure form fields are properly labeled and accessible

Troubleshooting

Common Issues

Template Rendering Errors

Problem: Schema fails to render with Jinja2 errors Solution:

  • Check template syntax for typos in {{enum___field___values}} format

  • Verify choice field names exist in the database

  • Test template rendering in development environment

Invalid JSON Schema

Problem: Rendered schema is not valid JSON Solution:

  • Ensure all template variables are properly closed

  • Check for missing commas or brackets

  • Validate rendered schema with JSON Schema validator

Choice List Not Populating

Problem: Dropdown shows empty or incorrect options Solution:

  • Verify choice records exist in the database

  • Check choice field names match template references

  • Ensure choices are marked as active (is_active=True)

UI Layout Issues

Problem: Form fields not displaying correctly Solution:

  • Verify definition keys match schema property names

  • Check Bootstrap CSS classes are valid

  • Ensure definition array is properly formatted

Debugging Tips

  1. Test template rendering: Use Django shell to test template rendering

  2. Validate JSON: Use online JSON validators for rendered schemas

  3. Check database: Verify choice data exists and is active

  4. Review logs: Check application logs for template rendering errors

Legacy Support

V1 eventtypes are maintained for backward compatibility but are not recommended for new implementations. Existing V1 eventtypes should be migrated to V2 when possible to take advantage of improved validation, performance, and tooling support.