Skip to content

[Draft] Feat/i18n full refactor#79

Open
helemazuba-boop wants to merge 35 commits intomrmagic2020:mainfrom
helemazuba-boop:feat/i18n-full-refactor
Open

[Draft] Feat/i18n full refactor#79
helemazuba-boop wants to merge 35 commits intomrmagic2020:mainfrom
helemazuba-boop:feat/i18n-full-refactor

Conversation

@helemazuba-boop
Copy link
Copy Markdown

Hi there! 👋

First of all, I want to say that this is an absolutely amazing project and I really love what you've built! Just a quick heads-up: I am a high school student from China, and since my English isn't very good yet, I used Gemini to help me draft the technical details below. 😅

Here is the status of the i18n refactor and some thoughts on the recent updates:

i18n Refactor Status & Conflict Report

1. i18n Refactor Completed: The next-intl refactor is now fully completed on this branch. We have eradicated the FALLBACK_T anti-pattern from DataTable, implemented ICU templates for complex pagination strings, fully localized all Statistics charts/heatmaps, and achieved 100% key parity between en.json and zh-CN.json. The codebase now passes npx tsc --noEmit successfully.

2. Legacy Route Cleanup Pending: The old app/(app) route tree still contains remnants of FALLBACK_T. Since middleware.ts routes traffic to app/[locale]/(app), these old routes seem to be legacy code. We should consider deleting them in the future to reduce technical debt.

3. Massive Conflict with PR #78: I noticed PR #78 (Social & Discovery features) introduces significant changes to app/(app)/.... This directly conflicts with this i18n refactor because:

Let's discuss a merge strategy to integrate the new social features into the next-intl architecture safely! Let me know what you think.

…- Refactor DataTable: remove FALLBACK_T anti-pattern, use ICU message templates\n for pagination (rowsSelected, pageIndicator) and SR-only accessibility text\n- Refactor statistics components: activity-heatmap, subject-bar-chart,\n status-doughnut-chart, progress-line-chart, subject-radar-chart\n to use useTranslations('Statistics') with locale-aware date formatting\n- Refactor UsageLimitsDialog to use useTranslations('Usage')\n- Update statistics-utils: getHeatmapMonthLabels returns monthIndex\n for locale-aware month name rendering via useFormatter\n- Deprecate LABELS in constants.ts in favor of i18n keys\n- Remove legacy TableMeta.t field from types.ts\n- Synchronize en.json and zh-CN.json: 100% key parity (0 mismatches)\n across all namespaces including Statistics, Usage, DataTable,\n CommonUtils (toolbar), Admin, Review, Subjects\n- Fix TypeScript compilation errors in data-table-faceted-filter,\n compact-search-filter, enhanced-problems-table, and\n add-problems-to-set-client\n- Update statistics-utils tests for monthIndex return type\n\nAll changes pass npx tsc --noEmit with exit code 0."
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 6, 2026

@helemazuba-boop is attempting to deploy a commit to the MagicWorks Team on Vercel.

A member of the Team first needs to authorize it.

@helemazuba-boop helemazuba-boop marked this pull request as draft April 6, 2026 06:13
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b4ba3cc584

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…ies\n\n- Fix P1: Update proxy.ts to capture NextRequest cookies generated by Supabase SSR client's setAll method and apply them dynamically to whichever NextResponse the proxy handles, preserving session token refresh.\n- Fix P0: Remove 'GRANT ALL ON ALL TABLES' from the initial_schema.sql. Add 'ENABLE ROW LEVEL SECURITY' for admin_settings, user_activity_logs, and review_sessions to prevent data breaches via client tokens.
@mrmagic2020
Copy link
Copy Markdown
Owner

Hello! Thank you so much for your interest in this project! I am in fact a Chinese high school student studying in Australia, so I'm all good if you'd like to communicate in Chinese :)

I am more than happy to have your PR merged and migrate my changes afterwards. Give me some time to review your changes, and I'll get back to you soon. I've been thinking about introducing i18n for a while, so this is really helpful.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 6, 2026

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

Project Deployment Actions Updated (UTC)
wrong-question-notebook Ready Ready Preview, Comment Apr 8, 2026 9:47am

