Skip to content

feat: Add usage budget controls - #2270

Open
niemyjski wants to merge 2 commits into
mainfrom
niemyjski/add-usage-budget-controls
Open

niemyjski wants to merge 2 commits into
mainfrom
niemyjski/add-usage-budget-controls

Conversation

@niemyjski

@niemyjski niemyjski commented May 31, 2026

Copy link
Copy Markdown
Member

Summary

Add organization budget alerts, optional project event caps, and automatic sampling for noisy projects. The Svelte usage pages let users configure, save, and clear these settings and show current throttling state.

  • Preserve organization overage and API-key behavior; expose additive organization/project fields and canonical nullable PATCH contracts.
  • Reserve accepted usage atomically, preserve failed events across single-event and mixed-batch retries, and commit accepted/discarded counters together. Completed reservations retain pending retry indexes; older records remain readable.
  • Send budget and throttle notices through the current Razor email templates, respect recipient preferences, and recheck current throttle state before sending.
  • Display server validation errors without losing form input and identify the chart's current project-limit reference.

Validation

  • Release solution build: 0 warnings/errors.
  • 115 focused backend tests passed, covering mail, validation, serialization, stale notifications, retry recovery, legacy records, partial enqueue, concurrent delivery, and acknowledgement failures.
  • 777 frontend unit tests passed; type check, lint, and build passed.
  • Four localhost browser cases passed at desktop/mobile widths with mocked API responses, including validation, save, clear, and server-error handling.
  • OpenAPI generated through the application provider with hosted services disabled; TypeScript models regenerated from that document. OpenSpec strict validation passed.

Hosted Build workflow passed on 2fda0f424: 3,048 backend tests passed and 3 were skipped; E2E reported 66 passed plus one existing dashboard chart-refresh test that passed on retry. Frontend and Docker checks also passed.

Local service-backed integration tests and OpenApiSnapshotTests were not rerun because the shared Elasticsearch cluster has unavailable primary shards; the hosted backend run supplied that integration coverage.

Compatibility and operation

Missing budget settings keep alerts disabled and project caps unset. Atomic reservations require a single Redis endpoint; Redis Cluster is rejected. Retry dispatch remains at least once: an enqueue that succeeds before its acknowledgement fails may duplicate the failed event, while processed events from the original batch remain completed.

Comment thread src/Exceptionless.Core/Models/Organization.cs Fixed
@niemyjski
niemyjski marked this pull request as ready for review May 31, 2026 12:03
@niemyjski
niemyjski requested a review from Copilot May 31, 2026 12:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds backend usage budget controls for organizations and projects, including budget alert settings, project ingest caps, smart throttling calculations, notification work items, and API contract updates.

Changes:

  • Adds organization budget alert and project ingest limit models/API fields.
  • Extends usage/event processing with alert checks, project budget allowance, and smart throttling sampling.
  • Adds notification messages, work items, mailer methods/templates, OpenSpec docs, OpenAPI baseline updates, and limited regression tests.

Reviewed changes

Copilot reviewed 39 out of 39 changed files in this pull request and generated 19 comments.

Show a summary per file
File Description
tests/Exceptionless.Tests/Services/UsageServiceTests.cs Adds a regression test for missing organization smart throttle handling.
tests/Exceptionless.Tests/Mail/NullMailer.cs Adds no-op implementations for new mailer methods.
tests/Exceptionless.Tests/Mail/CountingMailer.cs Adds stub implementations for new mailer methods.
tests/Exceptionless.Tests/Controllers/OrganizationControllerTests.cs Adds PATCH regression coverage for budget alert settings without name.
tests/Exceptionless.Tests/Controllers/Data/openapi.json Updates OpenAPI baseline for new usage budget fields and DTOs.
src/Exceptionless.Web/Models/Project/ViewProject.cs Exposes project ingest limit and smart throttle state.
src/Exceptionless.Web/Models/Project/UpdateProject.cs Allows project ingest limit updates.
src/Exceptionless.Web/Models/Organization/ViewOrganization.cs Exposes organization budget alert settings.
src/Exceptionless.Web/Models/Organization/UpdateOrganization.cs Adds organization PATCH DTO.
src/Exceptionless.Web/Mapping/ProjectMapper.cs Ignores computed project usage budget fields in mapper.
src/Exceptionless.Web/Mapping/OrganizationMapper.cs Adds organization update mapping.
src/Exceptionless.Web/Controllers/ProjectController.cs Populates computed project ingest/throttle fields.
src/Exceptionless.Web/Controllers/OrganizationController.cs Switches update DTO and adjusts name validation condition.
src/Exceptionless.Web/Bootstrapper.cs Registers new startup notification subscribers.
src/Exceptionless.Core/Services/UsageService.cs Adds budget alert checks, project allowance calculation, and smart throttle calculation.
src/Exceptionless.Core/Models/WorkItems/ProjectSmartThrottleWorkItem.cs Adds smart throttle notification work item.
src/Exceptionless.Core/Models/WorkItems/OrganizationBudgetAlertWorkItem.cs Adds budget alert notification work item.
src/Exceptionless.Core/Models/ProjectIngestLimit.cs Adds project ingest limit model and enum.
src/Exceptionless.Core/Models/Project.cs Persists optional project ingest limit.
src/Exceptionless.Core/Models/OrganizationBudgetAlertSettings.cs Adds organization budget alert settings model.
src/Exceptionless.Core/Models/Organization.cs Persists and validates organization budget alert settings.
src/Exceptionless.Core/Models/Messaging/ProjectSmartThrottleApplied.cs Adds smart throttle notification message.
src/Exceptionless.Core/Models/Messaging/OrganizationBudgetAlert.cs Adds budget alert notification message.
src/Exceptionless.Core/Mail/Templates/project-smart-throttle.html Adds smart throttle email template.
src/Exceptionless.Core/Mail/Templates/organization-budget-alert.html Adds budget alert email template.
src/Exceptionless.Core/Mail/Mailer.cs Implements new budget/throttle emails.
src/Exceptionless.Core/Mail/IMailer.cs Adds new budget/throttle mailer contracts.
src/Exceptionless.Core/Jobs/WorkItemHandlers/ProjectSmartThrottleWorkItemHandler.cs Adds smart throttle subscriber and email handler.
src/Exceptionless.Core/Jobs/WorkItemHandlers/OrganizationBudgetAlertWorkItemHandler.cs Adds budget alert subscriber and email handler.
src/Exceptionless.Core/Jobs/EventPostsJob.cs Enforces project allowance and applies smart throttle sampling.
src/Exceptionless.Core/Exceptionless.Core.csproj Embeds new email templates.
src/Exceptionless.Core/Bootstrapper.cs Registers new work item handlers.
openspec/changes/add-usage-budget-controls/tasks.md Adds implementation/verification task plan.
openspec/changes/add-usage-budget-controls/specs/organizations-projects-users-auth/spec.md Adds auth/ownership requirements.
openspec/changes/add-usage-budget-controls/specs/jobs-notifications-and-queues/spec.md Adds notification and queue requirements.
openspec/changes/add-usage-budget-controls/specs/event-ingestion/spec.md Adds ingestion, throttling, and project budget requirements.
openspec/changes/add-usage-budget-controls/specs/api-compatibility/spec.md Adds API compatibility requirements.
openspec/changes/add-usage-budget-controls/proposal.md Documents proposal and user-visible behavior.
openspec/changes/add-usage-budget-controls/design.md Documents detailed backend/UI design.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Jobs/EventPostsJob.cs Outdated
Comment thread src/Exceptionless.Core/Jobs/EventPostsJob.cs Outdated
Comment thread src/Exceptionless.Core/Jobs/EventPostsJob.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Jobs/EventPostsJob.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Fixed
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 49 out of 52 changed files in this pull request and generated 14 comments.

