メインコンテンツへ

テナントとメンバーシップ

一言でいうと

frontend の app/modules/tenant/ は「テナント設定画面」というひとつの UI のまとまりだが、その裏側は backend の複数モジュールに分かれている。メンバー招待・参加/離脱は membership、テナント名・ブランディング・プレゼンテーション設定は tenant、AI クレジット・プラン選択は billing が担当する(モジュール索引 の対応表注記参照)。「テナント設定を触る」タスクでは、まず自分が触ろうとしているのがどの backend モジュールの領域かを見極める必要がある。

主要ドメイン概念

概念役割主対応 backend モジュール
TenantMembershipユーザー×テナントの所属関係(Slack式に1ユーザーが複数テナントに所属可)。isActive で参加/離脱を表すmembership
TenantInvitationメール招待。トークン付きURL、期限切れ、承諾/拒否の状態遷移を持つmembership
Tenantテナント本体。名前・ブランディング・RoleKind・プレゼンテーション(テーマ/レイアウト)・有効プラグイン一覧を持つtenant
AI クレジット / プランテナットのAI利用量課金、Stripe連携billing

Backend 構造

core/membership/(招待・所属)

  • api/controller/: TenantInvitationController(テナント管理者側の招待発行・取消)、InvitationSelfServiceController(招待された本人が自分のメールアドレス宛の招待を確認・承諾/拒否する自己完結フロー)、TenantMembershipController(所属一覧・離脱)
  • domain/service/: TenantInvitationService(招待作成→メール送信、招待の承諾/拒否、期限切れバッチ処理 expireOldInvitations)、TenantMembershipService

core/tenant/(テナント本体・platform-admin)

  • api/controller/: TenantController(テナント設定 CRUD — 名前・ブランディング・プレゼンテーション・有効プラグイン)、PlatformTenantAdminController(運営者向けテナント横断操作、モジュール索引 の backend-only 節参照)
  • domain/service/: TenantServicecreateTenantupdateBrandingupdatePresentationupdateEnabledPluginstransferOwnership など)

core/billing/(AIクレジット・プラン)

  • api/controller/: TenantBillingControllerBillingPlanControllerCreditPackControllerCheckoutControllerStripeWebhookController
  • domain/service/: BillingServiceTenantUsageMeteringServicePlanFeatureCheckerStripeProvisioningService

Frontend 構造

app/modules/tenant/ は上記3つの backend モジュールをまとめて叩く単一の UI モジュール。

  • components/: InviteMemberDialog.vue / InvitationList.vue(招待、membership 対応)、TenantMemberList.vue + MemberListItem.vue / MemberActionMenu.vue / EditMemberRolesDialog.vue(所属メンバー管理)、TenantForm.vue / TenantSettingsDialog.vue(テナント設定、tenant 対応)、TransferOwnershipDialog.vue
  • components/settings/: TenantSettingsForm.vueTenantBrandingForm.vueTenantPresentationForm.vueTenantRoleKindForm.vueTenantDangerZone.vueTenantAICreditsScreen.vue + AICreditHistorySheet.vue(AIクレジット、billing 対応)、TenantAiDefaultSelector.vue / TenantAiSttSection.vue / TenantAiTierModelSelector.vue(AI設定)、TenantProviderSetupForm.vue / TenantCliSetupForm.vueTenantPluginSettingsForm.vue
  • composables/: useTenantMembers / useMemberDisplay / useMemberRoleCacheuseTenantInvitations / useMyTenantInvitationsuseTenants / useTenantListQuery / useTenantOwnershipuseTenantSettings / useTenantPresentationuseAICredits / useAIConfigurationbilling 対応)、usePlugins / usePluginSettings
  • repositories/: TenantRepository / TenantsRepositoryTenantMemberRepositoryTenantInvitationRepositoryTenantPresentationRepositoryAICreditsRepositoryAIConfigurationRepository

他モジュールとの辺

  • auth / role: メンバーのロール割り当て・権限判定は auth モジュール(Discord式権限モデル)が持つ。tenant はロールの「種類」(RoleKind)の設定のみ持つ
  • user: TenantMembership はユーザープロフィール(user モジュール)と紐づく
  • notification: 招待承諾時に通知が作成される(TenantInvitationService.createAcceptanceNotification

「テナント設定を直す」という依頼を frontend tenant モジュール1つの改修だと思い込むと、実装先の backend モジュールを間違える。メンバー管理・招待なら membership、名前/ブランディング/プレゼンテーションなら tenant、AIクレジット/プランなら billing — 触る画面のどの節(招待セクションか設定フォームかAIクレジット画面か)かを先に特定してから backend 側の対応 controller/service を探すこと。