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
This commit is contained in:
kevin-asprec
2026-03-04 18:40:40 +08:00
parent 71a9277913
commit 43761d94ee
5 changed files with 874 additions and 0 deletions

View File

@@ -52,6 +52,11 @@ model Tenant {
slug String @unique
ownerEmail String
/// Physical address of the ISP business (optional)
businessAddress String?
/// Primary contact phone number (optional)
contactPhone String?
status TenantStatus @default(ACTIVE)
/// Timestamp when suspension was triggered (starts grace period clock)
suspendedAt DateTime?