# MEMORY.md ## 2026-03-17 - GAIA_BL01 部署错误修复(更新) ### 遇到什么问题 - 用户点击部署时,如果存在未修改的文件(status: "unchanged"),会报错:`[404] [GAIA_BL01] 指定したファイル(id: XXXXX)が見つかりません。` - **之前分析不够准确**:原匹配逻辑只用文件名匹配,如果存在同名文件会匹配到错误的 fileKey ### 根本原因(更正) 1. **匹配逻辑缺陷**:只用文件名匹配,同名文件会返回第一个匹配的错误 fileKey 2. **类型守卫过于严格**:`isFileResource()` 要求 `fileKey` 存在才返回 true,可能导致有效文件被跳过 3. Kintone Customization API 的正确用法: - 从 `Get Customization` 获取的 fileKey 是实时有效的 - 只要文件附加到 Customization,fileKey 就永久有效 - 参考:https://docs-customine.gusuku.io/en/error/gaia_bl01/ ### 如何解决的 修改 `src/main/ipc-handlers.ts` 中的匹配逻辑: 1. **新增 `isFileType()` 类型守卫**:只检查 `type === "FILE"`,不要求 `fileKey` 存在 2. **实现三级匹配策略**: - 优先级 1:用前端传来的 `fileKey` 精确匹配(最可靠) - 优先级 2:用 URL 精确匹配(针对 URL 类型) - 优先级 3:用文件名匹配(fallback,同名文件可能出错) 3. 添加详细调试日志和验证检查 ```typescript // 新增类型守卫 function isFileType(resource): boolean { return resource.type === "FILE" && !!resource.file; } // 三级匹配策略 if (file.fileKey) { matchingFile = currentFiles?.find( (f) => isFileType(f) && f.file.fileKey === file.fileKey, ); } if (!matchingFile && file.url) { matchingFile = currentFiles?.find( (f) => isUrlResource(f) && f.url === file.url, ); } if (!matchingFile) { matchingFile = currentFiles?.find( (f) => isFileType(f) && f.file.name === file.fileName, ); } ``` ### 以后如何避免 1. **匹配逻辑优先使用唯一标识符**:不要只用名称匹配,优先使用 ID、key 等唯一标识 2. **类型守卫要区分"类型检查"和"有效性验证"**: - 类型检查:`type === "FILE"` - 有效性验证:`fileKey` 是否存在 - 这两个应该分开处理 3. **Kintone fileKey 的生命周期**: - 用于 Customization:永久有效(只要附加到 App) - 用于记录附件:3 天内必须使用 4. **添加调试日志**:在复杂的匹配逻辑中添加调试日志,便于排查问题 --- ## 2026-03-17 - GAIA_BL01 部署错误修复(初始记录 - 已过时) ### 遇到什么问题 - 用户点击部署时,如果存在未修改的文件(status: "unchanged"),会报错:`[404] [GAIA_BL01] 指定したファイル(id: XXXXX)が見つかりません。` - 根本原因:Kintone 的 `fileKey` 有两种类型: - **临时 fileKey**:Upload File API 生成,3天有效,**使用一次后失效** - **永久 fileKey**:文件附加到记录时,永久有效 - 部署时 `getAppCustomize` 返回的 fileKey 是临时的,部署后就被消费 - 再次部署时使用已失效的 fileKey 就会报 GAIA_BL01 错误 ### 如何解决的 修改 `src/main/ipc-handlers.ts` 中的 `registerDeploy` 函数: 1. 对于 "unchanged" 文件,不再使用前端传递的 `file.fileKey` 2. 改为从当前 Kintone 配置(`appDetail.customization`)中根据文件名匹配获取最新的 fileKey 3. 如果在当前配置中找不到该文件,抛出明确的错误提示用户刷新 ### 以后如何避免 - Kintone API 返回的 fileKey 是临时的,每次部署后都会失效 - 部署时必须从当前 Kintone 配置获取最新的 fileKey,而不是使用缓存的值 - 参考:https://docs-customine.gusuku.io/en/error/gaia_bl01/ --- # MEMORY.md ## 2026-03-15 - CSS 模板字符串语法错误 ### 遇到什么问题 - 在使用 `edit` 工具修改 `DomainForm.tsx` 中的 CSS 样式时,只替换了部分内容,导致 CSS 模板字符串语法错误 - 错误信息:`Unexpected token, expected ","` 在 `passwordHint` 定义处 - 原因:`.ant-form-item` 的 CSS 块没有正确关闭,缺少 `}` 和模板字符串结束符 `` ` `` ### 如何解决的 - 使用 `edit` 工具完整替换整个 `useStyles` 定义块,确保所有 CSS 模板字符串正确关闭 ### 以后如何避免 - 修改 CSS-in-JS 样式时,尽量替换完整的样式块而非单行 - 修改后立即运行 `npx tsc --noEmit` 验证语法 - 注意模板字符串的开始 `` ` `` 和结束 `` ` `` 必须成对出现 --- ## 2026-03-15 - UI 重构经验 ### 变更内容 1. **DomainForm 表单间距**:`marginMD` → `marginSM` 2. **AppDetail 头部布局**:标题和按钮同一行(flex 布局) 3. **AppDetail Tabs 重构**: - 移除 Tabs 组件 - 移除 "基本信息" tab - 合并 4 个 JS/CSS tab 为单页面(选项 A:单列滚动列表 + 分区标题) - 新增 `viewMode` 状态管理列表/代码视图切换 - 点击文件进入代码视图,带返回按钮 ### 文件修改 - `src/renderer/src/components/DomainManager/DomainForm.tsx` - `src/renderer/src/components/AppDetail/AppDetail.tsx` - `src/renderer/src/locales/zh-CN/app.json` - 添加 `backToList` - `src/renderer/src/locales/en-US/app.json` - 添加 `backToList` - `src/renderer/src/locales/ja-JP/app.json` - 添加 `backToList`