refactor(db): group database domain modules

This commit is contained in:
ZacharyZhang-NY committed 2026-04-22 19:24:25 -04:00
1 parent e43a89096d
commit 6da0a58769
160 files changed
+2124 -1999

No files matched your search

+12 -12
View File
@@ -12,7 +12,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
const targetAgentId = requireParam(params, "agentId");
const targetAgent = (() => {
try {
return db.entityCrud.getAgent(targetAgentId);
return db.core.entity.getAgent(targetAgentId);
} catch (err) {
log.warn(`[api/agent-control] getAgent failed for ${targetAgentId}:`, err instanceof Error ? err.message : String(err));
return null;
@@ -31,7 +31,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
});
const parsed = wakeSchema.safeParse(body);
const reason = parsed.success ? parsed.data.reason : "peer_request";
const alreadyActive = db.runs.hasActiveRun({ companyId: token.companyId, agentId: targetAgentId });
const alreadyActive = db.core.runs.hasActiveRun({ companyId: token.companyId, agentId: targetAgentId });
const runId = onWakeAgent(targetAgentId, token.companyId, reason);
if (runId) {
server.json(res, 200, { ok: true, runId, message: `Wake started for agent ${targetAgentId}` });
@@ -52,7 +52,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
const targetAgentId = requireParam(params, "agentId");
let targetAgent;
try {
targetAgent = db.entityCrud.getAgent(targetAgentId);
targetAgent = db.core.entity.getAgent(targetAgentId);
} catch (err) {
log.warn(`[api/agent-control] getAgent failed for heartbeat ${targetAgentId}:`, err instanceof Error ? err.message : String(err));
targetAgent = null;
@@ -65,7 +65,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Current agent is not allowed to trigger heartbeat for this agent" });
return;
}
const alreadyActive = db.runs.hasActiveRun({ companyId: token.companyId, agentId: targetAgentId });
const alreadyActive = db.core.runs.hasActiveRun({ companyId: token.companyId, agentId: targetAgentId });
const runId = onWakeAgent(targetAgentId, token.companyId, "peer_request");
if (runId) {
server.json(res, 200, { ok: true, runId, message: `Heartbeat triggered for agent ${targetAgentId}` });
@@ -86,7 +86,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
const agentId = requireParam(params, "agentId");
let agent;
try {
agent = db.entityCrud.getAgent(agentId);
agent = db.core.entity.getAgent(agentId);
} catch (error) {
log.warn(`[api/agent-skills:GET] getAgent(${agentId}) failed: ${error instanceof Error ? error.message : String(error)}`);
agent = null;
@@ -95,9 +95,9 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
server.json(res, 404, { error: "Agent not found in your company" });
return;
}
const skillIds = db.skills.listAgentSkillAssignments(agentId);
const skillIds = db.core.skills.listAgentSkillAssignments(agentId);
const skills = skillIds
.map((sid) => db.skills.getCompanySkill(token.companyId, sid))
.map((sid) => db.core.skills.getCompanySkill(token.companyId, sid))
.filter((s): s is NonNullable<typeof s> => s != null);
server.json(res, 200, skills.map((s) => ({
id: s.id,
@@ -118,7 +118,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
}
let agent;
try {
agent = db.entityCrud.getAgent(agentId);
agent = db.core.entity.getAgent(agentId);
} catch (error) {
log.warn(`[api/agent-skills:POST] getAgent(${agentId}) failed: ${error instanceof Error ? error.message : String(error)}`);
agent = null;
@@ -127,12 +127,12 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
server.json(res, 404, { error: "Agent not found in your company" });
return;
}
const skill = db.skills.getCompanySkill(token.companyId, parsed.data.skillId);
const skill = db.core.skills.getCompanySkill(token.companyId, parsed.data.skillId);
if (!skill) {
server.json(res, 404, { error: "Skill not found in your company" });
return;
}
db.skills.assignSkillToAgent(agentId, parsed.data.skillId);
db.core.skills.assignSkillToAgent(agentId, parsed.data.skillId);
onDomainChanged();
server.json(res, 200, { ok: true, message: `Skill "${skill.name}" assigned to agent ${agent.name}` });
});
@@ -142,7 +142,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
const skillId = requireParam(params, "skillId");
let agent;
try {
agent = db.entityCrud.getAgent(agentId);
agent = db.core.entity.getAgent(agentId);
} catch (error) {
log.warn(`[api/agent-skills:DELETE] getAgent(${agentId}) failed: ${error instanceof Error ? error.message : String(error)}`);
agent = null;
@@ -151,7 +151,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
server.json(res, 404, { error: "Agent not found in your company" });
return;
}
db.skills.removeSkillFromAgent(agentId, skillId);
db.core.skills.removeSkillFromAgent(agentId, skillId);
onDomainChanged();
server.json(res, 200, { ok: true, message: `Skill removed from agent ${agent.name}` });
});
+13 -13
View File
@@ -3,23 +3,23 @@ import type { AgentApiServer } from "./server-core";
export function registerAgentStandupRoute(server: AgentApiServer): void {
const db = server.db;
server.addRoute("GET", "/api/agents/me/standup", (_req, res, _params, token) => {
const agent = db.entityCrud.getAgent(token.agentId);
const agent = db.core.entity.getAgent(token.agentId);
if (!agent || agent.companyId !== token.companyId) {
server.json(res, 404, { error: "Agent not found" });
return;
}
const directReports = db.agents.listDirectReportsForStandup(token.companyId, token.agentId);
const directReports = db.core.agents.listDirectReportsForStandup(token.companyId, token.agentId);
const myTasks = db.tasks.listAssigneeTasksForStandup(token.companyId, token.agentId);
const myTasks = db.core.tasks.listAssigneeTasksForStandup(token.companyId, token.agentId);
const reportTasks = db.tasks.listTasksForAssignees(
const reportTasks = db.core.tasks.listTasksForAssignees(
token.companyId,
directReports.map((r) => r.id),
);
const reportStatusRows = directReports.length > 0
? db.agents.listReportStatusesForStandup(token.companyId, token.agentId)
? db.core.agents.listReportStatusesForStandup(token.companyId, token.agentId)
: [];
const tasksAwaitingMyReview = reportTasks.filter((t) => t.status === "in_review");
@@ -33,20 +33,20 @@ export function registerAgentStandupRoute(server: AgentApiServer): void {
...reportTasks.map((t) => t.id),
]);
const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString();
const recentComments = db.activityMod.listRecentTaskComments([...allRelevantTaskIds], twoHoursAgo, 20);
const recentComments = db.core.activity.listRecentTaskComments([...allRelevantTaskIds], twoHoursAgo, 20);
const myPendingApprovals = db.approvalsMod.listAgentPendingApprovals(token.companyId, token.agentId);
const myResolvedApprovals = db.approvalsMod.listAgentResolvedApprovals(token.companyId, token.agentId, 5);
const myPendingApprovals = db.core.approvals.listAgentPendingApprovals(token.companyId, token.agentId);
const myResolvedApprovals = db.core.approvals.listAgentResolvedApprovals(token.companyId, token.agentId, 5);
// Unread inbox lives in the standup briefing as the agent's
// canonical view of pending communication. Pre-fix the agent had
// to make a second API call to /messages?unreadOnly=true that the
// model frequently skipped, so messages from peers and managers
// sat dark while the agent posted heartbeat status comments.
const unreadInbox = db.messages.listAgentInboxUnread(token.companyId, token.agentId);
const unreadInbox = db.core.messages.listAgentInboxUnread(token.companyId, token.agentId);
const senderIds = new Set(unreadInbox.map((m) => m.fromAgentId));
const senderNames = senderIds.size > 0
? new Map(db.agents.listAgentNamesByIds(token.companyId, Array.from(senderIds)).map((row) => [row.id, row.name]))
? new Map(db.core.agents.listAgentNamesByIds(token.companyId, Array.from(senderIds)).map((row) => [row.id, row.name]))
: new Map<string, string>();
// Recent outputs the AGENT itself produced — closes the
@@ -59,10 +59,10 @@ export function registerAgentStandupRoute(server: AgentApiServer): void {
// surface keeps the briefing readable.
const RECENT_OUTPUT_LIMIT = 20;
const myTaskIds = new Set(myTasks.map((t) => t.id));
const recentDocuments = db.documentsMod.listDocuments(token.companyId)
const recentDocuments = db.core.documents.listDocuments(token.companyId)
.filter((doc) => doc.authorAgentId === token.agentId)
.slice(0, RECENT_OUTPUT_LIMIT);
const recentWorkProducts = db.documentsMod.listWorkProductsForCompany(token.companyId)
const recentWorkProducts = db.core.documents.listWorkProductsForCompany(token.companyId)
.filter((wp) => wp.taskId !== null && myTaskIds.has(wp.taskId))
.slice(0, RECENT_OUTPUT_LIMIT);
@@ -71,7 +71,7 @@ export function registerAgentStandupRoute(server: AgentApiServer): void {
...myTasks.map<[string, string]>((t) => [t.id, t.title]),
...reportTasks.map<[string, string]>((t) => [t.id, t.title]),
]);
const socialAccounts = db.social.listSocialAccounts(token.companyId);
const socialAccounts = db.core.social.listSocialAccounts(token.companyId);
server.json(res, 200, {
agent: { id: agent.id, name: agent.name, role: agent.role, status: agent.status },
+16 -16
View File
@@ -24,9 +24,9 @@ export function registerAgentRoutes(server: AgentApiServer) {
const callbacks = server.callbacks;
const onDomainChanged = server.onDomainChanged;
server.addRoute("GET", "/api/agents/me", (_req, res, _params, token) => {
const agent = db.entityCrud.getAgent(token.agentId);
const chainOfCommand = db.agents.getChainOfCommand(token.agentId);
const directReports = db.agents.getDirectReports(token.agentId, token.companyId);
const agent = db.core.entity.getAgent(token.agentId);
const chainOfCommand = db.core.agents.getChainOfCommand(token.agentId);
const directReports = db.core.agents.getDirectReports(token.agentId, token.companyId);
server.json(res, 200, { agent, chainOfCommand, directReports });
});
@@ -36,7 +36,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
// and the standup module is registered separately in api-server/index.ts.
server.addRoute("GET", "/api/agents/me/metrics", (_req, res, _params, token) => {
const companyMetrics = db.company.getCompanyMetrics(token.companyId, 30);
const companyMetrics = db.core.company.getCompanyMetrics(token.companyId, 30);
const agentMetric = companyMetrics.agentMetrics.find(m => m.agentId === token.agentId);
if (!agentMetric) {
server.json(res, 404, { error: "Metrics not found" });
@@ -47,12 +47,12 @@ export function registerAgentRoutes(server: AgentApiServer) {
server.addRoute("GET", "/api/agents/:agentId/metrics", (_req, res, params, token) => {
const agentId = requireParam(params, "agentId");
const agent = db.entityCrud.getAgent(agentId);
const agent = db.core.entity.getAgent(agentId);
if (!agent || agent.companyId !== token.companyId) {
server.json(res, 404, { error: "Agent not found" });
return;
}
const companyMetrics = db.company.getCompanyMetrics(token.companyId, 30);
const companyMetrics = db.core.company.getCompanyMetrics(token.companyId, 30);
const agentMetric = companyMetrics.agentMetrics.find((metric) => metric.agentId === agentId);
if (!agentMetric) {
server.json(res, 404, { error: "Metrics not found" });
@@ -64,7 +64,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
server.addRoute("GET", "/api/agents/:agentId", (_req, res, params, token) => {
let agent;
try {
agent = db.entityCrud.getAgent(requireParam(params, "agentId"));
agent = db.core.entity.getAgent(requireParam(params, "agentId"));
} catch (err) {
log.warn(`[api/agents] getAgent failed:`, err instanceof Error ? err.message : String(err));
server.json(res, 404, { error: "Agent not found" });
@@ -74,12 +74,12 @@ export function registerAgentRoutes(server: AgentApiServer) {
server.json(res, 404, { error: "Agent not found" });
return;
}
const directReports = db.agents.getDirectReports(agent.id, token.companyId);
const directReports = db.core.agents.getDirectReports(agent.id, token.companyId);
const reportsTo = agent.reportsTo;
const manager = reportsTo
? (() => {
try {
return db.entityCrud.getAgent(reportsTo);
return db.core.entity.getAgent(reportsTo);
} catch (error) {
log.warn(`[api/agents] manager lookup failed for ${reportsTo}: ${error instanceof Error ? error.message : String(error)}`);
return null;
@@ -98,7 +98,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const agents = db.agents.listAgentsForApi(params.companyId);
const agents = db.core.agents.listAgentsForApi(params.companyId);
server.json(res, 200, agents);
});
@@ -183,14 +183,14 @@ export function registerAgentRoutes(server: AgentApiServer) {
resolvedReportsTo &&
resolvedReportsTo !== token.agentId &&
!canManageOrganization(db, companyId, token.agentId) &&
!db.agents.getChainOfCommand(resolvedReportsTo).some((agent) => agent.id === token.agentId)
!db.core.agents.getChainOfCommand(resolvedReportsTo).some((agent) => agent.id === token.agentId)
) {
server.json(res, 403, { error: "Requested hire must report to you or a manager in your reporting chain." });
return;
}
const connectorRecord = (() => {
try {
return db.connectorsCrud.getConnector(input.connectorId);
return db.core.connectors.getConnector(input.connectorId);
} catch (err) {
log.warn(`[api/agents] getConnector failed for ${input.connectorId}:`, err instanceof Error ? err.message : String(err));
return null;
@@ -207,7 +207,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
}
// Prevent duplicate agents: reject if a non-terminated agent with the same name already exists
const existingAgents = db.agents.listExistingAgentsForHireCheck(companyId);
const existingAgents = db.core.agents.listExistingAgentsForHireCheck(companyId);
const duplicateByName = existingAgents.find(
(a) => a.name.toLowerCase() === input.name.toLowerCase(),
);
@@ -216,7 +216,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
return;
}
// Also check pending hire approvals with the same name to prevent concurrent duplicate requests
const pendingHires = db.approvalsMod.listPendingHireApprovalPayloads(companyId);
const pendingHires = db.core.approvals.listPendingHireApprovalPayloads(companyId);
for (const pending of pendingHires) {
try {
const payload = pending.payloadJson ? JSON.parse(pending.payloadJson) as Record<string, unknown> : {};
@@ -234,7 +234,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
const managerLabel = resolvedReportsTo
? (() => {
try {
return db.entityCrud.getAgent(resolvedReportsTo).name;
return db.core.entity.getAgent(resolvedReportsTo).name;
} catch (err) {
log.warn(`[api/agents] getAgent failed for manager ${resolvedReportsTo}:`, err instanceof Error ? err.message : String(err));
return resolvedReportsTo;
@@ -283,7 +283,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
return;
}
db.activityMod.addActivity({
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "agent.hire_requested",
+18 -18
View File
@@ -74,7 +74,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
// Reject the request at the API boundary so the model cannot
// circumvent the ordering by resubmitting.
if (input.type === "approve_ceo_strategy") {
const companyHireApprovals = db.approvalsMod.listCompanyApprovalsByType(companyId, "hire_agent");
const companyHireApprovals = db.core.approvals.listCompanyApprovalsByType(companyId, "hire_agent");
if (companyHireApprovals.length === 0) {
server.json(res, 409, {
error: "approve_ceo_strategy requires at least one hire_agent approval to exist first. Submit the intended hires, then file the strategy.",
@@ -82,7 +82,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
});
return;
}
const existingStrategy = db.approvalsMod.listCompanyApprovalsByType(companyId, "approve_ceo_strategy")
const existingStrategy = db.core.approvals.listCompanyApprovalsByType(companyId, "approve_ceo_strategy")
.find((a) => a.state === "pending" || a.state === "approved");
if (existingStrategy) {
server.json(res, 409, {
@@ -117,7 +117,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
let id: string;
try {
id = db.approvalsMod.requestApproval({
id = db.core.approvals.requestApproval({
companyId,
type: input.type,
relatedTaskId: input.relatedTaskId ?? null,
@@ -132,7 +132,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
return;
}
db.activityMod.addActivity({
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "approval.created",
@@ -186,7 +186,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
return;
}
const statuses = parsedQuery.data.status?.split(",").filter(Boolean) ?? null;
const approvals = db.approvalsMod.listApprovalsForApi(companyId, {
const approvals = db.core.approvals.listApprovalsForApi(companyId, {
requestedByAgentId: parsedQuery.data.requestedByAgentId,
relatedTaskId: parsedQuery.data.relatedTaskId,
statuses,
@@ -195,7 +195,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
});
server.addRoute("GET", "/api/approvals/:approvalId", (_req, res, params, token) => {
const approval = db.approvalsMod.findApprovalById(requireParam(params, "approvalId"));
const approval = db.core.approvals.findApprovalById(requireParam(params, "approvalId"));
if (!approval || approval.companyId !== token.companyId) {
server.json(res, 404, { error: "Approval not found" });
return;
@@ -209,28 +209,28 @@ export function registerApprovalRoutes(server: AgentApiServer) {
server.addRoute("GET", "/api/approvals/:approvalId/comments", (_req, res, params, token) => {
const approvalId = requireParam(params, "approvalId");
const approval = db.approvalsMod.findApprovalById(approvalId);
const approval = db.core.approvals.findApprovalById(approvalId);
if (!approval) { server.json(res, 404, { error: "Approval not found" }); return; }
if (approval.companyId !== token.companyId) { server.json(res, 403, { error: "Company mismatch" }); return; }
const comments = db.approvalsMod.listApprovalComments(approvalId, approval.companyId);
const comments = db.core.approvals.listApprovalComments(approvalId, approval.companyId);
server.json(res, 200, comments);
});
server.addRoute("POST", "/api/approvals/:approvalId/comments", (_req, res, params, token, body) => {
const approval = db.approvalsMod.findApprovalById(requireParam(params, "approvalId"));
const approval = db.core.approvals.findApprovalById(requireParam(params, "approvalId"));
if (!approval) { server.json(res, 404, { error: "Approval not found" }); return; }
if (approval.companyId !== token.companyId) { server.json(res, 403, { error: "Company mismatch" }); return; }
const data = body as Record<string, unknown>;
const commentBody = typeof data.body === "string" ? data.body.trim() : "";
if (!commentBody) { server.json(res, 400, { error: "Comment body is required" }); return; }
const commentId = db.approvalsMod.addApprovalComment({
const commentId = db.core.approvals.addApprovalComment({
companyId: approval.companyId,
approvalId: approval.id,
authorAgentId: token.agentId ?? null,
body: commentBody,
});
// Wake mentioned agents in comment
const mentionedIds = db.agents.findMentionedAgentIds(approval.companyId, commentBody);
const mentionedIds = db.core.agents.findMentionedAgentIds(approval.companyId, commentBody);
for (const mentionedId of mentionedIds) {
if (mentionedId !== token.agentId) {
onWakeAgent(mentionedId, approval.companyId, "approval_comment_mentioned");
@@ -241,7 +241,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
});
server.addRoute("POST", "/api/approvals/:approvalId/resubmit", (_req, res, params, token) => {
const approval = db.approvalsMod.findApprovalById(requireParam(params, "approvalId"));
const approval = db.core.approvals.findApprovalById(requireParam(params, "approvalId"));
if (!approval) { server.json(res, 404, { error: "Approval not found" }); return; }
if (approval.companyId !== token.companyId) { server.json(res, 403, { error: "Company mismatch" }); return; }
if (approval.state !== "revision_requested") {
@@ -252,34 +252,34 @@ export function registerApprovalRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Only the requesting agent can resubmit this approval" });
return;
}
db.approvalsMod.resubmitApproval(approval.id, approval.companyId);
db.core.approvals.resubmitApproval(approval.id, approval.companyId);
onDomainChanged();
server.json(res, 200, { resubmitted: true });
});
server.addRoute("GET", "/api/approvals/:approvalId/tasks", (_req, res, params, token) => {
const approvalId = requireParam(params, "approvalId");
const approval = db.approvalsMod.findApprovalById(approvalId);
const approval = db.core.approvals.findApprovalById(approvalId);
if (!approval) { server.json(res, 404, { error: "Approval not found" }); return; }
if (approval.companyId !== token.companyId) { server.json(res, 403, { error: "Company mismatch" }); return; }
const taskIds = db.approvalsMod.listTasksForApproval(approvalId);
const taskIds = db.core.approvals.listTasksForApproval(approvalId);
server.json(res, 200, taskIds);
});
server.addRoute("POST", "/api/approvals/:approvalId/tasks", (_req, res, params, token, body) => {
const approvalId = requireParam(params, "approvalId");
const approval = db.approvalsMod.findApprovalById(approvalId);
const approval = db.core.approvals.findApprovalById(approvalId);
if (!approval) { server.json(res, 404, { error: "Approval not found" }); return; }
if (approval.companyId !== token.companyId) { server.json(res, 403, { error: "Company mismatch" }); return; }
const data = body as Record<string, unknown>;
const taskIds = Array.isArray(data.taskIds) ? data.taskIds.filter((id): id is string => typeof id === "string") : [];
if (taskIds.length === 0) { server.json(res, 400, { error: "taskIds array is required" }); return; }
for (const taskId of taskIds) {
if (!db.settings.belongsToCompany("tasks", taskId, token.companyId)) {
if (!db.core.settings.belongsToCompany("tasks", taskId, token.companyId)) {
server.json(res, 400, { error: `Task ${taskId} does not belong to this company` }); return;
}
}
db.approvalsMod.linkManyTasksToApproval(approvalId, taskIds, token.companyId, token.agentId ?? null);
db.core.approvals.linkManyTasksToApproval(approvalId, taskIds, token.companyId, token.agentId ?? null);
onDomainChanged();
server.json(res, 200, { linked: taskIds.length });
});
+26 -26
View File
@@ -71,15 +71,15 @@ export function registerFileRoutes(server: AgentApiServer) {
const reviewerAgentId = data.reviewerAgentId ?? null;
const projectId = data.projectId ?? null;
const goalId = data.goalId ?? null;
if (reviewerAgentId && !db.settings.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
if (reviewerAgentId && !db.core.settings.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
server.json(res, 400, { error: "Reviewer agent does not belong to the current company" });
return;
}
if (projectId && !db.settings.belongsToCompany("projects", projectId, token.companyId)) {
if (projectId && !db.core.settings.belongsToCompany("projects", projectId, token.companyId)) {
server.json(res, 400, { error: "Project does not belong to the current company" });
return;
}
if (goalId && !db.settings.belongsToCompany("goals", goalId, token.companyId)) {
if (goalId && !db.core.settings.belongsToCompany("goals", goalId, token.companyId)) {
server.json(res, 400, { error: "Goal does not belong to the current company" });
return;
}
@@ -114,7 +114,7 @@ export function registerFileRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const docs = db.documentsMod.listDocuments(token.companyId);
const docs = db.core.documents.listDocuments(token.companyId);
server.json(res, 200, docs);
});
@@ -128,7 +128,7 @@ export function registerFileRoutes(server: AgentApiServer) {
server.json(res, 400, { error: "Missing documentId" });
return;
}
const doc = db.documentsMod.getDocumentForUpdate(documentId, token.companyId);
const doc = db.core.documents.getDocumentForUpdate(documentId, token.companyId);
if (!doc) {
server.json(res, 404, { error: "Document not found in this company" });
return;
@@ -146,7 +146,7 @@ export function registerFileRoutes(server: AgentApiServer) {
server.json(res, 400, { error: "Missing documentId" });
return;
}
const doc = db.documentsMod.getDocumentForUpdate(documentId, token.companyId);
const doc = db.core.documents.getDocumentForUpdate(documentId, token.companyId);
if (!doc) {
server.json(res, 404, { error: "Document not found in this company" });
return;
@@ -158,14 +158,14 @@ export function registerFileRoutes(server: AgentApiServer) {
const reviewerAgentId = data.reviewerAgentId !== undefined
? (data.reviewerAgentId ?? null)
: doc.reviewerAgentId;
if (data.reviewerAgentId !== undefined && reviewerAgentId && !db.settings.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
if (data.reviewerAgentId !== undefined && reviewerAgentId && !db.core.settings.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
server.json(res, 400, { error: "Reviewer agent does not belong to the current company" });
return;
}
// Conflict detection: if baseRevisionId provided, verify it matches current
if (data.baseRevisionId !== undefined) {
const currentRevId = db.documentsMod.getDocumentLatestRevisionId(documentId);
const currentRevId = db.core.documents.getDocumentLatestRevisionId(documentId);
if (currentRevId && data.baseRevisionId !== currentRevId) {
server.json(res, 409, { error: "Document was updated by someone else", currentRevisionId: currentRevId });
return;
@@ -182,7 +182,7 @@ export function registerFileRoutes(server: AgentApiServer) {
// Content update → create revision for audit trail
let updatedVersion = doc.version;
if (data.content !== undefined) {
const revision = db.documentsMod.createDocumentRevision({
const revision = db.core.documents.createDocumentRevision({
documentId,
companyId: token.companyId,
body: data.content,
@@ -194,9 +194,9 @@ export function registerFileRoutes(server: AgentApiServer) {
// Field updates (title, reviewer, tags, etc.)
if (data.status !== undefined) {
db.documentsMod.updateDocumentStatus(documentId, token.companyId, data.status);
db.core.documents.updateDocumentStatus(documentId, token.companyId, data.status);
}
db.documentsMod.saveDocument({
db.core.documents.saveDocument({
id: documentId,
companyId: token.companyId,
type: data.type ?? doc.type,
@@ -213,14 +213,14 @@ export function registerFileRoutes(server: AgentApiServer) {
});
onDomainChanged();
server.json(res, 200, { updated: true, latestRevisionId: db.documentsMod.getDocumentLatestRevisionId(documentId) });
server.json(res, 200, { updated: true, latestRevisionId: db.core.documents.getDocumentLatestRevisionId(documentId) });
});
server.addRoute("GET", "/api/companies/:companyId/documents/:documentId/revisions", (_req, res, params, token) => {
if (params.companyId !== token.companyId) { server.json(res, 403, { error: "Company mismatch" }); return; }
const documentId = params.documentId;
if (!documentId) { server.json(res, 400, { error: "Missing documentId" }); return; }
const revisions = db.documentsMod.listDocumentRevisions(documentId, token.companyId);
const revisions = db.core.documents.listDocumentRevisions(documentId, token.companyId);
server.json(res, 200, revisions);
});
@@ -228,9 +228,9 @@ export function registerFileRoutes(server: AgentApiServer) {
server.addRoute("GET", "/api/issues/:issueId/work-products", (_req, res, params, token) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
const products = db.documentsMod.listWorkProductsForTask(task.id, task.companyId);
const products = db.core.documents.listWorkProductsForTask(task.id, task.companyId);
server.json(res, 200, products);
} catch (error) {
log.warn(`[api/work-products] list failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
@@ -240,12 +240,12 @@ export function registerFileRoutes(server: AgentApiServer) {
server.addRoute("POST", "/api/issues/:issueId/work-products", (_req, res, params, token, body) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
const parsed = createWorkProductSchema.safeParse(body);
if (!parsed.success) { server.json(res, 400, { error: "Invalid input", details: parsed.error.flatten() }); return; }
const data = parsed.data;
const id = db.documentsMod.createWorkProduct({
const id = db.core.documents.createWorkProduct({
companyId: task.companyId,
taskId: task.id,
projectId: data.projectId ?? task.projectId,
@@ -275,7 +275,7 @@ export function registerFileRoutes(server: AgentApiServer) {
if (!wpId) { server.json(res, 400, { error: "Missing workProductId" }); return; }
const parsed = updateWorkProductSchema.safeParse(body);
if (!parsed.success) { server.json(res, 400, { error: "Invalid input", details: parsed.error.flatten() }); return; }
const changes = db.documentsMod.updateWorkProduct(wpId, token.companyId, parsed.data);
const changes = db.core.documents.updateWorkProduct(wpId, token.companyId, parsed.data);
if (changes === 0) { server.json(res, 404, { error: "Work product not found" }); return; }
onDomainChanged();
server.json(res, 200, { updated: true });
@@ -284,7 +284,7 @@ export function registerFileRoutes(server: AgentApiServer) {
server.addRoute("DELETE", "/api/work-products/:workProductId", (_req, res, params, token) => {
const wpId = params.workProductId;
if (!wpId) { server.json(res, 400, { error: "Missing workProductId" }); return; }
const changes = db.documentsMod.deleteWorkProduct(wpId, token.companyId);
const changes = db.core.documents.deleteWorkProduct(wpId, token.companyId);
if (changes === 0) { server.json(res, 404, { error: "Work product not found" }); return; }
onDomainChanged();
server.json(res, 200, { deleted: true });
@@ -294,9 +294,9 @@ export function registerFileRoutes(server: AgentApiServer) {
server.addRoute("GET", "/api/issues/:issueId/documents", (_req, res, params, token) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
const links = db.documentsMod.listDocumentsForTask(task.id, task.companyId);
const links = db.core.documents.listDocumentsForTask(task.id, task.companyId);
server.json(res, 200, links);
} catch (error) {
log.warn(`[api/task-documents] list failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
@@ -306,7 +306,7 @@ export function registerFileRoutes(server: AgentApiServer) {
server.addRoute("PUT", "/api/issues/:issueId/documents/:key", (_req, res, params, token, body) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
const key = String(params.key ?? "").trim().toLowerCase();
if (!key || !/^[a-z0-9][a-z0-9_-]*$/.test(key) || key.length > 64) {
@@ -315,10 +315,10 @@ export function registerFileRoutes(server: AgentApiServer) {
const parsed = linkDocumentSchema.safeParse(body);
if (!parsed.success) { server.json(res, 400, { error: "Invalid input", details: parsed.error.flatten() }); return; }
const documentId = parsed.data.documentId;
if (!db.settings.belongsToCompany("documents", documentId, token.companyId)) {
if (!db.core.settings.belongsToCompany("documents", documentId, token.companyId)) {
server.json(res, 400, { error: "Document does not belong to this company" }); return;
}
const linkId = db.documentsMod.linkDocumentToTask(task.id, documentId, task.companyId, key);
const linkId = db.core.documents.linkDocumentToTask(task.id, documentId, task.companyId, key);
onDomainChanged();
server.json(res, 200, { id: linkId, key });
} catch (error) {
@@ -329,10 +329,10 @@ export function registerFileRoutes(server: AgentApiServer) {
server.addRoute("DELETE", "/api/issues/:issueId/documents/:key", (_req, res, params, token) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
const key = String(params.key ?? "").trim().toLowerCase();
db.documentsMod.unlinkDocumentFromTask(task.id, key, task.companyId);
db.core.documents.unlinkDocumentFromTask(task.id, key, task.companyId);
onDomainChanged();
server.json(res, 200, { unlinked: true });
} catch (error) {
+7 -7
View File
@@ -33,7 +33,7 @@ export function registerMeetingRoutes(server: AgentApiServer) {
try {
const parsedParticipants = JSON.parse(input.participantAgentIds) as string[];
for (const agentId of parsedParticipants) {
if (typeof agentId !== "string" || !db.settings.belongsToCompany("agents", agentId, token.companyId)) {
if (typeof agentId !== "string" || !db.core.settings.belongsToCompany("agents", agentId, token.companyId)) {
server.json(res, 400, { error: "Meeting participants must belong to the current company" });
return;
}
@@ -43,7 +43,7 @@ export function registerMeetingRoutes(server: AgentApiServer) {
server.json(res, 400, { error: "participantAgentIds must be a JSON array of agent ids" });
return;
}
const id = db.knowledgeMod.saveMeeting({
const id = db.core.knowledge.saveMeeting({
companyId: token.companyId,
type: input.type,
title: input.title,
@@ -63,13 +63,13 @@ export function registerMeetingRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const meetings = db.knowledgeMod.listMeetings(token.companyId);
const meetings = db.core.knowledge.listMeetings(token.companyId);
server.json(res, 200, meetings);
});
server.addRoute("PATCH", "/api/meetings/:meetingId", (_req, res, params, token, body) => {
const meetingId = requireParam(params, "meetingId");
const existing = db.knowledgeMod.getMeeting(meetingId, token.companyId);
const existing = db.core.knowledge.getMeeting(meetingId, token.companyId);
if (!existing) {
server.json(res, 404, { error: "Meeting not found" });
return;
@@ -102,13 +102,13 @@ export function registerMeetingRoutes(server: AgentApiServer) {
return;
}
for (const item of actionItems) {
if (item.assigneeAgentId && !db.settings.belongsToCompany("agents", item.assigneeAgentId, token.companyId)) {
if (item.assigneeAgentId && !db.core.settings.belongsToCompany("agents", item.assigneeAgentId, token.companyId)) {
server.json(res, 400, { error: "Meeting action item assignees must belong to the current company" });
return;
}
}
}
db.knowledgeMod.saveMeeting({
db.core.knowledge.saveMeeting({
id: meetingId,
companyId: token.companyId,
type: data.type ?? "department_sync",
@@ -133,7 +133,7 @@ export function registerMeetingRoutes(server: AgentApiServer) {
);
continue;
}
db.tasks.saveTask({
db.core.tasks.saveTask({
companyId: token.companyId,
title: item.title,
description: item.description ?? `Action item from meeting: ${data.title ?? existing.title}`,
+11 -11
View File
@@ -20,13 +20,13 @@ export function registerMessageRoutes(server: AgentApiServer) {
return;
}
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) {
server.json(res, 404, { error: "Task not found" });
return;
}
const agent = db.entityCrud.getAgent(token.agentId);
const comment = db.activityMod.addComment({
const agent = db.core.entity.getAgent(token.agentId);
const comment = db.core.activity.addComment({
companyId: task.companyId,
taskId: task.id,
authorAgentId: token.agentId,
@@ -44,14 +44,14 @@ export function registerMessageRoutes(server: AgentApiServer) {
wokenForComment.add(task.assigneeAgentId);
}
const chain = db.agents.getChainOfCommand(token.agentId);
const chain = db.core.agents.getChainOfCommand(token.agentId);
if (chain.length > 0 && chain[0].id !== token.agentId && !wokenForComment.has(chain[0].id)) {
onWakeAgent(chain[0].id, task.companyId, "comment");
wokenForComment.add(chain[0].id);
}
// @mention detection: wake any mentioned agents not already woken
const mentionedIds = db.agents.findMentionedAgentIds(task.companyId, input.body);
const mentionedIds = db.core.agents.findMentionedAgentIds(task.companyId, input.body);
for (const mentionedId of mentionedIds) {
if (mentionedId !== token.agentId && !wokenForComment.has(mentionedId)) {
onWakeAgent(mentionedId, task.companyId, "comment_mentioned");
@@ -68,7 +68,7 @@ export function registerMessageRoutes(server: AgentApiServer) {
server.addRoute("GET", "/api/issues/:issueId/comments", (_req, res, params, token) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) {
server.json(res, 404, { error: "Task not found" });
return;
@@ -78,7 +78,7 @@ export function registerMessageRoutes(server: AgentApiServer) {
server.json(res, 404, { error: "Task not found" });
return;
}
const comments = db.activityMod.listComments(requireParam(params, "issueId"));
const comments = db.core.activity.listComments(requireParam(params, "issueId"));
server.json(res, 200, comments);
});
@@ -142,7 +142,7 @@ export function registerMessageRoutes(server: AgentApiServer) {
return;
}
const messages = db.messages.listAgentMessages(companyId, {
const messages = db.core.messages.listAgentMessages(companyId, {
agentId: token.agentId,
channel: channelParam ?? undefined,
channelTargetId: channelTargetId && channelTargetId.length > 0 ? channelTargetId : undefined,
@@ -158,12 +158,12 @@ export function registerMessageRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const message = db.messages.getAgentMessage(requireParam(params, "messageId"), companyId);
const message = db.core.messages.getAgentMessage(requireParam(params, "messageId"), companyId);
if (!message) {
server.json(res, 404, { error: "Message not found" });
return;
}
const visibleToAgent = db.messages.listAgentMessages(companyId, {
const visibleToAgent = db.core.messages.listAgentMessages(companyId, {
agentId: token.agentId,
messageId: message.id,
limit: 1,
@@ -172,7 +172,7 @@ export function registerMessageRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "This message is not visible to the current agent" });
return;
}
db.messages.markMessageReadForReader(requireParam(params, "messageId"), companyId, token.agentId);
db.core.messages.markMessageReadForReader(requireParam(params, "messageId"), companyId, token.agentId);
onDomainChanged();
server.json(res, 200, { ok: true });
});
+14 -14
View File
@@ -34,7 +34,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
const input = parsed.data;
const account = db.social.getSocialAccount(input.socialAccountId, companyId);
const account = db.core.social.getSocialAccount(input.socialAccountId, companyId);
if (!account) {
server.json(res, 404, { error: "Social account not found" });
return;
@@ -42,7 +42,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
const postActions = ["post", "reply", "dm"];
if (account.requireApproval && postActions.includes(input.actionType)) {
const approvalId = db.approvalsMod.requestApproval({
const approvalId = db.core.approvals.requestApproval({
companyId,
type: "dangerous_command",
relatedTaskId: null,
@@ -51,7 +51,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
impactSummary: `Will ${input.actionType} on ${account.displayName || account.accountName}'s ${account.platform} account. Content will be publicly visible.`,
});
const actionId = db.social.saveBrowserAction({
const actionId = db.core.social.saveBrowserAction({
companyId,
socialAccountId: input.socialAccountId,
agentId: token.agentId,
@@ -61,7 +61,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
approvalId,
});
db.activityMod.addActivity({
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "browser.action_pending_approval",
@@ -75,7 +75,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
return;
}
const actionId = db.social.saveBrowserAction({
const actionId = db.core.social.saveBrowserAction({
companyId,
socialAccountId: input.socialAccountId,
agentId: token.agentId,
@@ -84,7 +84,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
status: "queued",
});
db.activityMod.addActivity({
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "browser.action_queued",
@@ -108,7 +108,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const accounts = db.social.listSocialAccounts(requireParam(params, "companyId"));
const accounts = db.core.social.listSocialAccounts(requireParam(params, "companyId"));
const sanitized = accounts.map(a => ({
id: a.id,
platform: a.platform,
@@ -134,7 +134,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
return;
}
const account = db.social.getSocialAccount(parsed.data.socialAccountId, companyId);
const account = db.core.social.getSocialAccount(parsed.data.socialAccountId, companyId);
if (!account) {
server.json(res, 404, { error: "Social account not found" });
return;
@@ -142,7 +142,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
const contentPreview = parsed.data.content.slice(0, 120) + (parsed.data.content.length > 120 ? "..." : "");
const approvalId = db.approvalsMod.requestApproval({
const approvalId = db.core.approvals.requestApproval({
companyId,
requestedByAgentId: token.agentId,
type: "social_post",
@@ -171,7 +171,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
const status = url.searchParams.get("status") ?? undefined;
const limit = Number(url.searchParams.get("limit") || 50);
const actions = db.social.listBrowserActions(requireParam(params, "companyId"), { socialAccountId, status, limit });
const actions = db.core.social.listBrowserActions(requireParam(params, "companyId"), { socialAccountId, status, limit });
server.json(res, 200, actions);
});
@@ -198,7 +198,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
}
const input = parsed.data;
const id = db.knowledgeMod.saveKnowledgeEntry({
const id = db.core.knowledge.saveKnowledgeEntry({
companyId: token.companyId,
category: input.category,
topic: input.topic,
@@ -219,7 +219,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const entries = db.knowledgeMod.listKnowledgeEntries(token.companyId);
const entries = db.core.knowledge.listKnowledgeEntries(token.companyId);
server.json(res, 200, entries);
});
@@ -231,7 +231,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const skills = db.skills.listCompanySkills(companyId);
const skills = db.core.skills.listCompanySkills(companyId);
server.json(res, 200, skills.map((s) => ({
id: s.id,
name: s.name,
@@ -244,7 +244,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
});
server.addRoute("GET", "/api/skills/:skillId", (_req, res, params, token) => {
const skill = db.skills.getCompanySkill(token.companyId, requireParam(params, "skillId"));
const skill = db.core.skills.getCompanySkill(token.companyId, requireParam(params, "skillId"));
if (!skill) {
server.json(res, 404, { error: "Skill not found" });
return;
+3 -3
View File
@@ -16,7 +16,7 @@ function parsePositiveInt(value: string | null, fallback: number) {
}
function resolveAuthorizedRun(server: AgentApiServer, token: TokenPayload, runId: string) {
const runState = server.db.runs.getRunAuthState(runId);
const runState = server.db.core.runs.getRunAuthState(runId);
if (!runState || runState.companyId !== token.companyId || runState.agentId !== token.agentId) {
return null;
}
@@ -40,7 +40,7 @@ export function registerRunRoutes(server: AgentApiServer) {
const url = new URL(req.url ?? "/", `http://127.0.0.1:${server.port}`);
const offset = parsePositiveInt(url.searchParams.get("offset"), 0);
const limit = Math.min(parsePositiveInt(url.searchParams.get("limit"), DEFAULT_EVENT_LIMIT), MAX_EVENT_LIMIT);
const events = server.db.runs.listRunEvents(runId, token.companyId, { offset, limit });
const events = server.db.core.runs.listRunEvents(runId, token.companyId, { offset, limit });
server.json(res, 200, { events, nextOffset: offset + events.length });
});
@@ -66,7 +66,7 @@ export function registerRunRoutes(server: AgentApiServer) {
const flushPendingEvents = () => {
while (true) {
const events = server.db.runs.listRunEventsAfter(runId, token.companyId, cursor, SSE_BATCH_LIMIT);
const events = server.db.core.runs.listRunEventsAfter(runId, token.companyId, cursor, SSE_BATCH_LIMIT);
if (events.length === 0) return;
for (const event of events) {
writeSse(res, "run-event", event);
+17 -17
View File
@@ -39,17 +39,17 @@ export function registerTaskRoutes(server: AgentApiServer) {
const statuses = statusFilter ? statusFilter.split(",") : ["todo", "in_progress", "blocked"];
if (assigneeAgentId) {
const tasks = db.tasks.listAgentTasks(assigneeAgentId, companyId, statuses);
const tasks = db.core.tasks.listAgentTasks(assigneeAgentId, companyId, statuses);
server.json(res, 200, tasks);
} else {
const tasks = db.tasks.listTasksByStatuses(companyId, statuses);
const tasks = db.core.tasks.listTasksByStatuses(companyId, statuses);
server.json(res, 200, tasks);
}
});
server.addRoute("GET", "/api/issues/:issueId", (_req, res, params, token) => {
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) {
server.json(res, 404, { error: "Task not found" });
return;
@@ -74,7 +74,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
}
let task;
try {
task = db.entityCrud.getTask(requireParam(params, "issueId"));
task = db.core.entity.getTask(requireParam(params, "issueId"));
} catch (err) {
log.warn(`[api/tasks] getTask failed for checkout:`, err instanceof Error ? err.message : String(err));
server.json(res, 404, { error: "Task not found" });
@@ -89,7 +89,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
return;
}
const previousStatus = task.status;
const success = db.tasks.checkoutTask(task.id, token.runId);
const success = db.core.tasks.checkoutTask(task.id, token.runId);
if (!success) {
server.json(res, 409, { error: "Task cannot be checked out — already assigned or not in valid status" });
return;
@@ -109,7 +109,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
const update = parsedUpdate.data;
try {
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
const task = db.core.entity.getTask(requireParam(params, "issueId"));
if (task.companyId !== token.companyId) {
server.json(res, 404, { error: "Task not found" });
return;
@@ -133,10 +133,10 @@ export function registerTaskRoutes(server: AgentApiServer) {
return;
}
const actorAgent = db.entityCrud.getAgent(token.agentId);
const actorAgent = db.core.entity.getAgent(token.agentId);
let reviewRequest: { reviewerAgentName: string; documents: Array<{ id: string; title: string } & Record<string, unknown>> } | null = null;
if (effectiveStatus === "done" && task.requiresUserReview) {
const docs = db.documentsMod.listImportantDocsForReview({
const docs = db.core.documents.listImportantDocsForReview({
companyId: task.companyId,
types: IMPORTANT_DOC_TYPES,
authorAgentId: task.assigneeAgentId ?? null,
@@ -146,7 +146,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
reviewRequest = { reviewerAgentName: actorAgent.name, documents: docs };
}
const updateResult = db.tasks.updateTaskWithReviewSideEffects({
const updateResult = db.core.tasks.updateTaskWithReviewSideEffects({
taskId: task.id,
companyId: task.companyId,
actorAgentId: token.agentId,
@@ -183,7 +183,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
if (update.status && ["done", "in_review"].includes(newStatus)) {
if (updateResult.parentId) {
try {
const parentTask = db.entityCrud.getTask(updateResult.parentId);
const parentTask = db.core.entity.getTask(updateResult.parentId);
if (parentTask.assigneeAgentId && parentTask.assigneeAgentId !== token.agentId) {
onWakeAgent(parentTask.assigneeAgentId, task.companyId, "subtask_completed");
}
@@ -197,7 +197,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
// This is not a subtask — use a distinct wake reason so the
// reviewer prompt does not misframe the work as "a subtask
// you delegated".
const chain = db.agents.getChainOfCommand(token.agentId);
const chain = db.core.agents.getChainOfCommand(token.agentId);
if (chain.length > 0) {
onWakeAgent(chain[0].id, task.companyId, "task_review_requested");
}
@@ -205,7 +205,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
}
if (update.status && newStatus === "blocked") {
const chain = db.agents.getChainOfCommand(token.agentId);
const chain = db.core.agents.getChainOfCommand(token.agentId);
if (chain.length > 0) {
onWakeAgent(chain[0].id, task.companyId, "report_blocked");
}
@@ -225,7 +225,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
onWakeAgent(task.assigneeAgentId, task.companyId, "comment");
wokenForComment.add(task.assigneeAgentId);
}
const chain = db.agents.getChainOfCommand(token.agentId);
const chain = db.core.agents.getChainOfCommand(token.agentId);
if (chain.length > 0 && chain[0].id !== token.agentId && !wokenForComment.has(chain[0].id)) {
onWakeAgent(chain[0].id, task.companyId, "comment");
}
@@ -297,7 +297,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
let id: string;
try {
id = db.tasks.saveTask({
id = db.core.tasks.saveTask({
companyId,
title: input.title,
description: input.description ?? "",
@@ -317,12 +317,12 @@ export function registerTaskRoutes(server: AgentApiServer) {
// Auto-infer task_type from assignee's department
if (input.assigneeAgentId) {
const assignee = db.entityCrud.getAgent(input.assigneeAgentId);
const assignee = db.core.entity.getAgent(input.assigneeAgentId);
const inferredType = inferTaskType(assignee.department);
db.tasks.setTaskType(id, inferredType);
db.core.tasks.setTaskType(id, inferredType);
}
db.activityMod.addActivity({
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "task.created",
+13 -13
View File
@@ -35,7 +35,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
return;
}
const id = db.entityCrud.saveProject({
const id = db.core.entity.saveProject({
companyId,
name: input.name,
description: input.description ?? "",
@@ -45,7 +45,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
targetDate: input.targetDate ?? null,
});
db.activityMod.addActivity({
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "project.created",
@@ -79,7 +79,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
return;
}
const existing = db.entityCrud.getProjectForUpdate(projectId, token.companyId);
const existing = db.core.entity.getProjectForUpdate(projectId, token.companyId);
if (!existing) {
server.json(res, 404, { error: "Project not found" });
return;
@@ -91,7 +91,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
}
try {
db.entityCrud.saveProject({
db.core.entity.saveProject({
id: projectId,
companyId: token.companyId,
name: parsed.data.name ?? existing.name,
@@ -135,8 +135,8 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
return;
}
const id = db.entityCrud.saveGoal(input);
db.activityMod.addActivity({
const id = db.core.entity.saveGoal(input);
db.core.activity.addActivity({
companyId,
actor: token.agentId,
action: "goal.created",
@@ -167,7 +167,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
return;
}
const existing = db.entityCrud.getGoalForUpdate(goalId, token.companyId);
const existing = db.core.entity.getGoalForUpdate(goalId, token.companyId);
if (!existing) {
server.json(res, 404, { error: "Goal not found" });
return;
@@ -179,7 +179,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
}
try {
db.entityCrud.saveGoal({
db.core.entity.saveGoal({
id: goalId,
companyId: token.companyId,
title: parsed.data.title ?? existing.title,
@@ -200,7 +200,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const goals = db.entityCrud.listGoals(params.companyId);
const goals = db.core.entity.listGoals(params.companyId);
server.json(res, 200, goals);
});
@@ -209,7 +209,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const projects = db.entityCrud.listProjects(params.companyId);
const projects = db.core.entity.listProjects(params.companyId);
server.json(res, 200, projects);
});
@@ -219,7 +219,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const sprints = db.knowledgeMod.listSprints(companyId);
const sprints = db.core.knowledge.listSprints(companyId);
server.json(res, 200, sprints);
});
@@ -231,7 +231,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
}
const data = body as Record<string, unknown>;
try {
const id = db.knowledgeMod.saveSprint({
const id = db.core.knowledge.saveSprint({
companyId,
name: String(data.name ?? "Sprint"),
goal: String(data.goal ?? ""),
@@ -256,7 +256,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
server.json(res, 403, { error: "Company mismatch" });
return;
}
const { agents, tasks, recentActivity } = db.company.getDashboardSnapshot(companyId);
const { agents, tasks, recentActivity } = db.core.company.getDashboardSnapshot(companyId);
const tasksByStatus: Record<string, number> = {};
for (const t of tasks) {
+2 -2
View File
@@ -230,7 +230,7 @@ export class AgentApiServer {
if (typeof claimedRunId !== "string" || claimedRunId.trim() !== token.runId) {
return { ok: false, status: 401, error: "Missing or mismatched X-Agent-Company-Run-Id header" };
}
const runState = this._db.runs.getRunAuthState(token.runId);
const runState = this._db.core.runs.getRunAuthState(token.runId);
if (!runState || runState.companyId !== token.companyId || runState.agentId !== token.agentId) {
return { ok: false, status: 403, error: "Token references an unknown or mismatched run" };
}
@@ -362,7 +362,7 @@ export class AgentApiServer {
companyId: string,
refs: Array<{ id: string | null | undefined; table: "agents" | "goals" | "projects" | "tasks" | "workspaces" | "approvals"; label: string }>,
) {
const invalid = refs.find((ref) => ref.id && !this._db.settings.belongsToCompany(ref.table, ref.id, companyId));
const invalid = refs.find((ref) => ref.id && !this._db.core.settings.belongsToCompany(ref.table, ref.id, companyId));
if (!invalid) return false;
this.json(res, 422, { error: `${invalid.label} does not belong to the current company` });
return true;