Grainlify Backend is a Go-based API server that connects open-source developers with projects through GitHub integration, ecosystem tracking, and contribution management.
Grainlify Backend provides:
- GitHub OAuth authentication
- GitHub App integration for repository management
- Project ecosystem organization (Starknet, Ethereum, etc.)
- User profile tracking with contribution statistics
- KYC verification via Didit integration
- Admin endpoints for ecosystem management
- GitHub webhooks for syncing issues and pull requests
- PostgreSQL database with migration support
- Optional NATS event bus for async processing
- Optional Redis for caching
| Component | Technology |
|---|---|
| Language | Go 1.24+ |
| HTTP Framework | Fiber (fasthttp) |
| Database | PostgreSQL with pgx driver |
| Migrations | golang-migrate |
| Event Bus | NATS (optional) |
| Cache | Redis (optional) |
| Authentication | JWT + GitHub OAuth |
| KYC Provider | Didit |
flowchart TB
FE["Frontend"]
API["Backend API<br>Go + Fiber"]
DB[(PostgreSQL)]
GH[GitHub API / Webhooks]
DIDIT[Didit KYC]
FE --> API
GH --> API
DIDIT --> API
API --> DB
Grainlify-Backend/
├── cmd/
│ ├── api/ # Main API server
│ ├── migrate/ # Database migration runner
│ └── worker/ # Background worker (optional)
├── internal/
│ ├── api/ # HTTP handlers and routing
│ ├── auth/ # JWT authentication
│ ├── bus/ # Event bus interface (NATS)
│ ├── config/ # Configuration management
│ ├── db/ # Database connection
│ ├── github/ # GitHub API client
│ ├── handlers/ # HTTP endpoint handlers
│ ├── soroban/ # Stellar blockchain integration
│ └── worker/ # Background job processing
├── migrations/ # SQL migration files
├── .env.example # Environment variables template
├── go.mod # Go dependencies
└── Makefile # Build commands
- GitHub OAuth login/signup flow
- JWT token-based authentication
- Role-based access control (contributor, maintainer, admin)
- GitHub App for repository management
- Webhook handling for issues and pull requests
- Automatic repository verification
- Project syncing with GitHub data
- Register GitHub repositories as projects
- Organize projects by ecosystems (Starknet, Ethereum, etc.)
- Project verification and webhook setup
- Issue and PR tracking
- Contribution statistics
- Activity calendar (heatmap)
- Language and ecosystem breakdowns
- Paginated activity feed
- Didit integration for identity verification
- KYC session management
- Verification status tracking
- Bootstrap first admin user
- Manage user roles
- Create and manage ecosystems
- View system statistics
- Go 1.24+
- PostgreSQL 12+
- (Optional) NATS server
- (Optional) Redis server
# Clone the repository
git clone https://github.com/jagadeesh/grainlify/backend.git
cd Grainlify-Backend
# Install dependencies
go mod download
# Copy environment template
cp .env.example .env
# Edit .env with your configuration
# Set DB_URL, GitHub OAuth credentials, etc.Development with auto-reload (recommended):
./run-dev.sh
# or
make devStandard run:
go run ./cmd/apiBuild binary:
go build -o ./api ./cmd/api
./apigo run ./cmd/migrateMigrations run automatically on startup if AUTO_MIGRATE=true.
Key environment variables (see .env.example):
# Database
DB_URL=postgresql://user:password@localhost/dbname
AUTO_MIGRATE=true
# Authentication
JWT_SECRET=your-secret-key-min-32-chars
ADMIN_BOOTSTRAP_TOKEN=your-bootstrap-token
# GitHub OAuth
GITHUB_OAUTH_CLIENT_ID=your_client_id
GITHUB_OAUTH_CLIENT_SECRET=your_client_secret
GITHUB_OAUTH_REDIRECT_URL=http://localhost:8080/auth/github/callback
GITHUB_LOGIN_SUCCESS_REDIRECT_URL=http://localhost:5173
# GitHub App
GITHUB_APP_ID=123456
GITHUB_APP_SLUG=grainlify
GITHUB_APP_PRIVATE_KEY=<base64-encoded-private-key>
GITHUB_WEBHOOK_SECRET=your-webhook-secret
# URLs
PUBLIC_BASE_URL=http://localhost:8080
FRONTEND_BASE_URL=http://localhost:5173
# Optional Services
NATS_URL=nats://localhost:4222
REDIS_URL=redis://localhost:6379
# KYC (Didit)
DIDIT_API_KEY=your_didit_api_key
DIDIT_WORKFLOW_ID=your_workflow_idSee API Endpoints for the complete REST reference.
Interactive API docs are served at /docs (Swagger UI) and the raw OpenAPI 3.1 spec at /openapi.yaml.
See Railway Deployment for detailed Railway deployment instructions.
- Set environment variables
- Run migrations:
go run ./cmd/migrate - Build binary:
go build -o ./api ./cmd/api - Start server:
./api
Both cmd/api and cmd/worker use a cancelable root context for background
workers. On SIGINT or SIGTERM, the API process first stops accepting HTTP
requests, then cancels the sync worker context, waits for in-flight worker work
within the shutdown deadline, and only then lets deferred DB/NATS cleanup run.
The standalone worker process passes the same root context to the NATS webhook
consumer and sync worker. Canceling that context unsubscribes the consumer and
lets the sync worker finish or safely requeue work before Close() drains NATS
and closes the database pool.
make test
# or directly:
go test -race -short ./...- Standard Go formatting
- No ORM (use pgx directly)
- Minimal external dependencies
- Fast HTTP responses (no blocking calls in request path)
See Troubleshooting Guide for common issues and solutions.
The API exposes two standard observability endpoints:
GET /health— Liveness probe. Always returns 200 with build metadata and uptime. Never reflects dependency state (safe for load-balancer health checks).GET /ready— Readiness probe. Returns 200 only when all configured dependencies (PostgreSQL, NATS) are healthy; returns 503 with a per-dependency breakdown otherwise.
Example /health response:
{
"ok": true,
"service": "grainlify-api",
"version": "1.2.3",
"commit": "abc1234",
"build_time": "2025-06-22T12:00:00Z",
"uptime": "3h12m45s"
}Example /ready response (healthy):
{
"ok": true,
"deps": [
{ "name": "database", "ready": true, "status": "ok" },
{ "name": "nats", "ready": true, "status": "CONNECTED" }
]
}Example /ready response (degraded):
{
"ok": false,
"deps": [
{ "name": "database", "ready": true, "status": "ok" },
{ "name": "nats", "ready": false, "status": "DISCONNECTED" }
]
}Security: Neither endpoint leaks DB URLs, NATS credentials, JWT secrets, or internal hostnames. The health endpoint only returns build-time metadata and uptime.
Build metadata is injected at compile time via -ldflags. Example build command:
go build -ldflags="\
-X main.Version=$(git describe --tags --always 2>/dev/null || echo dev) \
-X main.Commit=$(git rev-parse --short HEAD) \
-X main.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o bin/grainlify-api ./cmd/apiWhen these flags are omitted, the defaults (dev, none, unknown) are used.
Full documentation index: docs/README.md
- Quick Start — Auto-reload development setup
- Development Guide — Dev commands and logging
- GitHub App Setup — GitHub App configuration
- API Endpoints — Complete API reference
[Add your license here]