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
@@ -30,6 +30,7 @@ export function useAdminOperationalSettings() {
twitchClientId: '',
twitchRedirectUri: '',
twitchScope: '',
sessionIdleTimeoutHours: 3,
maintenanceModeEnabled: false,
maintenanceTitle: fallbackMaintenanceTitle,
maintenanceMessage: fallbackMaintenanceMessage,
@@ -89,6 +90,12 @@ export function useAdminOperationalSettings() {
? demoCredentialsComplete.value ? 'warning' : 'danger'
: 'good',
},
{
label: 'Session Timeout',
value: `${operationalForm.sessionIdleTimeoutHours}h`,
note: `Logout nach ${operationalForm.sessionIdleTimeoutHours} Stunden ohne Aktivitaet.`,
tone: operationalForm.sessionIdleTimeoutHours >= 3 ? 'good' : 'danger',
},
{
label: 'Wartungsmodus',
value: operationalForm.maintenanceModeEnabled ? 'Aktiv' : 'Aus',
@@ -126,6 +133,7 @@ export function useAdminOperationalSettings() {
operationalForm.twitchClientId = response.twitchClientId
operationalForm.twitchRedirectUri = response.twitchRedirectUri
operationalForm.twitchScope = response.twitchScope
operationalForm.sessionIdleTimeoutHours = response.sessionIdleTimeoutHours
operationalForm.maintenanceModeEnabled = response.maintenanceModeEnabled
operationalForm.maintenanceTitle = response.maintenanceTitle
operationalForm.maintenanceMessage = response.maintenanceMessage
@@ -148,6 +156,7 @@ export function useAdminOperationalSettings() {
twitchClientId: operationalForm.twitchClientId,
twitchRedirectUri: operationalForm.twitchRedirectUri,
twitchScope: operationalForm.twitchScope,
sessionIdleTimeoutHours: operationalForm.sessionIdleTimeoutHours,
twitchClientSecretInput: twitchClientSecretInput.value,
maintenanceModeEnabled: operationalForm.maintenanceModeEnabled,
maintenanceTitle: operationalForm.maintenanceTitle,
@@ -208,6 +217,11 @@ export function useAdminOperationalSettings() {
return false
}
if (!Number.isInteger(operationalForm.sessionIdleTimeoutHours) || operationalForm.sessionIdleTimeoutHours < 3) {
operationalError.value = 'Session-Timeout muss mindestens 3 Stunden betragen.'
return false
}
return true
}
@@ -235,7 +249,7 @@ export function useAdminOperationalSettings() {
twitchClientSecretInput.value = ''
await loadOperationalSettings({ silent: true })
clearSiteStatusCache()
operationalSuccess.value = 'Demo-Zugang und Wartungsmodus wurden gespeichert.'
operationalSuccess.value = 'Demo-Zugang, Session-Timeout und Wartungsmodus wurden gespeichert.'
} catch (error) {
operationalError.value = error instanceof ApiRequestError
? error.message
@@ -254,6 +268,7 @@ export function useAdminOperationalSettings() {
operationalForm.twitchClientId,
operationalForm.twitchRedirectUri,
operationalForm.twitchScope,
operationalForm.sessionIdleTimeoutHours,
twitchClientSecretInput.value,
operationalForm.maintenanceModeEnabled,
operationalForm.maintenanceTitle,