27 KiB
Objects(实体)
持久名词 + 字段 + 归属系统。以
graph/ontology.jsonl为机器可审计真源。
entity:store
门店。宠物店主体,所有业务数据的归属范围。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| name | VARCHAR | 店铺名称 |
| logo | VARCHAR | 店铺 Logo |
| phone | VARCHAR | 联系电话 |
| address | VARCHAR | 地址 |
| latitude | Double | 纬度(公开报告页不返回) |
| longitude | Double | 经度(公开报告页不返回) |
| intro | TEXT | 简介 |
| owner_id | BIGINT | 老板用户 ID |
| invite_code | VARCHAR(8) | legacy 兼容字段;不返回客户端、不再作为员工注册凭证 |
| booking_day_start | LocalTime | 预约首号 |
| booking_last_slot_start | LocalTime | 预约末号 |
| booking_capacity | INT | 门店承诺的并发接待数(1~10) |
| onboarding_status | VARCHAR(16) | unknown(历史不可推断)/ in_progress / completed |
| onboarding_completed_at | DATETIME | 老板显式完成开通时间 |
| onboarding_completed_by_user_id | BIGINT | 显式完成开通的老板 |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Backend Core(
StoreController/StoreService/StoreMapper) - 代码:
backend/src/main/java/com/petstore/entity/Store.java - 文档:
docs/产品设计文档.md §三 t_store - 测试:
StoreControllerTest - 证据:
anchored
entity:staff_invitation
一次性员工邀请。老板按员工本人手机号创建,1~30 天有效、可撤销且只能接受一次。
| 字段 | 类型 | 说明 |
|---|---|---|
| invitation_id | VARCHAR(36) | 对外随机 ID,管理端撤销使用 |
| token_hash | VARCHAR(64) | 256-bit 原始 token 的 SHA-256;原始 token 不落库 |
| store_id | BIGINT | 受邀门店 |
| invited_name / invited_phone | VARCHAR | 受邀姓名 / 服务端核验手机号;API 只返回脱敏手机号 |
| status | VARCHAR(16) | pending / accepted / revoked / expired |
| expires_at | DATETIME | 到期时间 |
| created_by_user_id | BIGINT | 创建邀请的老板 |
| accepted_by_user_id / accepted_at | BIGINT / DATETIME | 首次成功接受回执 |
| revoked_by_user_id / revoked_at | BIGINT / DATETIME | 撤销回执 |
| create_time / update_time | DATETIME | 时间戳 |
- 安全边界:原始 token 仅在创建响应返回一次;列表/预览不返回
token_hash、原始 token 或完整手机号。 - 代码:
backend/src/main/java/com/petstore/entity/StaffInvitation.java、service/StaffInvitationService.java - 测试:
StaffInvitationServiceTest、StoreOnboardingMigrationTest - 证据:
anchored
entity:audit_log
不可变操作审计。记录开店、门店配置和员工权限类操作,与可统计经营事实 BusinessEvent 分开。
| 字段 | 类型 | 说明 |
|---|---|---|
| audit_id | VARCHAR(36) | 随机审计 ID |
| store_id | BIGINT | 强制门店范围 |
| actor_user_id / actor_role | BIGINT / VARCHAR | 操作人快照 |
| action | VARCHAR(64) | 受控动作名 |
| target_type / target_id | VARCHAR | 目标类型 / 安全引用 ID |
| outcome | VARCHAR(16) | success 等受控结果 |
| metadata_json | TEXT | 服务端白名单低敏标量 JSON |
| occurred_at / create_time | DATETIME | 发生 / 入库时间 |
- 禁止字段:手机号、token/URL、openid/unionid、密码/密钥、IP、地址/坐标、备注/内容和原始请求体。
- 代码:
backend/src/main/java/com/petstore/entity/AuditLog.java、service/AuditLogService.java - 测试:
AuditLogServiceTest、StoreOnboardingMigrationTest - 证据:
anchored
entity:user
用户。三角色:boss(老板)/ staff(员工)/ customer(宠主)。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| username | VARCHAR | 用户名 |
| password | VARCHAR | 密码(@JsonIgnore 不返回;登录成功 setPassword(null)) |
| name | VARCHAR | 姓名/技师名 |
| phone | VARCHAR | 手机号 |
| avatar | VARCHAR | 头像 |
| store_id | BIGINT | 所属店铺(customer 可空) |
| role | VARCHAR | boss / staff / customer |
| wechat_openid | VARCHAR(64) | 微信小程序 openid(@JsonIgnore,仅服务端使用) |
| wechat_unionid | VARCHAR(64) | 微信 unionid(@JsonIgnore) |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Backend Core(
UserController/UserService/UserMapper) - 代码:
backend/src/main/java/com/petstore/entity/User.java - 文档:
docs/产品设计文档.md §三 t_user、docs/.agents/common-context.md 术语规则 - 测试:
UserServiceLoginStrategyTest - 证据:
anchored
entity:appointment
预约。状态机:new(待开始)→ doing(服务中)→ done(已完成)/ cancel(已取消)。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| pet_name | VARCHAR | 宠物名称 |
| pet_type | VARCHAR | 宠物类型(猫/狗/其他) |
| service_type | VARCHAR | 服务类型 |
| appointment_time | DATETIME | 预约开始时间(半小时粒度,按服务时长检查跨桶容量) |
| duration_minutes | INT | 下单时的服务时长快照(30~480,30 分钟粒度) |
| status | VARCHAR | new / doing / done / cancel |
| store_id | BIGINT | 所属门店 |
| customer_user_id | BIGINT | 被服务客户账号;新业务归属主字段 |
| created_by_user_id | BIGINT | 实际创建预约的登录账号(customer/boss/staff) |
| user_id | BIGINT | legacy 兼容;新数据镜像 customer_user_id |
| assigned_user_id | BIGINT | 服务技师 ID(开始服务时赋值,API 别名 assignedStaffId) |
| pet_id | BIGINT | 宠物档案 ID |
| remark | TEXT | 备注 |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Backend Core(
AppointmentController/AppointmentService/AppointmentMapper) - 代码:
backend/src/main/java/com/petstore/entity/Appointment.java、backend/src/main/java/com/petstore/service/AppointmentService.java - 文档:
docs/产品设计文档.md §三 t_appointment §5.2 预约管理 - 测试:
AppointmentServiceTest、AppointmentControllerDetailTest - 证据:
anchored
entity:report
服务报告。一约一份,提交后锁死;必须绑定 appointment_id。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| appointment_id | BIGINT | 关联预约 ID(唯一约束 uk_report_appointment) |
| remark | TEXT | 备注 |
| customer_user_id | BIGINT | 报告归属客户,从预约派生 |
| author_staff_id | BIGINT | 实际提交报告的门店账号 |
| user_id | BIGINT | legacy 兼容;新数据镜像 author_staff_id |
| store_id | BIGINT | 所属门店 |
| report_token | VARCHAR | 公开访问令牌(UUID,不带回包给公开页) |
| pet_name | VARCHAR | 宠物名(冗余) |
| service_type | VARCHAR | 服务类型(冗余) |
| appointment_time | DATETIME | 服务时间(冗余) |
| staff_name | VARCHAR | 服务技师名快照(优先取预约 assigned_user_id) |
| send_status | VARCHAR(16) | unknown(历史不可确认)/ unsent(新报告待发送)/ sent(已显式确认) |
| sent_at | DATETIME | 首次显式确认发送时间 |
| sent_by_user_id | BIGINT | 首次确认发送的门店员工 |
| send_channel | VARCHAR(16) | wechat / qr / other;首次确认后不可覆盖 |
| highlight_video_url | VARCHAR(500) | 成片 MP4 相对 URL |
| highlight_video_status | VARCHAR(32) | processing / done / failed |
| highlight_video_error | VARCHAR(500) | 错误信息 |
| highlight_duration_sec | INT | 成片时长 |
| highlight_compose_mode | VARCHAR(16) | preset / interleave |
| highlight_fail_reason | VARCHAR(16) | material / service / network / unknown |
| highlight_share_cover_url | VARCHAR(500) | 成片首帧封面 |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Report Media Backend(
ReportController/ReportService/ReportMapper) - 代码:
backend/src/main/java/com/petstore/entity/Report.java、backend/src/main/java/com/petstore/service/ReportService.java - 文档:
docs/产品设计文档.md §三 t_report §5.3 服务报告、docs/API-报告成片字段契约.md - 测试:
ReportServiceTest、ReportControllerTest - 证据:
anchored
entity:report_lead
留资线索。宠主在公开报告页提交手机号,进入门店回访池。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| report_id | BIGINT | 关联报告 ID |
| store_id | BIGINT | 所属门店(用于回访池范围) |
| phone | VARCHAR | 手机号 |
| pet_name | VARCHAR | 宠物名(冗余) |
| service_type | VARCHAR | 服务类型(冗余) |
| wechat_openid | VARCHAR(64) | 微信 openid(脱敏返回 wechatOpenidMasked) |
| wechat_unionid | VARCHAR(64) | 微信 unionid(脱敏返回 wechatUnionidMasked) |
| reminder_type | VARCHAR | 提醒类型 |
| remind_date | DATE | 下次建议日期 |
| remind_status | VARCHAR | pending / sent / canceled / unsubscribed |
| unsubscribe_token | VARCHAR | 退订令牌 |
| client_ip | VARCHAR | 留资 IP(合规留证) |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Report Media Backend(
ReportLeadController/ReportLeadService) - 代码:
backend/src/main/java/com/petstore/controller/ReportLeadController.java、backend/src/main/java/com/petstore/entity/ReportLead.java - 文档:
docs/本期主线-下一步产品优化点.md §C 留资 - 测试:暂无(Batch D 未补
ReportLeadControllerTest,列为documentedgap) - 证据:
anchored(脱敏与跨店校验已实现并测试覆盖;去重逻辑documented)
entity:follow_up_task
门店回访执行任务。ReportLead 保留宠主同意和来源事实,本实体承载员工可领取、可改期、可终结的操作状态以及真实再次预约引用。
| 字段 | 类型 | 说明 |
|---|---|---|
| id / task_id | BIGINT / VARCHAR(36) | 内部主键 / Admin 对外随机 ID |
| store_id / store_customer_id | BIGINT | 同店范围 / canonical 客户主档 |
| source_lead_id / source_report_id | BIGINT | 来源留资 / 报告 |
| status | VARCHAR(16) | pending / in_progress / completed / canceled |
| outcome | VARCHAR(24) | rebooked / not_interested / invalid_contact / unsubscribed |
| due_date / assigned_user_id | DATE / BIGINT | 回访日 / 当前领取人 |
| attempt_count / last_attempt_outcome | INT / VARCHAR(24) | 已联系次数 / no_answer 或 follow_later |
| last_contacted_at / last_contacted_by_user_id | DATETIME / BIGINT | 最近联系回执 |
| closed_at / closed_by_user_id | DATETIME / BIGINT | 终态回执;退订取消无员工关闭人 |
| rebooked_appointment_id | BIGINT | 仅真实同店预约保存成功后写入 |
| create_time / update_time / version | DATETIME / DATETIME / BIGINT | 时间戳与并发版本 |
- 归属系统:Backend Core + Store Admin FE
- 代码:
backend/src/main/java/com/petstore/entity/FollowUpTask.java、service/FollowUpTaskService.java - 文档:
docs/架构决策-FollowUpTask回访状态机与再次预约归因-2026-08-02.md - 测试:
FollowUpTaskServiceTest、FollowUpTaskMigrationTest、AdminFollowUpTaskControllerTest - 证据:
anchored
entity:business_event
不可变业务事件。预约、履约、报告打开与留资等经营事实的统一持久化入口,为报告漏斗和 StoreCustomer 时间线提供可统计事实源。
| 字段 | 类型 | 说明 |
|---|---|---|
| id / event_id | BIGINT / VARCHAR(36) | 内部主键 / 随机事件 ID |
| event_type / event_version | VARCHAR(64) / INT | 事件类型与 schema 版本 |
| store_id / store_customer_id | BIGINT | 门店范围 / 可选客户关系 |
| aggregate_type / aggregate_id | VARCHAR(32) / BIGINT | 关联业务对象 |
| actor_user_id / actor_role | BIGINT / VARCHAR(16) | 操作人快照,匿名事件可空 |
| source | VARCHAR(32) | customer / admin / public_report / system / migration |
| occurred_at / create_time | DATETIME | 发生时间 / 入库时间 |
| metadata_json | TEXT | 服务端白名单低敏标量 JSON |
| idempotency_key | VARCHAR(128) | 可选幂等键 |
- 隐私:不保存手机号、报告 token/hash、媒体 URL、IP、openid/unionid、备注或原始请求体
- 不变量:只追加,不更新、不软删;通用事件明细不直接暴露给前端
- 归属系统:Backend Core(跨 Report Media Backend 写入点)
- 代码:
backend/src/main/java/com/petstore/entity/BusinessEvent.java、BusinessEventService.java - 测试:
BusinessEventServiceTest、BusinessEventMigrationTest - 证据:
anchored
Batch 2 录入实体
entity:pet
宠物档案。归属某客户(ownerUserId);商家/员工通过预约关联查看本店服务过的宠物。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| name | VARCHAR | 昵称 |
| pet_type | VARCHAR | 猫/狗/其他 |
| breed | VARCHAR | 品种(可选) |
| avatar | VARCHAR | 头像相对路径 |
| owner_user_id | BIGINT | 所属用户(客户) |
| remark | TEXT | 备注 |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Backend Core(
PetController/PetService/PetMapper) - 代码:
backend/src/main/java/com/petstore/entity/Pet.java、controller/PetController.java、service/PetService.java - 文档:
docs/产品设计文档.md §三 t_pet(隐含,预约含 pet_name/pet_type) - 测试:暂无
PetControllerTest(gap,建议补) - 证据:
anchored(实体与跨用户/跨店校验已实现;测试覆盖为gap)
entity:service_type
服务类型。storeId 为空表示系统默认(不可改删);非空为门店自定义。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| store_id | BIGINT | 门店 ID(NULL=系统默认) |
| name | VARCHAR | 服务名称 |
| duration_minutes | INT | 预计服务时长(30~480,30 分钟粒度) |
| create_time | DATETIME | 创建时间 |
- 归属系统:Backend Core(
ServiceTypeController/ServiceTypeService/ServiceTypeMapper) - 代码:
backend/src/main/java/com/petstore/entity/ServiceType.java、controller/ServiceTypeController.java - 文档:
docs/产品设计文档.md §三 t_service_type §5.2 服务类型 - 测试:
ServiceTypeControllerTest(12 用例) - 证据:
anchored
entity:schedule_block
门店日程手动占用。以半小时为粒度连续占用,用于到店客(walk_in,消耗一个容量)或暂停预约(blocked,关闭覆盖范围内全部容量)。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| store_id | BIGINT | 所属门店(非空) |
| slot_start | DATETIME | 半小时档起始时刻 |
| duration_minutes | INT | 连续占用时长(30~480,30 分钟粒度) |
| block_type | VARCHAR(32) | walk_in / blocked |
| note | VARCHAR(500) | 备注 |
| created_by_user_id | BIGINT | 创建人(从上下文派生) |
| create_time / update_time | DATETIME | 时间戳 |
| deleted | TINYINT(1) | 软删 |
- 归属系统:Backend Core(
ScheduleController/ScheduleService/ScheduleBlockMapper) - 代码:
backend/src/main/java/com/petstore/entity/ScheduleBlock.java、controller/ScheduleController.java、service/ScheduleService.java - 文档:
docs/产品设计文档.md §5.2(隐含,预约时段占用) - 测试:
ScheduleControllerTest、BookingCapacityServiceTest - 证据:
anchored
entity:report_image
报告媒体。photo_type 分组:before(服务前)/ after(服务后)/ during(服务过程中)。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| report_id | BIGINT | 关联报告 ID |
| photo_url | VARCHAR(500) | 媒体 URL |
| photo_type | VARCHAR(20) | before / after / during |
| media_type | VARCHAR(20) | photo / video(默认 photo) |
| sort_order | INT | 同类型内排序 |
| create_time | DATETIME | 创建时间 |
- 归属系统:Report Media Backend(
ReportImageMapper) - 代码:
backend/src/main/java/com/petstore/entity/ReportImage.java、mapper/ReportImageMapper.java - 文档:
docs/产品设计文档.md §三 t_report_image - 测试:间接(
ReportServiceTest#createWithImagesSavesEachImage) - 证据:
anchored
entity:highlight_video
服务回顾短片。当前作为 entity:report 的 highlight_* 字段承载,非独立 JPA 实体;状态机 processing / done / failed。
| 字段 | 类型 | 说明 |
|---|---|---|
| report_id | BIGINT | 关联报告(即 Report.id) |
| highlight_video_url | VARCHAR(500) | 成片 MP4 相对 URL |
| highlight_video_status | VARCHAR(32) | processing / done / failed |
| highlight_video_error | VARCHAR(500) | 错误信息 |
| highlight_duration_sec | INT | 成片时长 |
| highlight_compose_mode | VARCHAR(16) | preset / interleave |
| highlight_fail_reason | VARCHAR(16) | material / service / network / unknown |
| highlight_share_cover_url | VARCHAR(500) | 成片首帧封面 |
- 归属系统:Report Media Backend(
ReportHighlightVideoService) - 代码:
backend/src/main/java/com/petstore/entity/Report.java(字段承载)、service/ReportHighlightVideoService.java - 文档:
docs/API-报告成片字段契约.md、docs/洗美报告短视频成片方案.md - 测试:暂无独立测试(
gap,建议补成片三态用例) - 证据:
anchored(字段与三态已实现;FFmpeg 集成测试为gap)
entity:session_token
HMAC session token。非 JPA 实体,鉴权上下文数据结构;token 格式 base64url(payload).base64url(sig),HMAC-SHA256,默认 7 天。
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | Long | 用户 ID |
| storeId | Long | 门店 ID(customer 可空) |
| role | String | boss / staff / customer |
| exp | long | Unix 秒过期时间 |
- 归属系统:Backend Core(
SessionTokenService/CurrentUser/CurrentUserContext/AuthInterceptor) - 代码:
backend/src/main/java/com/petstore/auth/SessionTokenService.java、CurrentUser.java、CurrentUserContext.java、AuthInterceptor.java - 文档:
docs/ontology/rules.md#rule:BR-AUTH-001 - 测试:
SessionTokenServiceTest(7 用例) - 证据:
anchored
Batch 2.1 补录实体(audit_drift 发现的遗漏)
entity:report_testimonial
宠主寄语。生成分享海报时填写的一句话(口碑素材);同一报告保留一条,重复提交更新内容与时间。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| report_id | BIGINT | 关联报告(唯一约束,一报告一寄语) |
| store_id | BIGINT | 所属门店 |
| content | VARCHAR(200) | 寄语内容 |
| is_public | TINYINT(1) | 是否公开(默认 1) |
| create_time / update_time | DATETIME | 时间戳 |
- 归属系统:Report Media Backend(
ReportTestimonialService) - 代码:
backend/src/main/java/com/petstore/entity/ReportTestimonial.java、service/ReportTestimonialService.java - 入口:
POST /api/report/{token}/testimonial→ReportController#submitTestimonial - 证据:
anchored
entity:service_interval
服务建议周期配置。用于「下次该洗了」的日期预测;store_id 为 null 表示系统默认,老板可针对自家店覆盖。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | BIGINT | 主键 |
| store_id | BIGINT | 门店 ID(NULL=系统默认) |
| service_name | VARCHAR(64) | 与 t_service_type.name 对齐作为匹配键 |
| pet_type | VARCHAR(16) | 按宠物类型细分(dog/cat/other),NULL=全部 |
| interval_days_min | INT | 建议最短间隔(天) |
| interval_days_max | INT | 建议最长间隔(天) |
| create_time | DATETIME | 创建时间 |
- 归属系统:Report Media Backend(
ReportLeadService#suggestNext读取) - 代码:
backend/src/main/java/com/petstore/entity/ServiceInterval.java - 证据:
anchored(实体存在;独立 controller 接口gap,目前由ReportLeadService内部读取)
entity:highlight_fail_reason
成片失败原因归类(非 JPA 枚举)。对宠主展示口径,不含技术堆栈。
| 枚举值 | code | 说明 |
|---|---|---|
| MATERIAL | material | 素材缺失/无法读取/编码失败 |
| SERVICE | service | 合成服务异常(ffmpeg/磁盘等) |
| NETWORK | network | 网络类异常(预留) |
| UNKNOWN | unknown | 未归类 |
- 归属系统:Report Media Backend
- 代码:
backend/src/main/java/com/petstore/entity/HighlightFailReason.java - 证据:
anchored(jpa: false)
entity:customer_timeline
门店客户事实时间线(非 JPA 只读模型)。以 canonical StoreCustomer.id 为稳定客户关系键,把已经持久化的 BusinessEvent 投影为门店可理解的预约、履约、报告发送/打开、留资和回访任务记录;被合并投影的事件通过别名指针一并读取,不改写历史事件。
| 字段 | 说明 |
|---|---|
| customer | 客户称呼、脱敏手机号、首次来源、首次/最近接触时间 |
| total / page / pageSize / hasMore | 稳定倒序分页信息 |
| list | eventId/eventType/occurredAt/title/description 与可选预约/报告/留资/FollowUpTask 低敏摘要 |
- 归属系统:Backend Core / Store Admin FE
- 代码:
backend/src/main/java/com/petstore/service/StoreCustomerTimelineService.java、admin/src/views/CustomersView.vue - 隐私边界:不返回手机号原文、备注、媒体、报告/邀请 token、openid/unionid、IP 或原始
metadata_json - 证据:
anchored(jpa: false)
entity:current_user
当前登录用户上下文(非 JPA record)。由 AuthInterceptor 从 entity:session_token 解析后写入 ThreadLocal,与令牌实体区分。
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | Long | 用户 ID |
| storeId | Long | 所属门店(customer 可为 null) |
| role | String | boss / staff / customer |
- 归属系统:Backend Core(auth 包)
- 代码:
backend/src/main/java/com/petstore/auth/CurrentUser.java、CurrentUserContext.java、AuthInterceptor.java - 证据:
anchored(jpa: false)
Batch:门店 Web 后台(Phase A)
产品依据:
docs/门店管理后台升级方案-对标宠老板.md。
各对象按实际证据标记;收银/会员资产仍见下方 gap 占位。
entity:admin_console
门店 Web 管理后台(非 JPA)。与 uni-app 小程序并存的桌面优先管理端;登录落点为工作台,不做收银/库存首页。
| 字段(概念) | 说明 |
|---|---|
| surface | Web admin |
| navModules | workbench / appointments / reports / customers / leads / schedule / settings |
| storeScope | 单店 storeId |
| roleGate | Phase A:boss / staff 均可读写本店;customer 禁止 |
- 归属系统:Store Admin FE + Backend Core
- 证据:
documented(jpa: false) - 约束:
rule:BR-ADMIN-001…BR-ADMIN-004
entity:workbench
今日工作台(非 JPA 聚合视图)。指标卡 + 按履约优先级排序的行动队列 + 报告漏斗摘要;行动来自 appointment/report/follow_up_task/highlight,报告漏斗来自 BusinessEvent,无独立工作台表。服务端按完整本店数据计算准确总数,不再由前端拉取前 200 条估算。
| 字段(概念) | 说明 |
|---|---|
| todayAppointmentCount / todayDoneCount | 今日预约 / 今日完成 |
| overdueAppointmentCount / inServiceCount / upcomingTodayCount | 逾期未开始 / 服务中 / 今日待开始 |
| dueFollowUpCount / highlightAnomalyCount / unsentReportCount | 到期回访 / 成片失败或处理超时 / 新报告待发送 |
| actionGroups | entity:workbench_todo_item[](每组最多 3 条低敏预览) |
| reportFunnel | 已提交/已确认发送/已打开/已留资/回访后真实再次预约;全部来自 BusinessEvent |
| anomalyList | 成片失败或待回访最近 N 条 |
- 代码:
admin/src/views/WorkbenchView.vue、AdminBusinessEventController、AdminWorkbenchService、AdminBusinessEventService - 测试:
AdminBusinessEventControllerTest、AdminWorkbenchServiceTest、AdminBusinessEventServiceTest - 证据:
anchored - 动作:
action:view_workbench
entity:workbench_todo_item
工作台待办项。
| 字段 | 说明 |
|---|---|
| kind | overdue_appointment / in_service / upcoming_today / highlight_anomaly / unsent_report / follow_up_due |
| urgency | critical / high / normal |
| count | 数量 |
| items | 最多 3 条 resource ID + 宠物/服务/时间低敏预览;无手机号、token、媒体 URL |
| drilldownAction / filter | 下钻到的 admin list action 与预置筛选 |
- 代码:
AdminWorkbenchService、admin/src/views/WorkbenchView.vue - 测试:
AdminWorkbenchServiceTest - 证据:
anchored
entity:store_customer
StoreCustomer 门店客户主档(瘦身)。门店与客户的稳定关系实体,不是 entity:membership。后台读模型以它为入口,再聚合 Pet + Appointment + Report + ReportLead。
| 字段 | 说明 |
|---|---|
| id | 本店客户稳定 ID(API: storeCustomerId) |
| store_id | 本店范围 |
| customer_user_id | 可选全局 customer 账号;留资客户可先为空 |
| phone / display_name | 本店联系手机号与称呼;API 手机号默认脱敏 |
| source | 首次来源:customer_booking / assisted_booking / report_lead |
| first_contact_at / last_contact_at | 首次/最近接触时间 |
| merged_into_store_customer_id | 仅软删除投影使用;指向同店有效 canonical 主档,保持不可变事件连续性 |
| create_time / update_time / deleted | 审计与软删除 |
API 动态聚合字段:pets、lastVisitAt、lastReportId、leadStatus、source。lastVisitAt 只统计已开始/已完成的历史服务。
- 不做:余额、押金、积分、次卡、会员等级、批量导入持卡会员
- 证据:
anchored(t_store_customer+ 动态读模型) - 动作:
action:admin_list_service_customers
待录入(P1/P2 方向,gap 证据)
以下已在 graph/ontology.jsonl 以 evidence=gap + jpa=false 占位,不展开字段;Phase A 门店后台明确不做(rule:BR-ADMIN-004):
entity:membership(会员卡)— P1/P2 / C 期entity:stored_value(储值)— P1/P2entity:service_package(套餐/次卡)— P1/P2entity:report_history(宠主历史报告汇总)— P2entity:analytics_dashboard(经营分析看板)— B 期;A 期仅工作台轻量指标
后续如进入实现,再补完整字段、动作与规则。