i18n: replace hardcoded strings with i18n keys across controller layer#4949
i18n: replace hardcoded strings with i18n keys across controller layer#4949DieuNN wants to merge 1 commit into
Conversation
Replace hardcoded Chinese/English error strings in 16 controller files with i18n.T() and common.ApiErrorI18n() calls. Add 80+ new i18n message key constants covering channel, passkey, 2FA, topup, subscription, oauth, and misc modules. Add corresponding locale entries in en/zh-CN/zh-TW. - Add missing i18n imports (misc, passkey, secure_verification, twofa) - Fix pre-existing syntax errors in twofa.go (trailing commas) - Remove duplicate i18n constant blocks and YAML entries - Minor frontend i18n fixes (hero terminal demo, en.json) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (22)
WalkthroughThis PR internationalizes API error and success responses across the entire system. It replaces 16 controller handlers' hardcoded Chinese messages with i18n-backed helpers, defines 80+ new message key constants, extends translations in three backend locales and web UI, and updates frontend components to use localized text. ChangesAPI Response Internationalization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
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.
Pull request overview
This PR expands the existing i18n infrastructure by replacing many hardcoded controller-layer response strings with i18n key lookups (via i18n.T() / common.ApiErrorI18n() / common.ApiSuccessI18n()), and adds the necessary i18n keys and locale entries. It also includes small frontend i18n updates for the hero terminal demo.
Changes:
- Replaced numerous hardcoded controller responses with i18n keys across authentication (2FA/passkey/secure verification), payments/top-up, channels, and misc endpoints.
- Added many new i18n key constants (
i18n/keys.go) and expanded backend locale YAMLs (en/zh-CN/zh-TW). - Minor frontend i18n usage updates in the home hero terminal demo and a lockfile metadata update.
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| web/default/src/i18n/locales/en.json | Adds missing UI translation keys used by the hero terminal demo. |
| web/default/src/features/home/components/hero-terminal-demo.tsx | Switches several UI labels/status strings to react-i18next translation lookups. |
| web/default/bun.lock | Adds configVersion field to Bun lockfile. |
| i18n/locales/zh-TW.yaml | Adds new backend message translations (topup/channel/passkey/2FA/secure verification/etc.). |
| i18n/locales/zh-CN.yaml | Adds new backend message translations (topup/channel/passkey/2FA/secure verification/etc.). |
| i18n/locales/en.yaml | Updates English backend message translations and adds new keys. |
| i18n/keys.go | Adds many new i18n message key constants for controller responses. |
| controller/twofa.go | Replaces hardcoded 2FA messages with i18n-based API helpers. |
| controller/topup.go | Replaces several hardcoded top-up/payment messages with i18n lookups. |
| controller/topup_waffo_pancake.go | Replaces Waffo Pancake top-up messages with i18n lookups. |
| controller/topup_creem.go | Replaces Creem top-up messages with i18n lookups. |
| controller/subscription_payment_epay.go | Replaces subscription payment flow messages with i18n API helpers. |
| controller/subscription_payment_creem.go | Replaces subscription Creem payment flow messages with i18n API helpers. |
| controller/secure_verification.go | Replaces secure verification responses/errors with i18n API helpers. |
| controller/pricing.go | Replaces reset success message with i18n lookup. |
| controller/prefill_group.go | Replaces prefill group validation messages with i18n API helpers. |
| controller/passkey.go | Replaces various passkey responses with i18n API helpers. |
| controller/model_meta.go | Replaces model meta validation errors with i18n API helpers. |
| controller/misc.go | Replaces DB connection failure message with i18n lookup. |
| controller/codex_usage.go | Replaces Codex usage error messages with i18n API helpers. |
| controller/codex_oauth.go | Replaces Codex OAuth flow error messages with i18n API helpers. |
| controller/checkin.go | Replaces check-in enablement/success messaging with i18n API helpers. |
| controller/channel.go | Replaces multiple channel API errors/successes with i18n API helpers. |
Comments suppressed due to low confidence (3)
controller/secure_verification.go:62
- MsgSecureVerifyGetUserFailed maps to "secure_verify.get_user_failed", but the locales use "secure_verification.get_user_failed" and include a {{.Error}} template placeholder. This call also drops the underlying error details. Use the correct message ID and pass template data (e.g., {"Error": err.Error()}) so the translated message renders correctly.
// 获取用户信息
user := &model.User{Id: userId}
if err := user.FillUserById(); err != nil {
common.ApiErrorI18n(c, i18n.MsgSecureVerifyGetUserFailed)
return
}
controller/secure_verification.go:113
- These error branches use MsgSecureVerifyPasskeyStatusAbnormal/MsgSecureVerifyPasskeyNotReady ("secure_verify." IDs), but the locales use "secure_verification." and include an {{.Error}} placeholder for the abnormal-status case. Align the IDs with the locale keys and pass template data for the error case so translations work and placeholders are filled.
// Passkey branch only trusts the short-lived marker written by PasskeyVerifyFinish.
verified, err = consumePasskeyReady(c)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgSecureVerifyPasskeyStatusAbnormal)
return
}
if !verified {
common.ApiErrorI18n(c, i18n.MsgSecureVerifyPasskeyNotReady)
return
}
controller/secure_verification.go:131
- On session save failure this returns MsgPasskeySaveSessionFailed, but this is a secure verification flow and the locale additions include secure_verification.save_failed with an {{.Error}} placeholder. Use the secure_verification-specific key here and pass the underlying error as template data so the message is accurate and renders correctly.
// 验证成功,在 session 中记录时间戳
now, err := setSecureVerificationSession(c, req.Method)
if err != nil {
common.ApiErrorI18n(c, i18n.MsgPasskeySaveSessionFailed)
return
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ability.db_corrupted: "Database consistency has been compromised" | ||
| ability.repair_running: "A repair task is already running, please try again later" | ||
| # Secure verification messages | ||
| secure_verification.code_required: "Verification code cannot be empty" |
| MsgSecureVerificationCodeRequired = "secure_verification.code_required" | ||
| MsgSecureVerificationSuccess = "secure_verification.verify_success" | ||
| MsgSecureVerificationRequired = "secure_verification.required" | ||
| MsgSecureVerificationCorresponding = "secure_verification.corresponding_required" | ||
| MsgSecureVerifyNotLoggedIn = "secure_verify.not_logged_in" | ||
| MsgSecureVerifyGetUserFailed = "secure_verify.get_user_failed" | ||
| MsgSecureVerifyNo2FAOrPasskey = "secure_verify.no_2fa_or_passkey" | ||
| MsgSecureVerifyPasskeyStatusAbnormal = "secure_verify.passkey_status_abnormal" | ||
| MsgSecureVerifyPasskeyNotReady = "secure_verify.passkey_not_ready" | ||
| MsgSecureVerifyUnsupportedMethod = "secure_verify.unsupported_method" | ||
| MsgSecureVerifyFailed = "secure_verify.failed" |
| c.JSON(http.StatusUnauthorized, gin.H{ | ||
| "success": false, | ||
| "message": "未登录", | ||
| "message": i18n.T(c, i18n.MsgSecureVerifyNotLoggedIn), |
| if req.PaymentMethod != model.PaymentMethodCreem { | ||
| c.JSON(http.StatusOK, gin.H{"message": "error", "data": "不支持的支付渠道"}) | ||
| c.JSON(http.StatusOK, gin.H{"message": "error", "data": i18n.T(c, i18n.MsgTopupCreemUnsupportedPayment)}) | ||
| return | ||
| } | ||
|
|
||
| if req.ProductId == "" { | ||
| c.JSON(http.StatusOK, gin.H{"message": "error", "data": "请选择产品"}) | ||
| c.JSON(http.StatusOK, gin.H{"message": "error", "data": i18n.T(c, i18n.MsgTopupCreemSelectProduct)}) | ||
| return | ||
| } |
| if channel.Type == constant.ChannelTypeVertexAi { | ||
| if channel.Other == "" { | ||
| return fmt.Errorf("部署地区不能为空") | ||
| return fmt.Errorf(i18n.MsgChannelDeploymentRegionRequired) |
| } | ||
| if len(cleanKeys) == 0 { | ||
| return nil, fmt.Errorf("批量添加 Vertex AI 的 keys 不能为空") | ||
| return nil, fmt.Errorf(i18n.MsgChannelVertexAiKeysRequired) |
| default: | ||
| c.JSON(http.StatusOK, gin.H{ | ||
| "success": false, | ||
| "message": "不支持的添加模式", | ||
| "message": "unsupported add mode", | ||
| }) | ||
| return |
| func requireSecureVerificationMethod(c *gin.Context, method string) bool { | ||
| session := sessions.Default(c) | ||
| verifiedAt, ok := session.Get(SecureVerificationSessionKey).(int64) | ||
| if !ok || time.Now().Unix()-verifiedAt >= SecureVerificationTimeout { | ||
| session.Delete(SecureVerificationSessionKey) | ||
| session.Delete(secureVerificationMethodSessionKey) | ||
| _ = session.Save() | ||
| common.ApiErrorMsg(c, "请先完成安全验证") | ||
| common.ApiErrorI18n(c, i18n.MsgSecureVerificationRequired) | ||
| return false | ||
| } | ||
|
|
||
| if verifiedMethod, ok := session.Get(secureVerificationMethodSessionKey).(string); !ok || verifiedMethod != method { | ||
| common.ApiErrorMsg(c, "请先完成对应的安全验证") | ||
| common.ApiErrorI18n(c, i18n.MsgSecureVerificationCorresponding) | ||
| return false |
Summary
Replace hardcoded Chinese/English error strings across 16 controller files with proper
i18n.T()andcommon.ApiErrorI18n()calls. This makes all user-facing error messages translatable via the existing go-i18n infrastructure.Changes
Backend i18n
i18n/keys.go— added 80+ new message key constants (channel, passkey, 2FA, topup, subscription, oauth, misc, codex, distributor, custom_oauth)i18n/locales/{en,zh-CN,zh-TW}.yaml— added corresponding locale entriesi18nimport (misc, passkey, secure_verification, twofa)controller/twofa.go— fixed pre-existing syntax errors (trailing commas in struct literals)Frontend i18n
web/default/src/features/home/components/hero-terminal-demo.tsx— minor i18n fixesweb/default/src/i18n/locales/en.json— added missing keyVerification
go build ./controller/... ./i18n/... ./common/... ./model/... ./service/... ./router/... ./middleware/... ./relay/... ./setting/... ./dto/... ./oauth/... ./pkg/...— compiles cleanbun run build— builds clean🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Chores