fix(experiences): persist interview submissions with review status - #1375
fix(experiences): persist interview submissions with review status#1375nyxsky404 wants to merge 4 commits into
Conversation
Form only updated React state, so reload wiped cards despite the moderation success copy. Add a backend resource, save on submit, reload via client key, and surface pending/approved/rejected. Co-authored-by: Cursor <cursoragent@cursor.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughThe PR adds persistent interview-experience submissions with validation, MongoDB storage, moderation endpoints, optional authentication, client-key retrieval, status badges, retry states, and unit tests. ChangesInterview experience submission and moderation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant InterviewExperiences
participant interviewExperienceRoutes
participant optionalProtect
participant interviewExperienceController
participant InterviewExperience
InterviewExperiences->>interviewExperienceRoutes: submit interview experience with clientKey
interviewExperienceRoutes->>optionalProtect: attempt JWT authentication
optionalProtect->>interviewExperienceController: continue with optional req.user
interviewExperienceController->>InterviewExperience: create pending experience
InterviewExperience-->>interviewExperienceController: return saved document
interviewExperienceController-->>InterviewExperiences: return normalized experience
InterviewExperiences->>interviewExperienceRoutes: load personal experiences
interviewExperienceController->>InterviewExperience: query by user ID or clientKey
InterviewExperience-->>interviewExperienceController: return matching submissions
interviewExperienceController-->>InterviewExperiences: return submission statuses
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
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 `@backend/controllers/interviewExperienceController.js`:
- Line 39: Update the submission flow around InterviewExperience.create to
generate one idempotency key per modal submission, persist it on the interview
experience with a unique index, and return the existing submission when a POST
reuses that key instead of creating a duplicate. Add a regression test covering
repeated POSTs with the same key.
In `@backend/routes/interviewExperienceRoutes.js`:
- Around line 23-27: Update the PATCH /:id/status middleware chain to enforce
the existing moderator/admin authorization check between protect and
updateInterviewExperienceStatus, preventing regular authenticated users from
changing statuses. Add or update tests to verify non-moderators receive HTTP 403
while authorized moderators retain access.
In `@frontend/src/pages/InterviewExperiences/InterviewExperiences.jsx`:
- Around line 814-831: Update loadMyExperiences to also fetch
API_PATHS.INTERVIEW_EXPERIENCES.APPROVED and store the returned approved
experiences in dedicated state. Replace the Common tab’s static EXPERIENCES
source with that state, preserving the existing personal-submissions behavior
and ensuring both datasets reload together.
🪄 Autofix
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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ebb3e272-ade5-4f94-b417-e543a49e8fa5
📒 Files selected for processing (9)
backend/Input_validators/ValidateInterviewExperience.jsbackend/controllers/interviewExperienceController.jsbackend/middlewares/authMiddleware.jsbackend/models/InterviewExperience.jsbackend/routes/interviewExperienceRoutes.jsbackend/server.jsbackend/tests/interviewExperienceController.unit.test.jsfrontend/src/pages/InterviewExperiences/InterviewExperiences.jsxfrontend/src/utils/apiPaths.js
Add idempotent creates, restrict status updates to MODERATOR_EMAILS, and load approved experiences into the Common tab. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/models/InterviewExperience.js`:
- Around line 87-106: Update the create validator for InterviewExperience so
idempotencyKey is required and must be a non-empty string, matching the schema’s
unique partial index; ensure the controller rejects missing or blank keys before
creating a record.
🪄 Autofix
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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 03146be1-cff1-4181-8700-451b7451e223
📒 Files selected for processing (9)
backend/.env.examplebackend/Input_validators/ValidateInterviewExperience.jsbackend/controllers/interviewExperienceController.jsbackend/middlewares/authMiddleware.jsbackend/models/InterviewExperience.jsbackend/routes/interviewExperienceRoutes.jsbackend/tests/interviewExperienceController.unit.test.jsbackend/tests/requireModerator.unit.test.jsfrontend/src/pages/InterviewExperiences/InterviewExperiences.jsx
🚧 Files skipped from review as they are similar to previous changes (4)
- backend/routes/interviewExperienceRoutes.js
- backend/Input_validators/ValidateInterviewExperience.js
- backend/tests/interviewExperienceController.unit.test.js
- frontend/src/pages/InterviewExperiences/InterviewExperiences.jsx
Reject blank or missing keys so retries cannot bypass the unique partial index and create duplicate submissions. Co-authored-by: Cursor <cursoragent@cursor.com>
| try { | ||
| const experience = await InterviewExperience.findByIdAndUpdate( | ||
| req.params.id, | ||
| { status: req.body.status }, |
|
@nyxsky404 CodeQL detected a potential database injection issue because req.params.id and req.body.status are user-controlled inputs. Please validate the ID and restrict status to a whitelist of allowed values before performing the update |
Pull Request Description
Related Issue
Closes #935
Summary
Interview experience submit only wrote to local React state, so a refresh dropped the card even though the UI said it was submitted for review. Added
/api/interview-experiences(create, mine, approved, status update), wired the form to POST, reload User-tab entries via a stable client key, and show pending/approved/rejected on cards. Failure path keeps the form open so users can retry.Type of Change
How Has This Been Tested?
vitest run tests/interviewExperienceController.unit.test.js(7 passing)vitest run tests/authMiddleware.tokenVersion.unit.test.js(optionalProtect export still green)Screenshots (if applicable)
N/A
Checklist
Made with Cursor
Summary
/api/interview-experiences.optionalProtectexport.