Skip to content

fix(FE-567): add approve/reject to API request detail page#569

Merged
babltiga merged 4 commits into
mainfrom
fix/FE-567-api-request-detail-approve-reject
Jul 3, 2026
Merged

fix(FE-567): add approve/reject to API request detail page#569
babltiga merged 4 commits into
mainfrom
fix/FE-567-api-request-detail-approve-reject

Conversation

@babltiga

@babltiga babltiga commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Closes #567

Problem

A reviewer/admin opening a PENDING_REVIEW API request (apigov / AF-500) from /api-requests/api-requests/:id hit a dead-end: the detail page rendered only Execute (when APPROVED) and Cancel (when pending), with no approve/reject action and no link to the /api-reviews queue. The request looked unactionable and appeared stuck in PENDING_REVIEW.

Fix (frontend-only)

The backend endpoints (POST /api/v1/api-reviews/{id}/{approve,reject}) and the frontend API layer (approveApiReview/rejectApiReview) already existed — this wires up the UI.

frontend/src/pages/apigov/ApiRequestDetailPage.tsx:

  • Adds inline Approve / Reject buttons + a shared comment modal, reusing the exact pattern from ApiReviewQueuePage so the two apigov review surfaces behave identically.
  • Gated by canDecide = (REVIEWER/ADMIN) && PENDING_REVIEW && submitted_by !== user.id (self-approval also blocked server-side).
  • Optional comment for both actions (matches the backend DTO — @Size(max=2000), no @NotBlank — and the queue page), so validation parity holds.
  • Cancel is now gated with !canDecide (a reviewer isn't the submitter, so it wouldn't apply) — the submitter path is unchanged.
  • Zero new i18n keys — reuses the existing apiGov.reviews.* block, avoiding 7-locale parity work.

E2E (per the e2e-parity rule for new user-facing flows)

  • New spec e2e/tests/api-request-review.spec.ts: an ANALYST (granted can_write) submits a write op → routes to PENDING_REVIEW (default require_review_writes=true, AI skipped with no ai_config) → the admin approves from the detail page and the status flips to APPROVED.
  • New helpers in e2e/helpers/apiConnectors.ts: grantApiConnectorPermissionViaApi, submitApiRequestViaApi.

Docs

  • docs/06-frontend.md — the /api-requests/:id row now notes the inline reviewer approve/reject modal.
  • docs/04-api-spec.md — no change (endpoints already documented).
  • README / website — no change (bugfix to an existing governed-API flow; pitch, feature list, RBAC matrix and env vars unaffected).

Deferred

The "link the detail/list view to /api-reviews" follow-up from the issue is out of scope — the inline actions resolve the dead-end directly.

Verification

  • npm run lint (0 errors), npm run typecheck, npm run test:coverage (1128 tests pass, coverage above thresholds), npm run build — all green.
  • Full e2e docker stack not run locally: host ports 5173/8080 are occupied by a running local app, and the e2e CI job runs the new spec.

A reviewer/admin opening a PENDING_REVIEW API request at /api-requests/:id
previously found only Execute/Cancel and no way to action it, so the request
appeared stuck. Add an inline approve/reject comment modal (reusing the
ApiReviewQueuePage pattern and the existing approveApiReview/rejectApiReview
API layer), gated by canDecide (REVIEWER/ADMIN, PENDING_REVIEW, not the
submitter). Reuses existing apiGov.reviews.* i18n keys (no new keys).

Adds an e2e spec (analyst submits a write op -> PENDING_REVIEW -> admin
approves from the detail page) plus grant/submit e2e helpers, and updates
docs/06-frontend.md.

Closes #567
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Frontend Test Results

1 130 tests  ±0   1 130 ✅ ±0   2m 55s ⏱️ +50s
  153 suites ±0       0 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 32d765e. ± Comparison against base commit 72b9654.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Frontend Coverage (frontend)

Status Category Percentage Covered / Total
🔵 Lines 94.18% (🎯 90%) 1992 / 2115
🔵 Statements 92.11% (🎯 90%) 2220 / 2410
🔵 Functions 91.46% (🎯 90%) 600 / 656
🔵 Branches 83.69% (🎯 80%) 1247 / 1490
File CoverageNo changed files found.
Generated in workflow #715 for commit 32d765e by the Vitest Coverage Report Action

babltiga added 3 commits July 3, 2026 12:31
The grant-permission call 500'd because the invitation response carries the
invitation id, not the user id. Resolve the submitter's real user id via
GET /api/v1/me before granting. Also poll GET /api-requests/{id} for
PENDING_REVIEW instead of asserting the async submit response.
The grant body omitted can_break_glass; Jackson 3 maps the absent primitive
boolean constructor param to null and fails (FAIL_ON_NULL_FOR_PRIMITIVES),
returning 500. Send all three booleans explicitly, matching the frontend.
After approval, 'Approved' renders both in the StatusPill and the decisions
table, tripping strict-mode. Scope the assertion to .af-pill.
@babltiga
babltiga merged commit 7588ba0 into main Jul 3, 2026
14 checks passed
@babltiga
babltiga deleted the fix/FE-567-api-request-detail-approve-reject branch July 3, 2026 09:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API request stuck in PENDING_REVIEW: no approve/reject action on the API request detail page

1 participant