# 程哥猫咪优选 V1

## 项目结构与运行
- app/page.tsx：响应式图库、逐层筛选、直播灯箱、导入、审核、鉴定、分类、权限、备份工作台。
- app/api/v1/[...path]/route.ts：统一版本化后端 API，供网站和未来小程序共用。
- lib/server.ts：D1/R2 访问、服务端身份权限检查、图片签名与大小验证、操作日志。
- lib/catalog.ts：共享类型与初始分类。
- db/schema.ts、drizzle/：唯一数据库模式与可追踪迁移。
- .openai/hosting.json：逻辑数据库 DB 和图片存储 BUCKET；部署平台绑定实际资源。
- Vite + Vinext + React + Cloudflare Worker / D1 / R2。源码与部署版本共同保存在项目仓库。

本地 Node 22+；使用已选定 pnpm 和锁文件安装。执行 `pnpm build` 生成 Worker，按 README 的本地 D1 迁移指令应用 drizzle SQL，再使用 `pnpm start`；托管开发预览由 sites-preview 负责。生产数据库只通过迁移更新，禁止运行时建表。

## 第一次使用
1. 当前网站仅所有者可访问，打开后点击“启用我的工作台”。初始化只允许成员表为空时建立第一位所有者。
2. 先导入 10–30 张自有图片。图片默认 pending，AI 状态 not_configured。
3. 待审核中心按来源疑似标签归组，选择多张并确认分类。
4. 通过审核后出现在正式图库；继续补充品相、月龄、地区、参考价格和点评。
5. 加入标准库，进入直播模式，用方向键切图。
6. 开放访问前必须先完成所有者初始化。不要在成员表为空时将网站公开。

## 数据模型
cats 存图片引用、来源授权、状态、月龄、估价日期地区、价格区间、主品相级别、标准库标记和点评。
taxonomy 存 dimension + parent_id 分类树；cat_tags 是多对多标签。按父标签搜索递归包含其后代，多个选中标签以 AND 收窄。UI 每个维度选择一个值，数据库允许多标签。不同维度互不强行隶属：矮脚是腿型，不能仅凭外形自动认定纯种英国短毛猫。
appraisals 存申请人和结果，编号是检索标识，不是绕过权限的通行证。
logs 保存审核前数据和修改参数。members 定义 owner/editor/viewer。price_bands 管理预算区间。

## API 摘要
所有路径以 /api/v1/ 开头。读图库仅返回 approved；管理员可请求 pending/rejected。身份使用平台可信用户头，不能由客户端参数选择角色。
- GET session / taxonomy / stats
- POST initialize（仅私人站点首次启用）
- GET cats?tag=golden&tag=short-leg&tag=ny12&age=3&page=1&mixed=1
- POST upload multipart(file,rights=yes,source,license)：单张≤10MB JPG/PNG/WebP，按内容哈希去重，前端批量串行上传。
- POST import {rows:[{url,title,source,license,suggestions:[]}],rights:true,source,license}：每批≤100，逐条结果、链接去重；只存外链引用，不远程抓取，规避服务端 URL 抓取风险。
- POST review {ids,tags,status,grade,age,setPrice,priceMin,priceMax,comment,region,standard}：批量事务，选中的维度替换原维度标签，其余保留，审核记录写日志。
- GET image/{key}：按图库发布状态/申请所有者授权读取。
- GET/POST appraisals；POST appraise 完成结果。
- POST taxonomy / bands；GET/POST members；GET logs。
- GET export?table=cats&offset=0 每批500行；POST backup {id,table,offset} 每批100行，将原图及数据库分片复制到 backups/{id}/。

## 备份与恢复
第一版提供手动导出和 R2 同账户副本；创建备份时暂停写入以得到一致快照。需要保持页面开启直到全部分片完成。外链图片只备份 URL，自有上传图片复制原始字节。中断备份不是完成备份。
恢复暂由开发者从 JSON 分片按 taxonomy→cats→cat_tags 等依赖顺序恢复，R2 原图按 image_key 恢复；不要直接覆盖生产数据。尚无一键恢复、定时执行、异地副本或恢复演练，因此本版不能声称完整灾备已上线。

## 图片示例授权
示例仅在空状态展示，不入数据库，不附带品种/色号/估价。
- RobotBlanket: https://commons.wikimedia.org/wiki/File:Closeup_photo_of_a_cat.jpg
- Asabae2752: https://commons.wikimedia.org/wiki/File:A_photo_of_a_cat_sitting_down.jpg
- Christoffer G. Thomsen: https://commons.wikimedia.org/wiki/File:Cat-on-couch.jpg
以上来源页面标记 CC0 1.0。示例采用外链，连通性受来源站点影响。

## 后续开发清单（按优先级）
P0：完成首批真实图片小批试跑；接入合法图片来源，核实授权，逐步积累到约5000张。当前真实图库为空，不以样例冒充已审核资产。
P0：接入 AI 视觉服务与异步队列，保留模型版本、置信度和证据；先以人工标注集评估准确率，默认全部待审核，不能仅凭模型自报置信度发布。明确不可由照片确认的血统/健康信息。
P0：完善管理员身份配置；未来公开客户入口需要合适的手机号或微信身份适配器。现有 ChatGPT 身份方式适合私人试用，不能直接当作微信小程序登录方案。
P1：本地图片缩略图流水线、对象存储私有签名下载、授权外链迁入自有资源库；批量任务断点续传、服务端队列和撤销审核。
P1：标签重命名/合并/停用、价格档位修改、完整并发版本冲突控制（已预留 version 字段，当前不能宣称有乐观锁）、按真实市场数据分时期和地区估价。
P1：定时备份、独立账户/区域副本、备份完整清单与校验、可恢复演练、生命周期保留策略。
P1：鉴定补图、多图对比、用户删除申请、隐私告知与公开展示单独授权。
P2：5千/5万/50万量级压测，验证 SQL 查询计划和 P95 延迟；混合品相窗口排序、总量计数与 offset 深分页需要基于压测优化为分档候选缓存/游标分页。当前只能承诺已建索引和限制单次结果，不能承诺无限容量或秒级 SLA。
P2：微信小程序仅新增前端、微信身份校验和访问域名备案/审核，继续调用同一 /api/v1、DB 和 BUCKET，绝不另建猫咪数据库。

## 当前明确边界
这是可保存真实数据的第一版，不是5000张已标注图库。已实现 URL/CSV/本地批量导入；“API 数据”是授权 API 返回 JSON 的手动导入，不是在线外部 API 连接器。AI 未启用，所有自动识别待开发。当前未启用定时备份；尚未做大规模压测。管理员工作流是私人试用，面向普通客户公开开放需要后续访问及身份配置。

## 本次验证
- TypeScript 静态检查通过。
- Worker 构建通过；生产最终构建由发布流程再次执行。
- `node tests/route-harness.mjs` 直接运行真实 API 路由，以实际 SQLite 和测试图片存储替身验证：导入、文件哈希去重、批量审核、标签 AND/层级查询、预算筛选、状态隔离、权限拒绝、鉴定结果隐私、备份逻辑和审计日志。
- 图片存储替身测试不等同于生产 R2 端到端验收。当前环境无法完成浏览器交互验收；需要在正式私人网址上完成首批真实上传验收。
