Strava for developers — commit streaks, PR throughput, and contribution insights from your GitHub activity.
- Commit streak tracking — daily coding streaks with current/longest streak display and full-year contribution calendar
- GitHub contribution heatmap — visualize your activity intensity across the year at a glance
- PR throughput charts — track pull requests opened and merged over custom date ranges
- Code volume & churn ratio — net lines added/removed and churn ratio to measure effective output
- Language distribution — see which languages you spend the most time in across all tracked repositories
- Activity by hour — identify your peak coding hours from historical commit data
- Dark-first Linear-inspired UI — clean, distraction-free dashboard with violet accents and Spotify Wrapped-style achievement cards for milestone moments
┌──────────────┐ ┌─────────────────────────────┐
│ │ │ NestJS API :17642 │
│ Browser │──────▶ │ (Fastify + GraphQL/REST) │
│ │ │ │
│ Next.js │ │ ┌─────────────────────────┐ │
│ :38929 │ │ │ Bounded Contexts │ │
│ │ │ │ · Identity │ │
│ Apollo │ │ │ · Analytics │ │
│ Client │ │ │ · Notifications │ │
└──────────────┘ │ │ · Billing │ │
│ └─────────────────────────┘ │
│ │ │
└──────────────┼────────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌─────▼──────┐ ┌──────▼─────┐ ┌────────▼───────┐
│ PostgreSQL │ │ Redis │ │ GitHub API │
│ :5432 │ │ :6379 │ │ (Octokit) │
└────────────┘ └────────────┘ └────────────────┘
The API follows hexagonal (ports & adapters) architecture across four bounded contexts: Identity, Analytics, Notifications, and Billing. Domain logic depends only on port interfaces — adapters (Prisma, Redis, Octokit) are injected at the infrastructure layer. The GraphQL API handles all analytics queries; REST endpoints are reserved for GitHub OAuth callbacks and webhooks.
# Prerequisites: Node 22, pnpm 10, Docker
git clone https://github.com/your-username/reflog.git
cd reflog
cp .env.example .env # fill in GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, JWT_SECRET
docker compose up -d # postgres + redis
pnpm install
pnpm --filter api exec prisma migrate deploy
pnpm --filter api seed # optional: load demo data
pnpm dev # web :38929 + api :17642Once running:
- Dashboard: http://localhost:38929
- API (GraphQL Playground): http://localhost:17642/api/graphql
- API (Swagger / REST docs): http://localhost:17642/api/docs
Production environment: https://reflog-dev.duckdns.org
Copy .env.example to .env and fill in the required values.
| Variable | Required | Description |
|---|---|---|
NODE_ENV |
— | development | production |
DATABASE_URL |
yes | PostgreSQL connection string (postgresql://user:pass@host:5432/db) |
REDIS_URL |
yes | Redis connection string (redis://localhost:6379) |
GITHUB_CLIENT_ID |
yes | GitHub OAuth App client ID — create at github.com/settings/developers |
GITHUB_CLIENT_SECRET |
yes | GitHub OAuth App client secret |
GITHUB_CALLBACK_URL |
yes | Must match the callback URL registered in your GitHub OAuth App |
JWT_SECRET |
yes | Long random string used to sign JWTs; change in production |
JWT_EXPIRES_IN |
— | Token TTL, e.g. 7d (default) |
PORT |
— | API server port (default 17642) |
ALLOWED_ORIGINS |
— | CORS allowed origins, comma-separated (e.g. http://localhost:38929) |
NEXT_PUBLIC_API_URL |
yes | Full URL of the API as seen by the browser |
NEXTAUTH_URL |
yes | Canonical URL of the Next.js app |
NEXTAUTH_SECRET |
yes | NextAuth.js secret; change in production |
The API is available at /api/graphql. All queries require a Bearer JWT in the Authorization header (obtained after GitHub OAuth login).
Fetch metrics for a date range
query Metrics($from: DateTime!, $to: DateTime!) {
metrics(input: { from: $from, to: $to }) {
date
commits
additions
deletions
prsOpened
prsMerged
reviewsDone
netLines
churnRatio
}
}Fetch current streak
query Streak {
streak {
currentStreak
longestStreak
lastActiveDate
}
}List tracked repositories
query Repositories {
repositories {
id
fullName
language
isTracked
syncState
lastSyncedAt
}
}reflog/
├── packages/
│ ├── api/ # NestJS 11 + Fastify backend
│ │ ├── src/
│ │ │ ├── main.ts # Bootstrap, Swagger setup
│ │ │ ├── app.module.ts
│ │ │ └── ... # Feature modules (auth, analytics, etc.)
│ │ ├── prisma/
│ │ │ ├── schema.prisma # Data model
│ │ │ └── migrations/
│ │ └── Dockerfile
│ └── web/ # Next.js 15 App Router frontend
│ └── src/
│ ├── app/ # Pages (dashboard, metrics, streaks, repos)
│ └── graphql/ # Apollo Client queries
├── docs/
│ ├── ARCHITECTURE.md # Hexagonal architecture details
│ ├── DOMAIN.md # DDD bounded contexts & domain events
│ └── API.md # GraphQL schema & REST endpoint reference
├── docker-compose.yml # PostgreSQL 16 + Redis 7 + API
├── tsconfig.base.json # Shared TypeScript config (strict)
├── eslint.config.mjs # Shared ESLint flat config
├── .prettierrc # Shared Prettier config
└── .env.example # All required environment variables
# Run all tests
pnpm test
# Lint the entire monorepo
pnpm lint
# Build all packages for production
pnpm buildPer-package commands
pnpm --filter api test # API unit tests (Vitest)
pnpm --filter web test # Frontend tests
pnpm --filter api build # Compile API to dist/
pnpm --filter web build # Next.js production buildMIT