Skip to content

V8 — Right Sidebar: PR Panel + Merge Gate (Linked Issues, CI Checks, Review & Merge) #339

@Luis85

Description

@Luis85

Parent epic: #326 · Depends on: F2, F3, F4 · Stories: US-029, US-046, US-047, US-048

Problem

The PR Panel is where review and merge happen — the operational endpoint of the entire MVP loop. The merge gate (reviewStatus === 'approved' AND checks === 'passing') must be enforced inside MergePullRequestUseCase, not only in the template. Hiding the button is a usability hint; the use case is the safety rail.

Solution

PRPanel.vue — right-panel content when right === 'pr'

No header bar — the topbar breadcrumb + sidebar active state already communicate context (per the design brief).

Sections (vertical scroll):

A. Linked Issues (conditional — only if pr.issueIds.length > 0):

  • icon · Issue number · truncated title · status dot (Open = green)
  • Click → useAppStateStore.goToIssue(num) (US-029)

B. CI Checks (collapsible — collapsed by default):

  • Header summary: ✓ 4/4 passing (green) / ✕ N failing (red) / ○ N pending (amber)
  • chevron flips to on expand
  • Expanded: row per check (icon + name + status text); click shows status-detail toast

C. Review & Merge (unified — one continuous workflow):

  • Review status icon + label (◎ Review required / ✓ Approved / ◐ Draft / ⊛ Merged), color-coded
  • Approve button (visible when reviewStatus !== 'approved' and PR is not a draft): click → ApprovePullRequestUseCase; on success: pr.reviewStatus = 'approved', panel re-renders, merge unlocks (US-046)
  • Merge button (visible only after approve): full-width purple; enabled only when pr.checks === 'passing'; click → MergePullRequestUseCase (which re-checks the gate internally); 800ms transition; on success: pr.status = 'merged', sidebar pill → purple ✓, panel re-renders (US-047)
  • Before approval: dimmed "Approve this PR to unlock merge" message (US-047)
  • Draft state: shows ◐ Mark as Ready button instead of Merge; click → MarkDraftReadyUseCase; converts draft to open; re-renders both panels (US-048)
  • PR AI input at the bottom: prompt "Ask about PR #N…"; context-button label "PR context ▾"

Use cases (application layer)

  • GetPullRequestUseCase (already in V4)
  • ApprovePullRequestUseCase
  • MergePullRequestUseCasegate re-check: returns Result.err(MergeBlocked) if reviewStatus !== 'approved' OR checks !== 'passing', regardless of what the UI thinks
  • MarkDraftReadyUseCase

Acceptance criteria

  • Linked Issues section appears only when pr.issueIds.length > 0; row click navigates to the linked issue (US-029)
  • CI Checks section collapsed by default; header summary text matches counts; expand shows per-check rows
  • CI row click shows a contextual toast with the check status
  • Approve button visible only when not approved + not draft; click dispatches ApprovePullRequestUseCase; on success, panel re-renders and Merge button becomes visible (US-046)
  • Merge button enabled only when checks === 'passing'; click dispatches MergePullRequestUseCase; 800ms delay; on success, status = 'merged' and sidebar pill updates (US-047)
  • Gate enforcement test: a unit test calls MergePullRequestUseCase directly with reviewStatus === 'review-required' and asserts it returns Result.err(MergeBlocked) — without involving the UI. Same with checks === 'failing'.
  • Before approval, the dimmed gate message is shown and the Merge button is hidden (US-047)
  • Draft PRs show ◐ Mark as Ready instead of Merge; click converts; re-renders sidebar row + panel (US-048)
  • PageObject tests cover: linked-issue navigation, CI expand/collapse, approve flow, merge flow, draft-ready flow, gate-blocked rendering
  • Storybook: PR review-required + checks passing, PR review-required + checks failing, PR approved + checks passing, draft PR, merged PR, PR with no linked issues
  • npm run typecheck, npm run lint, npm run test, npm run test:storybook pass

Out of scope

  • Request-changes flow (post-MVP — ApprovePullRequestUseCase only handles approval)
  • PR comment thread (V4 handles activity timeline + comments in the main view)
  • Merge methods other than the default — pick one in F1 ADR-08

Affected files

File Action
src/ui/components/right/PRPanel.vue New
src/ui/components/right/LinkedIssues.vue New
src/ui/components/right/CIChecks.vue New
src/ui/components/right/ReviewAndMerge.vue New
src/application/pullrequest/ApprovePullRequestUseCase.ts New
src/application/pullrequest/MergePullRequestUseCase.ts New (gate-enforcing)
src/application/pullrequest/MarkDraftReadyUseCase.ts New
src/application/pullrequest/MergeGateError.ts New
tests/application/pullrequest/MergePullRequestUseCase.test.ts New (gate behaviour tested here)
tests/ui/components/right/PRPanel.test.ts + .po.ts New
stories/right/PRPanel.stories.ts New

References

  • inputs/specorator-mvp-design-2026-05/Specorator_Design_Brief.html §"PR Panel" + §"Review & Merge" (gated workflow flow diagram)
  • inputs/specorator-mvp-design-2026-05/Specorator_Handoff.html §"PR Merge Workflow (Gated)"
  • inputs/specorator-mvp-design-2026-05/SYNTHESIS.md §"PR merge gate enforcement"
  • User stories US-029, US-046, US-047, US-048

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions