Gamification Architecture
Technical architecture of the quest system, XP engine, leaderboard computation, and integration with the audit trail.
Last updated: 2025-02-18
Gamification Architecture
The gamification system is built as a layer on top of the event-sourced audit trail. XP awards are derived from operational events, ensuring game mechanics never conflict with compliance requirements.
System Architecture
XP Rules Engine
The rules engine maps operational events to XP awards:
<Card className="w-80"> <CardHeader className="pb-2"> <CardTitle className="text-sm">XP Rules Configuration</CardTitle> <CardDescription>Points awarded per action</CardDescription> </CardHeader> <CardContent className="space-y-2"> <div className="flex items-center justify-between text-xs p-2 rounded bg-muted"> <span>Placement with full evidence</span> <Badge variant="outline">100 XP</Badge> </div> <div className="flex items-center justify-between text-xs p-2 rounded"> <span>Supervisor verification</span> <Badge variant="outline">50 XP</Badge> </div> <div className="flex items-center justify-between text-xs p-2 rounded bg-muted"> <span>Stage advancement</span> <Badge variant="outline">75 XP</Badge> </div> <div className="flex items-center justify-between text-xs p-2 rounded"> <span>Under-time completion</span> <Badge variant="outline">25 XP bonus</Badge> </div> <div className="flex items-center justify-between text-xs p-2 rounded bg-muted"> <span>Perfect audit (no disputes)</span> <Badge variant="outline">500 XP</Badge> </div> </CardContent> </Card>
Rule Processing Pipeline
interface XPRule {
eventType: EventType;
condition?: (event: Event) => boolean;
baseXP: number;
multipliers?: XPMultiplier[];
}
// Example rule: placement with photo evidence
const placementRule: XPRule = {
eventType: 'PLACED',
condition: (e) => !!e.photo_url && !!e.scale_weight_kg,
baseXP: 100,
multipliers: [
{ type: 'streak', factor: (streak) => 1 + streak * 0.1 },
{ type: 'time', factor: (elapsed) => elapsed < 120 ? 1.25 : 1.0 },
],
};
Quest System
Quests are configured by administrators and tracked in real time:
Quest Types
| Type | Duration | Scope | Example |
|---|---|---|---|
| Daily | 24 hours | Individual | Process 20 units |
| Weekly | 7 days | Individual | Zero incidents week |
| Team | Variable | Team | Process 500 units as team |
| Challenge | Custom | Facility | Highest throughput this month |
| Achievement | Permanent | Individual | 1,000 lifetime placements |
Quest Data Model
interface Quest {
id: string;
title: string;
description: string;
type: 'daily' | 'weekly' | 'team' | 'challenge' | 'achievement';
criteria: QuestCriteria[];
xpReward: number;
badgeReward?: string;
deadline?: Date;
assignedTo: string[]; // operator IDs or 'all'
}
interface QuestCriteria {
metric: string; // e.g., 'placements_count', 'incidents_zero'
target: number;
current: number; // derived from events
}
Leaderboard Architecture
Leaderboards are computed from the XP event log using materialized aggregations:
| Board | Reset Period | Scope | Ranking Metric |
|---|---|---|---|
| Daily | Every 24h | Facility | XP earned today |
| Weekly | Every Monday | Facility | XP earned this week |
| Monthly | 1st of month | Organization | XP earned this month |
| All-time | Never | Organization | Total lifetime XP |
Computation
-- Weekly leaderboard (cached, refreshed every 5 minutes)
SELECT
operator_id,
SUM(xp_amount) as weekly_xp,
COUNT(*) as actions,
RANK() OVER (ORDER BY SUM(xp_amount) DESC) as rank
FROM xp_events
WHERE created_at >= date_trunc('week', NOW())
GROUP BY operator_id
ORDER BY weekly_xp DESC
LIMIT 50;
Level Progression
| Level | XP Required | Title | Perks |
|---|---|---|---|
| 1-5 | 0-2,500 | Novice | Basic quests |
| 6-10 | 2,500-10,000 | Skilled | Advanced quests |
| 11-15 | 10,000-25,000 | Expert | Team missions |
| 16-20 | 25,000-50,000 | Master | Challenge creation |
| 21+ | 50,000+ | Legend | All features |
Audit Integration
Compliance Safe
Every XP award, quest completion, and leaderboard change is recorded in the same immutable audit trail as operational events. Gamification never compromises audit integrity.
The gamification layer produces audit events of its own:
// Gamification events in the audit trail
{
type: 'GAMIFICATION',
subtype: 'XP_AWARDED',
operator: 'op-123',
data: {
amount: 100,
source: 'placement',
sourceEventId: 'evt-456',
questId: 'quest-789',
multiplier: 1.5,
streakDays: 15
},
hash: 'sha256:...',
timestamp: '2025-01-15T14:32:07Z'
}
Components
| Component | Path | Description |
|---|---|---|
GamificationHeader | @/components/whms/GamificationHeader | Persistent XP bar |
QuestCard | @/components/whms/QuestCard | Quest progress card |
QuestsTab | @/components/whms/QuestsTab | Quest list view |
QuestCreator | @/components/whms/QuestCreator | Admin quest builder |
MissionCard | @/components/whms/MissionCard | Team mission card |
MissionsTab | @/components/whms/MissionsTab | Missions on map |
AdminGameSetup | @/components/whms/admin/AdminGameSetup | Game configuration |