账单 skill

账单 skill

2026-09-08
13 分钟阅读
#技术笔记 #账本 #Skill

摘要

鱼蛋账本的代理操作规范:品牌与商品独立存储、订单整理、实付金额、去重、API 录入与旧数据迁移。

适用于鱼蛋账本的购物订单整理、去重、录入、编辑和数据迁移。品牌、商品独立保存;备注记录店铺、订单号、优惠和其他补充信息。

数据结构

一条交易对应 public.transactions 中的一行。使用以下七个业务字段:

字段类型规则
amountnumber人民币实付金额,大于 0,最多两位小数
typestring购物支出固定为 expense
brandstring / null明确的品牌;不能把淘宝、京东或不明确的店铺名当品牌
productstring / null商品名称,保留容量、数量、段位、尺寸、款式等关键规格
categorystring / null推荐使用下表的中文分类,不附带 emoji
transaction_timestring / null包含时区的 ISO 8601 时间;无法确认则为 null
notestring / null店铺、订单号、优惠和其他补充信息;没有则为 null

新增购物账单应填写商品。历史记录或来源缺失具体商品名称时允许 product: null,列为待补充,不编造「某品牌商品」。页面新增表单要求商品必填;接口为了兼容旧调用允许省略品牌和商品。

数据库另外保留 id、created_at,由系统管理。不要把品牌和商品重新合并进 note;不要发送 shop、order_number、discount 等不存在的独立列。

提取与金额

  • 只采用截图、订单详情或用户明确提供的信息。不猜测模糊或截断的订单号、商品、日期、品牌、优惠。
  • amount 使用明确的最终实付款,不使用原价、划线价、预估到手价或优惠前小计。不再减去备注里的优惠。
  • 无法确认实付款时跳过该条并说明缺失信息,不填 0。
  • 原始外币金额可写入备注;没有明确人民币实付或用户确认的换算金额时,不擅自换汇。
  • 一个订单有多件商品、只有整单实付款时,合并为一条交易。商品用分号列出;多品牌可在 brand 中用分号列出,商品需要时标明对应品牌。整单金额只计一次,不自行分摊。跨分类无法判断主要用途时用「其他」。
  • 优惠、店铺、物流只是补充信息。不得因为补充这些信息而重写金额、购买日期或原有分类。

备注格式

按「店铺 → 订单号 → 优惠 → 其他信息」排列,推荐换行,也兼容 | 分隔:

店铺:示例品牌旗舰店
订单号:EXAMPLE-000123
优惠:店铺优惠¥15
物流:用户提供的物流信息

只写已知项目,没有店铺或优惠时省略对应行。订单号始终按原始文本处理,保留前导零和字母,避免长数字精度丢失。只知道平台时写「渠道:淘宝」,不冒充具体店铺。

分类

按商品用途判断;新整理的购物支出优先使用以下八项。数据库兼容历史及用户自定义分类,迁移或补充字段时不擅自重分类。

分类示例
喂养用品奶粉、奶瓶、奶嘴、吸奶器、温奶器、奶瓶刷
护理清洁尿不湿、湿巾、棉柔巾、日常洗护、护理垫
辅食零食宝宝辅食、零食、饮用水、牛奶;奶粉归喂养用品
医疗健康体温计、药品、医疗器械、明确医用的消毒产品
衣物穿戴衣服、袜帽、围兜、衣架
大件用品婴儿床、推车、安全座椅、尿布台、餐椅
外出相关主要为旅行、外出携带设计的用品,例如外出奶粉分装盒;推车等已列大件除外
其他育儿书、早教玩具、收纳盒及无法确定分类的商品

接口兼容已知分类的内部英文值和带 emoji 的旧写法,并统一保存为中文名称。

日期

使用明确的购买或下单时间。默认按中国订单来源使用 +08:00;来源明确其他时区时按来源处理。

只有日期时使用 YYYY-MM-DDT00:00:00+08:00。只有月日时,结合来源和上下文确认年份,不能直接套用当前年份。日期或年份无法确认时填写 null,不使用录入时间伪造购买时间。

页面按设备当地时间输入,保存时转换为带时区时间。历史账单时间为空时,编辑其他字段必须保持为空;列表与统计可沿用创建时间归档,但这不表示购买时间已知。

去重与续录

优先对比「订单号 + 商品」,再辅助对比品牌、店铺、规格、实付金额和日期。同一订单的列表截图与详情截图应合并证据。不同订单号的同款商品不能仅凭商品同名判重。

同一整单已经记账后,不再把其中各商品重复记账。一个订单有不同商品且每件实付金额明确时,可以有多条记录,不按订单号单独去重。

用户说「还有这些」「继续整理」时,只处理新增记录;明确要求完整总表时才输出全部。没有新增时输出 {"transactions":[]}。

读取历史账单用于去重时,必须完成相关时间范围的所有分页,不能只检查第一页。当前页面搜索和 CSV 导出只覆盖已加载记录。

JSON 示例

整理模式的顶层为 transactions 数组。以下为虚构示例,不作为默认值:

{
  "transactions": [
    {
      "amount": 16,
      "type": "expense",
      "brand": "示例品牌",
      "product": "奶嘴收纳盒 2个装",
      "category": "喂养用品",
      "transaction_time": "2026-09-08T00:00:00+08:00",
      "note": "店铺:示例品牌旗舰店\n订单号:EXAMPLE-000123\n优惠:店铺优惠¥15"
    }
  ]
}

用户只要求 JSON 时输出合法 JSON,不加注释或额外字段。需解释未处理记录时,在 JSON 前单独简短说明。

实际录入和编辑

项目正式地址为 https://cost.ykn.cm。操作前确认目标环境已部署品牌/商品、账本写入回执与版本检查迁移,具体顺序见项目 README。

  • 用户仅要求整理、计划或 JSON 时,交付数据,不写入数据库。
  • 用户已明确要求把本批账单写入、编辑或迁移时,按其授权范围执行,不重复索要相同授权。
  • 优先使用应用 API。数据库管理或迁移使用 Supabase 时,核对目标项目和表;账本项目名为 YUDAN,不是物品库存项目 yudan-wupin。
  • 写接口使用 Authorization: Bearer <API_KEY 或授权 GitHub access token> 和 Content-Type: application/json。只使用用户配置的凭据,不把密钥写入文章、代码或日志。

读取:GET /api/list?limit=100,可加 year、month、type、category。返回 data、hasMore、nextCursor;继续用 cursor=<nextCursor> 获取后续页,直到 hasMore 为 false。

新增:POST /api/add,每次发送数组中的一个交易对象,并为本次操作生成 UUID 格式的 request_id。当前没有批量新增接口,不能把 {"transactions":[...]} 包装整体发给此接口。成功返回 success、交易 data(含整数 version)、request_id 和是否重放的 replayed。

编辑:PATCH /api/edit,发送读取结果的 id、expected_version(读取时的 version)、本次操作的 request_id 和需要修改的字段。省略业务字段表示保持原值;可选文本传 null 或空字符串表示清空。示例:

{
  "id": "数据库返回的真实 UUID",
  "request_id": "本次操作生成的 UUID",
  "expected_version": 1,
  "brand": "示例品牌",
  "product": "奶嘴收纳盒 2个装",
  "note": null
}

删除:DELETE /api/delete,传入 id、读取时的 expected_version 和本次操作的 request_id。编辑和删除缺少版本会返回 400,需先读取最新账单。

错误:参数或金额不合法为 400,无有效权限为 401,编辑/删除不存在的账单为 404,记录版本变化或请求 ID 被用于不同内容为 409,服务端失败为 500,必需写入 RPC 缺失为 503。版本冲突响应的 current 是最新账单;保留本地输入,对比后再明确决定如何处理,不自动覆盖。

保存后核对返回的品牌、商品、金额、日期、备注,再读取记录确认已保存。批量处理要汇总成功、跳过和失败条目。请求超时或响应不明确时,使用相同 request_id 和相同请求内容重试;服务端返回原保存结果,不重复新增。不要换 ID 重发,也不要在原 ID 下改变内容。确定发生版本冲突且用户决定继续修改后,使用新的请求 ID 和最新版本重新提交。未提供请求 ID 的旧新增调用仍兼容,但调用方无法可靠重试丢失响应;此时必须先读取核对。幂等不能替代录入前的订单去重。

旧数据迁移规则

本次升级在现有 transactions 表新增 brand、product,不换账单 ID,不把交易存为 JSON 数组。

先备份原始记录,再从明确的 [品牌] 商品 或经过核对的旧格式拆分。店铺、订单号、优惠、渠道、物流和原记录金额移到备注。不确定的信息保留原文,未知字段为空。禁止为了填满字段而猜测信息或删除疑似重复交易。

本次迁移的原始记录保存在非公开的 ledger_private.transactions_before_brand_product。该表用于人工审计与恢复,不作为日常录入接口,也不应公开授权。恢复前核对迁移后的新编辑,避免用旧备份覆盖新数据。

迁移后验收:笔数、总额、每条金额、分类、收支类型、创建时间和购买时间不变;订单号完整;原始记录可追溯;新增、编辑、列表、详情、搜索和导出都能处理新字段。

本次迁移于 2026 年 9 月 8 日完成:共 137 笔,合计 ¥34,915.65;135 笔有品牌,136 笔有商品名称。两笔品牌和一笔商品名称缺乏依据,保持为空。迁移前后逐笔财务与时间字段一致,订单号无丢失。

分享文章