2025-08-23 18:02:05 +09:00
2025-08-22 17:02:49 +09:00
2025-08-23 18:02:05 +09:00
2025-08-23 18:02:05 +09:00
2025-08-22 17:02:49 +09:00
2025-08-22 17:02:49 +09:00
2025-08-22 17:02:49 +09:00
2025-08-22 17:02:49 +09:00
2025-08-22 17:02:49 +09:00
2025-08-22 17:02:49 +09:00
2025-08-22 17:02:49 +09:00

Customer Portal Project

A modern customer portal where users can self-register, log in, browse & buy subscriptions, view/pay invoices, and manage support cases.

Architecture Overview

Systems of Record

  • WHMCS: Billing, subscriptions, and invoices
  • Salesforce: CRM (Accounts, Contacts, Cases)
  • Portal: Modern UI with backend for frontend (BFF) architecture

Identity Management

  • Portal-native authentication (email + password, optional MFA)
  • One-time WHMCS user verification with forced password reset
  • User mapping: user_id ↔ whmcs_client_id ↔ sf_contact_id/sf_account_id

Tech Stack

Frontend (Portal UI)

  • Next.js 15 with App Router
  • Turbopack for ultra-fast development and builds
  • React 19 with TypeScript
  • Tailwind CSS with shadcn/ui components
  • TanStack Query for data fetching and caching
  • Zod for validation
  • React Hook Form for form management

Backend (BFF API)

  • NestJS 11 (Node 24 Current or 22 LTS)
  • Prisma 6 ORM
  • jsforce for Salesforce integration
  • WHMCS API client
  • BullMQ for async jobs with ioredis
  • OpenAPI/Swagger for documentation

Logging

  • Centralized structured logging via Pino using nestjs-pino in the BFF
  • Sensitive fields are redacted; each request has a correlation ID
  • Usage pattern in services:
    • Inject Logger from nestjs-pino: constructor(@Inject(Logger) private readonly logger: Logger) {}
    • Log with structured objects: this.logger.error('Message', { error })
    • See docs/LOGGING.md for full guidelines

Data & Infrastructure

  • PostgreSQL 17 for users, ID mappings, and optional mirrors
  • Redis 8 for cache and queues
  • Docker for local development (Postgres/Redis)

Project Structure

projects/new-portal-website/
├── apps/
│   ├── portal/            # Next.js frontend (UI)
│   └── bff/               # NestJS backend (API)
├── tools/
│   ├── dev/               # Development scripts
│   └── deployment/        # Docker Compose for development
├── docs/                  # Documentation
├── packages/              # Shared packages
└── secrets/               # Private keys (git ignored)

Getting Started

Prerequisites

  • Node.js 24 (Current) or 22 (LTS)
  • Docker and Docker Compose
  • pnpm (recommended) via Corepack

Local Development Setup

  1. Start Development Environment

    # Option 1: Start everything at once (recommended)
    pnpm start:all
    
    # Option 2: Start services only, then apps manually
    pnpm start:services
    
  2. Setup Portal (Frontend)

    cd apps/portal
    cp .env.example .env.local
    pnpm install
    pnpm run dev
    
  3. Setup BFF (Backend)

    cd apps/bff
    # Choose your environment template:
    # cp .env.dev.example .env      # for development
    # cp .env.production.example .env  # for production
    cp .env.dev.example .env
    pnpm install
    pnpm run dev
    

Environment Variables

Portal (.env.local)

NEXT_PUBLIC_API_BASE="http://localhost:4000"
NEXT_PUBLIC_APP_NAME="Customer Portal"

BFF (.env)

DATABASE_URL="postgresql://app:app@localhost:5432/portal?schema=public"
REDIS_URL="redis://localhost:6379"
WHMCS_BASE_URL="https://<your-whmcs>"
WHMCS_API_IDENTIFIER="<identifier>"
WHMCS_API_SECRET="<secret>"
SF_LOGIN_URL="https://login.salesforce.com"
SF_CLIENT_ID="<consumer_key>"
SF_USERNAME="<integration@yourco.com>"
SF_PRIVATE_KEY_PATH="./secrets/sf.key"
BFF_PORT=4000

Data Model

Core Tables (PostgreSQL)

  • users - Portal user accounts with auth credentials
  • id_mappings - Cross-system user ID mappings
  • invoices_mirror - Optional WHMCS invoice cache
  • subscriptions_mirror - Optional WHMCS service cache
  • idempotency_keys - Prevent duplicate operations

API Surface (BFF)

Authentication

  • POST /api/auth/signup - Create portal user → WHMCS AddClient → SF upsert
  • POST /api/auth/login - Portal authentication
  • POST /api/auth/link-whmcs - OIDC callback or ValidateLogin
  • POST /api/auth/set-password - Required after WHMCS link

User Management

  • GET /api/me - Current user profile
  • GET /api/me/summary - Dashboard summary
  • PATCH /api/me - Update profile
  • PATCH /api/me/billing - Sync to WHMCS fields

Catalog & Orders

  • GET /api/catalog - WHMCS GetProducts (cached 5-15m)
  • POST /api/orders - WHMCS AddOrder with idempotency

Invoices

  • GET /api/invoices - Paginated invoice list (cached 60-120s)
  • GET /api/invoices/:id - Invoice details
  • POST /api/invoices/:id/sso-link - WHMCS CreateSsoToken

Subscriptions

  • GET /api/subscriptions - WHMCS GetClientsProducts

Support Cases (Salesforce)

  • GET /api/cases - Cases list (cached 30-60s)
  • GET /api/cases/:id - Case details
  • POST /api/cases - Create new case

Webhooks

  • POST /api/webhooks/whmcs - WHMCS action hooks → update mirrors + bust cache

Frontend Pages

Initial Pages

  • / - Dashboard (next invoice due, active subs, open cases)
  • /billing/invoices - Invoice list
  • /billing/invoices/[id] - Invoice details
  • /subscriptions - Active subscriptions
  • /support/cases - Support cases list
  • /support/cases/[id] - Case details
  • /support/new - Create new case
  • /account/profile - User profile management
  • /account/security - Security settings
  • /auth/login - Sign in
  • /auth/signup - Create account
  • /auth/set-password - Set password after WHMCS link

Development Milestones

Milestone 1: Identity & Linking

  • Portal login/signup
  • One-time WHMCS verification
  • Set new portal password
  • Store id_mappings

Milestone 2: Billing

  • Product catalog (GetProducts)
  • Checkout (AddOrder)
  • Invoice list/detail (GetInvoices)
  • WHMCS SSO deep links

Milestone 3: Cases & Webhooks

  • Salesforce case list/create
  • WHMCS webhooks → cache bust + mirrors
  • Nightly reconcile job (optional)

Security Features

  • HTTPS only with HttpOnly/SameSite cookies
  • Optional MFA for portal accounts
  • Idempotency keys on all mutating operations
  • Row-level security (user must own resources)
  • PII minimization with encryption at rest/in transit
  • No WHMCS/SF credentials exposed to browser

Caching Strategy

  • Invoices: 60-120s per page; bust on WHMCS webhook
  • Cases: 30-60s; bust after create/update
  • Catalog: 5-15m; manual bust on changes
  • Keys include user_id to prevent cross-user leakage

Current Status

Completed:

  • Project structure setup
  • Next.js 15 app with TypeScript
  • Tailwind CSS with shadcn/ui
  • TanStack Query configuration
  • Docker Compose for PostgreSQL 17 and Redis 8
  • Environment configuration
  • Basic landing page

🚧 Next Steps:

  • Set up NestJS backend (BFF)
  • Implement authentication system
  • Create database schema with Prisma
  • Build initial API endpoints

Contributing

  1. Ensure Docker services are running
  2. Follow the coding standards (ESLint, Prettier)
  3. Write tests for new features
  4. Update documentation as needed

License

[Your License Here]

Description
Assist Design
Readme 16 MiB
Languages
TypeScript 51%
JavaScript 47.2%
Shell 0.8%
HTML 0.5%
CSS 0.3%
Other 0.1%