Coach lineup polish, referee level/position delete, feature-flag nav gating, per-job pause

- Coach line-up screen: more breathing room above the sheet, brighter event
  subtitle, and the "Schedule" button now matches the date input's height.
- Positions and referee levels can now be deleted from Settings (blocked with
  a friendly message if still in use on a roster/referee profile/inheritance
  chain).
- The Evaluations nav placeholder is now gated on the formbuilder flag, same
  as Forms itself, since the design reuses formbuilder underneath.
- Control panel: each scheduled platform job can now be paused/resumed
  individually (features.models.JobToggle), independent of the platform-wide
  Maintenance lock.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 11:17:46 +02:00
parent e621086f37
commit 1365dcf18e
23 changed files with 422 additions and 3029 deletions

View File

@@ -13,7 +13,7 @@ from waffle import flag_is_active, get_waffle_flag_model
from club.models import Club
from .jobs import JOB_REGISTRY
from .models import JobRun, Maintenance
from .models import JobRun, JobToggle, Maintenance
Flag = get_waffle_flag_model()
User = get_user_model()
@@ -322,3 +322,34 @@ class JobRunTests(TestCase):
self.untracked_task.apply()
self.assertFalse(JobRun.objects.filter(name="features.tests.untracked").exists())
class JobToggleTests(TestCase):
"""Per-job pause/resume switch -- see features.models.JobToggle and its use in
events/billing/club's scheduled tasks (each checks JobToggle.is_enabled(name)
right alongside the existing Maintenance.is_on() gate)."""
def setUp(self):
# Same reasoning as MaintenanceModeTests -- the toggle's cache isn't
# rolled back with the test transaction.
cache.clear()
self.addCleanup(cache.clear)
def test_a_job_with_no_row_is_enabled_by_default(self):
self.assertTrue(JobToggle.is_enabled("events.tasks.extend_event_series"))
def test_disabling_a_job(self):
JobToggle.set_enabled("events.tasks.extend_event_series", False)
self.assertFalse(JobToggle.is_enabled("events.tasks.extend_event_series"))
def test_re_enabling_a_job(self):
JobToggle.set_enabled("events.tasks.extend_event_series", False)
JobToggle.set_enabled("events.tasks.extend_event_series", True)
self.assertTrue(JobToggle.is_enabled("events.tasks.extend_event_series"))
def test_toggling_one_job_does_not_affect_another(self):
JobToggle.set_enabled("events.tasks.extend_event_series", False)
self.assertTrue(JobToggle.is_enabled("events.tasks.send_deadline_reminders"))