Behind-the-scenes look at building the Developer Portfolio & SaaS Platform — architecture decisions, challenges solved, and lessons learned from shipping 60+ Prisma models and 15+ modules.
When I started freelancing, I was juggling multiple tools:
The vision was simple: build one platform that handles everything. The execution? That took a lot longer.
We evaluated several frameworks before committing:
| Framework | Pros | Cons | Verdict |
|---|---|---|---|
| Next.js 16 | RSC, Server Actions, mature ecosystem | Learning curve for App Router | ✅ Selected |
| Remix | Full-stack, great DX | Smaller ecosystem | Close second |
| Nuxt 3 | Vue ecosystem, good DX | Lower TypeScript adoption | Considered |
| SvelteKit | Performance, simplicity |
| Ecosystem maturity |
| Considered |
The deciding factors were Server Components (massive performance wins), Server Actions (eliminated 90% of API routes), and the ecosystem (Shadcn/UI, Prisma, NextAuth alternatives).
With 60+ Prisma models, database design was critical:
// Key patterns we established early:
// 1. CUID for all IDs
model User {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime? // Soft delete
}
// 2. Configuration from database, not .env
model SiteConfig {
id String @id @default(cuid())
key String @unique
value String
isSecret Boolean @default(false) // Encrypted values
}
// 3. Polymorphic relationships for notifications
model Notification {
id String @id @default(cuid())
userId String
type String // "order", "invoice", "message"
resourceId String // Links to order/invoice/message ID
}
We chose PostgreSQL for its reliability, JSON support, and full-text search. Learn more about database patterns in our Prisma ORM Advanced Patterns guide and PostgreSQL Performance Tuning.
We built custom JWT authentication using Jose and bcrypt instead of NextAuth:
// Why custom auth?
// 1. Full control over token structure
// 2. Edge-compatible (Jose works at the edge)
// 3. Role-based tokens with custom claims
// 4. No dependency lock-in
const token = await new SignJWT({
userId: user.id,
role: user.role, // SUPER_ADMIN | CLIENT | CUSTOMER | AFFILIATE
email: user.email,
})
.setProtectedHeader({ alg: "HS256" })
.setIssuedAt()
.setExpirationTime("7d")
.sign(secret);
This gives us complete control over the authentication flow, which is critical for a multi-portal platform with 4 user roles.
One of our best decisions was making the database the source of truth for ALL configuration:
.env file → Only 3 variables:
- DATABASE_URL
- CRON_SECRET
- JWT_SECRET
Everything else → SiteConfig table:
- SMTP settings (encrypted)
- PayPal credentials (encrypted)
- Feature flags
- Site metadata
- SEO defaults
This means you can change any setting from the admin dashboard without redeploying. The installation wizard sets up initial config on first run.
Supporting 4 different user portals was the biggest architectural challenge:
(public) → Portfolio, blog, store (everyone)
(admin) → Full system control (SUPER_ADMIN)
(account) → Purchases, licenses (CUSTOMER)
(portal) → Projects, invoices (CLIENT)
(affiliate-portal) → Referrals, commissions (AFFILIATE)
The solution: route groups for physical organization + middleware for access control. The middleware fetches state from an internal API (to avoid Edge database calls) and enforces RBAC.
For the SMS Gateway and device monitoring, we needed real-time communication:
Server (Socket.IO) ←→ HK Relay Android App
↕
Admin Dashboard (live status updates)
The HK Relay SMS Gateway ($79) connects Android phones to the platform via Socket.IO, enabling programmatic SMS and WhatsApp messaging. The HK AIR IoT Controls ($149) uses the same infrastructure for device telemetry and remote commands.
We needed time tracking that works where developers actually work:
Both sync with the platform dashboard via heartbeat APIs, creating a complete picture of billable hours without manual entry.
After 18 months of development:
any types — strict TypeScript throughout"use client" only when neededInstead of spending 18 months building from scratch, you can start with our platform:
Visit hardikkanajariya.in to explore the platform and start building today.
Related posts:
Hardik Kanajariya — Full Stack Developer, building tools that empower developers. Explore our products →
Get the latest articles, tutorials, and updates delivered straight to your inbox. No spam, unsubscribe at any time.