Files
openmaic/OpenMAIC/packages/@openmaic/importer/SKILL.md
2026-08-16 14:58:47 +08:00

222 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SKILL
`maic-importer` 开发规范。请先读 `DESIGN.md` 了解架构。
## 还原质量迭代(必读)
项目根目录 [`iterate-prompt.md`](../../iterate-prompt.md) 规定如何从 `comparison_run` 拉低分、聚类、写报告。每批迭代交付:
- `iteration-<version>-report.md`(仓库根目录)
- 针对本包的解析侧修复(渲染问题在 `packages/@openmaic/renderer`)
**test-0601-002**(deck:`第一节 养老服务管理概述`)要点:
| 现象 | 侧 | 查哪里 |
|---|---|---|
| Logo 上多 5 个空心圆 | 解析 | `layoutElements` 里 master 组「组合 7」;子椭圆 `grpFill` 勿把父组 fill 摊到每个 child → `shapeSerializer.ts` |
| 照片应是圆却变方 | 解析 | `p:pic` + `custGeom` → `imageSerializer.resolvePresetGeom` |
| 画布四周边框 | 渲染 | `SlideCanvas` `chrome`(截图须 `false`) |
| 文字整体偏上 | 解析+渲染 | `bodyPr@anchor` → `vAlign` → `transformParsedToSlides` + `BaseTextElement` |
| 正文偏粗、换行少 | 解析+渲染 | `replaceFontFamilyInHtml` / 文本框 `width` |
调试时 **一定要看 `layoutElements`**,Logo/页脚/master 装饰常在这里,不在 `elements`。
```bash
# 仓库根:拉低分
node --env-file=.env.development scripts/inspect-low-scores.mjs test-0601-002
# 本包:JSON(含 layoutElements)
npx tsx scripts/transvert.ts /path/to.pptx ./out.json
node -e "const s=require('./out.json').slides[1]; console.log(s.layoutElements?.length, s.elements?.length)"
```
## 修 bug 的标准流程
```bash
# 1. 解压 pptx 看源 XML
node scripts/extract-pptx-structure.js ./xxx.pptx ./out
# 2. 生成修改前的 JSON
npx tsx scripts/transvert.ts ./xxx.pptx ./before.json
# 3. 改代码
# 4. 生成修改后的 JSON,diff 对比
npx tsx scripts/transvert.ts ./xxx.pptx ./after.json
```
定位思路:JSON 数值错 → serializer;节点类型错 → model/Slide.ts;颜色错 → StyleResolver + color.ts;模板继承错 → RenderContext.ts;**master/layout 装饰** → `slideSerializer` 的 `layoutElements` + `shapeSerializer` 的 `grpFill` / `ln`+`noFill` vs `lnRef`。
## OOXML 陷阱(本 deck 已踩)
1. **`<a:grpFill/>`**:子形状由组级合成,JSON 里每个 child 的 `fill` 应为 `transparent`,**不能**把 `grpSpPr` 的 solidFill 抄到每个椭圆上,也**不能**用 `fillRef` 补色(test-0601-002 的 5 个 Logo 圆点即此类)。
2. **`<a:ln><a:noFill/></a:ln>`**:显式无描边优先于 `lnRef`(见 `shapeSerializer` 中 `noFillSuppressed`)。
3. **`p:pic` 圆形裁剪**:常为 `custGeom` 而非 `prstGeom prst="ellipse"`;仅读 `prstGeom` 会得到 `rect`。
4. **分层顺序**:`layoutElements`(master+layout)先画,`elements`(slide)后画——与 `transformParsedToSlides` 一致。
## 代码规范
- **TypeScript strict**,不用 `@ts-ignore`,`any` 仅在必要时局部使用并加注释
- **注释解释"为什么"**,不解释"做了什么"
- **用已有工具**:单位用 `parser/units.ts`,XML 用 `SafeXmlNode`,颜色用 `utils/color.ts`
- commit message:中文,动词起头,点出修了什么
- 好:`fix(text): 修复 solidFill/gradFill 互斥覆盖导致渐变遮盖文字颜色`
- 坏:`fix bug` / `update`
- 一个 commit 只做一件事,重构和 bug 修复分开提
## 类型协议(重要)
`src/adapter/types.ts` 是与下游的 **协议**,修改需谨慎:
- **不改** 已有字段的名字或类型
- **不把** 可选字段改为必选
- **新增** 字段一律 `?:` 可选,附 JSDoc 说明
- 长度单位 pt,颜色 `#RRGGBB`,角度 deg
`model/*` 的内部类型可以自由重构,但保持"模型层不感知样式"原则。
## 分层红线
| 层 | 该做 | 不该做 |
|---|---|---|
| parser | 解压、XML 解析、单位换算 | 解析 OOXML 业务语义 |
| model | 解析几何与结构 | 解析视觉样式 |
| serializer | 模型 + 上下文 → JSON 元素 | 直接读 zip |
| adapter | 定义类型、组装输出 | 写业务逻辑 |
| shapes | 输出 SVG path | 决定填充/边框 |
| utils | 通用工具 | 引用业务类型 |
依赖方向:`adapter → serializer → model → parser`,**禁止反向**。
## 高风险文件
改这些文件前请格外注意:
**`groupSerializer.ts`** — chOff/chExt 缩放 + flip/rotation 烘焙。改前想清楚 `flipH+flipV → +180°` 等价规则。新增 child 特殊缩放规则时做 fast-path 短路。
**`shapeSerializer.ts`** — 800+ 行,承担 Shape/Text 判定、preset 路径、自适应、`grpFill`/`fillRef`/`lnRef` 互斥等。调整 Shape vs Text 判定前,先用 `src1` 跑同样的 .pptx 对比。
**`imageSerializer.ts`** — `resolvePresetGeom` 影响下游 `clip`;`custGeom` 与 `prstGeom` 都要覆盖。
**`presets.ts`** — 200+ preset 共享辅助函数,修一个前看调用方,避免误伤。
**`parser/units.ts`** — 被广泛依赖,**不要改现有函数签名**,需要新单位就加新函数。
## 注意事项
- `*.pptx`、`slides.json`、`out/`、`dist/` 已在 .gitignore 中,提交前 `git status` 确认不要带入
- `src1/` 是原版参考实现,**只读不改不构建**
- 改了 `adapter/types.ts` 需在 commit body 写明协议变更
- 改解析后应用**新 version** 重跑 compare,避免与旧批次 reply 混淆