seaislee1209 8f80247e0d chore(core): idempotent demo seed (airshelf team) + data screenshot script
- seed_demo.py: ORM-only demo data for airshelf team — 2 products (w/ images+selling points),
  11 assets referencing real TOS objects (thumbnails resolve to real images), one COMPLETED
  project with full pipeline graph (script/base_assets/storyboard/video_segments/timeline) so
  pipeline stage2-5 has real data to render. Idempotent (skips if demo product exists). No schema changes.
- shot-data.mjs: capture dashboard/products/library with seeded data via 127.0.0.1:5180
- verified: products page shows real cover images via TOS preview_url

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 14:48:13 +08:00

22 lines
1.2 KiB
JavaScript

// 抓图:灌库 + TOS 后,现有页面的真数据+真图效果
import { chromium } from "playwright";
import { mkdirSync } from "node:fs";
const BASE = "http://127.0.0.1:5180";
const API = "http://127.0.0.1:8010";
const OUT = process.argv[2] || "shots-data";
mkdirSync(OUT, { recursive: true });
const token = (await (await fetch(`${API}/api/auth/login/`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username: "airshelf", password: "Restraint2026" }) })).json()).token;
const pages = [["dashboard", "/dashboard"], ["products", "/products"], ["library", "/library"]];
const browser = await chromium.launch();
const ctx = await browser.newContext({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 1 });
await ctx.addInitScript((t) => localStorage.setItem("airshelf_token", t), token);
const page = await ctx.newPage();
for (const [name, route] of pages) {
await page.goto(BASE + route, { waitUntil: "networkidle", timeout: 30000 });
await page.waitForTimeout(1800);
await page.screenshot({ path: `${OUT}/${name}.png`, fullPage: true });
console.log("shot", name);
}
await browser.close();
console.log("DONE ->", OUT);