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:
93
README.md
93
README.md
@@ -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 |
|
||||
|
||||
Reference in New Issue
Block a user