fix(join-group): redirect unauthenticated users to login + docs update

- JoinGroupPage: redirect to login when user is not authenticated
- CLAUDE.md: add env details, path alias, and coding constraints

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
congsh
2026-06-18 13:53:38 +08:00
parent d76ecb15d6
commit 80dc45f528
2 changed files with 21 additions and 7 deletions
+12 -6
View File
@@ -9,7 +9,7 @@ Game Group V2 — 游戏组队管理平台。用户创建/加入群组,组队
## 开发命令
```bash
# 构建前端
# 构建前端(先 vue-tsc 类型检查,再 vite build。类型错误会阻断构建)
# 注意:npm run build 默认加载 .env.dev 的变量。Docker 构建时通过 ARG 注入空 VITE_PB_URL,由 nginx 代理处理
# 如需本地测试 UAT 构建设置,使用:cd frontend && npm run build -- --mode uat
cd frontend && npm run build
@@ -63,7 +63,7 @@ docker logs -f gamegroup-frontend-uat # UAT 前端
Docker Compose 文件:`docker-compose.dev.yml`Dev 全套)、`docker-compose.uat.yml`UAT 全套),共享 `gamegroup-net` 网络。每个环境独立运行完整的 PB + LiveKit + Voice Token + 前端服务。
前端 `.env` 文件:`frontend/.env.dev`VITE_PB_URL=8711, PORT=7033)和 `frontend/.env.uat`VITE_PB_URL=8711, PORT=7034)。注意 Dev/UAT 构建时 VITE_PB_URL 都指向 8711,因为 Docker 构建时会将其覆盖为空,由 nginx 反向代理处理。
前端 `.env` 文件:`frontend/.env.dev``frontend/.env.uat`。每个 env 包含四个变量:`VITE_PB_URL`PocketBase 地址)、`VITE_PORT`dev server 端口)、`VITE_LIVEKIT_URL`LiveKit WebSocket 地址)、`VITE_VOICE_TOKEN_URL`Voice Token 服务地址)。Docker 构建时 `VITE_PB_URL`覆盖为空,由 nginx 反向代理处理。
## 架构
@@ -78,11 +78,12 @@ pocketbase.ts (PB 客户端初始化)
```
- **`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`, `voice.ts`, `bulletins.ts`
- **`stores/`** — Pinia stores,组合式 API 风格(`defineStore('name', () => {...})`
- **`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`, `voice.ts`, `bulletins.ts`, `events.ts`
- **`stores/`** — Pinia stores,组合式 API 风格(`defineStore('name', () => {...})`。共 11 个 storeuser/group/team/event/poll/ledger/asset/memory/notification/bulletin),`index.ts` 仅导出前 3 个,其余直接从文件导入
- **`composables/useRealtime.ts`** — 统一管理 PocketBase 实时订阅,组件卸载时自动清理
- **`composables/useVoiceRoom.ts`** — LiveKit 语音房间封装,处理连接/断开/麦克风/扬声器控制
- **`types/index.ts`** — 所有接口集中定义 + `displayName()` 工具函数 + 状态映射常量(如 `UserStatusMap``TeamStatusMap`
- **路径别名**: `@/` 映射到 `src/`,在 `vite.config.ts``tsconfig.json` 中配置
### 认证流程
@@ -92,7 +93,7 @@ pocketbase.ts (PB 客户端初始化)
### 路由结构
Layout (`/`) 下所有认证页面为子路由:Home, GroupView (`/group/:id`), LedgerView (`/group/:groupId/ledger`), AssetView (`/group/:groupId/assets`), BlacklistView (`/group/:groupId/blacklist`), VoiceRoom (`/group/:groupId/voice/:sessionId`), GamesLibrary, Profile, Settings, Changelog。Login/Register 为独立路由。
Layout (`/`) 下所有认证页面为子路由:Home, GroupView (`/group/:id`), LedgerView (`/group/:groupId/ledger`), AssetView (`/group/:groupId/assets`), BlacklistView (`/group/:groupId/blacklist`), VoiceRoom (`/group/:groupId/voice/:sessionId`), GamesLibrary, Profile, Settings, Changelog。Login/Register 为独立路由。JoinGroup (`/join/group/:groupId`) 和 JoinTeam (`/join/team/:sessionId`) 为无需认证的独立页面,用于外部邀请链接。
### Vite 代理 vs Nginx
@@ -148,5 +149,10 @@ HTTP 环境下 `navigator.mediaDevices` 受限,已在 `useVoiceRoom.ts` 中给
- 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 自动取消请求
## 编码约束
- **TypeScript 严格模式**: `strict: true` + `noUnusedLocals` + `noUnusedParameters`,未使用的变量/参数会导致构建失败
- **无测试框架**: 项目当前没有测试文件和测试配置,不要尝试运行测试
- **无 Linter 配置**: 没有 ESLint/Prettier 配置文件