Skip to content

refactor(community): give the provider port vendor-neutral types - #62

Closed
yufoxda wants to merge 2 commits into
agent/membership-workflowfrom
refactor/community-neutral-types
Closed

refactor(community): give the provider port vendor-neutral types#62
yufoxda wants to merge 2 commits into
agent/membership-workflowfrom
refactor/community-neutral-types

Conversation

@yufoxda

@yufoxda yufoxda commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

CommunityProvider は名前だけが汎用で、中身は Discord 固有でした。可換性を実際に成立させます。

⚠️ ベースは agent/membership-workflow(PR #61)です。#61 のマージ後に develop へ付け替わります。

何が問題だったか

  • ポートのメソッドが DiscordGuildMembership / DiscordMessage / DiscordReactionUser を返していた
  • 全IDが Discord の snowflake 形式(^\d{17,20}$)で検証されており、その正規表現がアプリ層まで到達していた
  • Discord の2000文字制限がポートの型に焼き込まれていた

結果として、プロバイダを差し替えるには「アダプタを入れ替える」のではなく、インターフェースと api_v0 の2つのサービスを書き換える必要がありました。

変更内容

ポート(中立)lib/community/type.ts, interface.ts

  • CommunityRole / CommunityMembership / CommunityMessage / CommunityReactionUser / CommunityAccountProfile に変更
  • IDは不透明な文字列として扱う(形式は発行者だけが知る)
  • メッセージ長制限を削除

アダプタ(Discord固有)lib/community/discord/schema.ts(新規)

  • snowflake 形式の検証、2000文字制限、global_name の写像をここに集約
  • 中立スキーマを .extend() して精緻化するため、検証は緩まない
  • global_namedisplayName に写像。保存先の provider_display_name 列とも整合

挙動は不変

snowflake 検証に依存する以下のテストが、移動後も通ることを確認済みです。

  • getCurrentDiscordUser rejects malformed provider responses as a bad gateway
  • getGuildMembershipAPI rejects a guild member response for another user

検証

対象 結果
community テスト 36 pass / 1 skip、tsc --noEmit クリーン
frontend テスト 25 pass、型チェッククリーン(globalName 参照なし=影響なし)

境界の確認

  • interface.ts / type.ts に Discord 語彙なし(コメントを除く)
  • api_v0 に Discord 固有型の参照なし
  • DiscordSnowflakeSchemalib/community/discord/ 配下のみ

🤖 Generated with Claude Code

The port was generic in name only. Its methods returned DiscordGuildMembership,
DiscordMessage and DiscordReactionUser, and every identifier was validated
against the Discord snowflake format, so the identifier regex reached callers
that have no reason to know what a snowflake is. Replacing the provider would
have meant editing the interface and both api_v0 services rather than swapping
an adapter.

The port now speaks CommunityRole, CommunityMembership, CommunityMessage,
CommunityReactionUser and CommunityAccountProfile, treats identifiers as opaque
strings, and drops the Discord message length limit. Discord's snowflake
format, its 2000-character limit, and the global_name field it returns are
refinements applied in discord/schema.ts, which is the only layer that issues
those values. The provider-specific field name is mapped to displayName at the
adapter boundary, matching the provider_display_name column it is stored in.

Behaviour is unchanged: the adapter still rejects a malformed provider response
and a guild member response for another user, both of which depend on the
snowflake assertion that moved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yufoxda
yufoxda force-pushed the refactor/community-neutral-types branch from 636e09e to c18ece5 Compare July 27, 2026 07:45
@yufoxda
yufoxda deleted the branch agent/membership-workflow July 27, 2026 12:51
@yufoxda yufoxda closed this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant