Skip to content

feat: support subscription redemption codes - #5084

Open
fishxcode wants to merge 9 commits into
QuantumNous:mainfrom
fishxcode:feature/subscription-redemption-codes
Open

feat: support subscription redemption codes#5084
fishxcode wants to merge 9 commits into
QuantumNous:mainfrom
fishxcode:feature/subscription-redemption-codes

Conversation

@fishxcode

@fishxcode fishxcode commented May 24, 2026

Copy link
Copy Markdown

提交说明 / PR Notice

Compare:
main...fishxcode:newapi:feature/subscription-redemption-codes

变更描述 / Description

本 PR 为兑换码增加“订阅套餐兑换码”能力,同时保持原有额度兑换码行为兼容。

主要变更:

  • 后端 Redemption 增加兑换类型、订阅套餐 ID、套餐标题展示字段。
  • 管理端创建/编辑兑换码时支持选择“额度”或“订阅套餐”。
  • 用户兑换订阅套餐码后会创建用户订阅,兑换码会被标记为已使用。
  • 用户兑换额度码仍保持旧行为:只增加用户额度,并且 /api/user/topupdata 继续返回数字,避免影响旧前端或外部调用方。
  • default 前端和 classic 前端均支持套餐兑换码发放、列表展示、用户兑换结果提示。
  • 补齐 default 和 classic 的新增 i18n 文案。
  • 增加回归测试覆盖套餐兑换、额度兑换兼容、额度兑换 API 返回格式。
  • 顺手修复本分支验证中暴露的几个既有测试/稳定性问题:stream scanner 非正超时防御、Claude 文件内容转换、token model limit 分组读取、stream status 保留预初始化状态。

变更类型 / Type of change

  • Bug 修复 (Bug fix)
  • 新功能 (New feature)
  • 性能优化 / 重构 (Refactor)
  • 文档更新 (Documentation)

关联任务 / Related Issue

提交前检查项 / Checklist

  • 人工确认:我已整理并撰写此描述,没有直接粘贴未经处理的原始输出。
  • 非重复提交:已检查当前功能范围,避免重复实现已有兑换码功能。
  • Bug fix 说明:本 PR 主要为新功能,附带修复本地验证中暴露的稳定性问题。
  • 变更理解:已确认额度码旧行为、套餐码新行为、两套前端 payload/response 与后端字段一致。
  • 范围聚焦:变更集中在兑换码、套餐兑换、相关前端与验证阻塞修复。
  • 本地验证:已在本地运行并通过测试和构建。
  • 安全合规:代码中无敏感凭据。

运行证明 / Proof of Work

本地验证通过:

go test ./... -count=1 -timeout 180s
cd web/default && bun run typecheck
cd web/default && bun run i18n:sync && bun run build
cd web/classic && bun run build
cd web/classic && bunx prettier --check "src/components/table/redemptions/modals/EditRedemptionModal.jsx" "src/components/table/redemptions/RedemptionsColumnDefs.jsx" "src/components/topup/index.jsx"
git diff --cached --check && git diff --check

功能核对:

  • default 前端:支持管理端发放额度码/套餐码,用户端兑换额度码/套餐码,响应处理兼容 number | object
  • classic 前端:支持管理端发放额度码/套餐码,用户端兑换额度码/套餐码,响应处理兼容 number | object
  • 后端:套餐码创建订阅;额度码保持原有加余额逻辑;额度兑换 API 保持旧数字响应格式。

Summary by CodeRabbit

  • New Features

    • Added subscription-based redemption codes alongside quota-based codes with new "Benefit" selection UI
    • File attachment support for Claude channel, including PDFs and text files
    • Enhanced redemption validation with specific error messages for invalid, used, or expired codes
  • Bug Fixes

    • Improved streaming timeout fallback logic with additional safety checks
  • Internationalization

    • Added translations for redemption benefits and subscription flows across 7 languages
  • Tests

    • New test coverage for subscription and quota redemption flows
    • New test for Claude file handling validation

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR extends redemption code functionality to support subscription plan grants alongside quota grants, implementing backend validation, data models, error handling, comprehensive testing, and full-stack frontend UI with multi-language support. It also adds Claude file relay handling and improves stream scanner resilience.

