Skip to content

Repository files navigation

GitProof 2

A sophisticated developer portfolio platform that transforms your GitHub activity into a shareable, AI-enhanced professional profile.

Next.jsTypeScriptPrismaTailwind CSS

GitProof 2 analyzes your public GitHub repositories, calculates impact metrics, generates AI-powered insights, and creates a beautiful public profile page to showcase your best work to recruiters and collaborators.


📖 Table of Contents


🎯 Overview

GitProof 2 is a full-stack Next.js application that helps developers:

  1. Authenticate with GitHub - Secure OAuth integration
  2. Sync repository data - Fetch public repos, commits, stars, forks
  3. Calculate impact scores - Smart algorithm (0-50 scale) based on popularity, recency, and maturity
  4. Generate AI insights - Use Google Gemini to analyze strengths and growth areas
  5. Customize portfolio - Select featured projects, rewrite descriptions with AI
  6. Share public profiles - Beautiful, shareable profile pages at /u/[username]

Live Example: /u/yourname shows your curated portfolio to the world.


✨ Features

🔐 GitHub Authentication

  • OAuth 2.0 integration with GitHub
  • Identity-only OAuth scopes (read:user, user:email)
  • Public-repo-only sync with no private-repository access
  • Encrypted server-side token storage via Prisma and NextAuth
  • Session persistence with JWT strategy

📊 Repository Analysis Dashboard

  • Contribution heatmap - GitHub-style activity visualization
  • Hourly activity chart - Discover your most productive hours
  • Impact scores - Algorithmic ranking (0-50) for each repository
  • Tech stack breakdown - Visual percentage bars for languages
  • Top 6 repositories - Auto-selected by impact score
  • Real-time sync - Manual refresh button with rate limit handling

✏️ Portfolio Editor

  • Featured project selection - Choose up to 6 projects to showcase
  • AI description rewriting - Use Gemini to make descriptions recruiter-friendly
  • Bio editor - Manual or AI-generated professional summary
  • Visibility controls - Hide/show projects from public profile
  • Live preview - See changes before publishing
  • Bulk actions - Save all changes at once

🤖 AI-Powered Features

  • Project description rewriting - Context-aware using README, topics, and stats
  • README generation - Analyzes repo structure, dependencies, and source code to generate comprehensive READMEs
  • Bio generation - Summarizes your top projects into a professional bio
  • Insight analysis - Detects strengths (consistency, expertise) and growth areas
  • Powered by Gemini 2.5 Flash Lite - Fast, cost-effective LLM

🌐 Public Developer Profiles

  • Shareable URLs - /u/[username] for public access
  • Privacy controls - Toggle profile visibility on/off
  • Featured projects showcase - Masonry grid layout
  • Impact metrics display - Report card with scores
  • Professional presentation - Clean, modern design with light/dark themes

📈 Analytics & Insights

  • Impact Score - Weighted algorithm combining popularity, recency, maturity
  • Consistency Metric - Percentage of active days in last year
  • Developer Archetype - Classification (e.g., "The Architect", "10x Engineer")
  • Growth Recommendations - AI-generated areas for improvement
  • Top Technologies - Language and topic analysis

⚙️ Settings & Account Management

  • Profile visibility - Public/private toggle
  • Theme switching - Light, dark, or system preference
  • Email notifications - Opt-in for product updates
  • Account deletion - Complete data removal + GitHub OAuth revocation
  • Session management - Sign out all devices

🛠 Tech Stack

Frontend

  • Next.js 16.0.10 - React framework with App Router
  • React 19.2.1 - UI library with Server Components
  • TypeScript 5 - Type-safe JavaScript
  • Tailwind CSS 4 - Utility-first styling
  • shadcn/ui - Accessible component library (Radix UI)
  • Framer Motion 12.23.26 - Animation library
  • Lucide React 0.561.0 - Icon system (561+ icons)

Backend

  • Next.js API Routes - RESTful endpoints
  • Server Actions - Type-safe mutations with "use server"
  • Prisma 5.22.0 - ORM for PostgreSQL
  • PostgreSQL - Primary database
  • NextAuth 5.0.0-beta.30 - Authentication

