Parent
#237
What to build
Enable Discord/Twitch bots to trigger check-ins via domain events. The bot dispatches a CheckInRequested event, the Events module listens and processes it, then dispatches a CheckInProcessed response event for the bot to reply to the user.
Domain event: CheckInRequested
- Dispatched by bot module (Discord slash command or Twitch chat command)
- Payload:
provider (discord/twitch), external_user_id, code (numeric), event_id (optional, can be inferred), channel_context (for bot reply routing)
Listener: HandleBotCheckIn (in Events module)
- Resolves user from
external_user_id + provider via Identity module
- Finds the user's enrollment for the relevant event (active event for today, or specified event_id)
- Delegates to
CheckInAction with method=numeric_code
- On success: dispatches
CheckInProcessed with status=success, enrollment info
- On failure: dispatches
CheckInProcessed with status=error, reason (invalid code, not enrolled, already checked in, etc.)
Domain event: CheckInProcessed (response)
- Payload:
provider, external_user_id, channel_context, status (success/error), message, enrollment_id
- Bot module listens and replies to user in chat
Auto-discovery:
- Listener uses type-hinted
handle(CheckInRequested $event) — Laravel auto-discovers it
- No manual registration needed
Edge cases:
- User not found by external_id: error response "User not linked to platform"
- User not enrolled in any active event: error response "No active enrollment found"
- Multiple active events: require explicit event_id or use the one happening today
- Code validation follows same rules as App panel (expiry, max_uses, date)
Important: This slice only implements the Events module side (listener + response event). The bot-side command that dispatches CheckInRequested is a separate concern in app-modules/bot-discord/.
Acceptance criteria
Blocked by
Parent
#237
What to build
Enable Discord/Twitch bots to trigger check-ins via domain events. The bot dispatches a
CheckInRequestedevent, the Events module listens and processes it, then dispatches aCheckInProcessedresponse event for the bot to reply to the user.Domain event:
CheckInRequestedprovider(discord/twitch),external_user_id,code(numeric),event_id(optional, can be inferred),channel_context(for bot reply routing)Listener:
HandleBotCheckIn(in Events module)external_user_id+providervia Identity moduleCheckInActionwith method=numeric_codeCheckInProcessedwith status=success, enrollment infoCheckInProcessedwith status=error, reason (invalid code, not enrolled, already checked in, etc.)Domain event:
CheckInProcessed(response)provider,external_user_id,channel_context,status(success/error),message,enrollment_idAuto-discovery:
handle(CheckInRequested $event)— Laravel auto-discovers itEdge cases:
Important: This slice only implements the Events module side (listener + response event). The bot-side command that dispatches
CheckInRequestedis a separate concern inapp-modules/bot-discord/.Acceptance criteria
CheckInRequestedevent is defined with proper payload structureCheckInProcessedresponse event is dispatched with success/error statusBlocked by