## Purpose

The super admin's view of who may use the system: creating accounts of either kind, the queue of
Google accounts awaiting approval, issuing temporary passwords, activation and withdrawal of
access, which of the two roles each account holds, and which host owns which event. It is how a
host is onboarded without anyone editing the database.

## ADDED Requirements

### Requirement: The admin roster screen (P0)
The system SHALL offer a screen, reachable only by a Super Admin, listing every admin account
with their email, name, username where they have one, **how they sign in**, role, state (pending
/ active / withdrawn), when they were first seen, when they last signed in, and how many events
they own. Accounts awaiting approval SHALL be presented distinctly from active ones, so a new
arrival is visible without searching for it. An account holding an unused temporary password
SHALL be identifiable as such, so a super admin can see that an onboarding was never completed.
The screen SHALL be absent from navigation for a Host, and its endpoints SHALL refuse a Host
regardless of that. It SHALL never display a password, a hash, or any part of either.

#### Scenario: Super admin opens the roster
- **WHEN** a Super Admin opens the admin roster
- **THEN** every admin account is listed with its kind, role, state, first-seen, last sign-in and owned-event count

#### Scenario: Pending accounts are surfaced
- **WHEN** two accounts are awaiting approval
- **THEN** they are shown apart from the active accounts and the screen indicates how many are waiting

#### Scenario: Unused temporary password is visible as a state
- **WHEN** an account was issued a temporary password and has not yet set its own
- **THEN** the roster shows that, without showing the password

#### Scenario: A host cannot see it
- **WHEN** a Host is signed in
- **THEN** the roster is not offered in navigation, and calling its endpoints directly is refused

### Requirement: Creating and editing accounts (P0)
A Super Admin SHALL be able to create an account of either kind and to edit any account.

Creating a **password account** SHALL take a username, an email, a name and a role, and SHALL
require a temporary password to be set in the same action — an account that cannot sign in has no
reason to exist yet. Usernames SHALL be unique, compared without regard to case, so two accounts
cannot differ only by capitalisation.

Creating a **Google account** SHALL take an email, a name and a role, and SHALL NOT accept a
password. The account becomes usable when its holder signs in with Google; a super admin may
create it in advance rather than waiting for the pending queue.

Editing SHALL cover name, email, username and role. An account's **kind SHALL NOT be editable**:
a Google account cannot be converted into a password account or the reverse, because either
conversion silently changes what evidence is accepted for that identity. To move someone between
kinds, a super admin creates the new account and withdraws the old one.

#### Scenario: Creating a password account
- **WHEN** a Super Admin creates a password account with a username, email, role and temporary password
- **THEN** the account exists as active, is marked as holding a temporary password, and can sign in with it

#### Scenario: Password account without a password
- **WHEN** a Super Admin submits a password account with no temporary password
- **THEN** the creation is refused

#### Scenario: Duplicate username
- **WHEN** a username is submitted that differs from an existing one only by capitalisation
- **THEN** the creation is refused as a duplicate

#### Scenario: Creating a Google account ahead of time
- **WHEN** a Super Admin creates a Google account for an address and assigns a role
- **THEN** that address signs in with Google directly, without passing through the pending queue

#### Scenario: No password on a Google account
- **WHEN** a Super Admin attempts to set a password on a Google-kind account
- **THEN** the attempt is refused

#### Scenario: Kind is fixed
- **WHEN** a Super Admin attempts to change an account's kind
- **THEN** the change is refused and the response says a new account is required instead

#### Scenario: Editing details
- **WHEN** a Super Admin edits an account's name, email, username or role
- **THEN** the change is saved and takes effect on the target's next request

### Requirement: Issuing a temporary password (P0)
A Super Admin SHALL be able to set a temporary password on any password account at any time —
at creation, and again later when someone is locked out or has forgotten theirs. This is the only
recovery path: there is no self-service forgotten-password flow, because the system has no
channel for sending an admin a reset link.

The temporary password SHALL be shown to the issuing super admin exactly once, at the moment it
is set, so it can be passed to its owner. It SHALL NOT be retrievable afterwards, SHALL NOT
appear in the roster, and SHALL NOT be written to the audit log or any other log — the audit
records **that** a temporary password was issued, by whom and for whom, and never its value.

Issuing one SHALL immediately invalidate the account's existing sessions and clear any lockout,
and SHALL mark the account as confined until its holder sets their own password.

#### Scenario: Issuing a reset
- **WHEN** a Super Admin issues a temporary password for a locked-out admin
- **THEN** the password is displayed once, the account's sessions stop working, any lockout is cleared, and the account is marked as confined

#### Scenario: Not retrievable later
- **WHEN** the super admin returns to the roster after issuing it
- **THEN** the password is nowhere on the screen and no endpoint returns it

#### Scenario: Never logged
- **WHEN** a temporary password is issued
- **THEN** the audit entry records who issued it and for whom, and contains no part of the password

#### Scenario: Not offered for a Google account
- **WHEN** a Super Admin views a Google-kind account
- **THEN** no temporary-password control is offered

