refactor(api): extract assistant config readmodels

This commit is contained in:
2026-03-30 21:27:23 +02:00
parent 9571d454d4
commit 72394747f9
3 changed files with 236 additions and 137 deletions
+13 -136
View File
@@ -87,6 +87,10 @@ import {
chargeabilityComputationReadToolDefinitions,
createChargeabilityComputationExecutors,
} from "./assistant-tools/chargeability-computation.js";
import {
configReadmodelToolDefinitions,
createConfigReadmodelExecutors,
} from "./assistant-tools/config-readmodels.js";
import {
countryMetroAdminToolDefinitions,
createCountryMetroAdminExecutors,
@@ -2776,46 +2780,7 @@ export const TOOL_DEFINITIONS: ToolDef[] = [
},
},
...countryMetroAdminToolDefinitions,
{
type: "function",
function: {
name: "list_management_levels",
description: "List management level groups and their levels with target percentages.",
parameters: { type: "object", properties: {} },
},
},
{
type: "function",
function: {
name: "list_utilization_categories",
description: "List utilization categories (cost classification for projects).",
parameters: { type: "object", properties: {} },
},
},
{
type: "function",
function: {
name: "list_calculation_rules",
description: "List calculation rules for cost attribution and chargeability.",
parameters: { type: "object", properties: {} },
},
},
{
type: "function",
function: {
name: "list_effort_rules",
description: "List effort estimation rules with their formulas and conditions.",
parameters: { type: "object", properties: {} },
},
},
{
type: "function",
function: {
name: "list_experience_multipliers",
description: "List experience multipliers that adjust effort estimates based on seniority.",
parameters: { type: "object", properties: {} },
},
},
...configReadmodelToolDefinitions,
{
type: "function",
function: {
@@ -5503,102 +5468,14 @@ const executors = {
toAssistantCountryMutationError,
toAssistantMetroCityMutationError,
}),
async list_management_levels(_params: Record<string, never>, ctx: ToolContext) {
const caller = createManagementLevelCaller(createScopedCallerContext(ctx));
const groups = await caller.listGroups();
return groups.map((g) => ({
id: g.id,
name: g.name,
target: g.targetPercentage ? `${g.targetPercentage}%` : null,
levels: g.levels.map((l: { id: string; name: string }) => ({ id: l.id, name: l.name })),
}));
},
async list_utilization_categories(_params: Record<string, never>, ctx: ToolContext) {
const caller = createUtilizationCategoryCaller(createScopedCallerContext(ctx));
const categories = await caller.list();
const categoriesWithCounts = await Promise.all(
categories.map(async (category) => {
const detailed = await caller.getById({ id: category.id });
return {
category,
projectCount: detailed._count.projects,
};
}),
);
return categoriesWithCounts.map(({ category, projectCount }) => ({
id: category.id,
code: category.code,
name: category.name,
description: category.description,
projectCount,
}));
},
async list_calculation_rules(_params: Record<string, never>, ctx: ToolContext) {
const caller = createCalculationRuleCaller(createScopedCallerContext(ctx));
const rules = await caller.list();
return rules.map((rule) => ({
id: rule.id,
name: rule.name,
description: rule.description,
isActive: rule.isActive,
triggerType: rule.triggerType,
orderType: rule.orderType,
costEffect: rule.costEffect,
costReductionPercent: rule.costReductionPercent,
chargeabilityEffect: rule.chargeabilityEffect,
priority: rule.priority,
project: rule.project
? {
id: rule.project.id,
name: rule.project.name,
shortCode: rule.project.shortCode,
}
: null,
}));
},
async list_effort_rules(_params: Record<string, never>, ctx: ToolContext) {
const caller = createEffortRuleCaller(createScopedCallerContext(ctx));
const ruleSets = await caller.list();
return ruleSets.flatMap((ruleSet) => ruleSet.rules.map((rule) => ({
id: rule.id,
description: rule.description,
scopeType: rule.scopeType,
discipline: rule.discipline,
chapter: rule.chapter,
unitMode: rule.unitMode,
hoursPerUnit: rule.hoursPerUnit,
sortOrder: rule.sortOrder,
ruleSet: {
name: ruleSet.name,
isDefault: ruleSet.isDefault,
},
})));
},
async list_experience_multipliers(_params: Record<string, never>, ctx: ToolContext) {
const caller = createExperienceMultiplierCaller(createScopedCallerContext(ctx));
const multiplierSets = await caller.list();
return multiplierSets.flatMap((multiplierSet) => multiplierSet.rules.map((rule) => ({
id: rule.id,
description: rule.description,
chapter: rule.chapter,
location: rule.location,
level: rule.level,
costMultiplier: rule.costMultiplier,
billMultiplier: rule.billMultiplier,
shoringRatio: rule.shoringRatio,
additionalEffortRatio: rule.additionalEffortRatio,
sortOrder: rule.sortOrder,
multiplierSet: {
name: multiplierSet.name,
isDefault: multiplierSet.isDefault,
},
})));
},
...createConfigReadmodelExecutors({
createManagementLevelCaller,
createUtilizationCategoryCaller,
createCalculationRuleCaller,
createEffortRuleCaller,
createExperienceMultiplierCaller,
createScopedCallerContext,
}),
async list_users(params: { limit?: number }, ctx: ToolContext) {
const caller = createUserCaller(createScopedCallerContext(ctx));