尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Actual 23.7.1 版本修复解析:银行同步、预算文件同步与月份选择器

Actual 23.7.1 版本修复解析:银行同步、预算文件同步与月份选择器 Actual 23.7.1 版本修复解析银行同步、预算文件同步与月份选择器【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actualActual 23.7.1 是 Actual 个人财务管理应用在 2023 年 7 月发布的一个补丁版本集中修复了银行同步GoCardless/Nordigen、新预算文件云端同步以及报告页月份选择器三个方向的回归问题。本文将逐条剖析该版本的三个 bugfix 对应的源码实现与修复背景帮助你理解 Actual 的同步架构、分类排序机制与组件库设计并给出可复现的验证方式。版本背景与发布信息该版本发布说明位于 packages/docs/blog/2023-07-05-release-23.7.1.md官方给出的版本标识如下Docker tag23.7.1Actual 版本23.7.1Actual Server 版本23.7.1Actual 采用 monorepo 结构核心包包括loot-core数据引擎与业务逻辑、desktop-client前端界面、sync-server自托管同步服务器与component-library跨端组件库。23.7.1 修复的三处问题恰好横跨了这几个模块银行同步位于sync-server与loot-core的联动层预算文件同步位于loot-core/src/server/budgetfiles月份选择器则位于component-library。修复一NordigenGoCardless同步问题与预算分类排序发布说明中的第一条修复为[#1289] Fix Nordigen sync issue; fix sorting of budget categories这条修复实际包含两个相互独立的问题分别对应两个功能面。Nordigen 同步问题Nordigen 是 Actual 早期接入的银行数据聚合服务后被 GoCardless 收购用于银行账户自动同步。在 23.7.1 中该修复针对的是同步链路中出现的回归问题。从当前仓库的 packages/sync-server/src/app-gocardless/app-gocardless.ts 可以看到这一链路的职责包括POST /link返回银行授权跳转页用户完成授权后窗口自动关闭LINK_PAGE_HTML中通过window.close()实现POST /create-web-token根据institutionId创建 requisition 并返回授权链接POST /get-accounts查询 requisition 关联的账户列表并对 IBAN 做sha256String哈希处理以保护隐私POST /transactions拉取交易明细按includeBalance参数决定是否同时返回余额信息并将交易分为booked、pending、all三组POST /remove-account删除 requisition。其中/transactions的错误处理体现了该接口对银行侧异常的精细分类见 app-gocardless.tsRequisitionNotLinked/EndUserAgreementExpiredError→ 返回ITEM_ERROR/ITEM_LOGIN_REQUIRED提示授权协议到期需要重新登录AccountNotLinkedToRequisition→ 返回INVALID_INPUT/INVALID_ACCESS_TOKENRateLimitError→ 返回RATE_LIMIT_EXCEEDED/NORDIGEN_ERROR并透传x-ratelimit-*响应头供客户端判断限流GenericGoCardlessError→ 返回SYNC_ERROR/NORDIGEN_ERROR。从代码结构看23.7.1 的 Fix Nordigen sync issue 属于对这条同步链路的回归修复目的是让银行同步在授权过期、限流等边界场景下返回可识别的错误码避免客户端卡死或误报。预算分类排序修复同一条 PR 还修复了预算分类排序的问题。Actual 的预算分类categories按组category groups组织用户可以在组内按名称对分类进行排序。核心实现位于 packages/loot-core/src/server/budget/sort-categories.tsexport async function sortCategories({ groupId, direction }) { const groups await db.getCategoriesGrouped(); const group groups.find(g g.id groupId); if (!group?.categories?.length) return; const sorted [...group.categories].sort((a, b) direction asc ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name), ); for (let i sorted.length - 1; i 0; i--) { await batchMessages(async () { await db.moveCategory( sorted[i].id, groupId, i sorted.length - 1 ? null : sorted[i 1].id, ); }); } }该实现的几个要点排序基准使用localeCompare按分类名称进行本地化排序direction支持asc升序与desc降序链表式重排Actual 中分类顺序以前置节点sortOrder/prevId的方式存储因此这里从后往前遍历把每个分类移动到其后一个分类的前面最后一个分类移动到组首前置为null批量消息每次移动通过batchMessages包裹保证 CRDT 同步消息以原子批次提交避免产生中间态导致多端同步错乱。23.7.1 修复的正是这个流程中因组内无分类或移动顺序处理不当导致的排序失效问题。相关测试位于 packages/loot-core/src/server/budget/sort-categories.test.ts可用于回归验证。修复二新预算文件无法正确同步第二条修复为[#1291] Fix new budget files not syncing correctly这条修复针对的是新建预算文件后云端同步失败的回归。Actual 的预算文件生命周期管理集中在 packages/loot-core/src/server/budgetfiles/app.ts其中与新建和同步相关的关键方法包括createBudget新建预算createBudgetapp.ts负责初始化一个全新预算文件通过fs.copyFile(fs.bundledDatabasePath, ...)复制随应用分发的初始数据库模板db.sqlite写入metadata.json由prefs.getDefaultPrefs(id, budgetName)生成调用_loadBudget(id)加载并迁移数据库非测试模式下调用cloudStorage.upload()上传到云端失败时仅记录警告不阻断本地使用。syncBudget 与 initialFullSync打开即同步新建预算文件后客户端通过sync-budget消息触发同步async function syncBudget() { setSyncingMode(enabled); const result await initialFullSync(); return result; }initialFullSync位于 packages/loot-core/src/server/sync/index.ts其注释明确说明它与普通fullSync的区别它会等待电子表格spreadsheet完成所有计算后再返回适合在操作文件前做首次全量同步。23.7.1 修复的场景是新建预算后立即进入同步流程时由于电子表格尚未完成初始化计算CRDT 消息的生成与上传顺序出现竞态导致云端文件缺失或落后。修复后新建预算的上传与初次全量同步严格串行确保云端与本地数据一致。此外app.ts 中的duplicateBudget在复制预算时会主动删除cloudFileId、lastUploaded、lastSyncedTimestamp等云端元数据再按需重新上传——这同样是为了避免新文件携带旧同步状态导致的同步异常与本次修复的语义一致。修复三报告页月份选择器与滚动容器第三条修复为[#1294] Fix month picker responsiveness in reports page and make the select boxes scrollable这条修复涉及两处界面体验问题均与 Actual 的组件库 packages/component-library 相关。月份选择器响应式修复报告的月份选择器基于组件库中的MonthPicker实现packages/component-library/src/MonthPicker.tsx。其内部结构为NavRow年份导航行通过canPrev/canNext结合min/max哨兵值0001-01与9999-12表示无限制控制前后翻页MonthGrid12 个月份的宫格布局MonthGrid.tsx使用 CSS GridgridTemplateColumns: repeat(4, 1fr)排列按localeBCP 47 语言标签本地化月份标签Popover触发按钮点击后弹出选择面板placementbottom start对齐。23.7.1 修复的是该选择器在报告页窄屏/小视口下的响应式问题确保弹层在空间受限时仍能完整展示并正确交互。下拉框可滚动修复同一 PR 还让报告页中的下拉选择框select boxes在选项过多时可滚动。报告页顶部的筛选与日期选择集中在 packages/desktop-client/src/components/reports/Header.tsx其使用组件库的Select组件承载报告类型、粒度granularity、预设范围DateRangePreset由buildDateRangePresets动态构建等选项。修复为这些容器补充了滚动约束避免长选项列表溢出页面。这两个组件的实现均可直接在组件库与桌面端源码中查看MonthPicker的单元级行为可由 RangeSelector.web.test.tsx 等测试覆盖报告页的整体交互则由 packages/desktop-client/e2e/reports.test.ts 的端到端用例验证。如何验证与升级到 23.7.1自托管部署DockerActual 官方发布说明明确标注了本次发布的 Docker 镜像标签docker pull actualbudget/actual-server:23.7.1将现有容器的镜像标签更新为23.7.1后重启即可完成升级。升级仅涉及 bugfix不包含数据迁移既有预算文件与云端同步状态不受影响。本地开发验证同步链路运行sync-server下的测试如 app-gocardless.test.ts可覆盖 requisition 创建、账户查询与交易拉取的错误分支分类排序运行sort-categories.test.ts验证升/降序与空组场景报告页交互运行桌面端报告相关 e2e 测试reports.test.ts确认月份选择器与下拉框在多种视口下表现正常。总结Actual 23.7.1 虽是小版本但三个修复点覆盖了实际使用中影响面最大的三类问题银行同步的稳定性、新建预算文件的云端一致性以及报告页在小屏设备上的可用性。透过源码可以看到这些修复并非孤立的打补丁而是与 Actual 的 CRDT 同步模型batchMessages、initialFullSync、组件库的响应式设计以及sync-server的银行聚合错误分类体系深度绑定。对于希望自托管 Actual 或参与其开发的读者理解这三条修复背后的机制比记住版本号本身更有价值。【免费下载链接】actualA local-first personal finance app项目地址: https://gitcode.com/GitHub_Trending/ac/actual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表