feat: bootstrap commercial AI drama platform

This commit is contained in:
xz
2026-08-24 10:24:34 +08:00
commit ffb27d845b
100 changed files with 35314 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
import assert from "node:assert/strict";
import { dbRun } 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 };
}
function headers(token) {
return { authorization: `Bearer ${token}`, ...scope };
}
async function login(email) {
const result = await request("/api/auth/login", { method: "POST", body: JSON.stringify({ email, password: "Demo@123456" }) });
assert.equal(result.response.ok, true, `${email} login failed`);
return result.payload.session.token;
}
const taskTitle = `smoke-task-${Date.now()}`;
let ownerToken = "";
let reviewerToken = "";
let taskId = "";
try {
const anonymous = await request("/api/tasks");
assert.equal(anonymous.response.status, 401, "anonymous task access must be rejected");
ownerToken = await login("producer@local.test");
reviewerToken = await login("review@local.test");
const created = await request("/api/tasks", {
method: "POST",
headers: headers(ownerToken),
body: JSON.stringify({
title: taskTitle,
description: "验证项目任务的负责人、状态、截止时间和审计链路",
kind: "review",
priority: "high",
assigneeUserId: "u-review",
targetTab: "qa",
dueAt: "2026-08-30T23:59:59.000Z"
})
});
assert.equal(created.response.status, 201, `task creation failed: ${JSON.stringify(created.payload)}`);
assert.equal(created.payload.task.title, taskTitle, "created task title mismatch");
assert.equal(created.payload.task.assignee.id, "u-review", "task assignee not persisted");
assert.equal(created.payload.task.priority, "high", "task priority not persisted");
taskId = created.payload.task.id;
const ownerList = await request("/api/tasks?status=all", { headers: headers(ownerToken) });
assert.equal(ownerList.response.ok, true, "owner task list failed");
assert.ok(ownerList.payload.tasks.some((task) => task.id === taskId), "owner should see created task");
assert.ok(ownerList.payload.summary.total >= 1, "task summary must include created task");
const reviewerList = await request("/api/tasks?assignedTo=me", { headers: headers(reviewerToken) });
assert.equal(reviewerList.response.ok, true, "reviewer assigned task list failed");
assert.ok(reviewerList.payload.tasks.some((task) => task.id === taskId), "assignee should see own task");
const reviewerNotifications = await request("/api/notifications?limit=200", { headers: headers(reviewerToken) });
assert.equal(reviewerNotifications.response.ok, true, "reviewer notification list failed");
assert.ok(reviewerNotifications.payload.notifications.some((notification) => notification.eventKey === "task.assigned" && notification.targetId === taskId), "task assignment must create an in-app notification");
const reviewerUpdate = await request(`/api/tasks/${encodeURIComponent(taskId)}`, {
method: "PATCH",
headers: headers(reviewerToken),
body: JSON.stringify({ status: "in_progress" })
});
assert.equal(reviewerUpdate.response.ok, true, "assignee status update failed");
assert.equal(reviewerUpdate.payload.task.status, "in_progress", "assignee status was not saved");
const reviewerEscalation = await request(`/api/tasks/${encodeURIComponent(taskId)}`, {
method: "PATCH",
headers: headers(reviewerToken),
body: JSON.stringify({ title: "越权修改标题" })
});
assert.equal(reviewerEscalation.response.status, 403, "assignee must not edit task metadata");
const ownerUpdate = await request(`/api/tasks/${encodeURIComponent(taskId)}`, {
method: "PATCH",
headers: headers(ownerToken),
body: JSON.stringify({ status: "done", priority: "medium" })
});
assert.equal(ownerUpdate.response.ok, true, "manager task update failed");
assert.equal(ownerUpdate.payload.task.status, "done", "manager status update was not saved");
assert.ok(ownerUpdate.payload.task.completedAt, "completed task must have completedAt");
const northstar = await request("/api/tasks", {
headers: { authorization: `Bearer ${ownerToken}`, "x-organization-id": "org-northstar", "x-workspace-id": "ws-northstar-main", "x-project-id": "northstar-pilot" }
});
assert.equal(northstar.response.ok, true, "northstar task scope request failed");
assert.ok(northstar.payload.tasks.every((task) => task.id !== taskId), "cross-organization task must not leak");
console.log(`tasks smoke passed: ${taskId}`);
} finally {
if (taskId) dbRun("DELETE FROM project_tasks WHERE id = ?", [taskId]);
if (taskId) {
dbRun("DELETE FROM user_notifications WHERE target_id = ?", [taskId]);
dbRun("DELETE FROM audit_logs WHERE target_type = 'project_task' AND target_id = ?", [taskId]);
}
if (ownerToken) await request("/api/auth/logout", { method: "POST", headers: { authorization: `Bearer ${ownerToken}` } }).catch(() => {});
if (reviewerToken) await request("/api/auth/logout", { method: "POST", headers: { authorization: `Bearer ${reviewerToken}` } }).catch(() => {});
}