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:
@@ -19,6 +19,7 @@ public static class WorkflowRuleSettings
|
||||
public const string MaxCandidateAppearances = "max_candidate_appearances";
|
||||
public const string MaxWinnerPlacements = "max_winner_placements";
|
||||
public const string WinnerRequiresClip = "winner_requires_clip";
|
||||
public const string RecommendedNominatorsPerSubcategory = "recommended_nominators_per_subcategory";
|
||||
|
||||
public static WorkflowRuleSetting[] Defaults { get; } =
|
||||
[
|
||||
@@ -26,11 +27,28 @@ public static class WorkflowRuleSettings
|
||||
new(MaxCandidateAppearances, "Kandidaturen pro Person", true, 2, "warn", "Warnt oder blockiert, wenn dieselbe Person in zu vielen Kategorien final auftaucht."),
|
||||
new(MaxWinnerPlacements, "Gewinnerplätze pro Person", true, 1, "block", "Verhindert oder warnt, wenn dieselbe Person mehrfach als Gewinner:in gesetzt wird."),
|
||||
new(WinnerRequiresClip, "Gewinner braucht Clip-Link", true, 1, "block", "Verhindert oder warnt, wenn ein Gewinner ohne gepflegten YouTube-/Twitch-Clip gesetzt wird."),
|
||||
new(RecommendedNominatorsPerSubcategory, "Empfohlene Nominierer pro Unterkategorie", true, 4, "warn", "Zeigt in der Kategorie-Übersicht an, ab wann eine Unterkategorie nominierungsseitig gut getragen ist. Diese Regel blockiert nichts."),
|
||||
];
|
||||
|
||||
public static WorkflowRuleSetting[] Read(SiteSettings? settings)
|
||||
{
|
||||
var storedRules = Parse(settings?.WorkflowRulesJson);
|
||||
return Read(storedRules);
|
||||
}
|
||||
|
||||
public static WorkflowRuleSetting[] Read(Season? season, SiteSettings? settings)
|
||||
{
|
||||
var seasonRules = Parse(season?.WorkflowRulesJson);
|
||||
if (seasonRules.Length > 0)
|
||||
{
|
||||
return Read(seasonRules);
|
||||
}
|
||||
|
||||
return Read(settings);
|
||||
}
|
||||
|
||||
private static WorkflowRuleSetting[] Read(WorkflowRuleSetting[] storedRules)
|
||||
{
|
||||
return Defaults
|
||||
.Select(defaultRule =>
|
||||
{
|
||||
@@ -98,6 +116,11 @@ public static class WorkflowRuleSettings
|
||||
_ => fallback.Mode,
|
||||
};
|
||||
|
||||
if (string.Equals(fallback.Key, RecommendedNominatorsPerSubcategory, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
mode = "warn";
|
||||
}
|
||||
|
||||
return rule with
|
||||
{
|
||||
Key = fallback.Key,
|
||||
|
||||
Reference in New Issue
Block a user