feat(tenancy): resolve active club from request subdomain
Add row-based multi-tenancy plumbing keyed on Club as the tenant root: - ClubTenantMiddleware maps the request's subdomain to a Club by slug, storing it on request.club and in a contextvar so service-layer code and management commands can read it via get_current_club(). Resolution honours CLUBMANAGER_BASE_DOMAIN (e.g. ajax-united.clubmanager.app), falling back to generic slug.example.com hosts, and ignores the bare base domain, www, and unknown slugs. - Club gains a unique slug (auto-derived from name on save) plus a ClubManager.current() accessor for the active tenant. - ClubScopedModel gets a TenantQuerySet (.for_club()/.current()) and auto-fills club from the active context on save. Contextvar helpers live in club.tenancy; Club is imported lazily there and in clubmanager.base to avoid an import cycle with club.models. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -55,10 +55,16 @@ MIDDLEWARE = [
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"club.tenancy.ClubTenantMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
# Multi-tenancy: base domain whose subdomains resolve to a club, e.g.
|
||||
# "ajax-united.clubmanager.app" -> the club with slug "ajax-united". Leave
|
||||
# unset to fall back to generic "slug.example.com" (3+ label) resolution.
|
||||
CLUBMANAGER_BASE_DOMAIN = config("CLUBMANAGER_BASE_DOMAIN", default="")
|
||||
|
||||
ROOT_URLCONF = "clubmanager.urls"
|
||||
|
||||
AUTH_USER_MODEL = "authentication.User"
|
||||
|
||||
Reference in New Issue
Block a user