feat: store 镜像层(全字段镜像+部门关系+生命周期+一次性 token)

新增镜像存储层并保留旧台账过渡:
- MirrorUser/MirrorDepartment/MirrorUserDepartment/ResignConfirmToken 模型
- ReplaceMirror 单事务整体替换:用户/部门/关系一致更新,失败回滚保留旧版
- 生命周期状态机:active→leave_candidate→pending_confirm→confirmed_leave→deleted,
  非法转移结构性报错;快照只覆盖飞书事实不清洗状态
- 一次性离职确认 token:crypto/rand 生成、一次使用、过期作废、可批量 revoke
- 单测:事务回滚、状态机转移、token 一次/过期/复用被拒 全部通过
- docs/migration-baseline.md 记录阶段0基线字段
This commit is contained in:
2026-09-29 23:19:47 +08:00
parent 947b1a1475
commit 48b0ea35fc
4 changed files with 760 additions and 1 deletions
+45
View File
@@ -0,0 +1,45 @@
# 阶段 0:基线冻结记录
## 基线验证
- `make build`:通过(`bin/idsync` 编译成功)
- `make test`:全绿(config/mapping/password/server/syncer 有测试;feishu/ldaplib/store/webui 无测试)
## 迁移前 config 字段(`config.yml` / `config.example.yml`)
### system
`mode`(debug/release)、`data-dir`
### server
`listen`、`admin-user`、`admin-password`、`admin-password-hash`、`session-secret`、`secure-cookie`
### feishu
`app-id`、`app-secret`、`base-url`、`dept-list`、`qps`、`timeout-sec`
### ldap
`url`、`base-dn`、`admin-dn`、`admin-pass`、`user-ou`、`inactive-ou`、
`group-root-name`、`group-object-class`、`group-member-attr`、`timeout-sec`、
`start-tls`、`insecure-skip-verify`、`initial-password`
### database
`source`
### sync
`enable`、`schedule`、`default-dry-run`、`max-deactivate`、`max-deactivate-percent`
## 迁移后应删除的项目(阶段 5)
- `ldap.user-ou` / `ldap.inactive-ou` → 固定 `ou=people`
- `ldap.group-root-name` / `ldap.group-object-class` / `ldap.group-member-attr` → LLDAP 形态,不再需要
- `ldap.initial-password` → 密码 LLDAP 独占
- `sync.*` 单套 → 拆为两套 schedule(snapshot / sync)
## 迁移后应新增的项目(阶段 5)
- `ldap` 写通道:`base-url`、`admin-user`、`admin-pass`(供 GraphQL login)
- `feishu.webhook-url`(离职卡片自定义机器人)
- `server.confirm-base-url`(一次性确认端点对外 URL)
- 两套 `schedule.snapshot` / `schedule.sync`
## 迁移状态(AGENTS.md「迁移状态」节引用的旧实现)
- `internal/ldaplib/ops.go` 写路径(Add/Modify/ModifyDN)、`internal/password`(SSHA)、
旧 config 项 —— 迁移完成前不作目标行为
- `internal/store` 现为轻量台账(Account/Group/SyncRun),待扩展为全字段镜像 + 部门关系
- `internal/feishu` 尚无可卡发送能力,离职确认通道未落地