Replace imports pointing to @/app/(app)/... with relative imports
within the [locale] tree so localized component versions are used.
Remove FALLBACK_T anti-pattern from shared components (add-to-set-dialog,
file-manager) in favor of useTranslations().
Delete old app/(app)/, app/auth/, app/upload/, app/page.tsx, and
app/privacy/ which created route conflicts with the new [locale]-prefixed
routes. All user-facing routes now go through app/[locale]/.
Replace useRouter, usePathname, and Link imports from next/navigation
and next/link with locale-aware versions from @/i18n/navigation across
client components, shared components, and hooks. Server-side redirect()
stays with next/navigation as the middleware handles locale routing.
Prevent open redirect by validating the 'next' query parameter:
reject protocol-relative URLs (//) and URLs containing ://.
Add locale-aware error redirects using the locale extracted from
the request pathname.
Remove console.log statements from useSubjectForm hook that exposed
user data and API details. Remove redundant NextIntlClientProvider
from root layout — the [locale]/layout.tsx provider with messages
is sufficient.
Replace hardcoded toast messages and UI strings with t() calls in
subject-row, session-review-client, and spaced-review-client.
Add missing Review namespace keys (failedToLoadReviewSession,
failedToCompleteSession, sessionProblemsDeleted) to both en.json
and zh-CN.json.
Delete supabase migration, config, and issue markdown that were
bundled in the i18n PR but aren't related to internationalization.
Fix import order in i18n/request.ts.
The root layout hosts ConsentProvider/ConsentDialog which use
useTranslations() outside the [locale] route tree. The root provider
must supply both locale and messages via getMessages().
The root path (/) was not in the public paths list, causing the
proxy to redirect unauthenticated users to login when visiting
the landing page.
@helemazuba-boop
Copy link
Copy Markdown
Author

哈哈奇妙的缘分,首先非常感谢你的认可和Review!今天我的清明假没了接下来可能就没太多时间了,还有个问题顺带在这里提下。

🗄️ 数据库 Schema 缺失问题

目前仓库里没有包含完整的数据库迁移文件(supabase/migrations/),导致新的贡献者在创建自己的 Supabase 项目后,无法独立还原出完整的数据库结构。具体表现为以下运行时报错:

缺失的 RPC 函数

| 函数名 | 触发页面 | 报错代码 |

|---|---|---|

| get_user_statistics(p_user_id) | 统计页 | PGRST202 |

| get_study_streaks(p_user_id, p_user_tz) | 统计页 | PGRST202 |

| get_session_statistics(p_user_id) | 统计页 | PGRST202 |

| get_subject_breakdown(p_user_id) | 统计页 | PGRST202 |

| get_weekly_progress(p_user_id, p_user_tz) | 统计页 | PGRST202 |

| get_activity_heatmap(p_user_id, p_user_tz) | 统计页 | PGRST202 |

| get_recent_study_activity(p_user_id) | 统计页 | PGRST202 |

| get_user_storage_bytes(p_user_id) | 用量检查 | PGRST202 |

缺失的表

| 表名 | 触发场景 | 报错代码 |

|---|---|---|

| user_quota_overrides | AI 提取配额检查 | PGRST205 |

缺失的字段

| 表.字段 | 触发场景 |

|---|---|

| problems.user_id | 删除题目时清理附件 |

💡 建议

能否考虑将完整的数据库 Schema 导出并提交到仓库中?这样做有几个好处:

  1. 新贡献者可以一键初始化开发环境:运行 supabase db reset 即可还原完整的表结构、RPC 函数和 RLS 策略

  2. 数据库变更可追溯:每次修改表结构都通过 Migration 文件记录,方便 Code Review

  3. 避免环境差异:确保所有开发者的数据库结构完全一致

具体操作可以参考:

# 从你的 Supabase 项目导出完整 Schema

supabase db pull



# 或者手动导出

supabase db dump -f supabase/migrations/00000000000000_initial_schema.sql

导出后将生成的 SQL 文件提交到 supabase/migrations/ 目录下即可。


这个反馈不影响项目本身的功能(因为你的线上数据库里这些都是存在的),主要是为了方便其他想参与贡献的开发者能更顺利地搭建环境。如果你方便的话,导出一份完整的 Schema 会非常有帮助!🙏

@mrmagic2020
Copy link
Copy Markdown
Owner

能否考虑将完整的数据库 Schema 导出并提交到仓库中?

当然!我开始做项目的时候完全没有考虑到会有其他开发者参与贡献,于是就没有注重环境配置这块的指引。我会把完整的schema跟这个PR一起merge进去的。

- Add locale switcher component to navigation bar
- Fix 97+ missing translation keys across all namespaces
- Fix hardcoded strings in attempt-timeline, attempt-timeline-entry,
  compact-search-filter, hero-animation, resume-session-dialog,
  problem-set-columns, and status-doughnut-chart
- Fix display name functions (column, type, status) not wrapped in t()
- Fix ICU format mismatches (streakDays, selectedRowsInfo)
- Fix string discrepancies vs main (statistics subtitle, insights
  page header, stat card labels, problem page title)
- Add i18n-status.js CI script and GitHub Actions workflow
- Remove superseded check-i18n.js

This comment was marked as outdated.

Use date-fns locale in notebook-card for formatDistanceToNow.
Rewrite formatRelativeTime to use Intl.RelativeTimeFormat and
make formatDisplayDate/formatDisplayDateTime locale-aware. All
three functions auto-detect locale from <html lang> so existing
callers get localized output without changes.
Use locale-aware toLocaleString for the generated-at date.
Replace hardcoded "x clusters" and weak spot pluralization with
ICU plural keys (weakSpotCount, clusterCount).
helemazuba-boop and others added 14 commits April 7, 2026 23:42
The root layout and [locale] layout both wrapped children in
NextIntlClientProvider, causing the full message bundle to be
serialized into client HTML twice. The [locale] layout is the
correct sole provider for all localized routes.
…layout"

This reverts commit e9454153ea11ee0a2f41a11a36e4926aabea795a.
The root layout's NextIntlClientProvider was shipping the full message
bundle, duplicating the [locale] layout's provider. Now only the
CookieConsent namespace is passed at root level, since that's the
only client component tree outside the [locale] provider scope.
The {plural} interpolation variable leaked English suffixes ("s") into
zh-CN translations. Replaced with ICU {count, plural, one {...} other {...}}
in both en.json and zh-CN.json, and removed the now-unnecessary plural
parameter from callers.
A path like /enrollment would falsely match the /en locale prefix and
get stripped to /rollment. Now requires the prefix to be followed by
'/' or be the exact path.
getUserFromRequest now returns both user and accessToken from a single
Supabase client, removing the second client creation and getSession()
call that was only used to obtain the access token for the login
heartbeat.
The [locale] layout had a duplicated ['en', 'zh-CN'] array. Now
imports from the single source of truth in i18n/routing.ts so
adding a locale doesn't require updating multiple files.
next-intl's t() never returns falsy — missing keys return the key
name itself. The || 'English string' fallbacks were dead code that
created ghost sources of truth outside the message files.
next-intl's t() accepts interpolation values as the second argument,
not defaultValue (that's React-Intl's API). The key Common.clickToViewFullSize
already exists in both locale files.
Replace informal "(s)" suffix with proper ICU {n, plural, one {...}
other {...}} syntax for minutesAgo, hoursAgo, daysAgo, weeksAgo.
This ensures correct grammar for singular values (e.g. "1 minute ago"
instead of "1 minute(s) ago").
- subject-row.tsx: translate Save/Cancel/Rename/Delete buttons and
  tooltip strings using Common, CommonUtils, and new Subjects keys
- answer-input.tsx: translate fallback "No answer input" message
- mobile-uploader.tsx: translate error messages for failed uploads
  and network errors
- problem-form.tsx: translate image save failure toast

Added corresponding keys to en.json and zh-CN.json in the Subjects,
Problems, and Upload namespaces.
Replace Subjects.problemCount "(s)" shorthand with proper ICU plural
syntax so cards display "1 problem" vs "2 problems" correctly.
- Remove unused useTranslations imports/variables in problem-set-columns,
  statistics-page-client, and sr-summary-client
- Remove unused catch bindings in file-manager
- Change finalResponse from let to const in proxy.ts
- Fix null-to-undefined type mismatch for accessToken in proxy.ts
- Add eslint-disable for require() imports in i18n-status.js script
Convert 13 remaining informal "(s)" plurals across Subjects,
ProblemSets, Statistics, and CommonUtils namespaces to proper ICU
{count, plural, one {...} other {...}} syntax. Fixes grammar for
singular values throughout the app (e.g. "1 problem" not "1 problem(s)").
@mrmagic2020 mrmagic2020 marked this pull request as ready for review April 8, 2026 11:53
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.

3 participants