75 lines
2.2 KiB
TypeScript
75 lines
2.2 KiB
TypeScript
import { Router } from 'express';
|
|
import { z } from 'zod';
|
|
|
|
import type { RuntimeStoryActionRequest } from '../../../../packages/shared/src/contracts/story.js';
|
|
import type { AppContext } from '../../context.js';
|
|
import { badRequest } from '../../errors.js';
|
|
import { asyncHandler, sendApiResponse } from '../../http.js';
|
|
import { requireJwtAuth } from '../../middleware/auth.js';
|
|
import { routeMeta } from '../../middleware/routeMeta.js';
|
|
import {
|
|
getRuntimeStoryState,
|
|
resolveRuntimeStoryAction,
|
|
} from './storyActionService.js';
|
|
|
|
const actionPayloadSchema = z.record(z.string(), z.unknown());
|
|
|
|
const runtimeStoryActionSchema = z.object({
|
|
sessionId: z.string().trim().min(1),
|
|
clientVersion: z.number().int().min(0).optional(),
|
|
action: z.object({
|
|
type: z.literal('story_choice'),
|
|
functionId: z.string().trim().min(1),
|
|
targetId: z.string().trim().optional(),
|
|
payload: actionPayloadSchema.optional().default({}),
|
|
}),
|
|
});
|
|
|
|
export function createStoryActionRoutes(context: AppContext) {
|
|
const router = Router();
|
|
const requireAuth = requireJwtAuth(context.config, context.userRepository);
|
|
|
|
router.use(requireAuth);
|
|
|
|
router.post(
|
|
'/actions/resolve',
|
|
routeMeta({ operation: 'runtime.story.actions.resolve' }),
|
|
asyncHandler(async (request, response) => {
|
|
const payload = runtimeStoryActionSchema.parse(
|
|
request.body,
|
|
) as RuntimeStoryActionRequest;
|
|
sendApiResponse(
|
|
response,
|
|
await resolveRuntimeStoryAction({
|
|
runtimeRepository: context.runtimeRepository,
|
|
llmClient: context.llmClient,
|
|
userId: request.userId!,
|
|
request: payload,
|
|
}),
|
|
);
|
|
}),
|
|
);
|
|
|
|
router.get(
|
|
'/state/:sessionId',
|
|
routeMeta({ operation: 'runtime.story.state.get' }),
|
|
asyncHandler(async (request, response) => {
|
|
const sessionId = request.params.sessionId?.trim() || '';
|
|
if (!sessionId) {
|
|
throw badRequest('sessionId is required');
|
|
}
|
|
|
|
sendApiResponse(
|
|
response,
|
|
await getRuntimeStoryState({
|
|
runtimeRepository: context.runtimeRepository,
|
|
userId: request.userId!,
|
|
sessionId,
|
|
}),
|
|
);
|
|
}),
|
|
);
|
|
|
|
return router;
|
|
}
|