9.8 KiB
Club tenancy and account access
Implemented for the requested model. On October 20, 2026, the development
database was backed up and migrated, and james.richie@onesourceits.com was
promoted to Super System Administrator. Its existing password was preserved;
old sessions were revoked. See the
development migration report for backup,
restoration and live verification results.
Access model
| Capability | Super System Administrator | Club Administrator | User/member |
|---|---|---|---|
| View clubs | All | Assigned clubs | Active joined clubs |
| View member records | All | All members of managed clubs | Own membership only |
| Invite members | Any club | Managed clubs | No |
| Appoint club administrators | Yes | No | No |
| Create a new club | Yes | No | No |
| Edit/archive/reactivate club | Any club | Managed clubs | No |
| Seasons, dues, payments, corrections/reversals | Any club | Managed clubs | Read own dues/history only |
| Export roster/financial data | Any club | Managed clubs | No |
| Tickets | All clubs | All tickets in managed clubs | Submit/read/reply to own tickets |
| Global accounts, credentials, notes, settings, journal | Yes | No | No |
An administrator assigned to two clubs can manage both. An administrator in one club who is an ordinary member of another gets only member access in that other club. Administrators sharing a club see the same membership and invitation data, regardless of who issued the invitation. An account can belong to several clubs; deactivating membership in one club leaves its global account and other club memberships intact.
Club administration is stored on club_memberships.membership_role, not inferred
from the old global Administrator or System Administrator label. Those old
labels do not confer cross-club access. The exact global
Super System Administrator role grants platform access. Only a current Super
System Administrator can assign global privileges or appoint club administrators.
The last active Super System Administrator and the last active administrator
membership in a club cannot be disabled/demoted through their respective controls.
Members get club name/seasons and their own membership, dues, payment and correction history. Other members' contact information and private tickets are not shown to them. Site alerts, dropdowns, popovers and account notes remain platform-wide features, editable only by the Super System Administrator; they are not private club content editors.
Invitations
Club administrators use Invite to this club within their club workspace, instead of the global Users directory or a username/email lookup of existing accounts. This prevents searching another tenant's accounts or changing shared login credentials. Your Super System Administrator retains global user controls and can directly assign an existing verified account when provisioning a club.
An invitation records the club, submitted email, inviter, role and seven-day expiration. It does not create an account, reset a password, or grant immediate access. The recipient signs up or signs in using that email, verifies mailbox ownership using the existing verification/reset process, opens Invitations, and explicitly accepts. A verified, signed-in matching email is required; an invitation ID alone is not a bearer credential. Consequently an invitation URL does not need to contain a secret token.
Invitations cannot be accepted by another account, after expiry/revocation, or after the inviter loses authority. Acceptance and revocation serialize on the club record. Repeated acceptance does not duplicate membership. Only the Super System Administrator can issue administrator invitations. Deactivating an existing membership revokes its outstanding invitations for that club. Sending again requires a one-minute wait; per-actor/club limits also apply.
Delivery uses the configured trusted HTTPS ApplicationUrl; the email explains
signup, verification and acceptance. Failed delivery leaves a visible warning
and a pending invitation that the recipient can find after signing in. An
administrator can retry sending to the same email after a minute. Development
email delivery is not claimed to work by these tests.
Tickets
Members submit a subject and message from Tickets or My tickets inside their club. Only the author, assigned club administrators and the Super System Administrator can see that ticket or its messages. Members may reply to open tickets; administrators can reply, close and reopen them. Archived clubs keep their history but do not accept new tickets/replies. Subject/message limits are 200/8,000 Unicode characters. Text is escaped on display, requests require CSRF protection, and submission/reply rates are limited.
Tickets and replies commit with mandatory audit records. Successful submissions redirect to a read page, so refreshing does not resubmit the form. Ticket lists use 25-item pages with subject search; count queries and every page retain the same club/author restrictions. Older authorized tickets are discoverable through page navigation or search. This feature supports text discussions, not attachments or email notifications.
Migration and rollout
Use a protected maintenance window for the coordinated code/schema change:
- Back up the target database and retain the matching application release.
- Ensure migrations 001–003 are already applied and the designated existing
login
james.richie@onesourceits.comis active. This migration does not create an owner account or guess a replacement if that email is missing. - With migration credentials, set
HCR_SUPER_ADMIN_EMAILtojames.richie@onesourceits.comand runphp bin/migrate-tenants.php. Remove that environment variable afterward; it is a one-time explicit bootstrap selection, not a runtime setting. - Deploy this version with all new files and the updated runtime grants in
deploy/runtime-grants.sql.example. Runbin/check-health.php. - Sign in again as the designated owner. Promotion revokes existing sessions and outstanding reset/verification tokens. Club memberships are not promoted automatically: open each club, assign its intended existing verified accounts if needed, and set their Club role to Administrator. Alternatively, invite an administrator and have them accept.
- Verify each club administrator/member with separate sessions, then reopen service. Test production inbox delivery separately.
The migration adds membership_role and three InnoDB tables:
club_invitations, club_tickets, club_ticket_messages. Existing memberships
default to member; clubs without an explicit administrator remain visible and
manageable by the Super System Administrator. No historical financial records or
memberships are removed. Club display names no longer need to be globally unique;
club IDs remain the tenant boundary. Rerunning the migration is safe and does not
re-promote an already promoted account or repeatedly revoke sessions.
Do not deploy the new application by itself against the old schema: health checks will reject missing tenancy tables. If rollback is required after using the new roles, restore the matching backed-up database and release together; older code does not understand the new Super System Administrator role.
Implementation and verification
TenantAccess.phpcentralizes current database-backed platform/club permissions.Base.phprestricts global routes and passes the navigation capability to XSL.RosterService.php,LedgerService.phpandRosterReports.phpenforce the selected club's access for reads, writes and downloads. Membership changes and permission checks participate in club transactions. Account services enforce Super System Administrator access and protect the final platform administrator.ClubInvitations.php,ClubTickets.phpand the new Roster screens implement the invitation and ticket flows.xsl/content.xslshows scoped navigation.migrations/004_tenants.sql,bin/migrate-tenants.php, runtime grants, release packaging, role options and application cache version (1.02) were updated.- Added separate migration, service, HTTP and browser tenancy suites; expanded concurrency coverage for invitation acceptance and the last club administrator. Test fixtures use generated scratch databases, capture invitation mail or force SMTP to a closed loopback port, and promote only a test account.
Verification passed: 497 checks plus seven concurrency scenarios, including the complete prior regression suite and the final owner-assignment browser check.
| Suite | Passed checks |
|---|---|
| Existing authentication, maintenance, security, ledger, browser, backup and release suites | 374 |
| Tenant migration | 8 |
| Tenant services | 32 |
| Tenant HTTP access and isolation | 75 |
| Tenant browser workflows, including owner assignment | 8 |
Source checks passed for 49 PHP files, 56 application JavaScript files and 39 XSL stylesheets. Concurrency scenarios cover defaults, payment limits, financial retries, the final platform administrator, invitation acceptance and the final club administrator. The disposable local test databases were removed and their loopback server stopped. No development records, real recipients or live account privileges were changed.
That regression run preceded the separately authorized development migration. The subsequent migration and 61 development acceptance checks are documented in the linked migration report; temporary verification data was removed afterward.
See the tenant repair follow-up for the invitation reactivation policy, bounded transaction retries and Unicode-aware ticket forms.
Mandatory administrator MFA and capacity controls require the security/capacity migration and deployment steps. Apply them before running this release.