Skip to content

Dev#8

Merged
Retsomm merged 6 commits into
mainfrom
dev
Jul 11, 2026
Merged

Dev#8
Retsomm merged 6 commits into
mainfrom
dev

Conversation

@Retsomm

@Retsomm Retsomm commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added Google sign-in/sign-out with a gated profile page and account deletion flow.
    • Users can edit name and upload/reposition profile images (save/cancel supported).
    • Added expanded experience growth history with updated mascot stages and XP milestones.
    • Introduced a 6‑month learning activity heatmap with level coloring, legend, and month labels.
    • Updated navigation and quiz UI to reflect login status and current stage.
  • Documentation
    • Added/expanded authentication and environment setup guidance.
  • Chores
    • Migrated the project from Vite to Next.js.

Retsomm and others added 2 commits July 11, 2026 18:21
Mascot 的 4 階段進化(蛋→貓頭鷹,700 XP 封頂)換成星際塵埃到黑洞的 12 階段
宇宙演化史,拉長成長曲線到 7000 XP 做長期目標,取代原本規劃另開一套等級稱號
系統的做法。Stats 頁新增 GitHub 風格的月曆熱力圖呈現近半年做題量,色階已用
dataviz skill 的 validate_palette.js 驗證過。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
未登入時「個人資料」分頁改成獨立登入頁,navbar 文字動態顯示「登入」;
登入後可上傳大頭貼並拖曳調整顯示位置、編輯單欄名稱,個人資料頁改成卡片式排版,
新增「查看成長史」可展開列表預覽全部 12 個吉祥物成長階段,登出按鈕改用實心描邊樣式。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
easy-learn Ready Ready Preview, Comment Jul 11, 2026 12:38pm

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Retsomm, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 reviews.

How do review 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 refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: aa818590-bb5e-43a1-9807-04f48c225f92

📥 Commits

Reviewing files that changed from the base of the PR and between 344e153 and 4c0b07b.

📒 Files selected for processing (8)
  • docs/roadmap.md
  • package.json
  • src/app/api/account/route.ts
  • src/app/api/progress/answer/route.ts
  • src/app/api/progress/finish-review/route.ts
  • src/app/api/progress/migrate-local/route.ts
  • src/app/api/progress/save-toggle/route.ts
  • src/components/AccountHeader.tsx
📝 Walkthrough

Walkthrough

The application migrates from Vite to Next.js, adds Clerk authentication and account management, introduces Prisma/PostgreSQL progress persistence with synchronized APIs, and expands XP progression and activity visualization with growth history and a 26-week heatmap.

Changes

Next.js, Clerk, and cloud progress platform

