Automate your GitHub workflow with AI-powered code reviews and issue management
Live Demo β’ API Server β’ Documentation β’ Contributing
- Overview
- Features
- Tech Stack
- Architecture
- Project Structure
- Getting Started
- Environment Variables
- Database Schema
- API Endpoints
- How It Works
- Analytics Dashboard
- Deployment
- Contributing
- Troubleshooting
- License
Axions is a SaaS platform that integrates with GitHub to provide:
- π AI-Powered Code Reviews - Automatically reviews pull requests and provides inline comments with suggestions
- π·οΈ Smart Issue Labeling - Automatically categorizes and labels issues based on content
- π Issue Summarization - Generates concise summaries for new issues
- π Analytics Dashboard - Track your team's productivity and code quality metrics
- Code Review Bottleneck: Senior developers spend hours reviewing PRs manually
- Inconsistent Issue Triage: Issues sit unlabeled, making prioritization hard
- Lack of Visibility: No insights into review patterns and team productivity
Axions acts as an AI teammate that:
- Reviews every PR instantly with consistent quality
- Labels and summarizes issues automatically
- Provides actionable analytics to improve your workflow
- Inline Comments: Line-by-line feedback on code changes
- PR Summary: Comprehensive review with overall assessment
- Smart Detection: Identifies bugs, security issues, and code smells
- Instant Feedback: Reviews posted within seconds of PR creation
- Auto-Labeling: Categorizes issues (bug, feature, priority, etc.)
- Color-Coded Labels: Consistent label colors across repos
- AI Summaries: Concise issue summaries posted as comments
- Review Metrics: PRs reviewed, comments posted, files analyzed
- Issue Metrics: Issues triaged, labels applied
- Time Series: Activity trends over time
- Repo Comparison: Compare performance across repositories
- Error Tracking: Monitor and debug failures
- GitHub OAuth: Secure authentication via GitHub
- Webhook Signatures: HMAC-SHA256 verification for all webhooks
- Token Encryption: Secure storage of access tokens
| Technology | Purpose |
|---|---|
| React 19 | UI framework |
| Vite | Build tool & dev server |
| Tailwind CSS | Styling |
| React Router | Navigation |
| Lucide Icons | UI icons |
| Technology | Purpose |
|---|---|
| Node.js | Runtime |
| Express | Web framework |
| MongoDB | Database |
| Mongoose | ODM |
| Passport.js | GitHub OAuth |
| esbuild | Server bundle |
| Service | Purpose |
|---|---|
| GitHub API | Repository operations |
| Gemini (Google Generative AI) | LLM for code analysis |
| Vercel | Deployment |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AXIONS ARCHITECTURE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββββββ
β GitHub ββββββΆβ Webhooks ββββββΆβ Express Server β
β (PR/Issue) β β Handler β β β
ββββββββββββββββ ββββββββββββββββ β ββββββββββββββββββ β
β β Review Service β β
ββββββββββββββββ β βββββββββ¬βββββββββ β
β React βββββββββββββββββββββββββββΆβ β β
β Frontend β REST API β βββββββββΌβββββββββ β
ββββββββββββββββ β β LLM Service β β
β β (Gemini) β β
ββββββββββββββββ β βββββββββ¬βββββββββ β
β MongoDB ββββββββββββββββββββββββββββ β β
β Database β β βββββββββΌβββββββββ β
ββββββββββββββββ β β GitHub Service β β
β ββββββββββββββββββ β
ββββββββββββββββββββββββ
1. PR/Issue Created on GitHub
β
βΌ
2. GitHub sends Webhook to /api/webhooks/github
β
βΌ
3. Verify signature & find connected repo
β
βΌ
4. Route to appropriate handler:
βββ PR β orchestrateReview()
βββ Issue β orchestrateIssueLabeling()
β
βΌ
5. Fetch diff/content from GitHub API
β
βΌ
6. Send to LLM for analysis
β
βΌ
7. Post results back to GitHub
β
βΌ
8. Record stats (locked, immutable)
β
βΌ
9. Dashboard reads from rebuildRepoStats()
Axions/
βββ client/ # React frontend
β βββ src/
β β βββ components/ # Reusable UI components
β β β βββ Logo.jsx
β β β βββ MetricCard.jsx
β β β βββ Navbar.jsx
β β β βββ Sidebar.jsx
β β β βββ StatCard.jsx
β β βββ hooks/ # Custom React hooks
β β β βββ useAnalyticsData.js
β β βββ lib/ # Utilities
β β β βββ api.js # API client
β β βββ pages/ # Route pages
β β β βββ DashboardPage.jsx
β β β βββ RepositoriesPage.jsx
β β β βββ AnalyticsPage.jsx
β β β βββ DeepAnalysisPage.jsx
β β β βββ ErrorTrackingPage.jsx
β β β βββ ...
β β βββ services/ # API service layer
β β β βββ analyticsService.js
β β βββ App.jsx # Root component
β β βββ main.jsx # Entry point
β βββ package.json
β βββ vite.config.js
β
βββ server/ # Express backend
β βββ api/
β β βββ index.js # Vercel serverless entry
β βββ config/
β β βββ passport.js # GitHub OAuth config
β βββ controllers/
β β βββ analyticsController.js
β β βββ authController.js
β β βββ repoController.js
β β βββ webhookController.js
β βββ lib/
β β βββ mongoose.js # DB connection helper
β βββ middleware/
β β βββ auth.js # JWT verification
β βββ models/ # MongoDB schemas
β β βββ ConnectedRepo.js
β β βββ ErrorLog.js
β β βββ IssueTriage.js
β β βββ PullRequestReview.js
β β βββ RepoStats.js
β β βββ User.js
β βββ routes/
β β βββ analytics.js
β β βββ auth.js
β β βββ github.js
β β βββ repos.js
β β βββ test.js
β β βββ webhooks.js
β βββ services/ # Business logic
β β βββ githubService.js # GitHub API wrapper
β β βββ llmService.js # AI analysis
β β βββ reviewService.js # PR review orchestration
β β βββ statsService.js # Analytics & stats
β βββ app.js # Express app setup
β βββ server.js # Server entry point
β βββ package.json
β
βββ README.md # This file
- Node.js 18+
- MongoDB (local or Atlas)
- GitHub OAuth App (for authentication)
- Gemini API Key (for AI analysis)
git clone https://github.com/yourusername/axions.git
cd axions# Install server dependencies
cd server
npm install
# Install client dependencies
cd ../client
npm installCreate .env files in both server/ and client/ directories.
Server .env:
# Database
MONGO_URI=mongodb://localhost:27017/axions
# GitHub OAuth
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GITHUB_CALLBACK_URL=http://localhost:5000/api/auth/github/callback
# GitHub Webhooks
GITHUB_WEBHOOK_URL=https://your-server-domain/api/webhooks/github
# JWT
JWT_SECRET=your_super_secret_jwt_key
JWT_EXPIRY=7d
# LLM Provider
GEMINI_API_KEY=your_gemini_api_key
GEMINI_MODEL=gemini-2.5-flash-lite
# Feature Flags
FEATURE_ISSUE_LABELING=true
FEATURE_ISSUE_SUMMARIZATION=true
ENABLE_AUTO_LABELS=true
ENABLE_AUTO_SUMMARY=true
# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:5173
CORS_CREDENTIALS=trueClient .env:
VITE_API_BASE_URL=http://localhost:5000- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in:
- Application name: Axions (Development)
- Homepage URL:
http://localhost:5173 - Authorization callback URL:
http://localhost:5000/api/auth/github/callback
- Copy Client ID and Client Secret to your
.env
# Terminal 1: Start backend
cd server
npm run dev
# Terminal 2: Start frontend
cd client
npm run devOpen http://localhost:5173 in your browser.
| Variable | Required | Description |
|---|---|---|
MONGO_URI |
β | MongoDB connection string |
GITHUB_CLIENT_ID |
β | GitHub OAuth App Client ID |
GITHUB_CLIENT_SECRET |
β | GitHub OAuth App Client Secret |
GITHUB_CALLBACK_URL |
β | OAuth callback URL |
GITHUB_WEBHOOK_URL |
β | Webhook delivery URL |
JWT_SECRET |
β | Secret for signing JWTs |
JWT_EXPIRY |
β | JWT expiry (default 7d) |
GEMINI_API_KEY |
β | Gemini API key |
GEMINI_MODEL |
β | Gemini model name |
FEATURE_ISSUE_LABELING |
β | Enable auto-labeling (true/false) |
FEATURE_ISSUE_SUMMARIZATION |
β | Enable auto-summarization (true/false) |
ENABLE_AUTO_LABELS |
β | Alternative flag for labeling |
ENABLE_AUTO_SUMMARY |
β | Alternative flag for summarization |
FRONTEND_URL |
β | Frontend URL for CORS |
CORS_CREDENTIALS |
β | Enable credentials for CORS |
SHOW_DETAILED_ERRORS |
β | Include stack traces in errors |
PORT |
β | Server port |
| Variable | Required | Description |
|---|---|---|
VITE_API_BASE_URL |
β | Backend API URL |
{
githubId: String, // GitHub user ID
username: String, // GitHub username
email: String, // Email address
avatar: String, // Profile picture
accessToken: String, // GitHub OAuth token
createdAt: Date,
updatedAt: Date
}{
userId: ObjectId, // Reference to User
githubRepoId: Number, // GitHub repository ID
name: String, // Repository name
fullName: String, // owner/repo
owner: String, // Repository owner
isPrivate: Boolean,
isConnected: Boolean, // Active connection status
webhookId: Number, // GitHub webhook ID
webhookSecret: String, // Webhook signature secret
reviewCount: Number, // Total reviews (legacy)
lastReviewedAt: Date,
createdAt: Date
}{
owner: String,
repo: String,
githubRepoId: Number,
pull_number: Number,
commit_id: String, // SHA of reviewed commit
userId: ObjectId,
repoId: ObjectId,
filesAnalyzed: Number,
commentsPosted: Number, // LOCKED on first insert
confidence: String,
analysis: Mixed, // Full LLM response
analyzedAt: Date
}
// Unique index: (githubRepoId, pull_number, commit_id){
owner: String,
repo: String,
githubRepoId: Number,
issue_number: Number,
userId: ObjectId,
repoId: ObjectId,
labelsApplied: [String], // LOCKED on first insert
summary: String
}
// Unique index: (githubRepoId, issue_number){
repoId: ObjectId,
githubRepoId: Number,
userId: ObjectId,
totalPRsReviewed: Number,
totalInlineComments: Number, // Total comments (body + inline)
totalIssuesTriaged: Number,
totalLabelsApplied: Number,
totalErrors: Number,
lastActivityAt: Date
}
// Rebuilt from PullRequestReview + IssueTriage records{
owner: String,
repo: String,
githubRepoId: Number,
pull_number: Number,
userId: ObjectId,
error: String,
errorStack: String,
createdAt: Date
}| Method | Endpoint | Description |
|---|---|---|
GET |
/api/auth/github |
Initiate GitHub OAuth |
GET |
/api/auth/github/callback |
OAuth callback handler |
GET |
/api/test/me |
Get current user (JWT) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/github/repos |
List user's GitHub repos |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/repos/connected |
List connected repos |
POST |
/api/repos/connect |
Connect a repository |
DELETE |
/api/repos/:repoId/disconnect |
Disconnect a repository |
| Method | Endpoint | Description |
|---|---|---|
POST |
/webhooks/github |
GitHub webhook receiver (local) |
POST |
/api/webhooks/github |
GitHub webhook receiver (serverless) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/analytics/summary |
User-wide stats summary |
GET |
/api/analytics/activity/recent |
Recent activity feed |
GET |
/api/analytics/timeseries |
Review activity over time |
GET |
/api/analytics/repos/comparison |
Compare repo performance |
GET |
/api/analytics/repo/:repoId/density |
Comment density analysis |
GET |
/api/analytics/repo/:repoId/confidence |
Confidence distribution |
GET |
/api/analytics/errors/trends |
Error rate trends (paged, 10 per page) |
GET |
/api/analytics/repo/:repoId/issues |
Issue triage analysis |
1. Developer creates/updates a PR
β
βΌ
2. GitHub sends webhook (pull_request.opened/synchronize)
β
βΌ
3. webhookController.js receives & verifies signature
β
βΌ
4. reviewService.orchestrateReview() is called
β
βββ 4a. githubService.fetchDiff() - Get PR diff
β
βββ 4b. llmService.analyzeDiff() - AI analysis
β βββ Returns: { inlineComments, filesAnalyzed, confidence }
β
βββ 4c. llmService.generatePRTextSummary() - Create review body
β
βββ 4d. githubService.postReview() - Post to GitHub
β
βββ 4e. statsService.recordReview() - Save to DB (locked)
βββ commentsPosted = 1 (body) + N (inline)
1. User creates a new issue
β
βΌ
2. GitHub sends webhook (issues.opened)
β
βΌ
3. webhookController.orchestrateIssueLabeling()
β
βββ 3a. llmService.generateIssueLabels() - Get labels
β
βββ 3b. githubService.applyColoredLabels() - Apply to issue
β
βββ 3c. llmService.generateIssueSummary() - Create summary
β
βββ 3d. githubService.postIssueSummaryComment() - Post comment
β
βββ 3e. statsService.recordIssueTriage() - Save to DB (locked)
| Page | Description |
|---|---|
| Dashboard | Overview with key metrics and recent activity |
| Repositories | Manage connected repositories |
| Analytics | Detailed charts and time-series data |
| Deep Analysis | Comment density, confidence distribution |
| Error Tracking | Monitor failures and error rates |
| Profile | User settings and account info |
- PRs Reviewed: Total pull requests analyzed
- Comments Posted: Review body + inline comments
- Issues Triaged: Issues with labels/summaries applied
- Labels Applied: Unique labels per issue
- Error Rate: Failed reviews / total attempts
- Avg Comments/PR: Code quality indicator
Both client and server are configured for Vercel deployment.
Server (server/vercel.json):
{
"version": 2,
"builds": [
{ "src": "api/index.js", "use": "@vercel/node" }
],
"routes": [
{ "src": "/(.*)", "dest": "api/index.js" }
]
}Client (client/vercel.json):
{
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}- Push to GitHub
- Import to Vercel (both client and server as separate projects)
- Set Environment Variables in Vercel dashboard
- Update OAuth Callback URL to production server URL
- Update
FRONTEND_URLto production client URL
- Set all environment variables in Vercel
- Update GitHub OAuth App with production URLs
- Test webhook delivery from GitHub
- Verify CORS configuration
We welcome contributions! Here's how to get started:
- Fork the repository
- Create a feature branch
git checkout -b feature/your-feature-name
- Make your changes
- Run tests (if available)
- Commit with clear messages
git commit -m "feat: add new analytics chart" - Push and create a PR
- Use ESLint for JavaScript linting
- Follow conventional commits for commit messages
| File | What It Does |
|---|---|
server/services/reviewService.js |
Orchestrates the entire PR review flow |
server/services/llmService.js |
All AI/LLM interactions |
server/services/statsService.js |
Analytics and stats aggregation |
server/controllers/webhookController.js |
Handles GitHub webhooks |
client/src/hooks/useAnalyticsData.js |
Frontend data fetching |
- Check webhook secret matches in GitHub and
.env - Verify webhook URL is publicly accessible
- Check GitHub webhook delivery logs
- Run
rebuildRepoStats()to recalculate from source records - Check for duplicate records in database
- Verify unique indexes exist on collections
- Verify callback URL matches exactly (including trailing slashes)
- Check client ID and secret are correct
- Ensure GitHub OAuth App is not suspended
- Verify API key is valid and has credits
- Check rate limits on Gemini
- Review error logs for specific failure messages
# Check MongoDB connection
mongosh $MONGO_URI --eval "db.stats()"
# View webhook logs
curl -H "Authorization: token YOUR_TOKEN" \
https://api.github.com/repos/OWNER/REPO/hooks/HOOK_ID/deliveriesThis project is licensed under the ISC License - see the LICENSE file for details.
- GitHub API for repository integration
- Google Generative AI for Gemini
- Tailwind CSS for styling
Built with β€οΈ by the Axions Team
