5d434ead6f
- LiveKit WebRTC SFU container in docker-compose - Voice token microservice (Node.js + Express) - VoiceRoom page with member grid and controls - useVoiceRoom composable for LiveKit connection - Voice entry button in TeamSessionPanel - Nginx proxy for voice-token service API Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
108 lines
5.7 KiB
Markdown
108 lines
5.7 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## 项目概述
|
||
|
||
Game Group V2 — 游戏组队管理平台。用户创建/加入群组,组队开黑,管理游戏库、投票、积分竞猜、账本和资产。
|
||
|
||
## 开发命令
|
||
|
||
```bash
|
||
# 构建前端
|
||
cd frontend && npm run build
|
||
|
||
# 本地开发(一般不用,用 Docker 部署代替)
|
||
cd frontend && npm run dev
|
||
|
||
# 部署脚本(根目录)
|
||
./deploy-backend.sh # 部署 PocketBase 后端
|
||
./deploy-dev.sh # 构建 + 部署 Dev 前端 (端口 7033)
|
||
./deploy-uat.sh # 构建 + 部署 UAT 前端 + 后端 (端口 7034/8712)
|
||
./stop-all.sh # 停止所有服务
|
||
|
||
# 查看日志
|
||
docker logs -f gamegroup-pb # 后端
|
||
docker logs -f gamegroup-frontend-dev # Dev
|
||
docker logs -f gamegroup-frontend-uat # UAT
|
||
```
|
||
|
||
**重要**: 不要在本地启动 vite dev server,使用 Docker 部署后通过端口访问测试。Dev 环境在 `http://192.168.1.14:7033`。部署到 UAT 前必须等用户确认。
|
||
|
||
## 技术栈
|
||
|
||
- **后端**: PocketBase 0.22.4 (Docker, `ghcr.io/muchobien/pocketbase`) — 无自定义 JS hooks,业务逻辑全在前端
|
||
- **前端**: Vue 3 + TypeScript + Pinia + Element Plus + Tailwind CSS + Vite
|
||
- **API 通信**: PocketBase JS SDK (`pocketbase` npm 包),localStorage 持久化认证
|
||
- **实时通信**: PocketBase realtime subscriptions
|
||
- **样式**: 自定义 CSS 变量 (`--gg-*` 前缀, `design.css`) + Tailwind + Element Plus,绿色主题
|
||
|
||
## 环境与端口
|
||
|
||
| 服务 | Dev | UAT |
|
||
|------|-----|-----|
|
||
| 前端 (nginx) | 7033 | 7034 |
|
||
| PocketBase | 8090 | 8712 |
|
||
|
||
Docker Compose 文件:`docker-compose.backend.yml`、`docker-compose.dev.yml`、`docker-compose.uat.yml`,共享 `gamegroup-net` 网络。
|
||
|
||
## 架构
|
||
|
||
### 前端核心流程
|
||
|
||
```
|
||
pocketbase.ts (PB 客户端初始化)
|
||
→ router guards (isAuthenticated 检查)
|
||
→ stores (user/group/team/notification/poll/ledger/asset/memory)
|
||
→ api/ (PocketBase CRUD 封装,每个领域一个文件)
|
||
→ components + views
|
||
```
|
||
|
||
- **`api/pocketbase.ts`** — 单例 PocketBase 客户端,导出 `pb`、`getCurrentUser()`、`isAuthenticated()`、`logout()`
|
||
- **`api/`** — 每个领域一个文件(`users.ts`, `groups.ts`, `sessions.ts`, `invitations.ts`, `games.ts`, `polls.ts`, `bets.ts`, `points.ts`, `ledgers.ts`, `assets.ts`, `memories.ts`, `notifications.ts`, `gameBlacklist.ts`, `playerBlacklist.ts`)
|
||
- **`stores/`** — Pinia stores,组合式 API 风格(`defineStore('name', () => {...})`)
|
||
- **`composables/useRealtime.ts`** — 统一管理 PocketBase 实时订阅,组件卸载时自动清理
|
||
- **`types/index.ts`** — 所有接口集中定义 + `displayName()` 工具函数 + 状态映射常量(如 `UserStatusMap`、`TeamStatusMap`)
|
||
|
||
### 认证流程
|
||
|
||
- 注册:用户输入中文昵称存 `name` 字段,`username` 自动生成 ASCII 标识(`'u' + Date.now().toString(36) + random`)
|
||
- 登录:支持昵称/邮箱/username 登录。输入不含 `@` 时查询 `users` collection 的 `name`/`username` 字段,获取 `username` 后调用 `authWithPassword(username, password)`
|
||
- 路由守卫:`requiresAuth` 跳转登录页,`requiresGuest` 跳转首页
|
||
|
||
### 路由结构
|
||
|
||
Layout (`/`) 下所有认证页面为子路由:Home, GroupView (`/group/:id`), LedgerView (`/group/:groupId/ledger`), AssetView (`/group/:groupId/assets`), BlacklistView (`/group/:groupId/blacklist`), GamesLibrary, Profile, Settings, Changelog。Login/Register 为独立路由。
|
||
|
||
### Vite 代理 vs Nginx
|
||
|
||
开发环境 Vite 将 `/api` 代理到 PocketBase(去掉 `/api` 前缀)。生产环境 nginx 做同样代理,SSE realtime 连接额外禁用 buffering。
|
||
|
||
### 数据模型(PocketBase Collections)
|
||
|
||
- **users** — 认证集合。`username` 是系统字段(不可改,仅 `[a-z0-9_-]`),中文昵称存 `name` 字段。状态:idle/working/in_team/away
|
||
- **groups** — owner + members 关系,支持审核加入(requireApproval)
|
||
- **team_sessions** — 临时组队,状态流转:recruiting → playing → finished/dissolved
|
||
- **invitations** — 组队邀请,pending/accepted/rejected
|
||
- **games** — 游戏库,归属 group,含平台、标签、封面
|
||
- **game_comments** / **game_favorites** — 评论和收藏
|
||
- **join_requests** — 入群申请
|
||
- **polls** / **poll_options** / **poll_votes** — 投票(选项投票/点名),含匿名、截止时间
|
||
- **bets** / **bet_options** / **bet_entries** — 积分竞猜,含下注范围和结算
|
||
- **point_logs** — 积分流水(vote/team/memory/bet 行为)
|
||
- **memories** — 多媒体记忆(图片/视频/音频/文档),归属 group
|
||
- **ledgers** — 群组账本(收入/支出),按游戏/聚餐/设备/交通分类
|
||
- **assets** — 群组资产(游戏账号/主机/设备/配件),含当前持有者
|
||
- **game_blacklist** — 游戏黑名单(行为/外挂/坑货/环境差)
|
||
- **player_blacklist** — 玩家黑名单(标签:挂机/送人头/喷人等)
|
||
- **notifications** — 站内通知(投票/组队/入群等事件)
|
||
|
||
### PocketBase 注意事项
|
||
|
||
- `users` collection 的 `listRule`/`viewRule` 设为空字符串(公开),以支持登录页查询用户
|
||
- Auth collection 的 `email` 字段不对未认证请求暴露,登录查找用 `username` 替代
|
||
- 数据迁移在 `backend/pb_migrations/`,由管理面板操作自动生成。**不要**为 `username` 等系统字段创建 `addField` 迁移,会导致 `duplicate column` 错误
|
||
- PocketBase 管理面板:`admin@example.com` / `admin123456`
|
||
- 前端 `.env` 文件:`VITE_PB_URL` 配置后端地址,`VITE_PORT` 配置开发端口
|
||
- API 调用添加 `$autoCancel: false` 避免 PocketBase SDK 自动取消请求
|