@musnows/scriverse 0.5.3 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/ai-protocol.js +216 -0
- package/dist/ai-protocol.js.map +1 -0
- package/dist/ai.js +961 -130
- package/dist/ai.js.map +1 -1
- package/dist/app.js +126 -58
- package/dist/app.js.map +1 -1
- package/dist/collaboration-presence.js +18 -7
- package/dist/collaboration-presence.js.map +1 -1
- package/dist/database.js +85 -0
- package/dist/database.js.map +1 -1
- package/dist/public/ai-usage.d.ts +20 -0
- package/dist/public/ai-usage.js +75 -0
- package/dist/public/app.js +1107 -117
- package/dist/public/background-task-center.d.ts +28 -0
- package/dist/public/background-task-center.js +30 -0
- package/dist/public/display-labels.d.ts +1 -0
- package/dist/public/display-labels.js +7 -0
- package/dist/public/index.html +41 -4
- package/dist/public/page-route.js +2 -2
- package/dist/public/race-hierarchy.js +35 -0
- package/dist/public/styles.css +230 -10
- package/dist/public/theme-init.js +2 -2
- package/dist/relationship-search.js +8 -1
- package/dist/relationship-search.js.map +1 -1
- package/dist/store.js +135 -75
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +7 -2
- package/dist/user-auth.js.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/app.js
CHANGED
|
@@ -27,7 +27,7 @@ import { accountReference, logger, sanitizeError } from "./logger.js";
|
|
|
27
27
|
import { currentRequestActor, runWithRequestActor } from "./request-context.js";
|
|
28
28
|
import { APP_VERSION } from "./version.js";
|
|
29
29
|
import { fullWorkModulePermissions, proseReplacementPermissionModules } from "./work-permissions.js";
|
|
30
|
-
import { CollaborationPresence,
|
|
30
|
+
import { CollaborationPresence, entityEditorPageKey, presencePageKinds } from "./collaboration-presence.js";
|
|
31
31
|
import { clearSessionCookie, createCliApiScopeMiddleware, createUserSessionMiddleware, createWorkAuthorizationMiddleware, relationshipAnalysisReadModules, setSessionCookie, UserAuthService } from "./user-auth.js";
|
|
32
32
|
const nonEmpty = z.string().trim().min(1);
|
|
33
33
|
const identifier = z.string().trim().min(1).max(200);
|
|
@@ -95,7 +95,7 @@ const presenceHeartbeatSchema = z.object({
|
|
|
95
95
|
z.object({ kind: z.literal(presencePageKinds[0]) }).strict(),
|
|
96
96
|
z.object({ kind: z.literal(presencePageKinds[1]), resourceId: identifier }).strict(),
|
|
97
97
|
z.object({ kind: z.literal(presencePageKinds[2]), module: z.enum(["settings", "characters", "races", "organizations", "timeline", "relationships", "outlines", "reviews", "tasks", "ai-settings"]) }).strict(),
|
|
98
|
-
z.object({ kind: z.literal(presencePageKinds[3]), module: z.enum(["setting", "character", "race", "organization"]), resourceId: identifier.optional() }).strict(),
|
|
98
|
+
z.object({ kind: z.literal(presencePageKinds[3]), module: z.enum(["setting", "character", "race", "organization", "relationship"]), resourceId: identifier.optional() }).strict(),
|
|
99
99
|
z.object({ kind: z.literal(presencePageKinds[4]) }).strict()
|
|
100
100
|
])
|
|
101
101
|
}).strict();
|
|
@@ -274,6 +274,7 @@ const providerSchema = z.object({
|
|
|
274
274
|
name: nonEmpty.max(200),
|
|
275
275
|
baseUrl: z.string().url().refine((value) => value.startsWith("http://") || value.startsWith("https://"), "接口地址必须使用 HTTP 或 HTTPS"),
|
|
276
276
|
apiKey: nonEmpty.max(10_000),
|
|
277
|
+
protocol: z.enum(["openai-chat-completions", "anthropic-messages"]).optional(),
|
|
277
278
|
status: z.enum(["enabled", "disabled"]).optional(),
|
|
278
279
|
note: z.string().max(10_000).optional(),
|
|
279
280
|
concurrencyLimit: z.number().int().min(1).max(100).optional(),
|
|
@@ -295,8 +296,18 @@ const modelSchema = z.object({
|
|
|
295
296
|
const aiPromptSchema = z.object({
|
|
296
297
|
systemPrompt: z.string().max(100_000).optional()
|
|
297
298
|
});
|
|
299
|
+
const aiUsageQuerySchema = z.object({
|
|
300
|
+
timezoneOffset: z.coerce.number().int().min(-840).max(840).default(0)
|
|
301
|
+
}).strict();
|
|
298
302
|
const platformPageSizesSchema = z.object({
|
|
303
|
+
settings: z.number().int().min(10).max(100).optional(),
|
|
299
304
|
characters: z.number().int().min(10).max(100).optional(),
|
|
305
|
+
races: z.number().int().min(10).max(100).optional(),
|
|
306
|
+
organizations: z.number().int().min(10).max(100).optional(),
|
|
307
|
+
timeline: z.number().int().min(10).max(100).optional(),
|
|
308
|
+
outlines: z.number().int().min(10).max(100).optional(),
|
|
309
|
+
relationships: z.number().int().min(10).max(100).optional(),
|
|
310
|
+
reviews: z.number().int().min(10).max(100).optional(),
|
|
300
311
|
analysisTasks: z.number().int().min(10).max(100).optional(),
|
|
301
312
|
fileVersions: z.number().int().min(10).max(100).optional()
|
|
302
313
|
}).strict();
|
|
@@ -357,12 +368,20 @@ const contextSchema = z.object({
|
|
|
357
368
|
includeBookSummary: z.boolean().optional()
|
|
358
369
|
});
|
|
359
370
|
const analysisTaskTypeSchema = z.enum(["structure", "chapter-analysis", "character-extraction", "character-summary", "character-identity-audit", "timeline-analysis", "worldview-analysis", "setting-extraction", "consistency-check", "report-update", "book-analysis"]);
|
|
371
|
+
const relationshipSourceRefSchema = z.object({
|
|
372
|
+
sourceType: z.string().trim().min(1).max(50).regex(/^[a-z][a-z-]*$/u),
|
|
373
|
+
sourceId: identifier,
|
|
374
|
+
sourceVersion: z.string().trim().min(1).max(200)
|
|
375
|
+
}).strict();
|
|
360
376
|
const relationshipAnalysisScopeSchema = z.object({
|
|
361
377
|
type: z.enum(["chapter", "book", "settings"]),
|
|
362
378
|
chapterId: identifier.optional(),
|
|
363
379
|
includeAllSettings: z.boolean().optional(),
|
|
364
380
|
additionalPrompt: z.string().trim().max(10_000).optional(),
|
|
365
381
|
characterIds: z.array(identifier).max(20).optional(),
|
|
382
|
+
preFilterRelationshipSources: z.boolean().optional(),
|
|
383
|
+
previewRelationshipChanges: z.boolean().optional(),
|
|
384
|
+
relationshipSourceRefs: z.array(relationshipSourceRefSchema).max(5_000).optional(),
|
|
366
385
|
replaceExistingRelationships: z.boolean().optional()
|
|
367
386
|
}).strict().superRefine((scope, context) => {
|
|
368
387
|
if (scope.type === "chapter" && !scope.chapterId) {
|
|
@@ -377,6 +396,18 @@ const relationshipAnalysisScopeSchema = z.object({
|
|
|
377
396
|
if (scope.replaceExistingRelationships && !scope.characterIds?.length) {
|
|
378
397
|
context.addIssue({ code: z.ZodIssueCode.custom, path: ["replaceExistingRelationships"], message: "覆盖已有关系前必须选择被分析角色" });
|
|
379
398
|
}
|
|
399
|
+
if (scope.preFilterRelationshipSources !== undefined && !scope.characterIds?.length) {
|
|
400
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["preFilterRelationshipSources"], message: "来源前置过滤仅支持定向人物关系分析" });
|
|
401
|
+
}
|
|
402
|
+
if (scope.relationshipSourceRefs !== undefined && !scope.characterIds?.length) {
|
|
403
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["relationshipSourceRefs"], message: "预检来源仅支持定向人物关系分析" });
|
|
404
|
+
}
|
|
405
|
+
if (scope.relationshipSourceRefs) {
|
|
406
|
+
const keys = scope.relationshipSourceRefs.map((ref) => `${ref.sourceType}:${ref.sourceId}`);
|
|
407
|
+
if (new Set(keys).size !== keys.length) {
|
|
408
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["relationshipSourceRefs"], message: "预检来源不能重复" });
|
|
409
|
+
}
|
|
410
|
+
}
|
|
380
411
|
});
|
|
381
412
|
const analysisTaskSchema = z.union([
|
|
382
413
|
z.object({ taskType: z.literal("relationship-analysis"), scope: relationshipAnalysisScopeSchema.optional(), modelId: identifier.optional() }).strict(),
|
|
@@ -387,6 +418,15 @@ const analysisTaskSchema = z.union([
|
|
|
387
418
|
if (input.scope?.additionalPrompt !== undefined) {
|
|
388
419
|
context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "additionalPrompt"], message: "额外分析提示仅支持人物关系分析" });
|
|
389
420
|
}
|
|
421
|
+
if (input.scope?.preFilterRelationshipSources !== undefined) {
|
|
422
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "preFilterRelationshipSources"], message: "来源前置过滤仅支持人物关系分析" });
|
|
423
|
+
}
|
|
424
|
+
if (input.scope?.previewRelationshipChanges !== undefined) {
|
|
425
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "previewRelationshipChanges"], message: "变更预览仅支持人物关系分析" });
|
|
426
|
+
}
|
|
427
|
+
if (input.scope?.relationshipSourceRefs !== undefined) {
|
|
428
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "relationshipSourceRefs"], message: "预检来源仅支持人物关系分析" });
|
|
429
|
+
}
|
|
390
430
|
if (input.scope?.characterIds !== undefined || input.scope?.replaceExistingRelationships !== undefined) {
|
|
391
431
|
context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "characterIds"], message: "被分析角色仅支持人物关系分析" });
|
|
392
432
|
}
|
|
@@ -491,6 +531,11 @@ function redactTaskCharacterNames(record, permissions) {
|
|
|
491
531
|
return redactedRelationship;
|
|
492
532
|
});
|
|
493
533
|
}
|
|
534
|
+
const changePreview = recordValue(taskResult.relationshipChangePreview);
|
|
535
|
+
if (changePreview) {
|
|
536
|
+
const { operations: _operations, ...redactedChangePreview } = changePreview;
|
|
537
|
+
redactedTaskResult.relationshipChangePreview = redactedChangePreview;
|
|
538
|
+
}
|
|
494
539
|
const analysisTarget = recordValue(taskResult.analysisTarget);
|
|
495
540
|
if (analysisTarget) {
|
|
496
541
|
const { characterNames: _characterNames, ...redactedAnalysisTarget } = analysisTarget;
|
|
@@ -499,6 +544,14 @@ function redactTaskCharacterNames(record, permissions) {
|
|
|
499
544
|
result.result = redactedTaskResult;
|
|
500
545
|
}
|
|
501
546
|
}
|
|
547
|
+
if (permissions.relationships === "none") {
|
|
548
|
+
const taskResult = recordValue(result.result);
|
|
549
|
+
const changePreview = recordValue(taskResult?.relationshipChangePreview);
|
|
550
|
+
if (taskResult && changePreview) {
|
|
551
|
+
const { operations: _operations, ...redactedChangePreview } = changePreview;
|
|
552
|
+
result.result = { ...taskResult, relationshipChangePreview: redactedChangePreview };
|
|
553
|
+
}
|
|
554
|
+
}
|
|
502
555
|
const resultSummary = recordValue(result.resultSummary);
|
|
503
556
|
const characterSensitiveTask = ["character-extraction", "character-summary", "character-identity-audit", "relationship-analysis"]
|
|
504
557
|
.includes(String(result.taskType));
|
|
@@ -548,14 +601,14 @@ export function createRuntime(options) {
|
|
|
548
601
|
mkdirSync(attachmentStorage.temporaryDirectory, { recursive: true, mode: 0o700 });
|
|
549
602
|
const auth = new UserAuthService(database);
|
|
550
603
|
const collaborationPresence = new CollaborationPresence();
|
|
551
|
-
const
|
|
604
|
+
const publishRelationshipChange = (workId, relationshipId) => {
|
|
552
605
|
const actor = currentRequestActor();
|
|
553
|
-
if (!actor || !workId || !
|
|
606
|
+
if (!actor || !workId || !relationshipId)
|
|
554
607
|
return;
|
|
555
|
-
collaborationPresence.publishChange(workId,
|
|
608
|
+
collaborationPresence.publishChange(workId, entityEditorPageKey("relationship", relationshipId), {
|
|
556
609
|
userId: actor.userId,
|
|
557
610
|
displayName: actor.displayName
|
|
558
|
-
}
|
|
611
|
+
});
|
|
559
612
|
};
|
|
560
613
|
const getDevelopmentUser = () => options.devAuthBypass
|
|
561
614
|
? auth.listUsers().find((user) => user.status === "active") ?? null
|
|
@@ -618,6 +671,7 @@ export function createRuntime(options) {
|
|
|
618
671
|
status: "ok",
|
|
619
672
|
version: APP_VERSION,
|
|
620
673
|
protocol: "openai-chat-completions",
|
|
674
|
+
protocols: ["openai-chat-completions", "anthropic-messages"],
|
|
621
675
|
development: options.developmentServer === true
|
|
622
676
|
});
|
|
623
677
|
});
|
|
@@ -944,14 +998,11 @@ export function createRuntime(options) {
|
|
|
944
998
|
const input = parse(z.object({ title: nonEmpty.max(300).optional(), content: z.string().max(2_000_000).optional(), excludedFromAnalysis: z.boolean().optional(), chapterType: chapterTypeSchema.optional(), source: z.enum(["manual", "auto"]).optional(), changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
945
999
|
const { source, changeNote, expectedVersionNo, ...chapterInput } = input;
|
|
946
1000
|
const chapter = store.saveChapter(request.params.chapterId, chapterInput, source ?? "manual", null, changeNote, expectedVersionNo);
|
|
947
|
-
publishCollaborativeChange(String(chapter.workId), editorPageKey(String(chapter.id)));
|
|
948
1001
|
data(response, chapter);
|
|
949
1002
|
});
|
|
950
1003
|
app.delete("/api/chapters/:chapterId", (request, response) => {
|
|
951
1004
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
952
|
-
const chapter = store.getChapter(request.params.chapterId);
|
|
953
1005
|
store.deleteChapter(request.params.chapterId, input.expectedVersionNo);
|
|
954
|
-
publishCollaborativeChange(String(chapter.workId), editorPageKey(String(chapter.id)));
|
|
955
1006
|
noContent(response);
|
|
956
1007
|
});
|
|
957
1008
|
app.get("/api/chapters/:chapterId/versions", (request, response) => {
|
|
@@ -965,7 +1016,6 @@ export function createRuntime(options) {
|
|
|
965
1016
|
app.post("/api/chapters/:chapterId/restore", (request, response) => {
|
|
966
1017
|
const input = parse(z.object({ versionNo: z.number().int().positive(), expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
967
1018
|
const chapter = store.restoreChapter(request.params.chapterId, input.versionNo, input.expectedVersionNo);
|
|
968
|
-
publishCollaborativeChange(String(chapter.workId), editorPageKey(String(chapter.id)));
|
|
969
1019
|
data(response, chapter);
|
|
970
1020
|
});
|
|
971
1021
|
app.post("/api/chapters/:chapterId/move", (request, response) => {
|
|
@@ -981,14 +1031,11 @@ export function createRuntime(options) {
|
|
|
981
1031
|
app.put("/api/chapters/:chapterId/outline", (request, response) => {
|
|
982
1032
|
const { changeNote, expectedVersionNo, ...input } = parse(chapterOutlineSchema.extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
983
1033
|
const outline = store.upsertChapterOutline(request.params.chapterId, input, "manual", null, changeNote, expectedVersionNo);
|
|
984
|
-
publishCollaborativeChange(String(outline.workId), modulePageKey("outlines"));
|
|
985
1034
|
data(response, outline);
|
|
986
1035
|
});
|
|
987
1036
|
app.delete("/api/chapters/:chapterId/outline", (request, response) => {
|
|
988
1037
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
989
|
-
const chapter = store.getChapter(request.params.chapterId);
|
|
990
1038
|
store.deleteChapterOutline(request.params.chapterId, input.expectedVersionNo);
|
|
991
|
-
publishCollaborativeChange(String(chapter.workId), modulePageKey("outlines"));
|
|
992
1039
|
noContent(response);
|
|
993
1040
|
});
|
|
994
1041
|
app.get("/api/works/:workId/foreshadows", (request, response) => {
|
|
@@ -1003,42 +1050,34 @@ export function createRuntime(options) {
|
|
|
1003
1050
|
});
|
|
1004
1051
|
app.post("/api/works/:workId/foreshadows", (request, response) => {
|
|
1005
1052
|
const foreshadow = store.createForeshadow(request.params.workId, parse(foreshadowSchema, request.body));
|
|
1006
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("outlines"));
|
|
1007
1053
|
data(response, foreshadow, 201);
|
|
1008
1054
|
});
|
|
1009
1055
|
app.get("/api/foreshadows/:foreshadowId", (request, response) => data(response, store.getForeshadow(request.params.foreshadowId)));
|
|
1010
1056
|
app.patch("/api/foreshadows/:foreshadowId", (request, response) => {
|
|
1011
1057
|
const { changeNote, expectedVersionNo, ...input } = parse(foreshadowSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1012
1058
|
const foreshadow = store.updateForeshadow(request.params.foreshadowId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1013
|
-
publishCollaborativeChange(String(foreshadow.workId), modulePageKey("outlines"));
|
|
1014
1059
|
data(response, foreshadow);
|
|
1015
1060
|
});
|
|
1016
1061
|
app.delete("/api/foreshadows/:foreshadowId", (request, response) => {
|
|
1017
1062
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1018
|
-
const foreshadow = store.getForeshadow(request.params.foreshadowId);
|
|
1019
1063
|
store.deleteForeshadow(request.params.foreshadowId, input.expectedVersionNo);
|
|
1020
|
-
publishCollaborativeChange(String(foreshadow.workId), modulePageKey("outlines"));
|
|
1021
1064
|
noContent(response);
|
|
1022
1065
|
});
|
|
1023
1066
|
app.post("/api/foreshadows/:foreshadowId/occurrences", (request, response) => {
|
|
1024
1067
|
const input = parse(foreshadowOccurrenceSchema.extend({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1025
1068
|
const { expectedVersionNo, ...occurrenceInput } = input;
|
|
1026
1069
|
const occurrence = store.createForeshadowOccurrence(request.params.foreshadowId, occurrenceInput, expectedVersionNo);
|
|
1027
|
-
publishCollaborativeChange(String(occurrence.workId), modulePageKey("outlines"));
|
|
1028
1070
|
data(response, occurrence, 201);
|
|
1029
1071
|
});
|
|
1030
1072
|
app.patch("/api/foreshadow-occurrences/:occurrenceId", (request, response) => {
|
|
1031
1073
|
const input = parse(foreshadowOccurrenceSchema.partial().extend({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1032
1074
|
const { expectedVersionNo, ...occurrenceInput } = input;
|
|
1033
1075
|
const occurrence = store.updateForeshadowOccurrence(request.params.occurrenceId, occurrenceInput, expectedVersionNo);
|
|
1034
|
-
publishCollaborativeChange(String(occurrence.workId), modulePageKey("outlines"));
|
|
1035
1076
|
data(response, occurrence);
|
|
1036
1077
|
});
|
|
1037
1078
|
app.delete("/api/foreshadow-occurrences/:occurrenceId", (request, response) => {
|
|
1038
1079
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1039
|
-
const occurrence = store.getForeshadowOccurrence(request.params.occurrenceId);
|
|
1040
1080
|
store.deleteForeshadowOccurrence(request.params.occurrenceId, input.expectedVersionNo);
|
|
1041
|
-
publishCollaborativeChange(String(occurrence.workId), modulePageKey("outlines"));
|
|
1042
1081
|
noContent(response);
|
|
1043
1082
|
});
|
|
1044
1083
|
app.get("/api/works/:workId/settings", (request, response) => {
|
|
@@ -1048,7 +1087,6 @@ export function createRuntime(options) {
|
|
|
1048
1087
|
});
|
|
1049
1088
|
app.post("/api/works/:workId/settings", (request, response) => {
|
|
1050
1089
|
const setting = store.createSetting(request.params.workId, parse(settingSchema, request.body));
|
|
1051
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("settings"));
|
|
1052
1090
|
data(response, setting, 201);
|
|
1053
1091
|
});
|
|
1054
1092
|
app.get("/api/works/:workId/settings/context", (request, response) => data(response, store.listSettings(request.params.workId, true)));
|
|
@@ -1056,14 +1094,11 @@ export function createRuntime(options) {
|
|
|
1056
1094
|
app.patch("/api/settings/:settingId", (request, response) => {
|
|
1057
1095
|
const { changeNote, expectedVersionNo, ...input } = parse(settingSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1058
1096
|
const setting = store.updateSetting(request.params.settingId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1059
|
-
publishCollaborativeChange(String(setting.workId), entityEditorPageKey("setting", String(setting.id)));
|
|
1060
1097
|
data(response, setting);
|
|
1061
1098
|
});
|
|
1062
1099
|
app.delete("/api/settings/:settingId", (request, response) => {
|
|
1063
1100
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1064
|
-
const setting = store.getSetting(request.params.settingId);
|
|
1065
1101
|
store.deleteSetting(request.params.settingId, input.expectedVersionNo);
|
|
1066
|
-
publishCollaborativeChange(String(setting.workId), entityEditorPageKey("setting", String(setting.id)));
|
|
1067
1102
|
noContent(response);
|
|
1068
1103
|
});
|
|
1069
1104
|
app.get("/api/works/:workId/characters", (request, response) => {
|
|
@@ -1081,7 +1116,6 @@ export function createRuntime(options) {
|
|
|
1081
1116
|
});
|
|
1082
1117
|
app.post("/api/works/:workId/characters", (request, response) => {
|
|
1083
1118
|
const character = store.createCharacter(request.params.workId, parse(characterSchema, request.body));
|
|
1084
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("characters"));
|
|
1085
1119
|
data(response, redactCharacterLinks(character, requestPermissions(request, request.params.workId)), 201);
|
|
1086
1120
|
});
|
|
1087
1121
|
app.get("/api/characters/:characterId", (request, response) => {
|
|
@@ -1090,7 +1124,6 @@ export function createRuntime(options) {
|
|
|
1090
1124
|
app.patch("/api/characters/:characterId", (request, response) => {
|
|
1091
1125
|
const { changeNote, expectedVersionNo, ...input } = parse(characterUpdateSchema.extend({ expectedVersionNo: expectedVersionNoSchema }), request.body);
|
|
1092
1126
|
const character = store.updateCharacter(request.params.characterId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1093
|
-
publishCollaborativeChange(String(character.workId), entityEditorPageKey("character", String(character.id)));
|
|
1094
1127
|
data(response, redactCharacterLinks(character, requestPermissions(request)));
|
|
1095
1128
|
});
|
|
1096
1129
|
app.get("/api/characters/:characterId/versions", (request, response) => {
|
|
@@ -1102,14 +1135,11 @@ export function createRuntime(options) {
|
|
|
1102
1135
|
app.post("/api/characters/:characterId/restore", (request, response) => {
|
|
1103
1136
|
const input = parse(z.object({ versionNo: z.number().int().positive(), expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1104
1137
|
const character = store.restoreCharacter(request.params.characterId, input.versionNo, input.expectedVersionNo);
|
|
1105
|
-
publishCollaborativeChange(String(character.workId), entityEditorPageKey("character", String(character.id)));
|
|
1106
1138
|
data(response, redactCharacterLinks(character, requestPermissions(request)));
|
|
1107
1139
|
});
|
|
1108
1140
|
app.delete("/api/characters/:characterId", (request, response) => {
|
|
1109
1141
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1110
|
-
const character = store.getCharacter(request.params.characterId);
|
|
1111
1142
|
store.deleteCharacter(request.params.characterId, input.expectedVersionNo);
|
|
1112
|
-
publishCollaborativeChange(String(character.workId), entityEditorPageKey("character", String(character.id)));
|
|
1113
1143
|
noContent(response);
|
|
1114
1144
|
});
|
|
1115
1145
|
app.post("/api/characters/:characterId/merge", (request, response) => {
|
|
@@ -1134,7 +1164,6 @@ export function createRuntime(options) {
|
|
|
1134
1164
|
});
|
|
1135
1165
|
app.post("/api/characters/:characterId/sections", (request, response) => {
|
|
1136
1166
|
const section = store.createCharacterProfileSection(request.params.characterId, parse(characterProfileSectionSchema, request.body));
|
|
1137
|
-
publishCollaborativeChange(String(section.workId), entityEditorPageKey("character", String(section.characterId)));
|
|
1138
1167
|
data(response, section, 201);
|
|
1139
1168
|
});
|
|
1140
1169
|
app.get("/api/character-sections/:sectionId", (request, response) => {
|
|
@@ -1143,14 +1172,11 @@ export function createRuntime(options) {
|
|
|
1143
1172
|
app.patch("/api/character-sections/:sectionId", (request, response) => {
|
|
1144
1173
|
const { changeNote, expectedVersionNo, ...input } = parse(characterProfileSectionSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1145
1174
|
const section = store.updateCharacterProfileSection(request.params.sectionId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1146
|
-
publishCollaborativeChange(String(section.workId), entityEditorPageKey("character", String(section.characterId)));
|
|
1147
1175
|
data(response, section);
|
|
1148
1176
|
});
|
|
1149
1177
|
app.delete("/api/character-sections/:sectionId", (request, response) => {
|
|
1150
1178
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1151
|
-
const section = store.getCharacterProfileSection(request.params.sectionId);
|
|
1152
1179
|
store.deleteCharacterProfileSection(request.params.sectionId, input.expectedVersionNo);
|
|
1153
|
-
publishCollaborativeChange(String(section.workId), entityEditorPageKey("character", String(section.characterId)));
|
|
1154
1180
|
noContent(response);
|
|
1155
1181
|
});
|
|
1156
1182
|
app.get("/api/character-sections/:sectionId/versions", (request, response) => {
|
|
@@ -1162,7 +1188,6 @@ export function createRuntime(options) {
|
|
|
1162
1188
|
app.post("/api/character-sections/:sectionId/restore", (request, response) => {
|
|
1163
1189
|
const input = parse(z.object({ versionNo: z.number().int().positive(), expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1164
1190
|
const section = store.restoreCharacterProfileSection(request.params.sectionId, input.versionNo, input.expectedVersionNo);
|
|
1165
|
-
publishCollaborativeChange(String(section.workId), entityEditorPageKey("character", String(section.characterId)));
|
|
1166
1191
|
data(response, section);
|
|
1167
1192
|
});
|
|
1168
1193
|
app.get("/api/works/:workId/attachments", (request, response) => {
|
|
@@ -1219,7 +1244,6 @@ export function createRuntime(options) {
|
|
|
1219
1244
|
});
|
|
1220
1245
|
app.post("/api/works/:workId/races", (request, response) => {
|
|
1221
1246
|
const race = store.createRace(request.params.workId, parse(raceSchema, request.body));
|
|
1222
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("races"));
|
|
1223
1247
|
data(response, redactRaceMembers(race, requestPermissions(request, request.params.workId)), 201);
|
|
1224
1248
|
});
|
|
1225
1249
|
app.get("/api/races/:raceId", (request, response) => {
|
|
@@ -1228,14 +1252,11 @@ export function createRuntime(options) {
|
|
|
1228
1252
|
app.patch("/api/races/:raceId", (request, response) => {
|
|
1229
1253
|
const { changeNote, expectedVersionNo, ...input } = parse(raceSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1230
1254
|
const race = store.updateRace(request.params.raceId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1231
|
-
publishCollaborativeChange(String(race.workId), entityEditorPageKey("race", String(race.id)));
|
|
1232
1255
|
data(response, redactRaceMembers(race, requestPermissions(request)));
|
|
1233
1256
|
});
|
|
1234
1257
|
app.delete("/api/races/:raceId", (request, response) => {
|
|
1235
1258
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1236
|
-
const race = store.getRace(request.params.raceId);
|
|
1237
1259
|
store.deleteRace(request.params.raceId, input.expectedVersionNo);
|
|
1238
|
-
publishCollaborativeChange(String(race.workId), entityEditorPageKey("race", String(race.id)));
|
|
1239
1260
|
noContent(response);
|
|
1240
1261
|
});
|
|
1241
1262
|
app.post("/api/races/:raceId/merge", (request, response) => {
|
|
@@ -1253,7 +1274,6 @@ export function createRuntime(options) {
|
|
|
1253
1274
|
});
|
|
1254
1275
|
app.post("/api/works/:workId/organizations", (request, response) => {
|
|
1255
1276
|
const organization = store.createOrganization(request.params.workId, parse(organizationSchema, request.body));
|
|
1256
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("organizations"));
|
|
1257
1277
|
data(response, redactOrganizationMembers(organization, requestPermissions(request, request.params.workId)), 201);
|
|
1258
1278
|
});
|
|
1259
1279
|
app.get("/api/organizations/:organizationId", (request, response) => {
|
|
@@ -1262,14 +1282,11 @@ export function createRuntime(options) {
|
|
|
1262
1282
|
app.patch("/api/organizations/:organizationId", (request, response) => {
|
|
1263
1283
|
const { changeNote, expectedVersionNo, ...input } = parse(organizationSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1264
1284
|
const organization = store.updateOrganization(request.params.organizationId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1265
|
-
publishCollaborativeChange(String(organization.workId), entityEditorPageKey("organization", String(organization.id)));
|
|
1266
1285
|
data(response, redactOrganizationMembers(organization, requestPermissions(request)));
|
|
1267
1286
|
});
|
|
1268
1287
|
app.delete("/api/organizations/:organizationId", (request, response) => {
|
|
1269
1288
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1270
|
-
const organization = store.getOrganization(request.params.organizationId);
|
|
1271
1289
|
store.deleteOrganization(request.params.organizationId, input.expectedVersionNo);
|
|
1272
|
-
publishCollaborativeChange(String(organization.workId), entityEditorPageKey("organization", String(organization.id)));
|
|
1273
1290
|
noContent(response);
|
|
1274
1291
|
});
|
|
1275
1292
|
app.post("/api/organizations/:organizationId/merge", (request, response) => {
|
|
@@ -1284,21 +1301,17 @@ export function createRuntime(options) {
|
|
|
1284
1301
|
});
|
|
1285
1302
|
app.post("/api/works/:workId/timeline-tracks", (request, response) => {
|
|
1286
1303
|
const track = store.createTimelineTrack(request.params.workId, parse(timelineTrackSchema, request.body));
|
|
1287
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("timeline"));
|
|
1288
1304
|
data(response, track, 201);
|
|
1289
1305
|
});
|
|
1290
1306
|
app.get("/api/timeline-tracks/:trackId", (request, response) => data(response, store.getTimelineTrack(request.params.trackId)));
|
|
1291
1307
|
app.patch("/api/timeline-tracks/:trackId", (request, response) => {
|
|
1292
1308
|
const { changeNote, expectedVersionNo, ...input } = parse(timelineTrackSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1293
1309
|
const track = store.updateTimelineTrack(request.params.trackId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1294
|
-
publishCollaborativeChange(String(track.workId), modulePageKey("timeline"));
|
|
1295
1310
|
data(response, track);
|
|
1296
1311
|
});
|
|
1297
1312
|
app.delete("/api/timeline-tracks/:trackId", (request, response) => {
|
|
1298
1313
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1299
|
-
const track = store.getTimelineTrack(request.params.trackId);
|
|
1300
1314
|
store.deleteTimelineTrack(request.params.trackId, input.expectedVersionNo);
|
|
1301
|
-
publishCollaborativeChange(String(track.workId), modulePageKey("timeline"));
|
|
1302
1315
|
noContent(response);
|
|
1303
1316
|
});
|
|
1304
1317
|
app.get("/api/works/:workId/timeline", (request, response) => {
|
|
@@ -1307,7 +1320,6 @@ export function createRuntime(options) {
|
|
|
1307
1320
|
});
|
|
1308
1321
|
app.post("/api/works/:workId/timeline", (request, response) => {
|
|
1309
1322
|
const event = store.createTimelineEvent(request.params.workId, parse(timelineSchema, request.body));
|
|
1310
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("timeline"));
|
|
1311
1323
|
data(response, event, 201);
|
|
1312
1324
|
});
|
|
1313
1325
|
app.post("/api/works/:workId/timeline/merge", (request, response) => {
|
|
@@ -1321,14 +1333,12 @@ export function createRuntime(options) {
|
|
|
1321
1333
|
}).strict(), request.body);
|
|
1322
1334
|
const { expectedVersionNos, ...mergeInput } = input;
|
|
1323
1335
|
const merged = store.mergeTimelineEvents(request.params.workId, input.eventIds, mergeInput, expectedVersionNos);
|
|
1324
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("timeline"));
|
|
1325
1336
|
data(response, merged, 201);
|
|
1326
1337
|
});
|
|
1327
1338
|
app.get("/api/timeline/:eventId", (request, response) => data(response, store.getTimelineEvent(request.params.eventId)));
|
|
1328
1339
|
app.patch("/api/timeline/:eventId", (request, response) => {
|
|
1329
1340
|
const { changeNote, expectedVersionNo, ...input } = parse(timelineSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1330
1341
|
const event = store.updateTimelineEvent(request.params.eventId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1331
|
-
publishCollaborativeChange(String(event.workId), modulePageKey("timeline"));
|
|
1332
1342
|
data(response, event);
|
|
1333
1343
|
});
|
|
1334
1344
|
app.post("/api/timeline/:eventId/split", (request, response) => {
|
|
@@ -1342,16 +1352,11 @@ export function createRuntime(options) {
|
|
|
1342
1352
|
expectedVersionNo: expectedVersionNoSchema
|
|
1343
1353
|
}).strict(), request.body);
|
|
1344
1354
|
const split = store.splitTimelineEvent(request.params.eventId, input.parts, input.expectedVersionNo);
|
|
1345
|
-
const first = split[0];
|
|
1346
|
-
if (first)
|
|
1347
|
-
publishCollaborativeChange(String(first.workId), modulePageKey("timeline"));
|
|
1348
1355
|
data(response, split, 201);
|
|
1349
1356
|
});
|
|
1350
1357
|
app.delete("/api/timeline/:eventId", (request, response) => {
|
|
1351
1358
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1352
|
-
const event = store.getTimelineEvent(request.params.eventId);
|
|
1353
1359
|
store.deleteTimelineEvent(request.params.eventId, input.expectedVersionNo);
|
|
1354
|
-
publishCollaborativeChange(String(event.workId), modulePageKey("timeline"));
|
|
1355
1360
|
noContent(response);
|
|
1356
1361
|
});
|
|
1357
1362
|
app.get("/api/works/:workId/relationships", (request, response) => {
|
|
@@ -1365,21 +1370,20 @@ export function createRuntime(options) {
|
|
|
1365
1370
|
});
|
|
1366
1371
|
app.post("/api/works/:workId/relationships", (request, response) => {
|
|
1367
1372
|
const relationship = store.createRelationship(request.params.workId, parse(relationshipSchema, request.body));
|
|
1368
|
-
publishCollaborativeChange(request.params.workId, modulePageKey("relationships"));
|
|
1369
1373
|
data(response, relationship, 201);
|
|
1370
1374
|
});
|
|
1371
1375
|
app.get("/api/relationships/:relationshipId", (request, response) => data(response, store.getRelationship(request.params.relationshipId)));
|
|
1372
1376
|
app.patch("/api/relationships/:relationshipId", (request, response) => {
|
|
1373
1377
|
const { changeNote, expectedVersionNo, ...input } = parse(relationshipSchema.partial().extend({ changeNote: changeNoteSchema, expectedVersionNo: expectedVersionNoSchema }).strict(), request.body);
|
|
1374
1378
|
const relationship = store.updateRelationship(request.params.relationshipId, input, "manual", null, changeNote, expectedVersionNo);
|
|
1375
|
-
|
|
1379
|
+
publishRelationshipChange(String(relationship.workId), String(relationship.id));
|
|
1376
1380
|
data(response, relationship);
|
|
1377
1381
|
});
|
|
1378
1382
|
app.delete("/api/relationships/:relationshipId", (request, response) => {
|
|
1379
1383
|
const input = parse(z.object({ expectedVersionNo: expectedVersionNoSchema }).strict(), request.body ?? {});
|
|
1380
1384
|
const relationship = store.getRelationship(request.params.relationshipId);
|
|
1381
1385
|
store.deleteRelationship(request.params.relationshipId, input.expectedVersionNo);
|
|
1382
|
-
|
|
1386
|
+
publishRelationshipChange(String(relationship.workId), String(relationship.id));
|
|
1383
1387
|
noContent(response);
|
|
1384
1388
|
});
|
|
1385
1389
|
app.get("/api/entity-versions/:entityType/:entityId", (request, response) => {
|
|
@@ -1432,6 +1436,20 @@ export function createRuntime(options) {
|
|
|
1432
1436
|
const permissions = requestPermissions(request, request.params.workId);
|
|
1433
1437
|
data(response, mapRecords(store.listTaskSummariesPage(request.params.workId, parsePagination(request.query) ?? { page: 1, limit: 30, offset: 0 }), (task) => redactTaskCharacterNames(task, permissions)));
|
|
1434
1438
|
});
|
|
1439
|
+
app.post("/api/works/:workId/tasks/relationship-source-preview", async (request, response) => {
|
|
1440
|
+
const input = parse(z.object({
|
|
1441
|
+
scope: relationshipAnalysisScopeSchema,
|
|
1442
|
+
modelId: identifier.optional()
|
|
1443
|
+
}).strict(), request.body);
|
|
1444
|
+
const permissions = requestPermissions(request, request.params.workId);
|
|
1445
|
+
const deniedModules = relationshipAnalysisReadModules(input.scope).filter((module) => permissions[module] === "none");
|
|
1446
|
+
if (deniedModules.length > 0) {
|
|
1447
|
+
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取人物关系来源预检所需资料模块的权限", {
|
|
1448
|
+
modules: deniedModules
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
data(response, await ai.previewRelationshipSources(request.params.workId, input.scope, input.modelId));
|
|
1452
|
+
});
|
|
1435
1453
|
app.post("/api/works/:workId/tasks", (request, response) => {
|
|
1436
1454
|
const input = parse(analysisTaskSchema, request.body);
|
|
1437
1455
|
data(response, redactTaskCharacterNames(ai.createTask(request.params.workId, input), requestPermissions(request, request.params.workId)), 201);
|
|
@@ -1483,7 +1501,30 @@ export function createRuntime(options) {
|
|
|
1483
1501
|
allowAdminAccess: request.authMethod !== "api-key"
|
|
1484
1502
|
} : undefined), requestPermissions(request)));
|
|
1485
1503
|
});
|
|
1504
|
+
app.post("/api/tasks/:taskId/rerun", (request, response) => {
|
|
1505
|
+
parse(z.object({}).strict(), request.body ?? {});
|
|
1506
|
+
const task = store.getTask(request.params.taskId);
|
|
1507
|
+
if (task.taskType === "relationship-analysis") {
|
|
1508
|
+
const permissions = requestPermissions(request, String(task.workId));
|
|
1509
|
+
const deniedModules = relationshipAnalysisReadModules(task.scope).filter((module) => permissions[module] === "none");
|
|
1510
|
+
if (deniedModules.length > 0) {
|
|
1511
|
+
throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取本次定向人物关系分析所需资料模块的权限", {
|
|
1512
|
+
modules: deniedModules
|
|
1513
|
+
});
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
data(response, redactTaskCharacterNames(ai.rerunTask(request.params.taskId), requestPermissions(request)), 201);
|
|
1517
|
+
});
|
|
1486
1518
|
app.post("/api/tasks/:taskId/cancel", (request, response) => data(response, redactTaskCharacterNames(ai.cancelTask(request.params.taskId), requestPermissions(request))));
|
|
1519
|
+
app.post("/api/tasks/:taskId/relationship-changes/apply", (request, response) => {
|
|
1520
|
+
parse(z.object({}).strict(), request.body ?? {});
|
|
1521
|
+
const applied = ai.applyRelationshipChangePreview(request.params.taskId);
|
|
1522
|
+
data(response, redactTaskCharacterNames(applied, requestPermissions(request)));
|
|
1523
|
+
});
|
|
1524
|
+
app.post("/api/tasks/:taskId/relationship-changes/discard", (request, response) => {
|
|
1525
|
+
parse(z.object({}).strict(), request.body ?? {});
|
|
1526
|
+
data(response, redactTaskCharacterNames(ai.discardRelationshipChangePreview(request.params.taskId), requestPermissions(request)));
|
|
1527
|
+
});
|
|
1487
1528
|
app.get("/api/platform/ai/providers", (request, response) => {
|
|
1488
1529
|
const pagination = parsePagination(request.query);
|
|
1489
1530
|
data(response, pagination ? ai.listProvidersPage(pagination) : ai.listProviders());
|
|
@@ -1495,12 +1536,39 @@ export function createRuntime(options) {
|
|
|
1495
1536
|
});
|
|
1496
1537
|
app.get("/api/platform/ai/settings", (_request, response) => data(response, store.getPlatformAiSettings()));
|
|
1497
1538
|
app.patch("/api/platform/ai/settings", (request, response) => data(response, store.updatePlatformAiSettings(parse(aiPromptSchema, request.body))));
|
|
1539
|
+
app.get("/api/platform/ai/usage", (request, response) => {
|
|
1540
|
+
const query = parse(aiUsageQuerySchema, request.query);
|
|
1541
|
+
data(response, ai.getPlatformTokenUsage(query.timezoneOffset));
|
|
1542
|
+
});
|
|
1498
1543
|
app.get("/api/ui-settings", (_request, response) => data(response, store.getPlatformUiSettings()));
|
|
1499
1544
|
app.get("/api/platform/ui-settings", (_request, response) => data(response, store.getPlatformUiSettings()));
|
|
1500
1545
|
app.patch("/api/platform/ui-settings", (request, response) => {
|
|
1501
1546
|
data(response, store.updatePlatformUiSettings(parse(platformUiSettingsSchema, request.body)));
|
|
1502
1547
|
});
|
|
1503
1548
|
app.get("/api/works/:workId/ai-settings", (request, response) => data(response, store.getWorkAiSettings(request.params.workId)));
|
|
1549
|
+
app.get("/api/works/:workId/ai-settings/usage", (request, response) => {
|
|
1550
|
+
const query = parse(aiUsageQuerySchema, request.query);
|
|
1551
|
+
data(response, ai.getWorkTokenUsage(request.params.workId, query.timezoneOffset));
|
|
1552
|
+
});
|
|
1553
|
+
app.get("/api/works/:workId/ai-settings/relationship-search-index", (request, response) => {
|
|
1554
|
+
data(response, ai.getRelationshipSearchIndexStatus(request.params.workId));
|
|
1555
|
+
});
|
|
1556
|
+
app.post("/api/works/:workId/ai-settings/relationship-search-index/sync", (request, response) => {
|
|
1557
|
+
const workId = request.params.workId;
|
|
1558
|
+
const result = ai.syncRelationshipSearchIndex(workId);
|
|
1559
|
+
store.audit(workId, "relationship.search-index.incremental-sync-queued", "work-ai-settings", workId, {
|
|
1560
|
+
queuedSourceCount: result.queuedSourceCount
|
|
1561
|
+
});
|
|
1562
|
+
data(response, result, 202);
|
|
1563
|
+
});
|
|
1564
|
+
app.post("/api/works/:workId/ai-settings/relationship-search-index/rebuild", (request, response) => {
|
|
1565
|
+
const workId = request.params.workId;
|
|
1566
|
+
const result = ai.rebuildRelationshipSearchIndex(workId);
|
|
1567
|
+
store.audit(workId, "relationship.search-index.rebuild-queued", "work-ai-settings", workId, {
|
|
1568
|
+
queuedSourceCount: result.queuedSourceCount
|
|
1569
|
+
});
|
|
1570
|
+
data(response, result, 202);
|
|
1571
|
+
});
|
|
1504
1572
|
app.patch("/api/works/:workId/ai-settings", (request, response) => {
|
|
1505
1573
|
const workId = request.params.workId;
|
|
1506
1574
|
const before = store.getWorkAiSettings(workId);
|