top of page

Design Notes: A Capture-First Client for Tree Risk Assessments

  • Roger Erismann
  • Jan 29
  • 2 min read

Updated: Jan 31

Initial UI notes
Initial UI notes

Instead of treating the device as a form entry tool, we treat it as a capture device. The mobile app records speech and photos and defers interpretation to the server. The client collects evidence; the backend extracts structure and generates the report.


This leads to an intentionally asymmetric architecture. The client is responsible for navigation, media capture, local storage, and synchronization. The server is responsible for understanding what the recordings mean and producing filled form data and narrative text. No domain-specific extraction logic lives on the device.


Work is organized around a job rather than a document. A job represents the full lifecycle of one assessment and moves through explicit states (draft, submitted, review, final, archived). Edits are only allowed in specific stages. This state machine exists mostly to make offline behavior predictable: uploads can retry, processing can take time, and users can safely resume work without worrying about partial submissions or conflicting edits.


During capture, the UI deliberately avoids structured inputs. Each section presents “memory aides,” which are display-only prompts that remind the operator what to talk about. They are not checklists or fields client. The operator records observations naturally; the server later extracts the structured data. Structure is recovered after the fact rather than enforced at entry time.


The interface itself is defined by a template. Sections, ordering, and memory aides come from versioned JSON that the app renders dynamically. Although Flutter is declarative, most Flutter apps still hardcode their forms in Dart and require a new release whenever the form changes. Here, the assessment structure is configuration. The app behaves more like a small runtime: it knows how to display sections and capture media, but not what the assessment contains.


Each job is tied to the template version it started with so the client and server always agree on structure. This reduces coupling and avoids frequent client releases. The implementation uses Flutter primarily to maintain a single Android/iOS codebase and for straightforward access to camera and microphone APIs. A local-only MVP currently validates the capture workflow with job creation, section-based recording, photo capture, and on-device storage, without server integration IMPLEMENTATION_NOTES. The goal is to prove the interaction model before adding backend concerns.


In practice, the client behaves less like a form app and more like a structured recorder. It stays stable while the server evolves. The device focuses on reliably collecting evidence; interpretation remains a backend problem.

Recent Posts

See All

Comments


© 2026 hammerdirt 

Contact roger[at]hammerdirt.solutions
bottom of page