Skip to main content

Overview

NuGet.SupportRequests.Notifications is a .NET Framework 4.7.2 console executable that runs as a scheduled backend job within the NuGet Gallery infrastructure. Its sole responsibility is to read open and recently-closed support tickets from the Gallery’s SQL-based support-request database, build HTML email reports, and route them to the appropriate recipients through the shared NuGet.Services.Messaging Service Bus pipeline. Two distinct notification types are supported:
  • OnCall Daily Summary — sent each day to the on-call engineer, listing all currently unresolved issues with their assigned admin and status.
  • Weekly Summary — sent once a week to a configured distribution address, comparing last week’s issue counts, closure rates, SLA metrics, and top request reasons against the prior week.
The job does not host a web server or long-running process. It is invoked by an external scheduler (Azure WebJobs or equivalent), executes a single task by name, then exits.

Role in System

Support Operations

Keeps on-call engineers and support leads informed about ticket volume and SLA trends without requiring manual database queries.

Email Pipeline

Produces email messages as Service Bus messages consumed by the EmailPublisher job, keeping email dispatch decoupled from report generation.

Jobs Infrastructure

Extends JsonConfigurationJob from NuGet.Jobs.Common, inheriting standard argument parsing, DI container setup, SQL connection management, and Application Insights telemetry.

Support Request DB

Queries the [dbo].[Issues], [dbo].[History], and [dbo].[Admins] tables in the Gallery support-request SQL database. No ORM is used — all queries are raw ADO.NET via SqlCommand.

Key Files and Classes


Dependencies

NuGet Packages (direct, via NuGet.Jobs.Common)

Internal Project References


Notable Patterns and Implementation Details

Task dispatch by reflection. ScheduledTaskFactory resolves the concrete task class entirely at runtime using Type.GetType($"NuGet.SupportRequests.Notifications.Tasks.{taskName}") and Activator.CreateInstance. Adding a new task requires no factory changes — only a new class in the Tasks namespace implementing IScheduledTask with the three-argument constructor (InitializationConfiguration, Func<Task<SqlConnection>>, ILoggerFactory).
Embedded resource templates with CSS inlining. HTML email templates (OnCallSummary.html, WeeklySummary.html) and the shared EmailStyles.css are all compiled as embedded resources. NotificationTemplateProvider inlines the CSS into each HTML template on first load and caches the result statically for the process lifetime. Placeholder substitution is done via simple string.Replace on named tokens defined in HtmlPlaceholders.
No ORM — raw ADO.NET with NOLOCK hints. All SQL queries use WITH (NOLOCK) table hints. This means reads are dirty and may return uncommitted data. The queries are stored as string constants in SqlQuery.cs and suppressed under CA2100 (SQL injection review) with a #pragma warning disable. Input parameters are correctly parameterised, so injection risk is low, but the suppression warrants review if queries are ever modified.
No plaintext email fallback. SupportRequestNotificationEmailBuilder.GetBody(EmailFormat format) returns the HTML body regardless of the format argument. The inline comment acknowledges this as a known gap. Recipients using plaintext-only email clients will receive raw HTML.
Week-over-week trend arithmetic uses safe division. WeeklySummaryNotification.GetDeltaPercentageSafe returns double.PositiveInfinity, double.NegativeInfinity, or double.NaN instead of throwing when the denominator is zero. Downstream callers in HtmlSnippets.GetTrendPercentageString must handle these sentinel values correctly.
IssueStatusId = 3 means Resolved. The constant 3 is used directly in several SQL WHERE clauses as well as in the IssueStatusKeys enum. When reading queries in SqlQuery.cs, the numeric literal 3 is always the Resolved status.