Add Portal Guides section to documentation

- Introduced a new "Portal Guides" section in the README and docs/README.md to provide high-level overviews and detailed explanations of various portal functionalities, including accounts, catalog, orders, billing, subscriptions, and support cases.
- Updated the main README to link to the new portal guides for better navigation and user guidance.
This commit is contained in:
barsa 2025-12-15 14:13:08 +09:00
parent ad6fadb015
commit 0d43e0d0b9
11 changed files with 541 additions and 1 deletions

View File

@ -481,6 +481,7 @@ rm -rf node_modules && pnpm install
- **[Deployment Guide](docs/DEPLOY.md)** - Production deployment instructions
- **[Architecture](docs/STRUCTURE.md)** - Code organization and conventions
- **[Logging](docs/LOGGING.md)** - Logging configuration and best practices
- **Portal Guides** - High-level flow, data ownership, and error handling (`docs/portal-guides/README.md`)
## Contributing

View File

@ -4,9 +4,23 @@ This directory contains comprehensive system design documentation for the Custom
---
## 👀 Portal Guides (How It Works)
- [Overview](./portal-guides/system-overview.md) — systems, data ownership, and caching quick reference
- [Accounts & Identity](./portal-guides/accounts-and-identity.md) — sign-up, WHMCS linking, and address/profile handling
- [Catalog & Checkout](./portal-guides/catalog-and-checkout.md) — product source, eligibility, and checkout rules
- [Orders & Provisioning](./portal-guides/orders-and-provisioning.md) — Salesforce orders and WHMCS fulfillment flow
- [Billing & Payments](./portal-guides/billing-and-payments.md) — invoices, SSO pay links, and payment methods
- [Subscriptions](./portal-guides/subscriptions.md) — how active services are read and refreshed
- [Support Cases](./portal-guides/support-cases.md) — Salesforce case creation and visibility
- [Complete Guide](./portal-guides/COMPLETE-GUIDE.md) — single, end-to-end explanation of how the portal works
---
## 📚 Core System Design Documents
### [System Architecture](./architecture/SYSTEM-ARCHITECTURE.md)
**Comprehensive overview of the entire system**
- System overview and high-level architecture
@ -22,6 +36,7 @@ This directory contains comprehensive system design documentation for the Custom
---
### [Integration & Data Flow](./architecture/INTEGRATION-DATAFLOW.md)
**External system integration patterns and data transformation**
- Integration architecture overview
@ -38,6 +53,7 @@ This directory contains comprehensive system design documentation for the Custom
---
### [Domain Layer Design](./architecture/DOMAIN-LAYER-DESIGN.md)
**Framework-agnostic type system and business logic**
- Domain-driven design principles
@ -52,6 +68,7 @@ This directory contains comprehensive system design documentation for the Custom
---
### [Authentication & Security](./architecture/AUTHENTICATION-SECURITY.md)
**Security architecture and implementation**
- Authentication flow (JWT access + refresh tokens)
@ -89,11 +106,13 @@ This directory contains comprehensive system design documentation for the Custom
### Integration Guides
**BFF Integration Layer:**
- [BFF Integration Patterns (Architecture)](./bff/BFF-INTEGRATION-PATTERNS-ARCHITECTURE.md) - Integration architecture
- [BFF Integration Patterns (Guide)](./bff/BFF-INTEGRATION-PATTERNS-GUIDE.md) - Implementation guide
- [DB Mappers](./bff/DB-MAPPERS.md) - Database mapping patterns
**Salesforce:**
- [Salesforce Portal Simple Guide](./salesforce/SALESFORCE-PORTAL-SIMPLE-GUIDE.md) - Getting started
- [Salesforce Order Communication](./salesforce/SALESFORCE-ORDER-COMMUNICATION.md) - Order integration
- [Salesforce Portal Security Guide](./salesforce/SALESFORCE-PORTAL-SECURITY-GUIDE.md) - Security setup
@ -102,6 +121,7 @@ This directory contains comprehensive system design documentation for the Custom
- [WHMCS Billing Issues Resolution](./salesforce/WHMCS_BILLING_ISSUES_RESOLUTION.md) - Troubleshooting
**API Integration:**
- [SIM Management API Data Flow](./api/SIM-MANAGEMENT-API-DATA-FLOW.md) - SIM API integration
- [Freebit SIM Management](./api/FREEBIT-SIM-MANAGEMENT.md) - Freebit integration
@ -125,6 +145,7 @@ This directory contains comprehensive system design documentation for the Custom
### Operations & Deployment
**Getting Started:**
- [Getting Started](./guides/GETTING_STARTED.md) - Setup instructions
- [Running the Application](./guides/RUN.md) - How to run
- [Deployment Guide](./guides/DEPLOY.md) - Deployment instructions
@ -132,11 +153,13 @@ This directory contains comprehensive system design documentation for the Custom
- [Address System](./guides/ADDRESS_SYSTEM.md) - Address handling
**Provisioning:**
- [Provisioning Runbook](./provisioning/RUNBOOK_PROVISIONING.md) - Provisioning procedures
- [Subscription Service Management](./provisioning/SUBSCRIPTION-SERVICE-MANAGEMENT.md) - Service management
- [Temporarily Disabled Modules](./provisioning/TEMPORARY-DISABLED-MODULES.md) - Disabled features
**Logging:**
- [Logging Guide](./logging/LOGGING.md) - Logging implementation
- [Logging Levels](./logging/LOGGING_LEVELS.md) - Log level configuration
@ -259,6 +282,7 @@ For questions about the system:
## 🏗️ Technology Stack
### Frontend
- Next.js 15 (App Router) with React 19
- Tailwind CSS 4 with shadcn/ui components
- TanStack Query for data fetching and caching
@ -266,6 +290,7 @@ For questions about the system:
- React Hook Form + Zod for form validation
### Backend (BFF)
- NestJS 11 with TypeScript
- Prisma 6 ORM with PostgreSQL 17
- p-queue for request throttling
@ -273,11 +298,13 @@ For questions about the system:
- Pino for structured logging
### External Integrations
- **WHMCS**: Custom API client for billing and subscriptions
- **Salesforce**: jsforce for REST API + salesforce-pubsub-api-client for Platform Events
- **Freebit**: Custom SIM management integration
### Infrastructure
- Docker for local development
- pnpm workspaces for monorepo management
- TypeScript project references for build optimization
@ -295,12 +322,14 @@ For questions about the system:
<summary>View all documentation files</summary>
### Core Design
- SYSTEM-ARCHITECTURE.md (check if exists in architecture/)
- INTEGRATION-DATAFLOW.md (check if exists in architecture/)
- DOMAIN-LAYER-DESIGN.md (check if exists in architecture/)
- AUTHENTICATION-SECURITY.md (check if exists in architecture/)
### Architecture
- architecture/MONOREPO-ARCHITECTURE.md
- architecture/MODULAR-PROVISIONING-ARCHITECTURE.md
- architecture/NEW-DOMAIN-ARCHITECTURE.md
@ -308,25 +337,30 @@ For questions about the system:
- architecture/PRODUCT-CATALOG-ARCHITECTURE.md
### API & Integration
- api/FREEBIT-SIM-MANAGEMENT.md
- api/SIM-MANAGEMENT-API-DATA-FLOW.md
### Authentication
- auth/AUTH-MODULE-ARCHITECTURE.md
- auth/AUTH-SCHEMA-IMPROVEMENTS.md
- auth/DEVELOPMENT-AUTH-SETUP.md
- auth/REDIS-TOKEN-FLOW-IMPLEMENTATION.md
### BFF
- bff/BFF-INTEGRATION-PATTERNS-ARCHITECTURE.md
- bff/BFF-INTEGRATION-PATTERNS-GUIDE.md
- bff/DB-MAPPERS.md
### Domain
- domain/DOMAIN-STRUCTURE.md
- domain/PACKAGE-ORGANIZATION.md
### Guides
- guides/ADDRESS_SYSTEM.md
- guides/DEPLOY.md
- guides/GETTING_STARTED.md
@ -334,14 +368,17 @@ For questions about the system:
- guides/STRUCTURE.md
### Logging
- logging/LOGGING.md
- logging/LOGGING_LEVELS.md
### Orders
- orders/ORDER-FULFILLMENT-COMPLETE-GUIDE.md
- orders/PORTAL-ORDERING-PROVISIONING.md
### Portal
- portal/PERFORMANCE.md
- portal/PORTAL-ARCHITECTURE.md
- portal/PORTAL-DATA-MODEL.md
@ -351,15 +388,18 @@ For questions about the system:
- portal/RECOMMENDED-LIB-STRUCTURE.md
### Products
- products/ADDON-INSTALLATION-LOGIC.md
- products/BUNDLE_ANALYSIS.md
### Provisioning
- provisioning/RUNBOOK_PROVISIONING.md
- provisioning/SUBSCRIPTION-SERVICE-MANAGEMENT.md
- provisioning/TEMPORARY-DISABLED-MODULES.md
### Salesforce
- salesforce/SALESFORCE-ORDER-COMMUNICATION.md
- salesforce/SALESFORCE-PORTAL-SECURITY-GUIDE.md
- salesforce/SALESFORCE-PORTAL-SIMPLE-GUIDE.md
@ -368,14 +408,15 @@ For questions about the system:
- salesforce/WHMCS_BILLING_ISSUES_RESOLUTION.md
### Types
- types/CONSOLIDATED-TYPE-SYSTEM.md
- types/UNIFIED-PRODUCT-TYPES.md
### Validation
- validation/SIGNUP_VALIDATION_RULES.md
- validation/VALIDATION_CLEANUP_SUMMARY.md
- validation/VALIDATION_PATTERNS.md
- validation/bff-validation-migration.md
</details>

