Test Cases: Admin Member Controls

Module: Membership & Profiles - Admin Controls

Backend Endpoints (mounted at /api/membership; legacy alias /membership):

Frontend: frontend/pwa-app/src/pages/AdminMembersPage.tsx + components/members/ (MemberDetailPanel, MemberDetailHeader, ChangeStatusModal, ManageRolesModal).

UI model: /admin/members is a list + split-view detail panel. Click a member → the right panel opens (URL gains ?selected=<id>). Admin actions live in the detail header's "Actions ▾" menu (Reset Password / Change Status / Manage Roles / Change Membership Type) and an "Edit Profile" button (ADMIN only → /admin/members/:id/edit). There are no per-row Suspend/Deactivate buttons.

Prerequisites

Test Cases

TC-ADM-01: List Members

StepActionExpected Result
1Sidebar Members → All Members (/admin/members).KPI row (Active / Overdue / Due Soon / Inactive·Suspended) + member list load.
2Click a member row.Right detail panel opens with tabs: Profile, Billing, Events, Member ID (ADMIN). URL gains ?selected=<id>.
3Note the top-right page action.It is "Import members" (→ /admin/members/import). There is no "Add Member" button.

TC-ADM-02: Suspend a Member

StepActionExpected Result
1Open an ACTIVE member → Actions ▾ → Change Status."Change Member Status" modal; offers Suspend Member / Deactivate Member.
2Select Suspend Member; type a required Reason; confirm.Calls POST /api/membership/members/:id/suspend. Status → SUSPENDED; sessions revoked; notification email sent.
3Check the member's audit log (Member ID tab / audit).Suspension recorded with actor + reason.

TC-ADM-03: Reactivate a Member

StepActionExpected Result
1Open a SUSPENDED member → Actions ▾ → Change Status → Reactivate Member (no reason) → confirm.Calls POST /api/membership/members/:id/reactivate. Status → ACTIVE.
2(For an EXPIRED member) Reactivate.Status → ACTIVE but expiry NOT reset (OQ-RET-16 / #151) — see TC-MEM-007 detailed.

TC-ADM-04: Edit Profile incl. Joined Date (#184)

StepActionExpected Result
1Open a member → "Edit Profile" (ADMIN only) → /admin/members/:id/edit.Full edit form loads.
2In "Membership Information", change "Member Since (Joined Date)" (date picker, max = today). Save.Calls PATCH /api/membership/members/:id with joinedAt. Saved; change written to the audit log.

TC-ADM-05: Manage Roles

StepActionExpected Result
1Open a member → Actions ▾ → Manage Roles (ADMIN only)."Manage Roles" modal with 6 built-in staff-role cards (see RBAC §TC-RBAC-019).
2Check a role (e.g. Officer) → Save Roles.Calls PUT /api/membership/members/:id/roles; chips update (MEMBER auto-retained).

TC-ADM-06: Change Membership Type

StepActionExpected Result
1Open a member → Actions ▾ → Change Membership Type → pick a type → save.Calls PUT /api/membership/members/:id/membership-type; type updates.

TC-ADM-07: Approve / Reject a Pending Application

StepActionExpected Result
1Open a member whose status is PENDING_APPROVAL.Inline Approve + Reject buttons appear in the detail header.
2Approve / Reject.POST .../approve or .../reject (guard requireApproverRole). See TC-MEM-004 for the prospect/application path used by the seeded pending@demo user.

TC-ADM-08: Audit Log

StepActionExpected Result
1Open a member → Member ID tab (ADMIN) / audit view. (GET /api/membership/members/:id/audit.)Lists events: created, approved, suspended, reactivated, profile changes — with actor + timestamp.

TC-ADM-09: Non-Admin Restrictions

StepActionExpected Result
1As MEMBERSHIP_MANAGER, open a member → Actions ▾."Change Status" visible; "Manage Roles" + "Edit Profile" are not shown (ADMIN-only).
2API: PUT /api/membership/members/:id/roles as MEMBERSHIP_MANAGER.403 (lacks ADMIN:EDIT:roles).