Changes

Subscription Redemption Code Implementation

Layer / File(s) Summary
Model error definitions and redemption data types
model/errors.go, model/redemption.go
Adds sentinel error types (ErrInvalidCode, ErrCodeUsed, ErrCodeExpired); extends Redemption with RedemptionType, SubscriptionPlanId, SubscriptionPlanTitle; introduces RedeemResult return type and NormalizeRedemptionType function.
Redemption transaction validation and type-specific processing
model/redemption.go
Implements Redeem function returning RedeemResult; normalizes type; validates code status with sentinel errors; branches for subscription (plan lookup, UserSubscription creation) vs quota (user quota increment); type-aware logging and error mapping.
Redemption queries with subscription plan title enrichment
model/redemption.go
Updates GetAllRedemptions, SearchRedemptions, GetRedemptionById to enrich results with subscription plan titles via batch and single title attachment helpers.
Redemption CRUD with type normalization and validation
controller/redemption.go
Updates AddRedemption and UpdateRedemption to normalize RedemptionType, validate subscription plan existence, set defaults per type, persist both fields.
TopUp endpoint error mapping and type-aware response shaping
controller/user.go
Maps sentinel errors to i18n responses; shapes data as legacy numeric quota for quota-type or full RedeemResult for subscriptions.
ListModels group loading conditional on token limiting
controller/model.go
Defers group lookup to execute only when token limiting is disabled.
Test database setup and TopUp handler test
model/task_cas_test.go, controller/redemption_topup_test.go
Configures shared in-memory SQLite; adds Redemption schema; implements TopUp legacy response test.
Subscription and quota redemption behavior tests
model/redemption_subscription_test.go
Tests subscription code creating UserSubscription and plan linkage; tests quota code preserving quota semantics without subscriptions.
Frontend type definitions for redemption models
web/default/src/features/redemption-codes/types.ts, web/classic/src/components/table/redemptions/...
Extends schemas with redemption_type and subscription_plan_id fields and defaults.
Classic frontend redemption table and TopUp UI
web/classic/src/components/table/redemptions/RedemptionsColumnDefs.jsx, web/classic/src/components/topup/index.jsx
Displays subscription plan or quota benefit by type; branches TopUp success handling by redemption_type.
Classic frontend edit redemption modal with dynamic type selection
web/classic/src/components/table/redemptions/modals/EditRedemptionModal.jsx
Fetches plans on modal open; adds type selector; conditionally renders plan dropdown and quota inputs; normalizes payload per type.
Default frontend redemption table and TopUp UI
web/default/src/features/redemption-codes/components/redemptions-columns.tsx, web/default/src/features/wallet/hooks/use-redemption.ts
Changes column header to Benefit; displays subscription plan or quota by type; branches TopUp success handling and toast messaging.
Default frontend redemptions drawer with type and plan management
web/default/src/features/redemption-codes/components/redemptions-mutate-drawer.tsx
Converts type to Select; fetches plans; clears plan when switching to quota; conditionally renders plan Select and quota input.
Default frontend form schema and payload transformations
web/default/src/features/redemption-codes/lib/redemption-form.ts
Adds form fields with cross-field validation; transforms payload per type; maps defaults from redemption model.
Default frontend wallet API response types
web/default/src/features/wallet/types.ts
Introduces RedemptionResult interface; supports number or RedemptionResult in RedemptionResponse.
Classic frontend internationalization for redemption UI
web/classic/src/i18n/locales/en.json, web/classic/src/i18n/locales/fr.json, web/classic/src/i18n/locales/ja.json, web/classic/src/i18n/locales/ru.json, web/classic/src/i18n/locales/vi.json, web/classic/src/i18n/locales/zh-CN.json, web/classic/src/i18n/locales/zh-TW.json, web/classic/src/i18n/locales/zh.json
Adds redemption type, benefit, benefit settings, and success message translations across all locales.
Default frontend internationalization with password-reset consolidation and redemption UI
web/default/src/i18n/locales/...
Consolidates auth.resetPasswordConfirm entries; adds benefit, type, plan activation, and success message translations; relocates keys for consistency.
Default frontend static i18n key definitions
web/default/src/i18n/static-keys.ts
Adds static entries for redemption code benefits labeling and plan activation success.

