Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 47 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@ Built on the [ObjectStack](https://github.com/objectstack-ai/objectstack) 17.x m
Organization, accounts, permissions, audit logging, import/export, list and form UI come from the
platform; six server-side code points carry what is specific to assessment.

> **Language note.** The application UI and the delivery documents under `docs/` are in Simplified
> Chinese — this system was built for a Chinese enterprise, and the copy is part of the domain
> modelling rather than an afterthought. The platform is configured for `zh-CN` and `en`
> (`objectstack.config.ts`), but the English bundle is currently a **stub fallback**: 32 labels
> across 7 objects, against 320 labels across 21 objects for `zh-CN`. Switching to English today
> gives a mixed-language UI, and view, action, page and error copy have no English at all. A full
> English UI is not yet in scope — see [Internationalization](#internationalization).
> This README is the English entry point.
> **Language note.** This system was built for a Chinese enterprise, so the domain copy is authored
> in Simplified Chinese and the delivery documents under `docs/` are Chinese throughout. The UI
> itself runs in English: every object, field, picklist value, list view, action and navigation
> label is translated (530 keys). A few surfaces are not yet covered — see
> [Internationalization](#internationalization) for exactly which.

![Workbench](docs/手册/图片/01-02-gongzuotai.png)
![One assessment cycle, by role](docs/readme/flow-swimlane.png)

*One assessment cycle. Solid arrows are the sheet moving between people; dashed arrows are the five
points where the system acts on its own.*

![Entry sheets in the console](docs/readme/ui-entry-sheets.png)

*Entry sheets queued by workflow state. The record names are Chinese because the bundled demo
dataset is — the interface is not.*

## Why this exists

Expand Down Expand Up @@ -145,14 +150,11 @@ grants from historical plans stay untouched. Once a plan is **closed or archived

## Business process

Four workflow steps by default; the steps are configurable per plan.
Four workflow steps by default; the steps are configurable per plan. Every transition is decided by
a server-side hook — buttons only write a pending action, so writing the status field directly is
refused the same way.

```
Plan draft ─publish (integrity check)─▶ entry sheets + lines (frozen copy of target, weight, scoring rule)
Entering ─submit─▶ Branch verification (parallel check tasks, advances when all confirm)
─▶ HR review ─▶ Executive approval ─▶ Passed ─archive─▶ Archived (immutable snapshot)
Any review step ─reject (reason required)─▶ previous step
```
![Entry sheet state machine and its gates](docs/readme/state-machine.png)

- **Scoring engine** — `src/lib/scoring.ts` (linear / step / range interpolation / CEL formula).
Saving an actual value scores it immediately and persists a human-readable calculation trace.
Expand Down Expand Up @@ -201,28 +203,41 @@ Full detail in [CLAUDE.md](CLAUDE.md). The load-bearing ones:
as issues on objectstack-ai/objectstack (symptom, minimal repro, expected capability, version) —
no fix PRs there. Application-side workarounds must be environment-gated and annotated with the
platform issue they track, and deleted once it is fixed.
- User-facing copy is Simplified Chinese. The `zh-CN` bundle is generated from metadata labels by
`pnpm i18n:extract`; never hand-edit its entries. The `en` bundle is hand-maintained.
- Metadata labels are authored in Simplified Chinese (`Field.number({ label: '实际值', … })`), which
fills the `zh-CN` bundle verbatim — never hand-edit its entries. The `en` leaves are translated by
hand; change a Chinese label and you must re-translate its English counterpart yourself.

## Internationalization

`objectstack.config.ts` declares `defaultLocale: 'zh-CN'`, `supportedLocales: ['zh-CN', 'en']` and
`fallbackLocale: 'zh-CN'`, so the English path works — but it is far from complete:
`fallbackLocale: 'zh-CN'`. Both bundles carry **530 keys** and are generated by `pnpm i18n:extract`
(`os i18n extract --locales=zh-CN,en --fill=default`), with `pnpm verify` failing on a stale bundle.

| Bundle | Objects | Labels | Maintenance |
|---|---|---|---|
| `zh-CN` | 21 | 320 | Generated by `pnpm i18n:extract` from metadata labels; entries must not be hand-edited |
| `en` | 7 | 32 | Hand-maintained |
| Bundle | Keys | How the leaves are filled |
|---|---|---|
| `zh-CN` | 530 | Copied verbatim from the metadata labels — **never hand-edit** |
| `en` | 530 | Seeded from the Chinese source, then translated by hand |

**Covered in English:** object, field and picklist labels; object descriptions; list views; record
actions; app navigation; dashboard titles and widget titles; page titles.

**Not covered, and why:**

| Surface | Why | Where it lives |
|---|---|---|
| Dataset field labels (the captions under dashboard metrics) | Outside the extractor's scope | `src/datasets/index.ts` |
| Dashboard filter labels and their options | Outside the extractor's scope | `src/dashboards/index.ts` |
| Workbench page body copy and block headings | Page *component properties* are not extracted; only a page's label/title/subtitle are | `src/pages/index.ts` |
| The three-part error messages raised by hooks | Plain strings in code, not metadata | `src/hooks/*.ts` |
| The bundled demo dataset (org units, indicator names, units) | It is data, not copy | `src/data/*.ts` |

Anything the `en` bundle misses falls back to Chinese, so an English session today is mixed-language.
Beyond object and field labels, **view tabs, action labels, workbench page copy, dashboards, reports
and the three-part error messages raised in hooks have no English translation** — metadata labels are
authored in Chinese (`Field.number({ label: '实际值', … })`), and English exists only where the bundle
covers it.
The first three are platform extractor gaps rather than missing translations. Closing the last one
would mean an English demo seed profile alongside the existing two. Contributions welcome — please
raise an issue first so the scope can be agreed.

Bringing the English UI up to parity is a self-contained piece of work — regenerate the `en` skeleton
with `os i18n extract --locales=en`, translate the entries, then extend to views, pages and hook
messages. Contributions welcome; please raise an issue first so the scope can be agreed.
**Re-translating after a label change.** Merge only fills *gaps*: if you change a Chinese metadata
label, the matching English leaf already holds a translation, so it is left alone and silently goes
stale. Nothing warns you. Re-translate it by hand when you change the source.

## Documentation

Expand All @@ -237,6 +252,7 @@ All documents are in Simplified Chinese.
| [docs/手册/KPI考核管理系统-操作手册.md](docs/手册/KPI考核管理系统-操作手册.md) | Operations manual, one chapter per business role, with real UI screenshots. Word build via `pnpm docs:manual` |
| [docs/汇报/KPI考核管理系统-解决方案汇报.html](docs/汇报/KPI考核管理系统-解决方案汇报.html) | Solution briefing: nine diagrams covering the process, scoring, aggregation and permission model, plus 26 UI screenshots. Self-contained single file via `pnpm docs:report` |
| [scripts/build-report-deck.mjs](scripts/build-report-deck.mjs) | Generates a 19-slide briefing deck from the same material, with speaker notes. See the script header for usage and dependencies |
| [docs/readme/diagrams.en.html](docs/readme/diagrams.en.html) | Source for the two English diagrams above. Re-export by screenshotting each `figure` with a headless browser at 2× |
| [CLAUDE.md](CLAUDE.md) | Development conventions and delivery-process checklist |

## Contributing
Expand Down
Loading
Loading