30 KiB
需求文档:小程序核心业务模块(miniapp-core-business)
简介
本 SPEC 实现小程序的核心业务逻辑,涵盖助教任务系统(生成、分配、状态流转、完成检测)、备注系统(CRUD、星星评分、类型区分)、以及后台触发器/轮询调度框架。系统基于 P1(miniapp-db-foundation)的数据库基础设施、P2(etl-dws-miniapp-extensions)的 DWS 指数数据、P3(miniapp-auth-system)的用户认证体系,在 test_zqyy_app.biz Schema 中创建任务、备注、触发器等业务表,并在 FastAPI 后端实现对应的 API 端点和后台调度逻辑。
术语表
- Task_Generator:任务生成器,每日 4:00 后运行,基于 WBI/NCI/RS 指数为每个助教分配 4 种类型任务的后台服务
- Task_Manager:任务管理服务,负责任务 CRUD、置顶、放弃、状态流转的后端模块
- Task_Expiry_Checker:任务有效期轮询器,每小时检查
expires_at并将过期任务标记为无效 - Recall_Completion_Detector:召回完成检测器,ETL 数据更新后检查助教是否为匹配客户提供了服务
- Note_Reclassifier:备注回溯重分类器,召回完成时回溯检查是否有普通备注需重分类为回访备注
- Note_Service:备注服务模块,负责备注 CRUD、星星评分存储与读取
- Trigger_Scheduler:触发器调度框架,支持 cron/interval/event 三种触发方式的统一调度引擎
- coach_tasks:助教任务表,位于
bizSchema,存储任务分配、状态、有效期等信息 - coach_task_history:任务变更历史表,记录任务关闭/新建的追溯链
- notes:统一备注表,位于
bizSchema,通过type字段区分普通备注/回访备注/放弃原因 - trigger_jobs:触发器配置表,位于
bizSchema,存储轮询/事件触发器的配置与执行状态 - task_type:任务类型枚举,取值为
high_priority_recall(高优先召回)/priority_recall(优先召回)/follow_up_visit(客户回访)/relationship_building(关系构建) - task_status:任务状态枚举,取值为
active(有效)/inactive(无效)/completed(已完成)/abandoned(已放弃) - note_type:备注类型枚举,取值为
normal(普通备注)/follow_up(回访备注)/abandon_reason(放弃原因) - priority_score:优先级分数,取
max(WBI, NCI)的快照值,用于任务排序 - expires_at:有效期时间戳,默认 NULL(无限期),填充后表示任务将在该时间点过期
- FDW:
postgres_fdw外部数据包装器,通过fdw_etlSchema 读取 ETL 库指数数据 - Migration_Script:存放在
db/zqyy_app/migrations/中的纯 SQL 迁移脚本,以日期前缀命名 - site_id:门店标识符,类型为
BIGINT,用于多门店数据隔离 - member_retention_clue:维客线索表,位于
publicSchema,存储助教为客户记录的维护线索(大类 + 摘要 + 详情),独立于 ETL 数据。当前已有基础表结构和 CRUD API(/api/retention-clue),若不足以支撑本 SPEC 的任务系统需求,可对其 DDL、Pydantic 模型及路由进行扩展或修改
需求
需求 1:业务数据表创建
用户故事: 作为后端开发者,我需要在 biz Schema 中创建任务、备注、触发器等业务表,以便支撑核心业务功能。
验收标准
- WHEN Migration_Script 执行完成, THE Task_Manager SHALL 在
bizSchema 中创建coach_tasks表,包含id(BIGSERIAL PK)、site_id(BIGINT NOT NULL)、assistant_id(BIGINT NOT NULL)、member_id(BIGINT NOT NULL)、task_type(VARCHAR NOT NULL)、status(VARCHAR NOT NULL DEFAULT 'active')、priority_score(NUMERIC(5,2))、expires_at(TIMESTAMPTZ,可空)、is_pinned(BOOLEAN DEFAULT FALSE)、abandon_reason(TEXT,可空)、completed_at(TIMESTAMPTZ,可空)、completed_task_type(VARCHAR,可空)、parent_task_id(BIGINT,可空,FK → coach_tasks)、created_at(TIMESTAMPTZ DEFAULT NOW())、updated_at(TIMESTAMPTZ DEFAULT NOW())字段 - WHEN Migration_Script 执行完成, THE Task_Manager SHALL 在
bizSchema 中创建coach_task_history表,包含id(BIGSERIAL PK)、task_id(BIGINT FK → coach_tasks)、action(VARCHAR NOT NULL)、old_status(VARCHAR)、new_status(VARCHAR)、old_task_type(VARCHAR)、new_task_type(VARCHAR)、detail(JSONB)、created_at(TIMESTAMPTZ DEFAULT NOW())字段 - WHEN Migration_Script 执行完成, THE Note_Service SHALL 在
bizSchema 中创建notes表,包含id(BIGSERIAL PK)、site_id(BIGINT NOT NULL)、user_id(INTEGER NOT NULL)、target_type(VARCHAR NOT NULL)、target_id(BIGINT NOT NULL)、type(VARCHAR NOT NULL DEFAULT 'normal')、content(TEXT NOT NULL)、rating_service_willingness(SMALLINT,可空,CHECK 1-5)、rating_revisit_likelihood(SMALLINT,可空,CHECK 1-5)、task_id(BIGINT,可空,FK → coach_tasks)、ai_score(SMALLINT,可空)、ai_analysis(TEXT,可空)、created_at(TIMESTAMPTZ DEFAULT NOW())、updated_at(TIMESTAMPTZ DEFAULT NOW())字段 - WHEN Migration_Script 执行完成, THE Trigger_Scheduler SHALL 在
bizSchema 中创建trigger_jobs表,包含id(SERIAL PK)、job_type(VARCHAR NOT NULL)、job_name(VARCHAR NOT NULL UNIQUE)、trigger_condition(VARCHAR NOT NULL)、trigger_config(JSONB NOT NULL)、last_run_at(TIMESTAMPTZ,可空)、next_run_at(TIMESTAMPTZ,可空)、status(VARCHAR NOT NULL DEFAULT 'enabled')、created_at(TIMESTAMPTZ DEFAULT NOW())字段 - THE Migration_Script SHALL 对
coach_tasks表创建唯一索引idx_coach_tasks_site_assistant_member_type在(site_id, assistant_id, member_id, task_type)上,仅对status = 'active'的记录生效(部分唯一索引) - THE Migration_Script SHALL 对
coach_tasks表创建索引idx_coach_tasks_assistant_status在(site_id, assistant_id, status)上,用于助教任务列表查询 - THE Migration_Script SHALL 对
notes表创建索引idx_notes_target在(site_id, target_type, target_id)上,用于按目标查询备注 - THE Migration_Script SHALL 使用
IF NOT EXISTS幂等语法,确保重复执行不会报错 - THE Migration_Script SHALL 在脚本中包含回滚语句(以注释形式)
需求 2:触发器种子数据预置
用户故事: 作为系统管理员,我需要系统预置核心触发器配置,以便后台调度任务自动运行。
验收标准
- WHEN 种子数据脚本执行完成, THE Trigger_Scheduler SHALL 在
biz.trigger_jobs表中插入task_generator记录(trigger_condition='cron',trigger_config 包含 cron 表达式 '0 4 * * *') - WHEN 种子数据脚本执行完成, THE Trigger_Scheduler SHALL 在
biz.trigger_jobs表中插入task_expiry_check记录(trigger_condition='interval',trigger_config 包含间隔秒数 3600) - WHEN 种子数据脚本执行完成, THE Trigger_Scheduler SHALL 在
biz.trigger_jobs表中插入recall_completion_check记录(trigger_condition='event',trigger_config 包含事件名 'etl_data_updated') - WHEN 种子数据脚本执行完成, THE Trigger_Scheduler SHALL 在
biz.trigger_jobs表中插入note_reclassify_backfill记录(trigger_condition='event',trigger_config 包含事件名 'recall_completed') - THE 种子数据脚本 SHALL 使用
ON CONFLICT (job_name) DO NOTHING语法,确保重复执行不会产生重复数据
需求 3:任务生成器
用户故事: 作为助教,我每天打开小程序能看到系统为我分配的任务列表,按优先级排序。
验收标准
- WHEN Task_Generator 运行时, THE Task_Generator SHALL 通过 FDW 读取
fdw_etl中的dws_member_winback_index(WBI)和dws_member_newconv_index(NCI)指数数据,计算priority_score = max(WBI, NCI) - WHEN
priority_score > 7, THE Task_Generator SHALL 为该客户-助教对生成high_priority_recall(高优先召回)类型任务 - WHEN
priority_score > 5且priority_score <= 7, THE Task_Generator SHALL 为该客户-助教对生成priority_recall(优先召回)类型任务 - WHEN 助教完成某客户的召回任务后该客户无回访备注, THE Task_Generator SHALL 为该客户-助教对生成
follow_up_visit(客户回访)类型任务 - WHEN 客户-助教对的 RS 指数 < 6(通过 FDW 读取
dws_member_assistant_relation_index), THE Task_Generator SHALL 为该客户-助教对生成relationship_building(关系构建)类型任务 - WHEN Task_Generator 生成任务时发现已存在相同
(site_id, assistant_id, member_id, task_type)且status = 'active'的任务, THE Task_Generator SHALL 跳过该任务不做任何操作 - WHEN Task_Generator 生成任务时发现已存在相同
(site_id, assistant_id, member_id)但task_type不同且status = 'active'的任务, THE Task_Generator SHALL 将旧任务状态设为inactive,创建新任务,并在coach_task_history中记录变更 - THE Task_Generator SHALL 按优先级从高到低的顺序处理任务类型:
high_priority_recall(0)>priority_recall(0)>follow_up_visit(1)>relationship_building(2),高优先级任务覆盖低优先级任务 - THE Task_Generator SHALL 通过
auth.user_assistant_binding确定助教与小程序用户的映射关系,仅为已绑定的助教生成任务 - THE Task_Generator SHALL 在
trigger_jobs中更新last_run_at和next_run_at时间戳
需求 4:48 小时回访滞留机制
用户故事: 作为系统,回访任务至少保留 48 小时,到期后自动失效。
验收标准
- WHEN Task_Generator 生成
follow_up_visit类型任务时, THE Task_Generator SHALL 将expires_at设为 NULL(无限期有效),status设为active - WHEN Task_Generator 检测到某
follow_up_visit任务的触发条件不再满足(指数变化), THE Task_Generator SHALL 将该任务的expires_at填充为created_at + 48 小时,status保持active - WHEN Task_Expiry_Checker 轮询检查时发现某任务的
expires_at不为 NULL 且当前时间超过expires_at, THE Task_Expiry_Checker SHALL 将该任务status设为inactive - WHEN 新的
follow_up_visit任务生成时发现同一(site_id, assistant_id, member_id)已存在一个有expires_at的follow_up_visit任务, THE Task_Generator SHALL 将旧任务标记为inactive,创建新的active任务(expires_at为 NULL) - THE Task_Expiry_Checker SHALL 每小时运行一次,由
trigger_jobs中的task_expiry_check配置驱动
需求 5:任务类型变更与状态流转
用户故事: 作为系统,当客户指数变化导致任务类型变更时,系统正确关闭旧任务并创建新任务。
验收标准
- WHEN 任务类型从
priority_recall变更为high_priority_recall, THE Task_Generator SHALL 将旧priority_recall任务标记为inactive(expires_at保持 NULL),创建新的high_priority_recall任务 - WHEN 任务类型从
follow_up_visit变更为high_priority_recall或priority_recall, THE Task_Generator SHALL 将旧follow_up_visit任务标记为active并填充expires_at = created_at + 48 小时,创建新的召回任务 - WHEN 任务类型从召回类型变回
follow_up_visit, THE Task_Generator SHALL 检查是否存在有expires_at的旧follow_up_visit任务,若存在则将旧任务标记为inactive,创建新的follow_up_visit任务 - THE Task_Manager SHALL 在每次状态变更时在
coach_task_history中记录action、old_status、new_status、old_task_type、new_task_type
需求 6:召回完成检测
用户故事: 作为助教,我完成召回任务后(客户到店被服务),系统自动标记任务完成。
验收标准
- WHEN ETL 数据更新后, THE Recall_Completion_Detector SHALL 通过 FDW 读取
fdw_etl.dwd_assistant_service_log中的新增服务记录 - WHEN 发现某助教为某客户提供了服务, THE Recall_Completion_Detector SHALL 查找该
(site_id, assistant_id, member_id)下所有status = 'active'的任务 - WHEN 匹配到活跃任务, THE Recall_Completion_Detector SHALL 将任务
status设为completed,记录completed_at为服务时间,记录completed_task_type为完成时的任务类型 - WHEN 召回完成后, THE Recall_Completion_Detector SHALL 触发
note_reclassify_backfill事件,通知 Note_Reclassifier 执行备注回溯 - THE Recall_Completion_Detector SHALL 由
trigger_jobs中的recall_completion_check配置驱动,在 ETL 数据更新事件后触发
需求 7:备注回溯重分类
用户故事: 作为系统,当 ETL 数据延迟导致召回完成晚于备注提交时,需要回溯重分类备注。
验收标准
- WHEN 召回完成事件触发后, THE Note_Reclassifier SHALL 查找该
(site_id, assistant_id, member_id)在召回服务结束时间之后提交的第一条type = 'normal'的备注 - WHEN 找到符合条件的普通备注, THE Note_Reclassifier SHALL 将该备注的
type从normal更新为follow_up - WHEN 备注重分类完成后, THE Note_Reclassifier SHALL 触发 AI 应用 6 对该备注进行含金量评分(评分逻辑由 P5 AI 集成层实现,本 SPEC 仅定义触发接口)
- WHEN AI 应用 6 返回评分 >= 6, THE Note_Reclassifier SHALL 生成一条
follow_up_visit任务并标记为completed(回溯完成) - WHEN AI 应用 6 返回评分 < 6, THE Note_Reclassifier SHALL 生成一条
follow_up_visit任务,status为active(回访未完成,需助教重新备注)
需求 8:任务 CRUD API
用户故事: 作为助教,我可以查看任务列表、置顶/放弃任务、取消置顶/取消放弃。
验收标准
- WHEN 助教请求任务列表, THE Task_Manager SHALL 返回该助教在当前
site_id下所有status = 'active'的任务,按is_pinned DESC, priority_score DESC, created_at ASC排序 - WHEN 助教请求任务列表, THE Task_Manager SHALL 在每条任务中包含客户基本信息(通过 FDW 读取
dim_member)、RS 指数(通过 FDW 读取dws_member_assistant_relation_index)、爱心 icon 档位(💖>8.5 / 🧡>7 / 💛>5 / 💙<5) - WHEN 助教置顶某任务, THE Task_Manager SHALL 将该任务的
is_pinned设为 TRUE,并在coach_task_history中记录 - WHEN 助教放弃某任务, THE Task_Manager SHALL 将该任务
status设为abandoned,记录abandon_reason(必填),并在coach_task_history中记录 - WHEN 助教取消置顶某任务, THE Task_Manager SHALL 将该任务的
is_pinned设为 FALSE - WHEN 助教取消放弃某任务, THE Task_Manager SHALL 将该任务
status恢复为active,清空abandon_reason - IF 助教放弃任务时未提供
abandon_reason, THEN THE Task_Manager SHALL 返回 HTTP 422 错误 - THE Task_Manager SHALL 通过 Permission_Middleware 验证用户身份,仅允许操作自己的任务
需求 9:备注 CRUD API
用户故事: 作为助教,我给客户添加备注后,系统正确存储备注内容和星星评分。
验收标准
- WHEN 助教创建备注时, THE Note_Service SHALL 在
biz.notes表中创建记录,包含site_id、user_id、target_type('member')、target_id(member_id)、type、content、可选的rating_service_willingness(1-5)、可选的rating_revisit_likelihood(1-5)、可选的task_id - WHEN 备注关联的任务类型为
follow_up_visit, THE Note_Service SHALL 将备注type自动设为follow_up - WHEN 备注关联的任务类型不是
follow_up_visit, THE Note_Service SHALL 将备注type设为normal - WHEN 备注创建成功且
type = 'follow_up', THE Note_Service SHALL 触发 AI 应用 6 备注分析接口(由 P5 实现),传入备注内容和客户信息 - WHEN AI 应用 6 返回评分 >= 6 且备注关联的
follow_up_visit任务status = 'active', THE Note_Service SHALL 将该任务标记为completed - WHEN 助教查询某客户的备注列表, THE Note_Service SHALL 返回该客户在当前
site_id下的所有备注,按created_at DESC排序,包含星星评分和 AI 评分 - WHEN 助教删除备注, THE Note_Service SHALL 执行软删除或硬删除(根据业务需要),删除前需二次确认(前端实现)
- IF 星星评分值不在 1-5 范围内, THEN THE Note_Service SHALL 返回 HTTP 422 错误
- THE Note_Service 的星星评分 SHALL 不参与回访完成判定(完成判定仅看 AI 应用 6 评分 >= 6),不参与 AI 应用 6 分析,仅作辅助数据存储
需求 10:触发器调度框架
用户故事: 作为系统,我需要一个统一的触发器调度框架,支持定时、间隔、事件驱动三种触发方式。
验收标准
- THE Trigger_Scheduler SHALL 支持
cron类型触发器,按 cron 表达式计算下次运行时间 - THE Trigger_Scheduler SHALL 支持
interval类型触发器,按固定间隔秒数计算下次运行时间 - THE Trigger_Scheduler SHALL 支持
event类型触发器,在指定事件发生时立即执行 - WHEN 触发器执行完成, THE Trigger_Scheduler SHALL 更新
trigger_jobs表中的last_run_at和next_run_at - WHEN 触发器
status = 'disabled', THE Trigger_Scheduler SHALL 跳过该触发器不执行 - THE Trigger_Scheduler SHALL 提供
fire_event(event_name, payload)方法,用于触发事件驱动型任务 - IF 触发器执行过程中发生错误, THEN THE Trigger_Scheduler SHALL 记录错误日志但不中断其他触发器的执行
需求 11:迁移脚本管理
用户故事: 作为后端开发者,我需要所有数据库变更都有对应的迁移脚本,以便变更可追溯、可重放。
验收标准
- THE Migration_Script SHALL 将所有业务表的 DDL 存放在
db/zqyy_app/migrations/目录中 - THE Migration_Script SHALL 使用日期前缀命名(格式:
YYYY-MM-DD__<描述>.sql) - THE Migration_Script SHALL 使用 UTF-8 编码,纯 SQL(非 ORM)
- THE Migration_Script SHALL 在每个脚本中包含回滚语句(以注释形式)
- THE Migration_Script SHALL 使用幂等语法(
IF NOT EXISTS、ON CONFLICT DO NOTHING),确保重复执行不会报错
需求 12:DDL 测试库落库与文档同步
用户故事: 作为后端开发者,我需要所有 DDL 变更在测试库中实际执行验证,并同步更新数据库手册和 DDL 基线。
验收标准
- WHEN 迁移脚本编写完成, THE Task_Manager SHALL 在
test_zqyy_app测试库中执行迁移脚本,验证无错误 - WHEN 迁移脚本执行成功, THE Task_Manager SHALL 创建或更新
docs/database/BD_Manual_biz_tables.md数据库手册,包含变更说明、兼容性影响、回滚策略、验证 SQL(至少 3 条) - WHEN 迁移脚本执行成功, THE Task_Manager SHALL 运行
python scripts/ops/gen_consolidated_ddl.py重新生成 DDL 基线文件 - WHEN 种子数据脚本执行成功, THE Task_Manager SHALL 在数据库手册中记录种子数据内容(触发器配置)
需求 13:小程序前端页面原型还原(强制)
用户故事: 作为产品经理,我需要小程序前端页面严格忠于 docs/h5_ui/pages/ 中的 H5 原型图结构和视觉细节,确保最终实现与设计稿高度一致。
原型图索引
| 原型文件 | 对应小程序页面 | 说明 |
|---|---|---|
docs/h5_ui/pages/task-list.html |
pages/task-list/task-list |
任务列表页(首页),含业绩进度卡片、置顶/一般/已放弃三区域 |
docs/h5_ui/pages/task-detail.html |
pages/task-detail/task-detail |
任务详情页 - 高优先召回(theme-red Banner) |
docs/h5_ui/pages/task-detail-priority.html |
pages/task-detail/task-detail |
任务详情页 - 优先召回(theme-orange Banner) |
docs/h5_ui/pages/task-detail-relationship.html |
pages/task-detail/task-detail |
任务详情页 - 关系构建(theme-pink Banner) |
docs/h5_ui/pages/task-detail-callback.html |
pages/task-detail/task-detail |
任务详情页 - 客户回访(theme-teal Banner) |
docs/h5_ui/pages/notes.html |
pages/notes/notes |
备注记录页 |
docs/h5_ui/pages/customer-detail.html |
pages/customer-detail/customer-detail |
客户详情页 |
验收标准
13.A 结构还原(强制)
- WHEN 实现任务列表页时, THE 小程序页面 SHALL 严格还原原型图中的以下结构层次:顶部用户信息区(头像 + 姓名 + 角色标签 + 门店名)→ 业绩进度卡片(5 段档位进度条 + 课时数据含红戳 + 奖金激励 + 预计收入)→ 任务列表区(📌 置顶区 / 一般任务区 / 已放弃区三个分区,每个分区有标签 + 计数)
- WHEN 实现任务卡片时, THE 每张任务卡片 SHALL 包含原型图中的全部元素:左侧 4px 彩色边框(高优先=红、优先=橙、关系构建=粉、客户回访=青)、任务类型标签(渐变色圆角矩形)、客户姓名、爱心 icon(💖/🧡/💛/💙)、备注指示器(📝)、描述行(最近到店 + 余额)、AI 建议行(含 AI 机器人 icon)、右侧箭头
- WHEN 实现任务详情页时, THE 页面 SHALL 严格还原原型图中的以下模块顺序:通栏 Banner(导航栏 + 客户信息 + 放弃按钮)→ 维客线索卡片(客户基础/消费习惯/玩法偏好/重要反馈,每条含大类标签 + 摘要 + 详情 + 来源标注)→ 与我的关系卡片(爱心档位标签 + 进度条 + RS 分数 + 描述 + 近期服务记录列表)→ 任务建议卡片(建议执行 + 话术参考含复制按钮)→ 我给 TA 的备注卡片(备注列表含星星评分 + 删除按钮)→ 底部操作栏(问问助手 + 备注两个按钮)
- WHEN 实现备注弹窗时, THE 弹窗 SHALL 包含原型图中的全部元素:标题行(添加备注 + 展开评价按钮)、可折叠的星星评分区(再次服务意愿 1-5 星 + 再来店可能性 1-5 星,各含文字提示)、文本输入区、保存按钮
- WHEN 实现长按上下文菜单时, THE 菜单 SHALL 还原原型图中的交互:遮罩层 + 圆角菜单面板(置顶/取消置顶、备注、放弃/取消放弃等选项)
- WHEN 实现备注记录页时, THE 页面 SHALL 还原原型图中的列表结构:每条备注含内容文本 + 底部标签(助教/客户类型标签 + 时间戳)
13.B 视觉还原(强制)
- THE 小程序页面 SHALL 使用与原型图一致的 TDesign 色彩体系:primary=#0052d9、success=#00a870、warning=#ed7b2f、error=#e34d59,灰阶色板 gray-1(#f3f3f3) 至 gray-13(#242424)
- THE 任务详情页 Banner SHALL 根据任务类型使用不同主题色:高优先召回=theme-red、优先召回=theme-orange、关系构建=theme-pink、客户回访=theme-teal,与原型图中的渐变背景一致
- THE 维客线索大类标签 SHALL 使用原型图中的配色方案:客户基础=primary/10 底色 + primary 文字、消费习惯=success/10 底色 + success 文字、玩法偏好=purple-500/10 底色 + purple-600 文字、重要反馈=error/10 底色 + error 文字
- THE 星星评分组件 SHALL 还原原型图中的视觉效果:填充星/空心星 SVG、支持半星显示(用于展示 AI 评分映射)
- THE 业绩进度卡片 SHALL 还原原型图中的 5 段档位进度条(按比例宽度:0-100 占 45.45%、100-130/130-160/160-190/190-220 各占 13.64%)、红戳动画(盖戳效果)、奖金金额突出样式
13.C WXML/WXSS 技术规范(强制)
- THE 小程序页面 SHALL 使用 WXML 语法而非 HTML 语法:
<view>替代<div>、<text>替代<span>/<p>、<image>替代<img>、<navigator>替代<a>,禁止使用 HTML 标签 - THE 小程序样式 SHALL 使用 WXSS 语法:使用
rpx单位替代px(750rpx = 屏幕宽度)、使用@import导入公共样式、禁止使用rem/em/vw/vh等 CSS 单位 - THE 小程序页面 SHALL 使用
wx:for替代 JavaScript 循环渲染、wx:if/wx:elif/wx:else替代条件渲染、bind:tap替代onclick、data-*+e.currentTarget.dataset替代 DOM 操作 - THE 小程序页面 SHALL 禁止使用以下 Web 特性:
document.*、window.*、localStorage(用wx.setStorageSync)、fetch/XMLHttpRequest(用wx.request)、CSSposition: fixed的bottom: 0底部栏(用小程序安全区域适配) - THE 小程序样式 SHALL 仅使用小程序支持的 CSS 选择器:
.class、#id、element、element, element、::after、::before,禁止使用>(子选择器)、+(相邻兄弟)、~(通用兄弟)、[attr](属性选择器)等不支持的选择器 - THE 小程序页面 SHALL 使用
<block>标签作为无渲染包裹容器(替代 HTML 的<template>或 React 的<Fragment>),<block>不会生成真实 DOM 节点
13.D TDesign 组件使用规范(强制)
- THE 小程序页面 SHALL 优先使用 TDesign 组件库中的组件,组件引入路径格式为
tdesign-miniprogram/{组件名}/{组件名},在页面.json的usingComponents中注册 - THE 以下 UI 元素 SHALL 使用对应的 TDesign 组件:导航栏→
t-navbar、底部标签栏→t-tab-bar、对话框→t-dialog、轻提示→t-toast、弹出层→t-popup、空状态→t-empty、加载→t-loading、骨架屏→t-skeleton、标签→t-tag、搜索框→t-search - THE TDesign 组件样式覆盖 SHALL 使用以下 4 种方式之一:
style/custom-style属性、解除样式隔离(addGlobalClass)、外部样式类(t-class)、CSS 变量(--td-*),禁止直接修改node_modules中的组件源码 - THE 小程序
app.jsonSHALL 移除"style": "v2"配置项,避免 TDesign 组件样式错乱 - WHEN 原型图中的 UI 元素无法用 TDesign 组件直接实现时(如自定义进度条、红戳动画、话术气泡等), THE 开发者 SHALL 使用原生 WXML + WXSS 自定义实现,但视觉效果必须与原型图一致
13.E 原型图参考流程(强制)
- WHEN 开始实现任何小程序页面前, THE 开发者 SHALL 首先阅读对应的
docs/h5_ui/pages/*.html原型文件,提取页面结构、组件层次、样式细节、交互行为 - WHEN 原型图中使用 Tailwind CSS 类名时, THE 开发者 SHALL 将其转换为等效的 WXSS 样式(如
px-4→padding: 0 32rpx、rounded-xl→border-radius: 24rpx、text-sm→font-size: 28rpx) - WHEN 原型图中使用
<iframe>嵌套页面时, THE 开发者 SHALL 理解这是原型展示方式,实际小程序中使用wx.navigateTo页面跳转 - WHEN 原型图中使用
onclick/history.back()等 Web API 时, THE 开发者 SHALL 转换为小程序等效 API:bind:tap+wx.navigateBack() - THE 开发者 SHALL 在实现前加载
wechat-miniprogramPower 的相关 steering 文件(view-layer.md、tdesign.md、builtin-components.md),确保使用正确的小程序语法和 TDesign 组件规范 - THE 开发者 SHALL 在实现前阅读项目内的 H5 转小程序避坑指南
apps/miniprogram/doc/h5-to-miniprogram-pitfalls.md,该文档基于本项目已转换页面的实际踩坑经验整理,涵盖标签映射、rpx 换算、事件系统、TDesign 覆盖方式、高频踩坑清单及新页面开发 Checklist,所有条目具有强制参考效力
需求 14:任务系统属性测试
用户故事: 作为后端开发者,我需要通过属性测试验证任务系统核心逻辑的正确性。
验收标准
- THE 属性测试 SHALL 验证:对于任意
(site_id, assistant_id, member_id, task_type)组合,status = 'active'的任务最多只有一条(唯一性不变量) - THE 属性测试 SHALL 验证:对于任意任务类型变更操作,旧任务被标记为
inactive且新任务被创建为active(状态机正确性) - THE 属性测试 SHALL 验证:对于任意
follow_up_visit任务,当expires_at不为 NULL 且当前时间超过expires_at时,轮询后status变为inactive(有效期机制) - THE 属性测试 SHALL 验证:对于任意任务放弃操作,
abandon_reason不为空字符串(放弃原因必填) - THE 属性测试 SHALL 验证:对于任意备注创建操作,
rating_service_willingness和rating_revisit_likelihood的值在 NULL 或 1-5 范围内(评分范围约束) - THE 属性测试 SHALL 验证:对于任意召回完成事件,
completed_task_type记录了完成时的任务类型快照(完成类型快照不变量) - THE 属性测试 SHALL 验证:对于任意备注回溯操作,重分类后的备注
type从normal变为follow_up(回溯分类正确性)
附录:原型还原强制规则摘要
以下规则适用于本 SPEC 及所有后续小程序页面开发 SPEC,具有全局约束力。
- 原型图是唯一视觉真相:
docs/h5_ui/pages/*.html中的结构、层次、元素、配色、间距、交互行为是小程序页面实现的唯一参考标准。任何偏离原型图的实现都需要明确的产品确认。 - WXML ≠ HTML:严禁在小程序中使用 HTML 标签(div/span/p/a/img 等),必须使用小程序原生标签(view/text/image/navigator 等)。
- WXSS ≠ CSS:使用 rpx 单位、仅支持有限选择器、无 DOM/BOM API、样式隔离机制不同。Tailwind CSS 类名必须手动转换为 WXSS。
- TDesign 优先:凡 TDesign 组件库能覆盖的 UI 元素,必须使用 TDesign 组件;自定义实现仅限 TDesign 无法覆盖的场景。
- Power 文档优先:实现前必须加载
wechat-miniprogramPower 的相关 steering 文件,确保语法和组件用法正确。 - 项目踩坑指南必读:实现前必须阅读
apps/miniprogram/doc/h5-to-miniprogram-pitfalls.md,该文档是基于本项目实际转换经验的避坑手册,涵盖 WXML/WXSS 差异、事件系统、TDesign 用法、rpx 换算规则及新页面开发 Checklist。