No description
  • Python 51.3%
  • Kotlin 29.5%
  • TypeScript 16.2%
  • DM 2.1%
  • Makefile 0.5%
  • Other 0.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Adler O S Neves bae80f892c
All checks were successful
continuous-integration/drone/push Build is passing
fix: extend tracker marker fade window
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-01 22:33:57 -03:00
android_code feat: add ETA overlay and manual app update 2026-06-01 02:35:12 -03:00
backend_code fix: cast ETA prediction scalars 2026-06-01 21:45:11 -03:00
debugtools fix: in-progress ETA arrival prediction 2026-06-01 01:11:58 -03:00
frontend_code fix: extend tracker marker fade window 2026-06-01 22:33:57 -03:00
server_deploy_config feat: add background ETA worker 2026-06-01 02:15:30 -03:00
.drone.yml feat: add background ETA worker 2026-06-01 02:15:30 -03:00
.gitignore fix: partial file import 2026-06-01 20:06:04 -03:00
AGENTS.md fix: LocationCallback to PendingIntent 2026-03-21 01:01:01 -03:00
BUSINESS.md feat: add tracker recovery diagnostics 2026-04-05 23:57:55 -03:00
README.md feat: add tracker recovery diagnostics 2026-04-05 23:57:55 -03:00

furmeet-gpstracked

Live shuttle tracking for a furry convention.

This repository contains the web frontend, backend API, Android tracker app, and offline analysis tools used to show shuttle vans as live-updating points on a map and to analyze device behavior after field tests.

Purpose

The product is intended to support real event logistics for a convention of roughly 1300 to 2500 attendees.

Key goals:

  • show current shuttle positions with operationally useful freshness
  • keep tracker devices alive and reliable in the field
  • preserve enough observability to diagnose stale data, battery issues, network gaps, and clock drift
  • keep backend, frontend, and Android contracts aligned

Business context is documented in BUSINESS.md. Technical agent guidance is documented in AGENTS.md and the subproject AGENTS.md files.

Repository Structure

  • frontend_code/ - Next.js frontend for the live map and /info debug page
  • backend_code/ - FastAPI backend, websocket/pubsub, SQLAlchemy models, Alembic migrations, OpenAPI generation
  • android_code/ - Kotlin Android tracker app with generated API client and device reliability controls
  • debugtools/ - offline CSV plotting tools and experiment analyses
  • server_deploy_config/ - deployment files such as systemd and nginx configuration

Subproject Guides

  • frontend_code/AGENTS.md
  • backend_code/AGENTS.md
  • android_code/AGENTS.md
  • debugtools/AGENTS.md

If you are editing code in one of those folders, read the nearest AGENTS.md first.

Common Commands

Frontend

Run from frontend_code/:

yarn
yarn build

Useful commands:

yarn dev
yarn lint
yarn openapi-regenerate

Backend

Run from backend_code/:

python3 -m py_compile app.py
make makemigrations
make migrate

Useful commands:

make devserver
make serve
make openapijson

Android

Run from android_code/:

./gradlew :app:test :app:assembleDebug

Useful commands:

./gradlew :app:assembleRelease
./gradlew :app:generateOpenApiClient
./gradlew -PversionCodeInt=123 -PversionNameStr=2026.03.20.01.18 :app:assembleDebug

Android notes:

  • ANDROID_HOME or ANDROID_SDK_ROOT must point to a valid SDK
  • android_code/local.properties can override SDK discovery
  • if Gradle gets stuck on a stale JDK/JRE path, ./gradlew --stop can clear it

Debugtools

Run from debugtools/:

python3 -m py_compile plot.py
ruff check plot.py
python3 ./plot.py ./tracker_history.csv 1 "2026-03-12T01:09:00-03:00" "2026-03-12T21:00:00-03:00"

API And Generated Code

Generated artifacts live in:

  • frontend_code/src/backend_api_client/*
  • android_code/app/src/main/java/app/furmeet/vantracker/api/generated/*
  • android_code/app/generated/openapi/*
  • backend_code/openapi.json

When backend contracts change:

  1. update backend models/routes
  2. regenerate OpenAPI
  3. regenerate frontend and Android clients
  4. validate each affected subproject

Timestamps And Clock Handling

  • Backend API timestamps should be explicit UTC-aware values
  • Frontend uses a server-adjusted clock for elapsed/staleness logic
  • Android also syncs clock offset from the backend and uses that offset for operational timing

Reliability Notes

The Android app includes several reliability-oriented features because field behavior matters:

  • foreground tracking service
  • location delivery tuned for field reliability, with the current implementation using the known-good callback path
  • configurable upload intervals
  • optional aggressive wake lock
  • periodic server clock resync
  • service watchdog recovery
  • delayed self-restart scheduling after package replacement
  • battery-optimization prompts and OEM guidance
  • APK-based self-update via android/app.json
  • device-owner aware UI and provisioning path

Telemetry currently includes battery percentage, absolute battery charge, inferred full/cutoff bounds on the backend, network type, and app version. It also now includes recovery-oriented diagnostics such as power-save state, charging state, interactive state, battery-optimization ignore status, service-start count, location-request count, and the last recorded recovery reason.

These recovery diagnostics exist to explain field failures and recoveries, not only to confirm that a tracker is alive.

At the moment, the known-good GPS collection path is the in-process LocationCallback approach. If location delivery is changed again in the future, treat reliability on older devices as the primary acceptance criterion.

These behaviors are part of product operation, not incidental implementation details.

Managed Device Provisioning

The intended deployment model is a dedicated Android tracker device provisioned as device owner.

Typical flow:

  1. factory reset the device
  2. avoid adding accounts during setup
  3. on some Motorola devices, remove the SIM before provisioning to avoid automatic account creation
  4. install the APK
  5. run adb shell dpm set-device-owner app.furmeet.vantracker/.TrackerDeviceAdminReceiver
  6. confirm the app shows Device owner: yes

APK Update Channel

The Android self-updater expects:

  • https://gpsvan.furmeet.app/android/app.apk
  • https://gpsvan.furmeet.app/android/app.json

The external app.json is used to discover updates cheaply. The APK also embeds its own identity manifest asset so the installed app can describe itself locally.

Telemetry History

Tracker updates are stored append-only in tracker_history.

  • timestamp represents the device-provided logical event time used by the upload payload.
  • uploaded_at is currently initialized as a clone of timestamp so historical rows stay non-null during the schema transition.

This makes it easier to evolve the meaning of upload-time versus event-time later without losing existing data continuity.

This self-update plus device owner flow is part of the intended operational model for dedicated tracker devices, not just a development convenience.

Documentation

Keep documentation updated whenever code changes alter:

  • product behavior or operational assumptions (BUSINESS.md)
  • technical workflows, architecture, commands, or constraints (AGENTS.md files)
  • user or operator workflows (README.md)

When in doubt, update the documentation in the same change as the code instead of leaving the clarification for later.

The goal is to preserve both the technical workflow and the reason the system exists.