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

40
docker-compose.yml Normal file
View File

@@ -0,0 +1,40 @@
version: '3.9'
services:
postgres:
image: postgres:16-alpine
container_name: nfchub-postgres
restart: unless-stopped
environment:
POSTGRES_DB: nfchub
POSTGRES_USER: nfchub
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-nfchubpass}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5433:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U nfchub"]
interval: 10s
timeout: 5s
retries: 5
app:
build:
context: .
dockerfile: Dockerfile
container_name: nfchub-app
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: postgresql://nfchub:${POSTGRES_PASSWORD:-nfchubpass}@postgres:5432/nfchub
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-change-me-in-production}
INTERNAL_API_KEY: ${INTERNAL_API_KEY:-change-me-internal}
ports:
- "3000:3000"
volumes:
postgres_data: