Files
james.maesandClaude Opus 5.5 f33e592aef refactor(signing): use core WebhookSigner and WebhookVerifier
Delete the local shared/signing package (WebhookSigner, WebhookVerifier,
WebhookSecret, WebhookVerificationException) and use core
com.kingsrook.qqq.backend.core.utils.webhooks from QQQ 4.1.0-RC.5.
Delivery signing, inbound verification and secret generation and rotation
all go through core. The wire format is unchanged: same headers, v1,
prefix, whsec_ secrets and timestamp tolerance. Endpoints, secret storage
and delivery stay in this qbit.

Refs QRun-IO/qqq#1160 (this repo has issues disabled), architecture review
QRun-IO/qqq#1150 finding F11.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 19:33:16 -05:00

2.8 KiB

CLAUDE.md

This file provides guidance to Claude Code when working with code in this repository.

Project Overview

QBit Webhooks: signed, SSRF-safe outbound webhooks for QQQ applications. It covers:

  • table, process, ESB and custom events
  • subscriptions with filters, and an outbox with replica-safe claims
  • retries, dead letters, endpoint health, and an app home

Design: docs/DESIGN.md (from QRun-IO/qqq#1105). Inbound webhooks are phase 2 (DESIGN section 10).

Build Commands

./mvnw compile          # always use the wrapper: Maven 3.10 cannot read the parent POM
./mvnw test
./mvnw verify           # tests + Checkstyle + JaCoCo gate (70% instructions, 90% classes)

Architecture

  • Entry point: WebhooksQBitProducer implements QBitMetaDataProducer<WebhooksQBitConfig>. Optional: WebhooksEsbSource.configure(qInstance) for ESB topics.
  • Packages:
    • metadata (tables, enums, validating customizers), registry (event types)
    • events:
      • record and process listeners
      • DeliveryOutbox, SubscriptionMatcher, PayloadBuilder
    • delivery:
      • DeliveryEngine (claim, send, outcome), EndpointHealth
      • WebhooksAlerts (reflective Alerts SPI)
    • secrets (AES-GCM, env references, rotation), processes, app (home, secret widget), permissions, esb, support/SystemWrites.
    • Signing uses core.utils.webhooks directly at the QQQ 4.1.0-RC.5 baseline (QRun-IO/qqq#1160). shared.http remains an internal copy of the safe HTTP client pending a separate migration to core.utils.http (DESIGN section 11).

Invariants

  • A delivery is sent only by the runner whose insert of (deliveryId, attemptNumber) succeeded. Never send without a claim.
  • Payloads are built at queue time and stored; retries resend the same bytes and the same webhook-id.
  • Secrets are never stored, logged, audited, put in process results, or returned in plain text. Only fingerprints.
  • Outbound requests go only through SafeHttpClient (via WebhooksRuntime.httpClient).
  • The qbit's own writes go through SystemWrites (authorized scope; customizers can tell them from people's).
  • No static config caches: read config with WebhooksRuntime.config().

Naming (owner rule)

  • Tables are lowercase snake_case, prefixed webhooks_; the backend name is the table name; column names are snake_case.
  • Permissions: webhooks.view, webhooks.manage, webhooks.admin (and webhooks.hasAccess).
  • Data lives in standard visible tables. Processes are table or record actions, never in the nav. The nav lists only the main tables.

Code Style

3-space indent, braces on the next line, return (x);, flower-box Javadoc on every class and method, fluent withX() setters.

Release

  • CircleCI qqq-orb 0.6.8.
  • develop publishes SNAPSHOTs.
  • release/* publishes RCs.
  • vX.Y.Z tags publish releases (GA tags only).