Difficulty: Expert
Type: feature
Background
apps/discord-bot is preserved as an optional legacy integration, and packages/integration-client is meant to hold shared types and an API client for use across apps — but there's no indication of a formal, versioned contract between the bot and the dashboard for the events they'd need to exchange (member joined via Discord, pass granted from dashboard should notify bot, etc.).
Problem
Without a shared, versioned protocol, the dashboard and Discord bot integration can drift independently, breaking compatibility silently (e.g., the bot expects a field the dashboard renamed) with no compile-time or runtime safety net.
Expected outcome
packages/integration-client defines a versioned event contract (e.g., GuildPassEventV1) with a discriminated union of event types (member.joined, pass.issued, pass.revoked, guild.updated), consumed identically by both apps/dashboard (as emitter) and apps/discord-bot (as consumer), with a documented deprecation/versioning policy for future breaking changes.
Suggested implementation
- Design a discriminated-union TypeScript type for all cross-app events, versioned via a
version field or a V1/V2 naming convention.
- Add runtime validation (e.g., zod schemas mirroring the types) so malformed events are rejected at the boundary, not just caught by TypeScript at compile time.
- Update
apps/discord-bot to consume events through this shared contract instead of any ad hoc shape it currently expects.
- Write a versioning policy doc (
docs/protocol.md or similar): how to add new event types, how to deprecate old ones, and how consumers should handle unknown event types gracefully (forward compatibility).
- Add contract tests that fail the build if
apps/discord-bot's expected event shapes diverge from packages/integration-client's published types.
Acceptance criteria
Likely affected files/directories
packages/integration-client/
apps/discord-bot/
apps/dashboard/
docs/
Difficulty: Expert
Type: feature
Background
apps/discord-botis preserved as an optional legacy integration, andpackages/integration-clientis meant to hold shared types and an API client for use across apps — but there's no indication of a formal, versioned contract between the bot and the dashboard for the events they'd need to exchange (member joined via Discord, pass granted from dashboard should notify bot, etc.).Problem
Without a shared, versioned protocol, the dashboard and Discord bot integration can drift independently, breaking compatibility silently (e.g., the bot expects a field the dashboard renamed) with no compile-time or runtime safety net.
Expected outcome
packages/integration-clientdefines a versioned event contract (e.g.,GuildPassEventV1) with a discriminated union of event types (member.joined,pass.issued,pass.revoked,guild.updated), consumed identically by bothapps/dashboard(as emitter) andapps/discord-bot(as consumer), with a documented deprecation/versioning policy for future breaking changes.Suggested implementation
versionfield or aV1/V2naming convention.apps/discord-botto consume events through this shared contract instead of any ad hoc shape it currently expects.docs/protocol.mdor similar): how to add new event types, how to deprecate old ones, and how consumers should handle unknown event types gracefully (forward compatibility).apps/discord-bot's expected event shapes diverge frompackages/integration-client's published types.Acceptance criteria
packages/integration-clientapps/discord-botconsumes events via the shared contractLikely affected files/directories
packages/integration-client/apps/discord-bot/apps/dashboard/docs/