all blog posts

Inside PortfolioPilot: Architecture of a Developer-First Portfolio Generator

·6 min read
Next.jsTailwind CSSRazorpayGemini AIFull StackSystem Design

Every software engineer eventually faces the recurring ritual: rebuilding their personal portfolio from scratch. The initial excitement quickly devolves into boilerplate wrestling: configuring Tailwind typography, troubleshooting dynamic Open Graph images, wiring up analytics, and writing copy for the “About Me” section.

I built PortfolioPilot to solve this problem permanently. It is a full-stack platform that enables developers to launch SEO-optimized, production-ready portfolios in minutes, backed by AI copy assistance, edge caching, and Razorpay billing.

In this deep dive, I’ll walk through the architectural design decisions, the payment verification flow, and how Google Gemini AI was integrated into the authoring pipeline.


System Architecture

PortfolioPilot is structured around three primary requirements: SEO discoverability, frictionless user onboarding, and bulletproof transactional integrity.

                           ┌───────────────────────────────┐
                           │      User Browser (Client)    │
                           └───────────────┬───────────────┘


┌─────────────────────────────────────────────────────────────────────────────┐
│                       Next.js App Router (Edge Runtime)                     │
│                                                                             │
│  ┌───────────────────────┐  ┌──────────────────────┐  ┌──────────────────┐  │
│  │ Server Components     │  │ Route Handlers       │  │ Dynamic Metadata │  │
│  │ (Zero-JS UI Rendering)│  │ (API Endpoints)      │  │ (SEO & OpenGraph)│  │
│  └───────────────────────┘  └──────────┬───────────┘  └──────────────────┘  │
└────────────────────────────────────────┼────────────────────────────────────┘

                 ┌───────────────────────┼───────────────────────┐
                 ▼                       ▼                       ▼
    ┌─────────────────────────┐ ┌──────────────────┐ ┌──────────────────────┐
    │    Google Gemini API    │ │  Razorpay Orders │ │  PostgreSQL / Redis  │
    │  AI Copywriting Engine  │ │  & Webhook HMAC  │ │  State & Session Cache│
    └─────────────────────────┘ └──────────────────┘ └──────────────────────┘

Core Technology Stack

  • Framework: Next.js 14 (App Router, Server Components, Route Handlers)
  • Styling: Tailwind CSS with custom glassmorphism design tokens
  • Database & Cache: PostgreSQL with Prisma ORM and Redis for rate-limiting
  • AI Generation: Google Gemini Flash API (@google/genai)
  • Payments: Razorpay Node SDK with HMAC-SHA256 webhook verification
  • Deployment: Edge-optimized serverless container deployment

Engineering the Dynamic SEO Engine

A portfolio without SEO visibility is essentially a digital paperweight. In PortfolioPilot, every user portfolio is rendered using Next.js Server-Side Rendering (SSR) to guarantee search engines receive fully hydrated semantic HTML.

We use dynamic route parameters to construct granular Open Graph meta tags and JSON-LD structured data:

// app/[username]/layout.tsx
import type { Metadata } from 'next';

type Props = {
  params: { username: string };
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const profile = await getDeveloperProfile(params.username);

  if (!profile) {
    return {
      title: 'Profile Not Found',
      robots: { index: false, follow: false },
    };
  }

  const title = `${profile.name} — ${profile.headline} | PortfolioPilot`;
  const description = profile.bio || `Discover software engineering projects by ${profile.name}.`;
  const canonicalUrl = `https://portfoliopilot.dev/${params.username}`;

  return {
    title,
    description,
    alternates: {
      canonical: canonicalUrl,
    },
    openGraph: {
      title,
      description,
      url: canonicalUrl,
      type: 'profile',
      images: [
        {
          url: profile.ogImage || `https://portfoliopilot.dev/api/og?name=${encodeURIComponent(profile.name)}`,
          width: 1200,
          height: 630,
          alt: `${profile.name}'s Portfolio`,
        },
      ],
    },
    twitter: {
      card: 'summary_large_image',
      title,
      description,
      creator: profile.twitterHandle,
    },
  };
}