External APIs

  • GitHub GraphQL API - Repository and user data
  • GitHub OAuth - Authentication provider
  • Google Gemini 2.5 Flash Lite - AI text generation

Data Visualization

  • Recharts 3.5.1 - React charting library
  • Victory Vendor - D3 components

Developer Experience

  • ESLint 9 - Code linting
  • PostCSS - CSS transformation
  • class-variance-authority - Component API builder

🚀 Getting Started

Prerequisites

  • Node.js 18+ - JavaScript runtime
  • npm/yarn/pnpm - Package manager
  • PostgreSQL - Database (local or hosted)
  • GitHub OAuth App - Create one here
  • Google AI API Key - Get one here

Installation

  1. Clone the repository

    git clone https://github.com/bgar324/gitproof-2
    cd gitproof-2
  2. Install dependencies

    npm install
  3. Set up environment variables

    Create a .env.local file in the root directory:

    # DatabaseDATABASE_URL="postgresql://user:password@localhost:5432/gitproof"# NextAuthAUTH_SECRET="generate-with-openssl-rand-base64-32"NEXTAUTH_URL="http://localhost:3000"# GitHub OAuthAUTH_GITHUB_ID="your_github_client_id"AUTH_GITHUB_SECRET="your_github_client_secret"# Google AIGOOGLE_GENERATIVE_AI_API_KEY="your_gemini_api_key"
  4. Set up the database

    npx prisma generate
    npx prisma db push
  5. Run the development server

    npm run dev
  6. Open the app

    Navigate to http://localhost:3000

GitHub OAuth Setup

  1. Go to GitHub Settings > Developer Settings > OAuth Apps
  2. Click New OAuth App
  3. Fill in:
    • Application name: GitProof 2
    • Homepage URL: http://localhost:3000
    • Authorization callback URL: http://localhost:3000/api/auth/callback/github
  4. Click Register application
  5. Copy Client ID and Client Secret to .env.local

📁 Project Structure

gitproof-2/
├── app/ # Next.js App Router
│ ├── (app)/ # Protected routes (auth required)
│ │ ├── dashboard/ # Analytics & overview
│ │ ├── editor/ # Portfolio editor
│ │ ├── settings/ # Account settings
│ │ └── layout.tsx # App-wide navbar
│ ├── (marketing)/ # Public marketing pages
│ ├── api/ # API routes
│ │ ├── auth/ # NextAuth handlers
│ │ └── sync/ # Data sync endpoint
│ ├── u/[username]/ # Public profile pages
│ ├── manifesto/ # Info pages
│ ├── methodology/
│ ├── privacy/
│ ├── actions.ts # Server actions
│ ├── layout.tsx # Root layout
│ └── globals.css # Global styles
├── components/ # React components
│ ├── ui/ # shadcn/ui primitives
│ ├── dashboard/ # Dashboard components
│ ├── editor/ # Editor components
│ ├── profile/ # Profile components
│ ├── marketing/ # Landing page sections
│ ├── layout/ # Navbar, footer, wrappers
│ ├── settings/ # Settings sections
│ ├── shared/ # Reusable utilities
│ ├── report-card.tsx # Main report card
│ └── repo-modal.tsx # Repository modal
├── lib/ # Utilities & business logic
│ ├── github.ts # GitHub GraphQL client
│ ├── sync.ts # Repository sync logic
│ ├── stats.ts # Analytics calculations
│ ├── rate-limit.ts # GitHub API rate limiting
│ ├── sanitize.ts # Data sanitization
│ ├── utils.ts # Helper functions
│ ├── language-colors.ts # Language colors
│ ├── db.ts # Prisma client
│ └── data/ # Static data
├── prisma/
│ └── schema.prisma # Database schema
├── types/
│ └── next-auth.d.ts # NextAuth types
├── auth.ts # NextAuth config
├── middleware.ts # Route protection
├── next.config.ts # Next.js config
├── tailwind.config.ts # Tailwind config
└── package.json # Dependencies

🏗 Architecture

App Router Flow

