feat(club): archive clubs instead of deleting them

Add Club.archived_at with active()/archived() managers, archive() and
restore(). An archived club stops resolving in ClubTenantMiddleware, so its
subdomain behaves as unknown — archiving is a real deactivation, not a
cosmetic flag — while every row it owns is retained.

There is no hard-delete path, deliberately. A club with any data cannot be
deleted anyway (ClubMembership PROTECTs its Season, and the shop chain
PROTECTs more), and invoices generally must be kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 15:29:10 +02:00
parent 10736fd5ee
commit ebb8bc3db1
5 changed files with 124 additions and 7 deletions

View File

@@ -67,7 +67,8 @@ class ClubTenantMiddleware:
if not subdomain:
return None
return Club.objects.filter(slug=subdomain).first()
# Archived clubs stop resolving: their subdomain behaves as unknown.
return Club.objects.active().filter(slug=subdomain).first()
@staticmethod
def get_subdomain(request) -> str | None: