Skip to content

Remove country selector from partner application form#3958

Merged
steven-tey merged 8 commits into
mainfrom
remove-country-from-partner-application
Jun 1, 2026
Merged

Remove country selector from partner application form#3958
steven-tey merged 8 commits into
mainfrom
remove-country-from-partner-application

Conversation

@pepeladeira
Copy link
Copy Markdown
Collaborator

@pepeladeira pepeladeira commented May 28, 2026

Summary by CodeRabbit

  • New Features

    • Country is now auto-detected during application submission when available.
  • Bug Fixes

    • Clear error message shown if partner country is missing during submission.
  • Refactor

    • Country made optional for program applications and removed from the top-level form.
    • Application form simplified to render dynamic group fields.
    • Required-fields preview now focuses on Name and Email with improved tooltips and layout.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 28, 2026

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

Project Deployment Actions Updated (UTC)
dub Ready Ready Preview May 29, 2026 9:23pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Country is made optional in schema and types, derived from x-vercel-ip-country in the server action (with local/CI "US" fallback), removed from the static application form in favor of group-managed dynamic fields, and submission now surfaces missing partner.country as a user-facing error.

Changes

Country Field Optionality and Dynamic Form Integration

Layer / File(s) Summary
Schema and type contracts
apps/web/lib/zod/schemas/programs.ts, apps/web/lib/actions/partners/create-program-application.ts
createProgramApplicationSchema.country and PartnerData.country are now optional while preserving COUNTRY_CODES enum validation when present.
Country derivation in server action
apps/web/lib/actions/partners/create-program-application.ts
Action reads x-vercel-ip-country, falls back to "US" for local/CI only, persists the computed country on create, and selects response partnerData.country from partner.country → submitted data.countryundefined.
Form structure and dynamic fields
apps/web/ui/partners/groups/design/application-form/program-application-form.tsx
Removes the static country field and CountryCombobox, restructures FormData to nest dynamic fields under formData, and renders group-provided fields via ProgramApplicationFormField.
Required fields preview UI refinement
apps/web/ui/partners/groups/design/application-form/required-fields-preview.tsx
Preview shows only Name and Email with optional tooltips, uses a 2-column grid, updates label markup, and removes the Country tile/icon.
Submission validation and error messaging
apps/web/ui/partners/program-application-sheet.tsx
Submit handler now shows an error toast when partner.country is missing while still early-returning for missing group, program, or partner.email.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • steven-tey

Poem

🐰 I nibble at fields, small and spry,

Country tucked where headers lie.
Dynamic hops in form's warm light,
Toasts warn softly if countries hide at night.
Hooray — applications take flight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: removing the country selector from the partner application form, which is reflected across multiple files in the changeset.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 remove-country-from-partner-application

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 and usage tips.

@pepeladeira pepeladeira marked this pull request as ready for review May 28, 2026 21:56
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/web/lib/actions/partners/create-program-application.ts (1)

304-312: ⚡ Quick win

Persist ProgramApplication.country explicitly in createApplicationAndEnrollment for consistency.

prisma.programApplication.create (apps/web/lib/actions/partners/create-program-application.ts, lines 304-312) saves country only via ...sanitizeData(data, group); it doesn’t explicitly set it from partner.country. The logged-in partner UI appears to always submit country: partner.country, so divergence is unlikely for that path, but making the create write explicit prevents future callers/changes from leaving ProgramApplication.country null while the response/events use partner data.

♻️ Possible fix
     prisma.programApplication.create({
       data: {
         ...sanitizeData(data, group),
+        country: partner.country ?? data.country,
         id: applicationId,
         programId: program.id,
         groupId: group.id,
       },
     }),
🤖 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 `@apps/web/lib/actions/partners/create-program-application.ts` around lines 304
- 312, The program application create call currently relies on
sanitizeData(data, group) to populate country, which can allow
ProgramApplication.country to be null if callers change; update the
prisma.programApplication.create data payload in createApplicationAndEnrollment
(the block using prisma.programApplication.create and sanitizeData) to
explicitly set country: partner.country (or the local partner variable)
alongside id, programId, and groupId so the DB write always persists
partner.country regardless of sanitizeData input.
🤖 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 `@apps/web/lib/actions/partners/create-program-application.ts`:
- Around line 304-312: The program application create call currently relies on
sanitizeData(data, group) to populate country, which can allow
ProgramApplication.country to be null if callers change; update the
prisma.programApplication.create data payload in createApplicationAndEnrollment
(the block using prisma.programApplication.create and sanitizeData) to
explicitly set country: partner.country (or the local partner variable)
alongside id, programId, and groupId so the DB write always persists
partner.country regardless of sanitizeData input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a2570a4c-feeb-43dc-ae5a-18c64ee239a9

📥 Commits

Reviewing files that changed from the base of the PR and between 49378e0 and c812807.

📒 Files selected for processing (5)
  • apps/web/lib/actions/partners/create-program-application.ts
  • apps/web/lib/zod/schemas/programs.ts
  • apps/web/ui/partners/groups/design/application-form/program-application-form.tsx
  • apps/web/ui/partners/groups/design/application-form/required-fields-preview.tsx
  • apps/web/ui/partners/program-application-sheet.tsx

@steven-tey
Copy link
Copy Markdown
Collaborator

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/ui/partners/groups/design/application-form/program-application-form.tsx (1)

199-210: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add optional chaining or fallback for fields to prevent potential runtime error.

Line 199 accesses .fields.map(...) without guarding against fields being undefined, whereas line 53-55 correctly uses group.applicationFormData?.fields ?? []. If applicationFormData is defined but fields is undefined, this will throw a TypeError.

🛡️ Proposed fix
-        {group?.applicationFormData?.fields.map((field, index) => {
+        {(group.applicationFormData?.fields ?? []).map((field, index) => {
🤖 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
`@apps/web/ui/partners/groups/design/application-form/program-application-form.tsx`
around lines 199 - 210, The map over group?.applicationFormData?.fields can
throw if fields is undefined; update the rendering of
ProgramApplicationFormField to iterate a safe array (e.g.,
group?.applicationFormData?.fields ?? []) or use optional chaining before .map
so fields.map is only called when defined; locate the JSX that renders
<ProgramApplicationFormField key={field.id} ...
keyPath={`formData.fields.${index}`} onStatusChange={(loading) =>
handleFieldStatusChange(field.id, loading)} /> and change the source collection
to a guarded expression (group?.applicationFormData?.fields ?? []) to prevent a
TypeError.
🧹 Nitpick comments (1)
apps/web/lib/actions/partners/create-program-application.ts (1)

304-312: ⚡ Quick win

Reuse sanitizedData instead of recomputing.

sanitizeData(data, group) is already computed at Line 262 (sanitizedData) and recomputed here. Reuse it to avoid the redundant call and prevent the two results from diverging.

♻️ Proposed refactor
     prisma.programApplication.create({
       data: {
-        ...sanitizeData(data, group),
+        ...sanitizedData,
         id: applicationId,
         programId: program.id,
         groupId: group.id,
       },
     }),
🤖 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 `@apps/web/lib/actions/partners/create-program-application.ts` around lines 304
- 312, The create transaction is recomputing sanitizeData(data, group) instead
of reusing the previously computed sanitizedData; update the
prisma.programApplication.create call (inside the prisma.$transaction array) to
spread sanitizedData rather than calling sanitizeData(data, group) again so the
created application uses the same sanitizedData value that was computed earlier
(ensure the variable sanitizedData is in scope where used).
🤖 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 `@apps/web/lib/actions/partners/create-program-application.ts`:
- Around line 408-416: The IP-derived country from headers() is being written
directly to Prisma and can be empty/invalid; import COUNTRY_CODES from
"`@dub/utils`" and validate/normalize the header value before persisting by
checking that headerList.get("x-vercel-ip-country") is a non-empty string
included in COUNTRY_CODES (e.g., uppercased/normalized to match entries); if
it’s invalid or empty, do not overwrite the already-validated country from
sanitizeData(data, group) (leave country undefined so the validated value or
schema default remains), and ensure the variable used in
prisma.programApplication.create({ data: { ...sanitizeData(...), country } })
only contains a validated value.

---

Outside diff comments:
In
`@apps/web/ui/partners/groups/design/application-form/program-application-form.tsx`:
- Around line 199-210: The map over group?.applicationFormData?.fields can throw
if fields is undefined; update the rendering of ProgramApplicationFormField to
iterate a safe array (e.g., group?.applicationFormData?.fields ?? []) or use
optional chaining before .map so fields.map is only called when defined; locate
the JSX that renders <ProgramApplicationFormField key={field.id} ...
keyPath={`formData.fields.${index}`} onStatusChange={(loading) =>
handleFieldStatusChange(field.id, loading)} /> and change the source collection
to a guarded expression (group?.applicationFormData?.fields ?? []) to prevent a
TypeError.

---

Nitpick comments:
In `@apps/web/lib/actions/partners/create-program-application.ts`:
- Around line 304-312: The create transaction is recomputing sanitizeData(data,
group) instead of reusing the previously computed sanitizedData; update the
prisma.programApplication.create call (inside the prisma.$transaction array) to
spread sanitizedData rather than calling sanitizeData(data, group) again so the
created application uses the same sanitizedData value that was computed earlier
(ensure the variable sanitizedData is in scope where used).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 70baa20d-c6f4-45a3-8ef0-bb7f2de82abb

📥 Commits

Reviewing files that changed from the base of the PR and between 6f9b008 and 19cbc7e.

📒 Files selected for processing (5)
  • apps/web/lib/actions/partners/create-program-application.ts
  • apps/web/lib/zod/schemas/programs.ts
  • apps/web/ui/partners/groups/design/application-form/program-application-form.tsx
  • apps/web/ui/partners/groups/design/application-form/required-fields-preview.tsx
  • apps/web/ui/partners/program-application-sheet.tsx

Comment thread apps/web/lib/actions/partners/create-program-application.ts
@steven-tey steven-tey merged commit a3a30f5 into main Jun 1, 2026
9 checks passed
@steven-tey steven-tey deleted the remove-country-from-partner-application branch June 1, 2026 22:52
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.

2 participants