Skip to content

FRD-067: Webhook Log Table Widget

FieldValue
OwnerDavid Holmes
StatusDraft
Last Updated2026-05-26
Target Releasev2.0.0 (P2)
T-Shirt SizeM
TypeWidget

Document Summary

A data-grid-based webhook log table displaying delivery attempts with status, endpoint URL, payload preview, timestamp, and a retry action. Designed for SaaS webhook management dashboards where developers monitor and debug outgoing webhook deliveries.


Introduction

Overview

SaaS platforms that send webhooks need a standard UI for monitoring delivery status. This widget provides a sortable, filterable data grid showing webhook delivery logs with status indicators, truncated payload previews, and retry capabilities.

Goals

  • Display webhook delivery logs in a DataGrid with sortable columns.
  • Show status (success, failed, pending, retrying), endpoint URL, payload preview, and timestamp.
  • Provide a retry action per failed delivery.
  • Support filtering by status.
  • Ship Storybook stories covering various states.

Non-Goals

  • Webhook endpoint configuration or management.
  • Payload editing or resending with modifications.
  • Real-time streaming of new deliveries (consumer polls or uses WebSocket).
  • Webhook signing or security configuration.

Scope

In Scope

ItemDescription
WebhookLogTable componentDataGrid with webhook delivery columns
Status columnBadge showing delivery status with semantic color
Payload previewTruncated JSON preview with expand/copy option
Retry actionButton per row for failed deliveries; calls onRetry(deliveryId)
Status filterDropdown filter to show only specific statuses
Storybook storiesDefault, AllSuccess, MixedStatus, WithRetry, Empty, Loading

Out of Scope

ItemRationale
Endpoint managementSeparate admin UI concern
Payload editingDifferent workflow; out of scope
Real-time updatesConsumer handles via polling or WebSocket
Delivery schedulingBackend concern

Users and Pain Points

UserPain Point
DevelopersNo standard webhook log UI; teams build custom tables per product
SRE/DevOpsDebugging failed deliveries requires switching to backend logs
Support engineersDifficulty identifying and retrying failed webhook deliveries for customers

Definitions

TermDefinition
Webhook deliveryA single HTTP request sent to a configured endpoint
Delivery statusThe outcome of the HTTP request (success, failed, pending, retrying)
Payload previewA truncated view of the JSON request body
RetryRe-sending a failed delivery to the same endpoint

Current State

No webhook log table exists in the design system. The people-table.tsx and billing-history-table.tsx widgets demonstrate the DataGrid pattern using TanStack Table. These can serve as reference implementations for column definitions, sorting, and filtering.


Proposed Solution

Create a WebhookLogTable widget at src/components/widgets/webhook-log-table.tsx that:

  1. Accepts an array of WebhookDelivery objects.
  2. Renders a DataGrid with columns: Status, Endpoint, Event Type, Payload Preview, Duration, Timestamp, Actions.
  3. Status column uses Badge with semantic variants.
  4. Payload preview truncates to a configurable length with a “View” action to expand.
  5. Actions column includes a Retry button for failed deliveries.
  6. Supports filtering by status via a toolbar dropdown.

Requirements

The table must use TanStack Table for consistency with existing DataGrid patterns. It must handle empty states and loading states gracefully.


Functional Requirements

IDRequirementPriority
FR-01Render a DataGrid with Status, Endpoint, Event Type, Payload Preview, Duration, Timestamp, and Actions columnsMust
FR-02Status column displays a Badge with semantic color (success=green, failed=red, pending=yellow, retrying=blue)Must
FR-03Payload preview column shows truncated JSON (first 80 chars)Must
FR-04Clicking payload preview opens a detail panel or modal with the full payloadShould
FR-05Actions column shows a Retry button for failed/retrying rowsMust
FR-06Call onRetry(deliveryId) when retry is clickedMust
FR-07Toolbar filter dropdown filters rows by statusMust
FR-08Support sorting by Timestamp and Duration columnsShould
FR-09Show empty state when no deliveries are presentMust
FR-10Support a loading prop that renders skeleton rowsShould
FR-11Call onViewPayload(deliveryId) when payload preview is expandedShould

