Skip to content

Admin: webhook delivery log + dashboard summary (Phase 8 cross-cutting) #19

Description

@pablo-clueless

Scope

The two things the Admin module itself owns: a cross-source webhook delivery log and the dashboard summary endpoint.

Webhook delivery log

All three webhook sources (GitHub practice repo, GitHub org, Stripe) already persist delivery/event ids for idempotency. Extend that seam into a queryable log: source, delivery id, event type, received-at, outcome (processed / duplicate / invalid-signature / handler-failed + error summary).

Method Path Notes
GET /admin/webhooks/deliveries?source=&outcome= last N (paginated, newest first) — invaluable for debugging redeliveries

Implementation: either widen each module's delivery table and expose via a small contract per module, or a shared webhook_deliveries table in the Admin schema written through a SharedKernel interface — pick whichever keeps module boundaries clean and document the choice in the PR.

Dashboard summary

Method Path Notes
GET /admin/summary counts for the sidebar/landing: pending members, active members, submitted posts (badge count), active mentorships, upcoming sessions, active sponsors, MRR

Each count sourced through the owning module's public contract — the Admin module aggregates, never queries foreign schemas directly.

Dependencies

Blocked by #1. Counts degrade gracefully (0) for modules not yet built — do not block on Phases 4–7; wire each count as its module lands.

Acceptance criteria

  • Failed handler outcomes captured with error summary (no stack traces in API responses)
  • Summary returns partial data when a module contract is unregistered
  • Both endpoints admin-gated + paginated where applicable

Conventions (project-wide, non-negotiable)

  • .NET 9, records for immutable shapes, file-scoped namespaces, primary constructors where they read well. Minimal-API endpoints grouped per module via IEndpointModule.MapEndpoints.
  • Result<T> (SharedKernel) instead of exception-driven control flow. Endpoint results map failures to ProblemDetails with the stable error codes listed above — the frontend keys off them.
  • Module owns its EF Core DbContext mapped to its own Postgres schema. Modules never reference each other's internals — cross-module needs go through a public contract interface or an in-process domain event (IEventPublisher).
  • All external calls (GitHub, Stripe, Brevo, Cloudinary, Meilisearch) behind interfaces owned by the consuming module.
  • Every list endpoint paginated (offset is fine). xUnit tests in tests/CommunityPro.Tests/<Module>/ following the existing harness patterns (see Members/MembersTestHarness.cs).

Metadata

Metadata

Assignees

No one assigned

    Labels

    adminPhase 8 — Admin dashboard

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions