Add viewer-range categories, nomination tracking, dynamic showact form, session timeout, share URLs, and workflow-per-season

Features:
- Category viewer ranges + subcategory templates (admin group modal, tree workspace)
- Nomination enrichment via TwitchTracker API (NominationEnrichmentService,
  TwitchTrackerViewerStatsProvider) with admin tracking rules editor
- Nomination group tracker: CategoryGroupName as primary identifier,
  CategoryId stays as nullable legacy field; StreamerIdentity table
- Dynamic showact application form builder (AdminShowactFormBuilder,
  ShowactApplicationSchedule)
- Session idle timeout setting (AdminSessionTimeoutCard)
- Share URLs for X and Discord (SiteSettings, public extras)
- Workflow rules now stored per season (falls back to global SiteSettings)
- New admin routes: settings/access, settings/workflows, tracking-rules
- New admin review workspace with subcategory tabs
- AdminCategoriesView rebuilt with group/subcategory modals

Migrations (all additive):
- AddShareUrls, AddShowactDynamicForm, AddCategoryViewerRanges,
  AddSessionIdleTimeoutSettings, AddSeasonSubcategoryTemplates,
  AddNominationGroupTrackerIdentity, AddShowactApplicationSchedule,
  AddSeasonWorkflowRulesJson

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
AzuTear
2026-06-28 23:32:21 +02:00
parent 4b2c5fa15d
commit b53c7fb736
178 changed files with 28933 additions and 1908 deletions
@@ -4,6 +4,8 @@ public sealed record AdminSiteSettingsResponse(
string HostDisplayName,
string HostTagline,
string NewsletterUrl,
string ShareXUrl,
string ShareDiscordUrl,
string PrivacyEmail,
string PrivacyPolicyContent,
string? PrivacyPolicyUpdatedBy,
@@ -17,12 +19,15 @@ public sealed record AdminSiteSettingsResponse(
string ShowactsUrl,
string ShowactsContent,
IEnumerable<PublicSocialLinkDto> SocialLinks,
IEnumerable<FaqItemDto> Faq);
IEnumerable<FaqItemDto> Faq,
string ShowactFormSchemaJson);
public sealed record UpdateSiteSettingsRequest(
string HostDisplayName,
string HostTagline,
string NewsletterUrl,
string ShareXUrl,
string ShareDiscordUrl,
string PrivacyEmail,
string PrivacyPolicyContent,
string ImprintUrl,
@@ -34,7 +39,8 @@ public sealed record UpdateSiteSettingsRequest(
string ShowactsUrl,
string ShowactsContent,
PublicSocialLinkDto[] SocialLinks,
FaqItemDto[] Faq);
FaqItemDto[] Faq,
string? ShowactFormSchemaJson = null);
public sealed record AdminOperationalSettingsResponse(
bool DemoLoginManagedByDatabase,
@@ -49,6 +55,7 @@ public sealed record AdminOperationalSettingsResponse(
bool TwitchClientSecretSet,
string TwitchRedirectUri,
string TwitchScope,
int SessionIdleTimeoutHours,
bool MaintenanceModeEnabled,
string MaintenanceTitle,
string MaintenanceMessage);
@@ -59,6 +66,9 @@ public sealed record AdminOptionalFeatureSettingsResponse(
bool ClipAdminMenuVisible,
string ClipSubmissionDisabledMessage,
bool ShowactApplicationsEnabled,
DateOnly? ShowactApplicationStartsAt,
DateOnly? ShowactApplicationEndsAt,
bool ShowactApplicationsOpenNow,
string ShowactApplicationDisabledMessage,
bool SponsorsVisible);
@@ -68,6 +78,8 @@ public sealed record UpdateOptionalFeatureSettingsRequest(
bool ClipAdminMenuVisible,
string ClipSubmissionDisabledMessage,
bool ShowactApplicationsEnabled,
DateOnly? ShowactApplicationStartsAt,
DateOnly? ShowactApplicationEndsAt,
string ShowactApplicationDisabledMessage,
bool SponsorsVisible);
@@ -81,6 +93,71 @@ public sealed record UpdateOperationalSettingsRequest(
string? TwitchClientSecret,
string TwitchRedirectUri,
string TwitchScope,
int SessionIdleTimeoutHours,
bool MaintenanceModeEnabled,
string MaintenanceTitle,
string MaintenanceMessage);
public sealed record AdminTrackingSourceDto(
string ProviderKey,
string ProviderLabel,
string BaseUrl,
string NotesSummary,
bool ShowManualReviewNotesInReview);
public sealed record AdminTrackingMetricRuleDto(
string Key,
string Label,
bool Enabled,
string SourceSupport,
string Description,
bool RequiredForAutoClassification,
bool ShowInReview,
bool ShowInAdminSummary,
bool ManualOverrideAllowed,
string WindowKey,
string[] AutoSupportedWindowKeys,
string? ProviderFieldKey,
int? TopCount,
int? MinPrimaryCategorySharePercent,
int? MinPrimaryCategoryHours,
int? MaxDistinctCategoriesBeforeFlag,
string[] IgnoredCategories,
bool MatchAwardCategoryAgainstTopCategories,
bool FlagIfAwardCategoryNotInTopX,
bool FlagIfCategorySpreadTooWide,
bool FlagIfNoCategoryContextAvailable,
int? MinValue,
int? MaxValue);
public sealed record AdminTrackingFlagRuleDto(
string Key,
string Label,
bool Enabled,
string Severity,
string Description,
bool AutoTriggerEnabled,
bool RequiresManualReview,
bool BlocksApproval,
bool AdminNoteRequiredOnOverride);
public sealed record AdminTrackingRulesResponse(
AdminTrackingSourceDto Source,
AdminTrackingMetricRuleDto[] ImportantMetrics,
AdminTrackingMetricRuleDto[] OptionalMetrics,
AdminTrackingFlagRuleDto[] Flags,
string ManualReviewNotes);
public sealed record UpdateTrackingRulesRequest(
AdminTrackingSourceDto Source,
AdminTrackingMetricRuleDto[] ImportantMetrics,
AdminTrackingMetricRuleDto[] OptionalMetrics,
AdminTrackingFlagRuleDto[] Flags,
string ManualReviewNotes);
public sealed record UpdateTrackingSourceRequest(
AdminTrackingSourceDto Source);
public sealed record UpdateTrackingReviewNotesRequest(
string ManualReviewNotes,
bool ShowManualReviewNotesInReview);