feat: add zod validation and character counters for forum posts (closes #19)#57
Conversation
rishabhx29#19) - app/src/lib/validators.ts: CreatePostSchema with title (10-150), content (20-10000), tags validation - CommunityForum.tsx: Replace raw useState with react-hook-form + zodResolver, add inline errors and character counters - forumController.ts: Add server-side validation for title, content, and tags with proper 400 responses
|
Someone is attempting to deploy a commit to the rishabhjtripathi2903-3434's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Warning Review limit reached
More reviews will be available in 55 minutes and 51 seconds. Learn how PR review limits work. To continue reviewing without waiting, enable usage-based billing in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds schema-backed validation for forum post creation in the forum UI and backend, including inline errors, character counters, and request trimming/length checks. Separately, it applies ESLint/TypeScript annotation updates across multiple UI primitives and learning sections, plus a sidebar skeleton state tweak. ChangesForum Post Creation Validation
TypeScript and ESLint Compliance Cleanup
Sequence Diagram(s)sequenceDiagram
participant User
participant CommunityForum
participant zodResolver
participant forumController
participant Prisma
User->>CommunityForum: submit title, content, category
CommunityForum->>zodResolver: validate with createPostSchema
zodResolver-->>CommunityForum: errors or valid form data
CommunityForum->>forumController: createPost(validated payload)
forumController->>forumController: trim and validate title, content, tags
alt invalid input
forumController-->>CommunityForum: 400 Bad Request
else valid input
forumController->>Prisma: forumPost.create(validated payload)
Prisma-->>forumController: created forum post
forumController-->>CommunityForum: 201 Created
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
app/src/lib/validators.ts (1)
3-17: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the exported max constants inside the schema to prevent drift.
TITLE_MAXandCONTENT_MAXare exported, but the schema still uses literal values. Keeping a single source avoids subtle contract drift later.♻️ Proposed refactor
import { z } from 'zod'; +export const TITLE_MAX = 150; +export const CONTENT_MAX = 10000; + export const createPostSchema = z.object({ title: z .string() .trim() .min(1, 'Title is required') .min(10, 'Title must be at least 10 characters') - .max(150, 'Title must be less than 150 characters'), + .max(TITLE_MAX, 'Title must be less than 150 characters'), content: z .string() .trim() .min(1, 'Content is required') .min(20, 'Content must be at least 20 characters') - .max(10000, 'Content must be less than 10,000 characters'), + .max(CONTENT_MAX, 'Content must be less than 10,000 characters'), category: z.string().default('general'), }); export type CreatePostFormData = z.infer<typeof createPostSchema>; - -export const TITLE_MAX = 150; -export const CONTENT_MAX = 10000;Also applies to: 21-22
🤖 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 `@app/src/lib/validators.ts` around lines 3 - 17, The createPostSchema object is using hardcoded literal values (150 for title and 10000 for content) in the max validation calls instead of referencing the exported TITLE_MAX and CONTENT_MAX constants. Replace the literal 150 in the title field's max() validation with TITLE_MAX and the literal 10000 in the content field's max() validation with CONTENT_MAX. Also check lines 21-22 mentioned in the comment for any other occurrences that need the same treatment.
🤖 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 `@backend/src/controllers/forumController.ts`:
- Around line 151-164: Add type guards to verify that `title` and `content` are
strings before calling the `.trim()` method on them in the code where
`trimmedTitle` and `trimmedContent` are assigned. Without these type checks,
non-string truthy values (like numbers or objects) will cause `.trim()` to throw
an error, resulting in a 500 response instead of a proper 400 validation error.
Use typeof checks to ensure both variables are strings before proceeding with
the trim operations.
- Around line 175-178: In the forumController.ts file, the current logic for
handling the postTags variable silently converts any non-array tags value to an
empty array, which masks invalid requests instead of rejecting them. Replace the
current conditional logic that assigns postTags to first check if tags is
provided and is not an array, and if so, return a 400 status response with an
appropriate error message indicating that tags must be an array. Only proceed
with the postTags assignment if tags is either undefined/null or is a valid
array, ensuring invalid tag types are properly rejected rather than silently
dropped.
---
Nitpick comments:
In `@app/src/lib/validators.ts`:
- Around line 3-17: The createPostSchema object is using hardcoded literal
values (150 for title and 10000 for content) in the max validation calls instead
of referencing the exported TITLE_MAX and CONTENT_MAX constants. Replace the
literal 150 in the title field's max() validation with TITLE_MAX and the literal
10000 in the content field's max() validation with CONTENT_MAX. Also check lines
21-22 mentioned in the comment for any other occurrences that need the same
treatment.
🪄 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 Plus
Run ID: 3257e421-332e-4ab5-b979-5b0803deaf9b
📒 Files selected for processing (3)
app/src/lib/validators.tsapp/src/sections/CommunityForum.tsxbackend/src/controllers/forumController.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
app/src/sections/AdminPanel.tsx (1)
136-145: 📐 Maintainability & Code Quality | 🔵 TrivialDefine typed response contracts in admin and content API modules to replace
anysuppressionsThe explicit-any suppressions in AdminPanel cascade from untyped admin and content API functions.
admin.tsfunctions likegetUsers,editUser,addProblem, andeditForumPostreturnresponse.datawithout type annotations, forcing AdminPanel state to useany. The forum API (forum.ts) shows the correct pattern: define interfaces likeForumPostSummaryandPostsResponse, then annotate functions withPromise<Type>return types.Apply the same pattern to
admin.ts(define types for user lists, problem/topic responses, admin stats) andcontent.ts(define types for paths, topics, problems), then update AdminPanel to use these typed APIs. This eliminates suppressions incrementally and prevents payload shape drift from going undetected.Lines affected across AdminPanel: - 136–145 (users, editingUser, editForm) - 329–340 (paths, topics, problems, editingProblem) - 548–554 (posts, editingPost) Also requires changes to app/src/api/admin.ts and app/src/api/content.ts🤖 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 `@app/src/sections/AdminPanel.tsx` around lines 136 - 145, The state variables in AdminPanel at lines 136-145 (users, editingUser, editForm) and 329-340 (paths, topics, problems, editingProblem) and 548-554 (posts, editingPost) use `any` type due to untyped API functions. Follow the pattern used in forum.ts by defining TypeScript interfaces in admin.ts for responses from getUsers, editUser, addProblem, and editForumPost functions, and in content.ts for responses from functions returning paths, topics, and problems. Add proper Promise<Type> return type annotations to these API functions, then update AdminPanel to type its state variables with these interfaces instead of `any`, removing the eslint-disable-next-line suppressions as they become unnecessary.
🤖 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 `@app/src/sections/Problems.tsx`:
- Line 323: In the Problems.tsx file, the line assigning problemMongoId uses a
redundant fallback expression where both sides reference the same field
(problem.id || problem.id), making it a no-op that provides no actual fallback.
Replace this with a proper fallback that checks an alternative field for the
mongo ID; commonly this would be problem._id as an alternative identifier when
problem.id may not be present. Ensure the fallback expression covers the case
where records come back with different id field naming so that action handlers
and list keys work correctly.
---
Nitpick comments:
In `@app/src/sections/AdminPanel.tsx`:
- Around line 136-145: The state variables in AdminPanel at lines 136-145
(users, editingUser, editForm) and 329-340 (paths, topics, problems,
editingProblem) and 548-554 (posts, editingPost) use `any` type due to untyped
API functions. Follow the pattern used in forum.ts by defining TypeScript
interfaces in admin.ts for responses from getUsers, editUser, addProblem, and
editForumPost functions, and in content.ts for responses from functions
returning paths, topics, and problems. Add proper Promise<Type> return type
annotations to these API functions, then update AdminPanel to type its state
variables with these interfaces instead of `any`, removing the
eslint-disable-next-line suppressions as they become unnecessary.
🪄 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 Plus
Run ID: 4b720773-30b8-42e1-a56d-d606c896e14e
📒 Files selected for processing (30)
app/src/api/admin.tsapp/src/components/custom/AlgoBot.tsxapp/src/components/custom/AuthModal.tsxapp/src/components/custom/Navigation.tsxapp/src/components/ui/badge.tsxapp/src/components/ui/button-group.tsxapp/src/components/ui/button.tsxapp/src/components/ui/form.tsxapp/src/components/ui/navigation-menu.tsxapp/src/components/ui/sidebar.tsxapp/src/components/ui/toggle.tsxapp/src/contexts/AuthContext.tsxapp/src/lib/validators.tsapp/src/sections/AdminPanel.tsxapp/src/sections/CTA.tsxapp/src/sections/CommunityForum.tsxapp/src/sections/CommunityHub.tsxapp/src/sections/DailyChallenges.tsxapp/src/sections/Dashboard.tsxapp/src/sections/Footer.tsxapp/src/sections/Hero.tsxapp/src/sections/Leaderboard.tsxapp/src/sections/Notes.tsxapp/src/sections/PathDetail.tsxapp/src/sections/ProblemWorkspace.tsxapp/src/sections/Problems.tsxapp/src/sections/Roadmaps.tsxapp/src/sections/TopicDetail.tsxapp/src/sections/UserHero.tsxbackend/src/controllers/forumController.ts
💤 Files with no reviewable changes (1)
- app/src/sections/Footer.tsx
✅ Files skipped from review due to trivial changes (20)
- app/src/components/ui/button.tsx
- app/src/components/ui/badge.tsx
- app/src/components/ui/toggle.tsx
- app/src/components/ui/button-group.tsx
- app/src/sections/Hero.tsx
- app/src/components/custom/Navigation.tsx
- app/src/components/ui/navigation-menu.tsx
- app/src/sections/Leaderboard.tsx
- app/src/sections/DailyChallenges.tsx
- app/src/sections/CommunityHub.tsx
- app/src/components/custom/AlgoBot.tsx
- app/src/components/ui/form.tsx
- app/src/sections/PathDetail.tsx
- app/src/sections/Notes.tsx
- app/src/components/custom/AuthModal.tsx
- app/src/sections/Dashboard.tsx
- app/src/sections/TopicDetail.tsx
- app/src/contexts/AuthContext.tsx
- app/src/sections/ProblemWorkspace.tsx
- app/src/api/admin.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- backend/src/controllers/forumController.ts
- app/src/lib/validators.ts
- app/src/sections/CommunityForum.tsx
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Summary
Adds input validation and character limits to the forum post creation form, both frontend and backend.
Changes
New Files
Modified Files
�pp/src/sections/CommunityForum.tsx:
eact-hook-form + zodResolver
�ackend/src/controllers/forumController.ts:
Acceptance Criteria
Testing
Closes #19
Summary by CodeRabbit
New Features
Bug Fixes