Merge service REST proxy changes
This commit is contained in:
@@ -2,6 +2,25 @@ import { Hono } from "hono";
|
||||
import { requireUser, type AuthContext } from "../auth/clerk.js";
|
||||
import { listServiceCapabilities } from "../workflows/service-capabilities.js";
|
||||
import { interviewService, resumeService, roleplayService, type JsonObject } from "../services/product-service-clients.js";
|
||||
import { db } from "../db/client.js";
|
||||
import { events } from "../db/schema.js";
|
||||
|
||||
const DEFAULT_QSCORE = {
|
||||
q_score: 76,
|
||||
profession: "Student",
|
||||
quotients: {
|
||||
SQ: 76,
|
||||
XQ: 74,
|
||||
CQm: 78,
|
||||
VQ: 72,
|
||||
DQ: 75,
|
||||
GQ: 80,
|
||||
},
|
||||
};
|
||||
|
||||
async function recordServiceEvent(userId: string, type: string, payload: Record<string, unknown>) {
|
||||
await db.insert(events).values({ userId, actorId: "service-gateway", type, payload });
|
||||
}
|
||||
|
||||
export function serviceRoutes() {
|
||||
const app = new Hono<AuthContext>();
|
||||
@@ -17,7 +36,18 @@ export function serviceRoutes() {
|
||||
return c.json({ error: "unknown_service" }, 404);
|
||||
});
|
||||
|
||||
app.post("/interview/configure", async (c) => c.json(await interviewService.configure(await c.req.json<JsonObject>())));
|
||||
app.get("/interview/page-state", async (c) => c.json(await interviewService.pageState(c.get("userId"))));
|
||||
app.post("/interview/configure", async (c) => {
|
||||
const body = await c.req.json<JsonObject>();
|
||||
const payload = {
|
||||
...body,
|
||||
user_id: String(body.user_id ?? c.get("userId")),
|
||||
org_id: String(body.org_id ?? "growqr"),
|
||||
} satisfies JsonObject;
|
||||
const result = await interviewService.configure(payload);
|
||||
await recordServiceEvent(c.get("userId"), "interview.configured", { request: payload, result });
|
||||
return c.json(result);
|
||||
});
|
||||
app.post("/interview/preview", async (c) => c.json(await interviewService.preview(await c.req.json<JsonObject>())));
|
||||
app.post("/interview/questions", async (c) => c.json(await interviewService.editQuestions(await c.req.json())));
|
||||
app.post("/interview/approve", async (c) => {
|
||||
@@ -28,13 +58,30 @@ export function serviceRoutes() {
|
||||
app.get("/interview/assignments", async (c) => c.json(await interviewService.listAssignments(c.req.query("email") ?? "", c.req.query("status") ?? "pending", Number(c.req.query("limit") ?? 20))));
|
||||
app.post("/interview/assignments/unassign", async (c) => c.json(await interviewService.unassign(await c.req.json())));
|
||||
app.post("/interview/results:bulk", async (c) => c.json(await interviewService.resultsBulk(await c.req.json<JsonObject>())));
|
||||
app.get("/interview/review/:sessionId", async (c) => c.json(await interviewService.review(c.req.param("sessionId"))));
|
||||
app.get("/interview/review/:sessionId", async (c) => {
|
||||
const sessionId = c.req.param("sessionId");
|
||||
const result = await interviewService.review(sessionId);
|
||||
await recordServiceEvent(c.get("userId"), "interview.review_checked", { sessionId, result });
|
||||
return c.json(result);
|
||||
});
|
||||
app.get("/interview/leaderboard", async (c) => c.json(await interviewService.leaderboard()));
|
||||
app.get("/interview/artifacts/:sessionId/:artifactType", async (c) => c.json(await interviewService.artifact(c.req.param("sessionId"), c.req.param("artifactType"))));
|
||||
app.post("/interview/sessions/:sessionId/video/upload-url", async (c) => c.json(await interviewService.createVideoUploadUrl(c.req.param("sessionId"), await c.req.json<JsonObject>())));
|
||||
app.post("/interview/sessions/:sessionId/video/uploaded", async (c) => c.json(await interviewService.markVideoUploaded(c.req.param("sessionId"), await c.req.json<JsonObject>())));
|
||||
|
||||
app.post("/roleplay/configure", async (c) => c.json(await roleplayService.configure(await c.req.json<JsonObject>())));
|
||||
app.get("/roleplay/page-state", async (c) => c.json(await roleplayService.pageState(c.get("userId"))));
|
||||
app.post("/roleplay/configure", async (c) => {
|
||||
const body = await c.req.json<JsonObject>();
|
||||
const payload = {
|
||||
...body,
|
||||
user_id: String(body.user_id ?? c.get("userId")),
|
||||
org_id: String(body.org_id ?? "growqr"),
|
||||
qscore: (body.qscore as JsonObject | undefined) ?? DEFAULT_QSCORE,
|
||||
} satisfies JsonObject;
|
||||
const result = await roleplayService.configure(payload);
|
||||
await recordServiceEvent(c.get("userId"), "roleplay.configured", { request: payload, result });
|
||||
return c.json(result);
|
||||
});
|
||||
app.post("/roleplay/preview", async (c) => c.json(await roleplayService.preview(await c.req.json<JsonObject>())));
|
||||
app.post("/roleplay/questions", async (c) => c.json(await roleplayService.editQuestions(await c.req.json())));
|
||||
app.post("/roleplay/approve", async (c) => {
|
||||
@@ -45,7 +92,12 @@ export function serviceRoutes() {
|
||||
app.get("/roleplay/assignments", async (c) => c.json(await roleplayService.listAssignments(c.req.query("email") ?? "", c.req.query("status") ?? "pending", Number(c.req.query("limit") ?? 20))));
|
||||
app.post("/roleplay/assignments/unassign", async (c) => c.json(await roleplayService.unassign(await c.req.json())));
|
||||
app.post("/roleplay/results:bulk", async (c) => c.json(await roleplayService.resultsBulk(await c.req.json<JsonObject>())));
|
||||
app.get("/roleplay/review/:sessionId", async (c) => c.json(await roleplayService.review(c.req.param("sessionId"))));
|
||||
app.get("/roleplay/review/:sessionId", async (c) => {
|
||||
const sessionId = c.req.param("sessionId");
|
||||
const result = await roleplayService.review(sessionId);
|
||||
await recordServiceEvent(c.get("userId"), "roleplay.review_checked", { sessionId, result });
|
||||
return c.json(result);
|
||||
});
|
||||
app.get("/roleplay/leaderboard", async (c) => c.json(await roleplayService.leaderboard()));
|
||||
app.get("/roleplay/artifacts/:sessionId/:artifactType", async (c) => c.json(await roleplayService.artifact(c.req.param("sessionId"), c.req.param("artifactType"))));
|
||||
app.post("/roleplay/sessions/:sessionId/video/upload-url", async (c) => c.json(await roleplayService.createVideoUploadUrl(c.req.param("sessionId"), await c.req.json<JsonObject>())));
|
||||
@@ -61,7 +113,13 @@ export function serviceRoutes() {
|
||||
app.post("/resume/resumes", async (c) => c.json(await resumeService.createResume(await c.req.json<JsonObject>())));
|
||||
app.get("/resume/resumes/:resumeId", async (c) => c.json(await resumeService.getResume(c.req.param("resumeId"))));
|
||||
app.put("/resume/resumes/:resumeId", async (c) => c.json(await resumeService.updateResume(c.req.param("resumeId"), await c.req.json<JsonObject>())));
|
||||
app.post("/resume/resumes/:resumeId/analyze", async (c) => c.json(await resumeService.analyzeResume(c.req.param("resumeId"), await c.req.json<JsonObject>().catch(() => ({})))));
|
||||
app.post("/resume/resumes/:resumeId/analyze", async (c) => {
|
||||
const resumeId = c.req.param("resumeId");
|
||||
const payload = await c.req.json<JsonObject>().catch(() => ({}));
|
||||
const result = await resumeService.analyzeResume(resumeId, payload);
|
||||
await recordServiceEvent(c.get("userId"), "resume.analysis_completed", { resumeId, request: payload, result });
|
||||
return c.json(result);
|
||||
});
|
||||
app.get("/resume/resumes/:resumeId/suggestions", async (c) => c.json(await resumeService.suggestions(c.req.param("resumeId"))));
|
||||
app.post("/resume/ai/copilot", async (c) => c.json(await resumeService.copilot(await c.req.json<JsonObject>())));
|
||||
app.post("/resume/ai/optimize-summary", async (c) => c.json(await resumeService.optimizeSummary(await c.req.json<JsonObject>())));
|
||||
|
||||
@@ -5,13 +5,6 @@ import { users, userStacks, type UserStack } from "../db/schema.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { provisionUserStack } from "../docker/manager.js";
|
||||
import { log } from "../log.js";
|
||||
import { createClient, type Client } from "rivetkit/client";
|
||||
import { config } from "../config.js";
|
||||
import type { Registry } from "../actors/registry.js";
|
||||
|
||||
let _client: Client<Registry> | null = null;
|
||||
function getClient(): Client<Registry> { return (_client ??= createClient<Registry>(config.rivetClientEndpoint)); }
|
||||
|
||||
function publicStack(stack: UserStack | null | undefined) {
|
||||
if (!stack) return stack;
|
||||
const { opencodePassword: _opencodePassword, ...safe } = stack;
|
||||
@@ -42,12 +35,10 @@ export function userRoutes() {
|
||||
);
|
||||
}
|
||||
|
||||
const grow = await getClient().growActor.getOrCreate([userId]).setup({ userId });
|
||||
|
||||
return c.json({
|
||||
user: userRow,
|
||||
stack: publicStack(stack) ?? { status: "provisioning" },
|
||||
grow,
|
||||
grow: null,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ async function serviceJson<T = JsonObject>(
|
||||
|
||||
export const interviewService = {
|
||||
health: () => serviceJson(config.interviewServiceUrl, "/health"),
|
||||
pageState: (userId: string) => serviceJson(config.interviewServiceUrl, `/api/v1/interviews/page-state?${new URLSearchParams({ user_id: userId })}`),
|
||||
configure: (payload: JsonObject) => serviceJson(config.interviewServiceUrl, "/api/v1/configure", { body: payload }),
|
||||
preview: (payload: JsonObject) => serviceJson(config.interviewServiceUrl, "/api/v1/configure/preview", { body: payload }),
|
||||
editQuestions: (payload: { session_id: string; questions: Array<JsonObject | string> }) =>
|
||||
@@ -55,6 +56,7 @@ export const interviewService = {
|
||||
|
||||
export const roleplayService = {
|
||||
health: () => serviceJson(config.roleplayServiceUrl, "/health"),
|
||||
pageState: (userId: string) => serviceJson(config.roleplayServiceUrl, `/api/v1/roleplays/page-state?${new URLSearchParams({ user_id: userId })}`),
|
||||
configure: (payload: JsonObject) => serviceJson(config.roleplayServiceUrl, "/api/v1/roleplays/configure", { body: payload }),
|
||||
preview: (payload: JsonObject) => serviceJson(config.roleplayServiceUrl, "/api/v1/roleplays/configure/preview", { body: payload }),
|
||||
editQuestions: (payload: { session_id: string; questions: Array<JsonObject | string> }) =>
|
||||
|
||||
Reference in New Issue
Block a user