feat(repo-ui): broken repository recovery (#283 PR 5/7)#292
feat(repo-ui): broken repository recovery (#283 PR 5/7)#292coji wants to merge 1 commit intofeat/issue-283-uifrom
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 Walkthroughウォークスルー破損したリポジトリの検出と手動再割り当て機能を導入します。新しい 変更内容
シーケンス図sequenceDiagram
actor User
participant UI as リポジトリ設定UI
participant Action as アクションハンドラー
participant Service as reassignBrokenRepository
participant DB as データベース
User->>UI: 「再接続」バッジをクリック
UI->>UI: フォーム送信<br/>(intent=reassignBroken)
UI->>Action: POST reassignBroken
Action->>Service: reassignBrokenRepository呼び出し<br/>(organizationId, repositoryId)
Service->>DB: githubInstallationId=NULLの<br/>リポジトリを読み込み
Service->>DB: 適格なGitHub App<br/>インストールをクエリ
Service->>DB: repositoryInstallationMemberships<br/>をクエリ
alt 一意の候補が存在
Service->>DB: githubInstallationIdを更新<br/>(canonical_reassigned イベント)
Service-->>Action: {status: 'reassigned'}
Action-->>UI: 成功トースト
else 複数の候補が存在
Service-->>Action: {status: 'ambiguous'}
Action-->>UI: 曖昧なメッセージトースト
else 候補がない
Service-->>Action: {status: 'no_candidates'}
Action-->>UI: 候補なしメッセージトースト
end
UI->>User: ユーザーへ結果を表示
見積もりコード レビュー作業量🎯 4 (Complex) | ⏱️ ~45 分 関連する可能性のあるプルリクエスト
詩
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
batch/commands/reassign-broken-repositories.ts (1)
29-37: トークンベースのリポジトリも取得される可能性があります。クエリは
githubInstallationId IS NULLのリポジトリを全て取得しますが、トークンベースの統合を使用しているリポジトリも該当する可能性があります。reassignBrokenRepositoryはno_candidatesを返すため動作上の問題はありませんが、大規模な組織では不要な処理が発生する可能性があります。統合メソッドでフィルタリングするか、ログに
not_broken/no_candidatesの件数を含めてオペレーターが状況を把握できるようにすることを検討してください。🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@batch/commands/reassign-broken-repositories.ts` around lines 29 - 37, クエリが githubInstallationId IS NULL の全リポジトリを取得してトークンベース統合のリポジトリまで含めてしまっているので、tenantDb の repositories クエリを更新してトークンベースの統合を除外するフィルタ(例: where('integration_method', '!=', 'token') — 実際のカラム名に合わせる)を追加するか、または broken の前後で reassignBrokenRepository の結果(not_broken / no_candidates)件数を processLogger に出力してオペレーターが状況を把握できるようにしてください; props.repositoryId 分岐と broken 変数はそのまま使ってください。app/services/github-app-membership.server.ts (1)
78-84: 存在しないリポジトリに対してnot_brokenを返す動作について。リポジトリが存在しない場合に
{ status: 'not_broken' }を返していますが、これは呼び出し元にとって誤解を招く可能性があります。現在の使用箇所(UI とCLI)ではリポジトリIDは常に有効なソースから取得されるため、実際には問題にならないと思いますが、将来的にnot_foundのようなステータスを追加することを検討してもよいかもしれません。現状の実装でも安全なフォールバックとして機能するため、このままでも問題ありません。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/services/github-app-membership.server.ts` around lines 78 - 84, The function currently returns { status: 'not_broken' } when the repository lookup (tenantDb.selectFrom('repositories')... -> repo) yields no row, which can be misleading; change that branch to return a distinct status such as { status: 'not_found' } (or add a new 'not_found' enum) instead of 'not_broken', and update any callers/UI/CLI that consume the result of this function in github-app-membership.server.ts to handle the new 'not_found' case appropriately (ensure code paths that expect valid repository ids still behave the same).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@app/services/github-app-membership.server.ts`:
- Around line 78-84: The function currently returns { status: 'not_broken' }
when the repository lookup (tenantDb.selectFrom('repositories')... -> repo)
yields no row, which can be misleading; change that branch to return a distinct
status such as { status: 'not_found' } (or add a new 'not_found' enum) instead
of 'not_broken', and update any callers/UI/CLI that consume the result of this
function in github-app-membership.server.ts to handle the new 'not_found' case
appropriately (ensure code paths that expect valid repository ids still behave
the same).
In `@batch/commands/reassign-broken-repositories.ts`:
- Around line 29-37: クエリが githubInstallationId IS NULL
の全リポジトリを取得してトークンベース統合のリポジトリまで含めてしまっているので、tenantDb の repositories
クエリを更新してトークンベースの統合を除外するフィルタ(例: where('integration_method', '!=', 'token') —
実際のカラム名に合わせる)を追加するか、または broken の前後で reassignBrokenRepository の結果(not_broken /
no_candidates)件数を processLogger に出力してオペレーターが状況を把握できるようにしてください;
props.repositoryId 分岐と broken 変数はそのまま使ってください。
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d20ec4d2-f5f0-4061-bcb7-dd54dbc09cbb
📒 Files selected for processing (7)
app/libs/github-account.tsapp/routes/$orgSlug/settings/repositories._index/+components/repo-columns.tsxapp/routes/$orgSlug/settings/repositories._index/index.tsxapp/services/github-app-membership.server.test.tsapp/services/github-app-membership.server.tsbatch/cli.tsbatch/commands/reassign-broken-repositories.ts
0e2f6f5 to
19f78bb
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
4e18e33 to
d0f0617
Compare
9072111 to
5e5aca9
Compare
d0f0617 to
26f67f3
Compare
26f67f3 to
f573893
Compare
b9ba6fb to
ddaae6e
Compare
ddaae6e to
577b1d8
Compare
5ab3838 to
073e9fe
Compare
577b1d8 to
042e55c
Compare
UX 哲学: 通常時は repository 一覧/詳細に installation 名を出さない (PR 4 の Vercel 哲学を継承)。canonical installation を失って `github_installation_id IS NULL` になった broken state の repository だけを救済導線として可視化する。
repositories list (settings/repositories):
- github_app モードかつ github_installation_id IS NULL の repository に "Needs reconnection" バッジ + tooltip
- 1-click "Reassign" ボタンで canonical reassignment helper を再実行
- 候補 1 件 → 自動 reassign + バッジ消失 (success toast)
- 候補 0 件 → "Reinstall the GitHub App and try again" (error toast)
- 候補 2+ 件 → "Disconnect unwanted installations to resolve" (error toast)
- loader が getIntegration().method を返し、columns が github_app モードのみバッジを出す
mutation (app/services/github-app-membership.server.ts):
- reassignBrokenRepository(orgId, repositoryId, source) helper を追加
- canonical reassignment helper と同じ eligibility ルール
- 結果を { reassigned | no_candidates | ambiguous | not_broken } の discriminated union で返す
- tenant first / shared second + audit log
route mutation wrapper (settings/repositories._index/mutations.server.ts):
- reassignBrokenRepositoryFromUI() で source='manual_reassign' を固定して呼ぶ
batch CLI (batch/commands/reassign-broken-repositories.ts):
- batch/cli.ts に `reassign-broken-repositories <orgId> [--repository <id>]` コマンド追加
- 全 broken repo を順次救済、結果を集計表示
- source='cli_repair'
tests (github-app-membership.server.test.ts):
- reassignBrokenRepository の 6 ケース追加 (1/0/2+ 候補, not_broken, suspended/uninitialized link 除外)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
042e55c to
bc5e2e9
Compare

Summary
Issue #283 の実装 stack PR 5/7 — broken state(
github_installation_id IS NULL)の repository を救済する UI / mutation / batch CLI を追加。設計根拠: `docs/rdd/issue-283-multiple-github-accounts.md`
作業計画: `docs/rdd/issue-283-work-plan.md`
依存: #288 (PR 1: schema), #296 (PR 2: query/octokit), #290 (PR 3: webhook/membership), #291 (PR 4: UI)
UX 哲学
PR 4 の Vercel 哲学を継承し、通常時は repository 一覧/詳細に installation 名を出さない。canonical installation を失った broken state の repository だけを救済導線として可視化する。
変更内容
service helper (`app/services/github-app-membership.server.ts`)
route mutation (`app/routes/$orgSlug/settings/repositories._index/`)
UI (`+components/repo-columns.tsx`)
batch CLI (`batch/commands/reassign-broken-repositories.ts`)
tests
満たす受入条件
Stack 位置
```text
PR 1 (#288): schema
└ PR 2 (#296): query/octokit
└ PR 3 (#290): webhook/membership
└ PR 4 (#291): UI
└ [PR 5: repo UI] ← this PR
└ PR 6 (backfill)
└ PR 7 (strict)
```
テスト
🤖 Generated with Claude Code
Summary by CodeRabbit
リリースノート