coulomb-social/coulomb_social/apps/spaces/services.py
tegwick be32432d39 Add Space metadata model and provisional Forgejo content ADR
Introduce tenant-scoped Space/SpaceMembership with list and detail views.
Document markdown-in-Forgejo as content SoR (ADR-0002). Run migrations on
container start so app.coulomb.social picks up the new tables.
2026-08-12 01:30:05 +02:00

39 lines
1.2 KiB
Python

"""Space queries scoped by tenant membership."""
from __future__ import annotations
from django.db.models import Q, QuerySet
from coulomb_social.apps.members.models import Member
from .models import Space, SpaceMembership
def spaces_for_member(member: Member | None) -> QuerySet[Space]:
"""Spaces visible to this member (same tenant, active).
Explicit SpaceMembership grants access; if none exist for the tenant yet,
all active tenant spaces are listed (operator-seeded MVP). Once any
memberships exist for the tenant, only membership + created_by apply.
"""
if member is None:
return Space.objects.none()
qs = Space.objects.filter(tenant_id=member.tenant_id, is_active=True)
tenant_has_memberships = SpaceMembership.objects.filter(
space__tenant_id=member.tenant_id
).exists()
if not tenant_has_memberships:
return qs.order_by("title", "slug")
return (
qs.filter(Q(memberships__member=member) | Q(created_by=member))
.distinct()
.order_by("title", "slug")
)
def get_space_for_member(member: Member | None, slug: str) -> Space | None:
if member is None:
return None
return spaces_for_member(member).filter(slug=slug).first()