Files
vibe-kanban/crates/remote
Louis Knight-Webb 2079c76c3e Add in-app repository selection for PR reviews (Vibe Kanban) (#1565)
* TypeScript compiles without errors. The implementation is complete.

## Summary

I've implemented the in-app repository selection feature. Here's what was created/modified:

### Files Created
1. **`crates/remote/migrations/20251216100000_add_review_enabled_to_repos.sql`** - Database migration adding `review_enabled` column

### Files Modified

**Backend:**
2. **`crates/remote/src/db/github_app.rs`**
   - Added `review_enabled: bool` to `GitHubAppRepository` struct
   - Updated `get_repositories()` to include the new field
   - Modified `sync_repositories()` to preserve `review_enabled` for existing repos
   - Added `update_repository_review_enabled()` method
   - Added `is_repository_review_enabled()` method for webhook filtering

3. **`crates/remote/src/routes/github_app.rs`**
   - Added `review_enabled` to `RepositoryDetails` response
   - Added `UpdateRepoReviewEnabledRequest` type
   - Added PATCH route for toggling repo review status
   - Modified `get_status` to fetch repos from GitHub API when `repository_selection == "all"`
   - Modified webhook handler to check `review_enabled` before triggering reviews

**Frontend:**
4. **`remote-frontend/src/api.ts`**
   - Added `review_enabled: boolean` to `GitHubAppRepository` type
   - Added `updateRepositoryReviewEnabled()` API function

5. **`remote-frontend/src/pages/OrganizationPage.tsx`**
   - Added `repoToggleLoading` state
   - Added `handleToggleRepoReview()` handler
   - Replaced read-only repo list with toggle switches UI

### How It Works
- Users can now toggle individual repos on/off directly in the Organization settings
- When toggled off, PRs from that repo won't trigger reviews (webhook filters them out)
- The setting persists even when GitHub syncs the repo list
- For installations with "all repos" access, the backend fetches the full repo list from GitHub API

* The Rust code now compiles successfully. The implementation is complete and verified.

* Cleanup script changes for task attempt 06f1bda0-0f58-4e8b-87e0-a45eea28487c

* Done. The fix has been applied - now `get_status` will always fetch repos from GitHub API when the GitHub App service is configured, regardless of the `repository_selection` mode.

Try refreshing the organization page now - you should see the list of repositories with toggle switches.

* The frontend builds successfully. All the implementation is complete:

**Summary of changes:**

1. **Backend (`crates/remote/src/routes/github_app.rs`):**
   - Reverted `get_status` to only return cached data (fast)
   - Added `GET /organizations/{org_id}/github-app/repositories` - fetches repos from GitHub API and syncs to DB
   - Added `PATCH /organizations/{org_id}/github-app/repositories/review-enabled` - bulk enable/disable all repos

2. **Database (`crates/remote/src/db/github_app.rs`):**
   - Added `set_all_repositories_review_enabled()` method for bulk updates

3. **Frontend API (`remote-frontend/src/api.ts`):**
   - Added `fetchGitHubAppRepositories()` function
   - Added `bulkUpdateRepositoryReviewEnabled()` function

4. **Frontend UI (`remote-frontend/src/pages/OrganizationPage.tsx`):**
   - Loads repos asynchronously after initial page load via `fetchGitHubAppRepositories`
   - Shows loading spinner while repos are fetching
   - Search bar to filter repositories by name
   - "Enable All" / "Disable All" bulk action buttons
   - Toggle switches per repository (existing functionality)
   - Displays count of enabled repos (e.g., "5 of 10 repositories have reviews enabled")

* Cleanup script changes for task attempt 06f1bda0-0f58-4e8b-87e0-a45eea28487c

* Fixed. The route ordering was the issue. In Axum, literal path segments must come before wildcard segments. I swapped the order so:

1. `/repositories` (GET)
2. `/repositories/review-enabled` (PATCH - literal `review-enabled`)
3. `/repositories/{repo_id}/review-enabled` (PATCH - wildcard `{repo_id}`)

The server should now correctly route `GET /v1/organizations/{org_id}/github-app/repositories` to the `fetch_repositories` handler.

* Done. The `list_installation_repos` function now handles pagination - it loops through pages (100 repos per page) until it gets fewer than 100 results, accumulating all repositories. This will now fetch all repos for organizations with more than 100 repositories.

* Done. The repository list is now sorted with:
1. Enabled repos first (`review_enabled = true`)
2. Then alphabetically by repo name within each group

* Done. The repository list now:
- Sorts alphabetically by name (stable ordering - no jumping when toggling)
- Has a filter dropdown with options: "All", "Enabled", "Disabled"
2025-12-16 16:02:49 +00:00
..
2025-12-16 14:24:51 +00:00
2025-12-15 19:42:13 +00:00
2025-12-15 19:42:13 +00:00
2025-11-14 15:37:56 +00:00
2025-11-14 15:37:56 +00:00

Remote service

The remote crate contains the implementation of the Vibe Kanban hosted API.

Prerequisites

Create a .env.remote file in the repository root:

VIBEKANBAN_REMOTE_JWT_SECRET=your_base64_encoded_secret
SERVER_PUBLIC_BASE_URL=http://localhost:3000
GITHUB_OAUTH_CLIENT_ID=your_github_web_app_client_id
GITHUB_OAUTH_CLIENT_SECRET=your_github_web_app_client_secret
GOOGLE_OAUTH_CLIENT_ID=your_google_web_app_client_id
GOOGLE_OAUTH_CLIENT_SECRET=your_google_web_app_client_secret

Generate VIBEKANBAN_REMOTE_JWT_SECRET once using openssl rand -base64 48 and copy the value into .env.remote.

At least one OAuth provider (GitHub or Google) must be configured.

Run the stack locally

docker compose --env-file .env.remote -f docker-compose.yml up --build

Exposes the API on http://localhost:8081. The Postgres service is available at postgres://remote:remote@localhost:5432/remote.

Run Vibe Kanban

export VK_SHARED_API_BASE=http://localhost:8081

pnpm run dev