Repository structure and conventions This monorepo hosts the portal (Next.js) and BFF (NestJS), plus domain types. High-level layout - apps/ - portal/ (Next.js) - bff/ (NestJS) - packages/ - domain/ (domain types/utilities) - scripts/, docker/, docs/ Configuration - Single root ESLint flat config (eslint.config.mjs) for all packages - Single Prettier config (config/prettier.config.js) and EditorConfig (config/.editorconfig) - Root TypeScript config tsconfig.json extended by packages Portal (Next.js) - src/lib/ contains cross-feature utilities: - api.ts: centralized HTTP client (typed, safe JSON parsing) - env.ts: zod-validated runtime environment - auth/: Zustand store and helpers - Hooks live under src/hooks/ and should consume the centralized client - Feature barrels are available under src/features/{billing,subscriptions,dashboard}/hooks for stable imports - Page components keep UI and delegate data-fetching to hooks BFF (NestJS) - Modules per domain (e.g., invoices, subscriptions) - Common concerns under src/common/ (logging, filters, config) - Strict DTO validation, error filtering (no sensitive data leaks) - Auth module layout: - `modules/auth/presentation` → controllers, guards, interceptors, passport strategies - `modules/auth/application` → orchestration facade coordinating workflows and tokens - `modules/auth/infra` → token services, Redis rate limiting, signup/password/WHMCS workflows - Zod schemas live in `@customer-portal/domain`; controllers use `ZodValidationPipe` ## Validation Workflow (Zod-First) - Shared schemas live in `packages/domain/src/validation`. - Backend registers `nestjs-zod`'s `ZodValidationPipe` globally via `APP_PIPE`. - Controllers compose schemas by importing contracts from the shared package. For query params and body validation, use `@UsePipes(new ZodValidationPipe(schema))`. - Services call `schema.parse` when mapping external data (Salesforce, WHMCS) to ensure the response matches the contract. - Frontend imports the same schemas/types (and `useZodForm` helpers) to keep UI validation in sync with backend rules. - Error handling runs through custom filters; if custom formatting is needed for Zod errors, catch `ZodValidationException`. Domain package - Domain folders (billing, subscriptions, cases) exporting typed models - No framework-specific imports; purely types/utilities Tooling - Pre-commit: format check, lint, type-check via Husky + lint-staged - CI: lint, type-check, test, build per app (to be wired) Coding standards - Strict TypeScript rules enforced repository-wide - No any in public APIs; avoid unsafe operations - Async handlers in React wrapped with void or promise-chaining # 🏗️ Project Structure ## 📁 **Current Directory Structure** ``` 📦 Customer Portal ├── 📄 .env.example # ✅ Single environment template ├── 📄 .env # ✅ Your actual config (gitignored) ├── 📄 .gitignore # ✅ Comprehensive gitignore ├── 📄 package.json # ✅ Root package with clean scripts ├── 📄 pnpm-workspace.yaml # ✅ PNPM workspace config ├── 📄 tsconfig.json # ✅ TypeScript root config ├── 📄 README.md # ✅ Project overview ├── 📄 SECURITY.md # ✅ Security documentation │ ├── 🚀 apps/ # Applications │ ├── bff/ # NestJS Backend │ │ ├── Dockerfile # ✅ Optimized production build │ │ ├── package.json # ✅ BFF dependencies │ │ ├── tsconfig.json # ✅ BFF TypeScript config │ │ ├── nest-cli.json # ✅ NestJS CLI config │ │ ├── prisma/ # ✅ Database schema & migrations │ │ ├── src/ # ✅ NestJS source code │ │ └── test/ # ✅ BFF tests │ │ │ └── portal/ # Next.js Frontend │ ├── Dockerfile # ✅ Optimized production build │ ├── package.json # ✅ Portal dependencies │ ├── tsconfig.json # ✅ Portal TypeScript config │ ├── next.config.mjs # ✅ Next.js configuration │ ├── components.json # ✅ UI components config │ ├── eslint.config.mjs # ✅ ESLint configuration │ ├── postcss.config.mjs # ✅ PostCSS configuration │ ├── src/ # ✅ Next.js source code │ └── public/ # ✅ Static assets │ ├── 🐳 docker/ # Docker configurations │ ├── dev/ # Development setup │ │ └── docker-compose.yml # ✅ Services only (PostgreSQL + Redis) │ └── prod/ # Production setup │ ├── docker-compose.yml # ✅ Complete production stack │ ├── nginx.conf # ✅ Reverse proxy configuration │ ├── postgres.conf # ✅ PostgreSQL optimization │ └── redis.conf # ✅ Redis optimization │ ├── 🛠️ scripts/ # Management scripts │ ├── dev/manage.sh # ✅ Development environment manager │ ├── prod/manage.sh # ✅ Production deployment manager │ └── plesk-deploy.sh # ✅ Plesk deployment script │ ├── 📚 docs/ # Documentation │ ├── README.md # ✅ Documentation index │ ├── STRUCTURE.md # ✅ This file │ ├── getting-started/ # Setup and running guides │ │ ├── setup.md # Initial project setup │ │ ├── running.md # Local development │ │ └── deployment.md # Production deployment │ ├── architecture/ # System design documents │ ├── how-it-works/ # Feature guides │ ├── integrations/ # External system integration │ ├── development/ # Development guides │ ├── operations/ # Operational runbooks │ └── _archive/ # Historical documents │ ├── 📦 packages/ # Shared packages │ └── domain/ # Domain TypeScript utilities │ ├── package.json # ✅ Domain package config │ ├── tsconfig.json # ✅ Domain TypeScript config │ └── src/ # ✅ Domain source code │ └── 🔒 secrets/ # Secure key storage (gitignored) ``` ## 🎯 **Environment Configuration** ### **Environment Template Approach** Environment templates are located in the `env/` folder: - **`env/dev.env.sample`** - Development environment template - **`env/portal-backend.env.sample`** - Backend-specific variables - **`env/portal-frontend.env.sample`** - Frontend-specific variables - **`.env`** - Your actual configuration (gitignored, at project root) ### **Environment Variables** ```bash # Application NODE_ENV=development APP_NAME=customer-portal-bff BFF_PORT=4000 # Security JWT_SECRET=your_secure_secret_minimum_32_chars BCRYPT_ROUNDS=12 # Database & Cache DATABASE_URL=postgresql://user:pass@localhost:5432/db REDIS_URL=redis://localhost:6379 # External APIs WHMCS_BASE_URL=https://your-domain.com SF_LOGIN_URL=https://login.salesforce.com # Frontend (NEXT_PUBLIC_ variables) NEXT_PUBLIC_API_BASE=http://localhost:4000 ``` ## 🐳 **Docker Organization** ### **Development (`docker/dev/`)** - **Services only** - PostgreSQL + Redis - **Apps run locally** via `pnpm dev` - **Optional tools** - Adminer, Redis Commander - **Port exposure** for local development ### **Production (`docker/prod/`)** - **Complete stack** - All services containerized - **Nginx reverse proxy** with SSL - **Optimized configs** for performance - **Health checks** and monitoring - **No port exposure** (internal networking) ## 🛠️ **Scripts Organization** ### **Development Scripts (`scripts/dev/`)** ```bash pnpm dev:start # Start PostgreSQL + Redis pnpm dev:stop # Stop services pnpm dev:tools # Start with admin tools pnpm dev:apps # Start services + local apps ``` ### **Production Scripts (`scripts/prod/`)** ```bash pnpm prod:deploy # Full production deployment pnpm prod:start # Start production stack pnpm prod:update # Zero-downtime update pnpm prod:backup # Database backup ``` ## 📚 **Documentation Structure** ### **Essential Guides** Documentation is organized in subdirectories: - **`docs/README.md`** - Documentation index and navigation - **`docs/STRUCTURE.md`** - This file (project structure) - **`docs/getting-started/`** - Setup, running, and deployment guides - **`docs/architecture/`** - System design and architecture - **`docs/how-it-works/`** - Feature guides and workflows - **`docs/integrations/`** - Salesforce, WHMCS, SIM integration - **`docs/development/`** - BFF, Portal, Auth development guides - **`docs/operations/`** - Runbooks and operational procedures ### **No Redundancy** - **Single source of truth** for each topic - **Clear separation** of concerns - **Consistent formatting** and structure ## 🎯 **Key Principles** ### **1. Separation of Concerns** - **Dev vs Prod** - Clear separation with appropriate tooling - **Services vs Apps** - Development runs apps locally, production containerizes everything - **Configuration vs Code** - Environment variables for configuration, code for logic ### **2. Single Source of Truth** - **One environment template** - `.env.example` - **One Docker Compose** per environment - **One script** per operation type ### **3. Simplicity** - **Clear naming** - No ambiguous file names - **Logical grouping** - Related files in same directory - **Minimal nesting** - Flat structure where possible ### **4. Production Ready** - **Security first** - All security measures implemented - **Performance optimized** - Database and cache tuning - **Monitoring ready** - Health checks and logging - **Scalable** - Containerized architecture ## 🚀 **Getting Started** 1. **Copy environment template**: `cp .env.example .env` 2. **Edit configuration**: Fill in your actual values 3. **Start development**: `pnpm dev:start` (services) + `pnpm dev` (apps) 4. **Deploy production**: `pnpm prod:deploy` --- **Last Updated**: $(date) **Status**: ✅ Clean and Organized **Redundancy**: ❌ None Found