video-shuoshan/CLAUDE.md
seaislee1209 13440f2709
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 5m58s
feat: v0.19.2 prompt 里 @素材名 按火山规范转为「图片N/视频N/音频N」
火山 Seedance 模型只能理解"素材类型+序号"的指代(官方文档 FAQ Q3);
对文件名 / asset id / URL 类字符串一律读不懂,只能按 content 数组里
图片出现顺序瞎猜谁是谁,导致用户看到的"人物颠倒"概率性现象(典型
任务 cgt-20260422163517-4k8x6)。

改动
- backend/apps/generation/views.py:
  - 新增 _format_prompt_for_ark(prompt, label_placeholders) helper
    用 str.replace 避 regex 元字符崩溃, 按 label 长度降序防子串吞噬
  - video_generate_view references 循环同步维护 image_n/video_n/audio_n
    三个独立计数器 + label_to_placeholder 映射
  - 关键不变量: 任意时刻 counter == content_items 里该类型 *_url 已 push 数
    group 老路径 counter 照推但不登记 label + WARNING, 避免编号错位
  - 调 create_task 前构造 api_prompt 传给火山, DB.prompt 保留用户原文
    (带 @xxx.jpg) 以便 reEdit 重建带缩略图标签

测试覆盖 14 项 (airlabs-test MySQL 全绿)
- 单元 9 项: 基础替换 / 多类型独立计数 / 重复 @ / 子串冲突 / 正则元字符 /
  空 mapping / label 未 @ / 中文标点 / 空 label 跳过
- 集成 5 项: local 正常替换 / DB 原文保留 / group 老路径不换 + WARN /
  混用 local+group counter 对齐 (关键回归) / 图片音频独立计数

兼容性
- reEdit: DB 保留原文, PromptInput.rebuildMentionSpans 按 @label 正则
  仍能重建 span, 缩略图正常
- regenerate: 走同一 POST /api/v1/video/generate, 二次过转换
- Celery: 只 query 不重发, 不受影响

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 20:52:32 +08:00

26 KiB
Raw Permalink Blame History

Jimeng Clone — AI Video Generation Platform

This file is the single source of truth for AI-assisted development on this project. AI agents (including Claude Code) should read this file first before making any changes.

Quick Start

Development Environment

  • Backend: Python 3.12 + Django 4.2 + DRF + SimpleJWT
  • Frontend: React 18 + Vite 6 + TypeScript 5 + Zustand
  • Database: SQLite (dev) / Aliyun RDS MySQL (prod)
  • UI Library: Arco Design (@arco-design/web-react)
  • Charts: ECharts 6 + echarts-for-react

Setup Commands

# Backend
cd backend
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver 8000

# Frontend
cd web
npm install
npm run dev          # Dev server at localhost:5173
npm run build        # Production build: tsc -b && vite build

Test Commands

# Frontend unit tests
cd web && npx vitest run

# Backend checks
cd backend && python manage.py check

Admin Credentials (Dev)

  • Username: admin / Password: admin123

Project Architecture

Directory Structure

jimeng-clone/
├── backend/                 # Django REST Framework backend
│   ├── config/              # Django settings, urls, wsgi
│   │   ├── settings.py      # Main config (DB, CORS, JWT, apps)
│   │   └── urls.py          # Root URL routing
│   ├── apps/
│   │   ├── accounts/        # User auth: models, views, serializers, urls
│   │   └── generation/      # Video generation: models, views, serializers, urls
│   ├── utils/               # Shared utilities (geo_client, anomaly_detector, alert_service, tos_client)
│   ├── data/                # Offline data files (ip2region.xdb)
│   ├── requirements.txt     # Python dependencies
│   └── Dockerfile           # Python 3.12 + gunicorn
├── web/                     # React 18 + Vite frontend
│   ├── src/
│   │   ├── App.tsx          # Root router (all routes defined here)
│   │   ├── main.tsx         # Entry point
│   │   ├── pages/           # Page-level components (one per route)
│   │   ├── components/      # Reusable UI components
│   │   ├── store/           # Zustand state stores
│   │   ├── lib/             # Utilities (API client, log center)
│   │   └── types/           # TypeScript type definitions
│   ├── nginx.conf           # Production nginx config
│   └── Dockerfile           # Node 18 + nginx
├── k8s/                     # Kubernetes deployment configs
├── docs/                    # PRD, design review documents
├── .gitea/workflows/        # CI/CD pipeline
└── .autonomous/             # Autonomous skill task tracking

