Backend API, mobile PWA, and admin dashboard for the MyAthan smart prayer device
Device management β’ Prayer times API β’ OTA updates β’ Fleet analytics
MyAthan Core is the cloud platform for MyAthan firmware devices. It provides device registration, config sync, OTA firmware updates, multi-room coordination, and fleet management.
The device works fully offline for prayer time calculation. This platform adds:
- Remote config management (change settings from anywhere)
- OTA firmware updates with staged rollouts
- Multi-room synchronized playback across devices
- Fleet analytics and monitoring
- Mobile PWA for device setup and control
ββββββββββββββββββββ
β MyAthan PWA β βββ React + Tailwind
β (app.myathan.com)β BLE + HTTP
ββββββββββ¬ββββββββββ
β
ββββββββββΌββββββββββ
β Fastify API β βββ TypeScript + Drizzle
β (api.myathan.com) β JWT + API Key auth
ββββββββββ¬ββββββββββ
β
ββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
ββββββββββββββ ββββββββββββ ββββββββββββββββ
β PostgreSQL β β Cloudflareβ β Admin Panel β
β (Drizzle) β β R2 β β (admin. β
β β β (storage)β β myathan.com)β
ββββββββββββββ ββββββββββββ ββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββ
β MyAthan Devices (ESP32) β
β Register β Config Sync β Heartbeat β OTAβ
ββββββββββββββββββββββββββββββββββββββββββββ
core/
βββ apps/
β βββ api/ # Fastify backend API
β β βββ src/
β β β βββ index.ts # Server entry + plugins
β β β βββ db/
β β β β βββ schema.ts # Drizzle ORM (6 tables)
β β β β βββ index.ts # DB connection pool
β β β βββ middleware/
β β β β βββ device-auth.ts # API key + JWT auth
β β β βββ routes/
β β β β βββ device/ # Device endpoints (7)
β β β β βββ admin/ # Admin endpoints (12)
β β β βββ services/
β β β βββ prayer-times.ts # adhan-js wrapper
β β β βββ hijri.ts # Hijri calendar
β β β βββ multi-room.ts # Sync coordinator
β β β βββ audio-catalog.ts# R2 audio storage
β β βββ vitest.config.ts
β β
β βββ web/ # Mobile PWA
β β βββ src/
β β β βββ pages/ # 7 pages
β β β βββ components/ # Shared UI components
β β β βββ hooks/ # useDeviceStatus, useDeviceConfig
β β β βββ lib/
β β β βββ device-api.ts # HTTP client (with timeout)
β β β βββ ble-provisioning.ts # Web Bluetooth
β β βββ index.html
β β
β βββ admin/ # Admin dashboard
β βββ src/
β β βββ pages/ # 5 pages + login
β β βββ components/ # AdminLayout
β β βββ lib/api.ts # Admin API client
β βββ index.html
β
βββ packages/
β βββ shared/ # Shared TypeScript types
β βββ src/types/
β βββ device.ts # DeviceConfig (matches firmware)
β βββ prayer.ts # PrayerTimes, HijriDate
β βββ multi-room.ts # Group sync types
β βββ holidays.ts # 7 Islamic holidays enum
β
βββ infra/
β βββ docker/
β β βββ docker-compose.yml # Dev (API + PostgreSQL)
β β βββ docker-compose.prod.yml # Production with healthchecks
β β βββ Dockerfile.api # Multi-stage build
β β βββ init.sql # DB initialization
β βββ coolify-setup.md # Production deployment guide
β βββ README.md # Infrastructure docs
β
βββ .github/workflows/
β βββ ci.yml # Lint β Test β Build β Docker
β βββ deploy.yml # Coolify webhook deploy
β
βββ package.json # npm workspaces root
βββ tsconfig.base.json # Shared TypeScript config
βββ .env.example # Environment variables template
βββ CLAUDE.md # AI assistant project context
| Layer | Technology | Purpose |
|---|---|---|
| API | Fastify 5, TypeScript | REST API (20+ endpoints) |
| ORM | Drizzle ORM | Type-safe PostgreSQL queries |
| Database | PostgreSQL 16 | Device registry, stats, releases |
| Auth | bcrypt + JWT + HMAC API keys | Admin login + device auth |
| Validation | Zod | Input schemas on all endpoints |
| Storage | Cloudflare R2 | Firmware binaries + audio files |
| PWA | React 19, Vite, Tailwind | Mobile device management |
| Admin | React 19, Vite | Fleet management dashboard |
| Deploy | Coolify on Hostinger VPS | Auto-deploy from git |
| CI/CD | GitHub Actions | Lint, test, build, deploy |
| Method | Path | Description |
|---|---|---|
POST |
/api/device/register |
Register device, receive API key |
GET |
/api/device/config |
Poll for config updates |
PUT |
/api/device/config |
Push config changes |
POST |
/api/device/heartbeat |
Status update + stats + sync triggers |
GET |
/api/device/timetable |
Server-side prayer times + Hijri date |
GET |
/api/device/ota/check |
Check for firmware updates |
GET |
/api/device/sync |
Get pending multi-room triggers |
| Method | Path | Description |
|---|---|---|
POST |
/api/admin/auth/login |
Admin login, returns JWT |
GET |
/api/admin/devices |
Paginated device fleet (with online status) |
GET |
/api/admin/devices/:id |
Device detail + 7-day stats |
PUT |
/api/admin/devices/:id/config |
Push config to device |
GET |
/api/admin/releases |
List firmware releases |
POST |
/api/admin/releases |
Register new release |
PUT |
/api/admin/releases/:version |
Update rollout % / mark stable |
GET |
/api/admin/groups |
List multi-room groups |
POST |
/api/admin/groups |
Create group |
POST |
/api/admin/groups/:id/sync |
Trigger synchronized playback |
GET |
/api/admin/stats |
Fleet analytics |
users devices device_groups
ββββββββββββ ββββββββββββββββββββ ββββββββββββββββ
β id (PK) βββββ userId (FK) β β id (PK) β
β email β β id (PK) ββββ β
β password β β deviceId (unique)β β name β
β role β β apiKey β β syncEnabled β
ββββββββββββ β groupId (FK) βββββββΆβ createdBy β
β firmwareVersion β ββββββββββββββββ
β lastHeartbeat β
β config (JSONB) β sync_triggers
ββββββββββββββββββββ ββββββββββββββββ
β groupId (FK) β
releases stats β prayer β
ββββββββββββββ ββββββββββββββββ β triggerEpoch β
β version β β deviceId β β consumed β
β sha256 β β date β ββββββββββββββββ
β size β β prayerPlays β
β r2Url β β errors β
β rollout % β β uptime β
β isStable β β freeHeap β
ββββββββββββββ ββββββββββββββββ
Indexes: devices(groupId), devices(lastHeartbeat), stats(deviceId, date), syncTriggers(groupId, consumed)
The PWA at app.myathan.com provides:
| Page | Features |
|---|---|
| Home | Next prayer countdown, quick play/preview, Hijri date, device info |
| Setup | BLE WiFi provisioning (Web Bluetooth API) |
| Prayer Times | All 6 times with next-prayer highlight, Hijri date + holidays |
| Audio Settings | Per-prayer track with preview button, volume schedule, iqama delay |
| Ramadan | Auto-detect toggle, suhoor mode (none/sound/LED/custom), Hijri adjustment |
| Multi-Room | Join/leave group, test sync |
| Settings | Location, calculation method, ASR (Standard/Hanafi), high-latitude, holidays |
- User opens PWA and taps "Set Up Device"
- Browser scans for
MyAthan-XXXXXXvia Web Bluetooth - Connects and writes WiFi SSID + password via GATT characteristics
- Device connects to WiFi and begins operation
The admin panel at admin.myathan.com provides:
| Page | Features |
|---|---|
| Dashboard | Fleet summary (total/online devices), firmware distribution, 7-day activity |
| Devices | Paginated table with online status, detail modal (config + stats + RSSI) |
| Releases | Firmware versions with staged rollout (10% β 50% β 100% β Stable) |
| Groups | Multi-room management, per-prayer sync trigger buttons |
| Analytics | Prayer play bar charts, error trends, firmware distribution, online rate |
- Node.js 20+
- PostgreSQL 16+ (or Docker)
- npm 9+
git clone https://github.com/My-Athan/core.git
cd corenpm installcp .env.example .env
# Edit .env with your values:
# DATABASE_URL=postgresql://myathan:myathan@localhost:5432/myathan
# JWT_SECRET=<generate: openssl rand -hex 32># Using Docker (recommended)
docker compose -f infra/docker/docker-compose.yml up db -d
# Push schema to database
npm run db:push --workspace=apps/api# API (port 3000)
npm run dev:api
# PWA (port 5173)
npm run dev:web
# Admin (port 5174)
npm run dev:admin
# Or start all at once
npm run dev:api & npm run dev:web & npm run dev:admin# API health check
curl http://localhost:3000/health
# Expected: {"status":"ok","version":"0.2.0","timestamp":"..."}
# PWA
open http://localhost:5173
# Admin
open http://localhost:5174# Run all tests
npm run test --workspace=apps/api
# Tests include:
# - Hijri calendar (7 tests): conversion, Ramadan, holidays, adjustment
# - Prayer times (5 tests): cities, methods, Hanafi, equatorSee infra/coolify-setup.md for step-by-step guide.
Cost: ~$7/month (Hostinger VPS + domain + R2)
Hostinger VPS ($6/mo)
βββ Coolify (manages everything)
βββ PostgreSQL 16
βββ API service (Fastify)
βββ PWA (static build)
βββ Admin (static build)
βββ Traefik (auto-SSL)
Cloudflare R2 (~$0.15/mo)
βββ firmware/ # OTA binaries
βββ audio/ # Athan/doaa files
Domain (~$1/mo)
βββ api.myathan.com
βββ app.myathan.com
βββ admin.myathan.com
# Build and start everything
docker compose -f infra/docker/docker-compose.yml up -d
# Production config
docker compose -f infra/docker/docker-compose.prod.yml up -d| Feature | Implementation |
|---|---|
| Device auth | HMAC-SHA256 API key derived from device MAC |
| Admin auth | bcrypt password hashing + JWT (24h expiry) |
| Input validation | Zod schemas on all endpoints |
| Rate limiting | 100 req/min via @fastify/rate-limit |
| CORS | Whitelist in production, open in dev |
| Config merge | Whitelist of allowed keys (firmware-side) |
| OTA safety | SHA256 verification + dual-partition rollback |
| DB indexes | Optimized queries for fleet-scale operations |
| Command | Description |
|---|---|
/dev |
Start development servers |
/db |
Database management (push/generate/migrate) |
/deploy |
Deploy to staging/production |
/review |
TypeScript + API + security review checklist |
/lint |
Type checking across all workspaces |
| Repository | Description |
|---|---|
| firmware | ESP32-C3 device firmware |
Copyright 2026 MyAthan Contributors.