Layer / File(s) Summary
Next.js and persistence bootstrap
.env.example, .gitignore, package.json, next.config.ts, prisma.config.ts, prisma/*, src/lib/prisma.ts, src/app/layout.tsx, src/app/page.tsx, src/proxy.ts, tsconfig.json
Migrates tooling to Next.js, configures Clerk and Supabase connection variables, adds Prisma models and migration data, initializes the shared Prisma client, and provides the Clerk-wrapped app shell.
Progress transformation and storage
src/lib/progressLogic.ts, src/lib/progressStore.ts
Maps Prisma records to application progress, calculates server streak updates, and creates or loads user progress with new-user detection.
Authenticated progress API flow
src/app/api/**, src/hooks/useProgress.ts
Adds authenticated progress reads, local migration, answer/save/level/review mutation routes, account deletion, and client synchronization using server-authoritative responses.
Clerk account experience
src/screens/Profile.tsx, src/components/AccountHeader.tsx, src/components/Navbar.tsx, src/components/Icons.tsx, src/index.css
Adds authentication-gated profile rendering, Google sign-in, profile editing, avatar upload and repositioning, sign-out, account deletion, navigation labels, icons, and account styling.
Growth progression and activity visualization
src/components/Mascot.tsx, src/components/GrowthHistory.tsx, src/screens/Stats.tsx, src/screens/Quiz.tsx, src/index.css, docs/roadmap.md
Updates XP stages, adds growth history and dynamic quiz labels, renders a 26-week activity heatmap, and records the completed roadmap items.
Application entry and layout cleanup
src/App.tsx, src/screens/Notes.tsx, index.html, src/main.tsx, vite.config.ts
Removes the Vite bootstrap path, removes progress export/import wiring, and removes the Notes page title.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Visitor
  participant Clerk
  participant App
  participant ProgressAPI
  participant Prisma
  Visitor->>Clerk: sign in
  Clerk-->>App: provide authenticated user
  App->>ProgressAPI: load or migrate progress
  ProgressAPI->>Prisma: read or persist user progress
  Prisma-->>ProgressAPI: return progress records
  ProgressAPI-->>App: return synchronized progress
  App-->>Visitor: render account and learning state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague and does not describe the substantial Next.js, Clerk, Prisma, and progress-tracking changes in the PR. Replace it with a concise, specific title that names the main change, such as the app migration to Next.js with Clerk and Prisma integration.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🤖 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 `@docs/roadmap.md`:
- Around line 133-134: Update the roadmap entry for “全真模考” to state that the
navbar placeholder/disabled tab was removed, aligning it with the earlier
roadmap note that no UI placeholder remains; preserve the existing
prioritization and user-demand wording.

In `@src/components/AccountHeader.tsx`:
- Around line 47-50: Add try/catch handling to the Clerk mutation flows in
saveMetadata and saveName, including their callers confirmReposition and
handleAvatarFile as needed, so update failures are caught rather than escaping
event handlers and the avatar UI remains synchronized. Reuse the existing
error-handling or user-feedback pattern in AccountHeader for both metadata and
name mutations.
- Line 1: Update AccountHeader’s saveMetadata, handleAvatarFile,
confirmReposition, and saveName flows to catch rejected Clerk requests, record
an appropriate error state, and preserve the current edit/reposition state when
persistence fails. Ensure success-only UI transitions occur after the awaited
operations complete, including avatar upload and position persistence.
- Around line 102-112: Update saveName to catch user.update failures, preserve
the editing state, and set an appropriate user-visible error message or error
state while still clearing savingName in finally. Reuse the component’s existing
error-display mechanism if available.
- Around line 52-64: Update handleAvatarFile to catch failures from
user.setProfileImage or saveMetadata and display the established avatar-upload
error feedback, while retaining the finally block so uploading is always reset
and allowing successful uploads to keep their current behavior.
- Around line 76-79: Update confirmReposition so it awaits saveMetadata(pos)
before calling setIsRepositioning(false), and ensure a rejected save leaves
repositioning mode open without clearing the unsaved avatar position.
- Line 107: Update the first-name edit flow in AccountHeader to pass only the
trimmed firstName to user.update, omitting lastName so an existing surname is
preserved.
🪄 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: 75a69de2-d867-4ebe-8666-cc3981d4ec46

📥 Commits

Reviewing files that changed from the base of the PR and between 24dc242 and 5626008.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (16)
  • .env.example
  • .gitignore
  • docs/roadmap.md
  • package.json
  • src/components/AccountHeader.tsx
  • src/components/GrowthHistory.tsx
  • src/components/Icons.tsx
  • src/components/Mascot.tsx
  • src/components/Navbar.tsx
  • src/index.css
  • src/main.tsx
  • src/screens/Notes.tsx
  • src/screens/Profile.tsx
  • src/screens/Quiz.tsx
  • src/screens/Stats.tsx
  • src/vite-env.d.ts
💤 Files with no reviewable changes (1)
  • src/screens/Notes.tsx

Comment thread docs/roadmap.md Outdated
Comment thread src/components/AccountHeader.tsx
Comment thread src/components/AccountHeader.tsx
Comment thread src/components/AccountHeader.tsx
Comment thread src/components/AccountHeader.tsx
Comment thread src/components/AccountHeader.tsx
Comment thread src/components/AccountHeader.tsx Outdated
- 框架從 Vite 換成 Next.js(App Router),進度儲存改走 PostgreSQL(Supabase)透過 Prisma,
  已登入時以資料庫為主、未登入沿用 localStorage
- 新增 DELETE /api/account:刪除帳號同時清除資料庫資料與 Clerk 帳號
- 個人資料頁移除進度備份/匯出區塊,登出按鈕旁新增刪除帳號按鈕
- 修正學習熱力圖橫向捲軸只在窄螢幕出現(含 CSS source order 修正)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Retsomm and others added 2 commits July 11, 2026 20:15
Vercel 每次 deploy 都是全新環境重新 install,沒有這一步的話 next build 會因為
找不到 @prisma/client 產出而失敗。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- confirmReposition 改成存檔成功才關閉調整模式,失敗時保留未存的位置
- handleAvatarFile、saveName 補上 catch,Clerk 請求失敗時提示使用者
- saveName 移除多餘的 lastName: '',避免改名時把既有姓氏清空
- roadmap.md 更新全真模考項目,對齊「navbar 佔位分頁已移除」的說明

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
docs/roadmap.md (1)

73-79: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Update the Clerk setup notes for Next.js.

These lines still instruct readers to use the removed Vite integration, main.tsx, and VITE_CLERK_PUBLISHABLE_KEY. The new setup uses Next.js and NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY as shown in .env.example; following this roadmap section can leave authentication unconfigured.

🤖 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 `@docs/roadmap.md` around lines 73 - 79, Update the Clerk setup notes in the
roadmap to describe the current Next.js integration instead of the removed Vite
setup: replace references to `@clerk/react`, main.tsx, and
VITE_CLERK_PUBLISHABLE_KEY with the Next.js setup and
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY used in .env.example. Keep the existing
authentication behavior notes unchanged.
🧹 Nitpick comments (3)
src/app/api/progress/answer/route.ts (1)

24-55: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Wrap the multi-step mutation in a transaction for atomicity. The wrongEntry, dailyStat, and chapterStat writes run as independent awaits. If a later write fails, the earlier ones are already committed and no response is returned, leaving the server-authoritative progress inconsistent with the client's optimistic state until the next full reload. prisma.$transaction([...]) (or the interactive form) keeps the answer update atomic.

🤖 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 `@src/app/api/progress/answer/route.ts` around lines 24 - 55, Wrap the
wrongEntry mutation logic, dailyStat upsert, and conditional chapterStat upsert
in a single Prisma transaction using prisma.$transaction. Ensure all three
writes use the transaction client and preserve the existing branching and update
values so either every answer-progress mutation commits or none does.
tsconfig.json (1)

16-16: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Set jsx to preserve in tsconfig.json:16 Next.js manages this value and will reset react-jsx back to preserve, so keeping it here just creates config churn.

🤖 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 `@tsconfig.json` at line 16, Update the jsx compiler option in tsconfig.json
from react-jsx to preserve, allowing Next.js to manage the setting and
preventing configuration churn.
src/app/api/progress/migrate-local/route.ts (1)

15-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Eliminate the redundant loadFullProgress call.

When !isNew, loadFullProgress is called twice — once for isNew (line 15) and again for progress (line 17). Destructure both from a single call.

♻️ Proposed refactor
-  const { isNew } = await loadFullProgress(userId)
+  const { progress, isNew } = await loadFullProgress(userId)
   if (!isNew) {
-    const current = await loadFullProgress(userId)
-    return NextResponse.json({ progress: current.progress })
+    return NextResponse.json({ progress })
   }
🤖 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 `@src/app/api/progress/migrate-local/route.ts` around lines 15 - 19, Update the
migrate-local route’s loadFullProgress usage to call it once, destructuring both
isNew and progress from the returned object. Use the destructured progress in
the existing !isNew response while preserving the current behavior.
🤖 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 `@src/app/api/account/route.ts`:
- Around line 11-16: Update the account deletion flow around clerkClient and
client.users.deleteUser to delete the Clerk user before removing the local
Prisma user record. Ensure errors from either deletion propagate and prevent the
success response, so return NextResponse.json({ ok: true }) only after both
operations complete.

In `@src/app/api/progress/finish-review/route.ts`:
- Around line 18-31: Validate xpEarned and today immediately after parsing
FinishReviewBody and before findUniqueOrThrow or any persistence: require
xpEarned to be a non-negative integer within the endpoint’s reasonable maximum,
and require today to match the YYYY-MM-DD format (reject invalid dates as well).
Return the route’s established client-error response for invalid input, while
preserving the existing streak and transaction flow for valid values.

In `@src/app/api/progress/migrate-local/route.ts`:
- Around line 15-52: Wrap the migration prisma.$transaction in a try/catch and
handle Prisma unique-constraint errors (P2002) by calling
loadFullProgress(userId) and returning the existing progress response. Preserve
the current migration flow for successful transactions and rethrow all other
errors; keep the existing !isNew early return unchanged.

In `@src/app/api/progress/save-toggle/route.ts`:
- Around line 18-23: Update the toggle logic around the existing
findUnique/delete/create operations to handle concurrent requests safely: catch
Prisma P2002 duplicate-create and P2025 missing-delete errors and return the
intended toggle response instead of allowing an unhandled 500, or replace the
check-then-act flow with an equivalent conflict-safe upsert/delete strategy.

---

Outside diff comments:
In `@docs/roadmap.md`:
- Around line 73-79: Update the Clerk setup notes in the roadmap to describe the
current Next.js integration instead of the removed Vite setup: replace
references to `@clerk/react`, main.tsx, and VITE_CLERK_PUBLISHABLE_KEY with the
Next.js setup and NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY used in .env.example. Keep
the existing authentication behavior notes unchanged.

---

Nitpick comments:
In `@src/app/api/progress/answer/route.ts`:
- Around line 24-55: Wrap the wrongEntry mutation logic, dailyStat upsert, and
conditional chapterStat upsert in a single Prisma transaction using
prisma.$transaction. Ensure all three writes use the transaction client and
preserve the existing branching and update values so either every
answer-progress mutation commits or none does.

In `@src/app/api/progress/migrate-local/route.ts`:
- Around line 15-19: Update the migrate-local route’s loadFullProgress usage to
call it once, destructuring both isNew and progress from the returned object.
Use the destructured progress in the existing !isNew response while preserving
the current behavior.

In `@tsconfig.json`:
- Line 16: Update the jsx compiler option in tsconfig.json from react-jsx to
preserve, allowing Next.js to manage the setting and preventing configuration
churn.
🪄 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: 65e07b8c-c847-4d97-a4e8-ee4765ef4044

📥 Commits

Reviewing files that changed from the base of the PR and between 5626008 and 344e153.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (34)
  • .env.example
  • .gitignore
  • docs/roadmap.md
  • index.html
  • next.config.ts
  • package.json
  • prisma.config.ts
  • prisma/migrations/20260711114101_init/migration.sql
  • prisma/migrations/migration_lock.toml
  • prisma/schema.prisma
  • src/App.tsx
  • src/app/api/account/route.ts
  • src/app/api/progress/answer/route.ts
  • src/app/api/progress/finish-level/route.ts
  • src/app/api/progress/finish-review/route.ts
  • src/app/api/progress/migrate-local/route.ts
  • src/app/api/progress/route.ts
  • src/app/api/progress/save-toggle/route.ts
  • src/app/layout.tsx
  • src/app/page.tsx
  • src/components/AccountHeader.tsx
  • src/components/Icons.tsx
  • src/components/Navbar.tsx
  • src/hooks/useProgress.ts
  • src/index.css
  • src/lib/prisma.ts
  • src/lib/progressLogic.ts
  • src/lib/progressStore.ts
  • src/main.tsx
  • src/proxy.ts
  • src/screens/Profile.tsx
  • src/vite-env.d.ts
  • tsconfig.json
  • vite.config.ts
💤 Files with no reviewable changes (4)
  • index.html
  • src/main.tsx
  • vite.config.ts
  • src/vite-env.d.ts
✅ Files skipped from review due to trivial changes (6)
  • src/app/page.tsx
  • prisma/migrations/migration_lock.toml
  • prisma/migrations/20260711114101_init/migration.sql
  • src/lib/prisma.ts
  • .gitignore
  • next.config.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/components/Navbar.tsx
  • src/components/Icons.tsx
  • src/components/AccountHeader.tsx
  • src/index.css

Comment thread src/app/api/account/route.ts Outdated
Comment thread src/app/api/progress/finish-review/route.ts
Comment thread src/app/api/progress/migrate-local/route.ts Outdated
Comment thread src/app/api/progress/save-toggle/route.ts
- account: 先刪 Clerk 帳號再刪本地資料,避免刪除失敗時進度已清空但帳號還在
- finish-review: 驗證 xpEarned/today 輸入,避免不合法值直接寫入
- migrate-local: 合併重複查詢、處理併發搬遷撞到 unique constraint 的情況
- save-toggle: 處理併發 toggle 造成的 P2002/P2025 race condition
- answer: 三個寫入操作包進同一個 transaction,避免部分寫入
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.

1 participant