View File

@ -0,0 +1,229 @@
# Customer Portal Complete Guide
This document gives a plain-language walkthrough of how the portal works end to end: what systems are involved, what data lives where, how each feature behaves, how caching keeps things fast, and what happens when something goes wrong.
## Systems and Roles (Who Owns What)
- Portal UI (Next.js) + BFF API (NestJS): handles all customer traffic and orchestrates calls to other systems.
- Postgres: stores portal users and the cross-system mapping `user_id ↔ whmcs_client_id ↔ sf_account_id`.
- Redis: cache for faster reads; all keys are scoped per user to avoid data mix-ups.
- WHMCS: system of record for billing (clients, addresses, invoices, payment methods, subscriptions, currencies).
- Salesforce: system of record for CRM (accounts/contacts), product catalog/pricebook, orders, and support cases.
- Freebit: SIM provisioning and management (activation, plan changes, voice features, data top-ups, cancellation).
- SFTP (fs.mvno.net): call and SMS detail CSV files for SIM usage history.
## Data Ownership at a Glance
- Identity/session: Portal DB (hashed passwords; no WHMCS/Salesforce credentials stored).
- Billing profile & addresses: WHMCS is authoritative; portal writes changes back there.
- Orders & statuses: Salesforce is authoritative; WHMCS gets the billing copy during fulfillment.
- Support cases: Salesforce (portal only shows cases for the mapped account).
## Where to Look (by task)
- Billing data (clients, invoices, payments, subscriptions, currencies): WHMCS.
- Catalog, orders, order status, eligibility: Salesforce (portal pricebook + orders).
- Support: Salesforce cases with Origin = "Portal Website."
- User-to-account links: Postgres `id_mappings` table, also reflected on Salesforce Account (portal status + WHMCS ID).
- SIM management (usage, top-ups, plan changes, voice features): Freebit API.
- Call/SMS history: SFTP (CSV files from fs.mvno.net, 2 months behind current).
## Core Flows
### 1) Sign-Up and Linking
- New sign-up:
- User enters email, password, name, phone, full address, and Customer Number.
- We check the Customer Number in Salesforce. If already linked, we stop and ask them to log in.
- We create a WHMCS client (billing account) with the provided contact + address and store custom fields when present (Customer Number, DOB, Gender, Nationality).
- We create the portal user, store the ID mapping (portal ↔ WHMCS ↔ Salesforce), and update the Salesforce Account with portal status + WHMCS ID.
- Linking an existing WHMCS user:
- Validate WHMCS credentials.
- Read Customer Number from WHMCS custom field 198 (“Customer Number”) and find the Salesforce Account.
- Create portal user (no password yet) and ID mapping, mark Salesforce portal flags, and ask the user to set a portal password.
- If something goes wrong: clear messages (invalid credentials, duplicate account, missing Customer Number). If WHMCS creation fails, we do not keep partial records; if the DB write fails after WHMCS creation, we mark the WHMCS client Inactive for cleanup.
What customers see:
- Immediate validation of Customer Number; clear prompts if the account already exists.
- Errors are phrased as actions: “Log in instead,” “Add missing billing info,” “Invalid WHMCS password.”
### 2) Profile and Address
- Address/profile edits are written to WHMCS (authoritative for billing).
- WHMCS cache for that user is cleared so new data shows up immediately.
- Salesforce only gets address snapshots on orders (so orders show the address used at checkout).
- Password changes are portal-only; WHMCS credentials are never stored.
### 2.5) Password Reset
- Users can request a password reset via email.
- The portal sends a reset link with a time-limited token.
- After resetting, all existing sessions are invalidated and the user must log in again.
- Rate limited to 5 attempts per 15 minutes to prevent abuse.
- The response is always "If an account exists, a reset email has been sent" to avoid leaking account existence.
### 3) Catalog and Eligibility
- Products and prices come from the Salesforce portal pricebook (`PORTAL_PRICEBOOK_ID`).
- Categories: Internet, VPN, SIM/mobile; only portal-marked products are shown.
- SIM family plans: if the user already has an active SIM in WHMCS, we show family/discount SIM plans; otherwise we hide family plans.
- Eligibility: Internet checks account-specific eligibility in Salesforce. Result is cached per account and invalidated on Salesforce changes.
- If something goes wrong: missing payment method blocks checkout; duplicate Internet or ineligible address stops the order with a clear reason; catalog unavailability returns a “try again later.”
### 4) Checkout and Order Creation
- Pre-checks: user must have a WHMCS client mapping and at least one WHMCS payment method. Internet orders also check for existing active Internet services in WHMCS (production).
- Salesforce Order created with:
- AccountId from mapping
- Order type (Internet, SIM, VPN)
- Activation preferences (type, schedule, SIM/MNP details)
- Address snapshot (from profile or updated during checkout)
- Status = “Pending Review”
- Order items are built from Salesforce pricebook entries for the selected SKUs.
- No card data is stored; we only verify payment method existence in WHMCS.
### 5) Fulfillment to WHMCS (and Freebit for SIM)
- Trigger: Salesforce Change Data Capture (CDC) sees status changes (e.g., Approved/Reactivate) and queues a provisioning job.
- Steps:
1. Set Salesforce activation status to “Activating.”
2. Map Salesforce order items to WHMCS products and call WHMCS AddOrder (creates billing order, invoices, subscriptions).
3. For SIM orders, call Freebit to activate SIMs when required.
4. Update Salesforce with WHMCS Order ID, activation status, and any error codes/messages.
5. Publish live events so the UI can stream status updates.
- If payment method is missing, provisioning pauses and writes `PAYMENT_METHOD_MISSING` to Salesforce so the UI can prompt the customer.
- If WHMCS/Salesforce is down, we fail fast with “try again later” and avoid partial writes.
### 6) Billing, Invoices, and Payments
- Data source: WHMCS (clients, invoices, payment methods, gateways, subscriptions).
- Invoice list and detail come from WHMCS; SSO links are generated so customers pay directly in WHMCS without re-entering credentials.
- Profile/address edits go to WHMCS and clear related caches so billing data reflects changes immediately.
- If billing is unavailable, we return a friendly message and avoid partial data.
- If an invoice is not found or belongs to another account, we respond "invoice not found" to avoid leakage.
**SSO Links**:
- The portal generates time-limited SSO tokens (~60 seconds) that redirect users to WHMCS for payment.
- Payment methods and gateways can be pre-selected via URL parameters.
- SSO links can also be used to access the WHMCS client area for account management (e.g., adding payment methods).
- The portal normalizes SSO redirect URLs to use the configured WHMCS base URL.
### 7) Subscriptions/Services
- Data source: WHMCS. Statuses (Active, Pending, Suspended, etc.) come directly from WHMCS.
- Used for dashboard stats (active counts, etc.).
- If mapping is missing, we return a clear error; if WHMCS is down, we ask to retry later and do not cache failures.
### 8) SIM Management
SIM subscriptions have additional management capabilities via Freebit integration:
- **Data Usage**: View remaining quota (MB/GB), used data (today/monthly), and usage history.
- **Top-Up Data**: Add data quota with optional campaign codes and expiry dates; can be scheduled.
- **Change Plan**: Switch to a different SIM plan. Changes are scheduled for the 1st of the following month (not immediate).
- **Reissue SIM/eSIM**: Request a replacement SIM card or reissue an eSIM profile.
- **Cancel SIM**: Cancel the SIM subscription. Once requested, plan changes are blocked.
- **Call History**: Access call/SMS history via SFTP-provided CSV files (talk-detail and sms-detail).
- **Voice Features**: Toggle voicemail, call waiting, and international roaming (takes effect immediately).
- **Network Type**: Switch between 4G and 5G (takes effect immediately).
**Important timing constraints**:
- Voice features, network type changes, and plan changes must be **at least 30 minutes apart**.
- Voice/network changes before the 25th of the month for billing cycle alignment.
- Plan changes and cancellations cannot coexist; a plan change will cancel a pending cancellation.
- Device restart may be required after changes are applied.
### 9) Support Cases
- Data source: Salesforce. Origin is "Portal Website."
- The portal shows only cases for the customer's mapped Salesforce Account.
- Create: requires subject/description; optional category/type and priority; sets Status = New.
- Reads are live (no cache) so status/priority/comments are up to date.
- If Salesforce is unavailable, we show "support system unavailable" and avoid leaking details.
### 10) Dashboard
The dashboard provides a summary view for customers:
- **Stats cards**: Recent orders count, pending invoices, active services, open support cases.
- **Upcoming invoice**: Shows the next invoice due with amount and a "Pay Now" button that opens WHMCS payment via SSO.
- **Recent activity feed**: Filterable list of recent events (invoices created/paid, services activated, cases created/closed).
- **Quick actions**: Links to view invoices, manage services, and open support tickets.
- Dashboard data is aggregated from multiple sources (WHMCS for billing/subscriptions, Salesforce for orders/cases).
## What Can Go Wrong (and What We Do)
- Sign-up/linking: missing Customer Number, already-linked account, or WHMCS email collision → block and show the action (log in, link instead, contact support). WHMCS creation failure leaves no portal record; DB failure after WHMCS creation marks the WHMCS client Inactive for cleanup.
- Catalog/eligibility: pricebook issues or eligibility lookup failures → "catalog unavailable/try later"; missing payment method → block checkout; duplicate Internet → block with a clear explanation.
- Checkout/order create: if mapping or payment method is missing, we stop; if Salesforce is down, we do not create partial orders.
- Fulfillment: payment method missing → pause with `PAYMENT_METHOD_MISSING` in Salesforce; WHMCS/Freebit errors → mark failed with messages in Salesforce; we avoid partial WHMCS orders on failure.
- Billing: WHMCS down → "billing system unavailable"; invoice not found → "invoice not found" (no other data leaked).
- Subscriptions: missing mapping → explicit error; WHMCS down → ask to retry later, do not cache the failure.
- Support: Salesforce down → "support system unavailable"; wrong account → "case not found" to avoid leaks.
- SIM management: operation timing violations → block with "must wait 30 minutes"; pending cancellation → block plan changes; Freebit unavailable → "try again later"; non-SIM subscription → "SIM management not available."
- Cache failures: fall back to live reads to avoid empty screens; caches are cleared on writes and webhooks to keep data fresh.
- Password reset: always responds with generic message ("If an account exists...") to avoid account enumeration.
## Caching Cheat Sheet (Redis)
- Catalog: event-driven (Salesforce CDC), no TTL; volatile bits use 60s TTL; eligibility per account cached without TTL and invalidated on change.
- Orders: event-driven (Salesforce CDC), no TTL; invalidated on Salesforce order/order-item changes and on create/provision.
- Invoices: list cached 90s; invoice detail 5m; invalidated by WHMCS webhooks and write ops.
- Subscriptions/services: list 5m; single subscription 10m; invalidated on WHMCS cache busts (webhooks, profile updates).
- Payment methods: 15m; payment gateways: 1h.
- WHMCS client profile: 30m; cleared after profile/address changes.
- Signup account lookup: 30s to keep the form responsive.
- Support cases: live (no cache).
- If cache access fails, we fall back to live reads to avoid empty screens.
## IDs and Mapping
- Each portal user is mapped to exactly one WHMCS client and one Salesforce Account via `id_mappings`.
- Mappings are validated on every operation that needs cross-system data (orders, billing, cases).
- Duplicate protection: we block sign-up/link if the mapping already exists.
## Events and Queues
- Salesforce Change Data Capture (CDC): drives catalog invalidation and order cache invalidation.
- Salesforce Platform Events / CDC: drive order fulfillment and status updates.
- Provisioning queue (BullMQ): ensures WHMCS/Freebit steps are retried safely and not run in parallel when status doesn't allow it.
- Real-time order events: published so the UI can live-update order status via SSE.
### Realtime Events (SSE)
The portal provides a single SSE endpoint (`/api/events`) for live updates:
- **Account-scoped stream**: Receives order status updates, fulfillment events, and other account-specific changes.
- **Global catalog stream**: Receives catalog/pricebook invalidation events.
- **Heartbeats**: Sent every 30 seconds to keep the connection alive.
- **Connection limiting**: Each user can only have a limited number of concurrent SSE connections to prevent resource abuse.
- **Rate limiting**: 30 connection attempts per minute to protect against reconnect storms.
- Backed by Redis pub/sub for multi-instance delivery.
## How We Handle Errors (Summary)
- Fail safe and clear: stop the action and tell the user what to fix (e.g., missing Customer Number, duplicate account, missing payment method).
- Avoid partial writes: if upstream systems fail, we do not store partial data; caches are not polluted with failures.
- Surface to Salesforce: fulfillment error codes/messages are written back so teams can see why an order paused.
- Security: if something is not found or belongs to another account, we return "not found" to avoid leaking data.
## Rate Limiting and Security
- All endpoints are rate-limited to prevent abuse. Limits are tracked per IP + User-Agent combination.
- Authentication endpoints have stricter limits: 5 login attempts per 15 minutes, 5 password reset requests per 15 minutes.
- SSE connections are limited per user to prevent resource exhaustion.
- WHMCS and Salesforce requests are queued with concurrency limits to respect upstream API limits.
- Failed authentication attempts are throttled progressively.
- CAPTCHA can be enabled for authentication endpoints after repeated failures.
## What to Expect Day-to-Day
- Data freshness: caches are short or event-driven; updates in WHMCS/Salesforce reflect quickly because we invalidate on change.
- Address authority: WHMCS is the billing source of truth; Salesforce shows order-time snapshots.
- Payment handling: portal never stores payment details; it only checks that WHMCS has a method on file.
- SIM experience: existing SIM customers see family/discount SIM plans; new SIM customers see standard plans.
- SIM management: changes to voice/network take effect immediately (~30 minutes); plan changes take effect on the 1st of the following month.
- Call history: CSV files are available 2 months behind the current month (e.g., in November you can access September's records).

View File

@ -0,0 +1,14 @@
# Portal Guides (How It Works)
These guides explain what the portal does, how data moves between WHMCS and Salesforce, and where caching affects what people see. They avoid deep implementation detail and focus on flows, data ownership, and error handling.
Start with `system-overview.md`, then jump into the feature you care about:
- `COMPLETE-GUIDE.md` — single, end-to-end explanation of how the portal works
- `system-overview.md` — high-level architecture, data ownership, and caching quick reference.
- `accounts-and-identity.md` — how sign-up, WHMCS linking, and address/profile updates behave.
- `catalog-and-checkout.md` — where products/pricing come from and what we check before checkout.
- `orders-and-provisioning.md` — order lifecycle in Salesforce and how it is fulfilled into WHMCS.
- `billing-and-payments.md` — invoices, payment methods, and how billing links are handled.
- `subscriptions.md` — how active services are read and refreshed.
- `support-cases.md` — how cases are created/read in Salesforce from the portal.

View File

@ -0,0 +1,45 @@
# Accounts & Identity
What to know about sign-up, WHMCS linking, and profile updates.
## New Sign-Up Flow
- Input required: email, password, name, phone, full billing address, and Customer Number (from Salesforce).
- Salesforce check: we look up the Customer Number; if it already has a portal/WHMCS link, we stop and tell the user to log in.
- WHMCS account creation: we create a WHMCS client using the provided contact + address details. Required fields include first/last name, email, phone, address1, city, state, postcode, and country. Optional custom fields we set when provided:
- Customer Number (custom field ID 198 by default)
- Date of Birth
- Gender
- Nationality
- Portal records: we store a portal user (password hashed with Argon2) and an `id_mapping` row linking the portal user, WHMCS client ID, and Salesforce account ID.
- Salesforce flags: after creation we set the portal status on the Salesforce Account (status = Active, source = New Signup) and write the WHMCS Account ID back to Salesforce.
- Address ownership: WHMCS is the billing system of record. The address entered at sign-up becomes the WHMCS address used for invoices and checks.
### If something goes wrong
- Customer Number not found or already mapped: we stop the flow and tell the user to log in instead.
- WHMCS already has this email: we ask the user to link instead of creating a duplicate.
- WHMCS creation fails: we show a clear “failed to create billing account” message; nothing is committed in the portal.
- Database write fails after WHMCS creation: we mark the WHMCS client as Inactive for cleanup and ask support to review.
## Linking an Existing WHMCS User
- For users who already have a WHMCS account with this email:
- We validate their WHMCS login.
- We read the Customer Number from WHMCS custom field 198 (label “Customer Number”) and find the matching Salesforce Account.
- We create a portal user (no password yet) and an `id_mapping` with WHMCS + Salesforce IDs.
- We set Salesforce portal flags (status = Active, source = Migrated) and prompt the user to set a new portal password.
- Duplicate protection: if the WHMCS client or Salesforce account is already mapped to a portal user, we ask the user to log in instead of linking again.
### If something goes wrong
- Invalid WHMCS credentials: we return “Invalid email or password.”
- WHMCS account not found: we return “No billing account found with this email.”
- Salesforce Customer Number missing in WHMCS: we tell the user to contact support (cannot link without it).
- Salesforce account lookup fails: we show a generic “unable to verify customer info” message and stop.
## Profile & Address Updates
- Address and profile edits in the portal are written directly to WHMCS, and the WHMCS cache for that user is cleared so the change shows up immediately.
- Address is treated as authoritative in WHMCS; Salesforce receives address snapshots only when orders are created (so order records show the address used at checkout).
- Password changes are portal-only; WHMCS credentials are never stored in the portal.

View File

@ -0,0 +1,30 @@
# Billing, Invoices & Payments
How billing data is shown, refreshed, and kept accurate.
## Data Sources
- WHMCS is the billing system of record for clients, invoices, payment methods, gateways, and subscriptions.
- The portal does not store payment details; it only reads payment methods already saved in WHMCS.
## Invoices
- Retrieval: invoice lists and details are pulled from WHMCS for the mapped client ID.
- Caching: lists cached 90s; single invoice cached 5m. WHMCS webhooks and write operations clear these caches to keep totals current.
- Paying invoices: the portal generates a WHMCS SSO link for the specific invoice so customers pay directly in WHMCS without re-entering credentials.
## Payment Methods & Gateways
- Payment methods are stored in WHMCS. Before an order is accepted we check that at least one method exists.
- Caching: payment methods cached 15m per user; payment gateway list cached 1h. Caches are cleared after changes or on webhook-driven invalidations.
## Address & Profile in Billing
- Billing address and contact fields shown in the portal are pulled from WHMCS and treated as authoritative.
- When customers edit their profile/address, the portal writes the change to WHMCS and clears the relevant cache so invoices immediately reflect the new address.
## If something goes wrong
- WHMCS unavailable: we show a friendly “billing system unavailable, please try again” and avoid showing partial data.
- Payment method missing: checkout/fulfillment stops and tells the user to add a method; Salesforce is updated with a clear error code.
- Invoice not found or access denied: we return “invoice not found” without leaking other user data.

View File

@ -0,0 +1,42 @@
# Catalog & Checkout
Where product data comes from, what we validate, and how we keep it fresh.
## Product Source
- Products and pricing come from the Salesforce portal pricebook (`PORTAL_PRICEBOOK_ID`), not WHMCS.
- Categories covered: Internet, VPN, SIM/mobile. Each SKU is a Salesforce Product2 + PricebookEntry record.
- The portal pulls only products marked for the portal category; Salesforce is the source of truth for names, SKUs, and prices.
### SIM family plans
- If a user already has an active SIM service in WHMCS, we also show SIM family/discount plans.
- If they do not have a SIM yet, we hide family plans and show regular plans only.
## Eligibility & Validation
- Internet orders check account-specific eligibility stored in Salesforce; the eligibility result is cached per account and invalidated when Salesforce signals a change.
- During checkout we confirm:
- The user has a WHMCS client mapping and at least one payment method on file in WHMCS.
- SKUs selected exist in the Salesforce pricebook.
- For Internet orders, we block duplicates when WHMCS already shows an active Internet service (in production).
## Checkout Data Captured
- Address snapshot: we copy the customers address (or the one they update during checkout) into the Salesforce Order billing fields so the order shows the exact data used.
- Activation preferences: stored on the Salesforce Order (activation type/schedule, SIM specifics, MNP details when applicable).
- No card data is stored in the portal; we only verify that WHMCS already has a payment method.
## Caching for Catalog Calls
- Catalog data uses Salesforce Change Data Capture (CDC) events; there is no time-based expiry. When Salesforce signals a product change, the cache is cleared.
- Volatile catalog bits (e.g., fast-changing reference data) use a 60s TTL.
- Eligibility per account is cached with no TTL and cleared when Salesforce changes.
- Request coalescing is used so multiple users hitting the same catalog do not spam Salesforce.
## If something goes wrong
- Missing payment method: checkout is blocked with a clear “add a payment method” message.
- Ineligible address or duplicate Internet: we stop the order and explain why (eligibility failed or active Internet already exists).
- Salesforce pricebook issues: we return a friendly “catalog unavailable, please try again later.”
- Cache failures: we fall back to live Salesforce reads to avoid empty screens.

View File

@ -0,0 +1,45 @@
# Orders & Provisioning
How customer orders are created, where they live, and how fulfillment reaches WHMCS.
## Order Creation (Customer Checkout)
- Orders are created in Salesforce using the portal pricebook. The record includes:
- AccountId (from the users mapping)
- Order type (Internet, SIM, VPN)
- Activation preferences (type, scheduled date, SIM/MNP details when provided)
- Address snapshot copied from the customer profile/checkout form
- Status starts at “Pending Review”
- Before creation we verify a WHMCS payment method exists and (for Internet) that WHMCS does not already have an active Internet service.
- Order items are built from the Salesforce pricebook entries for the selected SKUs.
## Fulfillment to WHMCS (Triggered by Salesforce)
- Salesforce Change Data Capture (CDC) watches for order status changes (e.g., Approved/Reactivate). When triggered, we enqueue a provisioning job.
- Fulfillment steps:
1. Set Salesforce order activation status to “Activating.”
2. Map Salesforce order items to WHMCS products and call WHMCS AddOrder to create the billing order (so invoices/subscriptions exist in WHMCS).
3. For SIM orders, call Freebit to activate SIMs when required.
4. Update Salesforce with WHMCS Order ID, activation status/results, and any error codes/messages.
5. Publish live events so the UI can update order status in real time (SSE).
- If Salesforce shows the last error code “PAYMENT_METHOD_MISSING,” provisioning is paused until the customer adds a payment method in WHMCS.
## Where Data Lives
- Salesforce: master order record, status, address snapshot, product lines.
- WHMCS: billing copy created during fulfillment (used for invoices/subscriptions).
- Freebit: only for SIM provisioning tasks.
## Freshness & Caching
- Orders and order items use CDC-driven caching (no TTL). Salesforce order/order-item change events invalidate caches immediately.
- Cache is also invalidated when we create or provision an order.
- Customers can subscribe to order event streams; UI updates without manual refresh.
## What happens on errors
- Payment method missing: fulfillment is paused; Salesforce `Activation_Error_Code__c` is set to `PAYMENT_METHOD_MISSING` and the UI shows a prompt to add a payment method.
- Validation/mapping issues (e.g., bad SKU, missing mapping): we stop and return a clear error; Salesforce gets an error code/message for traceability.
- WHMCS errors while creating the billing order: we mark fulfillment as failed, write the error back to Salesforce, and keep the Salesforce order intact (no partial WHMCS order is kept if creation fails).
- Freebit/SIM errors: logged and surfaced in the activation status; order remains in Salesforce for retry.
- Connectivity issues (Salesforce/WHMCS): we return “try again later,” do not commit partial work, and leave caches unchanged.

View File

@ -0,0 +1,23 @@
# Subscriptions & Services
How active services are displayed and refreshed.
## Data Source
- Subscriptions (services/products) are read from WHMCS via the mapped client ID.
- Statuses (Active, Pending, Suspended, Cancelled, Completed) come directly from WHMCS.
## Freshness
- Subscription list cached for 5 minutes; individual subscription cached for 10 minutes.
- Cache is cleared when WHMCS signals a change (webhooks) or when we update profile/address data that could affect related services.
## What you see
- Service name, status, start date, amount, and currency as stored in WHMCS.
- Subscriptions are also used in the dashboard stats (e.g., active count). Those stats refresh after cache invalidation.
## If something goes wrong
- Missing WHMCS mapping: we return a clear error instead of an empty list.
- WHMCS unavailable: we show “try again later” and do not cache failures.

View File

@ -0,0 +1,24 @@
# Support Cases
How the portal surfaces and creates support cases for customers.
## Data Source & Scope
- Cases are read and written directly in Salesforce. Origin is set to “Portal Website.”
- The portal only shows cases for the customers mapped Salesforce Account to avoid leakage across customers.
## Creating a Case
- Required inputs: subject and description. Optional: category/type and priority.
- The portal creates the case in Salesforce with Status = New and Priority mapped to Salesforce values.
- If a Contact ID is available it is used; otherwise the Account ID is set on the case.
## Viewing Cases
- We read live from Salesforce (no caching) to ensure status, priority, and comments are up to date.
- The portal summarizes open vs. resolved counts and highlights high-priority cases based on Salesforce status/priority values.
## If something goes wrong
- Salesforce unavailable: we show “support system unavailable, please try again later.”
- Case not found or belongs to another account: we respond with “case not found” to avoid leaking information.

View File

@ -0,0 +1,46 @@
# How the Portal Works (Overview)
Purpose: explain what the portal does, which systems own which data, and how freshness is managed.
## Core Pieces and Responsibilities
- Portal UI (Next.js) + BFF API (NestJS): handles all user traffic and calls external systems.
- Postgres: stores portal users and the cross-system mapping `user_id ↔ whmcs_client_id ↔ sf_account_id`.
- Redis cache: keeps short-lived copies of data to reduce load; keys are always scoped per user to avoid mixing data.
- WHMCS: system of record for billing (clients, addresses, invoices, payment methods, subscriptions).
- Salesforce: system of record for CRM (accounts/contacts), product catalog/pricebook, orders, and support cases.
- Freebit: SIM provisioning only, used during mobile/SIM order fulfillment.
## High-Level Data Flows
- Sign-up: portal verifies the customer number in Salesforce → creates a WHMCS client (billing account) → stores the portal user + mapping → updates Salesforce with portal status + WHMCS ID.
- Login/Linking: existing WHMCS users validate their WHMCS credentials; we create the portal user, map IDs, and mark the Salesforce account as portal-active.
- Catalog & Checkout: products/prices come from the Salesforce portal pricebook; eligibility is checked per account; we require a WHMCS payment method before allowing checkout.
- Orders: created in Salesforce with an address snapshot; Salesforce change events trigger fulfillment, which creates the matching WHMCS order and updates Salesforce statuses.
- Billing: invoices, payment methods, and subscriptions are read from WHMCS; secure SSO links are generated for paying invoices inside WHMCS.
- Support: cases are created/read directly in Salesforce with Origin = “Portal Website.”
## Data Ownership Cheat Sheet
- Identity & session: Portal DB (hashed passwords, no WHMCS/SF credentials stored).
- Billing profile & addresses: WHMCS (authoritative); the portal writes changes back to WHMCS.
- Orders & order status: Salesforce (source of truth); WHMCS receives the billing/provisioning copy during fulfillment.
- Support cases: Salesforce (portal only filters to the accounts cases).
## Caching & Freshness (Redis)
- Catalog: event-driven (Salesforce CDC), no TTL; “volatile” bits use 60s TTL; eligibility per account is cached without TTL and invalidated on change.
- Orders: event-driven (Salesforce CDC), no TTL; invalidated when Salesforce emits order/order-item changes or when we create/provision an order.
- Invoices: list cached 90s; invoice detail cached 5m; invalidated by WHMCS webhooks and by write operations.
- Subscriptions/services: list cached 5m; single subscription cached 10m; invalidated on WHMCS cache busts (webhooks or profile updates).
- Payment methods: cached 15m; payment gateways list cached 1h.
- WHMCS client profile: cached 30m; cleared after profile/address changes.
- Signup account lookup (Salesforce customer number): cached 30s to keep the form responsive.
- Support cases: read live from Salesforce (no cache).
## What Happens on Errors
- We prefer to fail safely with clear messages: for example, missing Customer Number, duplicate account, or missing payment method stops the action and tells the user what to fix.
- If WHMCS or Salesforce is briefly unavailable, the portal surfaces a friendly “try again later” message rather than partial data.
- Fulfillment writes error codes/messages back to Salesforce (e.g., missing payment method) so the team can see why a provision was paused.
- Caches are cleared on writes and key webhooks so stale data is minimized; when cache access fails, we fall back to live reads.