Table of Contents
- The Challenge
- Architecture & Solution
- Tech Stack
- Key Engineering Decisions
- Core Modules
- AI Integration
- E-Commerce Features
- LMS Platform
- Multi-Tenancy
- Deployment
- Roadmap
The Challenge
Building a comprehensive platform that enables users to create and manage personal portfolios, sell products and services, conduct online courses, handle appointment bookings, and access AI-powered divination services — all within a single unified system with multi-tenant isolation and custom domain support.
The Portfolio Management System (PMS) addresses the need for professionals, businesses, and content creators to have a comprehensive online presence without managing multiple disconnected platforms. Users can build their portfolio, sell digital/physical products, offer services with booking capabilities, and deliver online courses — all from one administration interface.
The requirement: Create a production-grade multi-tenant SaaS platform with portfolio builder, e-commerce capabilities, course management system (LMS), appointment scheduling, payment processing, and AI-powered services for numerology, astrology, and Lo Shu grid analysis.
Architecture & Solution
The system follows a modern monorepo architecture with separate frontend and backend applications:
Project Structure
PMS/
├── apps/
│ ├── backend/ # NestJS API (Port 3001)
│ │ └── src/
│ │ ├── auth/ # JWT, 2FA, Roles
│ │ ├── tenant/ # Multi-tenancy
│ │ ├── user/ # User management
│ │ ├── portfolio/
│ │ ├── course/ # LMS
│ │ ├── product/
│ │ ├── service/
│ │ ├── booking/
│ │ ├── payment/ # Razorpay
│ │ └── ai/ # AI services
│ └── frontend/ # Next.js 16 (Port 3000)
│ ├── app/
│ │ ├── (auth)/ # Login, Register
│ │ ├── (dashboard)/ # Main app
│ │ ├── (admin)/ # Admin panel
│ │ ├── learn/ # Course player
│ │ ├── p/ # Public portfolio
│ │ └── developer/ # Developer tools
│ └── components/
├── docker-compose.yml
└── scripts/ # Deployment & utilitiesTech Stack
| Layer | Technology | Version |
|---|---|---|
| Frontend | Next.js | 16.x |
| UI Library | React | 19.x |
| Components | Radix UI | latest |
| Styling | Tailwind CSS | 4.x |
| Animation | Framer Motion | 12.x |
| Charts | Recharts | 3.x |
| Backend | NestJS | 11.x |
| Database | PostgreSQL | 16 |
| ORM | Prisma | 5.x |
| Caching | Redis | 7.x |
| Storage | MinIO | latest |
| Auth | JWT + Passport | — |
| Payment | Razorpay | 2.x |
| Container | Docker Compose | — |
Key Engineering Decisions
1. Multi-Tenant Architecture with Data Isolation
The platform implements logical multi-tenancy with tenant-scoped data access:
// backend/src/common/guards/tenant.guard.ts
@Injectable()
export class TenantGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const user = request.user;
if (!user?.tenantId) {
throw new UnauthorizedException('Tenant context required');
}
// Attach tenant ID to request for downstream use
request.tenantId = user.tenantId;
return true;
}
}
// Prisma query with tenant scope
const products = await prisma.product.findMany({
where: {
tenantId: request.tenantId,
...filters
}
});2. JWT Authentication with Refresh Tokens
Secure authentication with access and refresh token rotation:
// auth.service.ts
async generateTokens(user: User) {
const payload = {
sub: user.id,
email: user.email,
role: user.role,
tenantId: user.tenantId
};
const accessToken = this.jwtService.sign(payload, {
expiresIn: '15m',
secret: process.env.JWT_SECRET
});
const refreshToken = this.jwtService.sign(payload, {
expiresIn: '7d',
secret: process.env.JWT_REFRESH_SECRET
});
// Store refresh token hash for verification
await this.redis.set(`refresh:${user.id}`,
await bcrypt.hash(refreshToken, 10),
60 * 60 * 24 * 7
);
return { accessToken, refreshToken };
}3. Course Progress Tracking with Granular Completion
The LMS tracks lesson completion at the most granular level:
// course.service.ts
async markLessonComplete(userId: string, lessonId: string) {
const progress = await prisma.courseProgress.create({
data: {
userId,
lessonId,
completedAt: new Date(),
}
});
// Check if module is complete
const moduleLessons = await prisma.lesson.findMany({
where: { moduleId: progress.lesson.moduleId }
});
const completedCount = await prisma.courseProgress.count({
where: {
userId,
lesson: { moduleId: progress.lesson.moduleId }
}
});
if (completedCount === moduleLessons.length) {
await this.completeModule(userId, progress.lesson.moduleId);
}
return progress;
}4. AI-Powered Divination Services
The platform integrates multiple AI services for divination:
// ai/loshu.service.ts
async function calculateLoShuGrid(dob: string): Promise<LoShuResult> {
const digits = extractDigits(dob);
const grid = buildLoShuGrid(digits);
// Calculate career line (sum of specific cells)
const career = grid[0] + grid[2] + grid[4] + grid[6] + grid[8];
const health = grid[2] + grid[4] + grid[6];
const emotions = grid[1] + grid[3] + grid[5] + grid[7];
// Identify missing numbers
const missing = findMissingNumbers(grid);
// Generate personality insights
const personality = generatePersonalityInsight(grid, missing);
return {
grid,
career,
health,
emotions,
missing,
personality,
favorableNumbers: findFavorableNumbers(grid),
unfavorableNumbers: findUnfavorableNumbers(grid),
};
}5. Payment Integration with Razorpay
Complete payment flow with webhook handling:
// payment.service.ts
async function createOrder(amount: number, currency: string = 'INR') {
const razorpay = new Razorpay({
key_id: process.env.RAZORPAY_KEY_ID,
key_secret: process.env.RAZORPAY_KEY_SECRET,
});
const order = await razorpay.orders.create({
amount: amount * 100, // Convert to paise
currency,
receipt: `order_${Date.now()}`,
payment_capture: 1,
});
return order;
}
async function verifyWebhook(payload: string, signature: string) {
const expected = crypto
.createHmac('sha256', process.env.RAZORPAY_WEBHOOK_SECRET)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Core Modules
Authentication & Authorization
| Feature | Implementation |
|---|---|
| JWT Access Tokens | 15-minute expiration |
| Refresh Tokens | 7-day rotation with hash storage |
| 2FA | TOTP with QR code setup |
| Roles | DEVELOPER, ADMIN, USER, GUEST |
| Password Reset | Email-based with tokens |
User Management
| Feature | Description |
|---|---|
| Profile Management | Avatar, bio, social links |
| Role Assignment | Hierarchical access control |
| User Invitation | Email-based tenant onboarding |
| Session Management | Active sessions listing and revocation |
Portfolio Builder
| Feature | Description |
|---|---|
| Custom Slug | Public URL like p/username |
| Theme Selection | Multiple portfolio themes |
| Section Builder | Drag-and-drop section ordering |
| Analytics | Visitor tracking |
| Custom Domains | Map own domain to portfolio |
AI Integration
Lo Shu Grid Analysis
The Lo Shu magic square analysis calculates personality traits based on birth date:
// Lo Shu Grid Structure
{
4: 9: 2
3: 5: 7
8: 1: 6
// Positions: Career, Friends, Family, etc.
// Missing numbers indicate weaknesses
// Repeated numbers indicate strengths
}Vedic Numerology
Core numbers calculated from birth date and name:
| Number | Significance |
|---|---|
| Life Path Number | Overall life journey |
| Destiny Number | Life purpose |
| Soul Number | Inner desires |
| Personality Number | External expression |
| Lucky Number | Favorable numbers |
Astrology Integration
Birth chart calculation with planetary positions:
- Moon Sign (Rashi)
- Ascendant (Lagna)
- Nakshatra (Birth Star)
- Dasha periods (Antardasha, Mahadasha)
E-Commerce Features
Products Module
| Feature | Description |
|---|---|
| Product Types | Physical, Digital, Service |
| Inventory Tracking | Stock levels with alerts |
| Variants | Size, color, etc. |
| Pricing | Base price, sale price, compare price |
| Digital Downloads | Presigned URL generation |
Services Module
| Feature | Description |
|---|---|
| Service Types | One-time, Recurring |
| Duration | Time-based pricing |
| Availability | Calendar-based slots |
| Pricing | Hourly, session-based |
Booking System
| Feature | Description |
|---|---|
| Calendar View | Interactive slot selection |
| Time Zones | UTC conversion for global clients |
| Buffer Time | Gap between appointments |
| Cancellation | Configurable policies |
| Reminders | Email/SMS notifications |
LMS Platform
Course Structure
Course
├── Modules
│ ├── Lessons
│ │ ├── Video Content
│ │ ├── Text/Markdown
│ │ ├── Quiz
│ │ └── Discussion
│ └── Module Quiz
└── Final AssessmentFeatures
| Feature | Description |
|---|---|
| Video Hosting | MinIO S3 storage with streaming |
| Progress Tracking | Granular lesson completion |
| Quizzes | Multiple choice, true/false |
| Certificates | Auto-generated PDF on completion |
| Discussions | Per-lesson Q&A threads |
| Drip Content | Scheduled content release |
Certificate Generation
// certificate.service.ts
async function generateCertificate(userId: string, courseId: string) {
const course = await prisma.course.findUnique({ where: { id: courseId }});
const user = await prisma.user.findUnique({ where: { id: userId }});
// Calculate completion percentage
const progress = await this.getCourseProgress(userId, courseId);
if (progress < 100) {
throw new BadRequestException('Course not completed');
}
// Generate PDF certificate
const pdf = await this.pdfGenerator.generate({
userName: user.name,
courseName: course.title,
completionDate: new Date(),
certificateId: `CERT-${Date.now()}`,
});
return pdf;
}Multi-Tenancy
Domain Management
| Feature | Description |
|---|---|
| Subdomains | {tenant}.aatmanova.in |
| Custom Domains | shop.example.com |
| SSL | Auto-provisioned via Let's Encrypt |
| Tenant Isolation | Logical data separation by tenantId |
Developer Dashboard
The DEVELOPER role has access to platform-wide controls:
- Tenant management
- User management across tenants
- System-wide audit logs
- Platform analytics
- Feature flags
- System configuration
Deployment
Local Development
# Start infrastructure
docker compose up -d
# Run migrations
npm run prisma:migrate
# Seed system
npm run seed
# Start apps
npm run devServices
| Service | Port | Description |
|---|---|---|
| PostgreSQL | 5433 | Primary database |
| Redis | 6379 | Cache & sessions |
| MinIO | 9001 | File storage |
| MailHog | 8025 | Email testing |
| Frontend | 3000 | Next.js app |
| Backend | 3001 | NestJS API |
Production Deployment
The project supports deployment via custom scripts:
# Deploy to production
./scripts/full_deploy.ps1Roadmap
- Phase 1 — Core Platform (Complete) - Auth, Tenant, User management
- Phase 2 — Portfolio Builder (Complete) - Public profiles, custom domains
- Phase 3 — E-Commerce (Complete) - Products, Services, Bookings
- Phase 4 — LMS Platform (Complete) - Courses, Progress, Certificates
- Phase 5 — AI Services (Complete) - Lo Shu, Numerology, Astrology
- Phase 6 — Payments (Complete) - Razorpay integration
- Phase 7 — Multi-Tenancy (Complete) - Custom domains, tenant isolation
- Phase 8 — Advanced Analytics (In Progress) - Platform-wide insights
- Phase 9 — Mobile Apps (Planned) - iOS/Android companions
- Phase 10 — White-label (Planned) - Full branding customization
Conclusion
The Portfolio Management System (PMS) represents a comprehensive multi-tenant SaaS platform that consolidates portfolio building, e-commerce, course management, and AI-powered divination services into a single unified system. The platform enables users to establish their online presence without managing multiple disconnected tools.
The production-ready architecture with NestJS backend, Next.js frontend, PostgreSQL database, Redis caching, and MinIO storage provides enterprise-grade performance and reliability. The multi-tenant design with custom domain support enables the platform to serve multiple organizations from a single deployment while maintaining data isolation and security.
AI integration for Lo Shu grid analysis, Vedic numerology, and astrology adds unique value propositions that differentiate this platform from generic portfolio builders. The comprehensive LMS with progress tracking, quizzes, and certificate generation enables professional course delivery, while the e-commerce modules support both physical and digital product sales with integrated booking capabilities.
Architecture Feedback
Spotted a potential optimization or antipattern? Let me know.