gapguide-api / apps /resources /management /commands /check_checkpoints.py
arifRB's picture
Deploy GapGuide backend (Docker)
ffd36e0 verified
Raw
History Blame Contribute Delete
1.79 kB
"""Audit: every COURSE/VIDEO resource should carry >=2 checkpoints.
Read-only. Exits nonzero (listing offenders) when any in-scope resource has
fewer, so it can gate CI / a release check. DOCS and ARTICLE are exempt — a
reference site's table of contents isn't a learning sequence, so those keep the
single manual-completion checkbox.
"""
import sys
from django.core.management.base import BaseCommand
from django.db.models import Count
from apps.resources.models import Resource
SCOPED_TYPES = ("COURSE", "VIDEO")
class Command(BaseCommand):
help = (
"Verify every COURSE/VIDEO resource has at least --min checkpoints "
"(default 2). Exits 1 and lists offenders if not. DOCS/ARTICLE exempt."
)
def add_arguments(self, parser):
parser.add_argument(
"--min", type=int, default=2,
help="Minimum checkpoints required per COURSE/VIDEO resource.",
)
def handle(self, *args, **options):
minimum = options["min"]
scoped = Resource.objects.filter(type__in=SCOPED_TYPES)
total = scoped.count()
offenders = list(
scoped.annotate(n=Count("checkpoints"))
.filter(n__lt=minimum)
.order_by("type", "title")
)
if not offenders:
self.stdout.write(self.style.SUCCESS(
f"OK: all {total} COURSE/VIDEO resources have >={minimum} checkpoints."
))
return
self.stdout.write(self.style.ERROR(
f"{len(offenders)} of {total} COURSE/VIDEO resources have "
f"<{minimum} checkpoints:"
))
for r in offenders:
self.stdout.write(
f" [{r.type}] {r.title} ({r.provider}) - {r.n} checkpoint(s)"
)
sys.exit(1)