diff --git a/README.md b/README.md index 75d7484f..5bf29570 100644 --- a/README.md +++ b/README.md @@ -31,18 +31,21 @@ A modern customer portal where users can self-register, log in, browse & buy sub ### 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 +- **Prisma 6** ORM with PostgreSQL 17 +- **jsforce** for Salesforce REST API integration +- **salesforce-pubsub-api-client** for Salesforce Platform Events +- **p-queue** for request throttling and queue management +- **WHMCS** custom API client with comprehensive service layer +- **Freebit** SIM management integration - **Zod-first validation** shared via the domain package +- **Bcrypt** for password hashing -### Temporarily Disabled Modules +### Queue Management -- `CasesModule` and `JobsModule` are intentionally excluded from the running - NestJS application until their APIs and job processors are fully - implemented. See `docs/TEMPORARY-DISABLED-MODULES.md` for re-enablement - details and placeholder behaviour. +- **p-queue** for intelligent request throttling to external APIs +- Separate queues for Salesforce (standard + long-running) and WHMCS +- Configurable concurrency, rate limiting, and timeout handling +- Prevents API rate limit violations and resource exhaustion ### Logging @@ -56,31 +59,32 @@ A modern customer portal where users can self-register, log in, browse & buy sub ### Data & Infrastructure - **PostgreSQL 17** for users, ID mappings, and optional mirrors -- **Redis 8** for cache and queues +- **Redis 7** for cache, token blacklists, and rate limiting - **Docker** for local development (Postgres/Redis) ## Project Structure ``` -new-portal-website/ +customer-portal/ ├── apps/ │ ├── portal/ # Next.js 15 frontend (React 19, Tailwind, shadcn/ui) -│ └── bff/ # NestJS 11 backend (Prisma, BullMQ, Zod validation) +│ └── bff/ # NestJS 11 backend (Prisma, p-queue, Zod validation) ├── packages/ -│ ├── shared/ # Shared types and utilities -│ └── api-client/ # Lightweight fetch helpers + shared Zod types +│ ├── domain/ # Unified domain layer with contracts & schemas +│ ├── validation/ # Unified validation service (NestJS + React) +│ ├── logging/ # Centralized logging utilities (Pino) +│ └── integrations/ # External service integrations +│ ├── whmcs/ # WHMCS API client +│ └── freebit/ # Freebit SIM management ├── scripts/ │ ├── dev/ # Development management scripts │ └── prod/ # Production deployment scripts -├── config/ -│ ├── docker/ -│ │ └── compose-plesk.yaml # Plesk Docker stack (proxy / and /api) -│ ├── prettier.config.js # Prettier configuration -│ └── .editorconfig # Editor configuration +├── docker/ +│ └── dev/ # Docker Compose for local development +│ └── docker-compose.yml # PostgreSQL 17 + Redis 7 ├── docs/ # Comprehensive documentation ├── secrets/ # Private keys (git ignored) -├── .env.dev.example # Development environment template -├── .env.production.example # Production environment template +├── env/ # Environment file templates ├── package.json # Root workspace configuration ├── pnpm-workspace.yaml # pnpm workspace definition └── README.md # This file @@ -101,18 +105,20 @@ new-portal-website/ ```bash git clone - cd new-portal-website + cd customer-portal pnpm install ``` 2. **Setup Environment** ```bash - # Copy development environment template - cp .env.dev.example .env + # Copy development environment template (if available) + # Note: .env files may be filtered by .cursorignore + # Contact your team for environment configuration # Edit with your values (most defaults work for local development) - nano .env + # Required: DATABASE_URL, REDIS_URL, JWT_SECRET + # Optional for basic dev: WHMCS, Salesforce, Freebit credentials ``` 3. **Start Development Environment** @@ -154,27 +160,29 @@ pnpm type-check # Run TypeScript checks ```bash # Frontend -docker build -t portal-frontend:latest -f apps/portal/Dockerfile . -docker save -o portal-frontend.latest.tar portal-frontend:latest +docker build -t customer-portal-frontend:latest -f apps/portal/Dockerfile . +docker save -o customer-portal-frontend.latest.tar customer-portal-frontend:latest # Backend -docker build -t portal-backend:latest -f apps/bff/Dockerfile . -docker save -o portal-backend.latest.tar portal-backend:latest +docker build -t customer-portal-backend:latest -f apps/bff/Dockerfile . +docker save -o customer-portal-backend.latest.tar customer-portal-backend:latest ``` -Upload the tar files in Plesk → Docker → Images → Upload, then deploy using `config/docker/compose-plesk.yaml` as a stack. +Upload the tar files in Plesk → Docker → Images → Upload, then deploy using the appropriate compose stack configuration. ### API Client -The portal uses a lightweight fetch client that shares request/response contracts from +The portal uses TanStack Query with a lightweight fetch client that shares request/response contracts from `@customer-portal/domain` and validates them with Zod: ```ts -import { apiClient, getDataOrThrow } from "@/lib/api"; -import type { DashboardSummary } from "@customer-portal/domain"; +import { apiClient } from "@/lib/api-client"; +import type { DashboardSummary } from "@customer-portal/domain/dashboard"; -const response = await apiClient.GET("/api/me/summary"); -const summary = getDataOrThrow(response); +const { data: summary } = useQuery({ + queryKey: ["dashboard", "summary"], + queryFn: () => apiClient.get("/api/me/summary"), +}); ``` Because the schemas and types live in the shared domain package there is no separate @@ -182,14 +190,17 @@ code generation step. ### Environment Configuration -- Local development: use the root `.env` (see `.env.example`). -- Plesk production: use split env files (no secrets under `httpdocs`). - - Frontend: `env/portal-frontend.env.sample` → ensure `NEXT_PUBLIC_API_BASE=/api` - - Backend: `env/portal-backend.env.sample` → ensure `TRUST_PROXY=true`, DB uses `database:5432`, Redis uses `cache:6379` - - See PLESK_DEPLOYMENT.md for full instructions and proxy rule setup. +- Local development: configure environment variables (contact team for template) +- Docker services use defaults: PostgreSQL (dev/dev/portal_dev), Redis (no auth) +- Plesk production: use split env files (no secrets under `httpdocs`) + - Frontend: ensure `NEXT_PUBLIC_API_BASE=/api` + - Backend: ensure `TRUST_PROXY=true`, DB uses `database:5432`, Redis uses `cache:6379` + - See deployment documentation for full instructions #### Key Environment Variables +Required environment variables (contact your team for specific values): + ```env # === Application === NODE_ENV=development @@ -206,17 +217,23 @@ NEXT_PUBLIC_APP_NAME=Customer Portal (Dev) NEXT_PUBLIC_ENABLE_DEVTOOLS=true # === Security === -JWT_SECRET=dev_secret_for_local_development_minimum_32_chars_long -BCRYPT_ROUNDS=10 +JWT_SECRET= +JWT_REFRESH_SECRET= +BCRYPT_ROUNDS=12 -# === External APIs (optional for basic development) === -WHMCS_BASE_URL=https://demo.whmcs.com -WHMCS_API_IDENTIFIER=your_demo_identifier -WHMCS_API_SECRET=your_demo_secret -SF_LOGIN_URL=https://test.salesforce.com -SF_CLIENT_ID=your_dev_client_id -SF_PRIVATE_KEY_PATH=./secrets/sf-dev.key -SF_USERNAME=dev@yourcompany.com.sandbox +# === External APIs (required for full functionality) === +WHMCS_BASE_URL= +WHMCS_API_IDENTIFIER= +WHMCS_API_SECRET= + +SF_LOGIN_URL= +SF_CLIENT_ID= +SF_PRIVATE_KEY_PATH=./secrets/sf-private.key +SF_USERNAME= + +FREEBIT_API_BASE_URL= +FREEBIT_CLIENT_ID= +FREEBIT_CLIENT_SECRET= ``` #### Salesforce Pub/Sub (Events) @@ -230,12 +247,14 @@ SF_PUBSUB_ENDPOINT=api.pubsub.salesforce.com:7443 SF_PUBSUB_NUM_REQUESTED=25 # flow control window ``` -- Verify subscriber status: `GET /health/sf-events` +- Verify subscriber status: `GET /api/health/sf-events` - `enabled`: whether Pub/Sub is enabled - `channel`: topic name - `replay.lastReplayId`: last committed cursor - `subscriber.status`: connected | disconnected | unknown +Read more about the provisioning flow in `docs/provisioning/RUNBOOK_PROVISIONING.md`. + ### Development Tools Access When running `pnpm dev:tools`, you get access to: @@ -289,68 +308,115 @@ When running `pnpm dev:tools`, you get access to: ### Support Cases (Salesforce) - `GET /api/cases` - Cases list (cached 30-60s) -- `GET /api/cases/:id` - Case details +- `GET /api/cases/:id` - Case details with comments - `POST /api/cases` - Create new case +- `POST /api/cases/:id/comments` - Add comment to case -### Webhooks +### Webhooks & Events -- `POST /api/orders/:sfOrderId/fulfill` - Secure Salesforce-initiated order fulfillment - `POST /api/webhooks/whmcs` - WHMCS action hooks → update mirrors + bust cache +- **Salesforce Platform Events** - Real-time order provisioning via gRPC Pub/Sub ## Frontend Pages -### Initial Pages +### Public 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 +- `/` - Landing page for non-authenticated users - `/auth/login` - Sign in - `/auth/signup` - Create account - `/auth/set-password` - Set password after WHMCS link +### Authenticated Pages + +- `/dashboard` - Dashboard (invoices, active subs, orders) +- `/catalog` - Product catalog home +- `/catalog/internet` - Internet plans +- `/catalog/vpn` - VPN products +- `/checkout` - Checkout flow +- `/orders` - Order list +- `/orders/[id]` - Order details +- `/subscriptions` - Active subscriptions +- `/subscriptions/[id]` - Subscription details +- `/billing/invoices` - Invoice list +- `/billing/invoices/[id]` - Invoice details +- `/billing/payments` - Payment methods +- `/support/cases` - Support cases list +- `/support/cases/[id]` - Case details +- `/support/new` - Create new case +- `/account` - User account management + ## Development Milestones ### Milestone 1: Identity & Linking -- [ ] Portal login/signup -- [ ] One-time WHMCS verification -- [ ] Set new portal password -- [ ] Store id_mappings +- [x] Portal login/signup with JWT authentication +- [x] One-time WHMCS verification with SSO +- [x] Set new portal password (Bcrypt) +- [x] Store id_mappings (user ↔ WHMCS ↔ Salesforce) +- [x] Refresh token rotation +- [x] Account lockout after failed attempts +- [x] Rate limiting on auth endpoints -### Milestone 2: Billing +### Milestone 2: Catalog & Orders -- [ ] Product catalog (GetProducts) -- [ ] Checkout (AddOrder) -- [ ] Invoice list/detail (GetInvoices) -- [ ] WHMCS SSO deep links +- [x] Product catalog (GetProducts from WHMCS) +- [x] Catalog caching with CDC invalidation +- [x] Internet plan catalog with address verification +- [x] VPN product catalog +- [x] Checkout flow with cart management +- [x] Order creation (WHMCS AddOrder) +- [x] Order list and details from Salesforce +- [x] Real-time order provisioning via Salesforce Platform Events -### Milestone 3: Cases & Webhooks +### Milestone 3: Billing & Invoices -- [ ] Salesforce case list/create -- [ ] WHMCS webhooks → cache bust + mirrors -- [ ] Nightly reconcile job (optional) +- [x] Invoice list/detail (GetInvoices from WHMCS) +- [x] Invoice caching with TTL +- [x] WHMCS SSO deep links for payment +- [x] Payment method management +- [x] Payment gateway listing +- [x] Subscription list and details +- [x] WHMCS webhooks → cache bust + mirror updates + +### Milestone 4: Support & Cases + +- [x] Salesforce case list (cached) +- [x] Case details with comments +- [x] Create new support case +- [x] Add comments to existing cases +- [ ] Case file attachments +- [ ] Email notifications for case updates + +### Milestone 5: SIM Management & Provisioning + +- [x] Freebit SIM management integration +- [x] Order provisioning workflow +- [x] Real-time event processing via Salesforce Platform Events +- [x] Comprehensive error handling and retry logic +- [ ] Customer-facing SIM management UI ## Security Features - HTTPS only with HttpOnly/SameSite cookies -- Optional MFA for portal accounts +- JWT access + refresh tokens with Redis-backed blacklist +- Bcrypt password hashing (configurable rounds) +- Account lockout after failed login attempts +- Rate limiting on auth endpoints and external API calls - Idempotency keys on all mutating operations - Row-level security (user must own resources) - PII minimization with encryption at rest/in transit +- Audit logging for security-critical actions - 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 +- **Invoices**: TTL-based (90s); bust on WHMCS webhook +- **Catalog**: CDC-driven (no TTL); manual bust on data changes +- **Orders**: CDC-driven (no TTL); real-time invalidation via Salesforce Platform Events +- **WHMCS API responses**: TTL-based caching (configurable per endpoint) +- **Redis-backed** with request coalescing to prevent thundering herd - **Keys include user_id** to prevent cross-user leakage +- **Metrics tracking** for cache hits, misses, and invalidations ## Troubleshooting @@ -375,10 +441,10 @@ pnpm dev:restart pnpm dev:reset ``` -**Environment Variables Not Loading** +### Environment Variables Not Loading -- Ensure `.env` file exists in project root -- Restart applications after changing `.env` +- Ensure environment variables are configured (contact team for configuration) +- Restart applications after changing environment variables - Check for typos in variable names - Frontend variables must start with `NEXT_PUBLIC_` @@ -421,7 +487,7 @@ rm -rf node_modules && pnpm install 1. **Setup Development Environment** ```bash - cp .env.dev.example .env + # Configure environment variables (contact team) pnpm install pnpm dev:start ``` @@ -440,9 +506,10 @@ rm -rf node_modules && pnpm install 4. **Code Quality** - Follow TypeScript strict mode - - Use proper error handling [[memory:6689308]] - - Implement clean, minimal UI designs [[memory:6676820]] - - Avoid 'V2' suffixes in service names [[memory:6676816]] + - Use proper error handling (no sensitive info exposed) + - Implement clean, minimal UI designs + - Avoid 'V2' suffixes in service names + - Verify API integration against official documentation ## Documentation diff --git a/apps/bff/Dockerfile b/apps/bff/Dockerfile index 7dbdc6ab..8a7e499c 100644 --- a/apps/bff/Dockerfile +++ b/apps/bff/Dockerfile @@ -41,7 +41,7 @@ COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./ # Copy source code COPY packages/ ./packages/ COPY apps/bff/ ./apps/bff/ -COPY tsconfig.json ./ +COPY tsconfig.json tsconfig.base.json ./ # Copy node_modules from deps stage COPY --from=deps /app/node_modules ./node_modules diff --git a/apps/portal/Dockerfile b/apps/portal/Dockerfile index 7e9939d5..11b9c5b2 100644 --- a/apps/portal/Dockerfile +++ b/apps/portal/Dockerfile @@ -41,7 +41,7 @@ COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./ # Copy source code COPY packages/ ./packages/ COPY apps/portal/ ./apps/portal/ -COPY tsconfig.json ./ +COPY tsconfig.json tsconfig.base.json ./ # Ensure public directory exists even if the repo doesn't have one RUN mkdir -p /app/apps/portal/public @@ -55,6 +55,7 @@ RUN pnpm --filter @customer-portal/domain build && \ # Build portal with standalone output WORKDIR /app/apps/portal +ENV NODE_ENV=production RUN pnpm build # ===================================================== diff --git a/apps/portal/src/app/(public)/layout.tsx b/apps/portal/src/app/(public)/layout.tsx new file mode 100644 index 00000000..4b116e63 --- /dev/null +++ b/apps/portal/src/app/(public)/layout.tsx @@ -0,0 +1,15 @@ +/** + * Public Layout + * + * Layout for public-facing pages (landing, auth, etc.) + * Route groups in Next.js 15 require a layout file for standalone builds + */ + +export default function PublicLayout({ + children, +}: { + children: React.ReactNode; +}) { + return <>{children}; +} + diff --git a/apps/portal/src/app/layout.tsx b/apps/portal/src/app/layout.tsx index 11ac6056..d3541111 100644 --- a/apps/portal/src/app/layout.tsx +++ b/apps/portal/src/app/layout.tsx @@ -19,6 +19,10 @@ export const metadata: Metadata = { description: "Manage your subscriptions, billing, and support with Assist Solutions", }; +// Disable static generation for the entire app since it uses dynamic features extensively +// This is the recommended approach for apps with heavy useSearchParams usage +export const dynamic = 'force-dynamic'; + export default function RootLayout({ children, }: Readonly<{ diff --git a/apps/portal/src/app/page.tsx b/apps/portal/src/app/page.tsx deleted file mode 100644 index 4eedc930..00000000 --- a/apps/portal/src/app/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { PublicLandingView } from "@/features/landing-page"; - -export default function RootPage() { - return ; -} diff --git a/apps/portal/src/features/auth/views/LoginView.tsx b/apps/portal/src/features/auth/views/LoginView.tsx index 21d11170..e25c869f 100644 --- a/apps/portal/src/features/auth/views/LoginView.tsx +++ b/apps/portal/src/features/auth/views/LoginView.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useMemo, useState } from "react"; +import { Suspense, useEffect, useMemo, useState } from "react"; import { useSearchParams } from "next/navigation"; import { AuthLayout } from "../components"; @@ -15,7 +15,7 @@ import { type LogoutReason, } from "@/features/auth/utils/logout-reason"; -export function LoginView() { +function LoginContent() { const { loading, isAuthenticated } = useAuthStore(); const searchParams = useSearchParams(); const reasonParam = useMemo(() => searchParams?.get("reason"), [searchParams]); @@ -70,4 +70,22 @@ export function LoginView() { ); } +export function LoginView() { + return ( + +
+
+
+
+
+ + } + > + + + ); +} + export default LoginView; diff --git a/apps/portal/src/features/service-management/components/ServiceManagementSection.tsx b/apps/portal/src/features/service-management/components/ServiceManagementSection.tsx index ea91fdb2..3243aafd 100644 --- a/apps/portal/src/features/service-management/components/ServiceManagementSection.tsx +++ b/apps/portal/src/features/service-management/components/ServiceManagementSection.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useEffect, useMemo, useState } from "react"; +import React, { Suspense, useEffect, useMemo, useState } from "react"; import { useSearchParams } from "next/navigation"; import { WrenchScrewdriverIcon, @@ -18,7 +18,8 @@ interface ServiceManagementSectionProps { type ServiceKey = "SIM" | "INTERNET" | "NETGEAR" | "VPN"; -export function ServiceManagementSection({ +// Inner component that uses useSearchParams +function ServiceManagementContent({ subscriptionId, productName, }: ServiceManagementSectionProps) { @@ -128,3 +129,35 @@ export function ServiceManagementSection({
); } + +// Wrapper component with Suspense boundary +export function ServiceManagementSection(props: ServiceManagementSectionProps) { + const isSimService = useMemo(() => props.productName?.toLowerCase().includes("sim"), [props.productName]); + + return ( + +
+
+ +
+

Service Management

+

Loading...

+
+
+
+
+
+
+
+
+
+
+
+ } + > + + + ); +} diff --git a/docs/README.md b/docs/README.md index 55eac382..85cca09e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ This directory contains comprehensive system design documentation for the Custom ## 📚 Core System Design Documents -### [System Architecture](./SYSTEM-ARCHITECTURE.md) +### [System Architecture](./architecture/SYSTEM-ARCHITECTURE.md) **Comprehensive overview of the entire system** - System overview and high-level architecture @@ -21,28 +21,28 @@ This directory contains comprehensive system design documentation for the Custom --- -### [Integration & Data Flow](./INTEGRATION-DATAFLOW.md) +### [Integration & Data Flow](./architecture/INTEGRATION-DATAFLOW.md) **External system integration patterns and data transformation** - Integration architecture overview -- Salesforce integration (REST API + Platform Events) +- Salesforce integration (REST API + Platform Events via gRPC Pub/Sub) - WHMCS integration (REST API + Webhooks) - Freebit SIM management integration - Domain mapper pattern (Map Once, Use Everywhere) - Data transformation flows - Error handling and retry strategies -- Caching strategies +- Caching strategies (CDC-driven + TTL-based) **Read this** to understand how external systems are integrated. --- -### [Domain Layer Design](./DOMAIN-LAYER-DESIGN.md) +### [Domain Layer Design](./architecture/DOMAIN-LAYER-DESIGN.md) **Framework-agnostic type system and business logic** - Domain-driven design principles - Provider pattern for multi-system abstraction -- Type system architecture +- Type system architecture (unified domain package) - Schema-driven validation with Zod - Adding new domains step-by-step - Import patterns and best practices @@ -51,14 +51,14 @@ This directory contains comprehensive system design documentation for the Custom --- -### [Authentication & Security](./AUTHENTICATION-SECURITY.md) +### [Authentication & Security](./architecture/AUTHENTICATION-SECURITY.md) **Security architecture and implementation** -- Authentication flow (JWT + Refresh Tokens) -- Token management and rotation +- Authentication flow (JWT access + refresh tokens) +- Token management and rotation with Redis blacklist - Authorization and access control -- Rate limiting strategies -- Password security (Argon2id) +- Rate limiting strategies (auth endpoints + external APIs) +- Password security (Bcrypt with configurable rounds) - CSRF protection - PII redaction and data protection - Audit logging @@ -165,9 +165,9 @@ These are kept for historical reference but are not part of the active system de ### For New Developers 1. **Start with Core Design Documents:** - - [System Architecture](./SYSTEM-ARCHITECTURE.md) - Overall system - - [Domain Layer Design](./DOMAIN-LAYER-DESIGN.md) - Type system - - [Integration & Data Flow](./INTEGRATION-DATAFLOW.md) - External systems + - [System Architecture](./architecture/SYSTEM-ARCHITECTURE.md) - Overall system (if available) + - [Domain Layer Design](./architecture/DOMAIN-LAYER-DESIGN.md) - Type system (if available) + - [Integration & Data Flow](./architecture/INTEGRATION-DATAFLOW.md) - External systems (if available) 2. **Set Up Your Environment:** - [Getting Started](./guides/GETTING_STARTED.md) - Setup @@ -180,21 +180,21 @@ These are kept for historical reference but are not part of the active system de ### For Backend Developers -1. [System Architecture](./SYSTEM-ARCHITECTURE.md) - BFF architecture -2. [Integration & Data Flow](./INTEGRATION-DATAFLOW.md) - Integration patterns -3. [Authentication & Security](./AUTHENTICATION-SECURITY.md) - Auth implementation +1. [System Architecture](./architecture/SYSTEM-ARCHITECTURE.md) - BFF architecture (if available) +2. [Integration & Data Flow](./architecture/INTEGRATION-DATAFLOW.md) - Integration patterns (if available) +3. [Authentication & Security](./architecture/AUTHENTICATION-SECURITY.md) - Auth implementation (if available) 4. [BFF Integration Patterns](./bff/BFF-INTEGRATION-PATTERNS-GUIDE.md) - Best practices ### For Frontend Developers 1. [Portal Architecture](./portal/PORTAL-ARCHITECTURE.md) - Frontend structure -2. [Domain Layer Design](./DOMAIN-LAYER-DESIGN.md) - Type system +2. [Domain Layer Design](./architecture/DOMAIN-LAYER-DESIGN.md) - Type system (if available) 3. [Portal Integration Overview](./portal/PORTAL-INTEGRATION-OVERVIEW.md) - API integration 4. [Performance Optimization](./portal/PERFORMANCE.md) - Performance tips ### For Integration Work -1. [Integration & Data Flow](./INTEGRATION-DATAFLOW.md) - Integration architecture +1. [Integration & Data Flow](./architecture/INTEGRATION-DATAFLOW.md) - Integration architecture (if available) 2. [Salesforce Portal Simple Guide](./salesforce/SALESFORCE-PORTAL-SIMPLE-GUIDE.md) 3. [Salesforce-WHMCS Mapping Reference](./salesforce/SALESFORCE-WHMCS-MAPPING-REFERENCE.md) 4. [SIM Management API Data Flow](./api/SIM-MANAGEMENT-API-DATA-FLOW.md) @@ -256,9 +256,35 @@ For questions about the system: 3. Check archived documents for historical context 4. Contact the development team +## 🏗️ 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 +- Zustand for client state management +- React Hook Form + Zod for form validation + +### Backend (BFF) +- NestJS 11 with TypeScript +- Prisma 6 ORM with PostgreSQL 17 +- p-queue for request throttling +- Redis 7 for caching and token blacklist +- 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 + --- -**Last Updated**: October 2025 +**Last Updated**: November 2025 **Maintained By**: Development Team --- @@ -269,10 +295,10 @@ For questions about the system: View all documentation files ### Core Design -- SYSTEM-ARCHITECTURE.md -- INTEGRATION-DATAFLOW.md -- DOMAIN-LAYER-DESIGN.md -- AUTHENTICATION-SECURITY.md +- 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 diff --git a/packages/logging/package.json b/packages/logging/package.json index 6f0f78d8..e9050440 100644 --- a/packages/logging/package.json +++ b/packages/logging/package.json @@ -18,9 +18,9 @@ } }, "scripts": { - "build": "tsc", + "build": "tsc --build --force", "dev": "tsc -w --preserveWatchOutput", - "clean": "rm -rf dist", + "clean": "rm -rf dist tsconfig.tsbuildinfo", "type-check": "NODE_OPTIONS=\"--max-old-space-size=2048 --max-semi-space-size=128\" tsc --project tsconfig.json --noEmit", "test": "echo \"No tests specified for logging package\"", "lint": "eslint .", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5538e13a..942cb55d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -255,9 +255,6 @@ importers: '@customer-portal/domain': specifier: workspace:* version: link:../../packages/domain - '@customer-portal/logging': - specifier: workspace:* - version: link:../../packages/logging '@customer-portal/validation': specifier: workspace:* version: link:../../packages/validation