Files
2026-06-07 23:57:52 -05:00

16 KiB
Raw Permalink Blame History

NomadCNA — Cursor 项目上下文报告

更新日期2026-06-08
用途:为 Cursor AI 助手提供项目全貌、架构约定与开发指引。
生产站点:https://nomadro.cn


1. 项目简介

NomadCNA游牧中国 是面向数字游民的生活操作系统,单仓 Monorepo 包含:

  • 主站:城市探索、下一站决策、活动、社区匹配、支付、统计、访谈视频等
  • Digital 子站/digital):指南、课程、电子书、远程工作、个人资料
  • FastAPI 后端:认证、业务 API、支付回调、PocketBase 集成
  • VPS 自建开源服务MiroTalk P2P视频、The Lounge + Ergo IRCWeb 群聊)
模块 说明
城市探索 18 城静态数据 + API生活成本/网速/安全等指标
下一站决策 /dashboard,预算/气候/标签推荐
活动 线上/线下/混合;统一活动间 /meetups/[id]/live 深度融合 MiroTalk + Lounge
访谈视频 /videos 列表 + /videos/[slug] 详情
社区匹配 /dating 滑动匹配、意图/城市筛选、互赞、额度、撤销
会员与支付 ZPay / XorPay加入表单 + VIP 状态
Digital 子站 课程章节、电子书 Markdown、资源导航
媒体 MinIO 上传 + app/lib/media.ts + /api/media/proxy

2. 技术栈

层级 技术 版本
前端框架 Next.js App Router 16.1.6
UI React + TypeScript 19.2.3 / TS 5
样式 Tailwind CSS 4
图表 ECharts 6
Markdown marked, react-markdown, highlight.js
后端 FastAPI + uvicorn ≥0.115
数据库 PocketBase SDK 0.27
对象存储 MinIO Node + Python SDK
视频会议 MiroTalk P2P VPS :9300
Web 群聊 The Lounge 4.5 + Ergo IRC 2.18 VPS :9000 / :6667
支付 ZPay / XorPay 适配层
包管理 pnpm 10.25.0
Node 生产版本 v22.13.1

