(SP: 2) [Frontend][Backend] Sync guest quiz results after authentication across all login methods#147
Conversation
✅ Deploy Preview for develop-devlovers ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThis PR moves guest-quiz post-login sync into a new PostAuthQuizSync client component mounted on the dashboard, converts guest-result API to session-authenticated, adds comprehensive validation and persistence for quiz attempts, changes Google OAuth callback to redirect to /dashboard, and removes rounding from average score display. Changes
Sequence DiagramsequenceDiagram
participant Browser
participant Dashboard
participant PostAuthQuizSync
participant LocalStorage
participant API as /api/quiz/guest-result
participant DB as Database
participant SessionStorage
Browser->>Dashboard: Navigate to /dashboard (post-auth)
Dashboard->>PostAuthQuizSync: Mount component
PostAuthQuizSync->>LocalStorage: Read pending quiz result
LocalStorage-->>PostAuthQuizSync: Return pending result
alt pending result exists
PostAuthQuizSync->>API: POST quizId, answers, violations, timeSpentSeconds
API->>DB: Validate quiz, questions, answer mappings
DB-->>API: Validation result
alt valid
API->>DB: Insert quizAttempt and quizAttemptAnswers
DB-->>API: Confirm insertion
API->>DB: Award points (awardQuizPoints)
DB-->>API: Points confirmed
API-->>PostAuthQuizSync: Return success
PostAuthQuizSync->>SessionStorage: Write quiz_just_saved summary
PostAuthQuizSync->>LocalStorage: Clear pending result
PostAuthQuizSync->>Dashboard: Trigger router.refresh()
else invalid
API-->>PostAuthQuizSync: Return 4xx error
end
else no pending result
PostAuthQuizSync-->>PostAuthQuizSync: Exit silently
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/app/api/quiz/guest-result/route.ts (1)
147-178: Wrap attempt/answers/points in a transaction to avoid partial writes — but note driver limitation.The concern about partial writes is valid: if awardQuizPoints fails after inserting the attempt and answers, the API returns 500 while persisting incomplete data, and a client retry creates duplicate attempts.
However, the suggested
.transaction()approach has a critical issue: the production database uses the Neon HTTP driver (drizzle-orm/neon-http), which does not support interactive transactions. Transactions require the Neon WebSocket driver or a full TCP pg driver.Recommended alternatives:
- Make
awardQuizPointsidempotent using a unique constraint onsourceIdinpointTransactions, so retries don't duplicate points.- Add compensating logic in the catch block to delete the attempt and answers if
awardQuizPointsfails, ensuring atomicity at the application level.- Switch the production database driver to Neon WebSocket/serverless if transaction support is critical.
🤖 Fix all issues with AI agents
In `@frontend/components/auth/PostAuthQuizSync.tsx`:
- Around line 13-65: The current flow sets sessionStorage key
"guest_quiz_sync_done" before the POST finishes, which can permanently block
future syncs; change the logic in PostAuthQuizSync (around
useEffect/getPendingQuizResult/clearPendingQuizResult) to stop setting the
global flag early — either remove the "guest_quiz_sync_done" flag entirely or
replace it with a result-scoped key (e.g., include pendingResult.quizId or
savedAt in the key) and only write that key after the POST returns success, keep
removing/clearing it on any failure or catch, and ensure
clearPendingQuizResult() and router.refresh() still run after a confirmed
successful save.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
frontend/app/[locale]/dashboard/page.tsxfrontend/app/[locale]/login/page.tsxfrontend/app/api/auth/google/callback/route.tsfrontend/app/api/quiz/guest-result/route.tsfrontend/components/auth/PostAuthQuizSync.tsxfrontend/project-structure.txt
💤 Files with no reviewable changes (1)
- frontend/app/[locale]/login/page.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-30T16:01:02.523Z
Learnt from: kryvosheyin
Repo: DevLoversTeam/devlovers.net PR: 88
File: frontend/drizzle/schema.ts:153-153
Timestamp: 2025-12-30T16:01:02.523Z
Learning: The file frontend/drizzle/schema.ts is a legacy file not used by Drizzle or the runtime. The canonical schemas live in frontend/db/schema/* as configured in drizzle-config.ts, and that's what migrations and runtime use.
Applied to files:
frontend/project-structure.txt
🧬 Code graph analysis (3)
frontend/components/auth/PostAuthQuizSync.tsx (1)
frontend/lib/quiz/guest-quiz.ts (2)
getPendingQuizResult(27-49)clearPendingQuizResult(51-54)
frontend/app/[locale]/dashboard/page.tsx (1)
frontend/components/auth/PostAuthQuizSync.tsx (1)
PostAuthQuizSync(10-70)
frontend/app/api/quiz/guest-result/route.ts (2)
frontend/lib/auth.ts (1)
getCurrentUser(95-116)frontend/db/queries/points.ts (1)
calculateQuizPoints(7-12)
🔇 Additional comments (3)
frontend/app/api/auth/google/callback/route.ts (1)
155-155: Redirect update looks good.Matches the new post-auth sync flow on the dashboard.
frontend/app/api/quiz/guest-result/route.ts (1)
2-146: Session-based userId + validation flow looks solid.Good tightening of input checks and server-side user identity.
frontend/app/[locale]/dashboard/page.tsx (1)
10-61: Dashboard integration looks good.PostAuthQuizSync placement is appropriate and average score calculation still reads clearly.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
d0590fe to
b6a41ee
Compare
This pull request introduces a refactor and improvement to the way guest quiz results are synchronized with user accounts after authentication. The main change is the extraction of guest quiz result synchronization logic from the login page into a new reusable client component, improving maintainability and user experience. There are also minor updates to the project structure documentation and a redirect fix for Google auth.
Guest Quiz Result Synchronization Improvements:
PostAuthQuizSyncclient component. This component is now rendered in the dashboard and handles quiz result submission and state cleanup, ensuring quiz results are saved after login and the page is refreshed as needed. (frontend/components/auth/PostAuthQuizSync.tsxR1-R70, frontend/app/[locale]/dashboard/page.tsxR10, frontend/app/[locale]/dashboard/page.tsxR61, frontend/app/[locale]/login/page.tsxL7-L10, frontend/app/[locale]/login/page.tsxL77-L120)/api/quiz/guest-resultendpoint to derive the user ID from the session rather than accepting it in the request body, improving security and simplifying the API.Authentication and Routing:
/dashboardinstead of the home page after successful authentication, improving user flow.Related Issue
Issue: #<146>
Database Changes (if applicable)
How Has This Been Tested?
Screenshots (if applicable)
Checklist
Before submitting
Reviewers
Summary by CodeRabbit
New Features
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.