Commit Graph

68 Commits

Author SHA1 Message Date
kevin-asprec
67bb6cc95c feat(01-04): CASL permission definitions and ability factory
- Install @casl/ability for role-based access control
- Create src/lib/casl/types.ts with AppAbility, AppSubjects, AppActions types
- Create src/lib/casl/permissions.ts with permission matrix for all 5 roles
- Create src/lib/casl/ability.ts with defineAbilityFor() factory function
- Support multi-role users via additive union of permissions
- Super-admin bypasses all permission checks via can("manage", "all")
2026-03-04 18:52:39 +08:00
kevin-asprec
36729343cc fix(01): use localhost DATABASE_URL for vitest host-side test execution
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:48:43 +08:00
kevin-asprec
dc85d348ef docs(01-03): complete tenant provisioning and isolation plan
Tasks completed: 2/2
- Task 1: Tenant signup API, tenant service, and signup UI
- Task 2: Prisma tenant middleware, PostgreSQL RLS, and isolation tests

SUMMARY: .planning/phases/01-foundation/01-03-SUMMARY.md
2026-03-04 18:47:01 +08:00
kevin-asprec
69eac9ffaa feat(01-03): Prisma tenant middleware, PostgreSQL RLS, and isolation tests
- Create src/lib/prisma-tenant.ts:
  - withTenantContext(tenantId) / createTenantPrisma — Prisma $extends client
  - Intercepts findMany, findFirst, findUnique, create, createMany, update,
    updateMany, delete, deleteMany, upsert, count, aggregate, groupBy on User
  - Auto-injects tenantId filter on all reads, writes, and deletes
  - setTenantRLS() helper for explicit RLS enforcement in transactions
  - TENANT_SCOPED_MODELS constant for future extensibility
- Create prisma/migrations/20260304104214_initial_schema — baseline migration
  capturing schema created by initial db push
- Create prisma/migrations/20260304104245_add_rls_policies:
  - ALTER TABLE User ENABLE ROW LEVEL SECURITY
  - CREATE POLICY tenant_isolation_user USING app.current_tenant_id session var
  - Defense-in-depth architecture comments explaining primary vs secondary enforcement
- Create src/lib/__tests__/tenant-isolation.test.ts (6 tests, all passing):
  - Test 1: Tenant A context returns only Tenant A's users (zero from B)
  - Test 2: Tenant B context returns only Tenant B's users (zero from A)
  - Test 3: create() auto-sets tenantId, invisible to other tenant
  - Test 4: findUnique by Tenant B's ID under Tenant A context returns null
  - Additional: findFirst cross-tenant blocked, count() is tenant-scoped
2026-03-04 18:45:13 +08:00
kevin-asprec
cf790c3257 docs(01-02): complete authentication plan
Tasks completed: 2/2
- Task 1: NextAuth.js configuration with credentials provider and JWT
- Task 2: Login page UI, logout flow, seed script, and auth unit tests

SUMMARY: .planning/phases/01-foundation/01-02-SUMMARY.md
2026-03-04 18:44:29 +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
19a5520dd5 docs(01-01): complete project scaffold and dev environment plan
Tasks completed: 2/2
- Task 1: Next.js 15 project with Docker Compose dev environment
- Task 2: Prisma schema with Tenant/User models and Vitest setup

SUMMARY: .planning/phases/01-foundation/01-01-SUMMARY.md
2026-03-04 18:32:40 +08:00
kevin-asprec
1adeab2fbc feat(01-01): Prisma schema with Tenant/User models and Vitest test setup
- prisma/schema.prisma with Tenant, User, Role, TenantStatus models
  - tenantId on all tenant-scoped models (RLS-ready convention)
  - @@unique([email, tenantId]) and @@index([tenantId]) on User
  - Grace period fields on Tenant (suspendedAt, gracePeriodEndsAt)
  - RLS comment block documenting tenantId convention for future models
- src/lib/prisma.ts singleton PrismaClient pattern (hot-reload safe)
- vitest.config.ts with node environment and @/* path alias
- src/lib/__tests__/setup.test.ts smoke test (2 tests passing)
- package.json scripts: test, test:watch, db:push, db:generate, db:studio
- Schema synced to PostgreSQL 16 via prisma db push
2026-03-04 18:31:04 +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
kevin-asprec
7e6d286fca docs(01): create phase plan
Phase 01: Foundation
- 5 plan(s) in 4 wave(s)
- 2 parallel (wave 2: auth + tenant provisioning), 3 sequential
- Ready for execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:13:27 +08:00
kevin-asprec
2506a6745c docs(01): capture phase context
Phase 01: Foundation
- Implementation decisions documented
- Phase boundary established

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 18:05:03 +08:00
kevin-asprec
1bdb4eafae docs: create roadmap (5 phases) and research
Phases:
1. Foundation: tenant isolation, auth, Docker, RBAC
2. Subscriber & Billing Core: subscribers, invoicing, payments, accounting ledger
3. Operational Modules: collectors, ticketing, job orders, technicians
4. Inventory, Expenses & Reports: event-ledger inventory, expenses, financial statements
5. Visibility & Client Portal: dashboard, client self-service, integration & e2e tests

All 66 v1 requirements mapped to phases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:45:09 +08:00
kevin-asprec
21541fd8d5 docs: define v1 requirements
53 requirements across 12 categories
11 requirements deferred to v2
Full double-entry accounting with audit trail and derived balances

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:40:14 +08:00
kevin-asprec
c407e182f8 docs: complete project research for NetForge ISP Management SaaS
Files:
- STACK.md
- FEATURES.md
- ARCHITECTURE.md
- PITFALLS.md
- SUMMARY.md

Key findings:
- Stack: Next.js 15 + TypeScript + PostgreSQL + Prisma monolith; BullMQ for billing cron jobs; MikroTik client needs library verification (LOW confidence)
- Architecture: Modular monolith with shared-DB multi-tenancy; JournalEntryService as sole ledger gateway; derived financial state (no balance fields)
- Critical pitfall: Cross-tenant data leakage + fake accounting + billing state machine must all be solved in Phase 1 before any feature work

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:21:44 +08:00
kevin-asprec
ec2e583787 chore: add project config
Mode: yolo
Depth: standard
Parallelization: disabled
Workflow agents: research=on, plan_check=on, verifier=on

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:14:25 +08:00
kevin-asprec
54fb4915f0 docs: initialize project
Multi-tenant SaaS platform for ISP operations management — billing, payments, inventory, technician job orders, and full accounting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:11:11 +08:00