# CLAUDE.md

本文件为 Claude Code (claude.ai/code) 在本仓库中工作时提供指导。

## 项目概述

QY LTY Backend 是一个基于 Django 的综合性后端服务，提供以下功能：
- 用户管理与认证系统
- AI 对话能力（支持语音的单轮/多轮聊天）
- 卡片管理系统，支持批量生成与二维码功能
- 通过 WebSocket 实时通信进行设备交互
- 成就系统
- 订阅管理
- 多种第三方集成（阿里云、火山引擎、腾讯等）

### 对接的客户端项目

本服务器作为统一后端，与以下客户端/管理端项目进行通讯和数据交互：

| 项目 | 路径 | 角色 | 通讯方式 |
|------|------|------|---------|
| **LTY_App_Project_URP** | `C:\Unity2022project\LTY_App_Project_URP` | 洛天依 APP（Unity URP 客户端） | HTTP REST API + WebSocket (`/ws/device/`) |
| **LTY_Project** | `C:\Unity2022project\LTY_Project` | 洛天依 Unity 项目（设备端/终端） | HTTP REST API + WebSocket + RTC（火山引擎） |
| **qy-lty-admin** | `../qy-lty-admin/`（`C:\Users\admin\Desktop\Lila-Server\qy-lty-admin`） | Web 管理后台（Next.js 15 + React 19） | HTTP REST API（`NEXT_PUBLIC_API_BASE_URL`） |

- 两个 Unity 客户端通过 `device_interaction` 模块共享同一套 WebSocket 通道（分组模型 `device_{user_id}`），设备端与 APP 端解析到同一 user_id 才能互通消息
- 管理后台通过 `/api/v1/admin/` 与各业务模块接口进行运营管理数据交互

## 开发命令

### 环境配置
```bash
# 安装依赖
pip install -r requirements.txt

# 复制环境配置文件
cp .env.bak .env

# 数据库迁移
python manage.py migrate

# 创建超级用户
python manage.py createsuperuser
```

### 运行应用
```bash
# 启动开发服务器（支持 WebSocket 的 ASGI）
./run.sh

# 或直接使用 daphne
daphne -b 0.0.0.0 -p 8000 qy_lty.asgi:application

# 传统 Django 开发服务器（仅 HTTP）
python manage.py runserver
```

### 数据库管理
```bash
# 创建新的迁移文件
python manage.py makemigrations
python manage.py makemigrations [app_name]

# 应用迁移
python manage.py migrate

# 数据库 shell
python manage.py dbshell

# Django shell
python manage.py shell
```

### 国际化 (i18n)
```bash
# 生成消息文件
django-admin makemessages -l en
django-admin makemessages -l zh_HAns

# 编译翻译
django-admin compilemessages
```

### Docker 部署
```bash
# 构建并启动容器
docker-compose up -d --build

# 通过 http://localhost:12012 访问应用
```

## 架构概览

