Files
growqr-backend/src/routes/workflows.ts
NinjasPyajamas 54297496a4 feat: Enhance Gitea integration and agent management
- Added ensureOrg and ensureOrgRepo methods to GiteaClient for centralized organization and repository management.
- Updated main application flow to ensure central Gitea readiness at startup.
- Introduced prompt-loader for dynamic loading of agent modules and system prompts from disk.
- Refactored agent routes to return sub-agent module catalog.
- Modified git routes to interact with a central Gitea instance instead of per-user containers.
- Updated workflow routes to utilize a unified user actor per user, streamlining job application workflows.
- Improved service agent handling with a new lightweight reference type.
2026-05-25 17:52:40 +05:30

77 lines
2.4 KiB
TypeScript

import { Hono } from "hono";
import { z } from "zod";
import { createClient } from "rivetkit/client";
import { config } from "../config.js";
import { requireUser, type AuthContext } from "../auth/clerk.js";
import type { Registry } from "../actors/registry.js";
const client = createClient<Registry>(config.rivetEndpoint);
// Per changes.md §5: one unified userActor per user.
function userActorFor(userId: string) {
return client.userActor.getOrCreate([userId]);
}
export function workflowRoutes() {
const app = new Hono<AuthContext>();
app.use("*", requireUser);
app.post("/job-application", async (c) => {
const userId = c.get("userId");
const body = z
.object({ goal: z.string().min(1).optional() })
.parse(await c.req.json().catch(() => ({})));
const handle = userActorFor(userId);
await handle.init({ userId });
const state = await handle.startWorkflow({ goal: body.goal });
return c.json({ workflow: state });
});
app.get("/job-application", async (c) => {
const userId = c.get("userId");
const handle = userActorFor(userId);
await handle.init({ userId });
const state = await handle.getWorkflowStatus();
return c.json({ workflow: state });
});
app.post("/job-application/pause", async (c) => {
const userId = c.get("userId");
const workflow = await userActorFor(userId).pauseWorkflow();
return c.json({ workflow });
});
app.post("/job-application/resume", async (c) => {
const userId = c.get("userId");
const workflow = await userActorFor(userId).resumeWorkflow();
return c.json({ workflow });
});
app.post("/job-application/agents/:moduleId/run", async (c) => {
const userId = c.get("userId");
const moduleId = c.req.param("moduleId");
const workflow = await userActorFor(userId).runWorkflowModule({ moduleId });
return c.json({ workflow });
});
app.post("/job-application/agents/:moduleId/score", async (c) => {
const userId = c.get("userId");
const moduleId = c.req.param("moduleId");
const body = z
.object({
question: z.string().min(1),
answer: z.string().min(1),
score: z.number().min(0).max(100),
notes: z.string().optional(),
})
.parse(await c.req.json());
const workflow = await userActorFor(userId).recordQaScore({
moduleId,
...body,
});
return c.json({ workflow });
});
return app;
}