183 lines
6.4 KiB
Markdown
183 lines
6.4 KiB
Markdown
# External Integrations
|
|
|
|
**Analysis Date:** 2026-05-07
|
|
|
|
## APIs & External Services
|
|
|
|
**qy_lty Backend (Django REST API):**
|
|
- Primary backend for all business logic
|
|
- URL: Base configured via `NEXT_PUBLIC_API_BASE_URL` (default: `http://localhost:8000/api`)
|
|
- SDK/Client: Axios (custom instance with interceptors)
|
|
- Auth: Bearer token via `Authorization: Bearer {token}` header
|
|
- Primary modules consumed:
|
|
- `/api/v1/admin/login/` - User authentication
|
|
- `/api/v1/admin/logout/` - User logout
|
|
- `/ai/bots/` - AI model CRUD
|
|
- `/card/category/clothing/` - Outfit/clothing items
|
|
- `/card/category/props/` - Props/accessories
|
|
- `/card/category/home-decor/` - Home decoration items
|
|
- `/card/category/food/` - Food items
|
|
- `/music/songs/` - Song management
|
|
- `/dances/` - Dance content
|
|
- `/achievements/` - Achievement system
|
|
- `/affinity/` - Affinity/favorability system
|
|
- `/common/upload/` - File upload endpoint
|
|
- `/common/upload/info/` - File metadata retrieval
|
|
|
|
**Request/Response Pattern:**
|
|
```typescript
|
|
// Axios configuration: lib/api/client.ts
|
|
const apiClient = axios.create({
|
|
baseURL: API_BASE_URL,
|
|
headers: { 'Content-Type': 'application/json' }
|
|
})
|
|
|
|
// Request interceptor: auto-injects token
|
|
apiClient.interceptors.request.use((config) => {
|
|
const token = localStorage.getItem('auth_token')
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`
|
|
}
|
|
return config
|
|
})
|
|
|
|
// Response interceptor: handles 401 (redirect to /login)
|
|
apiClient.interceptors.response.use(
|
|
(response) => response,
|
|
(error) => {
|
|
if (error.response?.status === 401) {
|
|
localStorage.removeItem('auth_token')
|
|
window.location.href = '/login'
|
|
}
|
|
return Promise.reject(error)
|
|
}
|
|
)
|
|
```
|
|
|
|
## Data Storage
|
|
|
|
**Databases:**
|
|
- No direct database connection from frontend
|
|
- Backend (qy_lty) manages all persistent data (PostgreSQL/MySQL presumed)
|
|
- Frontend uses in-memory mock data for fallback/demo scenarios only
|
|
|
|
**File Storage:**
|
|
- Backend-managed via `/common/upload/` endpoint
|
|
- Upload types supported:
|
|
- **Images** (JPEG, PNG, GIF, WebP) - max 10MB
|
|
- **Avatars** (JPEG, PNG) - max 2MB
|
|
- **Audio** (MP3, WAV, OGG, AAC, FLAC, WMA, M4A) - max 20MB
|
|
- **Animations** (MP4, AVI, MOV, WMV, FLV, GIF, Lottie JSON) - max 50MB
|
|
- **General files** - multipart/form-data
|
|
- Upload library: File API (FormData) via Axios
|
|
- Progress tracking: `onUploadProgress` callback support
|
|
|
|
**Caching:**
|
|
- Browser localStorage for:
|
|
- `auth_token` - Authentication token (auto-removed on 401)
|
|
- `is_superuser` - Superuser flag
|
|
- `user_role` - User role string (used for permission checks)
|
|
- `isLoggedIn` - Session state flag
|
|
- No server-side caching configured (Redis presumed in backend qy_lty)
|
|
|
|
## Authentication & Identity
|
|
|
|
**Auth Provider:**
|
|
- Custom implementation via qy_lty backend
|
|
- Backend OAuth/token system: admin token key format `admin_token:{token}` (in Redis)
|
|
|
|
**Login Flow:**
|
|
1. POST `/api/v1/admin/login/` with email + password
|
|
2. Backend returns: `{ success, code, data: { token, is_superuser?, role? }, message }`
|
|
3. Frontend stores token in localStorage + cookies (7-day expiry)
|
|
4. All subsequent requests include `Authorization: Bearer {token}`
|
|
5. On 401 response: clear tokens, redirect to `/login`
|
|
|
|
**Token Storage:**
|
|
- Primary: `localStorage.auth_token` (checked on every request)
|
|
- Secondary: `js-cookie` cookie `auth_token` (7-day expiry) for middleware access
|
|
- Logout clears both storages
|
|
|
|
**Role-Based Access:**
|
|
- Roles stored in localStorage: `user_role`
|
|
- Permission matrix defined in `lib/permissions.ts`
|
|
- Supported roles: 超级管理员, 内容管理员, AI模型管理员, 卡牌管理员, 查看者, 管理员
|
|
- Module-level access control via `hasPermission()` and `hasPathPermission()` functions
|
|
|
|
**Protected Routes:**
|
|
- Middleware: `middleware.ts` checks for token on protected paths
|
|
- Protected paths: `/`, `/dashboard`, `/users`, `/roles`, `/ai-models`, `/outfits`, `/props`, `/songs`, `/settings`
|
|
- Public paths: `/login`, `/register`, `/forgot-password` (no token required)
|
|
|
|
## Monitoring & Observability
|
|
|
|
**Error Tracking:**
|
|
- Not detected - errors logged to console only
|
|
- Error messages mapped in `lib/api/error-handler.ts`
|
|
- Toast notifications via Sonner for user-facing errors
|
|
|
|
**Logs:**
|
|
- Console logging (development-focused)
|
|
- Request/response logging in Axios interceptors (logs token status, URLs, headers, status codes)
|
|
- Client-side logging only (no centralized log aggregation)
|
|
|
|
## CI/CD & Deployment
|
|
|
|
**Hosting:**
|
|
- Docker containerization: `Dockerfile` (multi-stage build)
|
|
- Runtime: Node.js 22.10.0 Alpine Linux
|
|
- Port: 3000
|
|
- Command: `yarn start` (runs Next.js production server)
|
|
|
|
**CI Pipeline:**
|
|
- Not detected in codebase (likely external to this repo)
|
|
|
|
**Build Output:**
|
|
- Format: Next.js standalone (self-contained, no `node_modules` in runtime image)
|
|
- Files included: `.next/standalone/`, `public/`
|
|
- Size optimization: devDependencies not included in runner stage
|
|
|
|
## Environment Configuration
|
|
|
|
**Required env vars:**
|
|
- `NEXT_PUBLIC_API_BASE_URL` - Backend API base URL (must be public, prefixed with `NEXT_PUBLIC_`)
|
|
- Example: `http://localhost:8000/api` (development), `https://api.production.com/api` (production)
|
|
|
|
**Optional env vars:**
|
|
- `NODE_ENV` - Set to `production` in Docker runner stage
|
|
- `.env.local` - Overrides all other env files (gitignored)
|
|
- `.env.development` - Dev-specific overrides
|
|
- `.env.production` - Production-specific overrides
|
|
|
|
**Secrets location:**
|
|
- Authentication tokens: browser localStorage + cookies
|
|
- No API keys or credentials hardcoded in source
|
|
- Environment variable `NEXT_PUBLIC_API_BASE_URL` is the sole configuration bridge to backend
|
|
|
|
## Webhooks & Callbacks
|
|
|
|
**Incoming:**
|
|
- None detected
|
|
- Backend (qy_lty) may have webhooks, but frontend is purely client-side consumer
|
|
|
|
**Outgoing:**
|
|
- None detected
|
|
- All communication is request-response (REST API calls to qy_lty)
|
|
|
|
## Cross-Repo Dependencies
|
|
|
|
**qy_lty Backend (Sibling Repo):**
|
|
- Location: `C:\Users\admin\Desktop\Lila-Server\qy_lty\` (Django)
|
|
- Contract: `/api/v1/admin/` endpoint suite
|
|
- Shared concerns: Token format (`admin_token:{token}`), role names, permission structure
|
|
- Change coordination required: Both `docs/修改记录.md` files must be updated when API contracts change
|
|
|
|
**Notes:**
|
|
- Frontend is tightly coupled to backend API schema (no API versioning detected)
|
|
- Backend controls: authentication, authorization, data persistence, file storage
|
|
- Frontend is purely a UI/UX layer consuming backend HTTP APIs
|
|
|
|
---
|
|
|
|
*Integration audit: 2026-05-07*
|