The authoritative API server for Reposignal - a platform that helps open-source maintainers classify and manage GitHub issues while enabling contributors to discover good first issues.
- Overview
- Tech Stack
- Quick Start
- API Documentation
- Architecture
- Database
- Development
- Testing
- Contributing
- License
Reposignal Backend is the single source of truth for the Reposignal platform. It provides a RESTful API for:
- 🔐 GitHub OAuth authentication for users and maintainers
- 🤖 Bot integration via secure API key authentication
- 📦 Repository management with granular settings control
- 🏷️ Issue classification (difficulty levels 1-5, types, visibility)
- 🔍 Discovery engine for finding suitable issues with advanced filtering
- 📊 Analytics and statistics for repository health metrics
- 🪵 Immutable audit logging for all state changes
- 📝 Anonymous feedback collection from contributors
- 🎛️ Metadata management for languages, frameworks, and domains
✅ Security-first design - GitHub App validation, no frontend secrets
✅ Type-safe - Full TypeScript with strict mode and Zod validation
✅ OpenAPI documentation - Interactive Swagger UI at /documentation
✅ Audit trail - Immutable logs for every state change
✅ Opt-in philosophy - Maintainer authority and consent required
| Category | Technology |
|---|---|
| Runtime | Bun - Fast JavaScript runtime |
| Language | TypeScript 5.9.3 (strict mode) |
| Web Framework | Hono 4.11.0 - Ultrafast web framework |
| ORM | Drizzle ORM - TypeScript SQL ORM |
| Database | PostgreSQL - Relational database |
| Validation | Zod 4.1.13 - TypeScript-first schema validation |
| Auth | JWT + GitHub OAuth |
- Bun >= 1.0.0 (Install Bun)
- PostgreSQL >= 14
- GitHub App credentials (for OAuth and webhook validation)
# Clone the repository
git clone https://github.com/yourusername/reposignal-backend.git
cd reposignal-backend
# Install dependencies
bun installCreate a .env file with the following required variables:
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/reposignal
# GitHub App Configuration
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
GITHUB_APP_NAME=reposignal
# GitHub OAuth
GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret
OAUTH_REDIRECT_URI=http://localhost:3000/auth/github/callback
# Security
JWT_SECRET=your_jwt_secret_key
BOT_API_KEY=your_bot_api_key
# Setup Configuration
SETUP_WINDOW_MINUTES=30
# Frontend URLs (for CORS)
FRONTEND_URL=http://localhost:9000# Generate migration files
bun run db:generate
# Push schema to database
bun run db:push
# Seed canonical taxonomy (languages, frameworks, domains)
bun run db:seed
# Or do both in one command
bun run db:setupbun run devServer will be running at http://localhost:3000
Visit http://localhost:3000/documentation for the full interactive Swagger UI with:
- ✅ Live request testing
- ✅ Request/response examples
- ✅ Schema definitions
- ✅ Authentication testing
Raw OpenAPI 3.0 spec available at: GET /openapi.json
GET /health- Health checkGET /documentation- Swagger UIGET /openapi.json- OpenAPI specGET /meta/languages- List programming languagesGET /meta/frameworks- List frameworks (grouped by category)GET /meta/domains- List domain categories
GET /auth/github/login- Initiate GitHub OAuth flowGET /auth/github/callback- Handle OAuth callbackGET /auth/me- Get current user infoPOST /auth/logout- Logout and clear session
POST /bot/installations/sync- Sync GitHub App installationPOST /bot/issues/classify- Classify issue attributesDELETE /bot/issues- Delete issuePOST /bot/repositories/add- Add new repositoryPOST /bot/repositories/metadata- Update repository metadataPOST /bot/repositories/:id/settings- Update repository settingsPOST /bot/repositories/domains/add- Add domains to repositoryDELETE /bot/repositories/domains- Remove domain from repositoryPOST /bot/repositories/tags/add- Add tags to repositoryDELETE /bot/repositories/tags- Remove tag from repositoryPOST /bot/feedback- Submit anonymous contributor feedbackPOST /bot/logs- Log bot actions
POST /user/profile- Update user profilePOST /user/repositories/:id/settings- Update repository settingsGET /user/repositories/:id/logs- Get repository audit logs
GET /public/discovery- Discover issues with filtersGET /public/repositories/:id- Get repository detailsGET /public/repositories/:id/issues- List repository issuesGET /public/repositories/:id/stats- Get repository statisticsGET /public/users/:username- Get public user profile
GET /setup/context?installation_id=NUMBER- Get setup contextPOST /setup/complete- Complete repository setup
-
Session Tokens (User routes)
Authorization: Bearer <session_token> -
Bot API Key (Bot routes)
Authorization: Bearer <BOT_API_KEY> -
None (Public & Setup routes)
The backend follows a strict architectural model:
- Single source of truth - All data lives here
- Only database writer - No direct DB access from other services
- Deterministic state machine - Predictable state transitions
- Immutable audit ledger - All changes are logged permanently
- Does NOT talk to GitHub (except OAuth & permission validation)
- Does NOT execute background jobs
- Does NOT clean up comments or issues
- Does NOT infer languages/frameworks (bot does this)
🔐 Opt-in only - Repositories must explicitly enable features
👑 Maintainer authority first - Maintainers control everything
🔓 Public state, private intent - Issue data is public, maintainer decisions are private
🚫 No gamification - No points, badges, or leaderboards
🚫 No free-text feedback - Structured feedback only
🚫 No contributor reputation - Focus on issues, not people
⚖️ Nullable by design - Many fields are intentionally optional
✅ Empty is valid - Empty tables represent valid system states
┌─────────┐ ┌──────────┐ ┌──────────┐
│ Client │─────▶│ Hono │─────▶│ Auth │
│(Bot/Web)│ │ Routing │ │Middleware│
└─────────┘ └──────────┘ └──────────┘
│
┌───────────────────┘
▼
┌──────────┐ ┌──────────┐
│ Business │─────▶│ Drizzle │
│ Logic │ │ ORM │
└──────────┘ └──────────┘
│
▼
┌──────────┐
│PostgreSQL│
└──────────┘
The database uses PostgreSQL with the following main tables:
- installations - GitHub App installations
- repositories - Repository settings and metadata
- issues - Issue classifications (difficulty, type, visibility)
- users - User profiles from GitHub OAuth
- languages - Canonical programming language taxonomy
- frameworks - Canonical framework/library taxonomy
- domains - Canonical domain/category taxonomy
- repository_languages - Language associations with byte counts
- repository_frameworks - Framework associations (inferred or maintainer-set)
- repository_domains - Domain associations
- repository_tags - Custom repository tags
- feedback_events - Anonymous contributor feedback (PRIVATE)
- repository_feedback_aggregates - Aggregated feedback statistics
- logs - Immutable audit trail of all state changes
# Generate new migration files from schema changes
bun run db:generate
# Push schema directly to database (development)
bun run db:push
# Run migration files (production)
bun run db:migrate
# Seed canonical taxonomy data
bun run db:seed
# Full setup (push schema + seed data)
bun run db:setup
# Open Drizzle Studio (database GUI)
bun run db:studioMigrations are managed by Drizzle Kit and stored in src/db/migrations/.
reposignal-backend/
├── src/
│ ├── app.ts # Hono app configuration
│ ├── server.ts # Server entry point
│ ├── config.ts # Environment configuration
│ ├── auth/ # Authentication middleware
│ │ ├── botAuth.ts # Bot API key validation
│ │ ├── userAuth.ts # User session validation
│ │ ├── githubOAuth.ts # GitHub OAuth flow
│ │ ├── githubValidation.ts# GitHub App validation
│ │ └── repoPermission.ts # Repository permission checks
│ ├── db/
│ │ ├── client.ts # Database connection
│ │ ├── seedCanonical.ts # Taxonomy seed data
│ │ └── schema/ # Drizzle schema definitions
│ ├── modules/ # Business logic modules
│ │ ├── discovery/ # Issue discovery
│ │ ├── feedback/ # Feedback submission
│ │ ├── installations/ # Installation sync
│ │ ├── issues/ # Issue management
│ │ ├── logs/ # Audit logging
│ │ ├── meta/ # Taxonomy listing
│ │ ├── profiles/ # User profiles
│ │ ├── repositories/ # Repository management
│ │ └── stats/ # Statistics
│ ├── routes/ # Route handlers
│ │ ├── auth.ts # Auth routes
│ │ ├── bot.ts # Bot routes
│ │ ├── meta.ts # Meta routes
│ │ ├── public.ts # Public routes
│ │ ├── setup.ts # Setup routes
│ │ └── user.ts # User routes
│ └── utils/ # Utilities
│ ├── assert.ts # Type assertions
│ ├── enums.ts # Shared enums
│ ├── errorHandler.ts # Global error handler
│ ├── errors.ts # Custom error types
│ ├── logger.ts # Logging utilities
│ ├── normalization.ts # Data normalization
│ ├── openapi.ts # OpenAPI spec generation
│ └── swaggerUI.ts # Swagger UI server
├── docs/ # Documentation
│ ├── API_DOCUMENTATION.md
│ ├── ERROR_HANDLING.md
│ ├── SETUP_GUIDE.md
│ ├── SWAGGER_IMPLEMENTATION.md
│ └── TESTING_GUIDE.md
├── drizzle.config.ts # Drizzle Kit configuration
├── package.json
├── tsconfig.json
└── README.md
- TypeScript strict mode enabled
- ES modules (not CommonJS)
- Functional patterns preferred
- Explicit error handling - No silent failures
- Immutable logs - Never delete or modify log entries
All errors extend custom error classes in src/utils/errors.ts:
ValidationError(400)UnauthorizedError(401)ForbiddenError(403)ResourceNotFoundError(404)ConflictError(409)SetupAlreadyCompletedError(409)SetupWindowExpiredError(410)InstallationInvalidError(403)GitHubUnavailableError(502)
Refer to TESTING_GUIDE.md for comprehensive testing documentation.
- API Documentation - Detailed API reference
- Setup Guide - GitHub App installation flow
- Error Handling - Error handling patterns
- Swagger Implementation - OpenAPI documentation
- Quick Reference - Quick command reference
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
This project adheres to a Code of Conduct. By participating, you are expected to uphold this code.
This project is licensed under the GNU-AGPL 3.0 License - see the LICENSE file for details.
- Website: reposignal.com
- Documentation (Under Development): docs.reposignal.com
- GitHub: github.com/reposignal
Made with ❤️ by the Reposignal team