ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Actual 26.3.0 版本解析:同步服务器安全修复、Tags API、命令栏报表与 React Query 性能迁移

Actual 26.3.0 版本解析:同步服务器安全修复、Tags API、命令栏报表与 React Query 性能迁移 Actual 26.3.0 版本解析同步服务器安全修复、Tags API、命令栏报表与 React Query 性能迁移【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual本文基于 Actual 开源仓库 v26.3.0 发布说明 编写并结合仓库源码API 层、loot-core 服务端、测试用例对各项变更进行深度解读帮助读者理解本次版本更新的安全优先级、新能力与底层实现。Actual 26.3.0 是一次以安全优先、体验提质、性能筑基为基调的例行版本更新。本次版本包含一个面向所有同步服务器sync server用户的重要安全修复官方建议尽快升级同时为用户带来命令栏直达报表、银行同步账户关联体验改进、Tags 标签管理 API、自定义主题体系简化等多项新特性并持续推进从 Redux 到 React Query 的大规模状态管理层迁移。本文将从升级说明、安全修复、Tags API、报表入口、银行同步、主题体系、性能迁移等多个维度逐项解析 v26.3.0 的变更内容并给出对应的源码路径与测试证据方便开发者按图索骥、深入验证。版本信息与升级建议发布说明开篇即点明本次更新的核心优先级This release contains an important security fix for all users of the sync server. We suggest you update as soon as feasible.Docker Tag26.3.0Versionv26.3.0发布形式月度例行版本对应仓库 packages/docs/blog 下的 release 系列文档如果你通过 Docker 部署同步服务器直接拉取26.3.0标签的镜像即可完成升级桌面端用户则等待各平台Windows/macOS/Linux/Flathub构建产物发布。由于涉及安全修复升级优先级应高于普通功能版本。同步服务器安全修复与基础设施修复v26.3.0 是少数在发布说明开头就明确标注重要安全修复的版本。结合仓库源码本次与同步服务器健壮性直接相关的修复包括校验文件 ID 的正确性PR #7067文件 IDfileId是同步服务器区分不同预算文件的标识。此前未对传入的 file ID 做格式校验存在被构造畸形 ID 干扰服务器逻辑的风险本次更新补充了正确性校验从源头拦截非法输入。阻止单斜杠路径被解析为文件路径PR #6966同步服务器在解析请求路径时/这类单斜杠路径此前可能被误当作文件路径处理导致路径解析行为异常。修复后此类路径不再被错误解析。同步服务器迁移改用 ESM loaderPR #6346同步服务器在启动时执行数据库迁移脚本此前在部分运行环境下迁移加载方式有兼容性问题本次统一改为 ESM loader保证迁移可靠执行。修复 Windows 上运行服务器迁移失败的问题PR #7076迁移脚本在 Windows 平台的文件处理路径上存在缺陷本次修复后跨平台部署一致性得到保障。此外发布说明还提到若干非安全类基础设施修复send函数现在会正确传播错误catchErrors在浏览器服务器收到未知命令/方法时会把错误写入结果PR #6942预算切换时 React Query 缓存未清空的问题得到修复PR #6953。从源码结构看同步服务器的安全与迁移逻辑集中在 packages/sync-server 目录如app-sync.ts、migrations.ts、app.ts上述修复正是围绕该服务端的请求处理与迁移链路展开。Tags 标签管理 API四个方法的完整链路v26.3.0 为 API 新增了完整的标签管理能力PR #6746对外暴露getTags、createTag、updateTag、deleteTag四个方法。这是本次版本中可编程能力提升最显著的一块也是 API 使用者可以直接上手的新能力。客户端 API 层方法签名在 packages/api/methods.ts 中四个方法通过send命令映射到服务端 handlerexport function getTags() { return send(api/tags-get); } export function createTag(tag: OmitAPITagEntity, id) { return send(api/tag-create, { tag }); } export function updateTag( id: APITagEntity[id], fields: PartialOmitAPITagEntity, id, ) { return send(api/tag-update, { id, fields }); } export function deleteTag(id: APITagEntity[id]) { return send(api/tag-delete, { id }); }对应实体类型定义在 packages/loot-core/src/server/api-models.tsexport type APITagEntity Pick TagEntity, id | tag | color | description ; export const tagModel { toExternal(tag: TagEntity): APITagEntity { return { id: tag.id, tag: tag.tag, color: tag.color ?? null, description: tag.description ?? null, }; }, fromExternal(tag: PartialAPITagEntity): PartialTagEntity { return tag; }, };可见标签实体的四个对外字段为id标签 ID、tag标签名称、color颜色可为null、description描述可为null。toExternal会把内部模型中的可选字段统一归一化为null保证 API 输出的字段类型稳定。服务端 Handler 层命令路由与事务包装在 packages/loot-core/src/server/api.ts 中四个api/tags-*命令完成参数校验checkFileOpen后转发给标签应用层handlers[api/tags-get] async function () { checkFileOpen(); const tags await handlers[tags-get](); return tags.map(tag tagModel.toExternal(tag)); }; handlers[api/tag-create] withMutation(async function ({ tag }) { checkFileOpen(); const result await handlerstags-create; return result.id; }); handlers[api/tag-update] withMutation(async function ({ id, fields }) { checkFileOpen(); await handlerstags-update }); }); handlers[api/tag-delete] withMutation(async function ({ id }) { checkFileOpen(); await handlerstags-delete; });写操作create/update/delete统一由withMutation包装纳入同步变更流对应 loot-core 的 mutation 机制保证本地与云端数据一致性。标签应用层排序、去重与幂等标签的真正业务逻辑在 packages/loot-core/src/server/tags/app.ts该文件定义了完整的TagsHandlers包括tags-get、tags-create、tags-update、tags-delete以及内部使用的tags-rename、tags-discover、tags-hide-all等export type TagsHandlers { tags-get: typeof getTags; tags-create: typeof createTag; tags-delete: typeof deleteTag; tags-delete-all: typeof deleteAllTags; tags-hide-all: typeof hideAllTags; tags-unhide-all: typeof unhideAllTags; tags-update: typeof updateTag; tags-rename: typeof renameTag; tags-discover: typeof discoverTags; };值得注意的实现细节排序getTags使用Intl.Collatornumeric: true, sensitivity: base对标签按名称做自然排序数字与字母混合的标签名能按直觉排列。幂等创建createTag会先查询同名字标签若已存在同名标签则复用其 ID返回已有id避免重复创建。同步与撤销写操作经mutator(undoable(...))包装既进入同步消息流又支持撤销操作与 UI 中的标签编辑体验保持一致。测试用例可直接运行的验证示例API 测试位于 packages/api/methods.test.ts覆盖了完整的生命周期可直接作为使用范例// 创建标签 const tagId1 await api.createTag({ tag: test-tag1, color: #ff0000 }); const tagId2 await api.createTag({ tag: test-tag2, description: A test tag, }); // 查询标签 let tags await api.getTags(); // 更新标签可只更新单个字段其余保持不变 await api.updateTag(tagId1, { tag: updated-tag, color: #00ff00 }); // 删除标签 await api.deleteTag(tagId2);测试还专门验证了三种边界行为对实际调用很有参考价值最小字段createTag({ tag: minimal-tag })时color与description自动落为null单字段更新只传{ color }时tag与description保持原值置空字段updateTag(id, { color: null })、updateTag(id, { description: null })可显式清空可选字段。综合来看Tags API 打通了「客户端方法 →api/*handler → tags 应用层 → 数据库」的完整链路且与 UI 内建功能共用同一套服务端逻辑行为一致、可放心自动化使用。报表命令栏直达与配置页返回按钮v26.3.0 让报表Reports模块的触达路径更短报表接入命令栏PR #7002此前命令栏Command Bar主要用于快速跳转账户、预算页面现在输入报表名称即可在命令栏中直接打开对应报表。对于报表数量较多、习惯键盘操作的用户这显著减少了进入报表页再逐一点击的路径。报表配置页新增返回按钮PR #6702进入报表配置/编辑页面后现在可以一键返回报表列表避免多级页面的回退死角。从源码结构看命令栏相关逻辑位于 packages/desktop-client/src/components/command-bar报表模块则集中在 packages/desktop-client/src/components/reports。开发者可在这些目录中查看命令项注册与报表配置页的导航实现。配套的报表修复还包括报表卡片 tooltip 不再被相邻 widget 遮挡PR #6849净值报表第一个月净财富变化值计算修正PR #6968卡片视图下预算分析报表的日期范围计算修正PR #6875预算分析报表实验标志的反馈链接修正PR #6914。银行同步Bank Sync关联流程体验与 API 能力升级银行同步是本版本改进最密集的模块之一涵盖 UX 与 API 两个层面关联新账户时可指定自定义起始日期与余额PR #6629 允许用户在链接新的银行同步账户时指定自定义的起始日期starting date与起始余额balance。这对于银行历史数据不全或希望从某个时点开始记账的用户非常实用避免了默认起始点与实际记账需求不符的问题。账户 API 支持设置balance_currentPR #6915 让账户AccountAPI 支持写入balance_current字段。此前自定义导入器custom importers无法通过 API 同步当前余额导致对账时余额不可见现在自定义导入器可以在导入交易的同时写入当前余额直接服务于对账场景。发布说明明确描述了这一用途The Account API now allowsbalance_currentto be set, making balances visible for reconciliation when using custom importers.可配置是否用银行日期覆盖本地日期PR #6850 新增银行同步选项允许用银行提供的日期覆盖本地记录的日期。某些银行导入的日期与本地记录存在差异时用户可自行决定是否信任银行值。关联流程 UX 改进发布说明还提到账户关联流程的 UX 改进account linking flow结合相关变更本次银行同步的整体交互一致性得到增强。银行同步的服务端逻辑主要位于 packages/sync-server/src/app-gocardless、app-enablebanking 等目录账户相关 API 定义则在 packages/loot-core/src/server/accounts 与 packages/api 中可对照查看balance_current的读写链路。自定义主题图表变量、简化 CSS 与高对比度浅色主题v26.3.0 对自定义主题Custom Themes体系做了一轮系统性升级柱状/饼图配色变量PR #6909此前自定义主题无法控制报表中柱状图bar与饼图pie各分片的颜色。本次新增了专用于 bar/pie chart 分片的主题变量如bar1、bar2……以及饼图分片变量自定义主题作者现在可以完整控制图表配色而不再局限于主色/背景色等基础变量。简化自定义主题 CSS 变量PR #7018自定义主题此前需要编写大量细粒度 CSS 变量才能完成定制。本次允许使用简单的 CSS 变量simple CSS variables降低主题编写门槛——更少的变量即可生效主题作者无需再逐一覆盖几十个细粒度 token。高对比度浅色主题PR #7032新增一款高对比度7.0:1 或更高浅色主题面向弱视用户与强光环境进一步补齐了主题库的可访问性覆盖。主题库扩充与更名新增Catppuccin Themes到自定义主题目录PR #6857新增Butterfly自定义主题PR #6900新增You Need A Dark Mode主题PR #6891原Okabe Ito主题更名为Color-blind (dark)PR #7058命名更直观地表达其色盲友好定位Midnight 主题的menuAutoCompleteTextHover颜色调整为green400PR #7048。主题文件位于 packages/component-library/src/themes含light.css、dark.css、midnight.css、palette.css等自定义主题的引用与变量体系可在此目录及 packages/desktop-client/src/style 中进一步查阅。相关配套改动还包括桌面端预算页面统一使用一致的颜色变量PR #6820并新增 lint 规则禁止直接导入主题文件PR #6796保证主题引用规范。性能与状态管理迁移Redux → React Queryv26.3.0 延续了把状态管理从 Redux 迁移到 React Query 的长期工程Maintenance分类中大量相关 PR目标直指性能与可维护性迁移**付款方payee与账户account**状态管理PR #6880、#6140迁移标签tag管理PR #6941迁移分类category状态PR #5977、#6882迁移报表数据获取PR #6951重构useTransactionshook 以使用 React Query 获取交易数据PR #6757并新增refetchOnSync选项统一处理同步事件PR #6936重构仪表盘数据获取PR #6957重构useAccounts返回完整查询状态PR #7009改进分类服务端应用与 React Query mutation 的错误处理PR #6958。迁移的收益体现在多个方面数据缓存与失效机制更统一、组件订阅粒度更细避免无关状态变更引发重渲染、同步事件触发 refetch 的逻辑更集中。发布说明将其概括为性能和响应性改进Performance and responsiveness improvements这一点在交易列表、账户切换、报表加载等高频场景中感知最明显。此外配套的工程化改动包括每个包独立tsconfig.json并通过 lage 并行执行PR #7019、Electron 构建产物排除出 TypeScript 编译以提升效率PR #6883、fetch模块更名为connection以避免与原生 fetch 混淆PR #6943、arithmetic.ts移植为严格 TSPR #6801、oxlint/oxfmt 升级PR #6955以及 lint 规则全面收紧类型感知 lint PR #6984、warning 转 error PR #6970等。预算、导入与其他用户体验增强预算模板自动化补齐refill 模板类型的缺失逻辑PR #6690并新增limit/refill 自动化编辑器PR #6692用户可在界面上直接配置这两种模板的触发条件与参数修复跟踪预算中模板余额结转balance carryover处理PR #6922修复预算摘要金额的双负号显示问题PR #6843覆盖超支covering overspending时初始焦点落在分类而非金额上PR #7012为分类组新增筛选选项PR #6834交易导出时包含分类组信息PR #6960。nYNAB 导入增强支持将 nYNAB新版 YNAB的定期交易导入为 Actual 的 schedulesPR #6844从 nYNAB 导入时标签颜色与 YNAB flags 对应PR #6866修复 YNAB5 导入器重复分类导入报错PR #6878。货币与日期格式新增多米尼加比索DOPPR #7028与韩元KRWPR #6846到货币列表月年日期格式修正为不含逗号的 January 2026PR #6748。交互细节修复规则日期字段置空不再导致崩溃PR #6905修复 CtrlEnter 新增交易时丢失金额值PR #6911修复算数表达式解析中同级运算符*//、/-未按从左到右求值的问题PR #6993隐藏小数位数开启时移动端预算金额输入修复PR #6945移动端可隐藏已对账reconciled交易PR #6896移动端规则列表对齐与全宽显示调整PR #7081iOS Safari 状态栏颜色同步主题色管理增强PR #6983无账户时重定向到账户页PR #7007筛选器中隐藏已选账户PR #7030规则结果窗口导入付款方列的 tooltip 缺失修复PR #7031紧凑视图处理简化CashFlow 行为更一致PR #6765浏览器语言检测按优先级依次匹配PR #6812Token 过期时自动登出PR #6798修复 widget 删除按钮翻译问题PR #6845桌面端链接笔记保持行内PR #6858防止过去错过的日程日期被标记为 upcomingPR #6925模块解析与 API 解析问题修复PR #7084、#6966。小结与升级建议维度v26.3.0 要点安全同步服务器文件 ID 校验、单斜杠路径解析修复建议尽快升级新 APITags 管理四方法getTags / createTag / updateTag / deleteTag银行同步关联账户自定义起始日期与余额、balance_currentAPI、日期覆盖选项报表命令栏直达、配置页返回按钮、tooltip 与净财富计算修复主题bar/pie 图表变量、简化 CSS 变量、高对比度浅色主题、3 个新主题性能Redux → React Query 大规模迁移payee/account/tag/category/report/dashboard其他新货币、refill 模板逻辑、nYNAB schedules 导入、日期格式修正对于生产环境的用户建议优先执行同步服务器升级以覆盖安全修复API 使用者可直接利用 Tags 四方法把标签管理纳入自动化脚本参考 packages/api/methods.test.ts 的调用范式主题作者则可基于简化后的 CSS 变量体系重构现有主题并利用新增的图表配色变量完善报表观感。如需继续深入可在仓库中重点查阅以下路径API 方法定义 packages/api/methods.ts、API 模型与转换 packages/loot-core/src/server/api-models.ts、标签服务端逻辑 packages/loot-core/src/server/tags/app.ts、主题文件 packages/component-library/src/themes以及本次版本的完整变更记录 packages/docs/blog/2026-03-02-release-26-3-0.md。【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表