Skip to content

feat: API response time logging, delivery failure reasons, config validation, notification sorting - #565

Open
Lost-Z wants to merge 1 commit into
Core-Foundry:mainfrom
Lost-Z:feature/issues-491-493-494-495
Open

feat: API response time logging, delivery failure reasons, config validation, notification sorting#565
Lost-Z wants to merge 1 commit into
Core-Foundry:mainfrom
Lost-Z:feature/issues-491-493-494-495

Conversation

@Lost-Z

@Lost-Z Lost-Z commented Jul 30, 2026

Copy link
Copy Markdown

Summary

Implements four issues in a single PR.


Closes #491 — Add API Response Time Logging

  • New ResponseTimeMiddleware (listener/src/middleware/response-time.ts)
    • Records start time per-request via a symbol key on the ServerResponse
    • Sets X-Response-Time header on every response
    • Logs completed requests at INFO; flags requests exceeding slowRequestThresholdMs (default 1 000 ms) at WARN
    • Tracks totalRequests, slowRequests, totalResponseTimeMs, maxResponseTimeMs
    • slowRequestThresholdMs is configurable via EventsServerOptions
  • Wired into createEventsServer: start() at request open, finish() at the 404 fallthrough
  • New GET /api/metrics/response-time endpoint exposes counters; ?reset=true resets them

Closes #493 — Add Delivery Failure Reasons

  • NotificationSearchService: failureReason field added to NotificationSearchResult
    • Populated from last_error (scheduled_notifications) and error_reason (processed_events)
  • Dashboard eventsApi.ts: failureReason exposed on NotificationSearchResult
  • NotificationSearchPage: renders a Failure reason row in NotificationResultCard when the field is non-null

Closes #494 — Improve Configuration Validation

  • New validateConfig(config) exported from listener/src/config.ts
    • Validates RPC URL format, port range, poll intervals, scheduler lock/batch settings, retry multiplier ordering, rate-limit minimums, analytics bucket size, cleanup retention floors
    • Collects all violations before throwing so operators see every problem in one error message
    • Throws ConfigError with a numbered list of descriptive messages
  • index.ts: validateConfig(config) is called immediately after loadConfig() — invalid configuration blocks startup before any service initialises

Closes #495 — Add Notification Sorting Options

  • New NotificationSortOption type (newest | oldest | priority | delivery_status) added to dashboard/src/types/event.ts; sortBy field added to EventFilters
  • sortEvents() utility in eventData.ts implements all four strategies; filterEvents() accepts and applies sortBy
  • EventFiltersBar: Sort by dropdown; selection persisted to localStorage via setSortBy so it survives page refreshes
  • eventStore: setSortBy action writes to localStorage; loadPersistedSort() restores on init; selectFilteredEvents and useFilteredEvents thread sortBy through
  • Server-side: NotificationSearchParams.sortBy (newest | oldest | status) added to NotificationSearchService; sort applied before pagination
  • events-server: extracts sortBy query param and forwards to the search service
  • NotificationSearchPage: Sort by dropdown (newest / oldest / status); included in filtersKey so page resets on sort change; reset by Clear filters

…idation, notification sorting

Closes Core-Foundry#491
Closes Core-Foundry#493
Closes Core-Foundry#494
Closes Core-Foundry#495

## Core-Foundry#491 — Add API Response Time Logging
- New ResponseTimeMiddleware (listener/src/middleware/response-time.ts)
  - Records start time per request via res object symbol key
  - Sets X-Response-Time header on every response
  - Logs completed requests at INFO; flags slow requests at WARN
  - Tracks totalRequests, slowRequests, totalResponseTimeMs, maxResponseTimeMs
  - slowRequestThresholdMs defaults to 1000 ms (configurable via EventsServerOptions)
- Wire middleware into createEventsServer: start() at request open, finish() at 404 fallthrough
- New GET /api/metrics/response-time endpoint exposes counters; ?reset=true resets them

## Core-Foundry#493 — Add Delivery Failure Reasons
- NotificationSearchService: add failureReason field to NotificationSearchResult
  - Populated from last_error (scheduled_notifications) and error_reason (processed_events)
- Dashboard eventsApi.ts: expose failureReason on NotificationSearchResult
- NotificationSearchPage: render Failure reason row in NotificationResultCard when present

## Core-Foundry#494 — Improve Configuration Validation
- New validateConfig(config) in listener/src/config.ts
  - Validates all critical fields: RPC URL format, port range, poll intervals, scheduler
    lock/batch settings, retry multiplier/delay ordering, rate-limit minimums, analytics
    bucket size, cleanup retention floor
  - Collects all violations before throwing so operators see every problem at once
  - Throws ConfigError with numbered list of descriptive messages
- index.ts: call validateConfig(config) immediately after loadConfig() so invalid
  configuration blocks startup before any service initialises

## Core-Foundry#495 — Add Notification Sorting Options
- New NotificationSortOption type (newest | oldest | priority | delivery_status)
  added to dashboard/src/types/event.ts; sortBy field added to EventFilters
- sortEvents() utility in eventData.ts implements all four sort strategies;
  filterEvents() accepts and applies sortBy parameter
- EventFiltersBar: Sort by dropdown persists selection to localStorage via setSortBy
- eventStore: setSortBy action writes to localStorage; loadPersistedSort() restores
  on init; selectFilteredEvents and useFilteredEvents pass sortBy through
- Server-side: NotificationSearchParams.sortBy (newest | oldest | status) added;
  NotificationSearchService.search() applies sort before pagination
- events-server: extracts sortBy query param and forwards to search service
- NotificationSearchPage: Sort by dropdown (newest/oldest/status); included in
  filtersKey so page resets on sort change; cleared by Clear filters
@drips-wave

drips-wave Bot commented Jul 30, 2026

Copy link
Copy Markdown

@Lost-Z 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

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 Notification Sorting Options Improve Configuration Validation Add Delivery Failure Reasons Add API Response Time Logging

1 participant