Key Files (Most Commonly Modified)

  • web/src/App.tsx — Route definitions. Modify when adding new pages.
  • web/src/store/auth.ts — Auth state (login/logout/JWT refresh)
  • web/src/store/generation.ts — Video generation state & API calls
  • web/src/store/inputBar.ts — Input bar state (mode, files, prompt)
  • web/src/lib/api.ts — Axios client with JWT interceptor. API base URL configured here.
  • web/src/types/index.ts — All TypeScript interfaces
  • backend/config/settings.py — Django settings (DB, CORS, JWT, installed apps)
  • backend/config/urls.py — Root URL routing
  • backend/apps/accounts/models.py — User model (extends AbstractUser)
  • backend/apps/generation/models.py — GenerationRecord + QuotaConfig models
  • backend/apps/generation/views.py — All API endpoints (video, admin, profile)
  • backend/apps/generation/urls.py — API URL patterns

Development Conventions

Code Style

  • Frontend: TypeScript strict mode, functional components, named exports
  • Backend: PEP 8, function-based views with @api_view decorator
  • CSS: Inline styles + Arco Design component props (no separate CSS modules)

Naming Conventions

  • React Components: PascalCase files (e.g., LoginPage.tsx, InputBar.tsx)
  • Stores: camelCase files (e.g., auth.ts, generation.ts)
  • Django Apps: lowercase (e.g., accounts, generation)
  • API URLs: /api/v1/ prefix, no trailing slashes in URL patterns
  • Database: snake_case (Django default)

State Management Pattern

  • Zustand stores in web/src/store/, one store per domain
  • Each store exports a use[Name]Store hook
  • API calls are defined inside stores (not in components)
  • Pattern: const doSomething = useAuthStore((s) => s.doSomething)

Component Pattern

  • Pages in web/src/pages/ — full-page components mounted by router
  • Reusable components in web/src/components/
  • Protected routes use <ProtectedRoute> wrapper, admin routes add requireAdmin prop

Backend Pattern

  • Function-based views with @api_view(['GET', 'POST']) decorator
  • Auth via @permission_classes([IsAuthenticated])
  • Admin endpoints check request.user.is_staff
  • Singleton pattern for QuotaConfig (pk always = 1)

API Endpoints

Auth (/api/v1/auth/)

Method Endpoint Description
POST /api/v1/auth/register User registration (disabled)
POST /api/v1/auth/login JWT login (returns access + refresh tokens, creates ActiveSession)
POST /api/v1/auth/token/refresh Refresh JWT access token
GET /api/v1/auth/me Get current user info + quota + team + must_change_password
POST /api/v1/auth/change-password Change own password (clears must_change_password)

Video Generation (/api/v1/)

Method Endpoint Description
POST /api/v1/media/upload Upload reference media files
POST /api/v1/video/generate Submit video generation task
GET /api/v1/video/tasks List user's generation tasks
GET /api/v1/video/tasks/<uuid> Get task status & result

Admin (/api/v1/admin/)

