# AI Usage CNY Cost Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Make AI usage fees calculated and displayed as Chinese yuan. **Architecture:** Keep the existing AI usage ledger API and database compatibility fields. Update `AiCostCalculator` to use CNY model rates while preserving cache-hit, cache-miss, and completion token calculation. Update the admin Vue page label and formatter to present CNY. **Tech Stack:** Java, JUnit 4, Spring/MyBatis, Vue 2, Element UI. --- ### File Structure - Modify: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiCostCalculatorTest.java` - Owns pricing expectations for Flash, Pro, default DeepSeek models, missing usage, and cent rounding. - Modify: `ruoyi-generator/src/test/java/com/ruoyi/generator/service/front/AiUsageRecorderTest.java` - Verifies recorded ledger/scope costs reflect the calculator's CNY amount. - Modify: `ruoyi-generator/src/main/java/com/ruoyi/generator/service/front/AiCostCalculator.java` - Owns token-to-money calculation and model rate selection. - Modify: `ruoyi-ui/src/views/generator/aiUsage/index.vue` - Owns AI usage fee labels and currency formatting. ### Task 1: Backend Pricing Tests - [ ] **Step 1: Write failing calculator expectations** Update expected values in `AiCostCalculatorTest`: ```java assertEquals(300, calculator.estimateCostCents("deepseek", "deepseek-chat", 1_000_000, 1_000_000)); assertEquals(new BigDecimal("2.90200000"), calculator.estimateCostUsd("deepseek", "deepseek-v4-flash", usage)); assertEquals(new BigDecimal("9.02500000"), calculator.estimateCostUsd("deepseek", "deepseek-v4-pro", usage)); assertEquals(new BigDecimal("3.00000000"), calculator.estimateCostUsd("deepseek", "deepseek-chat", usage)); ``` - [ ] **Step 2: Verify tests fail under old USD rates** Run: ```bash mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest test ``` Expected: failures show old USD amounts such as `0.40628000` where CNY amounts are expected. - [ ] **Step 3: Update recorder expectation** In `AiUsageRecorderTest`, replace `0.40628000` expectations with `2.90200000`. - [ ] **Step 4: Verify recorder test fails under old USD rates** Run: ```bash mvn -pl ruoyi-generator -Dtest=AiUsageRecorderTest test ``` Expected: failures show old USD amount `0.40628000` instead of `2.90000000`. ### Task 2: Backend CNY Implementation - [ ] **Step 1: Replace calculator rate constants** In `AiCostCalculator`, replace USD constants with CNY constants: ```java private static final BigDecimal FLASH_CACHE_HIT_CNY_PER_1M = new BigDecimal("0.02"); private static final BigDecimal FLASH_CACHE_MISS_CNY_PER_1M = new BigDecimal("1"); private static final BigDecimal FLASH_OUTPUT_CNY_PER_1M = new BigDecimal("2"); private static final BigDecimal PRO_CACHE_HIT_CNY_PER_1M = new BigDecimal("0.025"); private static final BigDecimal PRO_CACHE_MISS_CNY_PER_1M = new BigDecimal("3"); private static final BigDecimal PRO_OUTPUT_CNY_PER_1M = new BigDecimal("6"); ``` Keep public method names unchanged for compatibility. - [ ] **Step 2: Update internal variable names where local only** Rename local variables and `Rate` fields from `Usd` to neutral `Amount` or `Cny` inside `AiCostCalculator`. Do not rename public methods or domain fields in this task. - [ ] **Step 3: Verify backend tests pass** Run: ```bash mvn -pl ruoyi-generator -Dtest=AiCostCalculatorTest,AiUsageRecorderTest test ``` Expected: both test classes pass. ### Task 3: Admin UI CNY Display - [ ] **Step 1: Update label and formatter** In `ruoyi-ui/src/views/generator/aiUsage/index.vue`: ```vue