41 lines
2.4 KiB
Markdown
41 lines
2.4 KiB
Markdown
|
|
---
|
||
|
|
brief: 2
|
||
|
|
convoy: repo-discovery-onboarding
|
||
|
|
role: role-implementer
|
||
|
|
title: Repository picker and batch connection
|
||
|
|
status: ready
|
||
|
|
priority: P1
|
||
|
|
slice_dependencies: [1]
|
||
|
|
recommended_model: qwen-coder
|
||
|
|
model_tier: local
|
||
|
|
workspace_id: global
|
||
|
|
---
|
||
|
|
|
||
|
|
# Brief 2 — Repository picker and batch connection
|
||
|
|
|
||
|
|
## Goal
|
||
|
|
|
||
|
|
Workspace admins can search discovered repositories, select multiple entries, and connect them to the current workspace in one idempotent operation while retaining the existing paste-URL workflow.
|
||
|
|
|
||
|
|
Backlog task: `plans/Plan-automation-foundation/Epic-repo-discovery-onboarding/Task-repo-picker-modal.md`.
|
||
|
|
|
||
|
|
## Files
|
||
|
|
|
||
|
|
- `apps/web/server/routers/connected-repos.ts` — add zod-validated, admin-only `batchConnect`. Re-resolve or validate selected remote IDs server-side; do not trust client-supplied owner, URLs, forge type, or token references. Insert with workspace scoping and conflict-safe behavior against `connected_repos_workspace_repo_unique`.
|
||
|
|
- `apps/web/app/(app)/[workspaceSlug]/settings/repos/page.tsx` — retain manual connection and add a discovery entry point with source/connection-state handling.
|
||
|
|
- `apps/web/components/settings/repo-picker-dialog.tsx` (new only if extraction improves the existing page) — search, pagination/load-more, multi-select, connected/disabled states, loading/error/empty states, and import progress using existing UI primitives.
|
||
|
|
|
||
|
|
## Acceptance
|
||
|
|
|
||
|
|
- The picker supports GitHub and Forgejo/Gitea connection states returned by Brief 1 and gives actionable reauthorization/configuration messages.
|
||
|
|
- Search matches full name and description without discarding selection when paging.
|
||
|
|
- Already-connected repos cannot be selected.
|
||
|
|
- `batchConnect` is atomic for valid selections, idempotent for duplicates, tenant-scoped, and returns per-repo connected/already-connected results.
|
||
|
|
- A stale or forged client selection cannot connect an arbitrary URL.
|
||
|
|
- Successful import invalidates `connectedRepos.list` and `listAvailable` and leaves the manual paste-URL dialog usable.
|
||
|
|
- Lint and type-check pass; cover server-side validation and selection-state helpers with tests where feasible.
|
||
|
|
|
||
|
|
## Prompt for implementer
|
||
|
|
|
||
|
|
Implement only Brief 2 after Brief 1 is complete. Read the matching backlog task and existing repo settings page before editing. Reuse Radix and `components/ui`; do not implement repository document ingestion or agent setup. Never send forge credentials to a client component.
|