Infrastructure and Relay Improvements

Layer / File(s) Summary
Claude relay file content conversion with MIME type handling
relay/channel/claude/relay-claude.go
Validates MessageFile and FileData; infers MIME type from filename; base64-decodes text/* into Claude text blocks; maps PDF to document blocks; rejects unsupported MIME types.
Claude relay file handling tests
relay/channel/claude/relay_claude_test.go
Updates unsupported file test to verify error; adds empty file content error test.
Stream status and timeout handling resilience
relay/helper/stream_scanner.go
Preserves existing StreamStatus; adds tiered fallback for non-positive timeout.
Payment setting compliance text punctuation reference
web/classic/src/components/settings/PaymentSetting.jsx
Changes punctuation reference from i18n lookup to hardcoded literal.
Usage logs route type validation schema fix
web/default/src/routes/_authenticated/usage-logs/$section.tsx
Updates parse failure fallback to undefined; marks type field optional.

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested Reviewers

  • Calcium-Ion
  • seefs001
  • creamlike1024

Poem

🐰 A code redeemed anew, two paths combined,
With quotas flowing and subscriptions signed,
The modal prompts, the dropdowns align,
While Claude reads files and stream scanners shine,
Through fifteen tongues, the UI's refined—
An elegant gift for users to find! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: support subscription redemption codes' directly and concisely describes the primary change: adding subscription plan redemption code support.
Linked Issues check ✅ Passed The PR comprehensively implements all coding requirements from issue #5086: subscription-aware redemption model [#5086], plan binding and validation [#5086], automatic subscription grant on redemption [#5086], credit/subscription distinction in records [#5086], and error handling for edge cases [#5086].
Out of Scope Changes check ✅ Passed All code changes are directly scoped to subscription redemption implementation or closely related incidental fixes (stream scanner timeout, Claude file handling, token model limiting). Minor incidental changes do not detract from core objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Nitpick comments (1)
web/classic/src/i18n/locales/zh-CN.json (1)

3811-3811: 💤 Low value

Questionable translation key: standalone punctuation

The key-value pair "、": "、" is unusual. The Chinese enumeration comma (、) is typically embedded directly within translated strings rather than defined as a separate translation key.

Unless there's a specific use case requiring this standalone punctuation key, consider removing it or documenting its purpose. If it's meant to be used in dynamic string concatenation, that pattern should be avoided in favor of proper i18n interpolation.

🤖 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 `@web/classic/src/i18n/locales/zh-CN.json` at line 3811, The translation file
contains a questionable standalone key "、" mapping to itself; remove this
standalone punctuation key from the locale (or add a clear comment/documentation
in the repo explaining its specific intended use) and refactor any code that
consumes it to use proper i18n interpolation/placeholders in functions like
t(...) instead of concatenating a punctuation translation; look for usages of
the symbol "、" in templates or code and replace dynamic concatenation with
interpolation in the relevant translation keys.
🤖 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 `@model/redemption.go`:
- Around line 286-288: The DB query that populates plans (the DB.Select("id",
"title").Where("id IN ?", planIDs).Find(&plans).Error check) is currently
returning silently on error; instead log the error with context (include the
error value and planIDs) and return the error up the stack (or at minimum return
after logging) so failures aren't swallowed; make the same change for the second
identical check later in the file (the other DB.Select(...).Find(&plans).Error
usage) and use the project’s logger (or log.Printf/log.Errorf) to emit a clear
message referencing "plans" and the planIDs variable.

In `@relay/channel/claude/relay-claude.go`:
- Around line 380-398: The code currently silently skips file parts in the
dto.ContentTypeFile branch (when file.FileData == "" or when mimeType is
unsupported), which can cause the request to proceed with missing attachments;
update the dto.ContentTypeFile handling (the block that reads
mediaMessage.GetFile(), uses mimeTypeFromMessageFile, and appends to
claudeMediaMessages with dto.ClaudeMediaMessage) to instead return a validation
error when file.FileData is empty but file.FileID exists (or when file is
entirely missing) and to return a clear validation error for unsupported MIME
types (i.e., not text/* or application/pdf) rather than continue; ensure the
error messages reference the offending file (file.FileID or a description) so
callers can correct the input.

In `@web/classic/src/components/topup/index.jsx`:
- Around line 179-210: The subscription-success branch (when
isSubscriptionRedemption is true) updates messaging but does not refresh the
subscriptions state (activeSubscriptions / allSubscriptions); add an await call
after the Modal.success in that branch to invoke the same routine that refreshes
subscriptions (the function used elsewhere to populate
activeSubscriptions/allSubscriptions — e.g.
fetchSubscriptions()/loadSubscriptions()/getSubscriptions()), similar to the
existing await getUserQuota() call at the end, so the UI updates immediately
after redemption.

In
`@web/default/src/features/redemption-codes/components/redemptions-mutate-drawer.tsx`:
- Around line 106-117: The effect that loads plans when the drawer opens
(useEffect dependent on open) currently calls getAdminPlans() but doesn't handle
promise rejections, which can leave stale plans; wrap the fetch in a try/catch
(or add .catch) and on any error or non-success result call setPlans([]) and
log/report the error so rejected promises are handled; update the block that
calls getAdminPlans() to ensure failures always clear plans (setPlans([])) and
avoid unhandled rejections.

In `@web/default/src/features/redemption-codes/lib/redemption-form.ts`:
- Line 42: The validation for quota_dollars in the redemption form uses
z.number().min(0) but the error text says "Quota must be a positive number";
update either the rule or the message to match: either change the schema to
z.number().min(1, t('Quota must be a positive number')) if zero should be
disallowed, or keep min(0) and change the message to t('Quota must be a
non-negative number') (update the quota_dollars line accordingly).

In `@web/default/src/features/wallet/hooks/use-redemption.ts`:
- Around line 45-59: The conditional currently treats response.data as an object
but doesn't guard against null (typeof null === 'object'); update the checks in
use-redemption.ts so you verify response.data is non-null before accessing
properties — e.g., change occurrences like "typeof response.data === 'object' &&
response.data.redemption_type === 'subscription'" to explicitly ensure
response.data != null (or response.data !== null) first, and similarly guard
access to response.data.subscription_plan_title,
response.data.subscription_plan_id and response.data.quota when computing
quotaAdded.

In `@web/default/src/i18n/locales/fr.json`:
- Line 539: Multiple billing/subscription strings in fr.json are still English
(e.g., the key/value pair "Bind a Pancake store + product": "Bind a Pancake
store + product"); replace these English values with their proper French
translations (or remove the entries so the app falls back to the base locale)
for that key and for the other affected entries referenced (lines/ranges you
listed). Locate and update the exact keys in
web/default/src/i18n/locales/fr.json (for example the "Bind a Pancake store +
product" key and the other keys in the ranges 566-567, 1033-1035, 1039-1040,
etc.) to French strings consistent with the UX, ensuring grammar and context
match billing/checkout flows.

In `@web/default/src/i18n/locales/ja.json`:
- Line 539: Several entries in the Japanese locale file are left in English
(e.g., the string key "Bind a Pancake store + product" and other entries listed
in the review) — locate those literal English values in ja.json (search for
"Bind a Pancake store + product" and the other English phrases around the
reported ranges) and replace them with accurate Japanese translations,
preserving the exact JSON keys, punctuation and any interpolation placeholders;
after editing, validate the JSON and run the i18n linter/tests to ensure no
missing keys or formatting issues.

In `@web/default/src/i18n/locales/ru.json`:
- Line 539: The Russian locale file contains untranslated English values (e.g.,
the key "Bind a Pancake store + product") which leads to mixed-language UI;
update the ru.json entries so the values are proper Russian translations for
that key and the other newly added keys referenced (those still showing English
strings), preserving the exact JSON keys and formatting, keeping any
placeholders intact, and run a quick lint/parse to ensure valid JSON after
replacing the English text with Russian equivalents.

In `@web/default/src/i18n/locales/vi.json`:
- Line 539: The added English entry "Bind a Pancake store + product" in vi.json
(and the other listed English lines) must be translated into Vietnamese before
merging; update the value for the "Bind a Pancake store + product" key (and the
entries at the provided locations: 566-567, 1033-1040, etc.) with accurate
Vietnamese translations, preserving any punctuation/placeholders and JSON string
formatting, then run the i18n JSON validator/linter to ensure no syntax errors
and that plural/placeholders remain intact (search for the English phrases in
vi.json to locate each key).

---

Nitpick comments:
In `@web/classic/src/i18n/locales/zh-CN.json`:
- Line 3811: The translation file contains a questionable standalone key "、"
mapping to itself; remove this standalone punctuation key from the locale (or
add a clear comment/documentation in the repo explaining its specific intended
use) and refactor any code that consumes it to use proper i18n
interpolation/placeholders in functions like t(...) instead of concatenating a
punctuation translation; look for usages of the symbol "、" in templates or code
and replace dynamic concatenation with interpolation in the relevant translation
keys.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2ba913ee-e480-4f20-9d05-f4839bbd99a7

📥 Commits

Reviewing files that changed from the base of the PR and between 0354c38 and 31783bf.

📒 Files selected for processing (40)
  • controller/model.go
  • controller/redemption.go
  • controller/redemption_topup_test.go
  • controller/user.go
  • model/errors.go
  • model/redemption.go
  • model/redemption_subscription_test.go
  • model/task_cas_test.go
  • relay/channel/claude/relay-claude.go
  • relay/helper/stream_scanner.go
  • web/classic/src/components/table/redemptions/RedemptionsColumnDefs.jsx
  • web/classic/src/components/table/redemptions/modals/EditRedemptionModal.jsx
  • web/classic/src/components/topup/index.jsx
  • web/classic/src/i18n/locales/en.json
  • web/classic/src/i18n/locales/fr.json
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/vi.json
  • web/classic/src/i18n/locales/zh-CN.json
  • web/classic/src/i18n/locales/zh-TW.json
  • web/classic/src/i18n/locales/zh.json
  • web/default/src/features/redemption-codes/components/redemptions-columns.tsx
  • web/default/src/features/redemption-codes/components/redemptions-mutate-drawer.tsx
  • web/default/src/features/redemption-codes/lib/redemption-form.ts
  • web/default/src/features/redemption-codes/types.ts
  • web/default/src/features/wallet/hooks/use-redemption.ts
  • web/default/src/features/wallet/types.ts
  • web/default/src/i18n/locales/_reports/_sync-report.json
  • web/default/src/i18n/locales/_reports/fr.untranslated.json
  • web/default/src/i18n/locales/_reports/ja.untranslated.json
  • web/default/src/i18n/locales/_reports/ru.untranslated.json
  • web/default/src/i18n/locales/_reports/vi.untranslated.json
  • web/default/src/i18n/locales/_reports/zh.untranslated.json
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
  • web/default/src/i18n/static-keys.ts

Comment thread model/redemption.go
Comment thread relay/channel/claude/relay-claude.go Outdated
Comment thread web/classic/src/components/topup/index.jsx
Comment thread web/default/src/features/redemption-codes/lib/redemption-form.ts
Comment thread web/default/src/features/wallet/hooks/use-redemption.ts Outdated
Comment thread web/default/src/i18n/locales/fr.json Outdated
Comment thread web/default/src/i18n/locales/ja.json Outdated
Comment thread web/default/src/i18n/locales/ru.json Outdated
Comment thread web/default/src/i18n/locales/vi.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@web/default/src/features/redemption-codes/lib/redemption-form.ts`:
- Line 42: The quota_dollars schema currently enforces z.number().min(1)
unconditionally which breaks subscription-type redemptions that legitimately
have quota 0; update the validation in redemption-form.ts so quota_dollars
allows 0 for subscription redemptions (or is optional/nullable when
redemptionType === 'subscription'). Locate the quota_dollars definition(s) (the
z.number().min(1, ...) lines) and replace with a conditional rule or refine the
parent schema to use z.preprocess/z.union or .refine that checks redemptionType
(or makes quota_dollars optional) so existing subscription codes from the
backend with quota 0 pass validation; apply the same change to the other
occurrences referenced (the blocks around the other quota_dollars definitions).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c09469f-7a96-48c8-953a-b86f335ff8f2

📥 Commits

Reviewing files that changed from the base of the PR and between 31783bf and 38a548a.

📒 Files selected for processing (25)
  • model/redemption.go
  • relay/channel/claude/relay-claude.go
  • relay/channel/claude/relay_claude_test.go
  • web/classic/src/components/settings/PaymentSetting.jsx
  • web/classic/src/components/topup/index.jsx
  • web/classic/src/i18n/locales/en.json
  • web/classic/src/i18n/locales/fr.json
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/vi.json
  • web/classic/src/i18n/locales/zh-CN.json
  • web/classic/src/i18n/locales/zh-TW.json
  • web/classic/src/i18n/locales/zh.json
  • web/default/src/features/redemption-codes/components/redemptions-mutate-drawer.tsx
  • web/default/src/features/redemption-codes/lib/redemption-form.ts
  • web/default/src/features/wallet/hooks/use-redemption.ts
  • web/default/src/i18n/locales/_reports/_sync-report.json
  • web/default/src/i18n/locales/_reports/fr.untranslated.json
  • web/default/src/i18n/locales/_reports/ja.untranslated.json
  • web/default/src/i18n/locales/_reports/ru.untranslated.json
  • web/default/src/i18n/locales/_reports/vi.untranslated.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
💤 Files with no reviewable changes (12)
  • web/classic/src/i18n/locales/fr.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/zh-TW.json
  • web/classic/src/i18n/locales/zh.json
  • web/default/src/i18n/locales/_reports/ru.untranslated.json
  • web/classic/src/i18n/locales/en.json
  • web/default/src/i18n/locales/_reports/fr.untranslated.json
  • web/default/src/i18n/locales/_reports/ja.untranslated.json
  • web/classic/src/i18n/locales/zh-CN.json
  • web/default/src/i18n/locales/_reports/vi.untranslated.json
  • web/classic/src/i18n/locales/vi.json
✅ Files skipped from review due to trivial changes (1)
  • web/default/src/i18n/locales/ru.json

Comment thread web/default/src/features/redemption-codes/lib/redemption-form.ts Outdated
fishxcode added 3 commits May 25, 2026 00:57
…n-redemption-codes

# Conflicts:
#	web/default/src/features/redemption-codes/components/redemptions-mutate-drawer.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
web/default/src/i18n/locales/ru.json (1)

527-527: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Untranslated English values are still present in ru.json.

These entries are still English and will cause mixed-language UI in the RU locale. Please localize them to Russian (keeping placeholders unchanged).

Tags:

Also applies to: 707-707, 3173-3173, 3185-3185, 3187-3187, 3538-3538, 3709-3709, 3744-3744

🤖 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 `@web/default/src/i18n/locales/ru.json` at line 527, Several keys in the
Russian locale file still have English values (e.g., the "Benefit" key and the
other entries referenced at positions 707, 3173, 3185, 3187, 3538, 3709, 3744);
update each value to its proper Russian translation while preserving all JSON
syntax, punctuation and any interpolation placeholders (e.g., {0}, {{name}})
exactly as-is. Locate the keys (such as "Benefit") in
web/default/src/i18n/locales/ru.json, replace the English strings with Russian
equivalents, keep surrounding quotes and trailing commas intact, and run a quick
JSON lint to ensure no formatting errors.
🤖 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 `@web/default/src/i18n/locales/vi.json`:
- Line 527: The vi.json localization contains untranslated English strings for
the redemption/subscription UX (e.g., the "Benefit" key) causing mixed-language
UI; open web/default/src/i18n/locales/vi.json, find the English-valued keys
related to redemption/subscription (including the "Benefit" key and the other
recently changed entries) and replace their values with proper Vietnamese
translations that match tone and context of adjacent keys so the UI is fully
localized.

---

Duplicate comments:
In `@web/default/src/i18n/locales/ru.json`:
- Line 527: Several keys in the Russian locale file still have English values
(e.g., the "Benefit" key and the other entries referenced at positions 707,
3173, 3185, 3187, 3538, 3709, 3744); update each value to its proper Russian
translation while preserving all JSON syntax, punctuation and any interpolation
placeholders (e.g., {0}, {{name}}) exactly as-is. Locate the keys (such as
"Benefit") in web/default/src/i18n/locales/ru.json, replace the English strings
with Russian equivalents, keep surrounding quotes and trailing commas intact,
and run a quick JSON lint to ensure no formatting errors.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 529748c8-c490-4504-b9ab-56060b825d6e

📥 Commits

Reviewing files that changed from the base of the PR and between 38a548a and a9d2bc9.

📒 Files selected for processing (14)
  • controller/user.go
  • web/classic/src/components/settings/PaymentSetting.jsx
  • web/default/src/features/redemption-codes/components/redemptions-columns.tsx
  • web/default/src/features/redemption-codes/components/redemptions-mutate-drawer.tsx
  • web/default/src/features/redemption-codes/lib/redemption-form.ts
  • web/default/src/i18n/locales/_reports/_sync-report.json
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
  • web/default/src/i18n/static-keys.ts
  • web/default/src/routes/_authenticated/usage-logs/$section.tsx
💤 Files with no reviewable changes (4)
  • web/classic/src/components/settings/PaymentSetting.jsx
  • web/default/src/routes/_authenticated/usage-logs/$section.tsx
  • web/default/src/i18n/static-keys.ts
  • web/default/src/i18n/locales/zh.json
✅ Files skipped from review due to trivial changes (2)
  • web/default/src/i18n/locales/_reports/_sync-report.json
  • web/default/src/i18n/locales/fr.json

Comment thread web/default/src/i18n/locales/vi.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@web/default/src/i18n/locales/vi.json`:
- Line 707: The Vietnamese translation for the key "Choose whether this code
grants quota or a plan" is grammatically awkward; update the value in vi.json
for that exact key to a more natural phrasing such as "Chọn xem mã này cấp hạn
mức hay cấp gói đăng ký" so the UX copy reads smoothly; locate the string
exactly ("Choose whether this code grants quota or a plan") and replace its
value with the suggested Vietnamese sentence (or an equivalent natural variant).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d20aa913-65b7-4e7e-b258-764eee4d57ab

📥 Commits

Reviewing files that changed from the base of the PR and between a9d2bc9 and bca2a12.

📒 Files selected for processing (3)
  • web/default/src/i18n/locales/_reports/_sync-report.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
✅ Files skipped from review due to trivial changes (1)
  • web/default/src/i18n/locales/_reports/_sync-report.json

Comment thread web/default/src/i18n/locales/vi.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@web/default/src/i18n/locales/vi.json`:
- Line 707: Replace the sentence-style translation key "Choose whether this code
grants quota or a plan" in the vi.json locale with a hierarchical key such as
redemption.form.benefitType.description, move the translated string under that
new key, and update all consumers that reference the old sentence key (e.g., any
i18n.t(...) or <Trans> usages) to use "redemption.form.benefitType.description"
instead; ensure you remove the old flat key to avoid duplication and keep naming
consistent across other locales.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 68ea2b80-7223-425b-aa7c-30a8c577add4

📥 Commits

Reviewing files that changed from the base of the PR and between bca2a12 and b09407e.

📒 Files selected for processing (4)
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json

Comment thread web/default/src/i18n/locales/vi.json
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