修复报销详情时区并按 KISS 收敛页面(07-27-yang-jun-reimbursement-readiness)
这个提交包含在:
@@ -36,6 +36,62 @@ and verification contracts. Do not copy broad aesthetic guidance from
|
||||
with `AUTH_005`.
|
||||
- Run `cd client && npm run typecheck && npm run build` for frontend changes.
|
||||
|
||||
## Scenario: UTC Date-Time Display In The Company Time Zone
|
||||
|
||||
### 1. Scope / Trigger
|
||||
|
||||
- Trigger: a frontend page displays an API timestamp such as attachment upload,
|
||||
approval action, payment or audit time. API timestamps remain ISO 8601 UTC;
|
||||
the company-facing OA displays date-times in `Asia/Shanghai`.
|
||||
|
||||
### 2. Signatures
|
||||
|
||||
- Shared formatter: `formatDisplayDateTime(value: string | null | undefined): string`.
|
||||
- Date-only values continue to use `formatDisplayDate`; do not turn business
|
||||
dates such as reimbursement or invoice dates into timezone-shifted instants.
|
||||
|
||||
### 3. Contracts
|
||||
|
||||
- Date-time pages reuse `client/src/lib/displayFormat.ts`; do not add a
|
||||
page-local formatter for the same contract.
|
||||
- `Intl.DateTimeFormat` must set `timeZone: "Asia/Shanghai"` explicitly so the
|
||||
result does not depend on the browser, workstation or CI timezone.
|
||||
- Database storage and API ISO strings remain unchanged.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
- Missing value -> `-`.
|
||||
- Invalid date-time -> the shared display fallback; never throw during render.
|
||||
- Valid UTC value -> Shanghai calendar date and clock time.
|
||||
- Browser outside China -> the same Shanghai result as a browser in China.
|
||||
|
||||
### 5. Good/Base/Bad Cases
|
||||
|
||||
- Good: `2026-05-27T09:10:00.000Z` displays as `2026年5月27日 17:10`.
|
||||
- Base: a null attachment or approval time displays `-`.
|
||||
- Bad: `value.slice(0, 19).replace("T", " ")`, which presents UTC clock
|
||||
fields as if they were local time.
|
||||
|
||||
### 6. Tests Required
|
||||
|
||||
- Focused Playwright uses synthetic UTC data and a browser `timezoneId` outside
|
||||
Shanghai, then asserts the exact Shanghai attachment/approval time.
|
||||
- Run `cd client && npm run typecheck && npm run build`.
|
||||
|
||||
### 7. Wrong vs Correct
|
||||
|
||||
#### Wrong
|
||||
|
||||
```ts
|
||||
const displayed = value.slice(0, 19).replace("T", " ");
|
||||
```
|
||||
|
||||
#### Correct
|
||||
|
||||
```ts
|
||||
const displayed = formatDisplayDateTime(value);
|
||||
```
|
||||
|
||||
## Convention: Frontend Design Token Sources
|
||||
|
||||
**What**: Runtime visual tokens use the sources that are actually consumed by
|
||||
|
||||
在新工单中引用
屏蔽一个用户