### 核心 Django 应用结构
- **userapp/**：自定义用户模型 (ParadiseUser)，包含认证、手机验证和用户管理
- **aiapp/**：AI 对话系统，集成 Kimi，通过多个服务商提供语音合成/识别
- **card/**：卡片管理系统，包含分类、批次、二维码和使用追踪
- **device_interaction/**：基于 WebSocket 的实时设备通信，带有认证机制
- **achievement_app/**：用户成就与进度追踪系统
- **subscription_app/**：用户订阅与计费管理
- **ali_vi_app/**：阿里云视觉智能集成
- **workflow_app/**：多租户工作流管理（开发中）

### 关键技术组件

#### ASGI/WebSocket 配置
- 使用 Django Channels 提供 WebSocket 支持
- 自定义基于 token 的 WebSocket 认证（`device_interaction.auth.TokenAuthMiddleware`，复用 `userapp.authentication.RedisTokenAuthentication`）
- 基于 Redis 的通道层用于实时消息传递
- WebSocket 路由：`ws://domain/ws/device/`（Header 鉴权）和 `ws://domain/ws/device/token/{token}/`（URL 鉴权）
- **分组模型**：`device_{user_id}` —— 设备端与手机端必须解析到 **同一个 user_id** 才能互通消息（详见下文"设备绑定与控制权"）

#### 认证系统
- 自定义用户模型：`userapp.ParadiseUser`，继承自 AbstractUser
- 基于 token 的 API 认证：token 存储在 Redis 中，普通用户 key 为 `token:{token}`，管理员为 `admin_token:{token}`，TTL 30 天（见 `userapp/utils.py:generate_token`）
- 通过短信进行手机验证（阿里云 SMS 服务）
- 通过 django-allauth 实现社交认证（微信）
- 设备端通过 `POST /api/user/mac-login/` 用 MAC 地址换取绑定用户的 user-token

#### 数据库配置
- 主库：PostgreSQL（可通过环境变量配置）
- Redis 用于缓存和 WebSocket 通道层
- 使用 python-decouple 进行基于环境的配置

#### 音频/语音服务
- 多服务商音频支持：阿里云、腾讯、火山引擎
- 通过 `AUDIO_SERVICE_PROVIDER` 配置切换服务商
- 支持语音合成与识别能力

## API 文档

### 访问入口
- Swagger UI：`http://localhost:8000/swagger/`
- ReDoc：`http://localhost:8000/redoc/`

### 主要 API 模块
- `/api/user/` - 用户认证与管理
- `/api/ai/` - AI 对话接口
- `/api/device/` - 设备交互与 WebSocket 消息
- `/api/card/` - 卡片系统管理
- `/api/achievement/` - 成就系统
- `/api/v1/admin/` - 管理功能

### WebSocket 消息类型
```json
{
    "type": "message_type",
    "message": "content",
    "user_id": "user_id"
}
```

支持的类型（见 `device_interaction/consumers.py:DeviceConsumer.receive`）：
- `chat_message` — 默认文本消息
- `weather` — 天气信息（message 为 JSON 字符串）
- `sing` / `dance` / `touch` — 动作指令
- `flow_light` — 流水灯开关
- `device_info` — 设备上报 MAC、电量、固件、WiFi 等，会写库并刷新心跳
- `device_state` — 手机端设备状态
- `conversation_status` / `conversation_subtitle` — 火山引擎对话回调转发
- `factory_reset` — 恢复出厂设置

### RTC（火山引擎）
- 端点 `/api/device/rtc-token/get_by_mac/?mac_address=...` 不需鉴权，根据 MAC 返回该设备绑定用户对应的 RTC token
- `room_id = f"room_{user_id}"`、token 缓存 key 为 `rtc_room:{user_id}:{task_id}`
- `room_id` 与 WebSocket 分组绑定的是同一个 user_id，保持端到端一致

## 环境配置

### 必需的环境变量 (.env)
- `SECRET_KEY` - Django 密钥
- `DEBUG` - 开发模式标志
- 数据库：`POSTGRESQL_DATABASE_*` 系列变量
- Redis：`REDIS_LOCATION`、`REDIS_PASSWORD`
- Kimi AI：`KIMI_API_KEY`、`KIMI_BASE_URL`
- 阿里云服务：各类 `ALIYUN_*` 密钥
- 音频服务：服务商相关配置
- 火山引擎：`VOLCENGINE_ACCESS_KEY`、`VOLCENGINE_SECRET_KEY`

## 关键依赖

### 核心框架
- Django 4.2.13 配合 Django REST Framework
- Django Channels 提供 WebSocket 支持
- Daphne ASGI 服务器

### 第三方集成
- 阿里云：SMS、OSS、NLS（语音）、视觉智能
- 火山引擎（字节跳动）：RTC 服务
- 腾讯：音频服务
- OpenAI 兼容 API（Kimi）

### 开发工具
- django-debug-toolbar 用于开发环境调试
- django-simpleui 用于增强后台管理界面
- drf-yasg 用于生成 API 文档

## 代码模式与约定

### 模型结构
- 自定义用户模型，包含丰富的资料字段（性别、MBTI、兴趣等）
- 卡片系统采用基于批次的生成方式，配合分类管理
- 成就系统包含稀有度等级与进度追踪

### API 响应格式
- 通过 `common.middleware.StandardResponseMiddleware` 实现标准化响应
- 自定义分页：`common.pagination.CustomPageNumberPagination`

### 日志
- 集成阿里云日志服务用于生产环境日志记录
- 为 aiapp、userapp、common 模块配置专用日志记录器

### 文件存储
- 使用 OSS（阿里云对象存储）存储音频和媒体文件
- 开发环境使用本地存储，路径可配置

## 开发说明

### WebSocket 开发
- 设备连接需要基于 token 的认证
- 通道层使用 Redis 进行消息传递
- 自定义消费者位于 `device_interaction.consumers`
- 设备心跳：每次收消息时刷新 `device:last_seen:{mac}`（TTL 5 分钟），断连时把 `Device.status` 标记为 `disconnected`

### 设备绑定与控制权（重要）
- `UserDevice` 关联表的 `Meta.ordering = ['-bound_at']`
- **"后绑的挤掉先绑的"语义**：`userapp/views.py` 的 MAC 登录显式按 `order_by('-bound_at').first()` 取最新绑定者并签发 user-token；`device_interaction/views.py` 中的 `bind_status` / `rtc-token/get_by_mac` 等使用 `.first()` 隐式依赖该 ordering，结果一致
- 由于 WebSocket 分组是 `device_{user_id}`，**同一台设备同一时刻只有一个用户能真正控制它**——即最近一次绑定的那个用户
- 旧的 `UserDevice` 记录**不会**被自动删除，仅在控制权解析中被忽略；如需"换绑"语义请显式删除旧记录
- `is_primary` 是"用户视角的主设备"（每个用户最多一个），**不是**"设备视角的主控用户"——同一台设备可能出现多条 `is_primary=True` 的记录
- **测试 MAC `AA:BB:CC:DD:EE:FF`** 在 `device_interaction/serializers.py` 与 `views.py` 中被硬编码跳过"设备已被其他用户绑定"校验，仅供测试用

### 音频服务集成
- 通过 `aiapp.audio.AudioService` 提供与服务商无关的接口
- 支持语音转文本与文本转语音能力
- 集成文件存储用于音频资源管理

### 卡片系统功能
- 批量生成，支持配置数量与格式
- 二维码生成与扫描
- 使用追踪与数据分析
- 基于分类的组织管理，支持属性配置

### 后台管理界面
- 深度定制 SimpleUI 主题
- 支持多语言（中文/英文）
- 为不同模块配置自定义图标与组织结构

## 项目修改记录规则（重要 — 自动执行）

每次对本仓库代码做出改动后，**必须**在同一会话内把变更追加到 [docs/修改记录.md](docs/修改记录.md) **顶部**（最新在最前），不要等用户提醒。条目格式遵循该文件头部"修改格式说明"约定：

```
### [日期] 修改简述

- **文件路径**: 相对于项目根目录的文件路径
- **修改类型**: 新增 / 修改 / 删除 / 重构 / 修复Bug
- **修改内容**: 具体修改了什么
- **修改原因**: 为什么要做这个修改
```

### `qy_lty` 与 `qy-lty-admin` 是独立项目，各自维护

- `qy_lty/docs/修改记录.md` — **仅**记录服务端（本仓库）改动
- `qy-lty-admin/docs/修改记录.md` — **仅**记录管理后台前端改动；如该文件不存在则新建（基于 qy_lty 同名文件的格式骨架）

跨项目联动（例如新增服务端接口 + 管理后台调用）：**两端各写一条，相互引用**对方的修改记录条目，不要把两端混进同一条记录里。

### 适用范围

- 业务代码、配置、迁移文件、CI / k8s / Dockerfile、文档结构性改动 → **必须**记录
- 单纯的 typo 修复、注释微调 → 可省略
- 临时调试脚本、`.gitignore` 中文件、本地实验文件 → 不记录
