Skip to content

Close Nigeria grants to new applications#1430

Open
buildwithnidhi wants to merge 2 commits into
stagingfrom
nigeria-grant-close
Open

Close Nigeria grants to new applications#1430
buildwithnidhi wants to merge 2 commits into
stagingfrom
nigeria-grant-close

Conversation

@buildwithnidhi

@buildwithnidhi buildwithnidhi commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Problem

We need to stop accepting new applications for the Nigeria grants:

  • touching-grass-nigeria
  • solana-foundation-nigeria-grants

Changing the DB rows to CLOSED already makes the grant header look closed, but it did not fully close the application flow. A user could still see application-oriented CTAs in some places, and direct API submissions were not guarded by grant status.

Solution

This makes Grant.status = CLOSED mean "not accepting new applications" across the grant application path:

  • The create application API now rejects closed grants.
  • The main grant CTA shows Closed and disables only the new-application state.
  • Existing pending application edits still work, so we do not freeze users who already applied.
  • Existing approved/KYC/tranche flows still work.
  • The older grants listing card now shows Closed instead of Apply Now for closed grants.

The code is intentionally not hardcoded to Nigeria. The rollout stays scoped to Nigeria by updating only those two grant rows to CLOSED in the DB.

Why this approach

Hardcoding Nigeria slugs would solve today's request, but it would make future grant closures require code changes. Since the product already has OPEN | CLOSED grant status and the header already treats non-open grants as closed, using that status as the source of truth is the simpler and more maintainable path.

DB follow-up

After this is deployed, close only the two Nigeria grants:

UPDATE Grants
SET status = 'CLOSED'
WHERE slug IN (
  'touching-grass-nigeria',
  'solana-foundation-nigeria-grants'
);

Checks

  • pnpm lint passed
  • git diff --check passed
  • pnpm check-types was run and still fails on existing generated/schema mismatches unrelated to this change

Summary by CodeRabbit

  • New Features

    • Grants now show whether applications are open or closed, with closed grants displaying “Closed” instead of “Apply Now.”
    • The application action button now reflects grant availability more clearly and prevents starting new applications when a grant is closed.
  • Bug Fixes

    • Pending applications now consistently stay editable instead of switching to a different state in some cases.
    • Grant application validation now respects closed-status checks, while selected flows can still bypass that check when needed.

@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
earn Error Error Jul 3, 2026 7:59am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR adds grant status tracking: Prisma selects now include status, validateGrantRequest gains a skipStatusCheck option that throws "Grant is closed" for non-OPEN grants, UI components (ApplicationActionButton, GrantEntry) show a "Closed" state, and useApplicationState simplifies pending-status handling.

Changes

Grant Status Closure

Layer / File(s) Summary
Status field and validation check
src/features/grants/constants/schema.ts, src/features/grants/utils/validateGrantRequest.ts, src/app/api/grant-application/update/route.ts
Adds status to grantsSelect and the validation query, adds skipStatusCheck option that throws "Grant is closed" unless bypassed, and the update route now passes skipStatusCheck: true.
UI closed-state rendering
src/features/grants/components/ApplicationActionButton.tsx, src/features/grants/components/GrantEntry.tsx, src/pages/earn/grants/index.tsx
Derives closed status from grant.status !== 'OPEN', disabling buttons and showing "Closed" label; grants index page passes status to GrantEntry.
Pending application state simplification
src/features/grants/hooks/useApplicationState.ts
Pending applications now always resolve to 'ALLOW EDIT' regardless of grant.isNative.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • SuperteamDAO/earn#1363: Both PRs modify validateGrantRequest.ts and its option handling for skip-based validation bypasses.

Suggested reviewers: a20hek

Poem

A grant once open, now shut its door,
"Closed" says the button, forevermore.
Status flows through select and check,
No more applying once it's said and shecked—
A rabbit hops on, code review done,
Another burrow of features won! 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: closing Nigeria grants to new applications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nigeria-grant-close

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/features/grants/utils/validateGrantRequest.ts (1)

7-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider declaring an explicit return type.

validateGrantRequest's signature was modified in this change (new skipStatusCheck option) but the function still relies on inferred return type ({ grant, user }). As per coding guidelines, **/*.ts: "Declare return types for top-level module functions in TypeScript (exception: React components returning JSX)".

🤖 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 `@src/features/grants/utils/validateGrantRequest.ts` around lines 7 - 11,
`validateGrantRequest` is a top-level TypeScript function and should not rely on
an inferred `{ grant, user }` return type. Add an explicit return type to the
`validateGrantRequest` signature, using the same `grant` and `user` shape
currently returned, and keep the new `skipStatusCheck` option unchanged.

Source: Coding guidelines

src/features/grants/components/GrantEntry.tsx (1)

42-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fail-closed on missing status, and duplicated closure logic.

Two issues:

  1. status?: string means an omitted prop silently resolves isClosed to true (since undefined !== 'OPEN'). As per coding guidelines, **/*.{ts,tsx}: "Use property: Type | undefined instead of property?: Type ... to force explicit property passing and prevent bugs from accidentally omitting required properties." Making the field status: string | undefined (still optional at the value level, but requiring callers to explicitly pass it) would surface any caller that forgets to wire it up, rather than silently mislabeling an open grant as "Closed".
  2. The status !== 'OPEN' check duplicates the same logic in ApplicationActionButton.tsx (Line 44: isClosedForNewApplications). If more grant statuses are introduced later, these two independent checks could drift. Consider extracting a shared helper (e.g. isGrantClosed(status)) into a common grants util.
♻️ Example shared helper
// src/features/grants/utils/grantStatus.ts
export function isGrantClosed(status: string | undefined): boolean {
  return status !== 'OPEN';
}
🤖 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 `@src/features/grants/components/GrantEntry.tsx` around lines 42 - 53, In
GrantEntry, make the status prop explicit as string | undefined instead of
optional so callers must pass it, and update the isClosed logic to use a shared
grants helper rather than duplicating the check. Add or reuse a common utility
such as isGrantClosed(status) and call it from both GrantEntry and
ApplicationActionButton so the closure rule stays consistent. Keep the behavior
fail-closed for undefined status, but ensure missing wiring is surfaced by the
type signature.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@src/features/grants/components/GrantEntry.tsx`:
- Around line 42-53: In GrantEntry, make the status prop explicit as string |
undefined instead of optional so callers must pass it, and update the isClosed
logic to use a shared grants helper rather than duplicating the check. Add or
reuse a common utility such as isGrantClosed(status) and call it from both
GrantEntry and ApplicationActionButton so the closure rule stays consistent.
Keep the behavior fail-closed for undefined status, but ensure missing wiring is
surfaced by the type signature.

In `@src/features/grants/utils/validateGrantRequest.ts`:
- Around line 7-11: `validateGrantRequest` is a top-level TypeScript function
and should not rely on an inferred `{ grant, user }` return type. Add an
explicit return type to the `validateGrantRequest` signature, using the same
`grant` and `user` shape currently returned, and keep the new `skipStatusCheck`
option unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c6aafb70-f664-4eec-a749-792bac34aaf7

📥 Commits

Reviewing files that changed from the base of the PR and between f38d908 and 73947b0.

📒 Files selected for processing (7)
  • src/app/api/grant-application/update/route.ts
  • src/features/grants/components/ApplicationActionButton.tsx
  • src/features/grants/components/GrantEntry.tsx
  • src/features/grants/constants/schema.ts
  • src/features/grants/hooks/useApplicationState.ts
  • src/features/grants/utils/validateGrantRequest.ts
  • src/pages/earn/grants/index.tsx

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.

1 participant