# 数据与同步 ## 核心实体 - `user`:用户。 - `device`:设备。 - `ledger`:账本。 - `ledger_member`:账本成员。 - `ledger_invitation`:账本邀请。 - `category`:分类。 - `entry`:账目。 - `sync_operation`:同步操作。 ## 账本字段 - `id` - `name` - `visibility`:`private` 或 `shared`。 - `owner_id` - `created_at` - `updated_at` - `deleted_at` ## 成员字段 - `ledger_id` - `user_id` - `role`:`owner` 或 `member`。 - `joined_at` - `removed_at` ## 邀请字段 - `id` - `ledger_id` - `token` - `created_by` - `expires_at` - `accepted_by` - `accepted_at` - `revoked_at` ## 权限规则 - 用户只能同步自己有成员关系的账本。 - 独享账本只有 owner 一名成员。 - 共享账本可以有多名成员。 - `owner` 可以邀请和移除成员。 - `member` 可以查看和记账。 - 首版不做单条账目权限。 ## 账目字段 - `id`:客户端生成 UUID。 - `ledger_id` - `type`:`expense` 或 `income`。 - `amount`:金额,整数分。 - `category_id` - `occurred_at` - `note` - `created_by` - `updated_by` - `created_at` - `updated_at` - `deleted_at` - `version` ## 同步原则 - 客户端先写 IndexedDB,界面立即成功。 - 每次本地变更生成一个 `operation_id`。 - 同步 API 必须幂等。 - 服务端保存账本变更日志。 - 客户端用游标拉取增量。 - 同步范围必须按账本成员权限过滤。 ## 同步流程 1. 用户新增、编辑或删除账目。 2. 客户端写 IndexedDB。 3. 客户端写本地同步队列。 4. 网络可用时推送队列。 5. 服务端按 `operation_id` 去重并应用。 6. 客户端拉取远端增量。 7. 客户端合并到 IndexedDB。 ## 冲突策略 - 新增记录基本无冲突,ID 由客户端生成。 - 删除使用软删除。 - 同一条账目被多人离线修改时,首版最后写入胜出。 - 不做字段级合并。 - 冲突历史和人工选择版本后置。 冲突示例: - 手机 A 和手机 B 都同步过同一笔账:`午餐 100 元`。 - 两台手机同时离线。 - 手机 A 改成 `120 CNY`。 - 手机 B 改成 `110 CNY` 或修改分类。 - 两台手机恢复网络后上传。 - 服务端必须决定最终版本。