Files
2026-05-27 23:29:53 +01:00

4.1 KiB

Tasks — add-discord-client

Every checkbox reflects work actually done in this change.

1. Spec authoring

  • 1.1 Read ../suaveplan/enterprise/discord-client.md end-to-end
  • 1.2 Read upstream impl at ../suaveplan/packages/universal/discord-client/src/
  • 1.3 Read OpenSpec templates + enterprise-package-migration SKILL
  • 1.4 Draft proposal.md from openspec/templates/proposal.md
  • 1.5 Fill in ## Source mapping table — every requirement cites a line range or is in the "no source line" table with justification
  • 1.6 Draft specs/discord-client/spec.md from openspec/templates/spec-delta.md
  • 1.7 Every requirement in the spec delta carries a **Verified by:** line naming concrete it(...) titles

2. Implementation

  • 2.1 Scaffold packages/messaging/discord-client/ (package.json @0.1.0, tsconfig, vite.config, vitest.config, polyfills)
  • 2.2 src/errors/discord-client-error.ts — defineCodes("DISCORD", [...]) + DiscordClientError extends SuaveplanError<DiscordClientCode>
  • 2.3 src/types/discord-client.types.ts — DiscordBotConfig/DiscordWebhookConfig/DiscordMessage/DiscordEmbed/DiscordResponse/DiscordChannel/DiscordDeliveryReport/FetchLike + Zod schemas
  • 2.4 src/utils/rate-limit.ts — parseRetryAfterMs(response, clock?) parser for 3 header variants
  • 2.5 src/utils/http.ts — executeDiscordRequest funnel mapping 401/403/404/429/5xx/non-ok to DISCORD codes, AbortController timeout → TIMEOUT, OTel counter + histogram lazy-init with resetDiscordHttpMetrics()
  • 2.6 src/core/bot-client/discord-bot-client.ts — full bot REST surface
  • 2.7 src/core/webhook/discord-webhook.ts — webhook surface + DeliveryReport
  • 2.8 src/index.ts — explicit named re-exports (no export *)

3. Tests

  • 3.1 src/errors/discord-client-error.test.ts — frozen registry, code prefix, code union, error class
  • 3.2 src/utils/rate-limit.test.ts — all 3 header variants, edge cases, default clock
  • 3.3 src/utils/http.test.ts — every status code mapping, abort/timeout, OTel via recording MeterProvider
  • 3.4 src/core/bot-client/discord-bot-client.test.ts — constructor validation, every public method, cache eviction, URL encoding
  • 3.5 src/core/webhook/discord-webhook.test.ts — config validation, send/sendText/sendEmbed, threading, defaults
  • 3.6 tests/dep-graph.test.ts — pins runtime deps + sideEffects: false
  • 3.7 Every it(...) carries { timeout: 5000 } or { timeout: 30000 }

4. Documentation

  • 4.1 Sibling .md for every implementation .ts (≥200 words, basic + advanced examples, full API reference) — 6 modules
  • 4.2 README.md at package root links every co-located .md under ## Modules

5. Pre-archive verification (5-gate triple)

  • 5.1 bun run check — exit 0, "No fixes applied"
  • 5.2 bunx turbo lint typecheck test --filter=@suaveplan/discord-client — green (62 tests pass)
  • 5.3 bunx turbo test:coverage --filter=@suaveplan/discord-client — 100/100/100/100 (istanbul)
  • 5.4 bun scripts/openspec-conformance.ts @suaveplan/discord-client — PASS (0 error, 0 warn, 0 info)
  • 5.5 bunx turbo build --filter=@suaveplan/discord-client — green

6. Pre-archive 7-row checklist

  • 6.1 Generics threaded — executeDiscordRequest<T> and DiscordClientCode literal union
  • 6.2 Zod schemas wired at every boundary — DiscordBotConfigSchema, DiscordWebhookConfigSchema, DiscordMessageSchema
  • 6.3 Every DISCORD_CODES code thrown by ≥1 production path
  • 6.4 Strict-mode behaviours tested (Zod boundary on/off — invalid config + valid config both pinned)
  • 6.5 OTel instruments emitted from production paths, asserted with a recording MeterProvider
  • 6.6 Lifecycle dedup tested where claimed — in-memory message cache set/get/evict
  • 6.7 No retroactive tick

7. Archive

  • 7.1 Fold spec delta into openspec/specs/discord-client/spec.md
  • 7.2 Move openspec/changes/add-discord-client/ → openspec/archive/2026-05-18-add-discord-client/