• Both are pluggable seams (dev-plan-4.md §1.2 items 1-2), same shape as
    T20's sendVerificationEmail: a fixed env var gates a real vendor call
    that isn't implemented yet (none has been picked), and the no-vendor
    path is what actually runs today.
    
    describeGarmentImage() — mode 2 has no admin around to hand-write
    garments.appearanceDescriptor the way admin_seed garments do, so it
    needs *something* non-empty to fill that field; today that's a fixed
    placeholder string, swapped for a real vision-model call once a
    vendor's picked.
    
    moderateGarmentImage() — the requirements doc flags image-content
    moderation as vendor-TBD but never actually lists it as its own task;
    this fills that gap. Every call writes a moderation_log row (new
    dressup-store.js export, M.9 schema) regardless of which branch runs,
    so the audit trail exists before a real vendor does. Default-permissive
    when unconfigured — T2's upload endpoint already enforces the real
    trust-boundary checks (magic-byte type check, 8MB cap, EXIF-stripped
    re-encode); this only covers the *content* check, which nothing here
    can perform without a vendor.
    
    Neither is unit-tested standalone (server.js doesn't export internal
    functions, matching sendVerificationEmail's existing precedent) — T27
    integration-tests both through the actual upload endpoint.
    
    Also adds pricing.js to the tmpdir file-copy list in every test that
    spawns server.js in isolation — server.js now requires it.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_011DUiYs6UjxDMkfvnjtsKFo
    yibo authored
     
    Browse File »
  • POST /api/auth/register, POST /api/auth/login, POST /api/auth/logout,
    and a debug GET /api/auth/me (T19's own acceptance criteria calls for
    it explicitly). Passwords hashed with node:crypto's scryptSync (salt
    stored alongside the hash, verified with timingSafeEqual) — still zero
    new dependencies.
    
    Sessions live in a separate user_session cookie from admin_session
    (T6) — the two are unrelated systems, confirmed by a test that a user
    session can't unlock /api/admin/*. Login and "email not registered"
    return the identical 401 body so the endpoint can't be used to
    enumerate registered emails.
    
    Every test file that spawns server.js in an isolated tmpdir now also
    copies db.js alongside it (dance-channel/dressup-generate/dressup-crud/
    admin-pages-flow/uploads-route .test.js) — server.js requires db.js
    unconditionally now, so those child processes were crashing silently
    without it.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_011Deddn3sM3oQnmvqWSMb4y
    yibo authored
     
    Browse File »
  • generateDanceVideo() takes a queued generationJobs record through
    prompt build -> forward character/garment/dance-ref uploads to H3
    Console's /v1/assets -> POST /v1/videos -> poll -> push a traced clip
    into library.json (characterId/garmentId/refDanceVideoId). Mirrors
    generateForPrompt's submit/poll/persist shape but keyed off the new
    generationJobs store so a restart resumes any in-flight job by its
    h3JobId, same as resumeGenerations() does for the live queue.
    
    POST /api/admin/generate accepts characterId/garmentId (+ optional
    refDanceVideoId, else a random active dance-ref is picked) and skips
    straight to the cached clip if that character x garment combo was
    already generated (M.7 dedupe). GET /api/admin/generate/:id polls job
    status.
    
    Tests spin up a mock H3 Console over HTTP so the full submit/poll/land
    path runs offline. Also fixes two existing test fixtures
    (dressup-crud, admin-pages-flow) that spawn server.js without copying
    prompt-template.js — worked until T8 added the first require() of it
    into server.js, at which point the spawned server silently failed to
    boot.
    
    Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
    yibo authored
     
    Browse File »
  • Table + inline edit + add-form pages matching admin.html's existing
    conventions, wired to the T3-T5 CRUD API and T2's upload endpoints.
    Cross-linked with admin.html and each other in the topbar.
    
    No browser tooling available in this environment to render/click
    through these, so admin-pages-flow.test.js exercises the exact API
    call sequence each page's JS performs (login -> upload a real file ->
    create with the returned URL -> list -> confirm the shape the table
    renders), which is where a field-name mismatch would surface.
    yibo authored
     
    Browse File »