### Requirement: Google accounts are administered by state and role only (P0)
For a Google-kind account, a Super Admin's controls SHALL be limited to activating, withdrawing,
assigning a role, editing name and email, and transferring event ownership. None of the password
machinery — temporary passwords, lockouts, forced changes, quality rules — SHALL apply to it or
be offered for it, because the credential lives with Google and the system holds nothing to
change.

#### Scenario: Full control over state and role
- **WHEN** a Super Admin activates, withdraws or re-roles a Google account
- **THEN** the change applies exactly as it does for a password account

#### Scenario: No password surface
- **WHEN** a Super Admin opens a Google account in the roster
- **THEN** no password field, temporary-password control or lockout state is shown

### Requirement: Approving a pending account (P0)
A Super Admin SHALL be able to activate a pending account, choosing its role in the same action.
Activation SHALL take effect on the target's next request or sign-in without them being asked to
do anything beyond signing in again. A Super Admin SHALL also be able to reject a pending account
outright, which SHALL leave a record of the rejection rather than silently deleting it, so the
same address arriving again is recognisable.

#### Scenario: Approving as a host
- **WHEN** a Super Admin activates a pending account with the Host role
- **THEN** that Google account can sign in and sees an empty set of events until one is assigned or created

#### Scenario: Approving as a super admin
- **WHEN** a Super Admin activates a pending account with the Super Admin role
- **THEN** that account can sign in and sees every event in the system

#### Scenario: Rejection
- **WHEN** a Super Admin rejects a pending account
- **THEN** that account cannot sign in, the rejection is recorded, and a later sign-in attempt by the same address does not create a fresh pending record

#### Scenario: Effect is immediate
- **WHEN** an account is activated while its holder has the sign-in page open
- **THEN** signing in from that page succeeds without any further administrative step

### Requirement: Changing role and withdrawing access (P0)
A Super Admin SHALL be able to change any account's role between the two roles, and to withdraw
an active account's access. Withdrawal SHALL take effect on the target's very next request, not
at their next sign-in, so an open session stops working immediately. Neither action SHALL delete
the account or anything it owns.

#### Scenario: Demotion applies immediately
- **WHEN** a Super Admin changes another Super Admin to Host while that person has the dashboard open
- **THEN** their next request is answered with Host permissions and Host scope

#### Scenario: Withdrawal ends the session
- **WHEN** a Super Admin withdraws access from an admin holding a valid session cookie
- **THEN** that admin's next request is rejected as unauthenticated

#### Scenario: Withdrawal preserves owned events
- **WHEN** access is withdrawn from a Host who owns three events
- **THEN** those events and their guests continue to exist, still recorded as owned by that account

### Requirement: The last active super admin is protected (P0)
The system SHALL refuse any operation that would leave zero active Super Admins — withdrawing the
last one, or demoting them to Host. The refusal SHALL be enforced by the API, SHALL say why, and
SHALL hold under concurrent requests, so two super admins demoting each other at the same moment
cannot both succeed.

#### Scenario: Demoting the only super admin
- **WHEN** the only active Super Admin tries to change their own role to Host
- **THEN** the operation is refused and the reason names the invariant

#### Scenario: Withdrawing the only super admin
- **WHEN** a Super Admin tries to withdraw access from the only active Super Admin account
- **THEN** the operation is refused

#### Scenario: Simultaneous demotions
- **WHEN** the two remaining Super Admins each demote the other in requests that overlap
- **THEN** at most one succeeds and at least one active Super Admin remains

### Requirement: Assigning and transferring event ownership (P0)
A Super Admin SHALL be able to see which events an account owns and to transfer any event to
another active account. Transfer SHALL move the whole event with it — its guests, invitations,
card design and message history follow the event, because they belong to it. The previous owner
SHALL lose access to that event on their next request. An account SHALL NOT be permanently
removed while it still owns events; the owner must be transferred first, so an owned event can
never end up unreachable.

#### Scenario: Transferring an event
- **WHEN** a Super Admin transfers an event from one Host to another
- **THEN** the new owner sees the event and its guests, and the previous owner no longer does

#### Scenario: Transfer target must be usable
- **WHEN** a Super Admin tries to transfer an event to a pending or withdrawn account
- **THEN** the transfer is refused

#### Scenario: Owned events block removal
- **WHEN** a Super Admin tries to remove an account that owns at least one event
- **THEN** the removal is refused and the response names how many events must be transferred first

### Requirement: Every roster change is audited (P0)
Every activation, rejection, role change, withdrawal and ownership transfer SHALL write an audit
entry naming the acting super admin, the affected account, and the before and after values. These
entries SHALL be visible in the audit log, which remains Super Admin only.

#### Scenario: Role change recorded
- **WHEN** a Super Admin changes an account's role
- **THEN** an audit entry records who changed it, whose account it was, and both the old and the new role

#### Scenario: Ownership transfer recorded
- **WHEN** an event is transferred between hosts
- **THEN** an audit entry records the event, the previous owner and the new owner
