Files
gitlab-instance-0a899031_cn…/PROJECT_ANALYSIS_REPORT.md
2026-06-06 04:29:46 -05:00

19 KiB
Raw Blame History

NomadCNA 前端项目分析报告

生成日期2026-06-06

1. 分析范围与结论

本报告只分析当前仓库中的前端项目现状。仓库内虽然存在 app/api、PocketBase、支付、MinIO 等旧接口适配代码,但根据当前开发方向,这部分后端实现已隔离,后续应由 FastAPI + PocketBase 重新设计和实现。因此本文不会把旧 app/api 作为未来后端实现依据,只把它们作为“前端当前依赖的接口形状”记录,方便后续替换。

总体判断:

  • 当前项目是一个 Next.js 16 App Router 前端应用,核心体验已经具备较完整的页面骨架和视觉资产。
  • 主要业务数据仍以 TypeScript 静态数据、配置文件和页面内 mock 数据为主。
  • 前端已覆盖城市探索、下一站决策、社区加入、会员支付入口、聚会、匹配、讨论、赏金、工具箱、年报、地图、内容页和法律页等模块。
  • 后续真实开发重点不是重写 UI而是抽离接口层、设计 PocketBase 数据模型、用 FastAPI 承接认证、业务规则、支付、上传、AI、统计等后端能力。
  • 当前前端和旧后端存在耦合,需要在后续开发中集中替换为统一 API client 和清晰的数据契约。

2. 技术栈概览

2.1 主要依赖

来自 package.json

  • Next.js16.1.6
  • React / React DOM19.2.3
  • TypeScript^5
  • Tailwind CSS^4
  • ECharts^6.0.0
  • PocketBase JS SDK^0.26.8
  • MinIO SDK^8.0.7
  • 包管理:pnpm@10.25.0

2.2 运行脚本

  • pnpm devnext dev -p 3001 -H 0.0.0.0
  • pnpm build:生产构建
  • pnpm start:生产启动
  • pnpm lintESLint

注意:README.md 中写的是打开 http://localhost:3000,但实际 dev 脚本端口是 3001,文档需要同步。

3. 目录结构与职责

当前关键目录:

app/
  [locale]/            多语言页面路由
  components/          通用前端组件
  context/             Locale / Theme Context
  data/                静态业务数据
  lib/                 前端工具库、旧服务适配、图表组件
  api/                 旧 Next API Route后续不建议作为目标后端保留
config/                站点、导航、首页、页脚、服务配置
i18n/                  本地化导航封装
messages/              zh / en 文案
public/                静态资源

3.1 前端核心文件

  • app/layout.tsx:全局 HTML、主题脚本、ThemeProvider。
  • app/[locale]/layout.tsx:语言路由布局,加载多语言消息,挂载 Navbar。
  • app/[locale]/page.tsx:首页,包含 Hero、城市列表、筛选、热门路线、社区动态。
  • app/globals.cssTailwind 4 入口、深色模式、全局布局类、城市卡片和表单样式。
  • app/context/LocaleContext.tsx:自定义 i18n Context 和路由跳转封装。
  • app/context/ThemeContext.tsx:亮色/暗色主题,使用 localStorage 保存偏好。

3.2 配置文件

  • config/site.config.ts:站点标题、描述、口号。
  • config/nav.config.ts:顶部导航入口。
  • config/home.config.ts:首页成员头像、路线、热门话题、统计数据。
  • config/footer.config.ts:页脚链接。
  • config/services.config.tsconfig/domain.config.ts:旧服务配置。未来后端重写时应重构为前端只保留 NEXT_PUBLIC_API_BASE_URL 等必要公开变量。

4. 页面模块梳理

当前 app/[locale] 下页面较完整,页面数量约 31 个。

4.1 首页与城市探索

相关文件:

  • app/[locale]/page.tsx
  • app/components/HeroSection.tsx
  • app/components/FilterBar.tsx
  • app/components/CityCard.tsx
  • app/components/CityModal.tsx
  • app/data/cities.ts

