Reducers Reference¶
All 24 platform reducers — admin actions, panel wrappers, and lifecycle hooks.
Overview¶
Platform reducers are the mutation interface to the QS-Bridge database. They are organized into three groups:
- Admin reducers — direct admin actions called by the bridge or CLI
- Panel wrapper reducers — gateway-proxied versions with
is_gateway()verification - Lifecycle reducers — bridge health monitoring
All reducers are implemented in Rust as #[reducer] functions in the SpacetimeDB WASM module.
Authentication Model¶
Panel wrapper reducers use the is_gateway() guard pattern:
fn is_gateway(ctx: &ReducerContext) -> bool {
if let Some(config) = ModuleConfig::filter_by_id(&0) {
ctx.sender == config.owner_identity
} else {
false
}
}
The API gateway connects to SpacetimeDB using the publisher's token, so ctx.sender() matches ModuleConfig.owner_identity. This ensures only the trusted gateway can trigger admin mutations — never a browser client directly.
Admin Reducers (12)¶
| # | Reducer | Parameters | Description |
|---|---|---|---|
| 1 | admin_ban |
ctx, player_id: String, player_name: String, reason: String, duration_hours: Option<u64> |
Ban a player cluster-wide. Creates a BanEntry row. If duration_hours is None, the ban is permanent. |
| 2 | admin_unban |
ctx, player_id: String |
Revoke an active ban. Sets revoked = true, revoked_by, and revoked_at on the BanEntry. |
| 3 | admin_kick |
ctx, player_id: String, reason: String |
Kick a player from their current server. Logs the action but does not create a ban. |
| 4 | admin_whitelist_add |
ctx, player_id: String |
Add a player to the cluster-wide whitelist. |
| 5 | admin_whitelist_remove |
ctx, player_id: String |
Remove a player from the whitelist. |
| 6 | admin_set_password |
ctx, password: String |
Set the server password. Stored as password_hash (bcrypt) in ServerConfig. |
| 7 | admin_toggle_whitelist |
ctx, enabled: bool |
Enable or disable whitelist enforcement on the server. |
| 8 | admin_set_max_players |
ctx, max_players: u32 |
Set the maximum player count for the server. |
| 9 | admin_set_motd |
ctx, motd: String |
Set the Message of the Day displayed to connecting players. |
| 10 | admin_grant_role |
ctx, player_id: String, role: AdminRoleLevel |
Grant an admin role (Moderator=0, Admin=1, Owner=2) to a player. |
| 11 | admin_revoke_role |
ctx, player_id: String |
Revoke a player's admin role. Deletes their AdminRole row. |
| 12 | admin_announce |
ctx, message: String |
Broadcast an announcement to all connected players on the server. |
Panel Wrapper Reducers (11)¶
These reducers are called by the API Gateway on behalf of authenticated panel users. Each verifies is_gateway() before delegating to the corresponding admin reducer, and logs the action in PanelAuditLog.
| # | Reducer | Parameters | Delegates To |
|---|---|---|---|
| 13 | panel_register_session |
ctx, player_id: String, display_name: String, role: AdminLevel |
Creates a PanelSession row |
| 14 | panel_end_session |
ctx |
Removes the PanelSession row for the caller |
| 15 | panel_log_action |
ctx, action: String, target: String, details: String |
Inserts into PanelAuditLog |
| 16 | panel_ban_player |
ctx, player_id: String, player_name: String, reason: String, duration_hours: Option<u64> |
admin_ban + audit log |
| 17 | panel_unban_player |
ctx, player_id: String |
admin_unban + audit log |
| 18 | panel_kick_player |
ctx, player_id: String, reason: String |
admin_kick + audit log |
| 19 | panel_announcement |
ctx, message: String |
admin_announce + audit log |
| 20 | panel_set_motd |
ctx, server_id: String, motd: String |
admin_set_motd + audit log |
| 21 | panel_set_max_players |
ctx, server_id: String, max_players: u32 |
admin_set_max_players + audit log |
| 22 | panel_set_password |
ctx, server_id: String, password: String |
admin_set_password + audit log |
| 23 | panel_toggle_whitelist |
ctx, server_id: String, enabled: bool |
admin_toggle_whitelist + audit log |
Note: Panel wrapper reducers accept
server_idto support multi-server clusters. The admin reducers they delegate to operate on the current server context.
Lifecycle Reducers (1)¶
| # | Reducer | Parameters | Description |
|---|---|---|---|
| 24 | server_heartbeat |
ctx |
Called by each bridge instance every 30 seconds. Updates ServerRegistry.last_heartbeat and online_count. Used by the panel to detect stale/offline servers. |
Error Handling¶
All reducers follow a consistent error pattern:
- Missing permissions — reducer logs a warning and returns without modifying state
- Invalid parameters — reducer returns an error string via
Err(String) - Duplicate operations — idempotent where possible (e.g., banning an already-banned player updates the existing ban)
Related Pages¶
- Platform Overview — table and reducer summary
- API Gateway — how the panel calls these reducers
- Authentication — Steam OpenID → JWT → reducer flow