0 Executive Summary
PromptShip is a hybrid SaaS + Education platform providing curated AI prompts, one-click code generation, and comprehensive learning resources for developers. This document outlines the complete technical architecture optimized for:
We recommend a monorepo architecture with Next.js serving all portals from a single deployment. This approach minimizes infrastructure costs, simplifies development, and maintains consistency while supporting distinct user experiences.
1 Portal Strategy & Deployment Architecture
1.1 Portal Overview
Based on the product requirements, we need 4 distinct portals with different purposes, audiences, and access levels. However, these are deployed as a single Next.js application with route-based separation.
๐ Marketing Portal (Public)
Landing page, pricing, blog, SEO content. Goal: Convert visitors to users.
- Landing page with value proposition
- Pricing page (INR/USD toggle)
- Blog/SEO content
- Documentation
- Changelog
๐ฏ Application Portal (Authenticated)
Main product experience. Dashboard, prompts, generator, learning hub.
- User dashboard
- Prompt library browser
- AI code generator
- Learning hub & courses
- Generation history
- User settings
โ๏ธ Admin Portal (Internal)
Content management, analytics, user management. Admin role only.
- Prompt CRUD management
- Course content editor
- User management
- Analytics dashboard
- Revenue tracking
- System health monitoring
๐ API & Docs Portal (Public/Auth)
API documentation, integration guides, developer resources.
- API reference (OpenAPI)
- Integration guides
- SDK documentation
- Webhook documentation
- Code examples
1.2 Why Single Deployment Over Multiple Sites?
| Approach | Pros | Cons | Monthly Cost |
|---|---|---|---|
| Single Next.js App โ | Shared auth, components, types; single deployment; unified analytics; simpler CI/CD | Larger bundle if not optimized | $0-20 (Vercel Pro) |
| Separate Apps (Monorepo) | Independent deployments; isolated failures | Complex auth sharing; multiple Vercel projects; duplicated code | $60-100 |
| Separate Repos | Team independence | Sync nightmares; divergent codebases; no shared types | $100+ |
Use single Next.js app with App Router + subdomain routing. A proxy.ts middleware detects the hostname and rewrites requests: app.promptship.dev/* โ (app)/*, admin.promptship.dev/* โ (admin)/admin/*. Route groups (marketing), (app), (admin) give clean separation without deployment complexity. Locally: app.localhost:3000, admin.localhost:3000.
1.3 Route Structure
src/
โโโ proxy.ts # Subdomain routing (replaces middleware.ts in Next.js 16)
โโโ app/
โ โโโ layout.tsx # Root layout
โ โ
โ โโโ (marketing)/ # promptship.dev โ public marketing pages
โ โ โโโ layout.tsx # Marketing layout (header + footer)
โ โ โโโ page.tsx # Landing page (/)
โ โ โโโ pricing/page.tsx # Pricing (/pricing)
โ โ โโโ blog/ # Blog (/blog/*)
โ โ โโโ page.tsx
โ โ โโโ [slug]/page.tsx
โ โ
โ โโโ (auth)/ # app.promptship.dev/login, /signup, /verify
โ โ โโโ layout.tsx # Centered auth layout
โ โ โโโ login/page.tsx
โ โ โโโ signup/page.tsx
โ โ โโโ verify/page.tsx
โ โ
โ โโโ (app)/ # app.promptship.dev/* โ authenticated user portal
โ โ โโโ layout.tsx # App layout with sidebar
โ โ โโโ dashboard/page.tsx # Dashboard (/dashboard)
โ โ โโโ prompts/ # Prompt library (/prompts/*)
โ โ โ โโโ page.tsx
โ โ โ โโโ [category]/page.tsx
โ โ โโโ generate/page.tsx # AI Generator (/generate)
โ โ โโโ learn/ # Learning hub (/learn/*)
โ โ โ โโโ page.tsx
โ โ โ โโโ [moduleId]/[lessonId]/page.tsx
โ โ โโโ history/page.tsx # Generation history
โ โ โโโ settings/page.tsx # User settings
โ โ
โ โโโ (admin)/ # admin.promptship.dev โ proxy rewrites / โ /admin
โ โ โโโ layout.tsx # Admin layout
โ โ โโโ admin/ # Internal path prefix (hidden from admin subdomain URLs)
โ โ โโโ page.tsx # Admin dashboard (admin.promptship.dev/)
โ โ โโโ prompts/page.tsx # Prompt management (admin.promptship.dev/prompts)
โ โ โโโ users/page.tsx # User management (admin.promptship.dev/users)
โ โ โโโ analytics/page.tsx # Analytics (admin.promptship.dev/analytics)
โ โ
โ โโโ (docs)/ # promptship.dev/docs/*
โ โ โโโ docs/page.tsx
โ โ โโโ docs/[...slug]/page.tsx
โ โ
โ โโโ api/ # API routes (all subdomains)
โ โโโ auth/[...all]/route.ts # Better Auth
โ โโโ generate/route.ts # AI generation
โ โโโ prompts/route.ts # Prompts CRUD
โ โโโ webhooks/
โ โโโ stripe/route.ts
โ โโโ razorpay/route.ts
โ
โโโ config/
โโโ site.ts # Subdomain URLs (appUrl, adminUrl, marketingUrl)
โโโ navigation.ts # Per-portal navigation configs
1.4 Domain & Subdomain Strategy
All portals are served from a single Next.js deployment. The proxy.ts file inspects the Host header and rewrites/redirects requests to the correct route group. Cross-subdomain links use plain <a> tags (not Next.js <Link>) since they are different origins.
| URL | Purpose | Proxy Action | Local Dev URL | Rendering |
|---|---|---|---|---|
promptship.dev |
Landing, Marketing, Blog, Docs | Pass-through | localhost:3000 |
Static (SSG) + ISR |
app.promptship.dev |
Main Application (authenticated) | Auth check โ pass-through to (app)/ and (auth)/ routes |
app.localhost:3000 |
SSR + Client |
admin.promptship.dev |
Admin Panel (admin role) | Auth check โ rewrite / โ /admin, /prompts โ /admin/prompts |
admin.localhost:3000 |
SSR |
promptship.dev/docs/* |
Documentation | Pass-through | localhost:3000/docs |
Static (MDX) |
promptship.dev/blog/* |
Blog/SEO | Pass-through | localhost:3000/blog |
Static + ISR |
api.promptship.dev |
Public API (Phase 2) | โ | โ | Serverless |
The proxy detects subdomains by comparing the Host header against NEXT_PUBLIC_ROOT_DOMAIN. On the main domain, requests to /dashboard, /prompts, etc. are redirected to app.promptship.dev. Requests to /admin/* are redirected to admin.promptship.dev. Auth pages (/login, /signup, /verify) live on the app subdomain and redirect to /dashboard if already authenticated.
2 System Architecture
2.1 High-Level Architecture
2.2 Request Flow Architecture
2.3 Technology Stack (Final)
Frontend
| Framework | Next.js 15 (App Router) |
| Language | TypeScript 5.x |
| Styling | Tailwind CSS 3.x |
| Components | shadcn/ui |
| State | Zustand + TanStack Query |
| Forms | React Hook Form + Zod |
| Animations | Framer Motion |
| Icons | Lucide React |
Backend
| Runtime | Node.js 20 LTS |
| API | Next.js API Routes + Server Actions |
| Auth | Better Auth (Magic Link) |
| Database | PostgreSQL (Neon Serverless) |
| ORM | Drizzle ORM |
| Cache | Upstash Redis |
| Queue | Inngest (Background Jobs) |
| Storage | Vercel Blob |
AI & ML
| Primary AI | Claude Sonnet 3.5 (95%) |
| Fallback AI | GPT-4 Turbo (5%) |
| Prompt Engine | Custom Template System |
| Code Validation | TypeScript Compiler API |
Infrastructure
| Hosting | Vercel |
| CDN | Vercel Edge Network |
| DNS | Cloudflare |
| Monitoring | Sentry + Vercel Analytics |
| Analytics | PostHog |
| Video | Mux |
| Resend |
3 Complete Module Specifications
3.1 Module Dependency Map
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ MARKETING PORTAL โ
โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ Landing โ โ Pricing โ โ Blog โ โ Docs โ โ
โ โโโโโโฌโโโโโ โโโโโโฌโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ
โ โ โ โ
โ โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโ โ
โ โผ โ โ
โ โโโโโโโโโโโโ โ โ
โ โ Auth โโโโโโโโโโ โ
โ โโโโโโฌโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ APPLICATION PORTAL โ
โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Dashboard โโโโโโโบโ Sidebar โ โ
โ โโโโโโโโฌโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ โ
โ โผ โผ โผ โผ โ
โ โโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ Prompts โ โ Generator โ โ Learning โ โ Settings โ โ
โ โ Library โ โ โ โ Hub โ โ โ โ
โ โโโโโโโฌโโโโโโโ โโโโโโโฌโโโโโโโ โโโโโโโฌโโโโโโโ โโโโโโโโโโโโ โ
โ โ โ โ โ
โ โ โผ โ โ
โ โ โโโโโโโโโโโโโโ โ โ
โ โโโโโโโโโโบโ History โโโโโโโโโโโ โ
โ โโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SERVICES LAYER โ
โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โ โ AI Svc โ โ Auth Svc โ โ Payment โ โ Email โ โ Analyticsโ โ
โ โ โ โ โ โ Service โ โ Service โ โ Service โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
3.2 Detailed Module Specifications
| Route | / |
| Rendering | Static Generation with ISR (revalidate: 3600) |
| Purpose | Convert visitors โ signups through compelling value proposition |
| Dependencies | None (standalone) |
| Data Sources | Static content + CMS (future) |
Components
- HeroSection โ Main headline, video demo, dual CTAs
- SocialProof โ User count, testimonials, company logos
- FeaturesGrid โ 4 feature cards with icons
- PromptGalleryPreview โ 6-8 prompt cards (from static data)
- HowItWorks โ 3-step visual process
- PricingPreview โ 3 tier cards (links to /pricing)
- FAQAccordion โ 8 common questions
- FinalCTA โ "Ready to ship faster?" conversion block
Performance Targets
- LCP < 2.5s
- FID < 100ms
- CLS < 0.1
- Page Weight < 500KB (initial load)
| Routes | /login, /signup, /verify, /onboarding |
| Provider | Better Auth (Magic Link primary, OAuth optional) |
| Session | JWT in httpOnly cookie + Upstash Redis session store |
| Dependencies | Resend (email), Neon (users table) |
Auth Flows
// Signup Flow 1. User enters email โ POST /api/auth/signup 2. Create user record (tier: 'free', credits: 0) 3. Generate magic link token (expires: 15min) 4. Send email via Resend 5. User clicks link โ GET /api/auth/verify?token=xxx 6. Validate token, create session 7. Redirect to /app/onboarding (first time) or /app/dashboard // Login Flow 1. User enters email โ POST /api/auth/login 2. Check user exists 3. Generate magic link token 4. Send email via Resend 5. User clicks link โ Session created โ Dashboard // Session Management - JWT token in httpOnly cookie (7 days) - Session data in Upstash Redis (fast lookup) - Middleware validates on every /app/* request
| Route | /app/dashboard |
| Rendering | SSR (user-specific data) |
| Purpose | Central hub for all user activities |
| Dependencies | Auth, Prompts, Generator, Learning modules |
Dashboard Layout
- Sidebar โ Navigation (Home, Prompts, Generate, Learn, History, Settings)
- WelcomeBanner โ Personalized greeting + quick tips
- StatsCards โ Credits remaining, generations this month, prompts copied
- QuickActions โ Generate, Browse Prompts, Continue Course
- RecentGenerations โ Last 4-6 generations with thumbnails
- CourseProgress โ Current module + completion percentage
- NewPromptsCarousel โ Latest additions to library
| Routes | /app/prompts, /app/prompts/[category], /app/prompts/[id] |
| Rendering | SSR with client-side filtering |
| Purpose | Browse, search, copy, and favorite prompts |
| Access Control | Tier-based (free: 5 copies/mo, starter: 50, pro: unlimited) |
Features
- Search โ Full-text search with instant results
- Filters โ Category, Framework, Tier, Sort (popular/newest)
- PromptCard โ Preview image, title, category, framework icons, quick actions
- PromptModal โ Full prompt text, usage instructions, copy button, generate button
- Favorites โ Save prompts for quick access
- Usage Tracking โ Copy count, generate count per prompt
Copy Limit Logic
// Copy Limit Check async function canCopyPrompt(userId: string, tier: Tier): Promise{ const limits = { free: 5, starter: 50, pro: Infinity, team: Infinity }; const copiesThisMonth = await db.promptCopies .where({ userId, createdAt: { gte: startOfMonth() } }) .count(); return copiesThisMonth < limits[tier]; }
| Route | /app/generate |
| Rendering | Client-side (heavy interactivity) |
| Purpose | One-click AI code generation from prompts |
| Credit Cost | 1 credit per generation |
| Dependencies | AI Service, Prompts module, History module |
Generator Interface
- Template Selection (dropdown/grid)
- Framework Selection (React, Flutter, HTML, Vue)
- Style Options (Glassmorphism, Minimal, Bold, Gradient)
- Color Picker (primary color + presets)
- Dark Mode Toggle
- Animation Level (None, Subtle, Dynamic)
- Border Radius Slider (0-24px)
- Custom Instructions (textarea)
- Generate Button + Credit Display
- Live Preview (Sandpack iframe)
- Device Toggle (Desktop/Tablet/Mobile)
- Theme Toggle (Light/Dark)
- Code Tabs (framework views)
- Syntax Highlighted Code
- Copy/Download Buttons
- Regenerate Button
- Save to History (auto)
Generator State Machine
type GeneratorState =
| 'IDLE' // Default, waiting for input
| 'VALIDATING' // Checking input validity
| 'CHECKING_CREDITS' // Verifying user has credits
| 'GENERATING' // AI processing (2-8 seconds)
| 'SUCCESS' // Display output
| 'ERROR'; // Show error with retry option
// State Transitions
IDLE โ (click generate) โ VALIDATING
VALIDATING โ (valid) โ CHECKING_CREDITS
VALIDATING โ (invalid) โ IDLE (show errors)
CHECKING_CREDITS โ (has credits) โ GENERATING
CHECKING_CREDITS โ (no credits) โ IDLE (show upgrade modal)
GENERATING โ (success) โ SUCCESS
GENERATING โ (failure) โ ERROR
SUCCESS โ (regenerate) โ GENERATING
ERROR โ (retry) โ GENERATING
| Routes | /app/learn, /app/learn/[moduleId], /app/learn/[moduleId]/[lessonId] |
| Video Provider | Mux (HLS streaming) |
| Access Control | Pro and Team tiers only |
| Progress Tracking | Lesson completion, resume position |
Course Structure (40 Lessons)
5 lessons โข 72 min
10 lessons โข 195 min
8 lessons โข 158 min
8 lessons โข 160 min
9 lessons โข 173 min
40 lessons โข ~13 hours
3.3 Complete Module Matrix
| Module | Route | Auth | Tier | Rendering | Priority |
|---|---|---|---|---|---|
| M1: Landing | / |
No | All | SSG + ISR | P0 |
| M2: Auth | /login, /signup |
No | All | SSR | P0 |
| M3: Dashboard | /app/dashboard |
Yes | All | SSR | P0 |
| M4: Prompts | /app/prompts/* |
Yes | All (limited) | SSR + Client | P0 |
| M5: Generator | /app/generate |
Yes | Pro/Team | Client | P0 |
| M6: Learning Hub | /app/learn/* |
Yes | Pro/Team | SSR | P1 |
| M7: History | /app/history |
Yes | All | SSR | P1 |
| M8: Settings | /app/settings |
Yes | All | SSR | P1 |
| M9: Pricing | /pricing |
No | All | SSG | P0 |
| M10: Blog | /blog/* |
No | All | SSG + ISR | P2 |
| M11: Admin Dashboard | /admin |
Admin | Admin | SSR | P1 |
| M12: Admin Content | /admin/prompts |
Admin | Admin | SSR | P1 |
| M13: Docs | /docs/* |
No | All | SSG (MDX) | P2 |
4 Database Design
4.1 Database Architecture
Serverless PostgreSQL with autoscaling, branching for development, and generous free tier. Perfect for startups with variable load patterns.
4.2 Complete Schema
-- ============================================= -- USERS & AUTHENTICATION -- ============================================= CREATE TYPE user_tier AS ENUM ('free', 'starter', 'pro', 'team'); CREATE TYPE user_role AS ENUM ('user', 'admin'); CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, name VARCHAR(255), avatar_url TEXT, tier user_tier DEFAULT 'free', role user_role DEFAULT 'user', credits INTEGER DEFAULT 0, default_framework VARCHAR(20) DEFAULT 'react', preferred_currency VARCHAR(3) DEFAULT 'USD', onboarding_completed BOOLEAN DEFAULT false, email_verified BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE sessions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, token VARCHAR(255) UNIQUE NOT NULL, expires_at TIMESTAMPTZ NOT NULL, ip_address INET, user_agent TEXT, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE magic_links ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) NOT NULL, token VARCHAR(255) UNIQUE NOT NULL, expires_at TIMESTAMPTZ NOT NULL, used_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW() ); -- ============================================= -- SUBSCRIPTIONS & PAYMENTS -- ============================================= CREATE TYPE subscription_status AS ENUM ('active', 'canceled', 'past_due', 'paused', 'trialing'); CREATE TYPE payment_provider AS ENUM ('stripe', 'razorpay'); CREATE TABLE subscriptions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, plan VARCHAR(50) NOT NULL, -- starter, pro_monthly, pro_yearly, team status subscription_status DEFAULT 'active', provider payment_provider NOT NULL, provider_subscription_id VARCHAR(255), provider_customer_id VARCHAR(255), current_period_start TIMESTAMPTZ, current_period_end TIMESTAMPTZ, cancel_at_period_end BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE payments ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE SET NULL, subscription_id UUID REFERENCES subscriptions(id), provider payment_provider NOT NULL, provider_payment_id VARCHAR(255), amount INTEGER NOT NULL, -- in smallest currency unit (paise/cents) currency VARCHAR(3) NOT NULL, status VARCHAR(50) NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() ); -- ============================================= -- PROMPTS & CATEGORIES -- ============================================= CREATE TABLE categories ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(100) NOT NULL, slug VARCHAR(100) UNIQUE NOT NULL, description TEXT, icon VARCHAR(50), display_order INTEGER DEFAULT 0, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE prompts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), category_id UUID REFERENCES categories(id), title VARCHAR(255) NOT NULL, slug VARCHAR(255) UNIQUE NOT NULL, description TEXT, prompt_text TEXT NOT NULL, tier user_tier DEFAULT 'free', frameworks VARCHAR(20)[] DEFAULT '{react}', preview_image_url TEXT, usage_count INTEGER DEFAULT 0, copy_count INTEGER DEFAULT 0, favorite_count INTEGER DEFAULT 0, is_featured BOOLEAN DEFAULT false, is_published BOOLEAN DEFAULT true, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE prompt_copies ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, prompt_id UUID REFERENCES prompts(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE favorites ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, prompt_id UUID REFERENCES prompts(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(user_id, prompt_id) ); -- ============================================= -- AI GENERATIONS -- ============================================= CREATE TABLE generations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, prompt_id UUID REFERENCES prompts(id) ON DELETE SET NULL, framework VARCHAR(20) NOT NULL, template_type VARCHAR(50), options JSONB DEFAULT '{}', input_prompt TEXT NOT NULL, output_code TEXT NOT NULL, ai_provider VARCHAR(20) DEFAULT 'claude', ai_model VARCHAR(50), tokens_input INTEGER, tokens_output INTEGER, latency_ms INTEGER, cost_usd DECIMAL(10, 6), created_at TIMESTAMPTZ DEFAULT NOW() ); -- ============================================= -- LEARNING HUB -- ============================================= CREATE TABLE course_modules ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title VARCHAR(255) NOT NULL, slug VARCHAR(255) UNIQUE NOT NULL, description TEXT, display_order INTEGER DEFAULT 0, is_published BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE lessons ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), module_id UUID REFERENCES course_modules(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL, slug VARCHAR(255) NOT NULL, description TEXT, video_url TEXT, -- Mux playback ID video_duration_sec INTEGER, display_order INTEGER DEFAULT 0, is_free_preview BOOLEAN DEFAULT false, is_published BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE lesson_progress ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, lesson_id UUID REFERENCES lessons(id) ON DELETE CASCADE, watch_time_sec INTEGER DEFAULT 0, is_completed BOOLEAN DEFAULT false, completed_at TIMESTAMPTZ, last_position_sec INTEGER DEFAULT 0, updated_at TIMESTAMPTZ DEFAULT NOW(), UNIQUE(user_id, lesson_id) ); -- ============================================= -- INDEXES -- ============================================= CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_tier ON users(tier); CREATE INDEX idx_sessions_token ON sessions(token); CREATE INDEX idx_sessions_user ON sessions(user_id); CREATE INDEX idx_subscriptions_user ON subscriptions(user_id); CREATE INDEX idx_subscriptions_provider ON subscriptions(provider, provider_subscription_id); CREATE INDEX idx_prompts_category ON prompts(category_id); CREATE INDEX idx_prompts_tier ON prompts(tier); CREATE INDEX idx_prompts_published ON prompts(is_published); CREATE INDEX idx_generations_user_date ON generations(user_id, created_at DESC); CREATE INDEX idx_prompt_copies_user_date ON prompt_copies(user_id, created_at); CREATE INDEX idx_favorites_user ON favorites(user_id); CREATE INDEX idx_lesson_progress_user ON lesson_progress(user_id); -- Full-text search on prompts CREATE INDEX idx_prompts_search ON prompts USING GIN(to_tsvector('english', title || ' ' || COALESCE(description, '')));
4.3 Entity Relationship Diagram
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ users โโโโ1:Nโโ subscriptions โ โ categories โ
โโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโค
โ id (PK) โ โ id (PK) โ โ id (PK) โ
โ email โ โ user_id (FK) โ โ name โ
โ tier โ โ plan โ โ slug โ
โ credits โ โ status โ โโโโโโโโโฌโโโโโโโโโ
โโโโโโโโฌโโโโโโโ โ provider โ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โ โ 1:N
โ โผ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โโโโโโโ1:Nโโโโโบโ generations โ โ prompts โ
โ โโโโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโค
โ โ id (PK) โโโN:1โโโ id (PK) โ
โ โ user_id (FK) โ โ category_id(FK)โ
โ โ prompt_id (FK) โ โ title โ
โ โ output_code โ โ prompt_text โ
โ โโโโโโโโโโโโโโโโโโโ โ tier โ
โ โโโโโโโโโฌโโโโโโโโโ
โ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โโโโโโโ1:Nโโโโโบโ prompt_copies โโโโโโโโN:1โโโโโโค
โ โโโโโโโโโโโโโโโโโโโค โ
โ โ user_id (FK) โ โ
โ โ prompt_id (FK) โ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโ โ
โโโโโโโ1:Nโโโโโบโ favorites โโโโโโโโN:1โโโโโโ
โโโโโโโโโโโโโโโโโโโค
โ user_id (FK) โ
โ prompt_id (FK) โ
โโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ
โ users โโโโ1:Nโโ lesson_progress โโโโN:1โโ lessons โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโค
โ module_id (FK) โ
โโโโโโโโโฌโโโโโโโโโ
โ N:1
โผ
โโโโโโโโโโโโโโโโโโ
โ course_modules โ
โโโโโโโโโโโโโโโโโโ
5 AI Engineering & Prompt System
5.1 AI Provider Strategy
Primary: Claude Sonnet 3.5
- 95% of all generations
- Best code quality for UI components
- Input: $3/1M tokens
- Output: $15/1M tokens
- Avg cost per generation: ~$0.02
Fallback: GPT-4 Turbo
- 5% of generations (fallback only)
- Activated when Claude is down or rate limited
- Input: $10/1M tokens
- Output: $30/1M tokens
- Avg cost per generation: ~$0.05
5.2 Prompt Template Architecture
// Prompt Template Structure interface PromptTemplate { id: string; name: string; category: PromptCategory; basePrompt: string; frameworkInstructions: Record<Framework, string>; styleVariants: Record<Style, string>; optionModifiers: OptionModifier[]; } // Complete Prompt Assembly function buildPrompt( template: PromptTemplate, options: GeneratorOptions ): string { return ` ${SYSTEM_PROMPT} ${template.frameworkInstructions[options.framework]} ${template.basePrompt} ${template.styleVariants[options.style]} ## Specifications: - Primary Color: ${options.primaryColor} - Dark Mode: ${options.darkMode ? 'Yes' : 'No'} - Animation Level: ${options.animationLevel} - Border Radius: ${options.borderRadius}px ${options.customInstructions ? `## Additional Requirements:\n${options.customInstructions}` : ''} ## Output Requirements: - Output ONLY the code, no explanations - Code must be complete and copy-paste ready - Include all necessary imports `.trim(); }
5.3 System Prompts by Framework
| Framework | Key Instructions | Output Format |
|---|---|---|
| React + Tailwind | Functional components, TypeScript, Tailwind CSS, Framer Motion for animations, named export | .tsx file |
| Flutter | StatelessWidget (or Stateful if needed), const constructors, Material 3 guidelines, proper widget composition | .dart file |
| HTML/CSS | Semantic HTML5, CSS in <style> tag, CSS custom properties, flexbox/grid, media queries | .html file |
| Vue | Composition API, TypeScript, <script setup>, scoped styles | .vue file |
5.4 AI Cost Projections
5.5 AI Service Implementation
// lib/ai/generate.ts import Anthropic from '@anthropic-ai/sdk'; import OpenAI from 'openai'; const anthropic = new Anthropic(); const openai = new OpenAI(); interface GenerationResult { code: string; provider: 'claude' | 'openai'; tokensInput: number; tokensOutput: number; latencyMs: number; costUsd: number; } export async function generateCode( prompt: string, framework: Framework ): Promise<GenerationResult> { const startTime = Date.now(); try { // Try Claude first const response = await anthropic.messages.create({ model: 'claude-3-5-sonnet-20241022', max_tokens: 4096, messages: [{ role: 'user', content: prompt }], }); const code = extractCode(response.content[0].text, framework); const latencyMs = Date.now() - startTime; return { code, provider: 'claude', tokensInput: response.usage.input_tokens, tokensOutput: response.usage.output_tokens, latencyMs, costUsd: calculateCost('claude', response.usage), }; } catch (error) { // Fallback to OpenAI console.error('Claude failed, falling back to OpenAI:', error); const response = await openai.chat.completions.create({ model: 'gpt-4-turbo', max_tokens: 4096, messages: [{ role: 'user', content: prompt }], }); const code = extractCode(response.choices[0].message.content!, framework); const latencyMs = Date.now() - startTime; return { code, provider: 'openai', tokensInput: response.usage!.prompt_tokens, tokensOutput: response.usage!.completion_tokens, latencyMs, costUsd: calculateCost('openai', response.usage!), }; } }
6 Cost Optimization Strategy
6.1 Monthly Infrastructure Costs (Projected)
| Service | Launch (Month 1) | Growth (Month 6) | Scale (Month 12) | Notes |
|---|---|---|---|---|
| Vercel (Hosting) | $0 (Hobby) | $20 (Pro) | $20 (Pro) | Pro tier at 5K+ users |
| Neon (Database) | $0 (Free) | $19 (Launch) | $69 (Scale) | Scale at 50K+ users |
| Upstash (Redis) | $0 (Free) | $10 | $30 | Pay-per-request |
| Claude API | $100 | $400 | $2,000 | ~$0.02/generation |
| Mux (Video) | $0 | $20 | $50 | Pay-per-minute watched |
| Resend (Email) | $0 (Free) | $20 | $40 | 3K free, then pay |
| Cloudflare (DNS) | $0 | $0 | $20 | Pro at high traffic |
| Sentry (Monitoring) | $0 (Free) | $26 | $26 | Team tier |
| PostHog (Analytics) | $0 (Free) | $0 | $50 | 1M free events/mo |
| TOTAL | ~$100 | ~$535 | ~$2,305 |
6.2 Cost Optimization Techniques
AI Cost Optimization
- Prompt caching โ Cache identical requests in Redis (15 min TTL)
- Token optimization โ Strip unnecessary whitespace, use efficient prompts
- Output limits โ Set max_tokens to prevent runaway costs
- Tiered models โ Use Claude Haiku for simpler generations (future)
- Request batching โ Batch API calls where possible
Infrastructure Optimization
- Edge caching โ CDN for all static assets
- ISR โ Incremental Static Regeneration for semi-static pages
- Connection pooling โ Neon serverless handles this automatically
- Image optimization โ Vercel Image Optimization, WebP/AVIF
- Lazy loading โ Code split, defer non-critical JS
6.3 Revenue vs Cost Analysis
| Month | Revenue (INR) | Revenue (USD) | Costs (USD) | Gross Margin | Net Profit |
|---|---|---|---|---|---|
| Month 1 | โน50,000 | $600 | $100 | 83% | $500 |
| Month 3 | โน1,45,000 | $1,740 | $300 | 83% | $1,440 |
| Month 6 | โน3,05,000 | $3,660 | $535 | 85% | $3,125 |
| Month 12 | โน5,50,000 | $6,600 | $2,305 | 65% | $4,295 |
7 Scalability Architecture
7.1 Scaling Strategy by Component
Frontend (Vercel)
Automatic horizontal scaling. Edge-first architecture.
- Static pages served from 100+ edge locations
- SSR functions auto-scale to demand
- No configuration needed up to millions of requests
Database (Neon)
Serverless PostgreSQL with automatic scaling.
- Scales to zero when idle (cost savings)
- Automatic read replicas at Scale tier
- Connection pooling built-in
AI Generation Queue
Rate limiting + queue for burst protection.
- Upstash Redis for rate limiting
- Inngest for background job processing
- Circuit breaker for AI provider failures
Video Streaming (Mux)
Enterprise-grade video infrastructure.
- HLS adaptive streaming
- Global CDN delivery
- No scaling concerns
7.2 Traffic Projections
| Metric | Launch | Month 6 | Year 1 | Year 2 |
|---|---|---|---|---|
| Monthly Active Users | 500 | 5,000 | 15,000 | 50,000 |
| Page Views/Month | 25,000 | 250,000 | 750,000 | 2.5M |
| AI Generations/Month | 5,000 | 20,000 | 100,000 | 400,000 |
| Video Hours Watched | 500 | 2,000 | 10,000 | 40,000 |
| Database Size | 100 MB | 1 GB | 5 GB | 20 GB |
7.3 Rate Limiting Strategy
// middleware.ts - Edge Rate Limiting import { Ratelimit } from '@upstash/ratelimit'; import { Redis } from '@upstash/redis'; const ratelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(10, '10 s'), // 10 requests per 10 seconds }); const aiRatelimit = new Ratelimit({ redis: Redis.fromEnv(), limiter: Ratelimit.slidingWindow(5, '60 s'), // 5 AI calls per minute }); export async function middleware(request: NextRequest) { const ip = request.ip ?? '127.0.0.1'; // Different limits for different endpoints if (request.nextUrl.pathname.startsWith('/api/generate')) { const { success, remaining } = await aiRatelimit.limit(ip); if (!success) { return new Response('Too many requests', { status: 429 }); } } return NextResponse.next(); }
8 DevOps & CI/CD
8.1 Repository Structure
promptship/ โโโ .github/ โ โโโ workflows/ โ โโโ ci.yml # Lint, type-check, test on PR โ โโโ preview.yml # Deploy preview on PR โ โโโ production.yml # Deploy to production on main โโโ src/ โ โโโ app/ # Next.js App Router โ โโโ components/ # React components โ โโโ lib/ # Utilities, services โ โโโ db/ # Drizzle schema, migrations โ โโโ styles/ # Global styles โโโ public/ # Static assets โโโ scripts/ # Build, seed scripts โโโ tests/ # Test files โโโ drizzle.config.ts # Drizzle ORM config โโโ next.config.js โโโ tailwind.config.js โโโ tsconfig.json โโโ package.json
8.2 CI/CD Pipeline
8.3 Environment Variables
# .env.example # Database DATABASE_URL="postgresql://..." DIRECT_URL="postgresql://..." # Auth BETTER_AUTH_SECRET="..." BETTER_AUTH_URL="https://promptship.dev" # AI Providers ANTHROPIC_API_KEY="sk-ant-..." OPENAI_API_KEY="sk-..." # Payments STRIPE_SECRET_KEY="sk_live_..." STRIPE_WEBHOOK_SECRET="whsec_..." RAZORPAY_KEY_ID="rzp_live_..." RAZORPAY_KEY_SECRET="..." RAZORPAY_WEBHOOK_SECRET="..." # Redis UPSTASH_REDIS_REST_URL="..." UPSTASH_REDIS_REST_TOKEN="..." # Email RESEND_API_KEY="re_..." # Video MUX_TOKEN_ID="..." MUX_TOKEN_SECRET="..." # Analytics NEXT_PUBLIC_POSTHOG_KEY="..." SENTRY_DSN="..."
8.4 Monitoring & Alerting
Sentry
- Error tracking
- Performance monitoring
- Release tracking
- Slack alerts for P0 issues
Vercel Analytics
- Core Web Vitals
- Page-level performance
- Real user monitoring
PostHog
- Product analytics
- Conversion funnels
- Feature flags
- Session recordings
9 Security Architecture
9.1 Security Layers
| Layer | Protection | Implementation |
|---|---|---|
| Edge | DDoS, Bot Protection | Cloudflare, Vercel WAF |
| Transport | Encryption in Transit | HTTPS everywhere, TLS 1.3 |
| Authentication | Identity Verification | Better Auth, Magic Links, httpOnly cookies |
| Authorization | Access Control | Tier-based permissions, RBAC for admin |
| Application | Input Validation | Zod schemas, parameterized queries |
| Data | Data Protection | Encryption at rest (Neon), hashed tokens |
| Secrets | Credential Management | Vercel Environment Variables, no .env in repo |
9.2 Authentication Security
// Security Headers (next.config.js)
const securityHeaders = [
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
},
{
key: 'Content-Security-Policy',
value: ContentSecurityPolicy.replace(/\s{2,}/g, ' ').trim()
}
];
9.3 Data Protection
- PII Handling โ Minimal collection, only email + name required
- Payment Data โ Never stored, handled by Stripe/Razorpay
- Generated Code โ Stored for user history, deletable on request
- Analytics โ PostHog with anonymization options
- Backups โ Neon automatic daily backups, 7-day retention
10 API Design
10.1 Internal API Routes
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/api/auth/[...all] |
* | No | Better Auth catch-all |
/api/generate |
POST | Yes | AI code generation |
/api/prompts |
GET | Yes | List prompts (filtered by tier) |
/api/prompts/[id] |
GET | Yes | Get single prompt |
/api/prompts/[id]/copy |
POST | Yes | Record prompt copy |
/api/favorites |
GET, POST, DELETE | Yes | Manage favorites |
/api/generations |
GET | Yes | User's generation history |
/api/user/settings |
GET, PATCH | Yes | User preferences |
/api/webhooks/stripe |
POST | Signature | Stripe webhooks |
/api/webhooks/razorpay |
POST | Signature | Razorpay webhooks |
10.2 Request/Response Examples
// POST /api/generate // Request { "templateId": "hero-cinematic", "framework": "react", "options": { "style": "glassmorphism", "primaryColor": "#6366F1", "darkMode": true, "animationLevel": "dynamic", "borderRadius": 16 }, "customInstructions": "Add a newsletter signup form" } // Response (200 OK) { "success": true, "data": { "id": "gen_abc123", "code": "import React from 'react';\n\nexport default function Hero() {\n ...", "framework": "react", "tokensUsed": 1247, "creditsRemaining": 84 } } // Response (402 - No Credits) { "success": false, "error": { "code": "INSUFFICIENT_CREDITS", "message": "You have 0 credits remaining. Upgrade to continue.", "upgradeUrl": "/pricing" } }
10.3 Public API (Phase 2)
In Phase 2 (Month 6+), we'll expose a public API at api.promptship.dev for Team tier users to integrate AI generation into their own tools. This will include API keys, rate limiting, and usage billing.
11 Development Roadmap
12-Week Implementation Plan
| Week | Phase | Deliverables | Priority |
|---|---|---|---|
| 1 | Foundation | Next.js setup, Neon DB, Drizzle schema, Better Auth | P0 |
| 2 | Foundation | Dashboard layout, settings page, email templates | P0 |
| 3 | Foundation | Prompt library UI, search, categories, copy function | P0 |
| 4 | Core | AI service, Claude integration, prompt templates | P0 |
| 5 | Core | Generator UI, live preview, code viewer | P0 |
| 6 | Core | Stripe + Razorpay, webhooks, subscription logic | P0 |
| 7 | Content | Mux setup, video player, progress tracking | P1 |
| 8 | Content | Course navigation, 20+ prompts added | P1 |
| 9 | Content | 40+ prompts, 5 course videos, admin panel | P1 |
| 10 | Launch | Landing page, SEO, analytics setup | P0 |
| 11 | Launch | Beta testing, bug fixes, performance optimization | P0 |
| 12 | Launch | Product Hunt prep, final polish, LAUNCH ๐ | P0 |
โ Summary & Key Decisions
โ Architecture Decisions
- Single Next.js app for all portals (cost efficient)
- Route groups for logical separation
- Serverless-first infrastructure
- Edge-first caching strategy
- Claude primary + OpenAI fallback for AI
โ ๏ธ Key Risks & Mitigations
- AI costs โ Rate limiting, caching, tiered access
- Scaling โ Serverless auto-scales, Redis queue
- Security โ Edge WAF, parameterized queries, auth everywhere
- Vendor lock-in โ Standard PostgreSQL, portable code
This architecture supports 50,000+ users at under $2,500/month infrastructure cost while maintaining 80%+ gross margins. The serverless approach means costs scale with revenue, not ahead of it.