Method Endpoint Description
GET /api/v1/admin/stats Dashboard statistics & charts data
GET /api/v1/admin/users List all users (search, filter, paginate)
POST /api/v1/admin/users/create Create new user
GET/PUT /api/v1/admin/users/<id> Get/update user details
PUT /api/v1/admin/users/<id>/quota Update user quota limits
PUT /api/v1/admin/users/<id>/status Toggle user active status
GET /api/v1/admin/records List all generation records
GET/PUT /api/v1/admin/settings Get/update global settings (QuotaConfig)
GET /api/v1/admin/teams List all teams
POST /api/v1/admin/teams/create Create new team
GET/PUT /api/v1/admin/teams/<id> Get/update team details
POST /api/v1/admin/teams/<id>/topup Add seconds to team pool
PUT /api/v1/admin/teams/<id>/set-pool Directly set team total seconds pool
POST /api/v1/admin/teams/<id>/admin Create team admin user
GET /api/v1/admin/anomalies Login anomaly records (filter by team/rule/level/date)
POST /api/v1/admin/test-feishu Send test Feishu alert message
POST /api/v1/admin/teams/<id>/auto-learn Auto-learn expected regions from login history
POST /api/v1/admin/teams/<id>/apply-learned-regions Apply auto-learned regions to team
GET /api/v1/admin/logs Audit logs (filter by action/operator/date)
GET /api/v1/admin/assets/overview Content assets: global stats + per-team summary
GET /api/v1/admin/assets/team/<id>/members Content assets: team members with video stats
GET /api/v1/admin/assets/user/<id>/videos Content assets: user's completed videos (paginated)

Team Admin Assets (/api/v1/team/assets/)

Method Endpoint Description
GET /api/v1/team/assets/overview Team stats + per-member video summary
GET /api/v1/team/assets/member/<id>/videos Member's completed videos (paginated)

Profile (/api/v1/profile/)

Method Endpoint Description
GET /api/v1/profile/overview User consumption summary
GET /api/v1/profile/records User's own generation records

Database Models

User (extends AbstractUser)

  • email (unique), daily_seconds_limit (default: 600), monthly_seconds_limit (default: 6000)
  • must_change_password (default: True) — forces password change on first login
  • team (FK to Team), is_team_admin, disabled_by (''|'admin'|'system')
  • created_at, updated_at

Team

  • name, total_seconds_pool, total_seconds_used, monthly_seconds_limit, daily_member_limit_default
  • expected_regions (CharField 500, comma-separated cities for anomaly detection R1)
  • disabled_by (''|'admin'|'system'), is_active

GenerationRecord

  • user (FK), task_id (UUID), ark_task_id, prompt, mode (universal|keyframe)
  • model (seedance_2.0|seedance_2.0_fast), aspect_ratio, duration, seconds_consumed
  • status (queued|processing|completed|failed), result_url, error_message, reference_urls (JSON)
  • Index: (user, created_at)

AdminAuditLog

  • operator (FK User, SET_NULL), operator_name (denormalized), action (12 choices)
  • target_type, target_id, target_name, before (JSON), after (JSON)
  • ip_address, created_at (indexed)

ActiveSession

  • user (FK), session_id (UUID, unique), device_type (desktop|mobile|unknown)
  • user_agent, created_at
  • Used for concurrent session limiting via JWT session_id claim

LoginRecord

  • user (FK), team (FK, redundant for efficient R4/R5 queries), ip_address, user_agent
  • geo_country, geo_province, geo_city, geo_source ('online'|'offline'|'skip'|'failed')
  • created_at (indexed)

TeamAnomalyConfig (OneToOne → Team)

  • Per-team anomaly detection thresholds (null = use global default)
  • r1_enabled, r2_enabled/r2_window_seconds, r3_enabled/r3_window_seconds/r3_max_count
  • r4_enabled/r4_window_seconds/r4_city_count, r5_enabled/r5_days/r5_country_count

LoginAnomaly

  • team (FK), user (FK), login_record (FK)
  • level (warning|critical), rule (region_mismatch|impossible_travel|login_frequency|multi_city|overseas_ip_diversity)
  • detail (JSON), alerted, auto_disabled, disabled_target (user|team|'')
  • created_at (indexed)

QuotaConfig (Singleton, pk=1)

  • default_daily_seconds_limit, default_monthly_seconds_limit
  • announcement, announcement_enabled
  • max_desktop_sessions (default: 1), max_mobile_sessions (default: 0)
  • Anomaly detection global defaults: anomaly_detection_enabled, R1-R5 enabled/thresholds
  • feishu_alert_mobiles, sms_alert_mobiles, alert_cooldown_seconds
  • updated_at

Frontend Routes

