From dc4ec15350f88a842db17c08af405b2135511a60 Mon Sep 17 00:00:00 2001 From: haotool Date: Sat, 27 Jun 2026 18:58:48 +0800 Subject: [PATCH] =?UTF-8?q?fix(split-meow):=20=E8=88=8A=E6=94=AF=E5=87=BA?= =?UTF-8?q?=E7=BC=BA=20currency=20=E5=9B=BA=E5=AE=9A=E4=BB=A5=20TWD=20?= =?UTF-8?q?=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - resolveExpenseCurrency 與 resolveTripCurrency 舊資料改 fallback TWD - 補 currencies 與 HistoryTab smoke 測試對齊 PR 445 審查結論 測試:pnpm typecheck、pnpm test、pnpm lint 全通過 Co-authored-by: Cursor --- .../review-445-legacy-expense-currency-twd.md | 5 +++++ .../__tests__/HomeAndHistorySmoke.test.tsx | 12 +++++++++--- .../src/config/__tests__/currencies.test.ts | 10 ++++++++-- apps/split-meow/src/config/currencies.ts | 15 ++++++++++----- docs/dev/002_development_reward_penalty_log.md | 7 ++++++- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 .changeset/review-445-legacy-expense-currency-twd.md diff --git a/.changeset/review-445-legacy-expense-currency-twd.md b/.changeset/review-445-legacy-expense-currency-twd.md new file mode 100644 index 000000000..fc68c815f --- /dev/null +++ b/.changeset/review-445-legacy-expense-currency-twd.md @@ -0,0 +1,5 @@ +--- +'@app/split-meow': patch +--- + +修正 KRW 上線前、localStorage 舊支出缺 currency 欄位時,切換全域幣別後歷史金額仍誤顯示為韓元;舊帳目改固定以台幣解析。 diff --git a/apps/split-meow/src/components/__tests__/HomeAndHistorySmoke.test.tsx b/apps/split-meow/src/components/__tests__/HomeAndHistorySmoke.test.tsx index ba3ef7060..39981b305 100644 --- a/apps/split-meow/src/components/__tests__/HomeAndHistorySmoke.test.tsx +++ b/apps/split-meow/src/components/__tests__/HomeAndHistorySmoke.test.tsx @@ -195,13 +195,19 @@ describe('HistoryTab', () => { } }); - it('幣別為 KRW 時以 ₩ 顯示金額', () => { - useStore.setState({ expenses: [EXPENSE_1], currency: 'KRW' }); + it('有 currency 快照的 KRW 支出以 ₩ 顯示金額', () => { + useStore.setState({ expenses: [{ ...EXPENSE_1, currency: 'KRW' }], currency: 'KRW' }); renderWith(); - // 總金額與費用列表均應顯示 ₩ expect(document.body.textContent).toContain('₩'); }); + it('缺 currency 的舊支出在全域 KRW 時仍顯示 NT$', () => { + useStore.setState({ expenses: [EXPENSE_1], currency: 'KRW' }); + renderWith(); + expect(document.body.textContent).toContain('NT$'); + expect(document.body.textContent).not.toContain('₩'); + }); + it('多筆消費顯示 settlement 區塊', () => { useStore.setState({ expenses: [ diff --git a/apps/split-meow/src/config/__tests__/currencies.test.ts b/apps/split-meow/src/config/__tests__/currencies.test.ts index 4083543f5..8be9c62f0 100644 --- a/apps/split-meow/src/config/__tests__/currencies.test.ts +++ b/apps/split-meow/src/config/__tests__/currencies.test.ts @@ -112,9 +112,15 @@ describe('trip currency helpers', () => { ).toEqual({ a: 50, b: -50 }); }); - it('resolveExpenseCurrency 舊資料 fallback 行程幣別', () => { - expect(resolveExpenseCurrency({}, 'KRW')).toBe('KRW'); + it('resolveExpenseCurrency 舊資料 fallback TWD', () => { + expect(resolveExpenseCurrency({}, 'KRW')).toBe('TWD'); expect(resolveExpenseCurrency({ currency: 'TWD' }, 'KRW')).toBe('TWD'); + expect(resolveExpenseCurrency({ currency: 'KRW' }, 'TWD')).toBe('KRW'); + }); + + it('resolveTripCurrency 舊資料 fallback TWD,空行程 fallback 全域幣別', () => { + expect(resolveTripCurrency([{}], 'KRW')).toBe('TWD'); + expect(resolveTripCurrency([], 'KRW')).toBe('KRW'); }); it('wouldCreateMixedCurrencyTrip 僅在單幣行程將混幣時為 true', () => { diff --git a/apps/split-meow/src/config/currencies.ts b/apps/split-meow/src/config/currencies.ts index 0b25c079a..6e44ef869 100644 --- a/apps/split-meow/src/config/currencies.ts +++ b/apps/split-meow/src/config/currencies.ts @@ -1,5 +1,8 @@ export type CurrencyCode = 'TWD' | 'KRW'; +/** KRW 上線前 localStorage 舊帳目皆為 TWD;缺 currency 欄位時不可跟著全域幣別漂移。 */ +const LEGACY_DEFAULT_CURRENCY: CurrencyCode = 'TWD'; + export interface CurrencyInfo { code: CurrencyCode; symbol: string; @@ -37,20 +40,22 @@ export function getCurrencySymbol(currency: CurrencyCode): string { return CURRENCIES[currency].symbol; } -/** 單筆費用的顯示幣別;舊資料缺欄位時 fallback 至行程主導幣別。 */ +/** 單筆費用的顯示幣別;舊資料缺欄位時視為 TWD。 */ export function resolveExpenseCurrency( expense: { currency?: CurrencyCode }, - tripCurrency: CurrencyCode, + _tripCurrency: CurrencyCode, ): CurrencyCode { - return expense.currency ?? tripCurrency; + return expense.currency ?? LEGACY_DEFAULT_CURRENCY; } -/** 行程主導幣別:最舊一筆記帳的幣別快照,舊資料 fallback 全域幣別。 */ +/** 行程主導幣別:最舊一筆記帳的幣別快照;舊資料 fallback TWD,空行程 fallback 全域幣別。 */ export function resolveTripCurrency( expenses: { currency?: CurrencyCode }[], globalCurrency: CurrencyCode, ): CurrencyCode { - return expenses[expenses.length - 1]?.currency ?? globalCurrency; + const oldest = expenses[expenses.length - 1]; + if (!oldest) return globalCurrency; + return oldest.currency ?? LEGACY_DEFAULT_CURRENCY; } /** 行程是否混用多種幣別;混幣時不可加總或結算。 */ diff --git a/docs/dev/002_development_reward_penalty_log.md b/docs/dev/002_development_reward_penalty_log.md index a988c661d..1ea55a8b2 100644 --- a/docs/dev/002_development_reward_penalty_log.md +++ b/docs/dev/002_development_reward_penalty_log.md @@ -2,7 +2,7 @@ > 版本:outline-v2-ultra > 原則:每筆只保留日期、ID、原因、解法。 -> 本次分數變化:+1(reward 1、penalty 0、neutral 0)|累計總分:+71 +> 本次分數變化:+1(reward 1、penalty 0、neutral 0)|累計總分:+72 ## 新增模板(4 行) @@ -13,6 +13,11 @@ ## 條目(新→舊) +- 日期:2026-06-27 +- ID:reward-split-meow-legacy-expense-currency-twd +- 原因:PR 445 審查發現缺 currency 的舊支出 fallback 至全域幣別,KRW 上線前 TWD 帳目切換幣別後仍誤顯示 ₩ +- 解法:resolveExpenseCurrency 與 resolveTripCurrency 舊資料固定 fallback TWD,補 currencies 單元測試 + - 日期:2026-06-27 - ID:reward-pw-version-unify-1611 - 原因:monorepo 混用 PW 1.57/1.61,Node24.16+ 搭配 PW<1.60 導致 nihonname E2E 安裝卡死