Complete the Season model:
- name property renders the start/end years as a "YY-YY" label (e.g.
"25-26") via strftime %y, and __str__ now returns it.
- get_current(date) returns the active club's season covering the given
date (today by default), inclusive of both boundaries, scoped through
the tenant queryset so it never crosses clubs.
Rename the tenant queryset's current() to current_club() for clarity and
update callers/tests. Cover the new behaviour; tenancy modules stay at
100%.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
- Split the accounts app into new authentication and club apps for better separation of concerns.
- Migrate the custom User, Member, and Family models to the authentication app.
- Introduce Club and ClubMembership models in the club app.
- Refactor Family model to use UUID as the primary key and consolidate family-role relationships into a new FamilyMembership model.
- Update tests, managers, and migrations to align with the new structure.