fix(critical): AI UX errors, rate limiting, and GDPR account controls - #14
Merged
Conversation
CRITICAL SECURITY & UX FIXES:
1. AI UX: cover-letter.ts now returns proper 4xx errors on parse failure
and provider errors instead of silently returning HTTP 200 with a fake
"Unable to generate" placeholder. CoverLetterStudio.tsx updated to
surface these errors as dismissible alerts instead of displaying the
fake result as valid output.
2. AI Rate Limiting: Added configurable per-user rate limits to all AI
endpoints (coach, resume-review, cover-letter, assessment-score) via
createAIHandler factory. Default: 15 req/min per authenticated user,
backed by the database (survives cold starts unlike middleware Map).
3. GDPR Account Controls:
- NEW GET /api/user/me/export — exports all user-owned data as JSON
(profile, sessions, resumes, cover letters, guide progress)
- NEW DELETE /api/user/me — permanently deletes account and all
cascade-related records; requires password confirmation in body.
- docs/SECURITY.md: updated checklist, added GDPR section.
Resolves: #CRITICAL-1 (silent AI failure), #CRITICAL-2 (no AI rate limiting),
#CRITICAL-3 (no account deletion/export)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review available on request
Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three CRITICAL security/UX issues resolved in a single checkpoint commit:
1. AI: cover-letter silently returned HTTP 200 on failure
Before:
onParseFailureandonProviderErrorreturnedok: truewith a fake"Unable to generate..."string. The HTTP status was 200, so the frontend treated it as success and displayed the fake text as a valid result.After: Both handlers now return
ok: falsewithstatus: 502(parse failure) andstatus: 503(provider error).CoverLetterStudio.tsxchecksres.okand surfaces the error message as a dismissible alert.src/lib/ai/cover-letter.ts— error responses instead of fake 200ssrc/components/interview-lab/CoverLetterStudio.tsx— error state + alert display2. No AI endpoint rate limiting
Before:
/api/ai/coach,/api/ai/resume-review,/api/ai/cover-letter,/api/ai/assessment-scorehad zero rate limiting. A single user could exhaust the Z AI quota at no cost.After: All AI routes now enforce 15 req/min per authenticated user via the database-backed
checkRateLimit()utility. Limits are configurable per-route.src/lib/ai/handlers.ts—rateLimitfield added toAIHandlerConfigwith DB-backed enforcementsrc/lib/ai/coach.ts,resume.ts,cover-letter.ts,assessment.ts— rate limit configs wired3. No account deletion / data export (GDPR exposure)
Before: No way for users to delete their account or export their data.
After:
GET /api/user/me/export— exports all user data as JSON (profile, sessions, resumes, cover letters, guide progress) withContent-Dispositionattachment headerDELETE /api/user/me— permanently deletes account + cascade relations; requires password confirmation ({ confirmPassword: "..." }) in request body to prevent CSRF-based deletiondocs/SECURITY.md— checklist updated, GDPR section addedCloses #CRITICAL-1 · #CRITICAL-2 · #CRITICAL-3