Skip to content

henryennis/GabApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GabApp Icon
GabApp

Clinical balance and mobility assessment using smartphone sensors


Overview

GabApp is a mobile application that enables clinicians to conduct standardised balance and gait assessments using only a patient's smartphone. It leverages the device's built-in gyroscope, accelerometer, magnetometer, and pedometer to collect high-frequency sensor data during timed clinical tests. Results are packaged as a JSON attachment and emailed directly to the clinician via the SendGrid API, eliminating the need for specialised laboratory equipment.

Screenshots

Home - test selection    Preparation checklist    Step-by-step instructions    Active sensor measurement    Submit results

Home  |  Prepare  |  Instructions  |  Assessment  |  Submit

Architecture

User Flow

flowchart LR
    A["Select Test"] --> B["Prepare"]
    B --> C["Instructions"]
    C --> D["Assessment"]
    D --> E["Submit"]
    E -->|"Email via SendGrid"| F["Clinician Inbox"]
    E -.->|"Retake"| D
Loading

Sensor Data Pipeline

flowchart TD
    subgraph Device Sensors
        G["Gyroscope"]
        Ac["Accelerometer"]
        M["Magnetometer"]
        P["Pedometer"]
    end

    G & Ac & M & P -->|"100 Hz sampling"| Buffer["In-Memory Log Buffer\n(ref-based, no re-renders)"]
    Buffer -->|"JSON serialise"| Encode["Base64 Encode"]
    Encode -->|"Attachment"| SG["SendGrid API"]
    SG -->|"Email"| Clinician["Clinician"]

    Config["clinicians-config.yaml"] -->|"Test definitions\nSampling rate\nRecipient email"| App["App Runtime"]
Loading

Tech Stack

Category Technology
Framework React Native 0.79 + Expo 53
Language TypeScript 5.8 (strict mode)
Routing Expo Router, file-based routing with grouped layouts
Sensors expo-sensors (gyroscope, accelerometer, magnetometer, pedometer)
Voice expo-speech (TTS) + expo-speech-recognition (STT)
Email SendGrid API via Axios
Forms React Hook Form + Zod validation
Config YAML-driven test definitions parsed at build time
State React Context (PatientTestingProvider)
Storage react-native-mmkv for local key-value persistence
Styling Material Design 3 tokens, DM Sans / DM Mono typography
Animation Moti + React Native Reanimated 3
Build / CI EAS Build with development, staging, and production profiles

Key Features

  • Configuration-driven tests: clinicians define test title, instructions, and duration in a YAML file; no code changes needed
  • High-frequency sensor capture: configurable sampling rate (default 100 Hz) across gyroscope, accelerometer, magnetometer (calibrated + uncalibrated), and pedometer
  • Ref-based data buffering: sensor readings accumulate in useRef buffers to avoid expensive re-renders during active collection
  • Voice narration: text-to-speech announces test instructions and completion, hands-free operation during assessment
  • Voice command support: speech recognition integration for hands-free test control
  • Automatic email delivery: sensor data is serialised to JSON, Base64-encoded, and sent as an email attachment via SendGrid
  • Multi-environment support: separate .env files and EAS build profiles for development, staging, and production
  • Zod-validated config: all environment variables and YAML configuration are runtime-validated with Zod schemas
  • Accessibility: ARIA roles, labels, and hints throughout; colour contrast meets WCAG guidelines
  • Screen keep-awake: prevents the device from sleeping during active data collection

Project Structure

src/
  app/                                # Expo Router file-based screens
    index.tsx                         # Home, test selection
    _layout.tsx                       # Root layout, font loading, providers
    (assessment)/                     # Assessment flow route group
      prepare.tsx                     # Safety checklist
      instructions.tsx                # Step-by-step guidance
      assessment.tsx                  # Active sensor collection
      submit.tsx                      # Results review and email submission
  components/
    theme.ts                          # Material Design 3 colour/typography/spacing tokens
  lib/
    email.ts                          # SendGrid email with Base64 JSON attachment
    speech-commander.ts               # Singleton speech recognition manager
    load-domain-configuration.js      # YAML config parser
    storage.tsx                       # MMKV storage wrapper
    react/
      use-sensors.ts                  # Multi-sensor hook with configurable sampling
      use-patient-testing.tsx         # Context provider for test session state
      use-voice-command.ts            # Voice command hook
  types/
    index.ts                          # Shared TypeScript definitions
clinicians-config.yaml                # Clinician-defined test configuration
env.js                                # Build-time env loading + Zod validation
app.config.ts                         # Expo app configuration

Getting Started

Prerequisites

Setup

# Clone
git clone https://github.com/henryennis/gabapp.git
cd gabapp

# Install dependencies
pnpm install

# Configure environment (copy the example and fill in your values)
cp .env.example .env.development

# Start the development server
pnpm start

Run on device / simulator

pnpm ios          # iOS simulator
pnpm android      # Android emulator
pnpm web          # Web browser

Configuration

Test definitions are managed in clinicians-config.yaml, allowing clinicians to customise assessments without modifying application code:

sensor-sampling-rate-hz: 100

clinician-email: clinician@example.com

clinical-tests:
  - title: 'Standing Test'
    instructions: >
      Stand still with your feet together on a firm, flat surface.
      The sensors will measure your postural sway and balance stability.
    duration: 60000 # milliseconds

Environment-specific secrets (SendGrid API key, sender email) are configured via .env.development, .env.staging, and .env.production. See .env.example for the required variables.

How It Works

  1. Configure: A clinician defines tests (title, instructions, duration) and the recipient email in clinicians-config.yaml. The YAML is parsed at build time, validated against a Zod schema, and injected into the app via Expo Constants.

  2. Select: The patient opens the app and selects a test from the home screen. The selected test is stored in React Context (PatientTestingProvider).

  3. Prepare and instruct: Two guided screens walk the patient through safety checks and phone placement (front pocket, screen facing body).

  4. Assess: On pressing "Start", the useLogging hook subscribes to all sensors at the configured sampling rate. Readings are timestamped and accumulated in a useRef buffer to avoid re-renders. expo-keep-awake prevents the screen from sleeping. A timer fires when the test duration elapses.

  5. Submit: The patient enters a referral code and accepts the privacy agreement. The sensor data is serialised to JSON, Base64-encoded, attached to an email, and sent to the clinician via the SendGrid API.

Future Improvements

  • Offline-first storage: queue results locally and sync when connectivity resumes
  • On-device signal processing: compute sway path length, RMS acceleration, and frequency-domain features before submission
  • Clinician dashboard: web portal for longitudinal patient tracking and trend visualisation
  • External sensor integration: Bluetooth pairing with research-grade IMU devices for validation studies
  • HIPAA-compliant pipeline: replace email delivery with a secure API endpoint and encrypted storage

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors