相关文档
从应用架构、核心业务模块到本地运行与质量验证,快速了解 PolyGo 的完整工程实现。
这里将 modules/ 中的模块说明整理为便于浏览的 HTML 文档,适合项目演示、代码阅读和开发协作时查阅。
认证模块说明
认证模块位于后端 backend/polygo_api/,涉及 routes.py、models.py、auth.py、create_account.py 与 database.py。它负责用户注册、登录、当前用户查询、Token 刷新、登出和密码重置演示流程。
认证流程
当前认证由 PocketBase 和 FastAPI 共同完成:
- 用户通过前端提交邮箱、用户名和密码。
- 后端用 Pydantic 模型校验输入。
create_account.py调用 PocketBase 的usersauth collection 创建或查询用户。- 登录成功后,FastAPI 自己签发 JWT。
- 前端保存
access_token,后续请求通过Authorization: Bearer ...访问后端。
PocketBase 的 users 集合中,前端的 username 会映射到 PocketBase 的 name 字段。
主要接口
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /auth/register | 注册用户 |
| POST | /auth/login | 登录用户 |
| GET | /auth/me | 获取当前用户 |
| POST | /auth/refresh | 刷新访问令牌 |
| POST | /auth/logout | 登出 |
| POST | /auth/reset-password-request | 请求密码重置 |
| POST | /auth/reset-password | 确认密码重置 |
密码规则
- 至少 8 位。
- 至少包含一个字母。
- 至少包含一个数字。
注册和密码重置都会走同样的基础校验。
验证方式
conda run -n polygo python -m pytest tests/test_auth.py
conda run -n polygo python scripts/test_api.py
完整认证链路应覆盖:注册、登录、/auth/me、refresh、密码重置请求、密码重置确认和 logout。
前端模块说明
前端主线在 frontend/polygo_web/,是当前 PolyGo Web 应用的入口。早期模板痕迹已经整理掉,后续前端改动都应围绕这里进行。
模块职责
- 登录、注册和登录态保存。
- 首页与出行计划入口。
- 创建计划、展示邀请码、通过邀请链接加入计划。
- 计划详情页中的可用时间填写、地点选择、地图搜索、推荐结果展示。
- 调用地点推荐、AI 助手、自定义行程等后端接口。
目录习惯
| 位置 | 用途 |
|---|---|
src/App.tsx | 前端路由入口 |
src/pages/ | 页面级功能,例如 Login、Register、Home、Plans |
src/components/ | 可复用组件,例如动画角色、图标等 |
src/services/api.ts | 后端 API 封装和类型定义 |
src/utils/ | 工具函数和对应测试 |
页面不要直接拼后端地址,统一通过 src/services/api.ts 调用接口。这样后端地址、Token、响应类型变化时,不需要到处改页面。
环境变量与常用命令
前端读取 VITE_API_BASE_URL;没有配置时默认访问 http://localhost:8000。本地开发通常由 Vite 跑在 5173 端口。
conda run -n polygo npm --prefix frontend/polygo_web install
conda run -n polygo npm --prefix frontend/polygo_web run dev
conda run -n polygo npm --prefix frontend/polygo_web run test
conda run -n polygo npm --prefix frontend/polygo_web run build
conda run -n polygo npm --prefix frontend/polygo_web run lint
页面交互改动后,除测试、构建和 lint 外,还应启动 Vite,至少检查 /、/login、/register 和相关计划页能正常打开。
后端模块总览
后端主线在 backend/polygo_api/,是 PolyGo 的 FastAPI 服务入口。它负责认证、计划、可用时间、地点推荐、AI 出行助手和自定义行程等业务能力,并通过 PocketBase 保存账号和业务数据。
应用入口
main.py 创建 FastAPI app,并统一处理应用元信息、Swagger 和 ReDoc 路径、CORS 配置、PocketBase 启动健康检查和关闭清理、请求日志、异常处理、/health 与 / 系统端点,以及各业务 router 注册。
http://localhost:8000/api/docs
http://localhost:8000/api/redoc
http://localhost:8000/health
分层约定
后端代码按 router → manager → model → database 的方式组织:
| 层级 | 文件形态 | 职责 |
|---|---|---|
| 路由层 | *_routes.py | 定义 HTTP 路径、依赖、请求和响应模型 |
| 业务层 | *_manager.py | 处理权限、业务规则、PocketBase 读写和领域流程 |
| 模型层 | models.py / *_models.py | 定义 Pydantic 请求、响应和领域数据结构 |
| 基础设施 | database.py / auth.py / logger.py | PocketBase 客户端、JWT、日志等通用能力 |
新增功能不要把业务逻辑直接写进 main.py,优先新增或扩展对应领域的 route、manager 和 model。
路由与权限
主 app 注册认证、计划、可用时间、地点推荐、AI 助手和自定义行程 router;前端统一通过 frontend/polygo_web/src/services/api.ts 调用。
- 计划、可用时间、地点推荐、AI 助手和自定义行程都要求用户已登录。
- 计划资源通常要求当前用户是计划成员。
- 确认推荐区域或最终行程等创建者专属操作需检查 owner 身份。
- 前端 token 存在
localStorage的access_token中。
配置与验证
重要环境变量包括 POCKETBASE_URL、SECRET_KEY、ALGORITHM、ACCESS_TOKEN_EXPIRE_MINUTES、ALLOWED_ORIGINS 以及可选的地图和 LLM 配置。没有外部 key 时,推荐与 AI 能力仍需保留 fallback 路径。
conda run -n polygo python -m pytest
conda run -n polygo python scripts/test_api.py
curl http://localhost:8000/health
计划与可用时间模块说明
计划与可用时间是 PolyGo 的主业务入口。它们负责把一个多人出行计划从“创建入口”推进到“收集成员时间和出发地点”。
出行计划
- 创建计划。
- 生成唯一邀请码与邀请链接。
- 通过邀请码或邀请链接加入计划。
- 查询计划成员和基础信息。
- 更新计划标题。
计划数据保存在 PocketBase 的 travel_plans collection,核心字段包括标题、邀请码、创建者、成员列表和时间戳。
可用时间和出发地点
- 成员提交可用日期与时段。
- 成员提交出发地点名称、经纬度、交通方式和备注。
- 成员更新或删除自己的提交。
- 计划成员查询所有可用时间。
- 后端统计推荐时间段。
可用时间数据保存在 travel_availabilities collection。推荐时间接口按“日期 + 时段”聚合成员提交情况,人数最多的组合会排在推荐结果前面;同一成员对同一时段的重复提交按一个成员计算。
前后端配合
| 方法 | 路径 | 用途 |
|---|---|---|
| POST | /plans | 创建计划 |
| PATCH | /plans/{plan_id} | 更新计划标题 |
| GET | /plans/{plan_id} | 获取计划 |
| POST | /plans/join | 通过邀请码加入 |
| POST | /plans/invite/{invite_code} | 通过邀请链接加入 |
| POST | /plans/{plan_id}/availabilities | 新增可用时间 |
| GET | /plans/{plan_id}/time-recommendation | 获取推荐时间 |
验证方式
conda run -n polygo python -m pytest tests/test_plans.py
live 验证应覆盖用户 A 创建计划、用户 B 加入、两人提交时间与地点、查询列表和推荐时间,以及更新、删除一条可用时间。
地点推荐模块说明
地点推荐模块根据成员出发地点、交通方式和活动类型,生成适合多人集合的候选区域,并在成员投票后生成行程建议。
模块入口
支持从已有出行计划创建推荐会话,或创建通用推荐会话并直接传入参与者位置。
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /plans/{plan_id}/location-recommendation | 从计划创建或恢复推荐会话 |
| POST | /recommendations/sessions | 创建通用推荐会话 |
| GET | /recommendations/sessions/{session_id} | 查询推荐会话 |
| POST | /recommendations/sessions/{session_id}/regions:generate | 重新生成推荐区域 |
| POST | /recommendations/sessions/{session_id}/regions/{region_id}/votes | 保存区域投票 |
| POST | /recommendations/sessions/{session_id}/regions/{region_id}:select | 创建者确认区域 |
| POST | /recommendations/sessions/{session_id}/itineraries:generate | 生成推荐行程 |
| POST | /recommendations/sessions/{session_id}/finalize | 确认最终行程 |
推荐流程
- 成员在计划中提交出发地点和交通方式。
- 后端从可用时间记录里提取有效坐标。
- 创建推荐会话和参与者记录。
- 根据成员位置生成候选区域。
- 成员对区域进行投票。
- 创建者确认一个区域。
- 后端在该区域内生成行程建议。
- 需要时生成澄清问题并根据回答重新排序。
- 创建者确认最终行程。
持久化与 fallback
PocketBase 保存会话、参与者、区域、投票、澄清问题、回答和行程记录。澄清回答可能触发重排,因此更新内容时需保留已有记录 ID。没有 AMap 或 LLM key 时,系统使用规则和内置候选数据生成可解释结果。
验证方式
conda run -n polygo python -m pytest tests/test_location_recommendations.py
AI 出行助手模块说明
AI 出行助手是在地点推荐基础上的轻量决策助手。它不会替代计划和地点推荐流程,而是在已收集成员位置并确认推荐区域后,帮助用户进一步筛选地点或生成可核验的搜索方案。
使用前提
- 用户属于该出行计划。
- 成员已提交出发地点和交通方式。
- 地点推荐模块已经生成并确认一个推荐区域。
如果上下文不足,助手会返回阻塞提示,让用户先完成前置步骤。
接口
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /plans/{plan_id}/agent/recommendations | 基于计划上下文和用户自然语言需求生成推荐 |
{
"message": "附近适合两个大学生的粤菜,预算不要太高,地铁方便一点"
}
处理流程
- 解析用户自然语言偏好。
- 读取计划和成员可用时间。
- 读取已确认的推荐区域。
- 根据偏好选择工具路由。
- 尝试生成候选 POI。
- 给候选地点打分并生成外部搜索链接。
- 返回推荐结果、解释文本和 trace。
fallback 与返回状态
外部 LLM 或 AMap Key 没有配置时,助手仍会结合确认区域和用户偏好返回可核验搜索方案。
| 状态 | 含义 |
|---|---|
answered | 成功拿到候选地点并回答 |
fallback | 使用规则兜底方案回答 |
needs_clarification | 用户需求过宽,需要追问 |
blocked | 缺少前置上下文 |
conda run -n polygo python -m pytest tests/test_travel_agent.py
自定义行程模块说明
自定义行程模块将推荐地点整理为用户可编辑的行程草稿。它关联 AI 助手和地点推荐模块,但更关注用户最后如何调整与确认。
模块职责
- 获取或创建某个计划的行程草稿。
- 将 Agent 推荐地点加入草稿。
- 更新站点停留时间、备注等信息。
- 删除站点、手动重排或按距离优化顺序。
- 确认最终行程。
接口
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /plans/{plan_id}/custom-itinerary | 获取或创建行程草稿 |
| POST | /plans/{plan_id}/custom-itinerary/stops | 添加站点 |
| PATCH | /plans/{plan_id}/custom-itinerary/stops/{stop_id} | 更新站点 |
| DELETE | /plans/{plan_id}/custom-itinerary/stops/{stop_id} | 删除站点 |
| POST | /plans/{plan_id}/custom-itinerary:reorder | 手动重排 |
| POST | /plans/{plan_id}/custom-itinerary:optimize | 自动优化顺序 |
| POST | /plans/{plan_id}/custom-itinerary:finalize | 确认最终行程 |
草稿结构与顺序处理
草稿保存计划 ID、创建者、draft 或 finalized 状态、站点列表、总预计时长、预计步行距离和行程摘要;站点保存 POI、顺序、停留时长、备注、来源查询和外部链接。
用户可传入 stop id 列表手动重排,或由后端基于站点经纬度进行简单近邻优化。自动优化并非复杂路线规划,出行前仍建议结合地图检查。
conda run -n polygo python -m pytest tests/test_custom_itinerary.py
数据与 PocketBase 迁移说明
PolyGo 使用 PocketBase 0.38.0 作为本地数据和用户认证存储。后端通过 PocketBase SDK 读写数据,前端不直接访问 PocketBase。
数据域
| 数据域 | 用途 |
|---|---|
users | PocketBase auth collection,保存账号、邮箱和用户名 |
travel_plans | 保存出行计划、邀请码、创建者和成员列表 |
travel_availabilities | 保存成员可用时间、出发地点、经纬度和交通方式 |
location_recommendation_* | 保存地点推荐会话、参与者、区域、投票、澄清问题和行程 |
custom_itinerary_drafts | 保存自定义行程草稿和站点 |
migrations 的作用
pb_migrations/ 保存 PocketBase collection 的结构演化,使新环境启动时能自动建出项目需要的集合。启动脚本会将 migrations 目录传给 PocketBase:
conda run -n polygo python scripts/start.py --pocketbase-only
./third_party/pocketbase serve --http=0.0.0.0:8090 --dir ./third_party/pb_data --migrationsDir ./pb_migrations
修改数据结构时
- 确认需要字段的业务模块。
- 新增或修改
pb_migrations/。 - 更新对应 manager 与 model。
- 运行后端测试。
- 启动真实 PocketBase 检查 migrations 是否可应用。
- 同步更新涉及的说明文档。
本地数据默认在 third_party/pb_data,它是运行产物;共享结构时应优先改 migrations。
运行与工程脚本说明
PolyGo 的本地运行和验证主要由 scripts/ 中的脚本串联,避免每次手动记忆 PocketBase、FastAPI、Vite 的启动顺序,并统一端口清理和 API 冒烟测试。
setup
setup.py 负责从 .env.example 创建 .env、安装 Python 与 Node 依赖,并检查 PocketBase 可执行文件位置。
conda run -n polygo python scripts/setup.py
conda run -n polygo python scripts/setup.py --skip-python
conda run -n polygo python scripts/setup.py --skip-node
start 与 stop
start.py 是本地启动主入口:先清理旧服务,再按顺序启动 PocketBase、FastAPI 和 Vite。stop.py 用来停止常见开发服务或检查端口占用。
conda run -n polygo python scripts/start.py
conda run -n polygo python scripts/start.py --pocketbase-only
conda run -n polygo python scripts/start.py --backend-only
conda run -n polygo python scripts/start.py --frontend-only
conda run -n polygo python scripts/start.py --no-frontend
conda run -n polygo python scripts/stop.py
conda run -n polygo python scripts/stop.py --check
常用端口为 8000(FastAPI)、8090(PocketBase)及 5173–5176(Vite)。
test_api 与 Docker Compose
test_api.py 在后端真实启动后验证注册、登录和当前用户查询;Docker Compose 则提供 frontend、backend、pocketbase 三服务部署方式。
conda run -n polygo python scripts/test_api.py
docker compose up --build
docker compose up -d --build
docker compose down
测试与质量验证说明
PolyGo 的验证分成后端 pytest、前端 Vitest、前端构建与 lint、真实服务 live smoke 四层。不同改动不一定都要跑全量,但提交前应至少覆盖受影响模块。
验证分层
| 层级 | 命令 | 主要覆盖 |
|---|---|---|
| 后端单元/接口测试 | python -m pytest | FastAPI route、manager、Pydantic 校验和 fallback 逻辑 |
| 前端测试 | npm --prefix frontend/polygo_web run test | 工具函数和前端可测试逻辑 |
| 前端构建 | npm --prefix frontend/polygo_web run build | TypeScript、Vite 打包和静态资源引用 |
| 前端 lint | npm --prefix frontend/polygo_web run lint | ESLint 规则和基础代码质量 |
| live API smoke | python scripts/test_api.py | 真实后端启动后的认证链路 |
| 手动 UI 验证 | 启动 Vite 后浏览器检查 | 页面路由、表单交互、地图和计划流程 |
常用验证命令
conda run -n polygo python -m pytest
conda run -n polygo npm --prefix frontend/polygo_web run test
conda run -n polygo npm --prefix frontend/polygo_web run build
conda run -n polygo npm --prefix frontend/polygo_web run lint
live smoke 与 UI 验证
conda run -n polygo python scripts/start.py --no-frontend
conda run -n polygo python scripts/test_api.py
curl http://localhost:8000/health
curl http://localhost:8090/api/health
涉及 UI 时,应启动完整本地栈并至少检查登录、注册、首页进入计划流程、创建计划、邀请码或邀请链接加入、提交可用时间和出发地点,以及无外部 key 时地图和推荐流程的反馈。
按改动范围选择验证
- 认证改动:
tests/test_auth.py与 livescripts/test_api.py。 - 计划/可用时间改动:
tests/test_plans.py与创建、加入、提交时间的 live 流程。 - 地点推荐、AI 助手、自定义行程改动:运行各自测试并覆盖相应 live 主路径。
- 前端页面或 API 类型改动:前端 test、build、lint 与浏览器手动验证。
- PocketBase schema 改动:相关测试加真实 PocketBase migration 检查。