Back to Projects
Sentinel
Period2025 - 2026
TeamSolo developer (API + Mobile client)
Contribution100%
RoleFull-stack & mobile developer: engineered the system architecture, Go backend API, and Flutter mobile client.
Sentinel is a safety dead man's switch platform engineered for high-risk situations (solo travel, remote fieldwork, personal safety). Users initiate timed safety check-in events accompanied by emergency contacts, GPS coordinates, and encrypted attachment files. If the user fails to check in before the timer elapses, the backend automatically dispatches alert notifications via AWS SES with the user's last known location and uploaded documents.
Go 1.24GinPostgreSQLGORMRedis 7FlutterDartRiverpodAWS SESAWS S3
Key Features
1
Resilient Go Backend & High-Availability Timers
- Dual-trigger timer scheduling: utilizes Redis Keyspace Notifications (notify-keyspace-events Ex) for real-time sub-second expiration triggers.
- Secondary fallback polling worker sweeps PostgreSQL every 30 seconds to recover any missed expiration events in case of Redis restart.
- Atomic database row-level locking (SELECT FOR UPDATE SKIP LOCKED) guarantees that multiple API replicas never trigger duplicate alert dispatches.
2
Persistent Mobile Safety & Background GPS Sync
- Native Android Foreground Service maintains the local countdown and persistent GPS location polling even when the application is swiped from memory or the device is locked.
- Reactive state management implemented with Riverpod and immutable state models for rock-solid UI synchronization.
- Automatic network reconnect and offline queuing for check-ins and location updates.
3
Passwordless Authentication & Emergency Contacts Pipeline
- Frictionless email OTP authentication generating HMAC-SHA256 signed JWTs with zero password storage vulnerability.
- Reusable emergency address book supporting 1 to 10 contacts per safety event with automatic deduplication.
- Alert dispatch engine backed by AWS SES with automated exponential backoff and up to 3 delivery retries per contact.
4
Secure File Attachment Ingestion via S3
- Pre-signed S3 upload pipelines allowing users to pre-attach emergency documents, medical instructions, or credentials.
- Automated 24-hour cleanup worker purges orphaned staged uploads that were never linked to an active safety event.
- Attachments are securely bundled and relayed to emergency contacts exclusively upon timer expiration.
Troubleshooting
Preventing Android OS from Terminating Critical Background Safety Timers
Problem Discovery
- Standard Flutter background tasks and timers were aggressively killed by Android's Doze Mode and OEM battery optimizations within 3 to 10 minutes of screen lock.
Solution Process
- Investigated Android lifecycle constraints, WorkManager limitations, and Foreground Service requirements for continuous background tracking.
- Engineered a dedicated Android Foreground Service with a persistent ongoing notification and partial wake lock (WAKE_LOCK).
- Configured precise location updates via FusedLocationProviderClient with balanced battery/accuracy power intervals.
Result
- Safety countdowns and background GPS location sync continue reliably uninterrupted across extended multi-hour events.
💡Lessons Learned
- Mission-critical mobile applications cannot rely on standard app lifecycles; native platform foreground services with explicit user transparency are essential for life-safety systems.
Mitigating Missed Expirations in Redis Keyspace Notifications
Problem Discovery
- Redis keyspace notifications operate over Pub/Sub, which is strictly fire-and-forget without message durability. If the API server restarted or suffered temporary network partitions, expired event triggers were lost.
Solution Process
- Designed a dual-layer timer architecture pairing Redis keyspace notifications with a persistent PostgreSQL event status store.
- Implemented a background reconciliation worker running on a 30-second ticker that queries for expired events where status = 'active' AND expires_at <= NOW().
- Applied database transaction locks to ensure idempotent alert firing between the Redis subscriber and the polling reconciler.
Result
- Zero missed alerts with immediate trigger execution under normal operations and guaranteed 30-second recovery under catastrophic Redis failures.
💡Lessons Learned
- In-memory pub/sub must always be backed by durable, transactional storage when coordinating critical irreversible side-effects.