Skip to content

feat(core): let suppliers maintain their profile in the portal (v0.6 U4) - #90

Merged
marchtian merged 3 commits into
mainfrom
claude/project-thread-gpx06r
Nov 2, 2026
Merged

marchtian merged 3 commits into
mainfrom
claude/project-thread-gpx06r

Conversation

@marchtian

@marchtian marchtian commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Requested by 田騏 · project thread

Closes #80(v0.6 U4:门户应用与资料自助)。基于 #88 的方案 B(成员键,ADR-0010)。

改了什么

门户导航:平台规定一个应用包只能有一个应用(objectstack ADR-0019 D3,os validate 拒绝第二个应用),所以门户不是独立的 srm_portal 应用,而是 srm_workbench 里的「供应商门户」导航组,只对持新能力 srm_portal_access(srm_portal_supplier 授予)的用户显示。首页 = 待办列表(待我处理的整改单 / 即将到期的证书 / 准入申请进度 / 最新绩效),其余分组按 05 §1.2。05 §1、设计 README、07 §3.1 已同步。导航只是体验,边界仍是门户 RLS。

证书(03 §11)

  • 门户可增可改证书(srm_portal_supplier 放开 allowEdit,子对象跟随主记录)。
  • srm_certificate_change_check(新):证书新建或改了类型 / 编号 / 发证机构 / 有效期 / 扫描件时,按 updated_by 是否持 srm_portal_user 区分:门户改动 → verified=false、清空核验人、通知品类 SQE(没有时通知质量经理);内部或系统写入 → 录入即核验。
  • srm_certificate_verify(新 screen flow + 按钮):SQE / 质量经理核验未核验、未过期的证书,写 verified_by。
  • verified 改为对象级只读,新增 verified_by(user,只读)。
  • srm_supplier_qualification_recalc 改为按类型判断:同类型有未过期且已核验的证书算「顶得住」;有过期必备证书顶不住 → 标记;每张过期或未核验的必备证书都顶得住 → 解除;两样都不满足就保持原值。所以门户上传新证书、把过期证书的有效期改长、把别的证书改类型来顶替,在核验前都解不了异常;门户改一张有效证书也不会新标异常。触发条件加了 verified 变化。

变更单(03 §5)

  • srm_change_submit(新 screen flow,供应商档案上的「提交变更申请」按钮,需持 srm_portal_manage):以系统身份运行,进门检查启动人持 srm_portal_admin,并且是这家供应商在职联系人上登记的门户账号(同一份名册);按类型代建变更单,发起人是门户管理员本人,之后沿用 v0.2 的审批与写回。
  • 退回修改:srm_portal_admin 对变更单 allowEdit,并加写 RLS srm_portal_change_request_revise(using:本公司且 approval_status == 'returned',check:本公司)。external 对 private 对象只能改自己拥有的行,所以只能改自己发起的单。

准入申请(03 §3 第 4 步):srm_application_resubmit(新 screen flow,需持 srm_portal_access)把「退回补充」的申请连同补充说明(新字段 supplement_note,只读)送回「资料审核」,并通知初审人。会按名册检查启动人属于这张申请的供应商。门户对申请仍只有读。

银行账户:门户管理员新建已在 U2 实现。本 PR 新增 srm_bank_pending_notice:新账户为「待核验」时通知应付会计,通知里不含账号。核验仍走 srm_bank_verify(双人原则)。

联系人:门户管理员可增可改,U2 已实现,这里补了测试。

隔离(红线 2)

  • 没有新增面向供应商的顶层对象。新增的写路径只有子对象(证书)和带 check 的写 RLS(变更单),都读成员键,元数据守卫测试照常通过。
  • portal-isolation.test.ts 新增用例「refuses the self-service write paths across suppliers」,覆盖:改别家的证书、联系人、变更单;把证书改挂到别家;在别家名下建银行账户;伪造 recordId 启动「提交变更申请」和「补充完成,重新提交」,按钮和直接触发两个入口都试;门户身份启动「核验证书」。全部被拒,别家记录不变。原「自解资质异常」用例改为断言改有效期会复位 verified。
  • 合并 feat(core): portal SCAR reply, claim confirmation and performance appeal (v0.6 U5) #91 后:两条新 flow 的名册检查改名为 load_membership / membership,加进 feat(core): portal SCAR reply, claim confirmation and performance appeal (v0.6 U5) #91 的元数据守卫(名册条件与成员键一致,gate 的每条边都经过它)。
  • 04 §3.2、§3.7、§4.2 已同步。

