All checks were successful
CI / build-test (push) Successful in 1m2s
- Add `.gitignore` to exclude `node_modules/`, `.vitepress/cache/`, and `.vitepress/dist/` directories - Include `bun.lock` for dependency management with Bun
4.0 KiB
4.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
# Run all tests with coverage
go test -v -coverprofile=coverage.out -coverpkg=./... ./...
# Run a single test
go test -v -run TestWebhookHandler ./pkg/diunwebhook/
# Run the app locally
go run ./cmd/diunwebhook/
# Build Docker image
docker build -t diun-webhook-dashboard .
# Run with Docker Compose (deploy — pulls from registry)
docker compose up -d
# Run with Docker Compose (dev — builds locally)
docker compose -f compose.dev.yml up -d
# Frontend (from frontend/ directory)
bun install # install deps
bun run dev # dev server on :5173 (proxies /api and /webhook to :8080)
bun run build # production build → frontend/dist/
# Documentation site (from docs/ directory)
bun install # install deps
bun run dev # VitePress dev server on :5174
bun run build # production build → docs/.vitepress/dist/
CI warns (but does not fail) when coverage drops below 80%.
Architecture
The app is a Go HTTP server that receives DIUN webhook events and exposes them via a JSON API and a React SPA dashboard. Events are persisted to a SQLite database (diun.db) using modernc.org/sqlite (pure Go, no CGO).
Package layout:
pkg/diunwebhook/— core library:DiunEvent,UpdateEntry, andTagstructs; SQLite-backed storage (guarded bysync.Mutex); HTTP handlers (WebhookHandler,UpdatesHandler,DismissHandler,TagsHandler,TagByIDHandler,TagAssignmentHandler)cmd/diunwebhook/main.go— callsInitDB(), wires handlers ontonet/http's default mux, serves./frontend/distat/, listens on:8080(overridable viaPORTenv var), graceful shutdownpkg/diunwebhook/diunwebhook_test.go— external test package (package diunwebhook_test); useshttptestfor handler testspkg/diunwebhook/export_test.go— test-only exportsfrontend/— React SPA (Bun + Vite + React 19 + Tailwind CSS + shadcn/ui + dnd-kit)docs/— VitePress documentation siteCONTRIBUTING.md— developer guide (project structure, development setup, testing, CI/CD)
Database schema (SQLite):
updates— one row per image (PRIMARY KEYimage), stores full event fields plusreceived_atandacknowledged_attags— user-defined tag/group names (idINTEGER PK,nameUNIQUE)tag_assignments— mapsimage→tag_id(FK with CASCADE delete)
API routes:
POST /webhook— accept a DIUN eventGET /api/updates— return all events (with tag and acknowledged state)PATCH /api/updates/{image}— mark an event as acknowledged (dismiss)GET /api/tags— list all tagsPOST /api/tags— create a tagDELETE /api/tags/{id}— delete a tag (cascades to assignments)PUT /api/tag-assignments— assign an image to a tagDELETE /api/tag-assignments— unassign an image from its tag
Environment variables:
PORT— listen port (default8080)DB_PATH— path to SQLite database file (default./diun.db); set to e.g./data/diun.dbin Docker to use a separate mountable directoryWEBHOOK_SECRET— when set, everyPOST /webhookmust include a matchingAuthorizationheader; when unset, the webhook is open (a warning is logged at startup)
Key data flow:
- DIUN POSTs JSON to
/webhook→WebhookHandlerdecodes intoDiunEvent→ upserted intoupdatestable (latest event per image wins, resets acknowledged state) - React SPA polls
GET /api/updatesevery 5 s →UpdatesHandlerreturns map ofUpdateEntry(includes event, received time, acknowledged flag, and optional tag) - User can dismiss updates via
PATCH /api/updates/{image}and organize images into tag groups via the tag/assignment endpoints
Test helpers exposed from the library package (not part of the public API, only for tests): GetUpdatesMap(), UpdatesReset(), UpdateEvent(), ResetTags().