能力现状:

  • 首页展示城市卡片网格,支持按标签筛选和按综合评分、费用、网速、安全、游民数量、温度排序。
  • 城市数据来自 app/data/cities.ts,共 18 个城市。
  • CityCard 提供卡片 hover 评分展示。
  • CityModal 提供接近 Nomad List 风格的城市详情弹窗,但大量 tab 内容仍是占位。
  • 首页的成员、路线、热门话题、社区动态来自 config/home.config.ts

后续真实化方向:

  • 城市、城市指标、标签、封面图、热度、评分、评论、气候、网速、生活成本应迁入 PocketBase。
  • 首页统计、热门路线、成员头像、热门话题应改由 FastAPI 聚合返回。
  • 筛选逻辑目前在前端内存完成;真实数据量上来后应由后端分页、排序、过滤。

4.2 下一站决策仪表盘

相关文件:app/[locale]/dashboard/page.tsx

能力现状:

  • 用户可设置预算、最低网速、时区、签证偏好、希望认识的人群。
  • 实际筛选只使用预算和网速,数据来自本地 cities
  • 成本曲线、游民密度热力图、AI 推荐等为占位。

后续真实化方向:

  • 建立城市推荐 API根据预算、网速、气候、社区密度、签证、职业偏好等返回排序结果。
  • AI 推荐可以由 FastAPI 调用模型服务,结果落库便于复盘。
  • 图表数据需要后端提供时间序列、城市指标、用户偏好权重。

4.3 加入社区与会员支付

相关文件:

  • app/[locale]/join/page.tsx
  • app/[locale]/join/paid/page.tsx
  • app/components/JoinModal.tsx
  • app/components/AuthModal.tsx
  • app/components/HeroSection.tsx