Path Component Auth Description
/login LoginPage No Login page
/ VideoGenerationPage Yes Main video generation UI
/profile ProfilePage Yes User consumption overview
/admin/dashboard DashboardPage Admin Stats & charts
/admin/users UsersPage Admin User management
/admin/records RecordsPage Admin Generation records
/admin/settings SettingsPage Admin Global quota, announcement & anomaly detection config
/admin/security AnomalyLogPage Admin Login anomaly records (security log)
/admin/logs AuditLogsPage Admin Admin operation audit logs
/admin/assets AdminAssetsPage Admin Content assets (team→member→video hierarchy)
/team/assets TeamAssetsPage TeamAdmin Team content assets (member→video hierarchy)

AI Skills Reference

本项目用 skill(可复用方法论)+ memory(个人纪律)+ hook(系统强制)三层指引 AI 开发。按编辑场景对应加载:

编辑场景 应用的 skill / memory / hook
backend/utils/seedance_client.py、任何 Seedance API 对接 Skill seedance-api-integration — 参数构造、token 计费、异步轮询、错误码映射、asset:// 引用、白标、5 起真实踩坑
Django models 新增字段(backend/apps/*/models.py)或改 create() 调用 Memory feedback_mysql_default / feedback_mysql_explicit_fields — MySQL 严格模式下 create() 必须显式传所有 CharField 值(已 1 起 2026-03-19 线上 500 事故)
任何 git push 操作 Hook ~/.claude/hooks/pre-git-push.sh 会拦截;用户明确授权后用 ALLOW_PUSH=1 git push 重试
用户可见 label / 按钮 / 错误提示 Memory feedback_write_full_labels(单位/类型/含义写全)+ feedback_user_facing_docs_plain_language(禁程序员术语)+ feedback_seconds_unit(只用秒,不换分钟/小时)
任何 user-facing 字符串含模型名 / 错误提示 / 帮助文案 Memory feedback_no_seedance_branding — 白标合同禁出现 "Seedance",用 "AirDrama" / "AirDrama Fast"
内联编辑按钮(保存 / 取消) Memory feedback_inline_edit_stylewhiteSpace: 'nowrap' 必加,历史多次被挤成两行
对接火山 / 豆包 / Seedance 等第三方 API 添加新字段或错误码 Memory feedback_follow_official_api — 严格按官方文档,不瞎编字段 / 错误码(历史:曾脑补 .PolicyViolation 子类型)
生成页 / @ mention / 素材库相关测试 tudou(团管)账号登录;admin 账号默认没 team进不了生成页
改完代码、宣称"完成"之前 Memory feedback_verify_before_deliver + feedback_verify_thoroughly — 必须自己跑完整 user 路径验证关键改动,不让用户替我们背锅
商业级代码要求(并发、失败、资源复用) Memory feedback_commercial_grade — 不准说"可以接受 / 后续优化",要么做到位要么明确标风险
改方案 / 改 UI 前发现截图或讨论 Memory feedback_no_rush_changes + feedback_simple_first — 先提方案(最简单的先给)等用户说"改吧"再动手

纪律分级:

  • Skill — 跨项目可复用的大块方法论(~/.claude/skills/
  • Memory — 协作纪律 / 个人偏好(自动加载到 session context~/.claude/projects/c--Airlabs-Project/memory/
  • Hook — 系统级硬拦截(~/.claude/settings.json + ~/.claude/hooks/
  • 项目特定架构约定直接写在本 CLAUDE.md 里Project Architecture / API Endpoints / Database Models 等章节)

增删映射项时: 新增跨项目规则写 memory、本项目特定规则写 CLAUDE.md 对应章节、跨项目技术方法论才做 skill参考 feedback_no_skill_bloat)。


Incremental Development Guide

How to Add Features to This Project

This project was generated and maintained using agent-auto(多 Agent 协作自动开发系统)。 项目路径:/Users/maidong/Desktop/zyc/研究openclaw/agent-auto/

增量开发有两种方式:

方式 1Direct AI Development小改动

Bug 修复、UI 微调、单个接口等小改动,直接在 Claude Code 中描述需求即可。 Claude Code 会读取本文件CLAUDE.md理解项目上下文。

示例:

  • "Add a logout button to the navbar"
  • "Fix the date format in the records table"
  • "修改轮询间隔为 3 分钟"
  • "Change the default daily quota from 600 to 1200 seconds"

IMPORTANT — 每次改动后必须更新文档:

  1. 更新 CLAUDE.md(本文件):

    • 新 API 端点 → 加到 API Endpoints 表
    • 新页面/路由 → 加到 Frontend Routes 表
    • 新 model/字段 → 加到 Database Models 区
    • 配置变更 → 更新对应区
    • 始终在底部 Change History 表加一行
  2. 更新 Claude Code memory(如有):

    • 更新 ~/.claude/projects/ 下的 memory 文件
    • 确保跨会话的 AI 也能了解变更
  3. 非架构性改动也要记录

    • Bug fix / UI 微调 / 依赖更新 / 配置值变更 → 都加到 Change History

未更新文档会导致后续 AI 会话使用过期上下文,引发冲突或重复工作。

方式 2agent-auto大功能 / 全栈新模块)

涉及 3+ 文件、新模块、跨模块重构等复杂需求,使用 agent-auto 自动完成全流程:

需求 → PRD → HTML 原型 → 设计评审 → 全栈代码 → 测试 → Bug 修复循环 → 完成

运行命令:

cd /Users/maidong/Desktop/zyc/研究openclaw/agent-auto

# 增量需求(在已有项目上加功能)
npx tsx src/index.ts --resume /Users/maidong/Desktop/zyc/研究openclaw/视频生成平台/jimeng-clone "你的增量需求描述"

# 崩溃恢复 / 继续执行
npx tsx src/index.ts --resume /Users/maidong/Desktop/zyc/研究openclaw/视频生成平台/jimeng-clone

agent-auto 会自动:

  1. 读取 .agent-auto/state.json 恢复项目状态
  2. product-agent 修订 PRDdocs/prd.md
  3. design-agent 更新 HTML 原型(prototype/
  4. product-agent 设计评审(docs/design-review.mdAPPROVED/REJECTED 循环)
  5. dev-agent 增量开发(保留已有代码,只新增/修改)
  6. test-agent 测试 + Bug 分类(test-report.md
  7. Bug 修复循环CODE_BUG → dev-agent / DESIGN_BUG → design-agent / REQUIREMENT_BUG → product-agent
  8. 全部通过 → COMPLETE

状态持久化:进度保存在 .agent-auto/state.json,中断后可随时 --resume 继续。

Agent 记忆:每个 Agent 有独立记忆文件(.agent-auto/{agent-name}/memory.md),跨轮次保持上下文。

变更日志维护

每次需求开发完成、测试验收通过后,必须docs/changelog.md 中记录本次变更:

  • 按日期倒序添加新条目(最新的在最前面)
  • 包含:变更标题、状态/验收、变更内容、变更文件、触发原因
  • 文件末尾有模板可直接复制使用
  • Direct AI 和 agent-auto 两种方式均需记录

何时用哪种方式

场景 方式
Bug 修复 / 单行改动 Direct AI
UI 微调(按钮、颜色、文案) Direct AI
添加单个 API 端点 Direct AI
修改已有组件行为 Direct AI
新功能模块3+ 文件) agent-auto
新增整页 CRUD如管理页面 agent-auto
跨多文件重构 agent-auto
新增子系统(通知、支付、权限) agent-auto

How to Add a New Page

  1. Create page component in web/src/pages/NewPage.tsx
  2. Add route in web/src/App.tsx inside <Routes>:
    <Route path="/new-page" element={<ProtectedRoute><NewPage /></ProtectedRoute>} />
    
  3. If it needs state, create store in web/src/store/newPage.ts
  4. Add API calls in the store using api.get() / api.post() from web/src/lib/api.ts

How to Add a New API Endpoint

  1. Add view function in backend/apps/generation/views.py (or relevant app):
    @api_view(['GET'])
    @permission_classes([IsAuthenticated])
    def new_endpoint_view(request):
        return Response({'data': ...})
    
  2. Add URL pattern in backend/apps/generation/urls.py:
    path('new/endpoint', views.new_endpoint_view, name='new_endpoint'),
    
  3. Add TypeScript types in web/src/types/index.ts
  4. Add API call in the relevant Zustand store

How to Add a New Database Model

  1. Define model in backend/apps/generation/models.py (or relevant app)
  2. Run migrations:
    cd backend
    python manage.py makemigrations
    python manage.py migrate
    
  3. Register in admin: backend/apps/generation/admin.py
  4. Create serializer if needed: backend/apps/generation/serializers.py

Environment Variables

Variable Description Required
DATABASE_URL MySQL connection string (prod) Prod only
SECRET_KEY Django secret key Yes
TOS_ACCESS_KEY Volcano Engine TOS AccessKeyId Yes (upload)
TOS_SECRET_KEY Volcano Engine TOS SecretAccessKey Yes (upload)
TOS_BUCKET Volcano TOS bucket name (default: airdrama-media) Yes (upload)
TOS_ENDPOINT TOS endpoint URL (default: https://tos-cn-beijing.volces.com) Yes (upload)
TOS_REGION TOS region (default: cn-beijing) Yes (upload)
TOS_CDN_DOMAIN TOS CDN domain for permanent URLs (default: https://airdrama-media.tos-cn-beijing.volces.com) Yes (upload)
ARK_API_KEY Volcano Engine ARK API key for Seedance Yes (video gen)
ARK_BASE_URL ARK API base URL (default: https://ark.cn-beijing.volces.com/api/v3) No
ALIYUN_IP_GEO_APPCODE Aliyun marketplace IP geolocation API AppCode Yes (anomaly detection)
FEISHU_APP_SECRET Feishu bot app secret for alert notifications Yes (anomaly alerts)

Deployment

  • CI/CD: Gitea Actions (.gitea/workflows/deploy.yaml)
  • Registry: Huawei Cloud SWR
  • Orchestration: Kubernetes (k8s/ directory)
  • Backend URL: airflow-studio-api.airlabs.art
  • Frontend URL: airflow-studio.airlabs.art
  • Database: Aliyun RDS MySQL (rm-7xv1uaw910558p1788o.mysql.rds.aliyuncs.com:3306)

Testing

  • Unit Tests: 227 tests in web/ via Vitest — cd web && npx vitest run
  • E2E Tests: 49 tests via Playwright — cd web && npx playwright test
  • Backend: Django system checks — cd backend && python manage.py check
  • Status: 211 passing, 16 pre-existing path-resolution failures in phase2/phase3 tests
  • Test DB Isolation: E2E tests use TESTING=true env var → backend writes to test_db.sqlite3 (not db.sqlite3). Playwright auto-starts a test backend on port 8000 with this env var. Dev data is never polluted by tests.

Design Guidelines

  • Color Palette: #0a0a0f (bg), #111118, #16161e, #2a2a38, #00b8e6 (accent)
  • Typography: Noto Sans SC (Chinese) + Space Grotesk (UI) + JetBrains Mono (code)
  • Style: Linear/Vercel dark theme aesthetic
  • Responsive: grid-cols-4 max-lg:grid-cols-2

Change History

完整变更日志见 docs/changelog.md,以下为摘要。

Date Change Scope
2025-01 Phase 1: Core video generation UI Frontend
2025-02 Phase 2: Backend + Auth + Admin panel Full stack
2025-03 Phase 3: Seconds-based quota, profile page, ECharts dashboard Full stack
2026-03 Added CLAUDE.md for AI-assisted incremental development Documentation
2026-03-13 Phase 4: TOS upload + Seedance API integration + DB persistence Full stack
2026-03-13 Test DB isolation: TESTING=true → test_db.sqlite3, Playwright auto-starts test backend Backend + Config
2026-03-13 Removed mock data fallback from DashboardPage — charts show real data only Frontend
2026-03-13 LogCenterMiddleware: Django 中间件兜底异常上报(捕获 DRF 之外的导入/中间件/URL 解析错误) Backend
2026-03-13 custom_exception_handler: 未处理异常返回 JSON 500 而非 HTML Backend
2026-03-13 前端轮询间隔从 5 秒改为 3 分钟 Frontend
2026-03-13 CLAUDE.md 增量开发指南更新为 agent-auto替换 Autonomous Skill Documentation
2026-03-15 v0.8.0: 音频引用支持 + 视频 TOS 持久化 + 移除硬编码密钥 + 渐进式轮询 Full stack
2026-03-15 TOS 桶切换到 airdrama-media (cn-beijing)K8s Secret 注入 TOS 密钥 Infra
2026-03-15 v0.8.1: Seedance API 友好错误提示 (SeedanceAPIError) + 前端 Mock 数据清理 Full stack
2026-03-16 v0.8.2: 管理后台 UI 修复 — DatePicker/Select 暗色主题、公告跑马灯、Toast 全局化、失败原因 tooltip Full stack
2026-03-16 v0.8.3: 团队详情抽屉→弹窗重构(VideoDetailModal 规范) + 修改秒数池功能 + member_count 修复 Full stack
2026-03-16 v0.8.4: 管理员操作审计日志 — AdminAuditLog 模型 + 12 处埋点 + 日志查询页面 Full stack
2026-03-18 v0.9.0: 首次登录强制改密 — must_change_password 字段 + ForceChangePasswordModal Full stack
2026-03-18 v0.9.0: 并发会话限制 — ActiveSession + SessionJWT + 可配置桌面/移动端会话数 Full stack
2026-03-18 v0.9.0: 登录记录 — LoginRecord 模型IP + User-Agent为异常检测打基础 Backend
2026-03-18 v0.9.0: Token 生命周期缩短 — access 30min, refresh 1天 Backend
2026-03-18 v0.9.0: 内容资产页 — 超管/团队管三级折叠式资产浏览(团队→成员→视频) Full stack
2026-03-18 v0.9.1: 登录风控第二期 — IP归属地解析 + 5条异常检测规则(R1-R5) + 飞书告警 + 自动封禁 Full stack
2026-03-18 v0.9.1: 安全日志页面 — LoginAnomaly 记录列表,按团队/规则/级别/时间筛选 Frontend
2026-03-18 v0.9.1: 系统设置页 — 异常检测总开关、R1-R5默认阈值、飞书接收人+测试、告警冷却 Frontend
2026-03-18 v0.9.1: 团队管理 — 预期登录城市(必填) + 自动学习 + disabled_by 来源标签 Full stack
2026-03-18 v0.9.1: 前端拦截器 — user_disabled/team_disabled 错误码处理,弹窗提示后跳登录 Frontend
2026-03-19 fix: LoginRecord 创建时显式传 geo 空字段,修复 MySQL 严格模式 IntegrityError Backend

Phase 4 Details (2026-03-13)

Backend new files:

  • backend/utils/tos_client.py — Volcano Engine TOS upload via official tos SDK
  • backend/utils/seedance_client.py — Seedance/ARK API client (create_task, query_task)

Backend changes:

  • backend/config/settings.py — Added TOS and ARK config
  • backend/apps/generation/models.py — Added ark_task_id, result_url, error_message, reference_urls (JSONField)
  • backend/apps/generation/views.py — New endpoints: upload_media_view, video_tasks_list_view, video_task_detail_view; Rewritten video_generate_view with Seedance integration
  • backend/apps/generation/urls.py — Added 3 routes: media/upload, video/tasks, video/tasks/<uuid>
  • backend/apps/generation/serializers.py — Added references field to VideoGenerateSerializer
  • backend/requirements.txt — Added tos>=2.7, requests>=2.31
  • Migration: 0003_generationrecord_ark_task_id_and_more.py

Frontend changes:

  • web/src/types/index.ts — Added BackendTask interface, tosUrl to UploadedFile, taskId/errorMessage to GenerationTask
  • web/src/lib/api.ts — Added mediaApi.upload(), videoApi.getTasks(), videoApi.getTaskStatus(); Changed videoApi.generate() to JSON
  • web/src/store/generation.ts — Complete rewrite: async TOS upload + API calls + polling + loadTasks() for refresh persistence
  • web/src/components/VideoGenerationPage.tsx — Added loadTasks() on mount
  • web/src/components/GenerationCard.tsx — Video player for results, error state display

Flow: Upload files → TOS → Generate API (Seedance) → DB record → Poll status → Display result