# 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*
