fix: implement decline applicant flow#253
Conversation
|
@uche102 is attempting to deploy a commit to the Threadflow Team on Vercel. A member of the Team first needs to authorize it. |
|
@frank0277 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
📝 WalkthroughWalkthroughAdds an applicant-decline flow: dashboard UI (Decline button + AlertDialog with optional reason), optimistic ChangesApplicant decline flow
CI workflow token wiring
Sequence DiagramsequenceDiagram
participant Reviewer
participant Dashboard
participant Mutation
participant Cache
Reviewer->>Dashboard: Click Decline
Dashboard->>Dashboard: Open AlertDialog
Reviewer->>Dashboard: Confirm with optional reason
Dashboard->>Mutation: handleDeclineApplicant(bountyId, applicant, reason)
Mutation->>Cache: onMutate: mark DECLINED and remove from applications
Cache-->>Mutation: onSuccess/onSettled
Mutation-->>Dashboard: optimistic UI already updated
Dashboard->>Reviewer: Remove card and show toast
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
9b0244b to
a8e4408
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/bounty/application-review-dashboard.tsx`:
- Around line 67-69: The component is crashing because useEffect is not imported
from React and the local hoisted stub function useEffect (the one that does
`throw new Error("Function not implemented.")` around lines 317-319) is being
called; update the React import to include useEffect (and drop unused useMemo if
appropriate), remove the local stub function named useEffect, and ensure the
effect call inside the component that calls setReviewApplications(applications)
uses the real React useEffect.
In `@hooks/use-bounty-application.ts`:
- Around line 214-231: The current update to prev.bounty.applications maps the
matching application to status "DECLINED" with declineReason/declinedReason and
declinedAt but then immediately chains .filter(...) which removes that declined
record from the cache; remove the chained .filter so the mapped DECLINED
application (with reason and declinedAt) is kept in prev.bounty.applications,
ensuring the declineReason persists in cache (update the code around the
applications mapping that references applicantAddress, reason, and declinedAt in
hooks/use-bounty-application.ts).
- Around line 184-199: useDeclineApplicant’s mutationFn only returns an
optimistic object and there is no persistence path in ApplicationContractClient,
so declined state is not durable; either (A) add a real decline
endpoint/contract and call it from useDeclineApplicant: implement a
declineApplicant(bountyId, applicantAddress, reason) method on
ApplicationContractClient, call that inside mutationFn (or mutationFn should
call the client and return the persisted result), and ensure the backend exposes
bounty.applications so bountyKeys.detail / bountyKeys.lists refetches reflect
the decline, or (B) if backend changes aren’t possible now, remove the fake
persisted declinedAt behavior and instead implement a proper optimistic update
via react-query callbacks (onMutate / onError / onSettled) to update the cached
applications for bountyKeys.detail locally and avoid/invalidate refetches that
would overwrite it; reference useDeclineApplicant, ApplicationContractClient,
bountyKeys.detail, bountyKeys.lists, and getApplications in
components/bounty-detail/bounty-detail-client.tsx when making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c58e9020-c495-4081-99eb-28724d2561b0
📒 Files selected for processing (2)
components/bounty/application-review-dashboard.tsxhooks/use-bounty-application.ts
| useEffect(() => { | ||
| setReviewApplications(applications); | ||
| }, [applications]); |
There was a problem hiding this comment.
Critical: useEffect is not imported — this call hits the throwing stub at Lines 317-319 and crashes the component on every render.
react is imported as { useMemo, useState } (Line 2), so useEffect resolves to the hoisted local function useEffect (Lines 317-319) which does throw new Error("Function not implemented."). The component will throw immediately.
🐛 Proposed fix: import the real `useEffect` and delete the stub
Line 2 (also drops the now-unused useMemo):
-import { useMemo, useState } from "react";
+import { useEffect, useState } from "react";Lines 317-319:
-function useEffect(arg0: () => void, arg1: Application[][]) {
- throw new Error("Function not implemented.");
-}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@components/bounty/application-review-dashboard.tsx` around lines 67 - 69, The
component is crashing because useEffect is not imported from React and the local
hoisted stub function useEffect (the one that does `throw new Error("Function
not implemented.")` around lines 317-319) is being called; update the React
import to include useEffect (and drop unused useMemo if appropriate), remove the
local stub function named useEffect, and ensure the effect call inside the
component that calls setReviewApplications(applications) uses the real React
useEffect.
| ...prev.bounty, | ||
| applications: prev.bounty.applications | ||
| .map((application) => | ||
| application.applicantAddress === applicantAddress | ||
| ? { | ||
| ...application, | ||
| status: "DECLINED", | ||
| declineReason: reason?.trim() || undefined, | ||
| declinedReason: reason?.trim() || undefined, | ||
| declinedAt, | ||
| } | ||
| : application, | ||
| ) | ||
| .filter( | ||
| (application) => | ||
| application.applicantAddress !== applicantAddress, | ||
| ), | ||
| updatedAt: declinedAt, |
There was a problem hiding this comment.
.filter() discards the record you just marked DECLINED — the decline reason is never recorded in cache.
The .map() marks the matching application as DECLINED and stores declineReason/declinedReason, but the chained .filter() then removes that exact entry, throwing away all of that work. This violates the requirement to record the decline reason in the cache.
Drop the filter so the declined record (with its reason) persists; the dashboard already removes the applicant from its own visible list.
🐛 Proposed fix: keep the declined record instead of filtering it out
applications: prev.bounty.applications
.map((application) =>
application.applicantAddress === applicantAddress
? {
...application,
status: "DECLINED",
declineReason: reason?.trim() || undefined,
declinedReason: reason?.trim() || undefined,
declinedAt,
}
: application,
- )
- .filter(
- (application) =>
- application.applicantAddress !== applicantAddress,
- ),
+ ),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ...prev.bounty, | |
| applications: prev.bounty.applications | |
| .map((application) => | |
| application.applicantAddress === applicantAddress | |
| ? { | |
| ...application, | |
| status: "DECLINED", | |
| declineReason: reason?.trim() || undefined, | |
| declinedReason: reason?.trim() || undefined, | |
| declinedAt, | |
| } | |
| : application, | |
| ) | |
| .filter( | |
| (application) => | |
| application.applicantAddress !== applicantAddress, | |
| ), | |
| updatedAt: declinedAt, | |
| ...prev.bounty, | |
| applications: prev.bounty.applications | |
| .map((application) => | |
| application.applicantAddress === applicantAddress | |
| ? { | |
| ...application, | |
| status: "DECLINED", | |
| declineReason: reason?.trim() || undefined, | |
| declinedReason: reason?.trim() || undefined, | |
| declinedAt, | |
| } | |
| : application, | |
| ), | |
| updatedAt: declinedAt, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/use-bounty-application.ts` around lines 214 - 231, The current update
to prev.bounty.applications maps the matching application to status "DECLINED"
with declineReason/declinedReason and declinedAt but then immediately chains
.filter(...) which removes that declined record from the cache; remove the
chained .filter so the mapped DECLINED application (with reason and declinedAt)
is kept in prev.bounty.applications, ensuring the declineReason persists in
cache (update the code around the applications mapping that references
applicantAddress, reason, and declinedAt in hooks/use-bounty-application.ts).
Benjtalkshow
left a comment
There was a problem hiding this comment.
The dashboard crashes at runtime. components/bounty/application-review-dashboard.tsx:67 calls useEffect, but the file only imports useMemo, useState from React. An AI auto-generated a fake stub at lines 317-319 that throws Error: Function not implemented. Build passes because the stub satisfies TypeScript, but the moment the parent passes a new applications prop the effect fires and the page crashes.
Three things to fix:
-
Import
useEffectfrom React on line 2 and delete the fake stub at the bottom of the file (lines 317-319). Also remove the unuseduseMemoimport. ESLint flags all three as warnings. -
hooks/use-bounty-application.ts:221-222sets bothdeclineReasonanddeclinedReasonto the same value. One is a typo. Pick one and delete the other. -
The dashboard duplicates state by syncing
applicationsprop intoreviewApplicationslocal state. That's what the broken effect was trying to keep in sync. TheuseDeclineApplicanthook already does the optimistic filter in the React Query cache. Drop the localreviewApplicationsstate entirely and render directly from the prop (which itself comes from the cache via the parent). Single source of truth.
Once those are in this is ready.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/check-schema.yml:
- Line 18: The workflow uses mutable tags "actions/checkout@v4" and
"actions/setup-node@v4"; update those uses entries to the corresponding full
40-character commit SHAs (replace each "`@v4`" occurrence for checkout and
setup-node with the commit SHA from the respective GitHub Actions repo) so the
CI references an exact immutable revision; ensure you update all occurrences in
the file (both checkout usages and the setup-node usage) and commit the updated
workflow.
- Around line 10-40: The job "check-schema" lacks an explicit permissions block
so it inherits full default GITHUB_TOKEN scopes; add a minimal permissions:
block under the check-schema job to grant only what is required (for example
read-only contents and repo access needed for actions/checkout and any API calls
your script uses) and remove unnecessary scopes; update the job definition
(check-schema) to include a permissions section that restricts permissions to
the least-privilege set required by the workflow.
- Around line 17-18: Update both checkout steps that use actions/checkout@v4 to
set persist-credentials: false so the runner does not persist the token to local
git config; locate the checkout invocations (the steps using
actions/checkout@v4) and add a persist-credentials: false entry under each
step's with: block (ensure YAML indentation is correct).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f2bf771a-2fa2-4552-badf-6129061224db
📒 Files selected for processing (3)
.github/workflows/check-schema.ymlcomponents/bounty/application-review-dashboard.tsxhooks/use-bounty-application.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- components/bounty/application-review-dashboard.tsx
| check-schema: | ||
| name: Check schema is in sync | ||
| runs-on: ubuntu-latest | ||
| env: | ||
| BOUNDLESS_NESTJS_TOKEN: ${{ secrets.BOUNDLESS_NESTJS_TOKEN }} | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Checkout canonical schema repo (private) | ||
| if: ${{ secrets.BOUNDLESS_NESTJS_TOKEN != '' }} | ||
| if: ${{ env.BOUNDLESS_NESTJS_TOKEN != '' }} | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: boundlessfi/boundless-nestjs | ||
| path: boundless-nestjs | ||
| token: ${{ secrets.BOUNDLESS_NESTJS_TOKEN }} | ||
| token: ${{ env.BOUNDLESS_NESTJS_TOKEN }} | ||
|
|
||
| - name: Note about private repo | ||
| if: ${{ secrets.BOUNDLESS_NESTJS_TOKEN == '' }} | ||
| if: ${{ env.BOUNDLESS_NESTJS_TOKEN == '' }} | ||
| run: | | ||
| echo "No secret BOUNDLESS_NESTJS_TOKEN provided; skipping checkout of private repo." | ||
| echo "If the canonical schema is in the private repo, add a repository secret named BOUNDLESS_NESTJS_TOKEN with a PAT that has access to boundlessfi/boundless-nestjs." | ||
|
|
||
| - name: Set up Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: '20' | ||
| node-version: "20" | ||
|
|
||
| - name: Run schema check | ||
| run: node ./scripts/sync-schema.js --check | ||
| run: node ./scripts/sync-schema.js --check No newline at end of file |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify explicit permissions are present in workflow files
rg -n '^\s*permissions\s*:' .github/workflows/*.yml .github/workflows/*.yamlRepository: boundlessfi/bounties
Length of output: 129
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Workflow files:"
ls -la .github/workflows || true
echo
echo "Searching for explicit job/workflow-level permissions blocks:"
# Only search files that actually exist
for f in $(ls .github/workflows/*.yml 2>/dev/null || true); do
rg -n '^\s*permissions\s*:' "$f" || true
done
for f in $(ls .github/workflows/*.yaml 2>/dev/null || true); do
rg -n '^\s*permissions\s*:' "$f" || true
done
echo
echo "=== check-schema.yml (lines 1-120) ==="
nl -ba .github/workflows/check-schema.yml | sed -n '1,120p'Repository: boundlessfi/bounties
Length of output: 478
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== check-schema.yml (cat -n) ==="
cat -n .github/workflows/check-schema.yml | sed -n '1,140p'
echo
echo "=== ci.yml (permissions search) ==="
rg -n '^\s*permissions\s*:' .github/workflows/ci.yml || true
echo
echo "=== check-schema.yml permissions search ==="
rg -n '^\s*permissions\s*:' .github/workflows/check-schema.yml || true
echo
echo "=== check-schema.yml persist-credentials search ==="
rg -n 'persist-credentials' .github/workflows/check-schema.yml || true
echo
echo "=== check-schema.yml action version pins ==="
rg -n 'uses:\s*actions/(checkout|setup-node)@' .github/workflows/check-schema.ymlRepository: boundlessfi/bounties
Length of output: 1893
Add an explicit least-privilege permissions block.
jobs.check-schema currently has no permissions: block, so the workflow falls back to default GITHUB_TOKEN scopes.
Suggested fix
jobs:
check-schema:
name: Check schema is in sync
runs-on: ubuntu-latest
+ permissions:
+ contents: read
env:
BOUNDLESS_NESTJS_TOKEN: ${{ secrets.BOUNDLESS_NESTJS_TOKEN }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| check-schema: | |
| name: Check schema is in sync | |
| runs-on: ubuntu-latest | |
| env: | |
| BOUNDLESS_NESTJS_TOKEN: ${{ secrets.BOUNDLESS_NESTJS_TOKEN }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Checkout canonical schema repo (private) | |
| if: ${{ secrets.BOUNDLESS_NESTJS_TOKEN != '' }} | |
| if: ${{ env.BOUNDLESS_NESTJS_TOKEN != '' }} | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: boundlessfi/boundless-nestjs | |
| path: boundless-nestjs | |
| token: ${{ secrets.BOUNDLESS_NESTJS_TOKEN }} | |
| token: ${{ env.BOUNDLESS_NESTJS_TOKEN }} | |
| - name: Note about private repo | |
| if: ${{ secrets.BOUNDLESS_NESTJS_TOKEN == '' }} | |
| if: ${{ env.BOUNDLESS_NESTJS_TOKEN == '' }} | |
| run: | | |
| echo "No secret BOUNDLESS_NESTJS_TOKEN provided; skipping checkout of private repo." | |
| echo "If the canonical schema is in the private repo, add a repository secret named BOUNDLESS_NESTJS_TOKEN with a PAT that has access to boundlessfi/boundless-nestjs." | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| node-version: "20" | |
| - name: Run schema check | |
| run: node ./scripts/sync-schema.js --check | |
| run: node ./scripts/sync-schema.js --check | |
| check-schema: | |
| name: Check schema is in sync | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| env: | |
| BOUNDLESS_NESTJS_TOKEN: ${{ secrets.BOUNDLESS_NESTJS_TOKEN }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Checkout canonical schema repo (private) | |
| if: ${{ env.BOUNDLESS_NESTJS_TOKEN != '' }} | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: boundlessfi/boundless-nestjs | |
| path: boundless-nestjs | |
| token: ${{ env.BOUNDLESS_NESTJS_TOKEN }} | |
| - name: Note about private repo | |
| if: ${{ env.BOUNDLESS_NESTJS_TOKEN == '' }} | |
| run: | | |
| echo "No secret BOUNDLESS_NESTJS_TOKEN provided; skipping checkout of private repo." | |
| echo "If the canonical schema is in the private repo, add a repository secret named BOUNDLESS_NESTJS_TOKEN with a PAT that has access to boundlessfi/boundless-nestjs." | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| - name: Run schema check | |
| run: node ./scripts/sync-schema.js --check |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 17-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 20-26: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[warning] 10-40: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 35-35: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/check-schema.yml around lines 10 - 40, The job
"check-schema" lacks an explicit permissions block so it inherits full default
GITHUB_TOKEN scopes; add a minimal permissions: block under the check-schema job
to grant only what is required (for example read-only contents and repo access
needed for actions/checkout and any API calls your script uses) and remove
unnecessary scopes; update the job definition (check-schema) to include a
permissions section that restricts permissions to the least-privilege set
required by the workflow.
| - name: Checkout repository | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect checkout steps and whether persist-credentials is set
rg -n -C3 'uses:\s*actions/checkout@' .github/workflows/*.yml .github/workflows/*.yaml
rg -n 'persist-credentials:\s*false' .github/workflows/*.yml .github/workflows/*.yamlRepository: boundlessfi/bounties
Length of output: 1670
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Show the relevant section of the workflow with line numbers
nl -ba .github/workflows/check-schema.yml | sed -n '1,120p'
# 2) Search only .yml files for persist-credentials on checkout steps
rg -n -C2 'uses:\s*actions/checkout@' .github/workflows/*.yml
rg -n 'persist-credentials:\s*false' .github/workflows/*.yml || true
rg -n 'persist-credentials:' .github/workflows/*.yml || trueRepository: boundlessfi/bounties
Length of output: 107
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Show the beginning of the workflow with line numbers
cat -n .github/workflows/check-schema.yml | sed -n '1,140p'
# 2) Search only .yml files for persist-credentials on checkout steps
rg -n -C2 'uses:\s*actions/checkout@' .github/workflows/*.yml
rg -n 'persist-credentials:\s*false' .github/workflows/*.yml || true
rg -n 'persist-credentials:' .github/workflows/*.yml || trueRepository: boundlessfi/bounties
Length of output: 2727
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Confirm persist-credentials usage only in check-schema.yml
rg -n 'persist-credentials' .github/workflows/check-schema.yml || true
rg -n -C2 'uses:\s*actions/checkout@' .github/workflows/check-schema.yml
# Reprint the relevant section cleanly
cat -n .github/workflows/check-schema.yml | sed -n '10,40p'Repository: boundlessfi/bounties
Length of output: 1689
Disable credential persistence on checkout steps in .github/workflows/check-schema.yml.
actions/checkout@v4 should set persist-credentials: false on both checkout steps (lines 17-18 and 20-26) to prevent the token/credentials from being written to the runner’s local git config for subsequent steps.
Suggested fix
- name: Checkout repository
uses: actions/checkout@v4
+ with:
+ persist-credentials: false
- name: Checkout canonical schema repo (private)
if: ${{ env.BOUNDLESS_NESTJS_TOKEN != '' }}
uses: actions/checkout@v4
with:
repository: boundlessfi/boundless-nestjs
path: boundless-nestjs
token: ${{ env.BOUNDLESS_NESTJS_TOKEN }}
+ persist-credentials: false🧰 Tools
🪛 zizmor (1.25.2)
[warning] 17-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/check-schema.yml around lines 17 - 18, Update both
checkout steps that use actions/checkout@v4 to set persist-credentials: false so
the runner does not persist the token to local git config; locate the checkout
invocations (the steps using actions/checkout@v4) and add a persist-credentials:
false entry under each step's with: block (ensure YAML indentation is correct).
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify all workflow `uses:` entries are SHA pinned (40-hex)
rg -n '^\s*uses:\s*[^@]+@' .github/workflows/*.yml .github/workflows/*.yamlRepository: boundlessfi/bounties
Length of output: 931
Pin GitHub Actions to commit SHAs instead of mutable tags.
.github/workflows/check-schema.yml uses mutable action tags (actions/checkout@v4 at lines 18 and 22, actions/setup-node@v4 at line 35); pin to full 40-hex commit SHAs for reproducible, safer CI.
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 17-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/check-schema.yml at line 18, The workflow uses mutable
tags "actions/checkout@v4" and "actions/setup-node@v4"; update those uses
entries to the corresponding full 40-character commit SHAs (replace each "`@v4`"
occurrence for checkout and setup-node with the commit SHA from the respective
GitHub Actions repo) so the CI references an exact immutable revision; ensure
you update all occurrences in the file (both checkout usages and the setup-node
usage) and commit the updated workflow.
Benjtalkshow
left a comment
There was a problem hiding this comment.
The new commit only touches CI config and doesn't address any of the three blockers from the previous review. The fake useEffect stub at line 317 is still there, the declineReason/declinedReason duplication is still there, and the local reviewApplications mirror state is still there.
The dashboard will still crash at runtime the moment the parent re-renders with new applications because the stub throws Error: Function not implemented. Please fix the three items from the previous review before this can go forward.
Implements the applicant decline flow on the application review dashboard.
Added
useDeclineApplicantmutationAdded Decline button beside Select on each application card
Added confirmation dialog with optional decline reason
Optimistically removes declined applicants from the review queue
Rolls back local dashboard state on decline failure
Removes declined applicants from comparison mode
Closes #208
Summary by CodeRabbit
New Features
Bug Fixes
Chores