Files
huntingclubroster/MEMBER-ACTIONS-2026-10-21.md
T

64 lines
3.6 KiB
Markdown
Raw Normal View History

# Administrator actions on member summaries
Administrators can now work directly from a member summary:
- Edit membership opens a prefilled dialog for membership status and join date.
Super Administrators can also change the club role. Club administrators cannot
edit protected administrator memberships or grant administrator roles.
- Record season dues opens a dialog tied to the selected member. Seasons are
drawn only from the selected club, with bounded paging for longer season lists.
Inactive memberships do not receive an add-dues action.
- Record payment appears beside each season with an outstanding balance. The
dialog is tied to that dues record and membership and supports amount, received
date, payment method and reference.
Dialogs identify the member, keep validation errors and entered values in place,
and use the existing cancellation and focus behavior. Successful saves return to
the same member summary, preserve its page selections, show a success notice and
refresh membership details and financial totals. All editing fields remain hidden
until an action is opened. Members retain their read-only summaries, and archived
clubs expose no write dialogs.
## Security and implementation
`MemberSummary.php` now handles an explicit allowlist of member, charge and
payment POST actions. It checks CSRF, club management permission, club status,
the selected membership and matching form identifiers before calling the existing
membership/ledger services. It returns a fixed local summary URL for successful
modal submissions; arbitrary return URLs are not accepted.
`Base.php` applies the existing recent-MFA requirement to membership edits on the
new endpoint. Existing server-side role restrictions, last-administrator
safeguards, audit requirements, duplicate-dues checks, payment idempotency and
overpayment checks remain active.
`LedgerService.php` accepts an optional membership constraint for payment writes.
The constraint is checked against the locked dues row inside the payment
transaction, before any write or idempotent success. A payment posted from one
member summary cannot target another member's dues, including within the same
club. Existing club-page callers retain their previous behavior.
`ClubFormModals.php` recognizes the member-summary form action and renders the
existing labelled Bootstrap dialogs. No new JavaScript dependency, database
schema change or migration is required.
Tests cover complete browser saves from all three dialogs, same-member redirects,
updated totals, privacy, CSRF, target tampering, audit rollback, archived clubs,
duplicate dues, foreign seasons, wrong-member payments, idempotency, overpayments,
administrator role restrictions and recent MFA. Test data is disposable and
external email is disabled.
Completed validation passed 195 targeted checks: 22 new action HTTP checks,
22 member-summary HTTP checks, 26 tenant browser checks, 33 general browser
checks, 24 MFA/session HTTP checks, 41 security/capacity service checks,
11 paging/export HTTP checks and 16 deployment tooling checks. Source validation
passed for 67 PHP files, 58 JavaScript files and 39 XSL stylesheets.
The four application files were deployed to development and their hashes
verified. A protected temporary probe confirmed the new summary forms, member
dialog rendering and membership-scoped payment API, then was removed. Prior
files were saved under
`.tools/deployment-backups/member-actions-7033d88c563c4b8ba6399f423cef1601`.
No existing development database records were changed. Disposable databases
were removed and the isolated local database server was stopped after testing.