1621 行
83 KiB
Markdown
1621 行
83 KiB
Markdown
# Frontend React / Vite / Design
|
|
|
|
## Source Of Truth
|
|
|
|
Frontend visual and interaction design uses the installed `frontend-design`
|
|
skill as the primary design authority. `docs/产品设计规则.md` remains a product
|
|
experience and business-boundary fact source, not a visual, brand or aesthetic
|
|
rulebook. For PC/mobile/WeCom pages, add Playwright or visual verification when
|
|
reasonable.
|
|
|
|
This spec keeps hyb-oa-specific React/Vite, shared-component, business-boundary
|
|
and verification contracts. Do not copy broad aesthetic guidance from
|
|
`frontend-design` into this file; use the skill directly for design judgment.
|
|
|
|
## Rules
|
|
|
|
- Use existing React/Vite/Tailwind patterns and shared components before adding
|
|
page-local UI systems.
|
|
- When `frontend-design` and older project visual rules conflict, follow
|
|
`frontend-design` for visual direction while preserving security, privacy,
|
|
Trellis, deployment and business data boundaries.
|
|
- Default product framing is a small-team Chinese workbench for domestic tech
|
|
startups with fewer than 10 people. User-facing copy should be natural
|
|
Chinese; avoid English product words such as `Portal`, `Dashboard` and
|
|
`Workflow` unless they are internal test fixtures or technical identifiers.
|
|
- PC pages should keep dense but orderly OA layouts: clear header, filters,
|
|
table/list, status, details and predictable actions.
|
|
- Mobile pages must reuse the existing unified mobile shell, card/list rows,
|
|
safe-area and sticky action patterns unless the current task intentionally
|
|
redesigns them with `frontend-design`.
|
|
- Do not add decorative landing-page styling to operational OA pages.
|
|
- Run `cd client && npm run typecheck && npm run build` for frontend changes.
|
|
|
|
## Convention: Mature Enterprise Page Baseline
|
|
|
|
**What**: From `05-30-unified-page-design-review`, hyb-oa PC/mobile pages use
|
|
Feishu approval/workbench mental models plus Ant Design / Ant Design Pro page
|
|
patterns as the mature enterprise baseline. This is a product/interaction
|
|
reference, not a copy of Feishu or Ant Design branding.
|
|
|
|
**Global contracts**:
|
|
|
|
- Interaction innovation is off by default for OA, approval, finance, contract,
|
|
asset and management surfaces. Prefer established Feishu / Ant Design style
|
|
patterns for page layout, action placement, button naming, tabs, filters,
|
|
detail panels, confirmations and more menus. Project-specific differences
|
|
should simplify or hide low-frequency work for small teams, not invent new
|
|
controls or unusual action flows.
|
|
- Page titles default to the route name only, such as `工作台`, `待我处理`, `报销`,
|
|
`合同台账`, `个人设置` and `通知中心`. Page subtitles are off by default and
|
|
appear only for exception, empty, permission-denied, Enterprise WeChat/OA
|
|
boundary, external-system boundary or irreversible-action explanations.
|
|
- Normal workflows should not be explained in default-visible copy. Do not add
|
|
subtitles, card descriptions, helper rows or notice bars that restate obvious
|
|
actions such as "待我处理是处理工作", "查看通知消息", "先核对再处理" or "去处理要做的事".
|
|
- Header primary actions are reserved for creation or a real page-level primary
|
|
action: `新建报销`, `新建采购`, `新增合同`, `新增资产`, `新建项目`. Workbench,
|
|
pending-task, notification and read-only record pages must not force a header
|
|
button for visual symmetry.
|
|
- Button labels use common enterprise verbs: `处理`, `去处理`, `查看详情`,
|
|
`查看全部`, `查看进度`, `继续编辑`, `新建`, `新增`, `提交`, `保存`, `取消`,
|
|
`撤回`, `作废`, `归档`, `更多`. Do not use slogan-like or invented labels
|
|
such as `处理最急的一件`.
|
|
- Sidebar entries are role-aware common work entries, not an all-permissions
|
|
module catalog. Direct entries may include `工作台`, `待我处理`, `报销`, `采购`,
|
|
`合同`, `项目`, `资产`, `付款`, `应付账款`, `票据`, `团队`, `请假记录` and `管理`
|
|
when the current role has real use. Low-frequency, frozen, staged or
|
|
troubleshooting routes stay in `更多` or the `管理` landing page.
|
|
- List pages use a right-side operation column or card tail. Default row actions
|
|
are `查看详情`, `处理`, `继续编辑` or `查看进度`; low-frequency or risky actions
|
|
such as export, batch, void, download, payment and sensitive attachment
|
|
handling move to `更多`, `台账工具` or the detail page.
|
|
- Business ledger pages use the same shape: page title and optional creation
|
|
action, visible common filters, table/card list and right-side operation
|
|
column. `台账工具` contains export, batch, statistics, templates, full-scope
|
|
views and advanced filters.
|
|
- Business ledger first screens are single-column list pages. Do not use a
|
|
default left-list/right-detail workspace for procurement, contracts, projects,
|
|
assets, payments, AP or invoices. Open details through a detail route, drawer
|
|
or explicit detail/edit area after the user chooses a row; the initial list
|
|
page must not auto-select the first item just to fill a second column.
|
|
- Ledger status summaries use tabs, segmented controls or compact chips with
|
|
counts. Do not place four or five large status cards above ordinary business
|
|
lists, and do not put explanatory sentences inside status cards.
|
|
- Ledger filters fit the first PC row around `search`, `status` and `scope`
|
|
when those capabilities exist. Supplier, legal entity, cost center, date
|
|
ranges, contract type, sensitivity, export and test-data toggles belong in
|
|
`筛选`, `台账工具` or a tab-specific advanced area; default-visible filters
|
|
should not occupy multiple rows.
|
|
- Business list columns show object identity, counterpart/person, amount/date,
|
|
state and operation. `下一步` is not a default list column or right-side help
|
|
panel. Use short state labels such as `待补材料` or `待你处理`; longer guidance
|
|
belongs in detail pages, exception blocks or confirmations.
|
|
- PC detail pages use an Ant Design Pro style detail workspace: top summary,
|
|
main facts/details/evidence, right-side state and action panel, and bottom
|
|
history. Do not build PC details as a free stack of equal-weight large cards.
|
|
- Workflow approval details use one action bar, not vertical action cards:
|
|
`通过` is the primary action, `退回` and `驳回` are secondary actions, and
|
|
`转审` defaults to `更多`. Actions that need a reason open a reason input and
|
|
confirmation after click. Confirmation must include the current object
|
|
summary and consequences.
|
|
- Mobile pages use top status/focus content, sectioned single-column details or
|
|
card lists, and one bottom safe-area primary action. Secondary, destructive,
|
|
approval, payment and transfer actions go into `更多` or a confirmation
|
|
panel; do not squeeze multiple risky actions into the bottom bar.
|
|
- Normal empty sections should disappear when they have no useful content. Empty
|
|
states only explain current filter/status absence and one real next step.
|
|
|
|
**Page map**:
|
|
|
|
| Surface | Template | First-screen content | Primary action rule |
|
|
| --- | --- | --- | --- |
|
|
| `工作台` | 工作台总览 | Compact counts, common entries, real reminders | No forced header action. Use `去处理`, `新建报销`, `查看全部` inside relevant sections; do not show helper sentences for ordinary items. |
|
|
| `待我处理` | 任务处理列表 | `待处理` / `已处理` tabs, count, minimal filters, task list | Row action is `处理`; `已处理记录` is a tab, not a separate header button. |
|
|
| `审批详情` | 详情工作区 | Summary, facts/evidence, right summary/action panel, history | One action bar: primary `通过`, secondary `退回`/`驳回`, `转审` in `更多`. |
|
|
| `报销` / `采购` / `合同` / `项目` / `资产` / `付款` / `应付账款` / `票据` | 业务台账列表 | One-row common filters plus table/card list | Header creation only when the route owns creation; risky tools in `台账工具` or detail; no default left-list/right-detail split. |
|
|
| Business details | 详情工作区 | Summary, facts, evidence, relations, history | Right-side state/action panel on PC; bottom primary action on mobile. |
|
|
| `管理` | 管理配置页 | Grouped landing: `人员组织`, `审批流程`, `基础资料`, `系统设置`, `审计排障` | Management subpages use search/filter, table and right operation column. |
|
|
| `个人设置` | 管理配置页 variant | `个人资料`, `账号安全`, `通知偏好`, `企业微信绑定` | No employee dossier, permission matrix or org maintenance in the default profile path. |
|
|
| `通知中心` | 业务台账列表 variant | Event inbox for state changes, reminders, failures and sync results | Notification click deep-links to business detail, workflow task or failure explanation; never duplicates `待我处理`. |
|
|
| `请假记录` / `考勤` | 业务台账列表 or record view | Enterprise WeChat-owned records, mirror status, exceptions and audit | Ordinary users do not see OA daily leave/punch approval creation; OA emergency entry only for authorized emergency/admin scope. |
|
|
| Mobile routes | Mobile expression of the same template | Top status/focus, card list or sectioned detail | One bottom safe-area primary action; secondary actions in `更多` or confirmation. |
|
|
|
|
**Implementation order for design refactors**:
|
|
|
|
1. A-class frequent pages: workbench, pending tasks, workflow task detail,
|
|
personal settings and notification center.
|
|
2. Business ledgers and details: reimbursement, procurement, contracts,
|
|
projects, assets, payments, AP and invoices.
|
|
3. Management and boundary pages: management landing/subpages, leave records,
|
|
attendance, Enterprise WeChat archive and mobile equivalents.
|
|
|
|
**Tests Required**:
|
|
|
|
- Documentation-only updates: `python3 ./.trellis/scripts/task.py validate
|
|
<task>`, `node scripts/qa/check-trellis-governance.mjs` and
|
|
`git diff --check`.
|
|
- Frontend implementation updates: `cd client && npm run typecheck`,
|
|
`cd client && npm run build`, plus focused Playwright or screenshot coverage
|
|
for changed A-class, detail, sidebar, action-bar or mobile surfaces.
|
|
|
|
## Frozen / Boundary Items
|
|
|
|
Frozen modules and Enterprise WeChat-owned HR/attendance entries must be labeled
|
|
or hidden according to the current Trellis task; do not silently re-enable them.
|
|
- Use the shared `WorkspaceNotice` pattern for trial boundaries, safety notes,
|
|
and post-trial capabilities instead of page-local warning blocks.
|
|
- Trial-facing PC lists must hide obvious TEST/SMOKE records by default when a
|
|
page-level toggle exists; the toggle may reveal them for troubleshooting.
|
|
|
|
## Scenario: Business Flow Tests And Frozen Modules
|
|
|
|
### 1. Scope / Trigger
|
|
|
|
- Trigger: Playwright or QA shell tests need to create workflow data while some
|
|
product modules are frozen for launch.
|
|
- Applies to `client/tests/e2e/**`, `scripts/qa/run-business-flow-gates.sh`,
|
|
and frontend route/permission assertions.
|
|
|
|
### 2. Signatures
|
|
|
|
- QA command: `BUSINESS_FLOW_GROUPS=<groups> bash scripts/qa/run-business-flow-gates.sh local`.
|
|
- Frozen-module API expectation: non-admin launch roles may receive `403` for
|
|
frozen module list/create/submit endpoints.
|
|
- Enabled workflow test data sources should use active entities such as leave,
|
|
reimbursement or procurement unless the task explicitly reopens the frozen
|
|
module.
|
|
|
|
### 3. Contracts
|
|
|
|
- Do not use a frozen module as fixture setup for an unrelated enabled feature.
|
|
Example: mobile approval offline sync should not create a travel request when
|
|
travel permissions are intentionally frozen.
|
|
- Permission direct-access tests must assert the frozen contract directly, such
|
|
as employee `GET /api/travel-requests?...` returning `403`.
|
|
- UI route smoke may still verify that a frozen page displays a boundary state
|
|
without entering a management or write-capable mode.
|
|
- Do not loosen roles or seed permissions merely to make old E2E data setup
|
|
pass.
|
|
|
|
### 4. Validation & Error Matrix
|
|
|
|
- Frozen role calls frozen module create/submit/list endpoint -> `403` or the
|
|
documented feature-gate status.
|
|
- Enabled workflow feature needs pending task data -> create data through an
|
|
enabled workflow entity.
|
|
- E2E fails with `PERM_001` while setting up unrelated feature data -> update
|
|
the test data source before changing app permissions.
|
|
|
|
### 5. Good/Base/Bad Cases
|
|
|
|
- Good: mobile approval offline test creates a submitted leave request, then
|
|
verifies pending-task deep link, offline queue, sync success and conflict.
|
|
- Base: travel-specific tests are skipped or admin-scoped while travel remains
|
|
frozen.
|
|
- Bad: grant employee `travel.create` only so a mobile approval test can build
|
|
a fixture.
|
|
|
|
### 6. Tests Required
|
|
|
|
- Focused E2E group that previously failed.
|
|
- Full affected business-flow group after the focused fix.
|
|
- `cd client && npm run typecheck && npm run build` when TypeScript test code
|
|
changes.
|
|
|
|
### 7. Wrong vs Correct
|
|
|
|
#### Wrong
|
|
|
|
```ts
|
|
await createSubmittedTravelRequestViaApi({ user: EMPLOYEE });
|
|
```
|
|
|
|
#### Correct
|
|
|
|
```ts
|
|
await createSubmittedLeaveViaApi({ user: EMPLOYEE });
|
|
```
|
|
|
|
## Convention: PC Operation List Density
|
|
|
|
**What**: PC list/workflow pages that combine status metrics, tabs/filters,
|
|
range controls, export and table/list content should reuse the shared operation
|
|
classes in `client/src/index.css`:
|
|
|
|
- `ops-status-strip` for compact status metrics.
|
|
- `ops-command-bar`, `ops-command-bar__row`, `ops-command-bar__tabs`,
|
|
`ops-command-bar__actions` and `ops-filter-label` for tabs, filters and
|
|
secondary actions.
|
|
- `ops-table-focus` for the primary desktop table container.
|
|
- `ops-inline-alert` for temporary mode hints such as batch operation notices.
|
|
- `PrimaryTable` already applies `ops-table-focus` by default; page code may
|
|
add responsive visibility classes such as `hidden md:block`, but should not
|
|
recreate a separate table frame.
|
|
- Finance/admin status summaries should prefer the shared `finance-status-strip`
|
|
and `finance-metric-card` classes unless the task introduces a new reusable
|
|
metric component.
|
|
|
|
**Why**: This keeps high-frequency PC pages dense and predictable without
|
|
recreating page-local Tailwind command bars. It also lets `frontend-design`
|
|
change the visual treatment once while preserving component contracts.
|
|
|
|
**Example**:
|
|
|
|
```tsx
|
|
<StatStrip columns={4} className="ops-status-strip">
|
|
<MetricCard title="待办总数" value={summary.pendingTotal} />
|
|
</StatStrip>
|
|
|
|
<FilterBar className="ops-command-bar !p-3 md:!p-3.5">
|
|
<div className="ops-command-bar__row">
|
|
<Tabs value={status}>
|
|
<TabsList className="ops-command-bar__tabs !h-auto !justify-start !bg-slate-50">
|
|
<TabsTrigger value="pending">待处理</TabsTrigger>
|
|
</TabsList>
|
|
</Tabs>
|
|
<div className="ops-command-bar__actions">...</div>
|
|
</div>
|
|
</FilterBar>
|
|
|
|
<PrimaryTable className="hidden md:block">...</PrimaryTable>
|
|
```
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright screenshot coverage when changing login, Portal, primary
|
|
PC list pages or command-bar/table styling.
|
|
|
|
## Convention: Page Template Taxonomy
|
|
|
|
**What**: hyb-oa frontend pages use six layout templates. New or redesigned
|
|
pages must pick one primary template before implementation:
|
|
|
|
- `工作台总览`: Portal and mobile home. Compact summary, today's actionable
|
|
items, conditional progress/blocker/reminder sections.
|
|
- `任务处理列表`: workflow task queues. Pending summary, task list, processed
|
|
records and advanced filters.
|
|
- `业务台账列表`: reimbursement, contracts, projects, payments, AP and invoices.
|
|
Page-header primary action, command bar, list/table body and folded ledger
|
|
tools.
|
|
- `主从工作台`: only for true task execution after an explicit user selection,
|
|
such as an inventory-check task that has been opened. It is not the default
|
|
first screen for procurement, assets, payments, AP or invoices.
|
|
- `详情工作区`: reimbursement detail, workflow task detail, project detail and
|
|
future contract detail. Overview, facts/evidence, right-side summary/command
|
|
panel and history.
|
|
- `管理配置页`: people, organization, master data, approval rules, workflow
|
|
definitions, feature flags and audit logs. Grouped settings, searchable
|
|
tables and confirmed destructive/configuration actions.
|
|
|
|
**Contracts**:
|
|
|
|
- A page has one primary template. Local sections may reuse shared components,
|
|
but the page must not mix ledger, configuration, detail and dashboard patterns
|
|
without an explicit Trellis task.
|
|
- Mobile is the responsive expression of these templates: top status/focus,
|
|
card list or sectioned detail, bottom primary action. Do not create a PC shell
|
|
inside mobile routes.
|
|
- B-class business pages should usually choose `业务台账列表`. Procurement,
|
|
assets, payments, AP and invoices must start as a list and open details only
|
|
through an explicit row action, `?id=` detail mode, drawer or detail route.
|
|
Use `主从工作台` only for explicit execution tasks, and never auto-select the
|
|
first item merely to fill a detail column.
|
|
- A-class task pages must not drift into configuration surfaces. C-class
|
|
configuration pages must not appear as ordinary employee task pages.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks for changed A-class, mobile or shared
|
|
template surfaces.
|
|
|
|
## Convention: Global Shell And Page Header Baseline
|
|
|
|
**What**: PC page redesigns should preserve the shared Wave0-2 shell and
|
|
header baseline instead of recreating page-local wrappers:
|
|
|
|
- `AppShellLayout` owns the PC shell background and content offset through
|
|
`app-shell` and `app-shell-main`.
|
|
- `Sidebar` and `NavLinks` own role-aware task navigation. The mental model is
|
|
a task-first primary list plus collapsed `更多`; enabled OA-owned business
|
|
ledgers such as contracts, procurement, assets and projects should not be
|
|
hidden in `更多` by default when the current role has access. Management
|
|
configuration is represented by one `管理` entry instead of many sidebar rows.
|
|
- `Topbar` is a compact command surface: page title, group badge, user context,
|
|
global search and notifications. Do not expand it back into a large hero.
|
|
- `PageHeader` and `WorkspaceHeader` should use `page-header-shell`,
|
|
`page-header-shell__eyebrow`, `page-header-shell__title`,
|
|
`page-header-shell__subtitle` and `page-header-shell__actions`.
|
|
- Auth guidance and step hints may use `ux-command-note`, `ux-step-list` and
|
|
`ux-step-item` when they explain the next action without adding page-local
|
|
warning cards.
|
|
|
|
**Why**: The shell/header baseline gives Wave3-5 pages a stable visual entry
|
|
point and prevents each route from inventing a different title/action layout.
|
|
|
|
**Navigation Rules**:
|
|
|
|
- Sidebar entries should be role-aware and task-first for domestic tech startups
|
|
under 10 people; do not expose all permission-allowed modules as a default
|
|
module catalog.
|
|
- Do show enabled, permission-allowed day-to-day business ledgers directly in
|
|
the primary sidebar, including `合同`, `采购`, `资产` and `项目` when relevant.
|
|
`更多` is for low-frequency, frozen, staged or occasional entries, not a
|
|
place to bury common work.
|
|
- Approvers see `待我处理`; ordinary employees should not see `待办` or
|
|
`审批待办` in the sidebar by default.
|
|
- PC leave navigation uses `请假记录` unless the current task explicitly opens OA
|
|
emergency leave submission.
|
|
- HR/attendance pages must encode WeCom ownership in the UI surface: employee
|
|
leave and mobile leave are record-first/read-only, and OA emergency forms are
|
|
hidden unless `leave.manage`; attendance correction forms are hidden unless
|
|
`attendance.manage`. Labels must say `OA 应急` / `提交应急审批` /
|
|
`提交应急修正` instead of generic `提交`.
|
|
- When a page repeats the same title in the page header and a content section,
|
|
Playwright assertions should target the page header (`h1` or the header test
|
|
id) rather than `getByRole("heading", { name })`, which becomes ambiguous.
|
|
- `个人设置` stays in the topbar account menu. Notifications stay in the topbar
|
|
bell and notification center.
|
|
- Finance labels should use work names such as `付款`, `应付账款` and `票据`;
|
|
internal platform words like `AP 运营`, `ERP 集成` and `功能开关` should be
|
|
hidden behind management wording or renamed for users.
|
|
- `更多` is a lightweight collapsed row for low-frequency, frozen, staged or
|
|
occasional entries; do not add a sidebar explanation card, subtitle or
|
|
onboarding copy around it.
|
|
- Playwright navigation helpers should use exact names or anchored regex for
|
|
short sidebar labels such as `管理`, otherwise fuzzy role-name matching can
|
|
click longer labels such as `预算管理`.
|
|
|
|
**Example**:
|
|
|
|
```tsx
|
|
<WorkspaceHeader
|
|
eyebrow="审批"
|
|
title="审批中心"
|
|
subtitle="先看待处理,再进入详情核对依据。"
|
|
/>
|
|
```
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage when changing `AppShellLayout`, `Sidebar`,
|
|
`Topbar`, `NavLinks`, `PageHeader`, `WorkspaceHeader`, login, Portal or other
|
|
A-class pages.
|
|
|
|
## Convention: Action Placement Baseline
|
|
|
|
**What**: Page actions, filters, ledger tools and destructive commands use one
|
|
system-wide coordinate model. New and redesigned pages should not invent
|
|
page-local action placement.
|
|
|
|
**Contracts**:
|
|
|
|
- PC page primary action lives in the page header action area
|
|
(`WorkspaceHeader` / `PageHeader` actions). Keep one primary action per page
|
|
surface and at most two visible secondary actions.
|
|
- List filters live in the first command bar below the page header. Search,
|
|
status, scope and other common filters stay on the left; ledger tools such as
|
|
export, batch, statistics, templates and advanced filters stay on the right or
|
|
inside `台账工具` / `更多`.
|
|
- Row-level actions live at the right edge of a table row or at the tail of a
|
|
card. Prefer `查看详情`, `查看处理` and `继续编辑` over broad verbs that hide the
|
|
result.
|
|
- Detail pages keep facts and evidence in the main content. High-risk actions
|
|
such as approve, reject, return, pay, publish, delete and configuration
|
|
switching live in the right command panel or a clearly separated
|
|
`detail-action-stack`, with confirmation that includes the current object
|
|
summary.
|
|
- Form save/submit actions live at the form bottom on PC. Long forms may add a
|
|
right-side summary command panel, but the same action should not be repeated in
|
|
unrelated header, row and footer locations.
|
|
- Mobile pages use top status/focus content plus a bottom safe-area action
|
|
surface for the primary action. Do not copy PC command bars or wide tables
|
|
into mobile routes.
|
|
- Batch actions only appear after selection, as a contextual command bar or
|
|
bottom sticky bar.
|
|
- Destructive, financial, approval and configuration-changing actions must be
|
|
visually and structurally separated from normal navigation/edit actions.
|
|
|
|
**Why**: hyb-oa targets small teams where one person may switch roles many times
|
|
per day. Stable action coordinates reduce relearning and help a solo developer
|
|
avoid page-by-page exceptions.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks when changing shared page headers,
|
|
command bars, task lists, detail action panels or mobile bottom actions.
|
|
|
|
## Convention: State-Driven Actions
|
|
|
|
**What**: Business actions are derived from explicit object state and current
|
|
actor context. Do not scatter page-local button conditions across route
|
|
components.
|
|
|
|
**Contracts**:
|
|
|
|
- Before redesigning a page with mutable business records, define or reference a
|
|
state matrix. The matrix must cover object state, actor role, primary action,
|
|
secondary actions, forbidden actions, reason text, risk level and confirmation
|
|
requirement.
|
|
- Common lifecycle states include draft, submitted, in approval, returned or
|
|
rejected, approved, pending execution or payment, completed or paid,
|
|
cancelled, abnormal and archived. Use the business module's real names when
|
|
they differ.
|
|
- Draft states prioritize edit, submit and delete draft. Do not show approval or
|
|
payment actions there.
|
|
- In-approval states prioritize progress, withdraw and supplement-material
|
|
actions. Approve, reject and return actions belong to the current user's
|
|
workflow task detail, not broad ledger rows.
|
|
- Returned or rejected states prioritize correction and resubmission.
|
|
- Approved-but-not-paid states route payment work to finance or cashier views;
|
|
ordinary employee views should explain the next step instead of exposing
|
|
executable payment controls.
|
|
- Payment actions such as mark paid, register payment, cancel payment, batch
|
|
payment and execute payment live only in payment, finance-processing,
|
|
payment-batch detail or an explicitly current finance task panel.
|
|
Reimbursement, procurement, contract and project ledgers/details show payment
|
|
status, receipt status, `查看付款`, `补回单` or a payment-record link instead
|
|
of executable payment controls.
|
|
- Paid, completed, archived and cancelled states are read-mostly. Print, export,
|
|
attachment download and history belong in `更多` or audit paths when allowed.
|
|
- Abnormal states must explain source, impact and next step. A red status label
|
|
alone is insufficient.
|
|
- Destructive, financial, approval and configuration-changing actions require
|
|
confirmation that shows the current object summary and writes audit evidence
|
|
when the backend supports it.
|
|
- The frontend may hide disabled actions or show reason text, but the backend
|
|
remains the source of truth for permission and state validation.
|
|
- Use destructive lifecycle verbs consistently: `删除` only for drafts,
|
|
non-effective temporary records or wrong materials that have not entered a
|
|
business process; `撤回` for initiator withdrawal during allowed workflow
|
|
states; `取消` when the business will not continue; `作废` when a numbered,
|
|
signed, paid, published or effective object becomes invalid; `归档` when a
|
|
completed object is locked for retention. Submitted business records should
|
|
not be physically deleted from ordinary UI paths.
|
|
|
|
**Why**: State-driven actions prevent pages from showing buttons that the user
|
|
cannot complete and keep reimbursement, procurement, contracts, assets and
|
|
payments consistent as the system grows.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage for changed state/action behavior, especially
|
|
draft, rejected/returned, in-approval, approved, paid/completed, cancelled and
|
|
abnormal states.
|
|
|
|
## Convention: Role-Scoped Data Surfaces
|
|
|
|
**What**: The backend is the source of truth for permissions and data scope. The
|
|
frontend shapes the authorized capabilities into the current task role instead
|
|
of exposing every allowed tool at once.
|
|
|
|
**Contracts**:
|
|
|
|
- Ordinary employee views default to `我的`, `与我相关`, `我发起` and
|
|
`需要我补充`. Do not show company-wide ledgers, batch tools, export, audit,
|
|
configuration, internal IDs or other people's sensitive attachments by
|
|
default.
|
|
- Initiator views emphasize current status, next step, supplement-material
|
|
needs, approval/payment progress and whether edit or withdraw is allowed.
|
|
- Approver and processor views emphasize `待我处理` and the current node task.
|
|
Show approve, reject, return or transfer actions only when the server-backed
|
|
task assignment says the current user can act.
|
|
- Approval actions such as approve, reject, return and transfer execute only in
|
|
`待我处理`, workflow task detail, mobile approval detail or an explicitly
|
|
current task-processing panel. Business ledger rows and ordinary business
|
|
details use `查看处理`, `查看进度`, `补材料` or a link into the workflow task;
|
|
they must not duplicate approval action buttons.
|
|
- Finance and cashier views may expose authorized reimbursement, payment,
|
|
invoice, AP, receipt and exception operations. Full-scope, export, batch,
|
|
delegated creation and statistics tools belong in `台账工具`, `更多` or
|
|
role-only panels.
|
|
- Owner and project-lead views emphasize team/project scope, blockers, risks and
|
|
approvals. They should not drift into system configuration unless the route is
|
|
a management route.
|
|
- Admin views live under `管理` and cover people, organization, workflow,
|
|
feature flags, integrations, audit and troubleshooting. Do not mix these
|
|
controls into ordinary employee paths.
|
|
- Read-only or audit views can show authorized evidence but must not show
|
|
mutable edit, approval, payment, publish or disable actions.
|
|
- Do not add a global role or identity switcher. Multi-role users do not choose
|
|
`员工` / `财务` / `管理员` before using the system. Routes infer the most
|
|
relevant task view by default.
|
|
- Multi-role users may switch scope inside a specific authorized ledger, but the
|
|
default scope follows the page purpose: reimbursement starts with mine,
|
|
workflow tasks start with my tasks, ledgers start with relevant or recent
|
|
records, management starts with management scope. Use route-local scope
|
|
controls such as `我相关` / `我负责` / `财务处理` / `全范围`.
|
|
- Use explicit controls such as `我的 / 团队 / 全范围` only when the server grants
|
|
those scopes. Hiding controls in the frontend is not a security boundary.
|
|
- Unauthorized actions should usually be hidden. When explanation is useful,
|
|
show short natural Chinese reasons such as `当前节点不是你处理`, `已支付单据不可编辑`
|
|
or `仅财务可导出`.
|
|
|
|
**Why**: hyb-oa users often wear several hats. Role-scoped surfaces keep one
|
|
person's broad authority from turning every page into an admin console.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Role-focused Playwright coverage when changing visibility for employee,
|
|
approver, finance/owner or admin paths.
|
|
|
|
## Convention: User-Facing Identifiers And Copy Semantics
|
|
|
|
**What**: Ordinary product surfaces use business identifiers and natural
|
|
Chinese. Internal identifiers are auxiliary evidence for audit and
|
|
troubleshooting, not primary user-facing content.
|
|
|
|
**Contracts**:
|
|
|
|
- Use business identifiers, names or summaries as primary labels: reimbursement
|
|
number, purchase request number, contract number, asset number, payment batch
|
|
number and project name.
|
|
- Do not show UUID, taskId, entityId, permission code, role code, internal state
|
|
code, raw payload, full local path, API path, database field name, OCR
|
|
provider, debug trace, Secret or token on ordinary employee, approver,
|
|
finance or mobile paths.
|
|
- Audit logs, admin troubleshooting, integration failure details, printed
|
|
evidence and export handoff files may show necessary internal IDs when
|
|
authorized. Place them in low-priority areas such as `技术信息`, `审计信息` or
|
|
`排障信息`; never use them as the page title, card title, button label or
|
|
first ordinary list column.
|
|
- Show one primary identifier for the same object in one surface. Avoid placing
|
|
business number, UUID, taskId and entityId together unless the route is an
|
|
audit/troubleshooting route.
|
|
- Translate technical enum values and platform words into natural Chinese:
|
|
`PENDING_APPROVAL` becomes `审批中`; `REJECTED` becomes `已驳回` or
|
|
`被退回待补正`; `AP Operations` becomes `应付账款`; `Feature Flag` becomes
|
|
management wording.
|
|
- Time copy should answer the business question. Prefer `已等待多久`, `接收于`,
|
|
`提交于`, `支付于` and `归档于` over generic `更新时间` when the user needs to
|
|
decide what to do.
|
|
- Errors and abnormal states must explain source, impact and next step in
|
|
natural Chinese. Do not surface only HTTP codes, backend enum names or red
|
|
badges.
|
|
- Notifications and mobile cards use the shortest useful business identifier or
|
|
summary. Do not pack long technical IDs into small surfaces.
|
|
|
|
**Why**: Internal implementation language makes the product feel complex and
|
|
unfamiliar. Business identifiers and natural Chinese keep small-team workflows
|
|
legible.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- UI tests or screenshot review for changed list/detail/notification/mobile
|
|
surfaces to confirm internal IDs and technical enum names are not visible.
|
|
|
|
## Convention: Ledger List Defaults
|
|
|
|
**What**: Business list and ledger pages default to a light, task-oriented list.
|
|
Advanced ledger capabilities remain available but must not dominate the first
|
|
screen.
|
|
|
|
**Contracts**:
|
|
|
|
- Keep 3 to 5 high-frequency filters visible by default. Prioritize search,
|
|
status, scope and date/time; add business-specific filters such as project,
|
|
person or type only when they are genuinely frequent.
|
|
- The default view must match the route's main job: `我的报销`, `待我处理`,
|
|
`合同台账`, `资产台账` and similar task nouns. Do not default ordinary users
|
|
into company-wide management views.
|
|
- Rows and cards must answer what the object is, current state, why it relates
|
|
to the current user and the next action.
|
|
- Place common filters on the left side of the command bar below the page
|
|
header. Put export, batch, statistics, templates, full-scope, advanced
|
|
filters, delegated creation and low-frequency module links in `台账工具`,
|
|
`更多` or role-only panels.
|
|
- Batch actions appear only after selection, as a contextual command bar or
|
|
bottom sticky bar. High-risk batch actions such as approve, pay, delete or
|
|
publish require summary confirmation and result details.
|
|
- Export is not a primary page action. Explain export scope and sensitive
|
|
content when relevant; finance, contract, asset and invoice exports must stay
|
|
permissioned and auditable.
|
|
- PC ledgers may use pagination, sorting and density controls. Default columns
|
|
should be decision-supporting fields only; low-frequency fields belong in
|
|
details, column configuration or advanced filters.
|
|
- Empty states are status-specific. `没有草稿`, `没有被驳回`, `没有待处理` and
|
|
`没有异常` should not all share one generic explanatory panel.
|
|
- Mobile routes do not copy PC ledger tools. Use search, status filtering, card
|
|
lists and one primary action; leave complex analysis, export and broad-scope
|
|
management to PC.
|
|
- Contract, procurement, project and finance ledgers use a list-to-detail
|
|
boundary. The list is for discovery, filtering, status reading and navigation.
|
|
High-risk or sensitive actions such as contract download, archive, payment,
|
|
export, batch processing, void/cancel and sensitive attachment viewing belong
|
|
in detail workspaces, detail command panels or `台账工具`, with permission,
|
|
audit and confirmation.
|
|
- Default ledger scope follows the current task role: ordinary employees see
|
|
`我发起` / `我相关`, owners and project leads see `我负责` / `项目相关`, finance
|
|
sees `待复核` / `待付款` / `异常`, and admins may enter or switch to `全范围`.
|
|
Full scope, export and batch commands stay in `台账工具` or role-only panels,
|
|
not ordinary first screens.
|
|
- Contract ledgers in V1 are registration, archive, due/renewal reminder and
|
|
relation surfaces for project, procurement and payment context. Do not design
|
|
`/contracts-registry` as e-signature, legal-review, clause-library,
|
|
version-collaboration or full CLM software. If contract approval is needed,
|
|
link to the OA approval center or a separate future task instead of adding an
|
|
approval workspace inside the contract ledger.
|
|
- Procurement ledgers in V1 are request, approval, attachment, light
|
|
acceptance/archive and relation surfaces for project, contract and payment/AP
|
|
context. Do not design `/purchase-requests` as purchase-order lifecycle,
|
|
inventory, three-way matching, supplier-lifecycle, tendering or ERP software.
|
|
Approved procurement means the request was approved; it does not imply paid,
|
|
received into inventory or converted into a fixed asset.
|
|
- Project pages in V1 are light project ledgers for status, owner/member,
|
|
milestone/task, risk, delivery-record and related reimbursement, procurement,
|
|
contract and payment context. Do not design `/projects` as full project
|
|
management software with Gantt charts, complex dependencies, timesheets,
|
|
resource scheduling, OKR, portfolio management or large collaboration suites.
|
|
Project pages summarize and route; source records stay in their business
|
|
modules.
|
|
- Finance ledgers in V1 are payment-preparation, payment-batch, receipt-audit,
|
|
AP-status, invoice/OCR-status and agency-accounting handover summaries. Do
|
|
not design payment, AP or invoice pages as online banking, bank-statement
|
|
ingestion, ERP/general-ledger, voucher-generation, auto-reconciliation, tax
|
|
filing or full accounting software. Real payment stays in offline banking or
|
|
existing finance/accounting workflows; OA records status, evidence and
|
|
handover summaries.
|
|
- Payment, AP and invoice pages default to task/exception visibility: `付款`
|
|
shows review, payment-marking, receipt and exception attention before batch
|
|
creation; `应付账款` shows pending payment, exceptions, risks and differences
|
|
before export; `票据` shows OCR status, failed invoices and bindable invoices
|
|
before broad-scope handover tools. Batch creation, export, full-scope views
|
|
and agency-accounting handover controls live in `台账工具` or selected-context
|
|
panels, never as the first-screen primary action.
|
|
- Payment actions require the finance/payment context: amount, payee or target
|
|
object, source records, offline payment explanation, evidence completeness,
|
|
receipt requirement and correction boundary. Do not place `标记已付款`,
|
|
`取消付款`, `批量付款` or `执行付款` directly in reimbursement, procurement,
|
|
contract or project ledgers/details.
|
|
- Cross-module relation sections are summary-and-route surfaces. Project,
|
|
procurement, contract, reimbursement, asset and payment pages may show related
|
|
business number/name, status, amount or quantity, owner, evidence completeness
|
|
and next-step summary, then link to the owning detail/task/finance page. Do not
|
|
duplicate the owning module's approval actions, payment actions, invoice/OCR
|
|
processing, contract-body download, sensitive attachment actions, state machine
|
|
or batch tools inside another module's relation card.
|
|
|
|
**Why**: The product's main complexity complaint is too many visible operations.
|
|
Light default ledgers keep daily work simple while preserving advanced finance
|
|
and management workflows.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks when changing list filters, command
|
|
bars, `台账工具`, batch selection behavior, empty states or mobile list cards.
|
|
|
|
## Convention: Asset Registry Pages
|
|
|
|
**What**: Asset pages render `FA` fixed assets as a lightweight responsibility
|
|
ledger inside the unified asset registry, not as a full accounting fixed-asset
|
|
subsystem.
|
|
|
|
**Contracts**:
|
|
|
|
- The default `/assets` view answers where the asset is, who uses it, who is
|
|
responsible for it, what state it is in and whether it needs inventory or
|
|
handover. Do not lead with depreciation, accounting subjects or ERP sync.
|
|
- Register physical items that must be returned, transferred, inventoried or
|
|
protected, such as computers, monitors, disks, equipment and security media.
|
|
Do not create `FA` cards for ordinary consumables.
|
|
- Every `FA` card needs an asset number. Physical assets that can carry labels
|
|
should expose QR-label status for scan, inventory, assignment and return
|
|
workflows. Assets that cannot be labeled must still expose serial number,
|
|
custodian and location as the lookup fallback.
|
|
- Inventory cadence is lightweight: quarterly routine checks by default, event
|
|
checks for departure, transfer, repair and retirement, and monthly custodian
|
|
plus location confirmation for high-risk physical assets such as backup disks,
|
|
security media and critical equipment.
|
|
- Assignment, return and transfer are daily flow actions that admins may record
|
|
with audit evidence. Disposal actions such as retirement, loss, sale and gift
|
|
require owner confirmation, a reason and consequence summary. If compensation,
|
|
money or responsibility is disputed, the asset UI records pending/confirmed
|
|
outcomes only and must not complete the dispute in one click.
|
|
- Keep acquisition source, business number, owner/custodian, location, status,
|
|
assignment, return, transfer, repair, retirement, inventory result and
|
|
handover evidence visible in the business flow.
|
|
- Procurement or reimbursement records may expose an asset-candidate signal, but
|
|
they must not create an `FA` asset card automatically after approval,
|
|
submission or payment. The asset registry UI may guide admins from candidates
|
|
to `新建资产卡片`, but the card is created only after manual verification of
|
|
delivery, quantity, owner/custodian, consumable status, returns and gifts.
|
|
- Move depreciation, residual value, accounting subject and monthly
|
|
depreciation voucher concepts out of the OA primary UI unless a later Trellis
|
|
task explicitly scopes accounting-ledger work.
|
|
- Keep classification maintenance, ERP sync, raw metadata and advanced filters
|
|
behind management, collapsed or advanced surfaces so they do not dominate the
|
|
asset list/detail first screen.
|
|
- Mobile asset lookup should prefer QR scan and fall back to asset number or
|
|
serial number input. Do not require heavy photo inventory unless a later task
|
|
explicitly scopes it.
|
|
- Asset list/detail UI may show last inventory, next inventory and overdue
|
|
hints. Do not turn cadence into a complex scheduling/configuration console in
|
|
the default asset registry view.
|
|
- Disposal commands must be visually separated from assignment/return/transfer
|
|
commands and use confirmation that shows asset number, name, owner, current
|
|
custodian, location, reason and effect on asset status.
|
|
- Electronic assets (`EA-DOC`, `EA-SYS`, `EA-REPO`, `EA-BKP`) are metadata and
|
|
responsibility indexes. Show owner, custodian/admin, permission-recovery
|
|
requirement, backup or restore-verification date, sensitivity level and
|
|
archive-location summary. Do not display or store source packages, secrets,
|
|
tokens, full configs, real full paths or backup contents.
|
|
- `EA-DOC` list/detail views show document name, type, hash or verification
|
|
summary, sensitivity level, owner, related project/contract/payment and
|
|
archive-location summary. Contract text, bank statements, certificate
|
|
originals, customer materials, sensitive quotes, payroll/social-security data
|
|
and personal identity materials must not appear as ordinary asset-page
|
|
content; route business originals through their module attachment permissions
|
|
or offline controlled archive.
|
|
|
|
**Tests Required**:
|
|
|
|
- Asset page screenshots or E2E assertions should verify the first screen is
|
|
asset-list/detail/task oriented, with classification and integration tooling
|
|
demoted.
|
|
- Mobile asset scan tests should cover lookup, summary and one allowed action;
|
|
mobile must not expose classification maintenance or full metadata editing.
|
|
Include QR scan or manual asset-number/serial-number fallback when this
|
|
surface changes.
|
|
- Electronic asset UI changes should assert that sensitive source/config/backup
|
|
content and full paths are not visible in ordinary list/detail/mobile views.
|
|
- `EA-DOC` UI changes should assert that high-sensitive originals are not
|
|
rendered in ordinary asset list/detail/mobile views.
|
|
|
|
## Convention: Forms, Drafts And Validation
|
|
|
|
**What**: Long business forms support interruption and recovery. Save draft and
|
|
submit are distinct actions with different consequences.
|
|
|
|
**Contracts**:
|
|
|
|
- Long forms should support drafts by default when the business object requires
|
|
multiple fields, line items or materials, including reimbursements,
|
|
procurement, contract drafting, asset intake and payment supplement flows.
|
|
- `保存草稿` stores progress only. It must not trigger approval, payment,
|
|
publishing or external synchronization. `提交` enters the business workflow.
|
|
- Draft save may allow incomplete data, but it must preserve entered fields,
|
|
line items, attachment references and the recoverable object state.
|
|
- Before submit, run business validation and show a summary confirmation with
|
|
the object summary, amount or quantity, important contract/asset/payment
|
|
facts, attachment or invoice completeness, and next node or consequence.
|
|
- Material upload is type-first. Let the user choose or enter the material type
|
|
before upload, then apply type-specific copy, validation, permissions, audit
|
|
and display placement. Do not use one generic attachment uploader for PDF
|
|
invoices, ordinary attachments, contract files, payment receipts, acceptance
|
|
materials, asset materials and electronic-document indexes.
|
|
- Upload labels must describe the result, such as `上传 PDF 发票`,
|
|
`补充付款回单`, `上传合同文件`, `补充验收材料` or `登记资产材料`.
|
|
- Validation errors must point to the field, line item, invoice, attachment,
|
|
contract material or asset section that needs work. A top-level `提交失败`
|
|
message alone is insufficient.
|
|
- Separate blocking errors from warnings. Blocking errors prevent submit;
|
|
warnings may allow users to confirm and continue when the business rule
|
|
permits it.
|
|
- Server-side validation failures must preserve user input and show repair
|
|
guidance in natural Chinese.
|
|
- Warn before navigation when the form has unsaved changes, including leaving
|
|
the route, closing a modal, switching record or returning to the list.
|
|
- Autosave can be used as an enhancement, but the visible state must still make
|
|
clear whether the object is draft, submitted or failed to save.
|
|
- Mobile forms keep only necessary fields, material upload, status explanation
|
|
and a bottom safe-area primary action. Do not move admin configuration,
|
|
complex configuration matrices, bulk import or workflow design into mobile
|
|
forms.
|
|
- Mobile validation messages should appear near the field or material card, and
|
|
bottom actions must not cover the final input.
|
|
|
|
**Why**: Small-team users often switch tasks mid-form. Drafts and precise
|
|
validation prevent repeated re-entry and reduce support/debugging cost.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage for draft save, submit validation, unsaved-change
|
|
protection and server-validation failure paths when changing form behavior.
|
|
|
|
## Convention: Detail Evidence Layout
|
|
|
|
**What**: Detail pages use one evidence-first structure so users can understand
|
|
state, facts and consequences before acting.
|
|
|
|
**Contracts**:
|
|
|
|
- Use this order for reimbursement, workflow task, procurement, contract, asset,
|
|
project and payment details: status/next step, business summary, evidence
|
|
materials, risk or validation signals, approval/processing history, actions.
|
|
- The top overview shows business number or name, current state, critical amount
|
|
or object facts, current handler or next node, and a clear return path.
|
|
- The first content block is `当前状态与下一步`: explain where the object is,
|
|
who needs to act, what happens next and whether there are blockers or
|
|
warnings.
|
|
- The business summary block shows the fields needed before approval or review:
|
|
requester, amount, project, purchase object, contract counterparty, asset
|
|
owner, payment batch and similar module facts.
|
|
- Evidence materials sit in the main content, grouped by business meaning:
|
|
line items, PDF invoices, attachments, contract files, asset photos/numbers,
|
|
receipts and acceptance materials.
|
|
- Risk or validation sections appear only when there is a real signal such as
|
|
budget issue, duplicate invoice, missing attachment, contract expiry, asset
|
|
anomaly or payment failure.
|
|
- Approval and processing history is for traceability. Keep a useful summary
|
|
visible, but do not let full history crowd out current status and evidence.
|
|
- PC high-risk actions live in the right command panel or separated action
|
|
stack. Mobile high-risk actions live in the bottom action surface or a
|
|
confirmation panel.
|
|
- Approve, reject, return, pay, publish, delete and void actions must show the
|
|
object summary and consequence before execution.
|
|
- When evidence is incomplete, change the primary action to supplement material,
|
|
view issues or an explained disabled state. Do not leave users guessing from a
|
|
disabled button alone.
|
|
- List and ledger rows show only evidence completeness summaries, missing
|
|
evidence hints and a detail entry. Invoice preview, attachment download,
|
|
contract file viewing, receipt download, evidence deletion and bulk packaging
|
|
belong in detail workspaces, detail command panels, `台账工具` or authorized
|
|
audit paths.
|
|
- Sensitive evidence such as invoices, contracts, receipts and attachments must
|
|
be permissioned; download and export belong in `更多` or audit paths when
|
|
appropriate.
|
|
- Detail evidence sections group materials by type. Do not mix invoices,
|
|
ordinary attachments, contract files, receipts, asset materials and
|
|
electronic-document indexes in one undifferentiated list.
|
|
- Mobile details use a top focus card, sectioned cards and bottom safe-area
|
|
actions. Do not copy PC two-column detail or wide tables into mobile.
|
|
|
|
**Why**: Detail pages are the place where users decide whether to approve,
|
|
reject, pay or supplement materials. Consistent evidence order reduces
|
|
misreads and accidental actions.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks when changing detail overview,
|
|
evidence sections, history placement, right command panels or mobile detail
|
|
bottom actions.
|
|
|
|
## Convention: Mobile Lightweight Surfaces
|
|
|
|
**What**: Mobile and Enterprise WeChat WebView routes are lightweight action
|
|
surfaces. They are not compressed PC management consoles.
|
|
|
|
**Contracts**:
|
|
|
|
- Mobile may support lightweight submit, supplement-material, status lookup,
|
|
task handling, scanning, upload and message-deeplink flows.
|
|
- Keep mobile pages to top status or focus card, card list or sectioned detail,
|
|
and bottom safe-area primary action.
|
|
- Mobile home should show compact status and today's actionable items. Do not
|
|
add a full module directory or dashboard.
|
|
- Mobile home finance summaries are conditional action cards. Render them only
|
|
when the current finance/cashier user has pending payment, payment exception
|
|
or risk-review counts to handle; do not show disabled finance placeholders or
|
|
unconditional mobile `我的` finance anchors.
|
|
- Mobile lists use search/status filtering, cards and one primary action. Do not
|
|
use wide tables, column configuration, complex multi-column filters,
|
|
full-scope management, admin configuration, batch export, bulk approval or
|
|
bulk payment.
|
|
- Mobile list search that filters the currently loaded list must expose the
|
|
visible label and aria label `当前列表搜索`; do not imply global search with
|
|
labels such as `搜索报销` or `搜索采购` unless the page actually queries a
|
|
global corpus.
|
|
- Mobile details use a focus card, sectioned evidence and bottom actions. Do not
|
|
copy PC two-column layouts.
|
|
- Mobile forms keep necessary fields, material upload, field-local validation
|
|
and a bottom action. Do not put admin configuration, workflow configuration,
|
|
feature flags, statistics dashboards or bulk import into mobile forms.
|
|
- Bottom actions must account for safe area and keyboard overlap. Button text
|
|
must remain readable on narrow screens.
|
|
- Dangerous mobile actions must open a confirmation panel that shows object
|
|
summary and consequence.
|
|
- Ordinary mobile paths must not show internal IDs, permission codes,
|
|
configuration matrices or audit troubleshooting panels.
|
|
- Enterprise WeChat remains the primary owner for daily HR/attendance actions
|
|
such as leave, missed punch, outing, overtime and check-in. OA mobile shows
|
|
mirror/history/exception/emergency takeover according to the business
|
|
boundary.
|
|
|
|
**Why**: Most mobile use happens from notifications or quick context switches.
|
|
Reducing mobile scope keeps the phone path fast and prevents PC admin
|
|
complexity from leaking into WeChat.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Playwright or screenshot coverage for representative narrow viewports when
|
|
changing mobile home, mobile lists, mobile details, bottom actions, upload
|
|
surfaces or Enterprise WeChat WebView flows.
|
|
- If true Enterprise WeChat device validation is unavailable, record it as
|
|
paused manual validation; do not claim full WebView acceptance.
|
|
|
|
## Convention: Notifications Versus Tasks
|
|
|
|
**What**: Task queues and notifications have separate jobs. A task queue is for
|
|
action; a notification center is for event awareness and navigation.
|
|
|
|
**Contracts**:
|
|
|
|
- `待我处理` is an action list. Include only items that require the current user
|
|
to process, supplement material, review, pay, approve, confirm or resolve an
|
|
exception.
|
|
- Task rows must have a clear next step, object summary, business state and
|
|
processing entry.
|
|
- Completed items, read-only progress, announcements, successful sync notices
|
|
and ordinary system messages do not belong in the pending task list.
|
|
- `通知中心` is an event inbox for status changes, reminders, failures, sync
|
|
results, workflow transitions, invoice/attachment recognition results and
|
|
Enterprise WeChat delivery results.
|
|
- Notifications should support read/unread, view, jump target and failure
|
|
explanation. Do not rebuild the full workflow task list inside the
|
|
notification center.
|
|
- Notification clicks must deep-link to the business detail, workflow task,
|
|
mobile target page or failure explanation. Do not send users back to a
|
|
generic notification list as the final destination.
|
|
- Notification copy should explain what happened, who or what is affected, and
|
|
the next useful step. Do not expose raw payloads, internal state codes or
|
|
debug fields.
|
|
- Workbench `今日待处理` aggregates only actionable items. Ordinary
|
|
notifications, read-only progress, completed activity and announcements are
|
|
not counted as pending work.
|
|
- If a notification represents real work, the backend or aggregation layer
|
|
should expose it as an explicit task item; the frontend should not infer every
|
|
notification is a task.
|
|
- The topbar bell is the notification entry. Do not add notification center as a
|
|
default sidebar row.
|
|
- Enterprise WeChat messages are an external delivery channel. Keep message
|
|
content desensitized and deep-link into the OA business or task detail.
|
|
|
|
**Why**: Separating event awareness from action prevents Portal, task queue and
|
|
notification center from showing the same thing in three different ways.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage when changing task aggregation, notification
|
|
center rows, topbar bell behavior, notification deep links or workbench
|
|
`今日待处理` counts.
|
|
|
|
## Convention: Sensitive Data And Exports
|
|
|
|
**What**: Contracts, finance, invoices, receipts, payments, assets and
|
|
attachments are sensitive by default. Frontend surfaces show the minimum useful
|
|
summary unless a permissioned workflow requires more.
|
|
|
|
**Contracts**:
|
|
|
|
- Treat contract text and attachments, quotations, acceptance materials,
|
|
invoices, receipts, payment information, bank accounts, supplier details,
|
|
asset serial/location/owner data, personnel records, payroll/performance,
|
|
audit records, original file names and export files as sensitive.
|
|
- Workbench, notifications, ordinary lists, mobile cards and Enterprise WeChat
|
|
messages show desensitized summaries only.
|
|
- Ordinary surfaces must not show full bank/account numbers, full local paths,
|
|
storage paths, raw payloads, full sensitive attachment names, Secrets, tokens
|
|
or high-sensitive contract/finance details.
|
|
- Previewing contract text, invoices, receipts and attachments requires
|
|
server-side permission checks. Frontend visibility is not a security boundary.
|
|
- High-sensitive previews should explain context or purpose when useful and
|
|
record view evidence when the backend supports it.
|
|
- Download, batch download, export, print, attachment packaging, contract text
|
|
export and finance ledger export must be controlled by server permissions and
|
|
data scope.
|
|
- Export is never the primary first-screen action. Put exports in `台账工具`,
|
|
`更多` or role-only finance/admin panels.
|
|
- Before exporting sensitive ledgers, explain scope and sensitive contents.
|
|
Finance, contract, asset and invoice exports should write audit records.
|
|
- Export file names use business numbers and dates. Do not concatenate complete
|
|
personal accounts, complete supplier secrets or internal filesystem paths.
|
|
- Audit sensitive operations with actor, time, object, action, scope and result
|
|
where supported.
|
|
- Permission-denied and failure messages use natural Chinese without leaking
|
|
full paths, permission codes, raw URLs, payloads, Secrets or tokens.
|
|
|
|
**Why**: The product is for small teams, but the data is still financial,
|
|
contractual and operationally sensitive. Small team convenience must not turn
|
|
into broad accidental disclosure.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks when changing attachment preview,
|
|
contract/invoice/receipt surfaces, export controls, mobile summaries,
|
|
notification copy or permission-denied states.
|
|
|
|
## Convention: Permission Empty And Error States
|
|
|
|
**What**: Permission-denied, empty and error states use natural Chinese that
|
|
explains cause and next step. Ordinary users should not inspect platform
|
|
internals to understand what happened.
|
|
|
|
**Contracts**:
|
|
|
|
- Hide unauthorized actions by default. If a route is opened directly or the
|
|
user needs context, show a natural Chinese explanation and a real next step
|
|
such as returning to workbench, viewing related records or contacting an
|
|
admin.
|
|
- Empty states are scoped to the current filter, status or section. Explain what
|
|
is absent and show one useful next step; if there is no real next step, hide
|
|
the section instead of adding instructional copy.
|
|
- Error states explain business cause, impact and recovery path such as retry,
|
|
supplement material, return to list or contact admin.
|
|
- Ordinary user paths must not show raw `403`, API route names, permission
|
|
codes, internal state codes, route stacks, full paths, raw payloads or long
|
|
technical error dumps.
|
|
- Admin, audit and troubleshooting routes may show the minimum technical
|
|
details needed to diagnose a problem, but the business reason and next step
|
|
remain primary.
|
|
- Mobile and notification targets use shorter copy, but must still include
|
|
cause and next step.
|
|
|
|
**Why**: Small-team users do not have time to decode implementation details.
|
|
Clear failure states reduce support work and avoid leaking internal platform
|
|
structure.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks when changing empty states,
|
|
permission-denied pages, notification failure targets or shared error
|
|
components.
|
|
|
|
## Convention: Dangerous Action Confirmation
|
|
|
|
**What**: Destructive, financial, approval, configuration, batch and external
|
|
sync actions require meaningful confirmation. A generic `确定吗?` dialog is not
|
|
enough.
|
|
|
|
**Contracts**:
|
|
|
|
- Treat delete, void, revoke, archive, restore, disable, publish, configuration
|
|
switching, workflow switching and feature-flag changes as dangerous actions.
|
|
- Treat pay, batch pay, sensitive export, batch download, contract text
|
|
download and attachment packaging as dangerous or high-sensitive actions.
|
|
- Treat approve, reject, return, transfer, batch approve and batch reject as
|
|
approval-risk actions that need context before execution.
|
|
- Treat external synchronization, retry external write and Enterprise
|
|
WeChat/OA emergency-takeover switching as integration-risk actions.
|
|
- Confirmation UI must show object summary: business number, name, requester or
|
|
counterparty, amount or quantity and current state when relevant.
|
|
- Confirmation UI must explain consequences: target state, reversibility,
|
|
notifications, payment/approval/configuration impact and external-system
|
|
effect.
|
|
- Confirmation UI must show impact scope for batch, export, configuration and
|
|
integration actions: selected count, data range, external system, Enterprise
|
|
WeChat message or audit scope.
|
|
- Rejection and return require a reason. Payment, publishing, batch and
|
|
configuration actions may require a confirmation word, explicit checkbox or
|
|
selected reason when risk is high.
|
|
- Dangerous actions must be visually separated from normal view, edit, save and
|
|
submit actions.
|
|
- Mobile dangerous actions use bottom or full-screen confirmation panels, not
|
|
instant execution from an easy-to-mistap control.
|
|
- Confirmation failure must preserve user input and show result details plus the
|
|
next repair action.
|
|
- Audited actions should record actor, time, object, action, scope, reason and
|
|
result where backend support exists.
|
|
- Delete, withdraw, cancel, void and archive confirmations must use the exact
|
|
business verb and explain the target state. Do not label cancel, void or
|
|
archive as `删除`.
|
|
|
|
**Why**: These actions can change finance, contracts, workflow, approvals,
|
|
configuration and external integrations. Users need context before execution,
|
|
and support needs an audit trail after execution.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage when changing delete, payment, approval,
|
|
publish/disable, batch, configuration or external-sync confirmations.
|
|
|
|
## Convention: Integration Boundary And External Status
|
|
|
|
**What**: External-system state is conservative. OA shows facts confirmed by its
|
|
own backend and explicit external acknowledgements; it does not present a queued
|
|
request, frontend click or message attempt as final business completion.
|
|
|
|
**Contracts**:
|
|
|
|
- OA owns reimbursement, procurement, contracts, projects, payments, AP,
|
|
invoices, assets, sensitive attachments, audit and OA workflow handling.
|
|
- Enterprise WeChat owns daily HR/attendance actions: check-in, leave, missed
|
|
punch, outing and overtime. OA shows mirror, history, exception, audit and
|
|
emergency-takeover records for those domains.
|
|
- ERP, agency accounting, bank, OCR and Enterprise WeChat messages are external
|
|
capabilities or delivery channels. They do not replace OA server-side
|
|
permissions or state machines.
|
|
- Show final labels such as `已同步`, `已发送`, `已付款` and `识别完成` only when the
|
|
relevant external system has returned a clear success acknowledgement.
|
|
- Use in-progress labels such as `同步中`, `等待回执`, `银行处理中`, `识别中` and
|
|
`消息发送中` when the request has started but is not confirmed.
|
|
- External failures must show source, impact and next step in natural Chinese,
|
|
such as `银行回执未返回` or `OCR 识别失败,需重新上传 PDF`.
|
|
- Do not expose raw external error codes, payloads, full URLs, secrets, tokens
|
|
or debug traces to ordinary users.
|
|
- External writes, payment execution, ERP sync, Enterprise WeChat resend and OCR
|
|
retry must be controlled by permissions and state-driven actions.
|
|
- Retry confirmation should explain which object will be retried, whether it may
|
|
send duplicate external messages, external-system impact and audit effect.
|
|
- External sync state should not block unrelated primary flows. If it blocks a
|
|
flow, show the blocker and manual repair path.
|
|
- Ordinary routes show summary, failure reason and next step. Admin, finance or
|
|
troubleshooting routes may show deeper diagnostics when authorized.
|
|
- HR/attendance routes should default to Enterprise WeChat record, sync mirror
|
|
or exception handling copy. Do not expose OA daily leave/missed-punch paths
|
|
unless OA emergency takeover is explicitly enabled.
|
|
- Enterprise WeChat messages carry desensitized summary and OA deeplink only;
|
|
they do not carry sensitive attachment text or final payment/approval actions.
|
|
- If bank, ERP, agency accounting or another integration is not connected or not
|
|
confirmed, UI copy must not imply the capability already completed.
|
|
|
|
**Why**: External integrations are asynchronous and failure-prone. Conservative
|
|
copy prevents users from trusting a state the system has not actually verified.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage when changing Enterprise WeChat boundary copy,
|
|
OCR status, bank/payment callbacks, ERP/accounting sync status, retry
|
|
controls, external failure messages or integration diagnostics.
|
|
|
|
## Convention: Verification And User-Testable Claims
|
|
|
|
**What**: Verification claims must describe the actual validation level. Local
|
|
checks, screenshots and mock Playwright runs do not mean a user can test the
|
|
change online.
|
|
|
|
**Contracts**:
|
|
|
|
- Local build passing means only the local code built successfully.
|
|
- Playwright passing means the specified automated path passed in the specified
|
|
environment and data state.
|
|
- Screenshot review passing means only the captured viewport and state were
|
|
reviewed.
|
|
- Deployment passing must identify the deployed environment, version or commit
|
|
and health check result when available.
|
|
- Say `可以线上测试` only after deployment, public access check, key-path smoke
|
|
testing and necessary screenshot evidence are complete.
|
|
- Before deployment, say `本地验证通过,尚未线上可测`.
|
|
- After deployment but before public access check, say `已部署,公网检查未完成`.
|
|
- If real-device or Enterprise WeChat WebView validation is unavailable, record
|
|
it as paused manual validation. Do not substitute automation for full WebView
|
|
acceptance.
|
|
- A-class page changes should keep build, focused Playwright or screenshot
|
|
evidence according to risk.
|
|
- Changes touching permissions, state machines, approval, payment, Enterprise
|
|
WeChat, external systems, sensitive downloads or production configuration
|
|
need rollback or manual repair notes.
|
|
- Updating this design/spec documentation does not mean pages were refactored,
|
|
deployed or accepted for live trial.
|
|
|
|
**Why**: This keeps delivery status honest and prevents the user from trying a
|
|
change that has not actually reached a public environment.
|
|
|
|
**Tests Required**:
|
|
|
|
- Documentation-only changes: Trellis task validation, governance check and
|
|
`git diff --check`.
|
|
- Frontend implementation changes: `cd client && npm run typecheck`,
|
|
`cd client && npm run build`, plus focused Playwright or screenshots based on
|
|
affected surface.
|
|
|
|
## Convention: A-Class PC Task-First Pages
|
|
|
|
**What**: A-class PC pages such as Portal, approvals, reimbursement list and
|
|
reimbursement detail should make the current user task obvious before exposing
|
|
secondary operations:
|
|
|
|
- Treat the primary persona as a small-team operator wearing multiple hats, not
|
|
a dedicated OA clerk. The first screen should reduce decision cost for a
|
|
founder, finance/admin owner, project lead or employee who may switch roles
|
|
during the same session.
|
|
- First visible task surface should answer: what needs attention, what can be
|
|
started, and where recent progress lives.
|
|
- Keep one primary action in the first screen. Allow at most two secondary
|
|
entries; move export, batch, delete, templates, complex filters, statistics
|
|
and admin/finance tools into `更多`, `高级 / 台账`, detail actions, role-only
|
|
panels or confirmation dialogs.
|
|
- Do not turn small-team workflows into platform-builder surfaces by default:
|
|
approval designers, broad configuration matrices, multi-level enterprise
|
|
dashboards and batch admin consoles need explicit Trellis task scope.
|
|
- Explanation text should only be default-visible for risk, exception or empty
|
|
states. Do not use repeated subtitles or notice cards to explain normal
|
|
workflow steps that the layout can express.
|
|
- Low-frequency capabilities are hidden or moved, not removed, unless the
|
|
current Trellis task explicitly deletes the capability.
|
|
- Portal/workbench first screen should use a compact status summary plus
|
|
`今日待处理`; do not use a persistent welcome hero, fixed `报销进度` button,
|
|
general announcement feed, or folded placeholder sections such as
|
|
`团队与通知`, `角色重点` or `试点观测摘要`.
|
|
- Workbench sections after `今日待处理` must be conditional: `团队卡点` only for
|
|
real blockers, `管理提醒` only for real admin/trial issues, and `我的进度`
|
|
only for reliable status updates. Empty data should disappear, not render as
|
|
collapsed drawers or statistic cards.
|
|
- Each workbench action row should state what the item is, why the current user
|
|
is involved, current status/timing, and one next action. Do not represent raw
|
|
application counts as progress unless the payload includes an actionable or
|
|
status-level signal.
|
|
- PC reimbursement list defaults to the initiator's own forms even for users
|
|
with finance/approval roles. The first screen may use task cards for
|
|
rejected corrections, drafts and reviewing progress; ledger/export/batch,
|
|
proxy submit, templates and travel-linking remain secondary and must be hidden
|
|
unless the current user has a real matching capability. Row workflow copy
|
|
should distinguish `待你处理` from read-only `当前节点`.
|
|
|
|
**Why**: hyb-oa serves small teams with overlapping roles. Core pages must make
|
|
the next click clear for ordinary employees and approvers, while keeping finance
|
|
and admin tools available without dominating the default path.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright or screenshot checks for changed A-class PC pages,
|
|
asserting the task surface, primary action and secondary/advanced entry
|
|
behavior.
|
|
|
|
### Convention: Approval Task List Defaults
|
|
|
|
**What**: PC approval task lists such as `/workflow/tasks` should make
|
|
`查看处理` the default row action. List-level `通过` is disabled by default unless
|
|
a later Trellis task adds an explicit backend eligibility contract.
|
|
|
|
**Contracts**:
|
|
|
|
- The row must answer what the item is, who requested it, why it is assigned to
|
|
the current user, how long it has waited, and the public business reference.
|
|
- History entry text should be explicit, such as `已处理记录`; avoid user-facing
|
|
`高级 / 历史` on the default task surface.
|
|
- Time labels should prefer `已等待多久` and `接收于` over database-shaped labels
|
|
such as `更新时间` when the source field is task creation/arrival time.
|
|
- HR/attendance items owned by Enterprise WeChat, including leave, missed
|
|
punch, outing, overtime and check-in related approvals, must not show OA
|
|
list-level quick approval. OA may show mirror/history/status/exception
|
|
context and emergency-takeover records according to the business boundary,
|
|
but normal approval remains in Enterprise WeChat.
|
|
- Reimbursement, procurement, travel, contract and other amount/evidence-heavy
|
|
OA-owned tasks should route through `查看处理` first.
|
|
- Business ledgers and ordinary business details must follow the same rule:
|
|
show the task entry or progress, but do not place `通过`, `驳回`, `退回` or
|
|
`转审` directly in reimbursement, procurement, contract, project or asset
|
|
tables/details.
|
|
- Future list-level quick approval requires the backend to expose an explicit
|
|
eligibility flag such as `quickApproveEligible=true`, plus task-domain and
|
|
audit semantics in the current Trellis task. Frontend heuristics based only on
|
|
entity type, duration or row text are not enough.
|
|
- If list quick approval is reintroduced later, its confirm dialog must still
|
|
explain action consequences and include the specific task summary.
|
|
|
|
**Why**: Small-team approvers should build the habit of opening the task detail
|
|
before approval, and the OA/Enterprise WeChat ownership boundary must stay clear
|
|
for HR/attendance workflows.
|
|
|
|
## Convention: Workbench Onboarding And Profile Scope
|
|
|
|
**What**: PC workbench and account settings should stay task-first, not become
|
|
training or permission-maintenance surfaces:
|
|
|
|
- Do not add a persistent `快速上手` / onboarding checklist to the workbench by
|
|
default. If first-login guidance is needed, use a dismissible welcome dialog
|
|
with at most three real business entries.
|
|
- Welcome or onboarding entries must point to executable user tasks, such as
|
|
`处理待办`, `提交报销` or `请假`; do not use explanatory entries like
|
|
`了解流程`, and do not route users to settings or notifications as a
|
|
substitute for task guidance.
|
|
- `个人设置` default content is personal profile, password/security,
|
|
notification preference and Enterprise WeChat binding. Organization, report
|
|
line and role summary may be folded under `账号详情`; permission code lists
|
|
and full employee dossier fields stay out of the default view. Do not add a
|
|
default `查看员工档案` / employee-maintenance jump from the ordinary profile
|
|
page; profile fields are read-only personal context, while dossier
|
|
maintenance belongs to `人员` / `管理`.
|
|
- Keep account settings separate from admin configuration. `个人设置` may show
|
|
personal profile, password/security, notification preferences and Enterprise
|
|
WeChat binding only. Organization maintenance, role assignment, approval
|
|
rules, feature flags, master data, audit logs, employee maintenance and
|
|
system configuration belong under `管理`, not the ordinary profile route.
|
|
- Mobile `我的` and `个人设置` must not expose an admin matrix or raw internal
|
|
labels. Hide `管理入口` / `人员管理` / `组织架构` / `系统设置` from mobile `我的`,
|
|
and map account status plus role codes to Chinese labels before display.
|
|
|
|
**Why**: Small teams need fewer default decisions. Persistent onboarding and
|
|
permission-heavy profile pages make ordinary users inspect system internals
|
|
before doing work.
|
|
|
|
**Tests Required**:
|
|
|
|
- Focused Playwright coverage for changed workbench or profile routes.
|
|
- Screenshot evidence for first-login welcome, workbench first screen and
|
|
profile default view when changing these surfaces.
|
|
- Workbench baseline screenshots must explicitly clear onboarding localStorage
|
|
such as `hyb_oa_show_welcome` and `hyb_oa_onboarding_active` before capture,
|
|
unless the test is intentionally verifying the welcome dialog.
|
|
|
|
## Convention: Detail And Mobile Command Surfaces
|
|
|
|
**What**: PC detail pages and notification-like flows should reuse the Wave3
|
|
surface classes in `client/src/index.css` before adding page-local Tailwind
|
|
card systems:
|
|
|
|
- `detail-workspace-grid` for the main PC detail two-column workspace.
|
|
- `detail-command-panel`, `detail-fact-grid` and `detail-fact-card` for compact
|
|
status, summary, payment, export and evidence facts.
|
|
- `detail-evidence-card` for attachments, invoices and other proof material.
|
|
- `detail-timeline` and `detail-timeline-item` for approval progress and
|
|
history.
|
|
- `detail-action-stack` and `detail-action-card` for approve/reject/return,
|
|
payment and other high-risk command groups.
|
|
- `notification-inbox`, `notification-row-card` and
|
|
`notification-row-card--unread` for PC notification streams; avoid reverting
|
|
notifications to a desktop table unless a task explicitly requires tabular
|
|
comparison.
|
|
|
|
Mobile key pages should reuse the mobile command classes in
|
|
`client/src/styles/mobile-touch.css`:
|
|
|
|
- `mobile-focus-card` for the current task, current list or account summary.
|
|
- `mobile-command-surface` for tabs, search and filters.
|
|
- `mobile-list-card--focus` and `mobile-list-card--unread` for state emphasis.
|
|
|
|
**Why**: Detail pages should feel like quiet command surfaces: status, summary,
|
|
primary action, evidence and history have predictable places. Mobile pages
|
|
should stay card/list based, with no PC tables, no horizontal overflow and no
|
|
button text squeeze.
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright screenshot coverage for changed PC detail, notification
|
|
and mobile pages.
|
|
- UI design rules check when changing shared visual classes.
|
|
|
|
## Scenario: Auth Pages And PWA Updates
|
|
|
|
### 1. Scope / Trigger
|
|
|
|
- Trigger: login, password change, password recovery or other unauthenticated
|
|
forms are active while the PWA service worker finds a new frontend version.
|
|
- Applies to `client/src/pwa.ts`, `client/src/layouts/AuthLayout.tsx`, and
|
|
auth routes such as `/login`, `/change-password`, `/forgot-password`, and
|
|
future reset-password pages.
|
|
|
|
### 2. Signatures
|
|
|
|
- Event name: `hyb-oa:pwa-update-ready`.
|
|
- Event detail: `{ applyUpdate?: () => void | Promise<void> }`.
|
|
- Route predicate: auth input pages must be checked by pathname before calling
|
|
`updateServiceWorker(true)`.
|
|
|
|
### 3. Contracts
|
|
|
|
- Auth input pages must not auto-reload when `onNeedRefresh()` fires.
|
|
- Auth input pages must show an explicit update prompt with a user-triggered
|
|
refresh action.
|
|
- Non-auth pages may keep automatic service-worker update behavior when the
|
|
task does not change broader runtime policy.
|
|
- Passwords and verification codes must stay only in React component state; do
|
|
not write them to `localStorage`, `sessionStorage`, URL params, reports, or
|
|
Trellis task evidence.
|
|
- Password visibility controls must use icon buttons with accessible labels and
|
|
preserve the current input value.
|
|
|
|
### 4. Validation & Error Matrix
|
|
|
|
- PWA update on `/login` -> dispatch update-ready event and keep form state.
|
|
- PWA update on `/forgot-password` -> dispatch update-ready event and keep
|
|
email/code/password fields in memory.
|
|
- User clicks refresh in the prompt -> run the captured update handler.
|
|
- User dismisses prompt -> no reload and no form reset.
|
|
- Password reset request returns success for any email -> show generic sent
|
|
message; do not reveal whether the account exists.
|
|
|
|
### 5. Good/Base/Bad Cases
|
|
|
|
- Good: user is typing a password, update prompt appears, typed values remain.
|
|
- Base: user is on a normal portal page, PWA update can refresh per existing
|
|
runtime behavior.
|
|
- Bad: service-worker update auto-refreshes an auth form and clears credentials.
|
|
- Bad: tests use real-looking personal email addresses or persist example
|
|
passwords outside the test file.
|
|
|
|
### 6. Tests Required
|
|
|
|
- Frontend typecheck and build.
|
|
- Focused Playwright auth UX test asserting:
|
|
- login password can be shown/hidden without losing value;
|
|
- forgot-password flow calls request-code and reset endpoints;
|
|
- auth-page PWA update prompt appears without clearing inputs.
|
|
- UI design rules check when auth page layout changes.
|
|
- Any Playwright test that renders `/login`, `/forgot-password` or another auth
|
|
route with mocked `/api/*` responses must mock `/api/auth/capabilities` with
|
|
`emailDelivery.ready`, `emailLoginCode.enabled` and `passwordReset.enabled`.
|
|
Returning `{}` for unknown auth APIs can crash auth pages before the visual or
|
|
navigation assertion actually runs.
|
|
|
|
### 7. Wrong vs Correct
|
|
|
|
#### Wrong
|
|
|
|
```ts
|
|
onNeedRefresh() {
|
|
void updateServiceWorker?.(true);
|
|
}
|
|
```
|
|
|
|
#### Correct
|
|
|
|
```ts
|
|
onNeedRefresh() {
|
|
if (isAuthInputPath(window.location.pathname)) {
|
|
window.dispatchEvent(new CustomEvent(PWA_UPDATE_READY_EVENT, { detail: { applyUpdate } }));
|
|
return;
|
|
}
|
|
applyUpdate();
|
|
}
|
|
```
|
|
|
|
## Scenario: Auth Page Layout And Login Entry Hierarchy
|
|
|
|
### 1. Scope / Trigger
|
|
|
|
- Trigger: login, password recovery, forced password change or future
|
|
unauthenticated auth forms need layout changes.
|
|
- Applies to `client/src/layouts/AuthLayout.tsx`, shared auth components under
|
|
`client/src/components/auth/`, and auth routes such as `/login`,
|
|
`/forgot-password` and `/change-password`.
|
|
|
|
### 2. Component Contract
|
|
|
|
- Auth routes should use one shared auth panel for brand, page title, subtitle,
|
|
content and optional footer links.
|
|
- `AuthLayout` owns only the auth page shell: background, width constraint,
|
|
centering, PWA update prompt and route outlet.
|
|
- Page implementations own only their form fields, submit actions, validation
|
|
messages and route-specific login-entry choices.
|
|
|
|
### 3. Visual Contracts
|
|
|
|
- Do not nest a form card inside another login card.
|
|
- Put the brand block inside the auth panel so logo, system name, title and
|
|
form share one visual axis.
|
|
- Keep the panel width stable around the current auth-shell width; auth pages
|
|
should feel like an OA workstation entry, not a marketing split hero.
|
|
- Place `忘记密码?` beside the password label or directly below the password
|
|
input on the right; do not bury it in help text or page footer.
|
|
- Keep the DOM/tab order aligned with the main form flow even when CSS places
|
|
`忘记密码?` visually beside the password label: username/email input -> password
|
|
input -> secondary controls. Do not render the forgot-password link before the
|
|
password input in DOM order.
|
|
- Use password visibility icon buttons with accessible labels and preserve the
|
|
current input value.
|
|
|
|
### 4. Login Entry Hierarchy
|
|
|
|
- Normal browser: account/password or email-code login is primary. Enterprise
|
|
WeChat is shown as a boundary notice or secondary entry that tells users to
|
|
open OA from the Enterprise WeChat workbench; do not require a clickable OAuth
|
|
button in ordinary browsers.
|
|
- Enterprise WeChat WebView: Enterprise WeChat one-click entry is primary;
|
|
account/password login remains available as the fallback path.
|
|
- Enterprise WeChat entry changes must remain frontend entry hierarchy changes
|
|
unless the task explicitly approves backend OAuth, binding or WeCom API work.
|
|
- Email verification-code login is a separate login mode. Do not infer it from
|
|
password-recovery verification-code flows without a backend login-code
|
|
contract and abuse-control plan.
|
|
|
|
### 5. Tests Required
|
|
|
|
- Frontend typecheck and build.
|
|
- Focused auth E2E covering:
|
|
- password visibility and forgot-password navigation on `/login`;
|
|
- keyboard Tab from the username/email field lands on the password input, not
|
|
the forgot-password link;
|
|
- password recovery request-code and reset flow on `/forgot-password`;
|
|
- normal-browser Enterprise WeChat boundary notice or secondary entry;
|
|
- WeCom WebView Enterprise WeChat entry as primary CTA with password fallback.
|
|
- UI design rules check and Playwright screenshot evidence when the auth layout
|
|
changes visibly.
|
|
|
|
### 6. Wrong vs Correct
|
|
|
|
#### Wrong
|
|
|
|
```tsx
|
|
<AuthLayout>
|
|
<Card>
|
|
<Card>
|
|
<LoginForm />
|
|
</Card>
|
|
</Card>
|
|
</AuthLayout>
|
|
```
|
|
|
|
#### Correct
|
|
|
|
```tsx
|
|
<AuthPanel title="登录工作台" subtitle="账号密码登录">
|
|
<LoginForm />
|
|
<SecondaryLoginMethods />
|
|
</AuthPanel>
|
|
```
|
|
|
|
#### Wrong
|
|
|
|
```tsx
|
|
<Label htmlFor="login-password">密码</Label>
|
|
<Link to="/forgot-password">忘记密码?</Link>
|
|
<PasswordInput id="login-password" />
|
|
```
|
|
|
|
#### Correct
|
|
|
|
```tsx
|
|
<Label htmlFor="login-password">密码</Label>
|
|
<PasswordInput id="login-password" />
|
|
<Link className="row-start-1" to="/forgot-password">忘记密码?</Link>
|
|
```
|
|
|
|
## Convention: Finance And Admin Console Surfaces
|
|
|
|
**What**: PC finance and C-class admin pages should reuse Wave4 shared classes
|
|
from `client/src/index.css` before creating page-local card/table layouts:
|
|
|
|
- `finance-status-strip`, `finance-metric-card`,
|
|
`finance-metric-card__label` and `finance-metric-card__value` for compact
|
|
five-column status summaries.
|
|
- `finance-workspace-grid`, `finance-command-panel`, `finance-list-card` and
|
|
`finance-list-card--active` for payment/AP/invoice operational workspaces.
|
|
- `admin-command-panel`, `admin-tile-grid`, `admin-tile-card` and
|
|
`admin-workspace-grid` for settings, workflow, feature-flag, user, master
|
|
data, notification-channel and audit pages.
|
|
|
|
**Why**: Finance/admin pages are lower-frequency but high-risk operational
|
|
surfaces. They need dense scanability, stable command regions and clear risk
|
|
hierarchy without turning every page into a bespoke Tailwind card system.
|
|
|
|
**Example**:
|
|
|
|
```tsx
|
|
<div className="finance-status-strip" data-testid="payment-batches-summary">
|
|
<div className="finance-metric-card">
|
|
<div className="finance-metric-card__label">可处理</div>
|
|
<div className="finance-metric-card__value">{actionableCount}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="finance-workspace-grid">
|
|
<section className="finance-command-panel">...</section>
|
|
<section className="finance-command-panel">...</section>
|
|
</div>
|
|
```
|
|
|
|
**Tests Required**:
|
|
|
|
- `cd client && npm run typecheck`
|
|
- `cd client && npm run build`
|
|
- Focused Playwright coverage for changed finance/admin pages. The Wave4
|
|
baseline test is `client/tests/e2e/pc-finance-admin-visual-wave4.spec.ts`.
|
|
- UI design rules check when changing these shared classes.
|