Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

115 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

MyAthan Core

Backend API, mobile PWA, and admin dashboard for the MyAthan smart prayer device
Device management β€’ Prayer times API β€’ OTA updates β€’ Fleet analytics

Fastify PostgreSQL React Coolify


Overview

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

Architecture

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚   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β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Monorepo Structure

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

Tech Stack

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

API Endpoints

Device Endpoints (authenticated via API key)

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

Admin Endpoints (authenticated via JWT)

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

Database Schema

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)


Mobile PWA

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

BLE Provisioning Flow

  1. User opens PWA and taps "Set Up Device"
  2. Browser scans for MyAthan-XXXXXX via Web Bluetooth
  3. Connects and writes WiFi SSID + password via GATT characteristics
  4. Device connects to WiFi and begins operation

Admin Dashboard

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

Getting Started

Prerequisites

  • Node.js 20+
  • PostgreSQL 16+ (or Docker)
  • npm 9+

1. Clone

git clone https://github.com/My-Athan/core.git
cd core

2. Install Dependencies

npm install

3. Set Up Environment

cp .env.example .env
# Edit .env with your values:
#   DATABASE_URL=postgresql://myathan:myathan@localhost:5432/myathan
#   JWT_SECRET=<generate: openssl rand -hex 32>

4. Start Database

# 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

5. Start Development Servers

# 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

6. Verify

# 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

Testing

# 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, equator

Deployment

Production (Coolify)

See 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

Docker (Manual)

# 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

Security

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

Claude Code Skills

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

Related

Repository Description
firmware ESP32-C3 device firmware

License

Copyright 2026 MyAthan Contributors.

About

No description, website, or topics provided.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages