# 00 术语表 - 文档状态:基线草案 - 用途:其他文档里出现的专业词,在这里能查到一句话解释 看文档时遇到不认识的词,先查这里。**不要靠猜**——这些词大多和数据安全、不重复下单直接相关,猜错会写出真出问题的代码。 ## 1. 最重要的三个 这三个词撑起了整个项目的可靠性设计,先看懂它们。本节最后还解释了一件事: 为什么本项目**没有**别的任务系统常见的"租约"和"心跳"。 ### 幂等(idempotent) **一句话:** 同一个操作做一次和做十次,结果一样。 **为什么要有:** 网络会超时。你给 Admin 发了"采购成功",但没收到回复——你不知道 Admin 到底收到没有。如果直接重发,Admin 可能记两笔。幂等就是让重发变安全:每次提交都带一个**幂等键**(`Idempotency-Key`),Admin 看到相同的键就知道"这条我处理过了",直接返回上次的结果,不会重复记账。 **在本项目里:** 幂等键存在 `outbox_events.idempotency_key`,格式见 [03 数据模型](03-data-model.md) §5.2。 ### Outbox(待发件箱) **一句话:** 一张本地表,结果先写进这张表,再由后台慢慢发给 Admin。 **为什么要有:** 手机上已经下单了,这一步**不可撤销**。如果这时候网断了,直接把结果丢掉,就等于白下单一次还没人知道。所以流程必须是:先把结果落到本地数据库(连同 Outbox 记录,在同一个事务里),再由后台反复重试发送。发不出去就一直留着,程序重启也还在。 **关键区别:** Outbox 重试的是**"提交这个结果"**,不是**"重新做一遍这个任务"**。发送失败只会重发消息,绝不会再去手机上点一次下单。 **在本项目里:** 表 `outbox_events`,见 [03 数据模型](03-data-model.md) §5。 ### 不可逆阶段标记 **一句话:** 数据库里的一个时间戳,意思是"这个任务我已经点过下单了,撤不回来了"。 **为什么要有:** 程序可能在下单那一刻崩溃或断电。重启后它不知道刚才那单到底成没成—— 这时候如果傻乎乎地重跑一遍,就会买两次。所以规则是:**点下单之前先把这个标记写进数据库**。 重启后只要看到它有值,就只准去"我的订单"里核对,绝不准重新下单。 **为什么它现在特别重要:** 本项目没有租约和心跳(见下方说明), 防重复下单**全靠它**。改动相关代码要格外小心。 **在本项目里:** `task_runs.irreversible_action_at`,规则见 [03 数据模型](03-data-model.md) §7.3。 ### 为什么没有"租约"和"心跳" 你可能在别的任务系统里见过这两个词——Admin 发一个限时凭证证明"这个任务归你", Client 定期发心跳续期,过期就得停手。**本项目故意没有这套东西。** 原因:本项目不自动付款,采购止于创建订单。就算两台 Client 撞车各下一单, 产生的也只是重复的**未付款**订单,人工审核时不付即可。为这点代价引入租约、心跳、 过期判断和一整套中断逻辑,不划算。 Admin 想知道某台 Client 是不是卡死了,用"领取后超时重派"就行,Client 不参与。 完整理由见 [04 接口契约](04-admin-api-contract.md) §1.1。 ## 2. 数据和接口 | 词 | 一句话解释 | 在本项目里指 | |---|---|---| | 分配 | Admin 决定某个任务归哪台 Client 做。**分配 ≠ 领取**:分配是 Admin 单方面指定,领取是 Client 主动调 `claim` 去拿 | 见 [04](04-admin-api-contract.md) §5.1 | | 退避 / backoff | 重试失败后逐次拉长等待时间(1秒、2秒、4秒……),别把服务端打垮 | Outbox 重试和领取轮询,见 [04](04-admin-api-contract.md) §8 | | DTO | 只用来在系统之间传数据的简单对象,没有业务逻辑 | Admin 接口收发的那些数据结构 | | Repository | 专门放数据库读写代码的一层。**别的地方不许直接写 SQL** | `src/infrastructure/db/` 下的类 | | Gateway | 隔离外部系统的一层。换实现(Mock ↔ 真 HTTP)时,上层代码不用改 | `AdminGateway` / `MockAdminGateway` | | 状态机 | 规定"什么状态能变成什么状态"的一张表,不在表里的变化就是 bug | 任务状态转换,见 [03](03-data-model.md) §7 | | 便携模式 | 程序和它的数据放在同一个文件夹里,整个拷走就能用,不往系统目录写东西 | `data/` 在 `launcher.exe` 旁边,见 [03](03-data-model.md) §2.1 | | frozen | Python 判断"我现在是不是打包成 exe 在跑"的标志 | `getattr(sys, "frozen", False)`,见 [03](03-data-model.md) §2.2 | | one-dir / one-file | PyInstaller 的两种打包形态:one-dir 产出一个文件夹,one-file 挤成单个 exe。**本项目用 one-dir**,好排查 | 见 [01 需求](01-requirements.md) §8.1 | | WAL | SQLite 的一种工作模式,好处是"读"和"写"可以同时进行,不互相锁死 | 建库时 `PRAGMA journal_mode = WAL` | | 事务 | 一组数据库操作,要么全部成功,要么全部不生效 | 写任务结果 + 写 Outbox 必须在一个事务里 | | schema_version | JSON 数据的版本号。以后结构变了,靠它认出旧数据 | `pdd_data` 和 `admin_payload` 的第一个字段 | ## 3. 界面和线程 | 词 | 一句话解释 | 在本项目里指 | |---|---|---| | Qt 主线程 | 唯一允许创建和修改界面控件的线程。**在这个线程里做耗时的事,界面就会卡死转圈** | 见 [02 架构](02-architecture.md) §5 | | Worker | 放在后台线程里干耗时活儿(联网、点手机、读大文件)的对象 | `TaskWorker`,模板见 [02](02-architecture.md) §5.1 | | 信号 / signal | Qt 里跨线程传消息的机制。后台线程算完了,用信号通知主线程去更新界面 | 后台结果回主线程的唯一正规途径 | | 模型/视图 | 表格分成两半:数据在"模型"里,显示在"视图"里。好处是几万行也不卡 | `TaskTableModel` + `TableView` | | 增量加载 | 表格先只加载 50 行,用户滚到底了再去数据库拿下一批 | `canFetchMore` / `fetchMore`,见 [05](05-ui-specification.md) §5.3 | | 委托 / delegate | 告诉表格"这一列要画成按钮/链接"的画笔对象。**比给每个格子塞一个真控件省资源得多** | "详情"那一列 | | InfoBar | Fluent 风格的横条提示。可以停着不消失,还能带按钮 | 可恢复错误的标准提示方式 | | 模态对话框 | 弹出来必须先处理它、否则动不了主窗口的窗口。**很打断人,只在必须做决定时用** | 高危确认 | | DPI / 显示缩放 | Windows 里"文字和应用的大小"那个百分比设置 | 需验证 100%~200% | | 高对比度 | Windows 的一种无障碍主题,颜色极简 | 需验证界面不能只靠颜色区分状态 | ## 4. 自动化和安全 | 词 | 一句话解释 | 在本项目里指 | |---|---|---| | uiautomator2 | 用 Python 控制安卓手机点击、滑动、读屏幕的库 | 采集和采购的执行手段 | | 控件树 / hierarchy | 手机当前这一屏所有元素的结构化描述(XML),能看到每个元素的文字和坐标 | `device.dump_hierarchy()` 的返回值 | | adb | 电脑和安卓手机通信的命令行工具 | 连设备用 | | SKU | 一个具体的、可以单独下单的商品组合。比如"黑色 + L 码"是一个 SKU,"黑色 + M 码"是另一个 | `pdd_data.skus`,每个 SKU 有自己的价格 | | 规格维度 | 选择商品时的一类选项,比如"颜色"是一个维度,"尺码"是另一个维度 | `pdd_data.dimensions` | | 不可逆阶段 | 一旦跨过去就撤不回来的操作阶段(真的把订单提交出去了) | 进入前必须先写 `irreversible_action_at`,见本文 §1 | | 演练模式 / dry_run | 前面步骤全做(选规格、选数量、算价格),**就是不点最后那个下单按钮** | 默认模式,见 [01](01-requirements.md) §8 | | 人工处理 / manual_review | 程序判断不了,停下来等人看。**绝不自己猜着往下做** | 任务状态之一,比如查到多个可能的订单时 | | 订单核对 / reconcile | 程序崩了、不确定到底下单成功没有,去"我的订单"里找证据 | 崩溃恢复的唯一正确做法,**不是重新下单** | | Artifact / 诊断产物 | 出错时留下的截图、控件树 XML、步骤日志,用来事后查原因 | 存在文件里,数据库只存路径 | | 脱敏 | 把敏感信息(token、Cookie、手机号、地址)从日志和截图里抹掉再保存 | 写 Artifact 前必做 | | 门禁 | 一组必须全部满足才允许做某事的条件清单 | 真实下单门禁,见 [06](06-quality-security.md) §3 | | 契约测试 | 用同一套测试去考 Mock 和真实 HTTP 两种实现,确保它们行为一致 | `AdminGateway` 的两个实现都要过 | ## 5. 流程相关 | 词 | 一句话解释 | |---|---| | 大工单 / Epic | 一个完整产品目标的总纲,下面挂很多小工单 | | MVP | 最小可用版本。先做出来能用的一小块,而不是一次做完所有功能 | | 单元任务工单 | 实际干活的最小单位,一个人一次能做完、能单独测、能单独回退 | | 归档 | 任务做完后,把结论写成 `docs/task/<工单号>-<名称>.md` 存起来 | | 基线文档 | `docs/client/` 下这几份,记录长期稳定的规则。改它们要谨慎 | 流程细节见仓库根目录 [AGENTS.md](../../AGENTS.md)。