Project Deep Dive

ShipWatch Live

ShipWatch Live is a full-stack developer tool that connects to your GitHub account via a GitHub App and receives webhook events from your repositories. It surfaces push activity, flags suspicious commits (bug fixes, large pushes, hotfixes), and gives you a live feed of what's happening across all your repos in one place.

Next.jsTypeScriptSupabaseTailwind CSSGitHub APIn8nClaude API

Shipwatch Intro — What It Is & Why It Exists

Shipwatch Tutorial — Setup, Dashboard & AI Review Pipeline

Shipwatch History — Architecture Decisions & How It Was Built

The Problem

When you're working across multiple active repositories, it's easy to lose the thread. A hotfix lands on main at midnight, a large batch of commits from a collaborator changes something you rely on, or a repo quietly goes stale. Email notifications drown in noise. Checking each repo individually doesn't scale. There was no tool that gave me one opinionated view of what actually mattered across my entire GitHub account.

What ShipWatch Live Does

ShipWatch Live is a real-time monitoring dashboard that installs as a GitHub App, receives signed webhook events from every connected repository, and surfaces the activity that deserves attention. The distinguishing feature is the AI review pipeline: any commit in the feed can be sent to Claude for a full code review, and any problem Claude identifies can be fixed with a single button click that commits the corrected code directly back to the repository.

Key Features

  • GitHub App installation — connects via the GitHub App flow (not plain OAuth), granting per-installation tokens scoped to specific repositories
  • HMAC-SHA256 webhook verification — every incoming payload is verified against GitHub's signature before processing, unauthenticated requests are rejected immediately
  • Real-time activity feed — push events, branch activity, commit authors, and timestamps rendered as they arrive
  • Smart alerting — automatic flags for bug-fix keywords (fix, bug, hotfix, patch, crash, broken), large pushes (10+ commits), direct pushes to main or master, and inactivity when a repo goes silent for 7+ days
  • AI commit review — the Review button on any commit fetches the full diff plus up to 15 of the most-changed source files, sends them to an n8n workflow connected to Claude, and renders a structured analysis in a modal (summary, issues, severity, suggestions)
  • One-click auto-fix — the Fix button on any AI-identified issue fetches the current file and its SHA, sends it to a separate n8n AI fix workflow, receives corrected file content, and commits it back via the GitHub Contents API — all without leaving the dashboard
  • Architecture

    The full pipeline from installation to auto-fix:

    GitHub App Install → OAuth Callback → Supabase upsert → webhook registration → HMAC-verified event → database write → server-rendered dashboard → AI review → one-click commit

    GitHub App Authentication

    ShipWatch Live authenticates as a GitHub App using RS256-signed JWTs, not a user OAuth token. On installation, the callback route receives the installation ID, generates an installation access token scoped to that install, and upserts a record in the `github_installations` table in Supabase. All subsequent API calls on behalf of a repository use that installation token rather than user credentials.

    Webhook Pipeline

    GitHub delivers signed `push`, `installation`, `installation_repositories`, and `ping` events to `/api/github/webhook`. The handler computes the expected HMAC-SHA256 digest using the shared webhook secret and rejects any payload where the signature does not match. Verified push payloads are written to the `webhook_events` table with the installation ID, event type, repository name, branch, commit count, and the full payload stored as `jsonb` for flexible querying.

    AI Review — `/api/review-commit`

    When the Review button fires, the route handler:

    1. Fetches the commit diff from GitHub using the installation token

    2. Parses changed files, sorts them by lines changed (descending), and fetches the full content of up to 15 files

    3. Sends the diff and file contents to an n8n webhook endpoint

    4. n8n passes the payload to Claude with a structured review prompt

    5. The response is normalized across multiple possible envelope shapes and returned as a typed analysis object

    The modal renders the result as a collapsible review with severity indicators and per-issue suggestions.

    One-Click Auto-Fix — `/api/apply-fix`

    When a Fix button fires on a specific suggestion:

    1. Fetches the current file content and its blob SHA from GitHub

    2. Sends the file content, the suggested fix description, and context to a separate n8n AI fix workflow

    3. n8n asks Claude to produce corrected file content

    4. The corrected content is base64-encoded and committed back via a PUT to the GitHub Contents API using the blob SHA as the update guard

    5. The dashboard reflects the fix without a page reload

    Middleware — `proxy.ts`

    A Next.js middleware layer runs on every request. It refreshes the Supabase session cookie from the request headers, protects all `/dashboard` routes by redirecting unauthenticated users to the login page, and explicitly allows `/api/github/webhook` through without an auth check — since GitHub's webhook delivery cannot carry a session cookie.

    Database Schema

    Two Supabase tables underpin the app:

  • `webhook_events` — `installation_id`, `event_type`, `repository`, `branch`, `commit_count`, `payload` (jsonb), `created_at`
  • `github_installations` — `user_id`, `installation_id`, `account_login`, `account_avatar_url`, `repositories` (jsonb), `updated_at`
  • Row Level Security is enabled on both tables so users only see data tied to their own GitHub App installation.

    Dashboard

    The dashboard page is a Next.js server component. On each request it queries Supabase for recent webhook events and the user's installations, computes alerts inline (no background job), and renders the activity feed and stats bar server-side. No client-side polling. The activity feed component is a client component responsible for the Review/Fix button interactions and AI modal state.

    What I Learned

    The GitHub App authentication model is meaningfully different from plain OAuth and requires more care. JWT generation with RS256, installation token scoping, and the distinction between user-granted access and installation-granted access all took deliberate study. The AI pipeline end-to-end — fetching context, routing through n8n, normalizing Claude's response shape, and committing corrected code back via the Contents API — turned out to be the most architecturally interesting part of the project. It forced me to think carefully about error states at each step: what happens if the diff is too large, if n8n times out, if the blob SHA is stale by the time the fix commit fires.