其他测试改动

  • 新增 test/portal-self-service.test.ts,共 10 例,对应 issue 的两个出口条件:X 在门户补证书,SQE 核验后资质异常解除;门户提交的基本信息变更、银行账户变更经审批写回。另含退回修改后重提、拒绝普通门户用户 / 内部人员 / 伪造供应商、准入退回补充后重提、门户新建银行账户由应付会计核验、联系人维护。
  • qualification.test.ts:「另一张必备证书仍过期」改成用另一种资质类型(按类型判断是 03 §11 的口径),并新增「同类型补一张已核验的证书即解除」。
  • portal-platform.test.ts(U1 探针):verified 现在由 flow 维护,探针岗位按内部写入处理,所以断言改为「被拒的写入没有改动它」。

需要注意

  • 存量证书的 verified 是 false。规则不会因此新标异常,但已有异常的供应商,要等它的必备证书都被 SQE 核验(或经内部修改自动核验)才会解除。门槛 2 之前不需要迁移说明;试运行环境升级后,可由 SQE 对存量证书点「核验证书」。
  • 门户管理员能改本公司联系人的全部字段,包括 contact_function。U3 的「开通门户」按 admin 职能授予门户管理员,但那一步由组织管理员操作,影响也只在同一家供应商内,所以这次没有锁这个字段。
  • 平台限制:直接触发 flow(REST trigger)不像按钮入口那样先按启动人的权限读 recordId。在 18.1.0 上实测:去掉 flow 内检查后,按钮对别家记录答「不存在」,直接触发却会在屏幕上显示别家公司名,并能在别家名下建变更单。已提 objectstack#29050,登记为 07 §6.3 PF18。在平台修复前,名册检查留在 flow 里。谁可以启动仍是 objectstack#25481。

验证

本地 pnpm validate、pnpm lint、pnpm typecheck、pnpm i18n:check、pnpm build 通过;pnpm test 28 个文件全部通过(1 个文件为既有的 skip)。CI(Metadata、Governance templates)在 5fdb39c 上全绿。


Generated by Claude Code

- Portal navigation group in srm_workbench, shown only with the new
  srm_portal_access capability (one app per package, objectstack ADR-0019 D3);
  home lists open corrective actions, expiring certificates, admission
  progress and latest performance.
- Certificates: the portal can add and edit; srm_certificate_change_check
  resets `verified` and notifies the SQE on portal edits, internal entry
  counts as verified. srm_certificate_verify lets the SQE / quality manager
  verify. The qualification recalc now only accepts verified, unexpired
  certificates of the same type and keeps the alert until verification.
- Change requests: srm_change_submit lets the portal admin submit key-info
  changes (roster-checked); a returned request can be revised by the portal
  admin through an update RLS limited to own supplier and returned requests.
- Applications returned for supplement: srm_application_resubmit writes
  the supplement note and returns the application to document review.
- New bank accounts in pending verification notify the AP accountants.
- Isolation test covers the new write paths; new portal-self-service test.

Closes #80

Claude-Session: https://claude.ai/code/session_017ihL2eFDUqnMy95b1fqMKJ
Co-authored-by: Claude <noreply@anthropic.com>
@marchtian marchtian self-assigned this Nov 2, 2026
srm_change_submit and srm_application_resubmit now name their roster check
load_membership / membership, so the metadata guard from #91 covers them too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2eFDUqnMy95b1fqMKJ
The trigger door does not read recordId in the caller's scope, unlike the
action door; filed upstream and registered as PF18.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ihL2eFDUqnMy95b1fqMKJ
@marchtian
marchtian merged commit 7ca2cb5 into main Nov 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v0.6 U4:门户应用 srm_portal 与资料自助

2 participants