Non-Functional Requirements

IDRequirement
NFR-01Renders 200 rows without perceptible lag
NFR-02Full light/dark theme support
NFR-03Table is horizontally scrollable on narrow viewports

API / Interface Requirements

type WebhookDeliveryStatus = "success" | "failed" | "pending" | "retrying";
interface WebhookDelivery {
id: string;
endpoint: string;
eventType: string;
status: WebhookDeliveryStatus;
statusCode?: number;
payloadPreview: string;
payload?: string;
durationMs?: number;
timestamp: string; // ISO 8601
retryCount?: number;
}
interface WebhookLogTableProps {
deliveries: WebhookDelivery[];
loading?: boolean;
emptyMessage?: string;
onRetry?: (deliveryId: string) => void;
onViewPayload?: (deliveryId: string) => void;
className?: string;
}

Accessibility Requirements

IDRequirement
A11Y-01Table uses proper <table> semantics with <th scope="col"> headers
A11Y-02Status badges include screen-reader-accessible labels
A11Y-03Retry buttons have aria-label including the delivery endpoint
A11Y-04Sort controls are keyboard-accessible
A11Y-05Empty state and loading state have role="status" with descriptive text
A11Y-06Payload preview expansion is keyboard-activatable

Content and Documentation Requirements

  • Storybook doc page with props, column descriptions, and integration guidance.
  • Stories: Default, AllSuccess, MixedStatus, WithRetry, Empty, Loading.
  • JSDoc on all exported types.

Dependencies

DependencyTypeNotes
@tanstack/react-tableExternalDataGrid core
BadgeInternalStatus column
ButtonInternalRetry action
DropdownMenuInternalStatus filter
SkeletonInternalLoading state

Risks and Tradeoffs

RiskImpactMitigation
Large payload previews slow renderingPerformance degradationTruncate aggressively; lazy-load full payload
Retry storms from rapid clickingBackend overloadDisable retry button after click until callback resolves
Status filter hides important failuresMissed issuesDefault to showing all statuses; badge colors draw attention

Open Questions

  1. Should payload detail open in a slide-out panel or a modal?
  2. Do we need a “Retry all failed” bulk action?
  3. Should the table support pagination for very long logs, or infinite scroll?

Acceptance Criteria

  • Table renders with all specified columns.
  • Status badges display correct semantic colors.
  • Payload preview truncates and expands correctly.
  • Retry button calls onRetry with the delivery ID.
  • Status filter filters rows correctly.
  • Empty and loading states render appropriately.
  • All Storybook stories render without errors.
  • Passes axe accessibility audit with zero violations.
  • Unit tests cover rendering, filtering, retry, and empty/loading states.

LLM Handoff Instructions

When implementing this FRD:

  1. Create src/components/widgets/webhook-log-table.tsx.
  2. Use @tanstack/react-table with getCoreRowModel, getSortedRowModel, and getFilteredRowModel.
  3. Reference billing-history-table.tsx and people-table.tsx for DataGrid conventions.
  4. Create src/components/widgets/webhook-log-table.stories.tsx with all listed stories.
  5. Create src/components/widgets/webhook-log-table.test.tsx.
  6. Status badge variant mapping: success=complete, failed=warning, pending=pending, retrying=active.
  7. Use cn() for class merging. Follow existing table styling patterns.

Decision Log

DateDecisionRationale
2026-05-26Use TanStack Table for consistencyMatches existing DataGrid patterns in the design system
2026-05-26Payload preview is truncated, not fullPerformance and readability; full payload on demand

Document History

DateVersionAuthorChanges
2026-05-260.1David HolmesInitial draft