Files
kandev/docs/plans/github-pr-review-rerequest/plan.md
T
2026-08-24 11:09:03 +00:00

5.7 KiB

spec, created, status
spec created status
docs/specs/ui/requirements/github-pr-review-actions.md 2026-07-23 completed

Implementation Plan: GitHub PR Review Re-request

Overview

Add the missing GitHub review-request write contract, expose it beside a dismissed review, and reuse that PR detail surface on phones. Backend and core frontend work can proceed in parallel because the route and payload are fixed by the spec; mobile composition and E2E follow after the shared action works.

Backend

GitHub client contract and implementations

  • Add RequestReviewers(ctx, owner, repo, number, reviewers) to apps/backend/internal/github/client.go.
  • Implement GitHub REST POST /repos/{owner}/{repo}/pulls/{number}/requested_reviewers in gh_client.go and pat_client.go.
  • Keep noop_client.go fail-closed.
  • Make mock_client.go record the request and update the seeded PR's RequestedReviewers, so integration and browser tests observe the same transition as GitHub.

Service and HTTP route

  • Add a service method in service_pr.go that delegates the write and deletes the affected prFeedbackCache and prStatusCache key after success.
  • Register POST /api/v1/github/prs/:owner/:repo/:number/requested-reviewers in controller.go.
  • Validate the PR number and a non-empty list of non-blank reviewer logins. Return the established GitHub/configuration error response and {"requested": true} on success.

Frontend

API and dismissed-review action

  • Add requestPRReviewers to apps/web/lib/api/domains/github-api.ts.
  • In pr-detail-panel.tsx, own mutation state, success/error toast, and feedback refresh using the existing approve-action pattern.
  • In pr-reviews-section.tsx, reconcile review history with explicit current requests case-insensitively. Only the latest DISMISSED review on an open PR gets a re-request action, and a requested reviewer renders once as pending.
  • Add a small accessible trailing action to pr-shared.tsx only if needed by the existing row layout. Use a compact direct sync action on wider screens and a minimum 44px touch target on phone/coarse-pointer layouts.

Mobile design contract

  • Desktop outcome: request the dismissed reviewer from the existing PR detail review row.
  • Phone entry: task bottom navigation Review.
  • Exemplar: GitLab's full-height mobile review in apps/web/components/task/mobile/session-mobile-layout.tsx, plus ReviewPRSelector for multi-PR selection.
  • Hierarchy/surface: optional PR selector, then one full-height PR detail surface; the dismissed-review action remains inside its review row.
  • Scroll/geometry: mobile layout owns 100dvh; PR content keeps one internal vertical scroll owner; existing bottom-nav safe-area padding stays authoritative; no document horizontal overflow.
  • Shared logic: the same feedback hook, request handler, PR selection, and reviews component serve every viewport. Only mobile composition differs.
  • Primary action: visible re-request control with an accessible reviewer name and at least a 44px active touch dimension.

Tests

  • Backend transport tests assert gh/PAT method, endpoint, and reviewer JSON.
  • Backend mock/service/controller tests assert mutation, validation, error behavior, and per-PR cache eviction.
  • Frontend API tests assert method, path, and body.
  • Review reconciliation tests cover dismissed-only eligibility, case-insensitive current requests, duplicate suppression, and closed PRs.
  • Mobile layout tests cover GitHub PR Review availability and fallback to the existing GitLab surface when no GitHub PR exists.

E2E Tests

  • Desktop: seed an open PR with a dismissed review, use the PR detail row action, and assert the reviewer becomes pending with no duplicate action.
  • Mobile: enter Review from bottom navigation, perform the same request, and assert pending state, 44px action geometry, viewport containment, and no document horizontal overflow.

Implementation Waves

Wave 1 (parallel):

Wave 2:

Wave 3:

Review remediation (parallel):

Verification

After targeted task checks, run formatting before the full pipeline:

make fmt
make typecheck test lint

Then run focused production-build browser coverage:

cd apps/web
pnpm e2e:run tests/pr/pr-rerequest-review.spec.ts tests/pr/mobile-pr-rerequest-review.spec.ts

Risks

  • GitHub keeps the old dismissed review in review history after a new request; explicit requested_reviewers must win during rendering.
  • Feedback/status caches can otherwise make a successful mutation look stale.
  • Adding GitHub to the phone Review destination must not remove the existing GitLab fallback for tasks without a GitHub PR.