Public Routes (no authentication)
├── / → Landing page
├── /methodology → How it works
├── /privacy → Privacy policy
├── /manifesto → Mission statement
├── /u/[username] → Public profile (if isPublic = true)
└── /api/auth/* → NextAuth OAuth callbacks
Protected Routes (requires authentication)
├── /dashboard → Analytics overview
├── /dashboard/repos → All repositories
├── /editor → Portfolio editor
└── /settings → Account settings

Data Flow

GitHub OAuth → NextAuth → Prisma → PostgreSQL
↓
User Session
↓
Authenticated Routes
↓
Server Components (DB queries)
↓
Client Components (interactivity)
↓
Server Actions (mutations)
↓
Database Updates

Server vs Client Components

  • Server Components (default): Fetch data, render on server

    • app/(app)/dashboard/page.tsx
    • app/u/[username]/page.tsx
  • Client Components ("use client"): Interactive UI

    • app/(app)/dashboard/view.tsx
    • components/dashboard/*
    • components/editor/*

💾 Database Schema

User Model

modelUser {idString@id@default(cuid())emailString@uniqueusernameString@uniquenameString?imageString?bioString?isPublicBoolean@default(false)emailNotificationsBoolean@default(false)lastSyncedAtDateTime?profileDataJson?// Cached GitHub datacreatedAtDateTime@default(now())updatedAtDateTime@updatedAtaccountsAccount[]sessionsSession[]projectsProject[]}

Project Model

modelProject {idString@id@default(cuid())userIdStringgithubIdIntnameStringdescString?urlStringhomepageString?languageString?topicsString[]starsInt@default(0)forksInt@default(0)lastPushDateTimeimpactScoreInt@default(0)// 0-50readmeString?// Original GitHub READMEaiDescriptionString?// AI-rewritten descriptionaiReadmeString?// AI-generated READMEisHiddenBoolean@default(false)createdAtDateTime@default(now())updatedAtDateTime@updatedAtuserUser@relation(fields: [userId], references: [id], onDelete: Cascade)@@index([userId])@@index([impactScore])@@index([lastPush])}

Account & Session Models (NextAuth)

modelAccount {idString@id@default(cuid())userIdStringproviderString// "github"providerAccountIdStringaccess_tokenString?// GitHub OAuth token// ... other OAuth fields}modelSession {idString@id@default(cuid())sessionTokenString@uniqueuserIdStringexpiresDateTime}

🔌 API & Server Actions

REST Endpoints

No standalone sync endpoint. Repository syncing is performed through authenticated server actions that fetch directly from GitHub on the server.

Server Actions

Located in app/actions.ts:

ActionDescription
triggerSync()Force sync GitHub repos
generateAIDescription(projectId)Generate AI description
generateReadme(projectId)Generate AI README
getProjectReadme(projectId)Get original + generated README
revertReadme(projectId)Clear generated README
toggleProfilePublic(isPublic)Toggle profile visibility
updateUserBio(bio)Save user bio
generateUserBio()AI generate bio
batchUpdateProjectVisibility()Bulk update visibility
updateProjectDescription()Edit project desc
deleteUserAccount()Delete account + revoke OAuth

🧩 Component System

Component Categories

Dashboard Components (components/dashboard/)

  • activity-heatmap - Contribution calendar
  • dashboard-header - Top stats header
  • dashboard-repo-card - Repository card
  • focus-hours-card - Hourly activity chart
  • impact-tooltip - Score explanation
  • score-modal - Algorithm breakdown
  • stat-card - Metric display
  • tech-stack-card - Language bars
  • time-range-selector - Filter controls
  • top-repos-header - Section header

Editor Components (components/editor/)

  • editor-repo-card - Editable repo card with AI rewrite
  • featured-section - Featured projects manager
  • identity-section - Bio editor
  • library-section - All projects grid
  • save-button - Save changes button

Modal Components (components/modals/)

  • readme-generator-modal - AI README generation with preview/raw/diff views

Profile Components (components/profile/)

  • hero-section - Profile header
  • portfolio-section - Projects display
  • public-repo-card - Public repo card

UI Primitives (components/ui/)

shadcn/ui components: badge, button, card, dialog, dropdown-menu, input, label, separator, skeleton, switch, tabs, textarea, tooltip


📊 Impact Score Algorithm

The Impact Score (0-50) combines three weighted components:

Formula

Score = min(round(Popularity + Recency + Maturity), 50)

1. Popularity (0-40 points, ~40-45%)

Logarithmic scale with increased multiplier to better reward popular projects:

Popularity=log₂(stars+forks×2+1)×4.5Popularity=min(Popularity,40)

Examples:

  • 100 stars, 10 forks → ~30 points
  • 1,000 stars, 100 forks → ~45 points (capped at 40)
  • 10,000 stars, 1,000 forks → ~60 points (capped at 40)

2. Recency (0-15 points, ~25-30%)

Graceful decay that rewards maintained projects, not just recently pushed:

< 7 days ago: +15 points (S-tier: Last week)
< 30 days ago: +12 points (A-tier: Last month)
< 90 days ago: +8 points (B-tier: Last quarter)
< 180 days ago: +5 points (C-tier: Last 6 months)
< 365 days ago: +2 points (D-tier: Last year)
else: +0 points (Abandoned)

3. Maturity (0-15 points, ~25-30%)

Multi-factor assessment of project quality:

Description:
> 100 chars: +5 points (Detailed)
> 20 chars: +3 points (Basic)
README:
> 2000 chars: +5 points (Comprehensive)
> 500 chars: +3 points (Good)
> 100 chars: +1 point (Minimal)
Homepage: +3 points
Topics:
≥ 3 tags: +3 points (Well-tagged)
≥ 1 tag: +1 point (Basic)

Max: 15 points from maturity (capped)

User Score Aggregation

Instead of a simple average, we use a weighted average of top 6 projects:

UserScore = top1×50% + top2×12.5% + top3×12.5% + top4×8.33% + top5×8.33% + top6×8.33%

This emphasizes quality over quantity - your best project carries 50% of the weight.

Example

Repository: "awesome-react-hooks"

  • Stars: 250, Forks: 30
  • Last Push: 10 days ago
  • Description: "Production-ready React hooks library"
  • Homepage: https://awesome-hooks.dev
  • Topics: ['react', 'hooks', 'typescript']
  • README: 1,500 chars

Calculation:

Popularity = log₂(250 + 30×2 + 1) × 4.5 = 37 points (was ~25 with old formula)
Recency = 12 points (< 30 days, A-tier)
Maturity:
- Description (42 chars): +3
- README (1500 chars): +3
- Homepage: +3
- Topics (3 tags): +3
= 12 points
Total = 37 + 12 + 12 = 50 points (capped) ✨

🤖 AI Integration

Google Gemini 2.5 Flash Lite

Used for:

  1. Project description rewriting
  2. README generation
  3. User bio generation
  4. Insight analysis

Configuration

GOOGLE_GENERATIVE_AI_API_KEY="your_api_key"

README Generation

The README generator analyzes your repository to create comprehensive, professional documentation.

Architecture

lib/readme.ts → Repository context fetching (GraphQL)
app/actions.ts → Server actions (generateReadme, revertReadme)
components/modals/ → ReadmeGeneratorModal UI component

How It Works

  1. Context Fetching (lib/readme.ts)

    • Fetches repository metadata via GitHub GraphQL API
    • Retrieves README variants (README.md, README.MD, readme.md)
    • Extracts config files (package.json, pyproject.toml, Cargo.toml, go.mod, etc.)
    • Builds file tree (2 levels deep)
    • Selects language-specific entrypoint files (up to 3)
  2. Confidence Scoring (0-3 scale)

    +1 point: Has config file (package.json, Cargo.toml, etc.)
    +1 point: Has recognized primary language
    +1 point: Has identifiable entrypoint file
    
  3. Smart Entrypoint Detection

    • Language-aware file selection (e.g., src/index.ts for TypeScript, main.py for Python)
    • Excludes test files, mocks, and utility modules
    • Truncates source to 1000 chars per file
  4. Generation (app/actions.ts)

    • Builds context-aware prompt with repo structure, dependencies, and code samples
    • Sends to Gemini 2.5 Flash Lite
    • Sanitizes output and saves to Project.aiReadme

Supported Languages & Entrypoints

LanguageEntrypoint Patterns
TypeScriptsrc/index.ts, src/main.ts, src/App.tsx, app/page.tsx
JavaScriptsrc/index.js, server.js, app.js, pages/index.jsx
Pythonmain.py, app.py, src/main.py, __main__.py
Rustsrc/main.rs, src/lib.rs
Gomain.go, cmd/main.go
Rubylib/main.rb, app.rb
PHPindex.php, public/index.php
Javasrc/main/java/Main.java, App.java
C#Program.cs, src/Program.cs
SwiftSources/main.swift, App.swift
Kotlinsrc/main/kotlin/Main.kt

Package Manager Detection

Automatically detects and includes correct install/run commands:

Config FileManagerInstall Command
package.jsonnpm/yarn/pnpm/bunnpm install
pyproject.tomlpoetry/pippoetry install
requirements.txtpippip install -r requirements.txt
Cargo.tomlcargocargo build
go.modgogo mod download
composer.jsoncomposercomposer install
Gemfilebundlerbundle install

UI Component

The ReadmeGeneratorModal provides:

  • Preview mode: Rendered markdown with syntax highlighting
  • Raw mode: Plain text for copying
  • Diff mode: Side-by-side comparison with original README
  • Actions: Copy to clipboard, download as file, revert to original

Server Actions

// Generate README for a projectgenerateReadme(projectId: string): Promise<{success: boolean;readme: string;confidenceScore: number;}>// Get original and generated READMEsgetProjectReadme(projectId: string): Promise<{original: string|null;generated: string|null;}>// Clear generated READMErevertReadme(projectId: string): Promise<void>// Alternative: generate by GitHub repo ID (for dashboard)generateReadmeByGithubId(githubId: number): Promise<{...}>

Database Schema

modelProject {// ... other fieldsreadmeString?// Original GitHub READMEaiReadmeString?// AI-generated README}

Prompt Examples

Project Description

You are a professional technical recruiter. Rewrite this GitHub
project description to be compelling for recruiters.
Project: awesome-api
Description: REST API with Node.js
Topics: nodejs, express, postgresql
README: Built a scalable REST API...
Make it:
- 1-2 sentences max
- Highlight technical skills
- Emphasize impact/value
- Professional tone
- No emojis

Output:

Built a high-performance REST API using Node.js and PostgreSQL,
serving 10K+ daily requests with 99.9% uptime. Implemented JWT
authentication, caching strategies, and comprehensive API docs.

AI Safety

All AI content is sanitized:

// lib/sanitize.tsexportfunctionsanitizeForPostgres(input: string|null): string{returninput?.replace(/\0/g,'')// Remove null bytes.replace(/[\x00-\x1F\x7F-\x9F]/g,(char)=>['\n','\t','\r'].includes(char) ? char : '')||'';}

🔐 Authentication Flow

Step-by-Step

  1. User clicks "Sign in with GitHub"

    <buttononClick={()=>signIn("github")}>SigninwithGitHub</button>
  2. GitHub OAuth prompts authorization

    • Scopes: read:user, user:email
  3. GitHub redirects with code

    /api/auth/callback/github?code=ABC123
    
  4. NextAuth exchanges code for token

    • Stores access token in Account table
    • Creates/updates User record
    • Issues JWT session
  5. Middleware protects routes

    // middleware.tsif(protectedPath&&!session){redirect('/');}
  6. Session available in components

    constsession=awaitauth();console.log(session.user.username);

Session Structure

{user: {email: "user@example.com",name: "John Doe",image: "https://avatars.githubusercontent.com/...",username: "johndoe"},expires: "2025-01-18T12:00:00.000Z"}

🔒 Security Features

1. Data Sanitization

All inputs sanitized before storage:

  • Remove null bytes (PostgreSQL errors)
  • Strip control characters
  • Keep safe whitespace (\n, \t, \r)

2. Access Control

  • Server-side session checks
  • Database queries filtered by userId
  • No cross-user data access

3. OAuth Token Security

  • Tokens stored encrypted server-side only (Prisma)
  • Never exposed to client
  • OAuth scopes limited to GitHub identity
  • Private repositories are never requested or synced
  • Revocation is attempted on account deletion

4. Route Protection

Middleware enforces auth:

constprotectedRoutes=['/dashboard','/editor','/settings'];if(protectedPath&&!session)redirect('/');

5. Rate Limiting

GitHub API rate limit handling:

  • In-memory cache per user
  • Exponential backoff
  • Custom error handling

6. SQL Injection Prevention

Prisma ORM provides parameterized queries:

// Safe - auto-escapedawaitdb.user.findUnique({where: {email: userInput}});

⚙️ Configuration

Environment Variables

# DatabaseDATABASE_URL="postgresql://user:password@localhost:5432/gitproof"# NextAuthAUTH_SECRET="openssl-rand-base64-32"NEXTAUTH_URL="http://localhost:3000"# GitHub OAuthAUTH_GITHUB_ID="github_client_id"AUTH_GITHUB_SECRET="github_client_secret"# Google AIGOOGLE_GENERATIVE_AI_API_KEY="gemini_api_key"

Next.js Config

// next.config.tsconstnextConfig={images: {remotePatterns: [{protocol: "https",hostname: "avatars.githubusercontent.com",},{protocol: "https",hostname: "github.com",},],},};

💻 Development

Scripts

# Development server (hot reload)
npm run dev
# Production build
npm run build
# Start production server
npm start
# Run linter
npm run lint
# Prisma commands
npx prisma generate # Generate client
npx prisma db push # Push schema to DB
npx prisma studio # Open GUI

Code Style

  • ESLint: Next.js recommended config
  • TypeScript: Strict mode enabled
  • Naming: kebab-case for components

Component Patterns

Server Component:

// app/dashboard/page.tsxexportdefaultasyncfunctionDashboardPage(){constsession=awaitauth();constuser=awaitdb.user.findUnique({where: {email: session.user.email},});return<DashboardViewdata={user}/>;}

Client Component:

// components/dashboard/view.tsx"use client";exportfunctionDashboardView({ data }){const[filter,setFilter]=useState("all");return<div>{/* ... */}</div>;}

