- Python 51.3%
- Kotlin 29.5%
- TypeScript 16.2%
- DM 2.1%
- Makefile 0.5%
- Other 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
continuous-integration/drone/push Build is passing
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> |
||
| android_code | ||
| backend_code | ||
| debugtools | ||
| frontend_code | ||
| server_deploy_config | ||
| .drone.yml | ||
| .gitignore | ||
| AGENTS.md | ||
| BUSINESS.md | ||
| README.md | ||
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/infodebug pagebackend_code/- FastAPI backend, websocket/pubsub, SQLAlchemy models, Alembic migrations, OpenAPI generationandroid_code/- Kotlin Android tracker app with generated API client and device reliability controlsdebugtools/- offline CSV plotting tools and experiment analysesserver_deploy_config/- deployment files such as systemd and nginx configuration
Subproject Guides
frontend_code/AGENTS.mdbackend_code/AGENTS.mdandroid_code/AGENTS.mddebugtools/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_HOMEorANDROID_SDK_ROOTmust point to a valid SDKandroid_code/local.propertiescan override SDK discovery- if Gradle gets stuck on a stale JDK/JRE path,
./gradlew --stopcan 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:
- update backend models/routes
- regenerate OpenAPI
- regenerate frontend and Android clients
- 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:
- factory reset the device
- avoid adding accounts during setup
- on some Motorola devices, remove the SIM before provisioning to avoid automatic account creation
- install the APK
- run
adb shell dpm set-device-owner app.furmeet.vantracker/.TrackerDeviceAdminReceiver - confirm the app shows
Device owner: yes
APK Update Channel
The Android self-updater expects:
https://gpsvan.furmeet.app/android/app.apkhttps://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.
timestamprepresents the device-provided logical event time used by the upload payload.uploaded_atis currently initialized as a clone oftimestampso 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.mdfiles) - 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.