Comment thread src/Exceptionless.Core/Jobs/EventPostsJob.cs Outdated
Comment thread src/Exceptionless.Core/Services/UsageService.cs Outdated
Comment thread tests/Exceptionless.Tests/Controllers/Data/openapi.json Outdated
Comment thread src/Exceptionless.Web/ClientApp/src/lib/features/organizations/schemas.ts Outdated
Comment thread src/Exceptionless.Web/ClientApp/src/lib/features/projects/schemas.ts Outdated
Comment thread tests/Exceptionless.Tests/Api/Data/openapi.json
Comment thread src/Exceptionless.Core/Models/Organization.cs Outdated
Comment thread src/Exceptionless.Web/ClientApp/src/lib/features/projects/models.ts Outdated
@niemyjski

Copy link
Copy Markdown
Member Author

Completed the final reviewer-feedback, thermo-nuclear, and runtime dogfood pass on b696ef46de562819aee5bbd5b79dc80f102e2b47.

  • Feedback audit: 37/37 review threads are resolved. 32 are outdated after later rewrites; the 5 still attached to current lines are already fixed by project-limit validation, nullable typed OpenAPI schemas, and delayed notification-handler rechecks. All 59 submitted reviews are COMMENTED; there are no change-request reviews, open threads to reply to, or actionable human/bot top-level comments.
  • Architecture: retained the minimal generic atomic-cache boundary rather than adding a thin ingest-store wrapper. Reservation generations, identity checks, accounting, blocked totals, capacity, state, TTLs, and usage-set membership are now handled atomically and fail closed. No changed production file crosses 1,000 lines and the final structural audit found no remaining code-judo, spaghetti, boundary, or partial-update blocker.
  • Local Redis dogfood: cap 2 produced 2 accepted / 3 blocked; two simultaneous 5-event requests against cap 6 produced exactly 6 accepted / 4 blocked; clearing the cap restored ingestion without altering prior blocked counts. Both isolated projects were deleted and verified absent.
  • Runtime cost/health: Aspire served the exact head; API/Jobs/dependencies were healthy. Each concurrent ingest used exactly two atomic scripts (reserve and complete), each 0.35–0.77 ms. No error traces were tied to the dogfood projects.
  • Browser: Svelte Usage saved 6 → 7 and returned effective_ingest_limit: 7; related requests were 200, page errors were empty, and desktop plus 390×844 layouts passed.
  • Verification: release build 0 warnings/errors; 2,592 passed / 2 skipped / 0 failed; focused usage 61/61, EventPost 7/7, real Redis 5/5; strict OpenSpec and diff checks passed. Required CI, including API coverage, is terminal green.

No external blocker remains.

@niemyjski
niemyjski force-pushed the niemyjski/add-usage-budget-controls branch from bea9811 to 2fda0f4 Compare September 16, 2026 01:03
@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.Insulation 39% 38% 304
Exceptionless.Web 85% 70% 8156
Exceptionless.Core 77% 69% 11125
Exceptionless.AppHost 38% 41% 147
Summary 79% (27449 / 34539) 69% (12804 / 18673) 19732

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.

2 participants