コラボレーション、従業員マーケットプレイス、オペレーターチャットコンテキスト
組織、チーム、ロール、ワークフロー共有、従業員マーケットプレイス、チャットへの従業員オンボーディング、ワークスペースコンテキストがオペレーター体験をどう形作るか。
概要
Supervity は 個人、組織、チーム のワークスペーススコープをサポートします。本ガイドでは以下をつなげて説明します。
- 組織/チームコンテキスト がワークフローサービスへどう送信されるか
- Keycloak ロール と共有リソースに対するアクションへのマッピング
- 共有(同一ワークフロー vs コピー)と UI が使用する API
- 従業員マーケットプレイス — 一覧データ、カタログルール、レビュー、モデレーション(アプリの Prisma モデルとサーバーモジュールに基づく)
- マーケットプレイスからインストール済み オペレーター への 従業員オンボーディング(ワークフローおよびアプリが実装する オペレーター チャットルート)
実行の仕組み(ステップ、実行、リトライ)は ワークフローの解説 と トラブルシューティング に記載されています。
組織とチーム
- Organization — メンバーシップは Keycloak で管理されます。アプリはユーザートークンと必要に応じて管理 API から組織 ID/名前とロールを解決します。
- Team — チームは組織に属し、独自のメンバーシップロールを持ちます。UI は現在の組織/チーム選択(チームの prefix が
teamKeyとして使用される)を保持します。
セレクターが重要な理由
ワークフローマイクロサービスへのブラウザ呼び出しには、getWorkflowServiceContextHeaders(app/utils/workflow-svc.tsx)で構築されたオプションヘッダーが含まれます。
x-active-org— 現在の組織 name(組織が選択されている場合)x-active-team— 現在のチーム name(チームが選択されている場合)x-teamKey— チーム prefix(チームが選択されている場合)
組織が選択されていない場合、これらのヘッダーは省略されます(個人ワークスペース)。ワークフローサービスへプロキシするサーバールート(例:/api/v1/workflows/:id/install-for-users)は getCurrentOrgTeam から同じヘッダーを転送し、インストールがセッションのアクティブスコープで実行されるようにします。
ロールとアクセス(RBAC)
組織とチームのロール
組織/チームチェックで使用されるロールには owner、admin、editor、viewer があります(app/utils/resource-ownership.server.ts の getUserRoleInOrganization / getUserRoleInTeam を参照)。
組織またはチームレベル のリソースについて、canPerformAction は以下を定義します。
| Role | create | read | update | delete |
|---|---|---|---|---|
| owner, admin | yes | yes | yes | yes |
| editor | yes | yes | yes | no |
| viewer | no | yes | no | no |
Private リソース(resourceOwnership.level === 'private')は canUserAccessResource で リソース所有者(ownerId === userId)のみが読み書き可能です — 組織/チームロールは他ユーザーのプライベートワークフローへのアクセスを付与しません。
コンテキスト切り替え時の実効ロール
getEffectiveOrgTeamRole(app/utils/permission-guard.server.ts)は以下を返します。
currentTeam.idが設定されている場合、現在のチーム に対するgetUserRoleInTeam(チームコンテキストが優先)。- それ以外で
currentOrg.idが設定されている場合、現在の組織 に対するgetUserRoleInOrganization。 - それ以外は
'admin'— コード上は プライベートコンテキスト として文書化され、ユーザー所有リソースの create/update/delete がこのヘルパーを呼ぶ組織/チームベースのガードを通過できるようにします。
この関数本体では「全組織を横断した最高ロール」は集約しません。アクティブ な組織またはチーム選択のみがここで重要です。
従業員マーケットプレイス公開(対象ロール)
requireMarketplacePublishContext(app/utils/marketplace/permissions.server.ts)は、ユーザーがその組織またはチームで owner、admin、editor のいずれかを持つ場合にのみ、ソースコンテキストから一覧(従業員が発見・インストールできる オペレーター)を公開できます。Viewer はそのコンテキストから公開できません。個人ワークスペースは、personal kind を使用する一覧作成フローのソースコンテキストとして常に許可されます。
ワークフロー共有 UI(ワークフローサービス baseRole)
共有 モーダル(app/components/workflow/workflow-share-modal.tsx)は、ワークフローサービスの baseRole で機能を制御します。
isOwner—baseRole === "owner"(組織/チームの可視性変更と コピーを送信 に必要)。canPublish—baseRoleがowner、admin、editorのいずれか — マーケットプレイス掲載の下書きを作成(従業員向け下書き一覧)に必要。canPublishを持つ非オーナーには、共有可視性を変更できるのはオーナーと組織管理者のみ である旨の通知が表示されます。
チーム スコープの editor で owner / admin でない場合、組織スコープに切り替える まで共有やコピー送信がブロックされることがあります(mustSwitchScopeForSharing)。
共有:同一ワークフロー vs 個別コピー
同一ワークフローを共有(組織またはチーム)
モーダルは updateWorkflowVisibility を以下で呼び出します。
targetScope:orgまたはteam- チームスコープの場合:
shareWithTeamKeys(チーム prefix 値)、必要に応じて組織/チーム名
UI の文言では、組織 への共有は 1 つのワークフローを維持し、プライベートから昇格する際は選択した組織へ 移動 すると説明されます。チーム共有は同じグラフを選択したチームキーにスコープします。
個人へコピーを送信
Send a copy は POST /api/v1/workflows/:workflowId/install-for-users(app/routes/api+/v1+/workflows+/$workflowId.install-for-users.tsx)に POST し、受信者ごとに recipientUserId 付きでワークフローサービス POST .../workflows/:workflowId/install-for-user を 1 回呼び出します。受信者には Keycloak ユーザー ID が必要です。リクエストは呼び出し元の現在の x-active-org / x-active-team / x-teamKey ヘッダーを使用し、ワークフローサービスがコンテキストを一貫して解決します。
従業員マーケットプレイス
マーケットプレイスは 従業員(および他のユーザー)が一覧としてパッケージ化された オペレーター を発見する場所です。技術的なモデル名(MarketplaceListing、/u/marketplace 配下のルートなど)はコードと同じままです。
公開カタログ(閲覧 / 発見)
catalogListingBaseWhereSql(app/utils/marketplace/listing.server.ts)のカタログ SQL は、すべて 次を満たす場合にのみ、従業員が閲覧/発見で見る一覧を表示します。
MarketplaceListing.status=approvedvisibility=publicdiscoverability=listeddelistedAtとsuspendedAtが nullcurrentPublishedVersionIdが設定済み(公開バージョンが存在)
検索ファセット(カテゴリ、オペレーター レベル、Employee Pack フィルター)がさらに絞り込みます。
一覧詳細 URL と従業員オンボーディング適格性
getMarketplaceListingBySlug は、従業員(または管理者)が slug で詳細ページを開き オンボーディング が許可される場合、slug で一覧を読み込みます。
status=approvedcurrentPublishedVersionIdが null でないdelistedAtとsuspendedAtが null
このクエリでは visibility / discoverability は再チェックしません — approved で public + listed の一覧はカタログに表示されます。他の可視性の組み合わせは誰が見つけるかに影響する場合がありますが、slug ベースの詳細と 従業員オンボーディング は上記の approved + モデレーションされていないルールを使用します。
従業員オンボーディング(app/utils/marketplace/onboarding.server.ts の onboardMarketplaceListing)は、従業員が選択したワークスペースに公開済み オペレーター をインストールします。そのレコードに currentPublishedVersion が必要です — なければ一覧がオンボーディング不可である旨を返します。
一覧の作成と編集(パブリッシャー、従業員向け)
- 新規一覧は
MarketplaceListing.status=draftで開始し、最初のMarketplaceListingVersionのsubmissionStatusはdraft(app/utils/marketplace/publisher.server.tsのcreateMarketplaceDraft)。 - バージョンは
submissionStatusがdraftまたはchanges_requestedの場合のみパブリッシャー UI で編集可能(publisher.server.tsのisEditableDraftStatus)。 - レビュー提出ではバージョンを
submissionStatus=pending_reviewに設定します。まだcurrentPublishedVersionIdが ない 場合のみ一覧のstatusがpending_reviewになります。ライブバージョンが既にある場合、一覧のstatusは変更せず、ストアフロントは最後の承認済みバージョンを提供し続けながら新バージョンをレビューします。
提出時は MARKETPLACE_REVIEWER_EMAILS のアドレス(フォールバック ADMIN_EMAILS)へメールを送り、パブリッシャーへ確認メールを送ります(publisher.server.ts の submitMarketplaceDraft)。従業員がインストールする前に 従業員向け 一覧をレビューできます。
バージョン提出タイプ
各バージョンには submissionType(Prisma の MarketplaceSubmissionType)があります:new_listing、metadata_update、source_version_update、republication。新規下書きは new_listing。既存バージョンからのクローン下書きは、前バージョンのフィールドをコピーする場合 metadata_update。
レビュー決定(管理者)
reviewMarketplaceSubmission(app/utils/marketplace/admin.server.ts)は submissionStatus が pending_review のバージョンのみ受け付けます。
- Approve — バージョンを
approvedに設定し、publishedAtを設定し、一覧のcurrentPublishedVersionIdをこのバージョンに向け、一覧statusをapprovedに設定し、delistedAt/suspendedAtをクリアし、パックフラグをコピーし、別行だった場合は以前の公開バージョンのsubmissionStatusをsupersededにします。 - Reject または Request changes — バージョンの
submissionStatusをrejectedまたはchanges_requestedに設定します。他にライブ公開バージョンが ない 場合のみ一覧statusがrejectedまたはchanges_requestedになります。以前のバージョンが既にライブの場合、一覧statusはapprovedのまま、最後の正常な公開を維持します。
各決定は MarketplaceReview 行を書き込み、メールがある場合はパブリッシャーへ MarketplaceReviewDecisionPublisherEmail を送信します。
一覧レベルのステータス(参考)
Prisma の MarketplaceListing.status 列挙型:draft、pending_review、approved、rejected、changes_requested、delisted、suspended、archived。
MarketplaceListingVersion.submissionStatus:draft、pending_review、approved、rejected、changes_requested、withdrawn、superseded。
公開後のモデレーション
updateMarketplaceListingLifecycle(管理者)は currentPublishedVersion が存在する場合のみ実行されます。コードで実装されているアクション:
| Action | Listing fields updated | MarketplaceReview.action when applicable |
|---|---|---|
| delist | status → delisted, delistedAt 設定, suspendedAt クリア | delisted |
| suspend | status → suspended, suspendedAt 設定 | suspended |
| restore | status → approved, delistedAt / suspendedAt クリア | restored |
| feature / unfeature | featuredRank 設定またはクリア | — |
| hide / show | discoverability → hidden または listed | — |
パブリッシャー削除ルール
deleteMarketplaceDraftListing は、currentPublishedVersionId が ない または 一覧 status が rejected または suspended の場合のみパブリッシャーが一覧を削除できます。ライブ approved 一覧はこの方法では削除できません — エラーメッセージはモデレーション/サポートへ誘導します。
Employee Pack オンボーディングガード
Employee Pack 一覧が手動でピン留めしたバンドル オペレーター ワークフローを期待する場合、解決されたメンバーワークフロー数が期待数と一致しないと onboardMarketplaceListing はインストール前に例外を投げます。エラー文字列:"This Employee Pack is missing pinned versions for one or more bundled workflows. Re-save and re-submit the listing before onboarding."(onboarding.server.ts)。
マーケットプレイスからの従業員オンボーディング → オペレーターワークフローとチャット
これは、承認済み一覧で Onboard を選択した後、従業員(またはワークスペース向けにインストールする人)が使用するパスです。
-
Onboard フォームは
/u/marketplace/:workflowId/onboardに POST します(workflowIdルートパラメータは一覧 slug)。 -
onboardMarketplaceListingはresolveOnboardingTargetContextからのターゲットスコープ(個人 vs 組織 vs 組織+チーム)へonboardOperatorでインストールし、公開バージョンのsourceWorkflowId、オプションのversionPublicId、該当時は Employee Pack のmemberWorkflowsを渡します。 -
成功時、
marketplace.$workflowId.onboardはresolveOnboardingTargetContext(app/utils/marketplace/onboarding-context.ts)のisDifferentFromCurrentContextを確認します。true— 例:セッションに組織/チームが選択されたまま 個人 へオンボーディング、または org/team キーがアクティブセッションと一致しない — アプリは成功トースト付きで/u/marketplace/<slug>へ リダイレクト(インストール済み オペレーター を開く前にワークスペースを切り替え)。false— アプリは/u/alpha/agent/workflow/<targetWorkflowId>?forked=1&marketplace_listing=<slug>へ リダイレクト(Remix ルートセグメントagentが現在の URL)し、従業員が新しい オペレーター ワークフローに即座に着地します。
-
従業員オンボーディングモーダル(
OnboardContextModal)は、ワークフローの Go to Chat で後から オペレーター をカスタマイズできると案内します —alpha.agent.workflow.$id.tsxのhandleGoToChat/createThreadFromWorkflowがそのワークフロー ID の オペレーター チャットスレッドを読み込みまたは作成し、/u/alpha/agent/<threadId>へ遷移します。
コンテキストベースのオペレーターチャット
- ブラウザからの送信 オペレーター チャットとワークフロー API トラフィックには
getWorkflowServiceContextHeaders()が付与され、ワークフローサービスはセレクターと同じ org/team を認識します(上記ヘッダー参照)。 GET /api/v1/community/workflow-contextは、同じセッション org/team ヘッダーでスコープし、ワークフロー ID の実行とチャットを返します。/u/alpha/agent/:id(オペレーターチャット UI;ルート名は変更なし)でスレッドを読み込むとメッセージを取得し、存在する場合はスレッドペイロードのworkflowオブジェクトでクライアントストアのプランナーワークフローをハイドレートします(alpha.agent.index.tsx)。
ヒント:ワークフローの構築とデバッグ
これらは UI で実行とステップを観察する方法(ログ、ステップ I/O、リトライ)に沿った運用プラクティスであり、別のプロダクトフラグではありません。
- スコープを絞る — ステップが少ないほど失敗を単一アクションにマッピングしやすい。
- ステップと入力に名前を付ける — 実行タイムラインとエクスポートの可読性が保たれる。
- 早期に検証する — 早期失敗ステップは部分的な副作用を減らす。
- 実行詳細を使う — オペレーター / ステッププロンプトを変更する前に stdout/stderr、出力、リトライ行を確認する。
- 人間レビュー — ポリシーが曖昧な箇所に承認ステップを追加する。人間レビューと承認 を参照。
次に読むべきドキュメント
- ワークフローの解説
- 人間レビューと承認
- スケジュールと自動化
- セキュリティとプライバシー
- Workflows API
- Chats API — HTTP 経由の オペレーター チャット
ワークスペースヘッダー、Keycloak ロール、従業員マーケットプレイス Prisma ステートマシン、従業員オンボードリダイレクトは上記のとおり実装されています。挙動が変わった場合は、listing.server.ts、publisher.server.ts、admin.server.ts、onboarding.server.ts とあわせて本ページを更新してください。