260 lines
9.9 KiB
Markdown
260 lines
9.9 KiB
Markdown
# PikaOA 运行与交付
|
||
|
||
## 配置真相
|
||
|
||
- PikaOA 运维配置的唯一真相是 `config/pikaoa.yaml`。
|
||
- 稳定开发运行面由 `config/pikaoa.yaml#developmentRuntime.targets.NC01` 声明:
|
||
- source branch:`master`;
|
||
- consumer:`pikaoa-dev-nc01`;
|
||
- runtime namespace:`pikaoa-dev`;
|
||
- CI namespace:`pikaoa-ci`;
|
||
- GitOps branch:`nc01-pikaoa-dev-gitops`;
|
||
- Argo Application:`pikaoa-dev-nc01`;
|
||
- 公网入口:`https://oa-dev.hwpod.com`;
|
||
- NodePort:`32080`。
|
||
- 生产运行面由 `config/pikaoa.yaml#releaseRuntime.targets.NC01` 声明:
|
||
- source branch:`release`;
|
||
- consumer:`pikaoa-nc01`;
|
||
- runtime namespace:`pikaoa`;
|
||
- CI namespace:`pikaoa-ci`;
|
||
- GitOps branch:`nc01-pikaoa-gitops`;
|
||
- Argo Application:`pikaoa-nc01`;
|
||
- 公网入口:`https://oa.hwpod.com`;
|
||
- NodePort:`32096`。
|
||
- development 与 production 必须保持独立:
|
||
- PostgreSQL role/database;
|
||
- Kubernetes Secret;
|
||
- 附件 PVC;
|
||
- GitOps branch;
|
||
- Argo Application;
|
||
- namespace 与公网入口。
|
||
- 已退役路径不得恢复:
|
||
- `testRuntime`;
|
||
- `pikaoa-test` namespace;
|
||
- `pikaoa-test-nc01` consumer/Repository;
|
||
- `pikaoa test-target` CLI;
|
||
- 动态测试 namespace;
|
||
- namespace-local PostgreSQL。
|
||
|
||
## 对象与模块边界
|
||
|
||
- PikaOA 是可扩展企业办公平台:
|
||
- 模块通过 descriptor 注册;
|
||
- 模块拥有自己的 schema 初始化、HTTP route、outbox event 和 worker;
|
||
- 新模块复用 identity、附件、审计、可观测性和 API 错误合同。
|
||
- 业务对象均为平级 REST 资源:
|
||
- 伙伴、伙伴分类、合同、合同版本、发票和附件都使用服务端生成的 UUIDv7;
|
||
- 对象之间只保存 typed ID 关联;
|
||
- 不把伙伴、合同或发票建模为另一个对象的从属资源。
|
||
- 合同版本关系:
|
||
- 每个合同版本拥有独立全局 ID;
|
||
- `contractId`、`previousVersionId` 和当前版本投影建立版本链;
|
||
- 发票可分别关联合同 ID 与合同版本 ID。
|
||
- 首版审计与一致性:
|
||
- 跨模块关联未完成一致性核验时只返回 `blocking=false` warning;
|
||
- 完整身份/RBAC、严格审计门禁和强一致性校验不作为 MVP 上线前置。
|
||
|
||
## 数据库与 Secret
|
||
|
||
- development 与 production 都使用 NC01 host PostgreSQL:
|
||
- owning YAML:`config/platform-db/postgres-nc01.yaml`;
|
||
- development role/database:`pikaoa_dev`;
|
||
- production role/database:`pikaoa`;
|
||
- 业务 schema:`pikaoa`;
|
||
- development export:`platform-infra/pikaoa-dev.env`;
|
||
- production export:`platform-infra/pikaoa.env`。
|
||
- 不迁移旧 test 数据:
|
||
- development 使用全新 role/database;
|
||
- 旧 test 数据、namespace 和运行对象可直接丢弃;
|
||
- 不增加兼容、回填或双写路径。
|
||
- Secret 分发的唯一真相是 `config/secrets-distribution.yaml`:
|
||
- development scope:`pikaoa-dev`;
|
||
- development Secret:`pikaoa-dev-runtime`;
|
||
- production scope:`pikaoa`;
|
||
- production Secret:`pikaoa-runtime`。
|
||
- runtime Secret 只包含敏感键:
|
||
- `DATABASE_URL`;
|
||
- `PIKAOA_SESSION_SECRET`;
|
||
- `OA_ADMIN_TOKEN`;
|
||
- `PIKAOA_BOOTSTRAP_ADMIN_PASSWORD`;
|
||
- `PIKAOA_BOOTSTRAP_EMPLOYEE_PASSWORD`。
|
||
- 非敏感 `pikaoa.yaml` 由 `pikaoa-runtime-config` ConfigMap 提供:
|
||
- API、Worker 和 initializer 从 ConfigMap 挂载配置;
|
||
- `DATABASE_URL` 在应用校验前由环境变量覆盖空配置值;
|
||
- 禁止把 `pikaoa.yaml` 写入 runtime Secret。
|
||
- Secret 来源和运行面输出必须脱敏:
|
||
- 只披露 sourceRef、key、presence、fingerprint 和摘要;
|
||
- 禁止从 Kubernetes Secret、Pod 环境、日志或数据库反解值;
|
||
- 禁止在命令参数、issue、截图或报告中写入 token、密码或完整 DSN。
|
||
|
||
## 首次引导
|
||
|
||
- 首次创建 development 数据库与导出:
|
||
|
||
```bash
|
||
bun scripts/cli.ts platform-db postgres plan \
|
||
--config config/platform-db/postgres-nc01.yaml
|
||
bun scripts/cli.ts platform-db postgres apply \
|
||
--config config/platform-db/postgres-nc01.yaml \
|
||
--confirm --wait
|
||
bun scripts/cli.ts platform-db postgres export-secrets \
|
||
--config config/platform-db/postgres-nc01.yaml \
|
||
--confirm
|
||
```
|
||
|
||
- 首次同步 development Secret:
|
||
|
||
```bash
|
||
bun scripts/cli.ts secrets plan \
|
||
--config config/secrets-distribution.yaml \
|
||
--scope pikaoa-dev
|
||
bun scripts/cli.ts secrets sync \
|
||
--config config/secrets-distribution.yaml \
|
||
--scope pikaoa-dev \
|
||
--confirm
|
||
```
|
||
|
||
- PaC consumer 只在首次引导时执行 bootstrap:
|
||
|
||
```bash
|
||
bun scripts/cli.ts platform-infra pipelines-as-code bootstrap \
|
||
--target NC01 \
|
||
--consumer pikaoa-dev-nc01 \
|
||
--dry-run
|
||
bun scripts/cli.ts platform-infra pipelines-as-code bootstrap \
|
||
--target NC01 \
|
||
--consumer pikaoa-dev-nc01 \
|
||
--confirm
|
||
```
|
||
|
||
- bootstrap 完成后不得再次用于 source delivery、恢复或补跑。
|
||
- 旧 Repository CR 与新声明使用同一 URL 时:
|
||
- 先精确确认旧对象属于已退役 PikaOA test consumer;
|
||
- 只退役该旧对象;
|
||
- 立即由已合并 owning YAML 的 bootstrap 创建新对象;
|
||
- 禁止修改共享 PaC controller、admission 或其他 consumer。
|
||
|
||
## 自动交付
|
||
|
||
- development 和 production 都使用 PaC 自动交付:
|
||
- GitHub source PR merge;
|
||
- GitHub webhook;
|
||
- Gitea controlled mirror 与 immutable snapshot;
|
||
- PaC/Tekton;
|
||
- GitOps branch;
|
||
- Argo 自动同步;
|
||
- runtime readiness 与 `/healthz`。
|
||
- 正常交付的唯一触发:
|
||
- development:合并 `pikainc/pikaoa@master` PR;
|
||
- production:合并 `pikainc/pikaoa@release` PR。
|
||
- `.tekton` 制品必须由 UniDesk source-artifact renderer 生成:
|
||
|
||
```bash
|
||
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact write \
|
||
--target NC01 \
|
||
--consumer pikaoa-dev-nc01 \
|
||
--source-worktree <clean-pikaoa-worktree> \
|
||
--confirm --json
|
||
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact check \
|
||
--target NC01 \
|
||
--consumer pikaoa-dev-nc01 \
|
||
--source-worktree <clean-pikaoa-worktree> \
|
||
--json
|
||
```
|
||
|
||
- 自动链禁止人工补齐:
|
||
- 不人工创建 PipelineRun;
|
||
- 不人工 mirror sync;
|
||
- 不人工 Argo sync/refresh;
|
||
- 不在 source PR merge 后再次 bootstrap/apply。
|
||
- 自动链失败时:
|
||
- 使用 `platform-infra pipelines-as-code status|history|debug-step` 只读归因;
|
||
- consumer 私有缺陷回到 owning YAML、renderer 或 source artifact 修复;
|
||
- 共享 PaC/controller/admission 故障只报告,不在 PikaOA 任务中修改公共 CI/CD 基础设施。
|
||
|
||
## 公网入口
|
||
|
||
- 公网入口的聚合真相是 `config/platform-infra/public-edge.yaml#targets.NC01`。
|
||
- 产品 hostname、NodePort 和 health path 只从 `config/pikaoa.yaml` 的 configRef/path 解析。
|
||
- 受控入口:
|
||
|
||
```bash
|
||
bun scripts/cli.ts platform-infra public-edge plan --target NC01
|
||
bun scripts/cli.ts platform-infra public-edge apply --target NC01 --dry-run
|
||
bun scripts/cli.ts platform-infra public-edge status --target NC01
|
||
```
|
||
|
||
- 公网入口 mutation 只由 `master` merge 触发的唯一 PaC authority执行;PikaOA任务和 L1 会话不得执行 `apply --confirm`、内部 `reconcile` 或直接改写 Caddy。
|
||
|
||
- NC01 共享 edge 约束:
|
||
- 复用唯一 Caddy `80/443` listener;
|
||
- 不访问 PK01;
|
||
- 保留 UDP `443`;
|
||
- 单站探针失败只输出 `blocking=false` warning;
|
||
- 禁止为 PikaOA 启动第二个独立 `80/443` proxy。
|
||
|
||
## CLI-first 验收
|
||
|
||
- 所有业务功能先使用 PikaOA CLI 验收:
|
||
- CLI 只调用与 Web 相同的公开 HTTP API;
|
||
- development endpoint 使用 `https://oa-dev.hwpod.com`;
|
||
- production endpoint 使用 `https://oa.hwpod.com`;
|
||
- `OA_ADMIN_TOKEN` 只通过进程环境注入,不创建 session 文件;
|
||
- CLI 输出不得打印 token。
|
||
- 最小顺序:
|
||
- `health`;
|
||
- `health --ready`;
|
||
- `metrics`;
|
||
- `modules`;
|
||
- `whoami`;
|
||
- 员工与角色;
|
||
- 伙伴分类与伙伴;
|
||
- 合同 v1;
|
||
- 合同 v2 版本链;
|
||
- 发票关联与废弃;
|
||
- 附件与审计;
|
||
- 合同和发票 PDF `import-preview`。
|
||
- PDF import-preview 约束:
|
||
- 原 PDF 作为附件保留;
|
||
- 自动提取结果包含置信度与 `manualReviewRequired`;
|
||
- 用户可人工校对后再创建或更新业务对象;
|
||
- 提取 warning 不阻塞手工校对流程。
|
||
- CLI 通过后才进入 Web 验收:
|
||
- 只使用 `$unidesk-webdev` 的 `web-probe`;
|
||
- 禁止裸 Playwright;
|
||
- 验证管理员登录、合同/发票/PDF 校对主路径和移动视口。
|
||
|
||
## 可观测性
|
||
|
||
- OTel 从第一版启用:
|
||
- API、Worker 与 CLI 使用 OpenTelemetry;
|
||
- runtime endpoint 由 `config/pikaoa.yaml` 声明;
|
||
- exporter 失败只记录 `blocking=false` warning;
|
||
- trace 不记录 Secret、完整 DSN、PDF 内容或业务敏感字段。
|
||
- Prometheus 从第一版启用:
|
||
- API 与 Worker 使用 owning YAML 的 label selector 和 scrape annotation;
|
||
- API 与 Worker 都提供 `/metrics`;
|
||
- 重点核验数据库、迁移、HTTP、pgx pool、Worker 周期和业务模块指标。
|
||
- 受控验收入口:
|
||
- OTel/Tempo 使用 `$unidesk-otel`;
|
||
- Prometheus 与 Web 哨兵使用 `$unidesk-monitor`;
|
||
- 指标、trace 或版本一致性漂移不得改变业务 ready 终态。
|
||
|
||
## 退役与推广
|
||
|
||
- development 验收通过后退役旧 test 对象:
|
||
- `pikaoa-test` namespace;
|
||
- 旧 test Repository/Argo/GitOps 资源;
|
||
- 旧 test Secret source 与数据库 role/database;
|
||
- 旧 test CLI 状态目录。
|
||
- 退役必须精确限定旧 test 对象:
|
||
- 禁止删除 `pikaoa` production namespace;
|
||
- 禁止删除 `pikaoa-ci`;
|
||
- 禁止删除 `pikaoa-dev`;
|
||
- 禁止触碰其他 PaC consumer。
|
||
- production 推广:
|
||
- 先完成 development CLI/Web/OTel/Prometheus 验收;
|
||
- 再通过正常 `master -> release` PR 推广;
|
||
- `release` PR merge 是生产自动交付的唯一触发;
|
||
- 生产推广不复制 development 数据。
|