feat: initial NFC Attendance Hub implementation

- Multi-tenant client management with unique API keys
- Semaphore SMS integration (per-client key + sender name + credit balance)
- DB-based SMS queue with 3-attempt retry and exponential backoff
- Failed SMS dashboard with manual retry button
- Reports page with date/client filter and CSV export
- Admin auth via NextAuth (email/password)
- Docker Compose setup (app + PostgreSQL 16)
- Prisma 5 schema with SmsQueue, SmsLog, Client, User models

Tech: Next.js 14 App Router + TypeScript + Tailwind CSS + Prisma + PostgreSQL
This commit is contained in:
Nemo
2026-03-12 08:49:13 +00:00
parent bb3f8d0ef2
commit b273f1a573
53 changed files with 6000 additions and 2 deletions

View File

@@ -1,3 +1,92 @@
# nfc-attendance-hub
# NFC Attendance Hub
NFC Student Attendance SMS Notification Hub - Admin Control Center
A multi-tenant admin web app that acts as middleware between on-premise NFC student attendance apps and the [Semaphore](https://semaphore.co) SMS API.
## Features
- **Multi-tenant Client Management** — Register schools/orgs, each gets a unique API key
- **Semaphore SMS Integration** — Per-client Semaphore API key + sender name, credit balance display
- **DB-based SMS Queue** — Retry up to 3 attempts with exponential backoff, tracks failure reasons
- **Failed SMS Dashboard** — View failed messages with error details, manual retry button
- **Reports** — SMS stats per client, date filter, CSV export
- **Admin Auth** — Email/password login with NextAuth
## Tech Stack
- Next.js 14 (App Router) + TypeScript
- Tailwind CSS + shadcn/ui-compatible components
- Prisma ORM (v5) + PostgreSQL
- NextAuth.js (credentials provider)
## Quick Start (Docker)
```bash
cp .env.example .env
# Edit .env with your values
docker compose up -d
```
App available at: http://localhost:3000
Default admin: `admin@nfchub.local` / `admin123`
## Development
```bash
npm install
cp .env.example .env
# Edit .env to point to a local PostgreSQL
npx prisma generate
npx prisma db push
npm run db:seed
npm run dev
```
## SMS API Reference
On-premise NFC apps submit attendance events to:
```
POST /api/v1/sms/send
Header: X-API-Key: <client_api_key>
Content-Type: application/json
{
"student_name": "Juan Dela Cruz",
"student_id": "2024-001",
"parent_phone": "09171234567",
"event": "time_in", // "time_in" or "time_out"
"timestamp": "2024-01-15T08:30:00+08:00",
"message": "Optional custom message" // optional
}
```
### Response
```json
{ "success": true, "queueId": "...", "message": "SMS queued for delivery" }
```
### SMS Queue Behavior
1. Submission is accepted immediately (202 Accepted)
2. Processing is triggered asynchronously
3. Failed sends are retried up to 3 times with exponential backoff (2min, 4min, 8min)
4. After 3 failures, SMS is marked FAILED and visible in the Failed SMS dashboard
## Environment Variables
| Variable | Description | Required |
|----------|-------------|----------|
| `DATABASE_URL` | PostgreSQL connection string | Yes |
| `NEXTAUTH_URL` | Public app URL | Yes |
| `NEXTAUTH_SECRET` | Random secret for JWT | Yes |
| `INTERNAL_API_KEY` | Internal queue trigger key | Yes |
## Docker Services
| Service | Port | Description |
|---------|------|-------------|
| `app` | 3000 | Next.js application |
| `postgres` | 5433 (host) | PostgreSQL 16 |