Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

05 - Screen Inventory (Webhooks Module)

Every screen of the Webhooks module, its intent, route, composition, states, permissions, platform behavior and events. Authoritative components in 00-shared/03; this file enumerates which ones each screen uses with module specifics.


Legend

States = idle / loading / success / empty / error(offline, rate, invalid) / disabled / permission. Analytics events follow {module}.{screen}.{action} (proposed; SDK open - 00-shared/10 §8).


1. Webhooks List (/webhooks)

FieldDetail
PurposeAll tenant webhooks, newest first
SourceGET /api/v1/webhooks (no pagination, sort createdAt: -1, webhooks.service.ts:35-37)
WidgetsAppListTile per webhook: name, url (monospace, clipped), events chips (up to 3 + "+n"), trailing AppBadge (active success / paused neutral), AppMenu (Edit / Pause-Resume / Delete)
CTA / FABAppFAB "New webhook" (webhook.create)
Statesloading (skeleton tiles), empty ("No webhooks yet"), error API, permission (webhook.read)
Row actionstap → detail (S3); delete → AppDialog confirm → DELETE /webhooks/:id (webhooks.controller.ts:45-50), optimistic remove, rollback on 404/500
Analyticswebhooks.list.open, webhooks.list.create, webhooks.list.open_detail (proposed)

2. Create Webhook (/webhooks/new)

FieldDetail
PurposeRegister subscription: name, url, events, secret, enabled
SourcePOST /api/v1/webhooks (webhooks.controller.ts:21-25); DTO create-webhook.dto.ts:11-34
InputsAppTextField name; url (.url keyboard); event picker (chips multi-select from event-queue-map.ts:6-43); secret (obscure + "generate" helper, min-length hint); enabled switch (default on, create-webhook.dto.ts:30-33)
Primary CTA"Create webhook"
Validationname/url/secret required; url @IsUrl({ require_tld: false }) (create-webhook.dto.ts:17-18); ≥1 event (ArrayMinSize(1), :22-23)
Statesloading, field errors, server error
Analyticswebhooks.create.submit, webhooks.create.success, webhooks.create.failure (proposed)
NoteForm is the largest surface - full spec in 08_Form_Specifications.md

3. Webhook Detail (/webhooks/:id)

FieldDetail
PurposeSingle subscription: config + health in one place
SourceGET /api/v1/webhooks/:id (webhooks.controller.ts:33-37); metrics GET /webhooks/:id/metrics (:72-76, webhooks.service.ts:142-156)
LayoutHeader card (name, url, enabled badge, events chips, secret masked with reveal); metrics tile (total / success / failed / pending counts); recent delivery logs preview (5 rows); actions
ActionsEdit (S4), Test (S7), Retry (S8, only when failed > 0), Pause/Resume (S9)
Statesloading skeleton, 404 → AppErrorState + back, error
Analyticswebhooks.detail.open, webhooks.detail.tab.{config,logs} (proposed)

4. Edit Webhook (/webhooks/:id/edit)

FieldDetail
PurposeModify url/events/secret/enabled - any subset
SourcePATCH /api/v1/webhooks/:id (webhooks.controller.ts:39-43); UpdateWebhookDto = PartialType (all optional, update-webhook.dto.ts:4)
Inputssame as S2, pre-filled from detail doc; secret shown masked, blank = keep unchanged
Primary CTA"Save changes"
NoteSecret rotation is a PATCH of secret today - a dedicated rotation flow is (forward-looking)

5. Delivery Logs (/webhooks/:id/logs)

FieldDetail
PurposePer-attempt delivery history, newest first
SourceGET /api/v1/webhooks/:id/logs - hard cap 50, sort createdAt: -1 (webhooks.service.ts:88-93)
WidgetsAppListTile per log: eventType, status badge (pending amber / success green / failed red), responseCode, attemptedAt; tap → S6
Empty"No deliveries yet - trigger an event or use Test"
Pull-to-refreshRefreshIndicator re-fetches
Statesloading, error, empty
Analyticswebhooks.logs.open, webhooks.logs.refresh (proposed)
NoteOne row per worker attempt (retries create new rows, webhooks.service.ts:62-67, 84-89); pagination (forward-looking)

6. Delivery Log Detail (bottom sheet from S5)

FieldDetail
PurposeFull attempt payload + response
Sourcesame doc as S5 (payload, responseCode, responseBody, attemptedAt, completedAt - webhook-delivery-log.schema.ts:12-38)
ContenteventType, status, timing, responseCode + responseBody (collapsed, monospace), full payload JSON (copyable)
Actions"Retry this webhook" (S8) if failed
a11ypayload/code blocks exposed as selectable text, not image

7. Test Delivery (dialog, from S3)

FieldDetail
PurposePing the endpoint with a synthetic event
SourcePOST /api/v1/webhooks/:id/test (webhooks.controller.ts:65-70) → queue job with eventType: 'WebhookTested', payload: { test: true, webhookId } (webhooks.service.ts:130-138)
Flowconfirm dialog → success snackbar "Test delivery queued" (server returns { message: 'Test delivery queued' }, :69) → user watches S5
NoteAsync: dialog must not claim delivery, only enqueue (queue webhook-deliver, queue.constants.ts:14)

8. Retry Delivery (dialog, from S3/S5/S6)

FieldDetail
PurposeRe-enqueue the latest failed delivery
SourcePOST /api/v1/webhooks/:id/retry (webhooks.controller.ts:58-63) → 404 'No failed deliveries to retry' if none (webhooks.service.ts:103-108); job reuses the failed log's payload (:110-118)
Preconditionlatest log for this webhook has status: 'failed' (webhooks.service.ts:103-106)
Flowdialog "Retry latest failed delivery?" → snackbar "Retry queued" → S5 refresh
NotecorrelationId is sent as '' on retries (webhooks.service.ts:117)

9. Pause / Resume (inline confirm from S1/S3)

FieldDetail
PurposeFlip enabled without editing the record
SourcePOST /webhooks/:id/pausesetEnabled(false); POST /webhooks/:id/resumesetEnabled(true) (webhooks.controller.ts:78-90, webhooks.service.ts:158-161)
Behaviorpaused webhooks are skipped by fan-out (webhook.repository.ts:23-28); toggle back via resume
NoteNo pause vs disabled distinction in the model - single enabled boolean (webhook.schema.ts:22-23)

Shared components used

AppTextField, AppButton, AppSnackbar, AppCard, AppListTile, AppBottomSheet, AppDialog, AppMenu, AppSkeleton, AppEmptyState, AppErrorState, AppOfflineBanner, AppFAB, AppChips, AppBadge, AppSwitch, AppStatTile (metrics). Module-specific: EventPickerChipField, SecretField, DeliveryLogTile, SignatureVerifyCard (developer docs) - defined in 07_Component_Library.md.

Analytics events (proposed)

webhooks.list.{open,create,open_detail}, webhooks.create.{submit,success,failure}, webhooks.detail.{open,pause,resume}, webhooks.edit.{submit,success}, webhooks.logs.{open,refresh,retry,test} (all proposed).

Keyboard, landscape, tablet, desktop

  • Forms portrait-first with resizeToAvoidBottomInset; tablet/desktop: list + detail master-detail (S1 → S3), forms centered ≤ 480 dp.
  • Code blocks (url, payload, responseBody) full-width monospace with horizontal scroll; long payloads collapse by default (S6).