Commit Graph

5 Commits

Author SHA1 Message Date
kevin-asprec
df40eae328 feat(01-05): super-admin API routes and middleware guard
- withSuperAdmin() HOF: checks isSuperAdmin from session, returns 401/403
- GET /api/admin/tenants: lists all tenants with userCount, subscriberCount
- GET /api/admin/tenants/[id]: single tenant detail with users list
- POST /api/admin/tenants/[id]/suspend: suspend/activate with 7-day grace
- prisma/seed.ts: add Test ISP 2 tenant and admin2@demo.com for isolation tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:04:10 +08:00
kevin-asprec
3c37cb1866 feat(01-02): login page UI, logout flow, seed script, and auth unit tests
- src/app/(auth)/layout.tsx: centered auth layout for login page
- src/app/(auth)/login/page.tsx: login form with error/loading states, sign up link
- src/components/providers.tsx: SessionProvider wrapper for client-side session
- src/components/layout/header.tsx: authenticated header with Sign out button
- src/app/(dashboard)/layout.tsx: dashboard layout wrapping Header component
- src/app/(dashboard)/dashboard/page.tsx: basic dashboard page post-login
- src/app/layout.tsx: wrap root with SessionProvider via Providers component
- prisma/seed.ts: idempotent seed for Demo ISP tenant + admin + super-admin users
- package.json: add db:seed script and prisma.seed config, add tsx devDep
- src/lib/__tests__/auth.test.ts: 8 unit tests for authOptions callbacks
2026-03-04 18:42:53 +08:00
kevin-asprec
43761d94ee feat(01-03): tenant signup API, service, and UI
- Add businessAddress and contactPhone fields to Tenant schema
- Create src/lib/tenant.ts with createTenant() function:
  - Validates input, slugifies business name, hashes password (bcrypt 12)
  - Prisma transaction creates Tenant + admin User atomically
  - Custom EmailAlreadyExistsError for 409 Conflict responses
- Create POST /api/tenants/signup route returning 201/400/409/500
- Create /signup page with full form (business name, owner info, password, optional fields)
  - Client-side validation: required fields, email format, password match
  - Redirects to /login?registered=true on success
- Update /login page to show success banner when ?registered=true
2026-03-04 18:40:40 +08:00
kevin-asprec
71a9277913 feat(01-02): configure NextAuth.js v4 with credentials provider and JWT
- Install next-auth@4, bcryptjs, @types/bcryptjs, @types/jest
- src/types/next-auth.d.ts: extend Session/JWT with tenantId, roles, isSuperAdmin
- src/lib/auth-options.ts: CredentialsProvider + JWT/session callbacks, 24h maxAge
- src/lib/auth.ts: getServerSession() and getCurrentUser() server helpers
- src/app/api/auth/[...nextauth]/route.ts: NextAuth GET/POST handler
- src/middleware.ts: withAuth middleware protecting all routes except /login /signup /api/auth/*
2026-03-04 18:37:29 +08:00
kevin-asprec
90bc5836fd feat(01-01): Next.js 15 project with Docker Compose dev environment
- Next.js 15 with App Router, TypeScript, Tailwind CSS (v4), ESLint
- docker-compose.yml with PostgreSQL 16, Redis 7, and app service
- Dockerfile (Node 20 alpine) for containerized development
- .env and .env.example with DATABASE_URL, DATABASE_URL_LOCAL, REDIS_URL
- src/app/page.tsx updated to render NetForge heading
- All three services start healthy with docker compose up -d
2026-03-04 18:24:59 +08:00