Admin Reducers
Reducers voor administratieve functies.
Admin Systeem
is_admin Helper
fn is_admin(ctx: &ReducerContext) -> bool {
ctx.db.admin_user().identity().find(ctx.sender).is_some()
}
add_admin
Voeg admin rechten toe (alleen bestaande admins).
#[reducer]
pub fn add_admin(
ctx: &ReducerContext,
target_identity: Identity,
permissions: String,
) -> Result<(), String>
Permissions:
| Permission | Beschrijving |
|---|---|
| full | Alle rechten |
| items_only | Alleen items beheren |
| read_only | Alleen data bekijken |
Item Beheer
create_item_definition
Maak nieuw item type aan.
#[reducer]
pub fn create_item_definition(
ctx: &ReducerContext,
item_id: String,
category: String,
display_name: String,
description: String,
icon_path: String,
max_stack: u32,
is_tradeable: bool,
rarity: u8,
) -> Result<(), String>
Permission: Admin
Client (Admin Panel):
// Next.js admin panel
async function createItem(item: ItemDefinition) {
const result = await spacetimeClient.callReducer('create_item_definition', [
item.itemId,
item.category,
item.displayName,
item.description,
item.iconPath,
item.maxStack,
item.isTradeable,
item.rarity
]);
if (result.status === 'failed') {
throw new Error(result.message);
}
}
update_item_definition
Wijzig bestaand item.
#[reducer]
pub fn update_item_definition(
ctx: &ReducerContext,
item_id: String,
display_name: Option<String>,
description: Option<String>,
icon_path: Option<String>,
max_stack: Option<u32>,
is_tradeable: Option<bool>,
rarity: Option<u8>,
) -> Result<(), String>
Note: item_id en category kunnen niet wijzigen.
delete_item_definition
Verwijder item type.
#[reducer]
pub fn delete_item_definition(
ctx: &ReducerContext,
item_id: String,
) -> Result<(), String>
Warning: Verwijdert NIET bestaande items in inventories.
Container Types
create_container_type
Maak nieuw container type.
#[reducer]
pub fn create_container_type(
ctx: &ReducerContext,
type_id: String,
display_name: String,
slot_count: u8,
icon_path: String,
) -> Result<(), String>
Voorbeeld containers:
// Starter bag
create_container_type(ctx, "starter_bag", "Starter Rugzak", 8, "containers/starter.png")?;
// Upgraded bags
create_container_type(ctx, "leather_backpack", "Leren Rugzak", 12, "containers/leather.png")?;
create_container_type(ctx, "adventure_pack", "Avonturen Rugzak", 16, "containers/adventure.png")?;
Speler Beheer
give_item_to_player
Geef items aan speler.
#[reducer]
pub fn give_item_to_player(
ctx: &ReducerContext,
player_username: String,
item_id: String,
quantity: u32,
) -> Result<(), String>
Permission: Admin
give_resource_to_player
Geef resources aan speler.
#[reducer]
pub fn give_resource_to_player(
ctx: &ReducerContext,
player_username: String,
resource_type: String,
amount: u64,
) -> Result<(), String>
ban_player
Ban een speler.
#[reducer]
pub fn ban_player(
ctx: &ReducerContext,
player_identity: Identity,
reason: String,
duration_hours: u32, // 0 = permanent
) -> Result<(), String>
Side effects:
- Disconnect de speler
- Voeg toe aan ban list
- Log de actie
unban_player
Verwijder ban.
#[reducer]
pub fn unban_player(
ctx: &ReducerContext,
player_identity: Identity,
) -> Result<(), String>
Quest Beheer
create_quest_definition
Maak nieuwe quest.
#[reducer]
pub fn create_quest_definition(
ctx: &ReducerContext,
quest_id: String,
title: String,
description: String,
category: String,
difficulty: u8,
min_level: u8,
prerequisites: String, // JSON
objectives: String, // JSON
rewards: String, // JSON
time_limit_minutes: u32,
repeatable: bool,
cooldown_minutes: u32,
giver_npc: Option<String>,
) -> Result<(), String>
toggle_quest_active
Activeer/deactiveer quest.
#[reducer]
pub fn toggle_quest_active(
ctx: &ReducerContext,
quest_id: String,
is_active: bool,
) -> Result<(), String>
Asset Tickets
create_asset_ticket
Maak asset request ticket.
#[reducer]
pub fn create_asset_ticket(
ctx: &ReducerContext,
category_id: String,
title: String,
description: String,
reference_urls: String,
style_notes: String,
priority: u8,
game_path: String,
) -> Result<(), String>
assign_ticket
Wijs ticket toe aan designer.
#[reducer]
pub fn assign_ticket(
ctx: &ReducerContext,
ticket_id: u64,
designer_email: String,
) -> Result<(), String>
update_ticket_status
Update ticket status.
#[reducer]
pub fn update_ticket_status(
ctx: &ReducerContext,
ticket_id: u64,
new_status: String,
comment: Option<String>,
) -> Result<(), String>
Status transitions:
open → in_progress → review → approved
→ revision → in_progress
Server Maintenance
broadcast_message
Stuur bericht naar alle online spelers.
#[reducer]
pub fn broadcast_message(
ctx: &ReducerContext,
message: String,
message_type: String, // "info", "warning", "maintenance"
) -> Result<(), String>
schedule_maintenance
Plan onderhoud window.
#[reducer]
pub fn schedule_maintenance(
ctx: &ReducerContext,
start_time: Timestamp,
duration_minutes: u32,
message: String,
) -> Result<(), String>
Logging
Alle admin acties worden gelogd:
#[table(name = admin_log)]
pub struct AdminLog {
#[primary_key]
#[auto_inc]
pub id: u64,
pub admin: Identity,
pub action: String,
pub target: String,
pub details: String,
pub performed_at: Timestamp,
}
fn log_admin_action(ctx: &ReducerContext, action: &str, target: &str, details: &str) {
ctx.db.admin_log().insert(AdminLog {
id: 0,
admin: ctx.sender,
action: action.to_string(),
target: target.to_string(),
details: details.to_string(),
performed_at: ctx.timestamp,
});
}
Admin Panel Integratie
Het admin panel (Next.js) gebruikt deze reducers:
// pages/api/admin/items.ts
export async function POST(req: Request) {
const session = await getServerSession();
if (!session?.user?.isAdmin) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
const item = await req.json();
const result = await spacetimeAdmin.createItem(item);
return Response.json(result);
}