路径别名:@/* → 项目根目录(见 tsconfig.json)。


3. 架构总览

flowchart TB
    subgraph Client["浏览器"]
        Next["Next.js 16<br/>:3001 dev / :4002 prod"]
    end

    subgraph APIs["API 层"]
        NextAPI["Next Route Handlers<br/>/api/digital/*<br/>/api/media/*"]
        FastAPI["FastAPI<br/>:8000<br/>/api/*"]
    end

    subgraph Data["数据与服务"]
        PB["PocketBase :8090"]
        MinIO["MinIO :9100"]
        MiroTalk["MiroTalk P2P :9300"]
        Lounge["The Lounge :9000"]
        Ergo["Ergo IRC :6667"]
    end

    Client --> Next
    Next -->|"rewrite 排除 digital/media"| FastAPI
    Next --> NextAPI
    NextAPI --> PB
    NextAPI --> MinIO
    FastAPI --> PB
    FastAPI --> MinIO
    Next -->|"活动间 iframe"| MiroTalk
    Next -->|"活动间 iframe"| Lounge
    Lounge --> Ergo

API 路由分流(关键)

next.config.tsdigitalmedia 的所有 /api/* 转发到 FastAPI

source: "/api/:path((?!(?:digital|media)(?:$|/.*)).*)"
destination: "http://127.0.0.1:8000/api/:path*"
路径前缀 处理方
/api/digital/* Next.js Route Handlers
/api/media/* Next.js Route Handlers
其他 /api/* FastAPI经 rewrite 代理)

前端统一通过 app/lib/api-client.tsapiFetch() / apiUrl() 调用后端。


4. 目录结构

.
├── app/
│   ├── [locale]/              # 主站多语言页面(~54 个 page.tsx
│   │   ├── dating/            # 匹配页 + components/
│   │   ├── meetups/           # 活动列表、host、[id]/live 活动间
│   │   ├── videos/            # 访谈列表 + [slug] 详情
│   │   └── digital/           # Digital 子站页面路由
│   ├── api/
│   │   ├── digital/           # Digital 认证、支付、上传、VIP
│   │   └── media/proxy/       # 远程媒体代理
│   ├── components/
│   │   └── meetups/EventLiveRoom.tsx  # 活动间分屏 UI
│   ├── context/               # LocaleContext、ThemeContext
│   ├── data/                  # cities.ts、avatars.ts、mock.ts
│   ├── digital/               # Digital 子站组件、lib、context
│   └── lib/                   # api-client、meetups、media、payment、pocketbase
├── backend/
│   ├── main.py                # FastAPI 入口(~70 个端点)
│   ├── meetup_live.py         # 活动间 URL / 权限
│   ├── avatar_assets.py       # 头像池(与前端 avatars.ts 同步)
│   ├── settings.py            # 环境变量
│   ├── pb_client.py           # PocketBase HTTP 客户端
│   ├── payment.py             # ZPay / XorPay
│   ├── minio_storage.py       # MinIO 上传
│   ├── init_db.py             # 集合 schema + seed
│   └── seed_data.py           # 种子数据
├── config/
│   ├── remote-services.ts     # 线上服务地址、Windows 远程开发
│   ├── site.config.ts         # 主站 SEO
│   ├── nav.config.ts          # 顶部导航
│   └── digital/               # Digital 子站专属配置
├── scripts/
│   ├── dev-tunnel.py          # SSH 隧道MinIO → localhost:9100
│   └── dev-windows.ps1        # Windows 一键开发
├── i18n/                      # routing.ts、navigation.ts
├── messages/                  # zh.json、en.json 主站文案
└── next.config.ts

主站 vs Digital 子站代码边界

区域 路径 说明
主站页面 app/[locale]/* 城市、活动、匹配、视频等
主站组件 app/components/ Navbar、EventLiveRoom 等
主站工具 app/lib/ api-client、meetups、media、payment
Digital 页面 app/[locale]/digital/* 课程、电子书、工作等
Digital 组件 app/digital/components/ 独立 Header、Hero、课程区块
Digital 工具 app/digital/lib/ 平行的 payment、pocketbase、learning
Digital 配置 config/digital/* 课程、域名、视觉主题

两套代码 有意平行(非完全共享),修改时注意对应目录。


5. 路由与国际化

  • 语言:zh(默认)、en,路由 始终带前缀/zh/.../en/...
  • 配置:i18n/routing.ts
  • 文案:messages/zh.jsonmessages/en.json
  • 语言感知导航:必须使用 i18n/navigation.tsLinkuseRouteruseTranslation
import { Link, useRouter, useTranslation } from "@/i18n/navigation";

新页面:在 app/[locale]/page.tsx → 补 messages/*.json → 必要时改 config/nav.config.ts


6. API 端点速查

6.1 Next.js Route Handlers

路径 作用
app/api/digital/auth/* Digital 认证
app/api/digital/joinpay/*vip/check 加入、支付、VIP
app/api/digital/upload-media 媒体上传 MinIO
app/api/media/proxy 远程媒体抓取/缓存

6.2 FastAPIbackend/main.py

分类 端点
健康/认证 GET /api/health`POST /api/auth/email
加入/支付 POST /api/joinPOST /api/payGET /api/pay/status
城市/内容 GET /api/citiesGET /api/content/homeGET /api/content/{slug}
视频 GET /api/videos
活动 GET/POST /api/meetupsGET /api/meetups/{id}GET /api/meetups/{id}/session
匹配 `GET /api/matches/candidates
社区 GET/POST /api/discussions/api/gigsGET /api/profiles
通知/统计 /api/notifications/*/api/stats/*
其他 POST /api/feedbackPOST /api/recommendations/next-stop
支付回调 /cnomadcna/zpay_order_status/cnomadcna/xorpay_notify

注意/api/videos 必须独立路由,不能走 /api/content/{slug}slug=videos 会 404


7. 核心业务模块指引

7.1 城市探索

  • 静态:app/data/cities.ts18 城)
  • 首页:app/[locale]/page.tsx + FilterBar、CityCard、CityModal
  • APIGET /api/cities/api/cities/{slug}

7.2 活动 / 视频 / 群聊(深度融合)

层级 文件
列表/弹窗 app/[locale]/meetups/page.tsx
活动间 app/[locale]/meetups/[id]/live/page.tsx
UI 组件 app/components/meetups/EventLiveRoom.tsx
前端逻辑 app/lib/meetups.ts
后端逻辑 backend/meetup_live.py
会话 API GET /api/meetups/{id}/session

流程:

  1. 用户打开活动详情 → 「进入活动间」
  2. Live 页请求 /api/meetups/{id}/session(带 Cookie
  3. 返回 videoUrlMiroTalk + name=)、chatUrlLounge channel deep linkcanJoin
  4. EventLiveRoom 分屏 iframe 嵌入;支持只看视频/只看群聊

PocketBase meetups 关键字段:modeaccessLevelmirotalkRoomloungeChannelfeatures

7.3 访谈视频

  • 列表:app/[locale]/videos/page.tsxGET /api/videos
  • 详情:app/[locale]/videos/[slug]/page.tsx
  • 首页 video 卡片 targetUrl 固定 /videos(见 app/[locale]/page.tsxnormalizeHomeContentItem

7.4 社区匹配Dating

  • 页面:app/[locale]/dating/page.tsx
  • 组件目录:app/[locale]/dating/components/
    • IntentTabsCityFilterSwipeStackSwipeCard
    • LikesPanelMatchModalAdvancedFiltersSwipeQuota
  • 常量/类型:constants.tstypes.tsutils.ts
  • 头像:app/data/avatars.tsbackend/avatar_assets.py
  • SchemaprofileslookingFor、gender、citySlugswipesintentmatch_connections

7.5 支付

  • 前端:app/lib/payment/
  • Digitalapp/digital/lib/payment/
  • 后端:backend/payment.py
  • 配置:config/services.config.tsconfig/digital/services.config.ts

7.6 媒体

  • app/lib/media.tsURL 规范化、Unsplash 直连、MinIO 公开路径
  • app/api/media/proxy/route.ts:代理失败时 passthrough 原图

7.7 认证

  • Cookieapp/lib/auth-cookie.ts
  • PocketBaseapp/lib/pocketbase/auth.ts
  • FastAPI 会话:backend/pb_client.py + current_user()

8. 配置系统

文件 用途
config/site.config.ts 主站 SEO
config/nav.config.ts 顶部导航
config/home.config.ts 首页静态块
config/remote-services.ts nomadro.cn 各服务 URL、MinIO/PB 解析、isRemoteDevMode()
config/services.config.ts 主站 PocketBase/支付/MinIO
config/runtime-env.ts APP_ENV 判断
config/digital/* Digital 子站

9. 开发命令

pnpm install
pnpm dev                    # http://localhost:3001

# 后端Windows
python -m venv backend/.venv
backend\.venv\Scripts\pip install -r backend/requirements.txt
backend\.venv\Scripts\uvicorn backend.main:app --host 127.0.0.1 --port 8000 --reload

# Windows 连线上 MinIO
python scripts/dev-tunnel.py

# 初始化 PocketBase 集合 + 种子
python -m backend.init_db

# 质量检查(上线前)
pnpm lint
pnpm exec tsc --noEmit --pretty false

PowerShell 不支持 &&,命令分步执行。

本地需 Next.js (:3001) + FastAPI (:8000) 同时运行。8000 端口若被多个旧 uvicorn 占用,新路由不会生效——先杀干净再启一个实例。


10. 环境变量要点

⚠️ 勿提交 .env.localbackend/.env 或真实密钥。

前端(.env.local

变量 说明
NEXT_PUBLIC_SITE_URL 本地 http://localhost:3001
NEXT_PUBLIC_API_BASE_URL 生产 /api;本地可留空走 rewrite
FASTAPI_PROXY_TARGET rewrite 目标,默认 http://127.0.0.1:8000
NEXT_PUBLIC_POCKETBASE_URL PocketBase
NEXT_PUBLIC_MIROTALK_URL MiroTalk
NEXT_PUBLIC_LOUNGE_URL The Lounge
NEXT_PUBLIC_MINIO_PUBLIC_URL MinIO 公开读
DEV_SSH_* dev-tunnel 用(勿提交密码)

后端(backend/.env

变量 说明
POCKETBASE_URL 内网或公网 PB
MIROTALK_URL / LOUNGE_URL 活动间 URL 生成
MINIO_* 对象存储
DEV_AUTO_PAY 开发自动完成支付

完整列表见 .env.exampleREADME.md


11. AI 编码约定

必须遵守

  1. 最小改动:只改任务相关文件
  2. 匹配现有风格@/ import、组件结构一致
  3. 国际化UI 文案走 messages/*.json + t()
  4. 路由app/[locale]/ + @/i18n/navigationLink
  5. API:主站用 app/lib/api-client.tsapiFetch
  6. 活动:复用 app/lib/meetups.ts + backend/meetup_live.py
  7. 媒体:复用 app/lib/media.ts
  8. 支付:复用 app/lib/payment + backend/payment.py
  9. 不提交密钥

文件选择决策树

新功能属于 Digital
├── 是 → app/[locale]/digital/ + app/digital/ + config/digital/
└── 否 → app/[locale]/ + app/components/ + config/

需要新 API
├── Digital → app/api/digital/
├── 媒体代理 → app/api/media/
└── 主站业务 → backend/main.py

线上活动?
├── 列表/弹窗 → meetups/page.tsx
├── 活动间 → meetups/[id]/live + EventLiveRoom.tsx
└── URL/权限 → meetups.ts + meetup_live.py + /session API

Python 约定

  • 请求体用 Pydantic BaseModel
  • PocketBase 走 pb_client.py
  • 新端点加 main.py,配置加 settings.py

12. 生产部署架构

域名 上游 服务
nomadro.cn :4002 Next.jscnomadcna.service
api.nomadro.cn :8000 FastAPI
pocketbase.nomadro.cn :8090 PocketBase
minio.nomadro.cn :9100/9101 MinIO
mirotalk.nomadro.cn :9300 MiroTalk P2P
lounge.nomadro.cn :9000 The Lounge
ergo.nomadro.cn HTTPS 重定向 → loungeIRC 仅本机 :6667

VPS82.157.112.245,代码目录 /home/ubuntu/gitlab-instance-0a899031_cnomadcna

上线前端:

APP_ENV=production NEXT_PUBLIC_APP_ENV=production NODE_ENV=production pnpm build
systemctl restart cnomadcna.service

活动间相关改动需同步部署 Next.js + FastAPIVPS 上 MiroTalk/Lounge 配置变更需 systemctl restart


13. 常见陷阱

问题 说明
dev 端口 pnpm dev3001,不是 3000
API 分流 /api/digital/*/api/media/* 不走 FastAPI
/api/videos 独立路由;/api/content/videos 会 404
8000 多进程 多个 uvicorn 占端口时 session 等新路由可能不生效
PowerShell 不支持 &&,分步执行
双套 lib app/lib/ vs app/digital/lib/ 各自独立
MiroTalk embed ALLOWED_EMBED_ORIGINS 需含 nomadro.cn 与 localhost:3001
Ergo 公网 不开放 IRC 6697仅 The Lounge 内网连 Ergo
密钥 .env.example 仅示例,生产用独立密钥

14. 关键文件索引

场景 文件
新增主站页面 app/[locale]/messages/*.json
活动间 meetups/[id]/live/page.tsxEventLiveRoom.tsxmeetup_live.py
活动 URL/权限 app/lib/meetups.ts
访谈视频 videos/page.tsxGET /api/videos
社区匹配 dating/page.tsxdating/components/*
调用后端 app/lib/api-client.ts
封面/媒体 URL app/lib/media.ts
头像池 app/data/avatars.tsbackend/avatar_assets.py
远程开发 config/remote-services.tsscripts/dev-tunnel.py
API 代理 next.config.ts
后端入口 backend/main.py
DB 初始化 backend/init_db.pyseed_data.py
完整运维 README.md

15. 相关文档

  • README.md — 业务介绍、部署、MiroTalk/Lounge 运维、Windows 本地开发
  • .env.example — 环境变量模板
  • app/lib/charts/README.md — 图表组件

本文件供 Cursor AI 编辑 NomadCNA 时快速建立上下文。重大架构变更后请同步更新。