Secure Payments with Razorpay HMAC Verification

Allowing developers to upgrade to custom domains and premium portfolio templates required a rock-solid payment flow. Relying purely on client-side checkout callbacks is unsafe because bad actors can forge successful client requests.

PortfolioPilot uses a two-phase verification pattern:

  1. Order Creation: The backend generates a signed Razorpay order_id.
  2. Cryptographic Webhook Verification: The frontend completes the Razorpay modal, but the account upgrade is only granted once the backend cryptographically verifies the SHA256 signature.
// app/api/payments/verify/route.ts
import { NextResponse } from 'next/server';
import crypto from 'crypto';

export async function POST(req: Request) {
  try {
    const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = await req.json();

    const secret = process.env.RAZORPAY_KEY_SECRET;
    if (!secret) {
      return NextResponse.json({ error: 'Server misconfiguration' }, { status: 500 });
    }

    // Construct expected signature: HMAC_SHA256(order_id + "|" + payment_id, secret)
    const payload = `${razorpay_order_id}|${razorpay_payment_id}`;
    const expectedSignature = crypto
      .createHmac('sha256', secret)
      .update(payload)
      .digest('hex');

    const isAuthentic = crypto.timingSafeEqual(
      Buffer.from(expectedSignature, 'utf-8'),
      Buffer.from(razorpay_signature, 'utf-8')
    );

    if (!isAuthentic) {
      return NextResponse.json({ error: 'Invalid payment signature' }, { status: 400 });
    }

    // Idempotently update user subscription in PostgreSQL
    await upgradeUserSubscription(razorpay_order_id, razorpay_payment_id);

    return NextResponse.json({ success: true, message: 'Tier activated successfully' });
  } catch (err) {
    return NextResponse.json({ error: 'Verification failed' }, { status: 500 });
  }
}

[!IMPORTANT] Always use crypto.timingSafeEqual when verifying HMAC signatures to protect your authentication pipeline against timing attacks.


AI-Assisted Copywriting with Gemini API

Developers are notoriously self-critical when writing their own biographies. To reduce onboarding drop-off, PortfolioPilot integrates Google’s Gemini AI to transform a simple list of GitHub repositories, technical skills, and past jobs into compelling portfolio descriptions.

// lib/ai/bio-generator.ts
import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

export async function generateProfessionalBio(skills: string[], projects: string[]) {
  const prompt = `
    You are an expert technical resume writer and software branding consultant.
    Synthesize the following developer details into a punchy, 3-sentence professional bio:
    Skills: ${skills.join(', ')}
    Key Projects: ${projects.join(', ')}

    Constraints:
    - Tone: Confident, pragmatic, architecture-oriented.
    - Focus on measurable impact and systems thinking.
    - Avoid generic buzzwords like "ninja" or "rockstar".
  `;

  const response = await ai.models.generateContent({
    model: 'gemini-1.5-flash',
    contents: prompt,
    config: {
      temperature: 0.6,
      maxOutputTokens: 250,
    },
  });

  return response.text?.trim();
}

This reduced user onboarding completion time from over 20 minutes to under 3 minutes.


Results and What’s Next

Deploying PortfolioPilot delivered measurable improvements over manual portfolio management:

Metric Before PortfolioPilot With PortfolioPilot
Time to Launch 2 - 4 days (custom code) < 5 minutes
Lighthouse Performance Variable (~60 - 80) 98 - 100 Score
SEO Indexing Manual sitemaps & headers Automatic SSR & JSON-LD
Payment Activation Custom gateway setup 1-Click Razorpay checkout

Check out the full repository on GitHub: anshu4sharma/Portfoliopilot-v1.

For my personal implementation running this architecture, visit anshu.uk.