Skip to content

Developer architecture overview

Pullminder is a Turborepo pnpm monorepo with five apps:

AppStackPurpose
apiGo, chi routerREST API and webhook handler
dashboardReact, Vite, TanStack Router/Query, Tailwind CSSWeb UI for teams
cliGo, CobraOffline analysis and platform commands
marketingAstroPublic website at pullminder.com
docsAstro StarlightDocumentation site

The API server is a single Go binary built around the chi router. Business logic lives in internal/ packages:

PackageResponsibility
apiHTTP handlers and middleware
authGitHub OAuth, sessions, CSRF
billingSubscription management
configEnvironment and feature flags
cryptoField encryption, HMAC signing
evaluationRule engine, risk scoring
githubGitHub API client, webhook parsing
notifyEmail and Slack notifications
observeLogging, tracing, metrics
queueTask definitions and handlers
registryRule pack fetching and caching
riskRisk model and score calculation
sessionSession store (PostgreSQL-backed)
storeDatabase queries

PostgreSQL is the primary data store. The schema is managed through sequential migrations that run automatically when the API server starts. All queries use the database driver directly — there is no ORM.

Redis powers the task queue. Four task types flow through the queue:

TaskDescription
analyze_prFetch diff, run analyzers, post results
send_notificationDeliver email or Slack message
fetch_coveragePull coverage data from CI provider
baseline_scanFull-repo scan on initial install

The dashboard is a React SPA using TanStack Router for file-based routing and TanStack Query for server state. Styling uses Tailwind CSS. Charts are rendered with Recharts.

The CLI is a standalone Go binary built with Cobra. It runs the same analyzers as the platform but operates entirely offline against local diffs. Platform commands (sync, login) connect to the API.

The API and worker run as Docker containers. The dashboard, marketing site, and docs deploy to Cloudflare Pages with automatic builds from the main branch.

  • Logging — structured JSON via slog
  • Error tracking — Sentry-compatible service
  • Tracing — OpenTelemetry
  • Metrics — Prometheus endpoint (internal, token-authenticated)
  • Field encryption — with rotatable keys for sensitive data at rest
  • Badge signing — cryptographic signing to prevent badge URL tampering
  • CSRF — double-submit cookie pattern
  • Sessions — HttpOnly, Secure, SameSite cookies backed by PostgreSQL
  1. A pull request is opened or updated on GitHub.
  2. GitHub sends a webhook to the API server.
  3. The API validates the webhook signature, persists the event, and enqueues an analyze_pr task.
  4. The worker picks up the task, fetches the diff from GitHub, runs it through the rule engine, calculates a risk score, and stores the results.
  5. The worker posts a comment on the PR and sets a commit status check.
  6. The dashboard queries the API (backed by PostgreSQL) to display results to the team.