Server Action:

// app/actions.ts"use server";exportasyncfunctionupdateBio(bio: string){constsession=awaitauth();if(!session)thrownewError("Unauthorized");awaitdb.user.update({where: {email: session.user.email},data: { bio },});}

🚀 Deployment

Vercel (Recommended)

  1. Push to GitHub

    git push origin main
  2. Import to Vercel

    • Go to vercel.com
    • Click "New Project"
    • Import repository
  3. Set environment variables

    DATABASE_URL
    AUTH_SECRET
    NEXTAUTH_URL
    AUTH_GITHUB_ID
    AUTH_GITHUB_SECRET
    GOOGLE_GENERATIVE_AI_API_KEY
    
  4. Deploy

    • Auto-deploys on push to main

Database Options

Post-Deployment

  • Environment variables set
  • Database connected
  • Prisma schema pushed
  • GitHub OAuth callback URL updated
  • Test authentication
  • Monitor logs

🤝 Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
    git checkout -b feature/amazing-feature
  3. Commit changes
    git commit -m "Add amazing feature"
  4. Push to branch
    git push origin feature/amazing-feature
  5. Open a Pull Request

Guidelines

  • Follow TypeScript/ESLint rules
  • Use kebab-case for files
  • Add tests if applicable
  • Update documentation

📄 License

MIT License - see LICENSE file


🙏 Acknowledgments

  • Next.js - React framework
  • Vercel - Hosting platform
  • shadcn/ui - Component library
  • Prisma - Database ORM
  • GitHub - OAuth & data source
  • Google Gemini - AI generation

📚 Additional Resources


Built by Benjamin Garcia.

About

GitProof is an analytics platform that evaluates public GitHub profiles using deterministic metrics and privacy-safe heuristics. It generates shareable reports with impact scores, consistency analysis, and archetype classifications, backed by GitHub’s GraphQL API and OAuth authentication.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages