Skip to content

feat: add provider capability declaration system - #773

Merged
Abd-Standard merged 1 commit into
Core-Foundry:mainfrom
Moh-dakai:feat/provider-capability-system
Sep 1, 2026
Merged

Abd-Standard merged 1 commit into
Core-Foundry:mainfrom
Moh-dakai:feat/provider-capability-system

Conversation

@Moh-dakai

Copy link
Copy Markdown

Summary

Introduces a capability-aware notification provider abstraction so providers can declare what features they support, unsupported features are handled gracefully, and the core notification pipeline never depends on a concrete
provider class.

Motivation

The pipeline previously had a hard-coded switch statement in NotificationScheduler.executeNotification that directly instantiated Discord-specific logic and threw not yet implemented errors for every other channel. This made it
impossible to add new providers without modifying the scheduler, and gave callers no way to know whether a feature like rich formatting or file attachments was available before attempting delivery.

Changes

New types — src/types/provider-capabilities.ts

  • ProviderCapability enum with six values: RICH_FORMATTING, ATTACHMENTS, MESSAGE_UPDATES, THREADING, INTERACTIVE_COMPONENTS, NATIVE_SCHEDULING
  • ProviderMetadata — id, name, version, and a ReadonlySet
  • DeliveryPayload / DeliveryResult — strongly-typed input/output for every provider
  • NotificationProvider interface — the only type the pipeline imports; no concrete classes

Discord provider — src/services/providers/discord-provider.ts

  • Wraps the existing DiscordNotificationService behind NotificationProvider
  • Declares 5 capabilities (RICH_FORMATTING, ATTACHMENTS, MESSAGE_UPDATES, THREADING, INTERACTIVE_COMPONENTS)
  • Any requested feature not in that set is logged and listed in DeliveryResult.degradedCapabilities; delivery still proceeds

Webhook provider — src/services/providers/webhook-provider.ts

  • Generic HTTP POST provider; declares only ATTACHMENTS
  • All other requested features degrade gracefully

Provider registry — src/services/provider-registry.ts

  • ProviderRegistry class: register, unregister, get, has, listIds, findByCapability, deliver
  • Module-level singleton helpers: getProviderRegistry / setProviderRegistry / resetProviderRegistry for easy test isolation
  • deliver() returns success: false with a clear error message instead of throwing when no provider is registered for a type

Scheduler update — src/services/notification-scheduler.ts

  • Injects ProviderRegistry (defaults to the module singleton, overridable in tests)
  • executeNotification queries the registry first; falls back to the existing direct-Discord path so existing deployments without a bootstrapped registry continue to work
  • Added missing verifyPayloadIntegrity import (was called but never imported)

Tests — src/services/providers/provider-capabilities.test.ts

35 tests covering:

  • ProviderCapability enum shape
  • hasCapability true/false for declared vs undeclared features
  • Discord provider: capability declarations, successful delivery, 4xx/network failure, graceful degradation
  • Webhook provider: same matrix
  • Registry: register, overwrite, unregister, findByCapability, dispatch to correct provider, unknown-provider error
  • Singleton helpers: isolation between test runs
  • Pipeline independence: an ad-hoc provider object satisfies the contract; providers can be swapped without changing the call site

Acceptance criteria

┌──────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Criterion │ How it is satisfied │
├──────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Providers can declare supported capabilities │ ProviderMetadata.capabilities: ReadonlySet + hasCapability() │
├──────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Unsupported features are handled gracefully │ deliver() populates DeliveryResult.degradedCapabilities and logs a warning; delivery still succeeds │
├──────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ The core pipeline does not depend on a specific provider │ NotificationScheduler only imports ProviderRegistry and the NotificationProvider interface │
└──────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────┘

Testing

35 tests, 35 passed

Closes #708

Introduce a capability-aware notification provider abstraction so that
providers can declare what features they support and the core pipeline
never depends on a concrete provider implementation.

Changes:
- Add ProviderCapability enum (RICH_FORMATTING, ATTACHMENTS,
  MESSAGE_UPDATES, THREADING, INTERACTIVE_COMPONENTS, NATIVE_SCHEDULING)
  and NotificationProvider interface in src/types/provider-capabilities.ts
- Implement DiscordNotificationProvider (declares 5 capabilities,
  delegates HTTP delivery to sendWebhook, degrades unsupported features
  gracefully) in src/services/providers/discord-provider.ts
- Implement WebhookNotificationProvider (declares ATTACHMENTS only,
  generic JSON POST) in src/services/providers/webhook-provider.ts
- Add ProviderRegistry with register/unregister/get/findByCapability/
  deliver and module-level singleton helpers in
  src/services/provider-registry.ts
- Update NotificationScheduler to dispatch through the registry first;
  falls back to legacy direct-Discord path for backward compatibility
- Add 35 unit tests covering all acceptance criteria in
  src/services/providers/provider-capabilities.test.ts
@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Moh-dakai Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Abd-Standard
Abd-Standard merged commit 5866229 into Core-Foundry:main Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Provider Capability Metadata

3 participants