Files
ai-drama-platform/scripts/smoke-production-catalog.mjs

81 lines
3.8 KiB
JavaScript

import assert from "node:assert/strict";
import { dbRun, withTransaction } from "../server/db.mjs";
const api = process.env.AI_DRAMA_API_BASE || "http://127.0.0.1:8787";
const scope = {
"x-organization-id": "org-studio-lab",
"x-workspace-id": "ws-local-aidrama",
"x-project-id": "thunder-mouth"
};
async function request(path, options = {}) {
const response = await fetch(`${api}${path}`, {
...options,
headers: { "content-type": "application/json", ...(options.headers || {}) }
});
const payload = await response.json().catch(() => ({}));
return { response, payload };
}
const login = await request("/api/auth/login", {
method: "POST",
body: JSON.stringify({ email: "producer@local.test", password: "Demo@123456" })
});
assert.equal(login.response.ok, true, "catalog smoke login failed");
const headers = { authorization: `Bearer ${login.payload.session.token}`, ...scope };
let seasonId = "";
let episodeId = "";
try {
const catalog = await request("/api/production/catalog", { headers });
assert.equal(catalog.response.ok, true, "production catalog must be readable");
assert.ok(catalog.payload.catalog.seasons.length >= 1, "catalog must include at least one season");
assert.ok(catalog.payload.catalog.seasons[0].episodes.length >= 1, "catalog must include at least one episode");
const createdSeason = await request("/api/production/seasons", {
method: "POST",
headers,
body: JSON.stringify({ title: `Smoke Season ${Date.now()}` })
});
assert.equal(createdSeason.response.status, 201, "season creation must return 201");
seasonId = createdSeason.payload.season.id;
const createdEpisode = await request("/api/production/episodes", {
method: "POST",
headers,
body: JSON.stringify({ seasonId, title: "Smoke Episode" })
});
assert.equal(createdEpisode.response.status, 201, "episode creation must return 201");
episodeId = createdEpisode.payload.episode.id;
assert.equal(createdEpisode.payload.episode.shotCount, 1, "new episode must initialize one shot draft");
const graph = await request(`/api/production/graph?episodeId=${encodeURIComponent(episodeId)}`, { headers });
assert.equal(graph.response.ok, true, "episode graph must be readable");
assert.equal(graph.payload.graph.episode.id, episodeId, "graph must switch to requested episode");
assert.equal(graph.payload.graph.shots.length, 1, "new episode graph must contain starter shot");
assert.equal(graph.payload.graph.catalog.activeEpisodeId, episodeId, "catalog must reflect active episode");
const updated = await request(`/api/production/episodes/${encodeURIComponent(episodeId)}`, {
method: "PATCH",
headers,
body: JSON.stringify({ status: "production", hook: "Smoke hook" })
});
assert.equal(updated.response.ok, true, "episode update must succeed");
assert.equal(updated.payload.episode.status, "production", "episode status must persist");
console.log("production catalog smoke passed");
} finally {
if (seasonId) {
withTransaction(() => {
dbRun("DELETE FROM review_comments WHERE review_id IN (SELECT id FROM reviews WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?))", [episodeId]);
dbRun("DELETE FROM reviews WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?)", [episodeId]);
dbRun("DELETE FROM voice_lines WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?)", [episodeId]);
dbRun("DELETE FROM shot_versions WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?)", [episodeId]);
dbRun("DELETE FROM shots WHERE episode_id = ?", [episodeId]);
dbRun("DELETE FROM script_documents WHERE episode_id = ?", [episodeId]);
dbRun("DELETE FROM episodes WHERE id = ?", [episodeId]);
dbRun("DELETE FROM seasons WHERE id = ?", [seasonId]);
dbRun("DELETE FROM audit_logs WHERE target_id IN (?, ?)", [seasonId, episodeId]);
});
}
}