fix: exclude terminated agents from list and org chart endpoints
Terminated agents (e.g. from rejected hire approvals) were visible in
GET /companies/:companyId/agents and GET /companies/:companyId/org because
list() and orgForCompany() had no status filtering.
- Add ne(agents.status, "terminated") filter to both queries
- Add optional { includeTerminated: true } param to list() for callers
that need all agents (e.g. company-portability export with skip counting)
- orgForCompany() always excludes terminated (no escape hatch needed)
Fixes #5
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { createHash, randomBytes } from "node:crypto";
|
import { createHash, randomBytes } from "node:crypto";
|
||||||
import { and, desc, eq, inArray } from "drizzle-orm";
|
import { and, desc, eq, inArray, ne } from "drizzle-orm";
|
||||||
import type { Db } from "@paperclipai/db";
|
import type { Db } from "@paperclipai/db";
|
||||||
import {
|
import {
|
||||||
agents,
|
agents,
|
||||||
@@ -251,8 +251,12 @@ export function agentService(db: Db) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
list: async (companyId: string) => {
|
list: async (companyId: string, options?: { includeTerminated?: boolean }) => {
|
||||||
const rows = await db.select().from(agents).where(eq(agents.companyId, companyId));
|
const conditions = [eq(agents.companyId, companyId)];
|
||||||
|
if (!options?.includeTerminated) {
|
||||||
|
conditions.push(ne(agents.status, "terminated"));
|
||||||
|
}
|
||||||
|
const rows = await db.select().from(agents).where(and(...conditions));
|
||||||
return rows.map(normalizeAgentRow);
|
return rows.map(normalizeAgentRow);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -469,7 +473,10 @@ export function agentService(db: Db) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
orgForCompany: async (companyId: string) => {
|
orgForCompany: async (companyId: string) => {
|
||||||
const rows = await db.select().from(agents).where(eq(agents.companyId, companyId));
|
const rows = await db
|
||||||
|
.select()
|
||||||
|
.from(agents)
|
||||||
|
.where(and(eq(agents.companyId, companyId), ne(agents.status, "terminated")));
|
||||||
const normalizedRows = rows.map(normalizeAgentRow);
|
const normalizedRows = rows.map(normalizeAgentRow);
|
||||||
const byManager = new Map<string | null, typeof normalizedRows>();
|
const byManager = new Map<string | null, typeof normalizedRows>();
|
||||||
for (const row of normalizedRows) {
|
for (const row of normalizedRows) {
|
||||||
|
|||||||
@@ -556,7 +556,7 @@ export function companyPortabilityService(db: Db) {
|
|||||||
requiredSecrets: [],
|
requiredSecrets: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const allAgentRows = include.agents ? await agents.list(companyId) : [];
|
const allAgentRows = include.agents ? await agents.list(companyId, { includeTerminated: true }) : [];
|
||||||
const agentRows = allAgentRows.filter((agent) => agent.status !== "terminated");
|
const agentRows = allAgentRows.filter((agent) => agent.status !== "terminated");
|
||||||
if (include.agents) {
|
if (include.agents) {
|
||||||
const skipped = allAgentRows.length - agentRows.length;
|
const skipped = allAgentRows.length - agentRows.length;
|
||||||
|
|||||||
Reference in New Issue
Block a user