from django.db import models class GuidePage(models.Model): class Audience(models.TextChoices): SHARED = "shared", "Shared" BUYER = "buyer", "Buyer" OPS = "ops", "Operations" ADMIN = "admin", "Administrator" AUDIENCE_PREFIXES = ( ("user-guides/index", Audience.SHARED), ("user-guides/buyer/", Audience.BUYER), ("user-guides/ops/", Audience.OPS), ("user-guides/admin/", Audience.ADMIN), ) path = models.CharField(max_length=255, unique=True) title = models.CharField(max_length=255) audience = models.CharField(max_length=20, choices=Audience.choices) content = models.TextField(blank=True, default="") updated_at = models.DateTimeField() synced_at = models.DateTimeField(auto_now=True) class Meta: ordering = ["path"] def __str__(self): return self.title @property def page_slug(self): return self.path[len("user-guides/"):] if self.path.startswith("user-guides/") else self.path def preview(self, max_chars=180): for line in self.content.splitlines(): line = line.strip() if not line or line.startswith(("#", "-", ">", "|", "*", "![", "```", "<")): continue text = line.replace("**", "").replace("`", "").replace("*", "").strip() if text: return text[:max_chars] return "" @classmethod def map_audience(cls, path): for prefix, audience in cls.AUDIENCE_PREFIXES: if path == prefix or path.startswith(prefix): return audience return None # The help centre is scoped by PORTAL first, then by role. Which guides are # listed depends on which portal you are standing in, not only on who you are: # an admin browsing the buyer portal sees the buyer guides, because it is the # buyer portal. The admin-only guides never surface there. AUDIENCES_BY_PORTAL = { "portal": frozenset({GuidePage.Audience.SHARED, GuidePage.Audience.BUYER}), "ops": frozenset({GuidePage.Audience.SHARED, GuidePage.Audience.OPS}), } # Extra audiences unlocked by ROLE, per portal. Admin guides are ops-side # material, so they are only ever added inside the ops portal. ADMIN_EXTRA_AUDIENCES = { "ops": frozenset({GuidePage.Audience.ADMIN}), } def allowed_audiences(portal, role=None, is_superuser=False): """Guide audiences visible in `portal` ("portal" or "ops") for this user.""" allowed = set(AUDIENCES_BY_PORTAL.get(portal, frozenset())) if is_superuser or role == "admin": allowed |= ADMIN_EXTRA_AUDIENCES.get(portal, frozenset()) return allowed