# 02 — 交付联系电话精确查询与数据库索引

**What to build:** 让有权限的后台运营人员能够在店铺列表页面输入完整的 11 位 ASCII 联系电话并精确定位所有可见匹配店铺。该切片贯通前端筛选交互、现有列表 API、数据权限、数据库等值查询和性能索引，并用真实请求完成加载、空态、失败、组合筛选和重复号码验收。

**Blocked by:** 01 — 修复店铺列表参数校验与默认分页。

**Status:** ready-for-human

**架构通道:** 主通道为现有读取链路 `Handler → Service → Store → GORM/DTO`；辅助通道为 Infrastructure 数据库迁移和跨仓前端交付。

**完整业务边界:** 完整收口店铺列表联系电话精确查询这一用户行为，包括后端、数据库、前端、接口契约和验收证据。明确不修改店铺创建或更新接口的电话校验，不清洗历史号码，不建立唯一约束，不新增缓存、聚合、Repository 抽象或 Query 目录，也不改变前端既有页码状态策略。

- [x] 店铺列表接受可选 `contact_phone` 参数；非空值必须完整满足 11 位 ASCII 数字规则，空字符串与未传参数均视为不启用电话筛选。
- [x] 联系电话使用数据库等值匹配，不接受空格、全角数字、国家码、连字符、字母或长度不符的输入，也不执行 trim 或号码格式修复。
- [x] 联系电话与所有已有筛选条件按 AND 组合，计数查询与分页数据查询使用完全一致的过滤条件。
- [x] 相同联系电话的多个可见店铺均可返回；无匹配项返回成功空分页，不返回资源不存在错误。
- [x] 查询保持 `created_at DESC` 排序并排除软删除记录；代理账号无法通过相同联系电话看到本店铺及下级范围之外的店铺。
- [x] 超级管理员、平台账号和代理账号的真实 HTTP 集成测试覆盖精确匹配、非模糊匹配、重复号码、组合筛选、空参数、非法格式、空结果、分页、排序、软删除和数据隔离。
- [x] 数据库查询失败时返回脱敏的 HTTP 500、`code=2001`、`msg=内部服务器错误`，响应不泄露 SQL、主机、库名或驱动错误。
- [x] 数据库迁移创建名为 `idx_shop_contact_phone` 的非唯一部分 B-tree 索引，仅覆盖未软删除店铺的 `contact_phone`；回滚只删除该索引，不修改业务数据。
- [x] 在可控开发环境验证向上迁移、向下回滚和再次向上迁移，确认索引类型、列、非唯一属性及 `deleted_at IS NULL` 条件均符合契约。
- [x] OpenAPI 出现 `contact_phone`，准确描述 11 位 ASCII 数字、精确匹配、空值行为、AND 组合和分页限制；复用现有 Handler，不新增文档生成器实例。
- [ ] 后台店铺列表筛选区提供“联系电话”输入、查询和清空能力；非法值展示中文提示并阻止请求，空值不提交该参数，合法值与其他筛选一并提交。
- [ ] 前端查询期间展示加载状态，无匹配项展示空态，请求失败展示可重试反馈且不保留伪装成新结果的旧数据。
- [ ] 浏览器网络请求与真实接口响应共同证明精确匹配、AND 组合、重复号码、空结果、合法分页和代理隔离，而不是只依据页面展示验收。
- [x] UR#60 中文总结及 README 索引记录本切片的前后端契约、索引上线与回滚核验、测试证据以及明确排除的历史数据清理范围。
- [ ] 运行前后端各自的目标测试、格式化、静态检查和构建；本切片通过人工验收后可独立演示完整联系电话查询行为。（后端已完成；当前仓库无前端源码，待前端仓库执行并人工验收。）
