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
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# hotsrm 持续集成:元数据校验、lint、类型检查、翻译覆盖、启动测试,以及体系文件检查。
# 元数据错误在运行时是静默的,这里把 AGENTS.md §6 的验证项变成合入前必过的门槛。

name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
metadata:
name: Metadata
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
# pnpm 要在 setup-node 之前装好,`cache: pnpm` 需要它;版本取 package.json 的 packageManager。
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
with:
node-version: '22'
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm validate
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm i18n:check
- run: pnpm test
- run: pnpm build

governance:
name: Governance templates
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- run: pip install pyyaml
- run: python3 governance/scripts/build.py --check
- run: python3 governance/scripts/build.py --check --packs bulk,hazmat,soe
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 生成物
build/
__pycache__/
# ObjectStack
node_modules/
dist/
.objectstack/
*.log
.env
.env.*
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,5 @@ hotsrm 是基于 [ObjectStack](https://github.com/objectstack-ai/objectstack)
- 体系文件:`python3 governance/scripts/build.py --check` 与
`python3 governance/scripts/build.py --check --packs bulk,hazmat,soe` 都通过;改了模板的,
生成 Word 打开检查版式。
- 元数据(有代码之后):校验、类型检查、lint、构建、测试全部通过;每种扩展包组合都能构建。
- 元数据:`pnpm validate`、`pnpm lint`、`pnpm typecheck`、`pnpm i18n:check`、`pnpm test`、
`pnpm build` 全部通过(CI 同样跑这些);有扩展包之后,每种扩展包组合都能构建。
37 changes: 24 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,32 @@ hotsrm/
│ └── adr/ 决策记录
├── governance/ 体系文件模板与生成脚本
├── params/ 参数定义与示例默认值(制度与系统共用)
├── src/ 〔待建〕
├── src/
│ ├── core/ 核心(type: app)
│ ├── bulk/ hazmat/ soe/ 三个扩展包(type: module)
│ └── bridges/ 扩展包之间的联动(type: module)
├── test/ 门户隔离、封标、组合构建、flow 测试 〔待建〕
├── objectstack.composition.ts 按开关选出要组合的模块 〔待建〕
├── objectstack.config.ts 合成一个发布制品 〔待建〕
└── objectstack.manifest.json 标准版的应用标识 〔待建〕
│ ├── bulk/ hazmat/ soe/ 三个扩展包(type: module) 〔待建〕
│ └── bridges/ 扩展包之间的联动(type: module) 〔待建〕
├── test/ 启动测试;门户隔离、封标、组合构建、flow 测试随功能补齐
├── objectstack.composition.ts 按开关选出要组合的模块
├── objectstack.config.ts 合成一个发布制品
└── objectstack.manifest.json 标准版的应用标识(市场展示信息)
```

## 当前状态
## 本地开发

需要 Node 22 和 pnpm 10。

```bash
pnpm install
pnpm dev # 本地启动(内存库)
pnpm validate # 每次改元数据后跑;其余检查见 AGENTS.md §6
```

定时 flow(证书到期扫描)受部署开关 `OS_AUTOMATION_SCHEDULED_WORK_ENABLED` 控制,平台默认关闭,本地和
托管云都要显式打开才会运行;托管云上如何为本应用打开,待与平台确认。

设计阶段:核心设计、三个扩展包设计、第一批决策记录、参数文件首版、体系文件生成脚本和
第一份模板(QP-01)已完成。文档目录见
[docs/README.md](./docs/README.md);参与开发前先读 [AGENTS.md](./AGENTS.md)。
## 当前状态

下一步:补齐第一批体系文件模板,然后按[核心设计第一期](./docs/design/07-delivery-plan.md)
实现应用包。
v0.1 开发中:工程骨架、CI 和核心应用外壳(`srm_workbench` 工作台、采购品类)已就位。
建议的 v0.1 范围是内部工作台上的供应商主数据、准入审批和资质到期预警,门户、寻源和 ERP 集成
放在后续版本。设计文档目录见 [docs/README.md](./docs/README.md);参与开发前先读
[AGENTS.md](./AGENTS.md)。
7 changes: 6 additions & 1 deletion docs/design/02-domain-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ erDiagram
| 字段 | 类型 | 说明 |
|---|---|---|
| `name` | text | 必填 |
| `contact_role` | multiselect | `admin` 主账号 / `sales` 商务 / `logistics` 物流 / `quality` 质量 / `finance` 财务 |
| `contact_function` | multiselect | `admin` 主账号 / `sales` 商务 / `logistics` 物流 / `quality` 质量 / `finance` 财务 |
| `mobile` / `email` | phone / email | email 必填(门户邀请与通知用) |
| `portal_user` | user | 已开通门户账号时关联的平台用户;该用户同时被任命到供应商的门户岗位(见 [04 §3](./04-security-and-portal.md#3-供应商门户的数据隔离)) |
| `is_primary` | boolean | 默认 false;每家供应商至多一位主联系人(校验规则) |
Expand Down Expand Up @@ -276,6 +276,11 @@ erDiagram
| `reject_reason` | textarea | |
| `cycle_days` | number | 从提交到批准的天数,批准时由 flow 写入(准入周期指标) |

> v0.1(内部代录,见 [07 §1.1](./07-delivery-plan.md#11-第一期的拆分))先实现一个子集:申请由内部人员为已登记的
> 潜在或淘汰供应商发起,直接关联 `supplier`;申请品类用多值 lookup `applied_categories`(不经匿名表单,
> 可以读品类对象);不含现场审核分支和公司资料等表单字段;`approval_status` 记录审批节点的结论。
> 公开表单与门户随 v0.2 加入时再补齐本表其余字段。

**`srm_supplier_audit` 供应商审核**(OWD `private`):`audit_no`、`supplier`
(lookup)、`application`(lookup,可空)、`audit_type`(`admission` 准入 / `annual`
年度 / `special` 专项)、`audit_date`、`auditors`(user,多选)、`checklist_score`
Expand Down
5 changes: 5 additions & 0 deletions docs/design/03-processes-and-automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,11 @@ stateDiagram-v2
| 资质恢复 | 证书写入后的记录触发 | 重新计算:每一种必备资质类型都有 `status == 'valid'` 且 `verified == true` 的证书时,`qualification_alert = false`(四期起关闭对应风险事件)。只上传新证书而未经 SQE 核验,不会解除异常 |
| 外部风险 | `schedule`:每周一 04:00(四期) | flow 按批 `loop` 合格供应商,`http` 节点调用企业信息服务;新出现的经营异常、失信、重大诉讼、股权变更按 `external_ref` 去重后建风险事件,`high` 级通知品类经理(FR-903) |

> v0.1 先实现其中的一部分:`srm_certificate_expire_sweep` 每日一次,把证书状态对齐到已过期 / 即将到期(30 天内)/
> 有效(有效期被延长时恢复);`srm_supplier_qualification_recalc` 在证书状态或「必备」标志变化后重算
> `qualification_alert`。到期提醒通知、`is_mandatory` 按品类必备资质自动写入、「经 SQE 核验才解除」随门户版本
> (v0.2)加入;v0.1 由内部人员维护证书与「必备」标志。

## 12. 审批矩阵

审批人一律按**岗位**或**记录上的人员字段**解析,不写死具体的人;换人只改岗位任命,
Expand Down
11 changes: 11 additions & 0 deletions docs/design/07-delivery-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ gantt
第一期试运行(2 个品类) :after p1, 4w
```

### 1.1 第一期的拆分

第一期按可独立验收的小版本推进,每个版本一个次版本号。按 2026-10-23 的产品决定(面向已有 ERP 的大型企业,只做基础核心包,暂不集成 ERP),v0.3 完成即为当前第一期的终点:

| 版本 | 范围 | 随版本落地的红线测试 |
|---|---|---|
| v0.1 | 内部工作台:品类、工厂、供应商及联系人 / 证书 / 供货品类资格、准入申请与两级审批、资质到期扫描;由内部人员代录 | — (无面向供应商的对象,无报价) |
| v0.2 | 供应商门户:门户岗位与 RLS、公开注册表单、门户补录、供应商审核 | 04 §3.7 隔离测试 |
| v0.3 | 寻源:寻源单 / 明细 / 邀请、报价、开标、比价矩阵、定标审批、价格库 | 封标测试 |
| 暂缓 | ERP 集成 I1–I6、物料、银行账户:等客户需要时再排期;银行与付款始终留在 ERP | — |

**上线策略**:第一期先选 **2 个品类、20–30 家供应商**试运行 4 周,跑通准入与至少 5 张
询价单后再全面推广;推广按品类分批,而不是按工厂。

Expand Down
6 changes: 6 additions & 0 deletions objectstack.composition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import core from './src/core/index.js';

// 选出要合成进制品的模块(ADR-0002)。目前只有核心;扩展包落地后在这里按开关加入,
// 两个扩展包同时选中时带上对应的桥接模块。
// objectstack.config.ts 不能有具名导出(构建按严格的 stack schema 解析它),所以选择逻辑放在这里。
export const stacks = [core];
5 changes: 5 additions & 0 deletions objectstack.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { composeStacks } from '@objectstack/spec';
import { stacks } from './objectstack.composition.js';

// 把选中的模块合成一个发布制品(ADR-0002);`preserve` 保留每个包各自的身份。
export default composeStacks(stacks, { manifest: 'preserve' });
24 changes: 24 additions & 0 deletions objectstack.manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
"name": "hotsrm",
"specVersion": "^18.0.0",
"engines": {
"protocol": "^18.0.0"
},
"manifestId": "app.objectstack.hotsrm",
"displayName": "hotsrm",
"description": "供应商关系管理(SRM):供应商全生命周期、寻源定价、订单协同、质量、绩效、对账与供应商门户。",
"tagline": "基于 ObjectStack 的供应商关系管理。",
"category": "srm",
"isStarter": false,
"publisher": "objectstack",
"homepageUrl": "https://github.com/objectstack-ai/hotsrm",
"tags": ["srm", "procurement", "supplier", "sourcing"],
"skills": [
"objectstack-platform",
"objectstack-data",
"objectstack-ui",
"objectstack-automation"
],
"readmePath": "README.md"
}
32 changes: 32 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "hotsrm",
"version": "0.1.0",
"private": true,
"type": "module",
"engines": {
"pnpm": ">=10.15"
},
"scripts": {
"dev": "objectstack dev",
"start": "objectstack start",
"build": "objectstack build",
"validate": "objectstack validate",
"lint": "objectstack lint --strict",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"i18n:check": "objectstack i18n check --strict",
"verify": "pnpm validate && pnpm lint && pnpm typecheck && pnpm i18n:check && pnpm test && pnpm build"
},
"dependencies": {
"@objectstack/runtime": "18.0.0",
"@objectstack/spec": "18.0.0"
},
"devDependencies": {
"@objectstack/cli": "18.0.0",
"@objectstack/skills": "18.0.0",
"@objectstack/verify": "18.0.0",
"typescript": "^5.3.0",
"vitest": "~4.0.0"
},
"packageManager": "pnpm@10.28.0"
}
Loading
Loading