Files
DiunDashboard/.claude/CLAUDE.md
Jean-Luc Makiola c0746a7f02
All checks were successful
CI / build-test (push) Successful in 1m28s
**feat(webhook):** add WEBHOOK_SECRET for token authentication support
- Protect `/webhook` endpoint using the `Authorization` header
- Update `README.md` with setup instructions and examples for authentication
- Warn when `WEBHOOK_SECRET` is not configured
- Add tests for valid, missing, and invalid token scenarios
- Update `docker-compose.yml` to support `WEBHOOK_SECRET` configuration
2026-02-27 14:58:43 +01:00

3.4 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
docker compose 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/

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, and Tag structs; SQLite-backed storage (guarded by sync.Mutex); HTTP handlers (WebhookHandler, UpdatesHandler, DismissHandler, TagsHandler, TagByIDHandler, TagAssignmentHandler)
  • cmd/diunwebhook/main.go — calls InitDB(), wires handlers onto net/http's default mux, serves ./frontend/dist at /, listens on :8080 (overridable via PORT env var), graceful shutdown
  • pkg/diunwebhook/diunwebhook_test.go — external test package (package diunwebhook_test); uses httptest for handler tests
  • pkg/diunwebhook/export_test.go — test-only exports
  • frontend/ — React SPA (Bun + Vite + React 19 + Tailwind CSS + shadcn/ui + dnd-kit)

Database schema (SQLite):

  • updates — one row per image (PRIMARY KEY image), stores full event fields plus received_at and acknowledged_at
  • tags — user-defined tag/group names (id INTEGER PK, name UNIQUE)
  • tag_assignments — maps imagetag_id (FK with CASCADE delete)

API routes:

  • POST /webhook — accept a DIUN event
  • GET /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 tags
  • POST /api/tags — create a tag
  • DELETE /api/tags/{id} — delete a tag (cascades to assignments)
  • PUT /api/tag-assignments — assign an image to a tag
  • DELETE /api/tag-assignments — unassign an image from its tag

Environment variables:

  • PORT — listen port (default 8080)
  • WEBHOOK_SECRET — when set, every POST /webhook must include a matching Authorization header; when unset, the webhook is open (a warning is logged at startup)

Key data flow:

  1. DIUN POSTs JSON to /webhookWebhookHandler decodes into DiunEvent → upserted into updates table (latest event per image wins, resets acknowledged state)
  2. React SPA polls GET /api/updates every 5 s → UpdatesHandler returns map of UpdateEntry (includes event, received time, acknowledged flag, and optional tag)
  3. 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().