Remove final AppDatabase pass-through methods with ESLint guard (C1 part 3/3)
Migrate all remaining pass-through call sites (social, skills, budget,
entityCrud, documents, knowledge, automation, wakeup, backup, threads,
settings, snapshot, connectors, workspaces, activity) to their owning
domain modules. `AppDatabase` now carries only three methods:
- createHireRequest (multi-module composite: agents + approvalsMod)
- rollbackConfigRevision (multi-module composite: documents + entityCrud)
- queryAll (raw-SQL escape hatch, @internal)
The vault/env-binding infrastructure previously passed argument-by-
argument into `entityCrud.saveSecret`/`resolveSecretEnv` now binds at
module construction, letting callers invoke `db.entityCrud.saveSecret({...})`
without carrying vault plumbing.
Structural types that narrowed AppDatabase to a bag of flat methods
(`ConnectorModelPolicyDeps` callers, `CapabilityMatchDb`, test mocks in
budget-enforcement / budget-incidents / task-quality-gates /
failure-escalation / task-quality-gates-sweep) are reshaped to the new
namespace. `connectorPolicyDepsFromDb` replaces the old pattern of
handing the whole AppDatabase to `validateConnectorModelSelection`.
A new ESLint rule in eslint.config.mjs blocks new top-level methods on
AppDatabase so the pass-through layer cannot silently grow back.
`AppDatabase.ts` dropped from 193 lines to 58; `AppDatabaseBase` lost
the 270-line trailing pass-through block.
This commit is contained in:
1 parent
a69fbb053b
commit
118e3d8795
120 files changed
+838
-933
No files matched your search
@@ -95,9 +95,9 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
|
||||
server.json(res, 404, { error: "Agent not found in your company" });
|
||||
return;
|
||||
}
|
||||
const skillIds = db.listAgentSkillAssignments(agentId);
|
||||
const skillIds = db.skills.listAgentSkillAssignments(agentId);
|
||||
const skills = skillIds
|
||||
.map((sid) => db.getCompanySkill(token.companyId, sid))
|
||||
.map((sid) => db.skills.getCompanySkill(token.companyId, sid))
|
||||
.filter((s): s is NonNullable<typeof s> => s != null);
|
||||
server.json(res, 200, skills.map((s) => ({
|
||||
id: s.id,
|
||||
@@ -127,12 +127,12 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
|
||||
server.json(res, 404, { error: "Agent not found in your company" });
|
||||
return;
|
||||
}
|
||||
const skill = db.getCompanySkill(token.companyId, parsed.data.skillId);
|
||||
const skill = db.skills.getCompanySkill(token.companyId, parsed.data.skillId);
|
||||
if (!skill) {
|
||||
server.json(res, 404, { error: "Skill not found in your company" });
|
||||
return;
|
||||
}
|
||||
db.assignSkillToAgent(agentId, parsed.data.skillId);
|
||||
db.skills.assignSkillToAgent(agentId, parsed.data.skillId);
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { ok: true, message: `Skill "${skill.name}" assigned to agent ${agent.name}` });
|
||||
});
|
||||
@@ -151,7 +151,7 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
|
||||
server.json(res, 404, { error: "Agent not found in your company" });
|
||||
return;
|
||||
}
|
||||
db.removeSkillFromAgent(agentId, skillId);
|
||||
db.skills.removeSkillFromAgent(agentId, skillId);
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { ok: true, message: `Skill removed from agent ${agent.name}` });
|
||||
});
|
||||
|
||||
@@ -33,7 +33,7 @@ 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.listRecentTaskComments([...allRelevantTaskIds], twoHoursAgo, 20);
|
||||
const recentComments = db.activityMod.listRecentTaskComments([...allRelevantTaskIds], twoHoursAgo, 20);
|
||||
|
||||
const myPendingApprovals = db.approvalsMod.listAgentPendingApprovals(token.companyId, token.agentId);
|
||||
const myResolvedApprovals = db.approvalsMod.listAgentResolvedApprovals(token.companyId, token.agentId, 5);
|
||||
@@ -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.listDocuments(token.companyId)
|
||||
const recentDocuments = db.documentsMod.listDocuments(token.companyId)
|
||||
.filter((doc) => doc.authorAgentId === token.agentId)
|
||||
.slice(0, RECENT_OUTPUT_LIMIT);
|
||||
const recentWorkProducts = db.listWorkProductsForCompany(token.companyId)
|
||||
const recentWorkProducts = db.documentsMod.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.listSocialAccounts(token.companyId);
|
||||
const socialAccounts = db.social.listSocialAccounts(token.companyId);
|
||||
|
||||
server.json(res, 200, {
|
||||
agent: { id: agent.id, name: agent.name, role: agent.role, status: agent.status },
|
||||
|
||||
@@ -164,7 +164,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
|
||||
}
|
||||
const connectorRecord = (() => {
|
||||
try {
|
||||
return db.getConnector(input.connectorId);
|
||||
return db.connectorsCrud.getConnector(input.connectorId);
|
||||
} catch (err) {
|
||||
log.warn(`[api/agents] getConnector failed for ${input.connectorId}:`, err instanceof Error ? err.message : String(err));
|
||||
return null;
|
||||
@@ -257,7 +257,7 @@ export function registerAgentRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.addActivity({
|
||||
companyId,
|
||||
actor: token.agentId,
|
||||
action: "agent.hire_requested",
|
||||
|
||||
@@ -85,7 +85,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.addActivity({
|
||||
companyId,
|
||||
actor: token.agentId,
|
||||
action: "approval.created",
|
||||
@@ -228,7 +228,7 @@ export function registerApprovalRoutes(server: AgentApiServer) {
|
||||
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.belongsToCompany("tasks", taskId, token.companyId)) {
|
||||
if (!db.settings.belongsToCompany("tasks", taskId, token.companyId)) {
|
||||
server.json(res, 400, { error: `Task ${taskId} does not belong to this company` }); return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
|
||||
if (reviewerAgentId && !db.settings.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
|
||||
server.json(res, 400, { error: "Reviewer agent does not belong to the current company" });
|
||||
return;
|
||||
}
|
||||
if (projectId && !db.belongsToCompany("projects", projectId, token.companyId)) {
|
||||
if (projectId && !db.settings.belongsToCompany("projects", projectId, token.companyId)) {
|
||||
server.json(res, 400, { error: "Project does not belong to the current company" });
|
||||
return;
|
||||
}
|
||||
if (goalId && !db.belongsToCompany("goals", goalId, token.companyId)) {
|
||||
if (goalId && !db.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.listDocuments(token.companyId);
|
||||
const docs = db.documentsMod.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.getDocumentForUpdate(documentId, token.companyId);
|
||||
const doc = db.documentsMod.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.getDocumentForUpdate(documentId, token.companyId);
|
||||
const doc = db.documentsMod.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.belongsToCompany("agents", reviewerAgentId, token.companyId)) {
|
||||
if (data.reviewerAgentId !== undefined && reviewerAgentId && !db.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.getDocumentLatestRevisionId(documentId);
|
||||
const currentRevId = db.documentsMod.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.createDocumentRevision({
|
||||
const revision = db.documentsMod.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.updateDocumentStatus(documentId, token.companyId, data.status);
|
||||
db.documentsMod.updateDocumentStatus(documentId, token.companyId, data.status);
|
||||
}
|
||||
db.saveDocument({
|
||||
db.documentsMod.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.getDocumentLatestRevisionId(documentId) });
|
||||
server.json(res, 200, { updated: true, latestRevisionId: db.documentsMod.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.listDocumentRevisions(documentId, token.companyId);
|
||||
const revisions = db.documentsMod.listDocumentRevisions(documentId, token.companyId);
|
||||
server.json(res, 200, revisions);
|
||||
});
|
||||
|
||||
@@ -230,7 +230,7 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
try {
|
||||
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
|
||||
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
|
||||
const products = db.listWorkProductsForTask(task.id, task.companyId);
|
||||
const products = db.documentsMod.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)}`);
|
||||
@@ -245,7 +245,7 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
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.createWorkProduct({
|
||||
const id = db.documentsMod.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.updateWorkProduct(wpId, token.companyId, parsed.data);
|
||||
const changes = db.documentsMod.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.deleteWorkProduct(wpId, token.companyId);
|
||||
const changes = db.documentsMod.deleteWorkProduct(wpId, token.companyId);
|
||||
if (changes === 0) { server.json(res, 404, { error: "Work product not found" }); return; }
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { deleted: true });
|
||||
@@ -296,7 +296,7 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
try {
|
||||
const task = db.entityCrud.getTask(requireParam(params, "issueId"));
|
||||
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
|
||||
const links = db.listDocumentsForTask(task.id, task.companyId);
|
||||
const links = db.documentsMod.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)}`);
|
||||
@@ -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.belongsToCompany("documents", documentId, token.companyId)) {
|
||||
if (!db.settings.belongsToCompany("documents", documentId, token.companyId)) {
|
||||
server.json(res, 400, { error: "Document does not belong to this company" }); return;
|
||||
}
|
||||
const linkId = db.linkDocumentToTask(task.id, documentId, task.companyId, key);
|
||||
const linkId = db.documentsMod.linkDocumentToTask(task.id, documentId, task.companyId, key);
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { id: linkId, key });
|
||||
} catch (error) {
|
||||
@@ -332,7 +332,7 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
const task = db.entityCrud.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.unlinkDocumentFromTask(task.id, key, task.companyId);
|
||||
db.documentsMod.unlinkDocumentFromTask(task.id, key, task.companyId);
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { unlinked: true });
|
||||
} catch (error) {
|
||||
|
||||
@@ -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.belongsToCompany("agents", agentId, token.companyId)) {
|
||||
if (typeof agentId !== "string" || !db.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.saveMeeting({
|
||||
const id = db.knowledgeMod.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.listMeetings(token.companyId);
|
||||
const meetings = db.knowledgeMod.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.getMeeting(meetingId, token.companyId);
|
||||
const existing = db.knowledgeMod.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.belongsToCompany("agents", item.assigneeAgentId, token.companyId)) {
|
||||
if (item.assigneeAgentId && !db.settings.belongsToCompany("agents", item.assigneeAgentId, token.companyId)) {
|
||||
server.json(res, 400, { error: "Meeting action item assignees must belong to the current company" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
db.saveMeeting({
|
||||
db.knowledgeMod.saveMeeting({
|
||||
id: meetingId,
|
||||
companyId: token.companyId,
|
||||
type: data.type ?? "department_sync",
|
||||
|
||||
@@ -26,7 +26,7 @@ export function registerMessageRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
const agent = db.entityCrud.getAgent(token.agentId);
|
||||
const comment = db.addComment({
|
||||
const comment = db.activityMod.addComment({
|
||||
companyId: task.companyId,
|
||||
taskId: task.id,
|
||||
authorAgentId: token.agentId,
|
||||
@@ -78,7 +78,7 @@ export function registerMessageRoutes(server: AgentApiServer) {
|
||||
server.json(res, 404, { error: "Task not found" });
|
||||
return;
|
||||
}
|
||||
const comments = db.listComments(requireParam(params, "issueId"));
|
||||
const comments = db.activityMod.listComments(requireParam(params, "issueId"));
|
||||
server.json(res, 200, comments);
|
||||
});
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
|
||||
|
||||
const input = parsed.data;
|
||||
|
||||
const account = db.getSocialAccount(input.socialAccountId, companyId);
|
||||
const account = db.social.getSocialAccount(input.socialAccountId, companyId);
|
||||
if (!account) {
|
||||
server.json(res, 404, { error: "Social account not found" });
|
||||
return;
|
||||
@@ -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.saveBrowserAction({
|
||||
const actionId = db.social.saveBrowserAction({
|
||||
companyId,
|
||||
socialAccountId: input.socialAccountId,
|
||||
agentId: token.agentId,
|
||||
@@ -61,7 +61,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
|
||||
approvalId,
|
||||
});
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.addActivity({
|
||||
companyId,
|
||||
actor: token.agentId,
|
||||
action: "browser.action_pending_approval",
|
||||
@@ -75,7 +75,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const actionId = db.saveBrowserAction({
|
||||
const actionId = db.social.saveBrowserAction({
|
||||
companyId,
|
||||
socialAccountId: input.socialAccountId,
|
||||
agentId: token.agentId,
|
||||
@@ -84,7 +84,7 @@ export function registerMiscRoutes(server: AgentApiServer) {
|
||||
status: "queued",
|
||||
});
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.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.listSocialAccounts(requireParam(params, "companyId"));
|
||||
const accounts = db.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.getSocialAccount(parsed.data.socialAccountId, companyId);
|
||||
const account = db.social.getSocialAccount(parsed.data.socialAccountId, companyId);
|
||||
if (!account) {
|
||||
server.json(res, 404, { error: "Social account not found" });
|
||||
return;
|
||||
@@ -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.listBrowserActions(requireParam(params, "companyId"), { socialAccountId, status, limit });
|
||||
const actions = db.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.saveKnowledgeEntry({
|
||||
const id = db.knowledgeMod.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.listKnowledgeEntries(token.companyId);
|
||||
const entries = db.knowledgeMod.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.listCompanySkills(companyId);
|
||||
const skills = db.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.getCompanySkill(token.companyId, requireParam(params, "skillId"));
|
||||
const skill = db.skills.getCompanySkill(token.companyId, requireParam(params, "skillId"));
|
||||
if (!skill) {
|
||||
server.json(res, 404, { error: "Skill not found" });
|
||||
return;
|
||||
|
||||
@@ -127,7 +127,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
// Deliverable review gate: intercept agent trying to advance a flagged task to "done".
|
||||
// This MUST succeed — silently skipping review would let unreviewed work advance.
|
||||
if (update.status === "done" && task.requiresUserReview) {
|
||||
const docs = db.listImportantDocsForReview({
|
||||
const docs = db.documentsMod.listImportantDocsForReview({
|
||||
companyId: task.companyId,
|
||||
types: IMPORTANT_DOC_TYPES,
|
||||
authorAgentId: task.assigneeAgentId ?? null,
|
||||
@@ -152,7 +152,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
db.agents.setHeartbeat(task.assigneeAgentId, false, prodAgent.heartbeatIntervalSec || 120);
|
||||
}
|
||||
}
|
||||
db.addComment({ companyId: task.companyId, taskId: task.id, authorAgentId: null, authorName: "System", body: "Deliverable submitted for board review." });
|
||||
db.activityMod.addComment({ companyId: task.companyId, taskId: task.id, authorAgentId: null, authorName: "System", body: "Deliverable submitted for board review." });
|
||||
update.status = "in_review";
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
|
||||
if (update.comment) {
|
||||
const agent = db.entityCrud.getAgent(token.agentId);
|
||||
db.addComment({
|
||||
db.activityMod.addComment({
|
||||
companyId: task.companyId,
|
||||
taskId: task.id,
|
||||
authorAgentId: token.agentId,
|
||||
@@ -198,7 +198,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
});
|
||||
}
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.addActivity({
|
||||
companyId: task.companyId,
|
||||
actor: token.agentId,
|
||||
action: `task.${update.status ? "status_changed" : "updated"}`,
|
||||
@@ -357,7 +357,7 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
db.tasks.setTaskType(id, inferredType);
|
||||
}
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.addActivity({
|
||||
companyId,
|
||||
actor: token.agentId,
|
||||
action: "task.created",
|
||||
|
||||
@@ -35,7 +35,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const id = db.saveProject({
|
||||
const id = db.entityCrud.saveProject({
|
||||
companyId,
|
||||
name: input.name,
|
||||
description: input.description ?? "",
|
||||
@@ -45,7 +45,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
|
||||
targetDate: input.targetDate ?? null,
|
||||
});
|
||||
|
||||
db.addActivity({
|
||||
db.activityMod.addActivity({
|
||||
companyId,
|
||||
actor: token.agentId,
|
||||
action: "project.created",
|
||||
@@ -79,7 +79,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existing = db.getProjectForUpdate(projectId, token.companyId);
|
||||
const existing = db.entityCrud.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.saveProject({
|
||||
db.entityCrud.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.saveGoal(input);
|
||||
db.addActivity({
|
||||
const id = db.entityCrud.saveGoal(input);
|
||||
db.activityMod.addActivity({
|
||||
companyId,
|
||||
actor: token.agentId,
|
||||
action: "goal.created",
|
||||
@@ -167,7 +167,7 @@ export function registerWorkGraphRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
const existing = db.getGoalForUpdate(goalId, token.companyId);
|
||||
const existing = db.entityCrud.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.saveGoal({
|
||||
db.entityCrud.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.listGoals(params.companyId);
|
||||
const goals = db.entityCrud.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.listProjects(params.companyId);
|
||||
const projects = db.entityCrud.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.listSprints(companyId);
|
||||
const sprints = db.knowledgeMod.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.saveSprint({
|
||||
const id = db.knowledgeMod.saveSprint({
|
||||
companyId,
|
||||
name: String(data.name ?? "Sprint"),
|
||||
goal: String(data.goal ?? ""),
|
||||
|
||||
@@ -349,7 +349,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.belongsToCompany(ref.table, ref.id, companyId));
|
||||
const invalid = refs.find((ref) => ref.id && !this._db.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;
|
||||
|
||||
Reference in new issue
Block a user