• Extends the 跳舞直播间 (dance room) system to one independent live room
    per character, with an operator playback-management/blacklist layer
    (T39), a "我的作品" page for paid users (T38), a standalone 人衣图生成
    admin tool, and a new admin-dance-library.html page for curating the
    per-character dance clip pool with AI QC.
    
    On top of that, dance clips now have an explicit published (上架/下架)
    status: passing AI QC (or a manual admin override to "correct") auto-
    publishes a clip, failing it auto-unpublishes it, and only published
    clips are eligible for a room's random-fill pool — unreviewed/rejected
    clips stay in the library but no longer autoplay for viewers. Existing
    already-QC'd "correct" clips are backfilled to published on first boot
    so the room doesn't go quiet.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01MvkJsRcQ2qEuaFea31rBY8
    yibo authored
     
    Browse File »

  • New blacklist store (dressup-store.js) — explicitly distinct from T32's
    automated face-blacklist model and T26's garment moderation, per M.11's
    own warning. isBlacklisted(targetType, targetId) is checked at every
    submission entry point (/api/dance/pick, both paid upload endpoints —
    rejected before any spend, matching M.11's "不进流水线、不扣积分") and
    filters GET /api/dance/wardrobe and pickNextDanceClip's random-fill
    pool (extending T36's expired-character filter to also drop
    blacklisted garments/characters/generated_videos) — records are never
    deleted, just excluded from future selection, same "记录保留" spirit as
    T36.
    
    Admin CRUD: GET/POST /api/admin/blacklist, DELETE
    /api/admin/blacklist/:id — creation attributed via adminActorUserId
    (T30), same null-over-the-legacy-ADMIN_PASSWORD-channel behavior as
    credit/adjust.
    
    Playback management (需求文档 6.5 节): POST
    /api/admin/dance/schedule/pin inserts an existing clip into the very
    next slot (factored T34's priorityInbox-insert logic into a shared
    insertClipNext() so both call sites move in lockstep); POST
    .../schedule/skip advances past whatever's currently playing; POST
    /api/admin/dance/pause freezes only the random-fill loop (paid_boost
    content still drains immediately even while paused — 需求文档 6.5 节
    frames "暂停自动填充" as filler-specific, not a full stop).
    
    dance-admin-ops.test.js covers blacklist CRUD/attribution, entry-point
    rejection for both a blacklisted garment (pick) and a blacklisted
    user (upload), pin/skip changing the schedule, and pause/resume
    against a deliberately drained-to-stable-size schedule (comparing exact
    lengths — comparing clip ids/count directly was flaky since a small
    mock pool can legitimately re-pick the same clip after a skip).
    
    This completes dev-plan-5.md (T31-T39) — 需求文档 9 节's fifth and final
    planned phase.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_011DUiYs6UjxDMkfvnjtsKFo
    yibo authored
     
    Browse File »