AI-Powered GitHub Code Reviews & Analytics Platform
Automate code review workflows with advanced AI analysis. Get intelligent insights on pull requests, track coding activity, and improve code quality at scale.
- ✨ Features
- 🛠️ Tech Stack
- 📋 Project Structure
- 🏗️ Architecture
- 🚀 Getting Started
- 📖 Development Guide
- 🔄 Data Flow
- 📚 API Routes
- 🤝 Contributing
- 🐛 Troubleshooting
- Automated Pull Request Analysis - Leverage Google's Gemini AI to automatically analyze pull requests
- Intelligent Comments - AI generates contextual code review comments with suggestions
- Quality Metrics - Assess code quality, complexity, and best practices
- Multi-Repository Support - Review code from multiple GitHub repositories simultaneously
- Contribution Graph - Visualize coding frequency and patterns over the past year
- Activity Overview - Monthly breakdown of commits, PRs, and AI reviews
- Repository Statistics - Track total repos, commits, pull requests, and reviews
- Real-time Updates - Keep your metrics fresh with automatic data collection
- GitHub OAuth Integration - Seamless login with GitHub
- Session Management - Secure session handling with better-auth
- Protected Routes - Role-based access control for dashboard pages
- Flexible Plans - Multiple subscription tiers via Polar.sh
- Payment Processing - Secure payment handling and invoicing
- Usage Tracking - Monitor review credits and API usage
- GitHub Webhooks - Real-time PR notifications and event handling
- Background Processing - Async job queue with Inngest for heavy workloads
- Event Logging - Track all AI reviews and system events
| Category | Technology | Version | Purpose |
|---|---|---|---|
| Framework | Next.js | 16.2.2 | Full-stack React framework with App Router |
| Runtime | React | 19.2.4 | UI component library |
| Language | TypeScript | 5.9.3 | Type-safe JavaScript |
| Styling | Tailwind CSS | v4 | Utility-first CSS framework |
| UI Components | shadcn/ui | - | Beautiful, accessible component library |
| Database | PostgreSQL | - | Primary data store |
| ORM | Prisma | 7.5.0 | Type-safe database client |
| Authentication | better-auth | 1.5.5 | Full-stack auth solution |
| AI/ML | Google AI SDK | 3.0.54 | Gemini API for code analysis |
| Vector DB | Pinecone | 7.1.0 | Semantic search & embeddings |
| State Management | TanStack Query | 5.94.5 | Server state management |
| Theme | next-themes | 0.4.6 | Light/dark mode support |
| Background Jobs | Inngest | 3.52.7 | Serverless task queue |
| Payments | Polar.sh SDK | 0.46.7 | Subscription management |
| Analytics | Vercel Analytics | 2.0.1 | User behavior tracking |
codehawk/
├── 📁 app/ # Next.js App Router pages
│ ├── 📁 (auth)/ # Auth route group
│ │ └── 📄 login/page.tsx # GitHub OAuth login page
│ ├── 📁 api/ # API routes
│ │ ├── 📄 auth/[...all]/route.ts # Auth endpoints
│ │ ├── 📄 inngest/route.ts # Inngest webhook handler
│ │ └── 📄 webhooks/github/route.ts # GitHub webhook receiver
│ ├── 📁 dashboard/ # Protected dashboard pages
│ │ ├── 📄 layout.tsx # Dashboard layout with sidebar
│ │ ├── 📄 page.tsx # Main dashboard (stats & graphs)
│ │ ├── 📁 repository/ # Repository management
│ │ ├── 📁 reviews/ # Review history & details
│ │ ├── 📁 settings/ # User settings & preferences
│ │ └── 📁 subscription/ # Subscription management
│ ├── 📄 layout.tsx # Root layout (HTML, providers)
│ ├── 📄 page.tsx # Home page (redirect to dashboard)
│ ├── 📄 global-error.tsx # Global error boundary
│ ├── 📄 error.tsx # App-level error boundary
│ ├── 📄 not-found.tsx # 404 page
│ └── 📄 globals.css # Global styles
│
├── 📁 components/ # Reusable React components
│ ├── 📁 providers/
│ │ ├── 📄 root-wrapper.tsx # Client providers (Theme, Query, Analytics)
│ │ ├── 📄 theme-provider.tsx # next-themes wrapper
│ │ └── 📄 query-provider.tsx # TanStack Query provider
│ ├── 📁 ui/ # shadcn/ui components
│ │ ├── 📄 button.tsx
│ │ ├── 📄 card.tsx
│ │ ├── 📄 sidebar.tsx
│ │ ├── 📄 tooltip.tsx
│ │ ├── 📄 chart.tsx
│ │ └── ... (60+ more)
│ ├── 📄 app-sidebar.tsx # Main app navigation
│ ├── 📄 contribution-graph.tsx # GitHub contribution visualization
│ └── ... (more components)
│
├── 📁 lib/ # Utilities & business logic
│ ├── 📁 auth/
│ │ ├── 📄 auth.ts # better-auth configuration
│ │ ├── 📄 auth-utils.ts # Session & route helpers
│ │ └── 📄 auth-client.ts # Client-side auth functions
│ ├── 📁 actions/
│ │ ├── 📄 dashboard.ts # Dashboard data fetching
│ │ ├── 📄 reviews.ts # AI review logic
│ │ └── ... (more server actions)
│ ├── 📁 db/
│ │ └── 📄 client.ts # Prisma client instance
│ └── ... (utilities, helpers)
│
├── 📁 prisma/ # Database schema
│ ├── 📄 schema.prisma # Data models
│ └── 📁 migrations/ # Database migrations
│
├── 📁 inngest/ # Background job functions
│ └── 📄 functions.ts # Inngest job definitions
│
├── 📁 public/ # Static assets
│ └── 📄 favicon.ico
│
├── 📄 package.json # Dependencies & scripts
├── 📄 tsconfig.json # TypeScript configuration
├── 📄 next.config.ts # Next.js configuration
├── 📄 tailwind.config.js # Tailwind CSS configuration
├── 📄 .env # Environment variables
├── 📄 .env.example # Env template
└── 📄 README.md # This file
┌─────────────────────────────────────────────────────────────────┐
│ GitHub Platform │
│ ┌────────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ User Repos │ │ Pull Requests │ │ Webhooks API │ │
│ └────────────────┘ └──────────────┘ └─────────────────┘ │
└────────┬──────────────────────────────────────┬─────────────────┘
│ │
│ │
┌────────▼──────────────────────────────────────▼─────────────────┐
│ CodeHawk Application │
│ (Next.js 16.2.2 + Turbopack) │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Frontend (React 19) │ │
│ │ ┌────────────────┐ ┌──────────────┐ ┌────────────┐ │ │
│ │ │ Dashboard │ │ Settings │ │ Reviews │ │ │
│ │ │ (Analytics) │ │ (Preferences)│ │ (History) │ │ │
│ │ └────────────────┘ └──────────────┘ └────────────┘ │ │
│ │ ▲ ▲ │ │
│ │ │ TanStack Query (State) │ │ │
│ │ │ next-themes (Styling) │ │ │
│ │ │ Vercel Analytics │ │ │
│ └───────┼──────────────────────────────────────┼───────────┘ │
│ │ │ │
│ ┌───────▼──────────────────────────────────────▼───────────┐ │
│ │ Next.js API Routes & Server Actions │ │
│ │ ┌─────────────┐ ┌──────────┐ ┌────────────────┐ │ │
│ │ │ Auth API │ │Webhook │ │ Inngest Queue │ │ │
│ │ │ (better-auth) │Handler │ │Handler │ │ │
│ │ └─────────────┘ └──────────┘ └────────────────┘ │ │
│ └──────────┬────────────────────────────────┬────────────┘ │
│ │ │ │
└─────────────┼────────────────────────────────┼─────────────────┘
│ │
┌─────────▼─────────────┐ ┌──────────▼──────────┐
│ PostgreSQL Database │ │ Google Gemini API │
│ (Prisma ORM) │ │ (AI Code Analysis) │
│ │ │ │
│ • Users │ │ • PR Analysis │
│ • Repositories │ │ • Code Review │
│ • Reviews │ │ • Quality Metrics │
│ • Webhooks │ │ │
│ • Subscriptions │ │ │
└───────────────────────┘ └─────────────────────┘
│ │
└──────────────┬───────────────┘
│
┌────────▼──────────┐
│ Inngest Server │
│ (Background Jobs)│
│ │
│ • PR Processing │
│ • AI Review Gen │
│ • Data Sync │
│ • Event Handler │
└───────────────────┘
GitHub PR Event
│
▼
┌──────────────────────────┐
│ Webhook Receiver API │
│ (/api/webhooks/github) │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Event Validation │
│ & Auth Check │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Store in Database │
│ (Prisma) │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Trigger Inngest Job │
│ (Background Queue) │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Fetch PR Changes │
│ from GitHub API │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Send to Google Gemini │
│ (AI Analysis) │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Process AI Response │
│ (Analyze & Format) │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Post PR Comments │
│ via GitHub API │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Save Review Record │
│ to Database │
└────────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ Update Dashboard │
│ Analytics (via Query) │
└──────────────────────────┘
User
│
▼
┌─────────────────┐
│ Login Page │
│ (GitHub OAuth) │
└────────┬────────┘
│
▼
┌─────────────────────────┐
│ GitHub OAuth Provider │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ better-auth Handler │
│ (/api/auth/[...all]) │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ Create/Update Session │
│ (Database) │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ Set Auth Cookie │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ Redirect to Dashboard │
│ (Protected Route) │
└────────┬────────────────┘
│
▼
┌─────────────────────────┐
│ protectedRoute() │
│ Validates Session │
└────────┬────────────────┘
│
Yes ▼ No
✓ ▼
Redirect to /login
- Node.js 18+ (recommended: 20+)
- npm or pnpm
- PostgreSQL 12+
- Git
- A GitHub Account (for OAuth setup)
- Google AI API Key (Gemini)
- Polar.sh account (for payments)
-
Clone the repository
git clone https://github.com/surajit20107/code-hawk.git cd code-hawk -
Install dependencies
npm install # or pnpm install -
Set up environment variables
cp .env.example .env
Fill in the required variables:
# Database DATABASE_URL="postgresql://user:password@localhost:5432/codehawk" # GitHub OAuth GITHUB_CLIENT_ID=your_github_app_id GITHUB_CLIENT_SECRET=your_github_app_secret GITHUB_APP_WEBHOOK_SECRET=your_webhook_secret # Google AI GOOGLE_GENERATIVE_AI_API_KEY=your_gemini_api_key # Pinecone (Vector DB) PINECONE_API_KEY=your_pinecone_key PINECONE_INDEX_NAME=your_index_name # Polar.sh (Payments) POLAR_API_KEY=your_polar_key # Auth Secret BETTER_AUTH_SECRET=your_random_secret_key # Inngest INNGEST_EVENT_KEY=your_inngest_key
-
Set up the database
npx prisma migrate dev --name init npx prisma db seed # Optional: seed test data -
Start the development server
npm run dev
The app will be available at
http://localhost:5000
# Start development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run linter
npm run lint
# Start Inngest dev server (background jobs)
npm run inngest
# Run both Inngest and dev server
npm run server// Server Component (default)
// Can access database, secrets, file system
export default async function Dashboard() {
const data = await db.user.findUnique(...)
return <div>{data}</div>
}
// Client Component (with "use client")
"use client"
// Can use hooks, state, event handlers
export function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}// lib/actions/reviews.ts
"use server"
export async function submitReview(formData: FormData) {
// Runs on the server
const review = await db.review.create({...})
revalidatePath('/dashboard/reviews')
return review
}// dashboard/page.tsx
import { protectedRoute } from "@/lib/auth/auth-utils"
export default async function DashboardPage() {
const session = await protectedRoute() // Redirects if not authenticated
return <div>Welcome {session.user.name}</div>
}"use client"
import { useQuery } from "@tanstack/react-query"
export function ReviewsList() {
const { data, isLoading } = useQuery({
queryKey: ["reviews"],
queryFn: async () => await fetch("/api/reviews").then(r => r.json())
})
if (isLoading) return <Spinner />
return <div>{data.map(r => <ReviewCard key={r.id} review={r} />)}</div>
}// prisma/schema.prisma
model User {
id String @id @default(cuid())
email String @unique
name String?
repositories Repository[]
reviews Review[]
createdAt DateTime @default(now())
}
model Repository {
id String @id @default(cuid())
owner String
name String
userId String
user User @relation(fields: [userId], references: [id])
pullRequests PullRequest[]
}
model Review {
id String @id @default(cuid())
pullRequestId String
content String
status String // pending, completed, failed
userId String
user User @relation(fields: [userId], references: [id])
createdAt DateTime @default(now())
}components/ → Reusable UI components
├── ui/ → shadcn/ui base components
├── providers/ → Context & provider components
└── [feature]/ → Feature-specific components
lib/ → Business logic & utilities
├── auth/ → Authentication
├── actions/ → Server actions
├── db/ → Database utilities
└── utils/ → Helper functions
app/ → Next.js App Router
├── api/ → API routes
├── (auth)/ → Route groups for auth pages
└── dashboard/ → Protected app pages
1. USER ONBOARDING
├─ User visits codehawk.vercel.app
├─ Clicks "Sign in with GitHub"
├─ Redirects to GitHub OAuth
├─ GitHub redirects back with auth code
├─ better-auth validates & creates session
├─ User stored in PostgreSQL database
└─ Redirect to /dashboard
2. SETUP & CONFIGURATION
├─ User connects GitHub repositories
├─ Repositories saved to database
├─ GitHub webhooks registered
├─ User selects subscription plan
├─ Payment processed via Polar.sh
└─ Review credits allocated
3. PULL REQUEST REVIEW PROCESS
├─ PR created on user's GitHub repo
├─ GitHub sends webhook event
├─ CodeHawk webhook handler receives event
├─ Event queued in Inngest (background)
├─ Job fetches full PR details from GitHub
├─ Code diff sent to Google Gemini AI
├─ AI generates review comments
├─ CodeHawk posts comments to GitHub
├─ Review record saved to database
└─ Dashboard updated with new review
4. ANALYTICS & INSIGHTS
├─ User views dashboard
├─ Frontend fetches stats via server actions
├─ Database queries run (optimized)
├─ GitHub API called for fresh data (periodic)
├─ Charts & graphs rendered with Recharts
├─ Contribution graph shows activity
└─ Real-time updates via TanStack Query
POST /api/auth/sign-up # Register new user
POST /api/auth/sign-in # Sign in with credentials
POST /api/auth/callback/github # GitHub OAuth callback
POST /api/auth/sign-out # Sign out user
GET /api/auth/session # Get current session
POST /api/webhooks/github # GitHub webhook receiver
GET /api/reviews # List all reviews
GET /api/reviews/:id # Get review details
POST /api/reviews # Create new review
DELETE /api/reviews/:id # Delete review
GET /api/user # Get current user profile
PUT /api/user # Update user profile
GET /api/user/subscriptions # Get subscription info
GET /api/repositories # List connected repos
POST /api/repositories # Connect new repo
DELETE /api/repositories/:id # Disconnect repo
POST /api/inngest # Inngest job events
We welcome contributions! Please follow these guidelines:
-
Create a feature branch
git checkout -b feature/amazing-feature
-
Make your changes
- Follow the existing code style
- Update tests if applicable
- Add comments for complex logic
-
Test locally
npm run dev npm run lint
-
Push and create a Pull Request
git push origin feature/amazing-feature
- Use TypeScript for all new code
- Follow ESLint rules (run
npm run lint) - Use meaningful variable names
- Add JSDoc comments for functions
- Keep components focused and reusable
- Write server actions for sensitive operations
// components/ReviewCard.tsx
'use client'
import { Review } from '@prisma/client'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
interface ReviewCardProps {
review: Review
onDelete?: (id: string) => void
}
/**
* Displays a single review with AI insights
* @param review - The review object
* @param onDelete - Optional callback when user deletes review
*/
export function ReviewCard({ review, onDelete }: ReviewCardProps) {
return (
<Card>
<CardHeader>
<CardTitle>{review.title}</CardTitle>
</CardHeader>
<CardContent>
{/* Component content */}
</CardContent>
</Card>
)
}Error: ECONNREFUSED 127.0.0.1:5432
Solution:
1. Ensure PostgreSQL is running
2. Check DATABASE_URL is correct
3. Run: npm run db:push
Error: Invalid client_id
Solution:
1. Verify GitHub App credentials in .env
2. Check OAuth redirect URI matches
3. Ensure GitHub App has correct permissions
Error: Job queued but not executing
Solution:
1. Start Inngest dev server: npm run inngest
2. Check job is properly defined
3. Verify environment variables are set
Error: Gemini API returns error
Solution:
1. Validate GOOGLE_GENERATIVE_AI_API_KEY
2. Check PR file size isn't too large
3. Verify API quota isn't exceeded
Error: non-standard NODE_ENV value
Solution:
npm run build # Automatically sets NODE_ENV=production
- Use TanStack Query for efficient data fetching
- Enable Database indexing on frequently queried fields
- Implement pagination for large datasets
- Cache static pages when possible
- Use incremental static regeneration for dashboards
Enable verbose logging:
DEBUG=codehawk:*
LOG_LEVEL=debug- Built with ❤️ using Next.js, React, and TypeScript
- UI Components by shadcn/ui
- AI powered by Google Gemini
- Background jobs by Inngest
- Subscriptions by Polar.sh
Happy coding! 🚀
Last Updated: April 2025