能力现状:

  • 首页 Hero 支持输入邮箱并进入加入/支付流程。
  • /join 是较完整的报名表单,包含昵称、性别、感情状态、职业、微信、手机、自我介绍、学历、毕业时间、头像/视频上传。
  • 当前页面会调用旧接口:/api/auth/me/api/join/api/join/status/api/vip/check/api/upload-media/api/pay/status/api/meetup/* 等。
  • 支付成功页负责完成订单、同步登录态、设置改密状态等。

后续真实化方向:

  • FastAPI 统一接管登录、报名、会员状态、订单创建、支付回调、支付状态查询、媒体上传。
  • PocketBase 存储用户、资料、报名表、会员权益、订单、支付流水。
  • 前端应只调用 FastAPI不直接处理 PocketBase 管理员逻辑。
  • 支付状态和订单状态需要明确状态机,例如 pendingpaidfailedexpiredrefunded

4.4 社区、匹配、聚会、讨论、赏金

相关页面:

  • app/[locale]/dating/page.tsx
  • app/[locale]/meetups/page.tsx
  • app/[locale]/meetups/host/page.tsx
  • app/[locale]/discuss/page.tsx
  • app/[locale]/gigs/page.tsx

能力现状:

  • 匹配页有 profile card、喜欢/不感兴趣按钮、匹配类型 tab但使用页面内 mock。
  • 聚会页有 upcoming / previous tab聚会列表全部 hardcode。
  • 发起聚会页有表单,文案明确“演示模式,数据不会保存”。
  • 讨论页使用 MOCK_TOPICS,支持搜索过滤。
  • 赏金墙使用 MOCK_GIGS

后续真实化方向:

  • 聚会:活动创建、审核、发布、报名、取消报名、参与者列表、城市筛选。
  • 匹配:个人资料、目标类型、滑动记录、互相喜欢、举报/拉黑、推荐排序。
  • 讨论:话题、评论、点赞、浏览数、标签、审核。
  • 赏金:任务发布、接单、交付、评价、平台抽成、支付/托管。

4.5 工具箱、AI、年报、地图和数据报告

相关页面:

  • app/[locale]/tools/page.tsx
  • app/[locale]/ai/page.tsx
  • app/[locale]/report/page.tsx
  • app/[locale]/report/data/page.tsx
  • app/[locale]/map/page.tsx
  • app/lib/charts/*

能力现状:

  • 工具箱包含静态汇率、税务估算、签证倒计时FIRE 和气候查询为占位。
  • AI 页面为即将上线状态。
  • 年报页面是静态生成入口和展示样式。
  • 地图和数据报告使用 MAP_CITIES 静态城市坐标和 ECharts 地图组件。

后续真实化方向:

  • 汇率、天气、气候、签证政策属于外部数据集成,应由 FastAPI 定时同步或按需代理。
  • 年报依赖用户行程、城市停留、消费、活动报名、社区互动等真实数据。
  • 地图应聚合匿名化成员城市分布,避免暴露个人精确位置。
  • AI 需要用户上下文、城市数据和安全边界。

4.6 内容与静态信息页

相关页面:

  • blogcareerspresshelp
  • aboutcontactsupport
  • termsprivacycookiessafetyguidelines

能力现状:

  • 多数内容来自 app/data/mock.ts
  • 页面完成度适合 MVP 展示,但没有 CMS 或后台维护能力。

后续真实化方向:

  • 内容可先继续静态化,后期迁入 PocketBase 作为轻量 CMS。
  • 法律、隐私、帮助中心等应有版本号和更新时间。
  • 招聘、媒体报道、博客需要 slug、SEO metadata、草稿/发布状态。

5. 数据来源现状

5.1 静态数据

  • app/data/cities.ts18 个城市,含成本、网速、安全、温度、标签、封面、经纬度等。
  • app/data/map-cities.ts:地图城市坐标和成员数。
  • app/data/mock.ts博客、招聘、媒体报道、帮助中心、安全指南、社区准则、联系信息、条款、隐私、Cookie。
  • config/home.config.ts:首页社群头像、旅行中成员、聚会、热门话题、路线、统计。
  • 页面内 mock聚会、匹配、讨论、赏金等。

5.2 多语言数据

  • messages/zh.json
  • messages/en.json

当前 i18n 是自定义 Context不依赖 next-intl。优点是简单可控缺点是类型约束弱缺少自动 key 检查,也没有格式化复数、日期、变量插值的完整能力。

5.3 外部资源

当前大量图片来自:

  • i.pravatar.cc
  • images.unsplash.com
  • api.dicebear.com
  • logo.clearbit.com

这些适合原型阶段,但生产环境需要明确版权、可用性、缓存策略、头像隐私和图片优化策略。

6. 前端状态与交互方式

当前项目大量使用 client component

  • useState 管理表单、弹窗、tab、筛选、排序。
  • useMemo 做城市筛选、聚会分类。
  • localStorage 保存主题、旧 PocketBase token、用户信息、支付订单。
  • document.cookie 保存旧支付订单状态和服务端 session。
  • createPortal 实现 AuthModal、JoinModal、CityModal。
  • window.location.href / replace 用于语言切换、支付回跳和登录同步。

后续建议:

  • 建立统一 app/lib/api-client.tsapp/services/*,集中处理 API base URL、鉴权、错误码、重试、超时。
  • 把旧 PocketBase 前端 SDK 调用逐步移除,前端只通过 FastAPI 访问业务接口。
  • 登录态统一为 httpOnly cookie + /auth/me,避免前端长期保存敏感 token。
  • 表单建议引入 schema 校验,例如 Zod至少在前后端共享字段约束。

7. 当前主要风险

7.1 敏感信息风险

.env.example.env.local 中存在 PocketBase 管理员邮箱和密码字段,并且当前样例包含明文值。即使这些只是旧后端配置,也应立即视为泄露风险:

  • 从仓库中移除真实凭据。
  • 轮换 PocketBase 管理员密码。
  • .env.example 只保留占位符。
  • 后续 FastAPI 服务端使用 Secret Manager 或部署平台环境变量。

7.2 前端与旧后端耦合

多个核心前端组件直接调用旧路径:

  • Navbar/api/auth/me/api/auth/sync-session
  • HeroSection/api/auth/me/api/meetup/check-user/api/meetup/ensure-user
  • JoinModal/api/meetup/ensure-user
  • join/page.tsx/api/join/api/join/status/api/vip/check/api/upload-media
  • join/paid/page.tsx/api/meetup/complete-order/api/auth/change-password
  • payment hooks/api/pay/api/pay/status
  • charts/api/geo/china

这些路径后续需要迁移到 FastAPI并通过统一 API client 映射。

7.3 大量业务仍为 mock

当前页面中明确存在“演示模式”“开发中”“即将上线”:

  • 反馈提交
  • 发起聚会
  • 成员地图
  • 数据报告
  • AI
  • FIRE 计算器
  • 气候查询
  • 仪表盘图表

这不是坏事,说明前端原型覆盖面广;但后续排期需要明确哪些 mock 优先变成真实闭环。

7.4 日期数据过期

当前日期为 2026-06-06但聚会页仍把 2026-03 和 2026-04 的活动标记为“即将举办”。后续真实数据必须由后端按当前时间计算活动状态,不能依赖静态 isUpcoming

7.5 文档与实际运行不一致

  • README 写 localhost:3000,脚本实际是 3001
  • README 写 Node.js 18+,但 Next.js 16 / React 19 的实际运行要求需要在开发环境中确认并统一。

7.6 UI 资产和图片生产化不足

  • 大量使用第三方随机头像和远程图片。
  • 未系统使用 next/image
  • 没有图片域名、尺寸、占位、失败回退策略。

8. 后续 FastAPI + PocketBase 目标架构建议

8.1 推荐边界

建议后续边界如下:

Next.js 前端
  只负责页面、交互、渲染、调用 FastAPI

FastAPI
  负责业务 API、认证会话、权限、支付、上传、AI、统计聚合、外部服务集成

PocketBase
  负责数据存储、基础用户表、文件/记录管理、后台管理界面、必要的 realtime 能力

关键原则:

  • 前端不要直接使用 PocketBase 管理员权限。
  • 复杂业务规则放在 FastAPI不散落在前端。
  • PocketBase 作为数据和后台管理层,不承担所有业务流程。
  • 支付回调、会员开通、退款、上传鉴权、AI 调用必须走 FastAPI。

8.2 建议数据模型

首批 PocketBase collections 可按以下方向设计:

  • users:用户基础账号,可使用 PocketBase auth collection。
  • profiles:昵称、头像、职业、城市、简介、标签、匹配偏好。
  • member_applications:加入社区报名表。
  • memberships:会员等级、有效期、权益、状态。
  • orders:订单号、用户、金额、渠道、状态、业务类型。
  • payment_events:支付回调原始事件和处理状态。
  • media_assets:上传文件、类型、归属用户、用途。
  • cities城市基础信息、slug、多语言名称、坐标、封面。
  • city_metrics:成本、网速、气候、安全、社区密度等指标。
  • city_guides城市攻略、共享办公、社区推荐、tips。
  • meetups:聚会活动。
  • meetup_rsvps:活动报名关系。
  • discussions:讨论话题。
  • comments:评论。
  • gigs:赏金任务。
  • gig_applications:接单/投递。
  • swipes:匹配滑动记录。
  • matches:互相喜欢记录。
  • feedback:建议与 Bug 反馈。
  • annual_reports:年报生成结果和快照。

9. FastAPI API 清单草案

9.1 认证与用户

  • POST /auth/register
  • POST /auth/login
  • POST /auth/logout
  • GET /auth/me
  • POST /auth/change-password
  • GET /users/me/profile
  • PATCH /users/me/profile

9.2 加入社区与会员

  • GET /join/status
  • POST /join/applications
  • GET /memberships/me
  • POST /payments/checkout
  • GET /payments/{order_id}/status
  • POST /payments/webhooks/{provider}

9.3 媒体上传

  • POST /media/uploads
  • GET /media/{id}
  • DELETE /media/{id}

9.4 城市与推荐

  • GET /cities
  • GET /cities/{slug}
  • GET /cities/{slug}/metrics
  • GET /cities/{slug}/guide
  • POST /recommendations/next-stop
  • GET /routes/hot

9.5 社区模块

  • GET /meetups
  • POST /meetups
  • GET /meetups/{id}
  • POST /meetups/{id}/rsvp
  • DELETE /meetups/{id}/rsvp
  • GET /discussions
  • POST /discussions
  • GET /discussions/{id}/comments
  • POST /discussions/{id}/comments

9.6 匹配模块

  • GET /matches/candidates
  • POST /matches/swipes
  • GET /matches/me
  • POST /reports/profile
  • POST /blocks/profile

9.7 赏金与反馈

  • GET /gigs
  • POST /gigs
  • POST /gigs/{id}/apply
  • POST /feedback

9.8 数据报告与 AI

  • GET /stats/member-map
  • GET /stats/city-ranking
  • POST /reports/annual/generate
  • GET /reports/annual/{id}
  • POST /ai/assistant

10. 前端改造路线

阶段 0清理与契约冻结

  • 移除仓库中的真实密钥,轮换泄露风险凭据。
  • 明确旧 app/api 全部为 legacy不继续扩展。
  • 建立 NEXT_PUBLIC_API_BASE_URL
  • 梳理当前前端调用接口,写成接口契约文档。
  • 修正 README 端口和环境说明。

阶段 1统一 API client

  • 新增统一 API client集中处理
    • base URL
    • credentials
    • JSON 解析
    • 错误响应
    • 登录失效
    • loading / retry 策略
  • 替换 fetch("/api/...") 为领域服务函数,例如 authApi.me()joinApi.submit()
  • 前端保留 mock fallback方便后端未完成时继续开发 UI。

阶段 2认证、报名、支付闭环

优先原因:这是转化和会员收入核心链路。

  • FastAPI 实现注册、登录、会话、改密。
  • FastAPI 实现报名表提交。
  • 实现支付下单、支付状态、支付回调、会员开通。
  • 实现上传鉴权和媒体资产记录。
  • 前端替换 Hero、JoinModal、JoinPage、JoinPaidPage、Navbar 的旧接口调用。

阶段 3城市数据真实化

  • cities.ts 迁入 PocketBase。
  • 前端首页和仪表盘改为调用 /cities
  • 城市详情弹窗拆分真实字段和占位字段。
  • 建立城市 slug避免只用中文城市名作为业务 key。

阶段 4社区功能真实化

  • 聚会列表和发起聚会落库。
  • 讨论和评论落库。
  • 匹配候选人、滑动、match 记录落库。
  • 赏金墙发布和接单落库。

阶段 5AI、年报、统计

  • 接入 AI 助手。
  • 根据真实用户行为生成年度报告。
  • 地图、城市排名、增长趋势改由后端聚合。

阶段 6运营后台与权限

  • 使用 PocketBase Admin 作为轻量后台。
  • 增加内容审核、聚会审核、举报处理、会员管理、订单查询。
  • FastAPI 增加管理员 API 或管理脚本。

11. 建议优先级

P0

  • 凭据清理与轮换。
  • 统一 API base URL 和 API client。
  • 认证、报名、支付、会员状态真实闭环。
  • 上传链路真实化。

P1

  • 城市数据迁移 PocketBase。
  • 首页、城市详情、仪表盘接入真实城市 API。
  • 聚会列表和报名真实化。
  • 反馈提交真实化。

P2

  • 匹配、讨论、赏金墙真实化。
  • 地图和数据报告真实化。
  • AI 助手上线。

P3

  • 内容 CMS 化。
  • SEO metadata 完善。
  • 图片优化和 CDN 策略。
  • 自动化测试和监控。

12. 测试与验收建议

前端:

  • pnpm lint
  • pnpm build
  • 首页、加入表单、登录弹窗、支付回跳、城市筛选、语言切换、暗色模式的 Playwright E2E。
  • 移动端视口检查尤其是首页网格、Join 表单、CityModal。

后端:

  • FastAPI 单元测试:认证、报名、支付状态机、权限。
  • 支付 webhook 幂等测试。
  • PocketBase collection rule 测试。
  • 媒体上传大小、类型、权限测试。

契约:

  • OpenAPI 自动生成。
  • 前端类型从 OpenAPI 生成或至少共享 DTO schema。
  • mock server 保持和 OpenAPI 一致。

13. 总结

当前项目的价值主要在前端产品原型和页面覆盖度导航、首页、城市探索、会员加入、社区、工具、内容页都已经成型。短板集中在数据真实性、后端契约、认证支付安全、mock 数据和旧接口耦合。

后续开发不建议在旧 app/api 上继续补功能。更稳妥的路线是保留当前 Next.js 前端体验,新增 FastAPI 后端PocketBase 作为数据和后台管理层,然后按“认证/报名/支付 -> 城市数据 -> 社区互动 -> AI/统计”的顺序逐步替换 mock 和旧接口。