lty/qy_lty/.planning/codebase/INTEGRATIONS.md
2026-05-07 10:37:16 +08:00

180 lines
9.5 KiB
Markdown

# External Integrations
**Analysis Date:** 2026-05-07
## APIs & External Services
**AI & Language Models:**
- Kimi (OpenAI-compatible) - LLM for multi-turn AI conversations
- SDK: `openai` Python package (in `requirements.txt`)
- Implementation: `aiapp/kimi.py` (lines 1-29)
- Config: `KIMI_API_KEY`, `KIMI_BASE_URL` (set at `qy_lty/settings.py:349-350`, loaded from `.env`)
- Purpose: Single/multi-turn chat with users via POST `/api/ai/chat/` and `/api/ai/multi-chat/`
**Real-Time Communications (RTC):**
- Volcengine (ByteDance) - RTC service for voice/video calls
- SDK: Custom token generation in `common/VolcEngineAccessToken.py` (lines 1-204), HTTP API calls in `device_interaction/volcengine_api.py`
- Config: `VOLCENGINE_ACCESS_KEY`, `VOLCENGINE_SECRET_KEY`, `VOLCENGINE_APP_ID`, `VOLCENGINE_APP_KEY` (at `qy_lty/settings.py:241-243`)
- Purpose: Generate RTC tokens for device-to-device or device-to-app real-time communication
- Endpoint: `POST /api/device/rtc-token/get_by_mac/?mac_address=...` (no auth required, returns RTC token for device's bound user)
- Room structure: `room_id = f"room_{user_id}"` (shared with WebSocket group `device_{user_id}`)
**Audio/Speech Services (Multi-Provider):**
- Configured via `AUDIO_SERVICE_PROVIDER` setting (default: `'huoshan'`) at `qy_lty/settings.py:415`
**Aliyun NLS (Natural Language Service):**
- SDK: `aliyun-python-sdk-core` + custom integration
- Implementation: `aiapp/audio/AliyunAudioService.py`
- Config keys: `ALIYUN_NLS_ACCESS_KEY_ID`, `ALIYUN_NLS_ACCESS_KEY_SECRET`, `ALIYUN_NLS_APP_ID` (in `qy_lty/settings.py:419-421`)
- Purpose: Speech synthesis (text→voice) and recognition (voice→text)
- Storage: Audio uploaded to Aliyun OSS (see OSS section)
**Tencent Audio:**
- Implementation: `aiapp/audio/TencentAudioService.py`
- Config keys: `AUDIO_SERVICE_TENCENT_API_KEY`, `AUDIO_SERVICE_TENCENT_API_SECRET` (at `qy_lty/settings.py:430-431`)
- Purpose: Text-to-speech and speech-to-text via Tencent APIs
**Volcengine/Huoshan (ByteDance):**
- Implementation: `aiapp/audio/HuoshanAudioService.py`, `aiapp/audio/HuoshanAudioService_new.py`
- Config keys: `AUDIO_SERVICE_HUOSHAN_APPID`, `AUDIO_SERVICE_HUOSHAN_ACCESS_TOKEN`, `AUDIO_SERVICE_HUOSHAN_CLUSTER`, `AUDIO_SERVICE_HUOSHAN_VOICE_TYPE`, `AUDIO_SERVICE_HUOSHAN_STORAGE_DIR`, `AUDIO_SERVICE_HUOSHAN_BASE_URL` (at `qy_lty/settings.py:434-439`)
- Purpose: TTS (text→speech) and ASR (speech→text) with local storage fallback
- Also includes nested Aliyun ASR config (lines 440-451) as fallback
**Audio Service Factory:**
- Entry point: `aiapp/audio/AudioService.py:get_audio_service()` (lines 8-19)
- Base class: `aiapp/audio/BaseAudioService.py` (abstract interface at lines 1-35)
- Used by: `aiapp/views.py` (ChatBotAPIView, MultiChatAPIView) and tests
## Data Storage
**Databases:**
- **PostgreSQL** (Primary)
- Connection: `POSTGRESQL_DATABASE_*` env vars (configured at `qy_lty/settings.py:166-172`)
- Client: psycopg2-binary
- Contains: User models, AI conversations, device bindings, card data, achievement records, subscription info
- **Redis** (Cache + Message Queue)
- Connection: `REDIS_LOCATION`, `REDIS_PASSWORD` (configured at `qy_lty/settings.py:252-260`)
- Client: django-redis
- Purpose: Token storage (key format: `token:{token}` or `admin_token:{token}` with 30-day TTL, see `CLAUDE.md` line 122), channel layer for WebSocket, caching
- Channel layer config: `CHANNEL_LAYERS.default.BACKEND = 'channels_redis.core.RedisChannelLayer'` (at `qy_lty/settings.py:504-511`)
**File Storage:**
- **Aliyun OSS (Object Storage Service)** - Production storage for audio, images, documents
- SDK: `oss2` Python package (in `requirements.txt`)
- Implementation: `common/oss.py` (OSSUploader class at lines 1-90)
- Config: `AUDIO_SERVICE_CONFIG['aliyun']` with `oss_key_id`, `oss_key_secret`, `oss_bucket`, `oss_endpoint`, `oss_host` (at `qy_lty/settings.py:422-427`)
- Used by: Audio service, image processing endpoints, media uploads
- Path pattern: `{base_dir}/[permanent|temporary]/{YYYYMMDD}/{filename}`
- Dev fallback: Local filesystem storage at `MEDIA_ROOT` (`qy_lty/settings.py:238`)
**Caching:**
- Redis (see above)
- TTL for RTC tokens: `rtc_room:{user_id}:{task_id}` (see `CLAUDE.md` line 172)
- Device last-seen cache: `device:last_seen:{mac}` with 5-min TTL (see `CLAUDE.md` line 230)
## Authentication & Identity
**Auth Provider:**
- Custom Redis-backed token authentication + django-allauth social auth
**Custom Token Auth:**
- Implementation: `userapp/authentication.RedisTokenAuthentication` (at `userapp/authentication.py:10-34`)
- Storage: Redis with keys `token:{token}` (users) and `admin_token:{token}` (admins)
- TTL: 30 days
- Used for: API requests via `Authorization: Bearer {token}` header
- Generated by: `userapp/utils.py:generate_token()` (referenced in `CLAUDE.md` line 122)
**WeChat Social Auth:**
- Provider: django-allauth with Weixin provider (configured at `qy_lty/settings.py:56`)
- Backend: `allauth.account.auth_backends.AuthenticationBackend` (at `qy_lty/settings.py:324`)
**WebSocket Auth:**
- Custom middleware: `device_interaction/auth.TokenAuthMiddleware` (lines 1-50)
- Reuses `RedisTokenAuthentication` logic with mock request adapter
- Routes: `ws://domain/ws/device/` (Header auth) and `ws://domain/ws/device/token/{token}/` (URL auth)
- Group model: Messages routed to `device_{user_id}` (same user controls device and app)
**Device MAC Login:**
- Endpoint: `POST /api/user/mac-login/` (referenced in `CLAUDE.md` line 125)
- Returns: User-token for device's bound user (latest binding via `order_by('-bound_at').first()`)
- Model: `UserDevice` relationship with `bound_at` ordering
## Monitoring & Observability
**Error Tracking:**
- No dedicated external error tracking (Sentry, etc.) detected
**Logs:**
- **Aliyun Log Service** - Production logging integration
- SDK: `aliyun-log-python-sdk` (in `requirements.txt`)
- Implementation: `common/aliyun_logging.py` (AliyunLogHandler at lines 16-36, setup_logging() at lines 32-36)
- Config: `ALIYUN_LOG_PROJECT`, `ALIYUN_LOG_STORE`, `ALIYUN_LOG_ENDPOINT`, `ALIYUN_LOG_ACCESS_KEY_ID`, `ALIYUN_LOG_ACCESS_KEY_SECRET` (env vars, loaded at lines 7-11)
- Logging config: `qy_lty/settings.py:372-411` configures handlers for `django`, `django.request`, `aiapp`, `common`, `userapp` loggers
- Log levels: INFO for production, DEBUG for console in dev
## CI/CD & Deployment
**Hosting:**
- Docker containers (self-managed or cloud-hosted)
- Image base: Python 3.8 via docker.m.daocloud.io (China mirror)
**CI Pipeline:**
- No dedicated CI/CD service detected in code (GitHub Actions, GitLab CI, etc. config not present)
**Deployment:**
- Docker Compose for local/staging (docker-compose.yml:1-33)
- Production via Docker Compose or Kubernetes (see Dockerfile for structure)
- Port exposure: 12012 (maps to ASGI 8000)
## Environment Configuration
**Required env vars (from settings.py and CLAUDE.md):**
- `SECRET_KEY` - Django secret
- `DEBUG` - Debug mode
- `POSTGRESQL_DATABASE_NAME`, `POSTGRESQL_DATABASE_USER`, `POSTGRESQL_DATABASE_PASSWORD`, `POSTGRESQL_DATABASE_HOST`, `POSTGRESQL_DATABASE_PORT`
- `REDIS_LOCATION`, `REDIS_PASSWORD`
- `KIMI_API_KEY`, `KIMI_BASE_URL` (default: https://api.moonshot.cn/v1)
- `ALIYUN_SMS_ACCESS_KEY_ID`, `ALIYUN_SMS_ACCESS_KEY_SECRET`, `ALIYUN_SMS_SIGN_NAME`, `ALIYUN_SMS_TEMPLATE_CODE`
- `ALIYUN_NLS_ACCESS_KEY_ID`, `ALIYUN_NLS_ACCESS_KEY_SECRET`, `ALIYUN_NLS_APP_ID`
- `ALIYUN_OSS_ACCESS_KEY_ID`, `ALIYUN_OSS_ACCESS_KEY_SECRET`, `ALIYUN_OSS_BUCKET`, `ALIYUN_OSS_ENDPOINT`, `ALIYUN_OSS_HOST`, `ALIYUN_OSS_AUDIO_BASE_DIR`
- `ALIYUN_VI_ACCESS_KEY_ID`, `ALIYUN_VI_ACCESS_KEY_SECRET`, `ALIYUN_VI_ENDPOINT`, `ALIYUN_VI_REGION`
- `ALIYUN_LOG_PROJECT`, `ALIYUN_LOG_STORE`, `ALIYUN_LOG_ENDPOINT`, `ALIYUN_LOG_ACCESS_KEY_ID`, `ALIYUN_LOG_ACCESS_KEY_SECRET`
- `VOLCENGINE_ACCESS_KEY`, `VOLCENGINE_SECRET_KEY`, `VOLCENGINE_APP_ID`, `VOLCENGINE_APP_KEY`
- `AUDIO_SERVICE_PROVIDER` (values: 'aliyun', 'tencent', 'huoshan'; default: 'huoshan')
- `AUDIO_SERVICE_HUOSHAN_APPID`, `AUDIO_SERVICE_HUOSHAN_ACCESS_TOKEN`, `AUDIO_SERVICE_HUOSHAN_CLUSTER`, `AUDIO_SERVICE_HUOSHAN_VOICE_TYPE`, `AUDIO_SERVICE_HUOSHAN_STORAGE_DIR`, `AUDIO_SERVICE_HUOSHAN_BASE_URL`
- `AUDIO_SERVICE_TENCENT_API_KEY`, `AUDIO_SERVICE_TENCENT_API_SECRET` (if provider='tencent')
**Secrets location:**
- `.env` file (git-ignored, copy from `.env.bak` template during setup per `CLAUDE.md` line 44)
## Webhooks & Callbacks
**Incoming:**
- WebSocket device messages routed to `device_{user_id}` group (see `CLAUDE.md` line 118)
- Volcengine RTC conversation callbacks: `conversation_status`, `conversation_subtitle` message types forwarded via WebSocket (see `CLAUDE.md` line 167)
- Device heartbeat: `device:last_seen:{mac}` refreshed on message receipt (see `CLAUDE.md` line 230)
**Outgoing:**
- No outbound webhooks detected (integrations are request/response based)
## API Documentation
**Documentation Endpoints:**
- Swagger UI: `http://localhost:8000/swagger/`
- ReDoc: `http://localhost:8000/redoc/`
- Generated by: drf-yasg (configured at `qy_lty/settings.py:513-549`)
**Main API Routes:**
- `/api/user/` - User auth & management (MAC login, token generation)
- `/api/ai/` - AI chat (single-turn, multi-turn, voice synthesis/recognition)
- `/api/device/` - Device interaction, RTC tokens, binding status
- `/api/card/` - Card system (batch generation, QR codes, usage tracking)
- `/api/achievement/` - Achievement tracking
- `/api/v1/admin/` - Admin operations
- `/ws/device/` - WebSocket for real-time device communication
---
*Integration audit: 2026-05-07*