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
+121
View File
@@ -0,0 +1,121 @@
import assert from "node:assert/strict";
const api = process.env.AI_DRAMA_API_BASE || "http://127.0.0.1:8787";
const localScope = {
"x-organization-id": "org-studio-lab",
"x-workspace-id": "ws-local-aidrama",
"x-project-id": "thunder-mouth"
};
const northstarScope = {
"x-organization-id": "org-northstar",
"x-workspace-id": "ws-northstar-main",
"x-project-id": "northstar-pilot"
};
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, scope) {
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: ${JSON.stringify(result.payload)}`);
return result.payload.session.token;
}
const tokens = [];
try {
const anonymous = await request("/api/notifications");
assert.equal(anonymous.response.status, 401, "anonymous notifications must be rejected");
const ownerToken = await login("producer@local.test");
tokens.push(ownerToken);
const ownerHeaders = headers(ownerToken, localScope);
const preferences = await request("/api/notification-preferences", { headers: ownerHeaders });
assert.equal(preferences.response.ok, true, JSON.stringify(preferences.payload));
assert.equal(preferences.payload.preferences.length, 7, "notification preference catalog must be complete");
assert.equal(preferences.payload.preferences.find((item) => item.category === "billing")?.enabled, true, "billing preference must default to enabled");
const disabledPreferences = await request("/api/notification-preferences/billing", {
method: "PATCH",
headers: ownerHeaders,
body: JSON.stringify({ enabled: false })
});
assert.equal(disabledPreferences.response.ok, true, JSON.stringify(disabledPreferences.payload));
const preferenceMarker = `preference-${Date.now()}`;
const preferenceEvent = await request("/api/system/notifications/test", {
method: "POST",
headers: ownerHeaders,
body: JSON.stringify({ event: "quota.warning", payload: { targetId: preferenceMarker, detail: "通知偏好 smoke 事件" } })
});
assert.equal(preferenceEvent.response.ok, true, JSON.stringify(preferenceEvent.payload));
const ownerAfterPreference = await request("/api/notifications?limit=80", { headers: ownerHeaders });
assert.equal(ownerAfterPreference.response.ok, true, JSON.stringify(ownerAfterPreference.payload));
assert.ok(!ownerAfterPreference.payload.notifications.some((item) => item.targetId === preferenceMarker), "disabled category must not create a notification for that user");
const restoredPreferences = await request("/api/notification-preferences/billing", {
method: "PATCH",
headers: ownerHeaders,
body: JSON.stringify({ enabled: true })
});
assert.equal(restoredPreferences.response.ok, true, JSON.stringify(restoredPreferences.payload));
const marker = `smoke-${Date.now()}`;
const event = await request("/api/system/notifications/test", {
method: "POST",
headers: ownerHeaders,
body: JSON.stringify({ event: "system.changed", payload: { targetId: marker, detail: "通知 smoke 验证事件" } })
});
assert.equal(event.response.ok, true, `notification event failed: ${JSON.stringify(event.payload)}`);
assert.ok(event.payload.userNotifications?.length >= 1, "event must create in-app notifications for eligible recipients");
const ownerInbox = await request("/api/notifications?limit=40", { headers: ownerHeaders });
assert.equal(ownerInbox.response.ok, true, JSON.stringify(ownerInbox.payload));
const created = ownerInbox.payload.notifications.find((item) => item.targetId === marker);
assert.ok(created, "owner must see the notification in the current workspace");
assert.ok(ownerInbox.payload.unreadCount >= 1, "new notification must increase unread count");
const writerToken = await login("writer@local.test");
tokens.push(writerToken);
const writerHeaders = headers(writerToken, localScope);
const writerReadOwnerMessage = await request(`/api/notifications/${encodeURIComponent(created.id)}`, {
method: "PATCH",
headers: writerHeaders,
body: JSON.stringify({ read: true })
});
assert.equal(writerReadOwnerMessage.response.status, 404, "a different user cannot mark another user's notification read");
const ownerRead = await request(`/api/notifications/${encodeURIComponent(created.id)}`, {
method: "PATCH",
headers: ownerHeaders,
body: JSON.stringify({ read: true })
});
assert.equal(ownerRead.response.ok, true, JSON.stringify(ownerRead.payload));
assert.ok(ownerRead.payload.notifications.some((item) => item.id === created.id && item.read), "single notification must become read");
const ownerReadAll = await request("/api/notifications/read-all", { method: "POST", headers: ownerHeaders, body: "{}" });
assert.equal(ownerReadAll.response.ok, true, JSON.stringify(ownerReadAll.payload));
assert.equal(ownerReadAll.payload.unreadCount, 0, "read-all must clear the current user's unread count");
const northstar = await request("/api/notifications?limit=40", { headers: headers(ownerToken, northstarScope) });
assert.equal(northstar.response.ok, true, JSON.stringify(northstar.payload));
assert.ok(northstar.payload.notifications.every((item) => item.organizationId === "org-northstar"), "cross-organization notifications must be isolated");
assert.ok(!northstar.payload.notifications.some((item) => item.targetId === marker), "northstar must not see local notification IDs");
const northstarPreferences = await request("/api/notification-preferences", { headers: headers(ownerToken, northstarScope) });
assert.equal(northstarPreferences.response.ok, true, JSON.stringify(northstarPreferences.payload));
assert.equal(northstarPreferences.payload.preferences.find((item) => item.category === "billing")?.enabled, true, "notification preferences must be organization scoped");
console.log(`notifications smoke passed: owner=${ownerInbox.payload.notifications.length}, preference-filtered=true, writer-cross-user=blocked, northstar=${northstar.payload.notifications.length}`);
} finally {
for (const token of tokens) {
await request("/api/auth/logout", { method: "POST", headers: { authorization: `Bearer ${token}` } }).catch(() => {});
}
}