Open-World: добавить контрагентский и договорной профиль в бизнес-обзор

This commit is contained in:
2026-05-05 13:24:38 +03:00
parent 466b3b66e5
commit 42283a6ac2
9 changed files with 544 additions and 38 deletions
@@ -241,6 +241,21 @@ describe("assistant MCP discovery answer adapter", () => {
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_DT_OPS", AccountDt: "60", Amount: 9 },
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_KT_OPS", AccountDt: "62", Amount: 6 }
]
},
{
rows: [
{ Period: "2020-01-01T00:00:00", Registrator: "CP_TOTAL", Amount: 412 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_CUSTOMER_ACTIVE", Amount: 145 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_SUPPLIER_ACTIVE", Amount: 94 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_MIXED_ACTIVE", Amount: 23 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_ACTIVE_UNION", Amount: 216 }
]
},
{
rows: [
{ Period: "2020-01-01T00:00:00", Registrator: "CT_TOTAL", Amount: 520 },
{ Period: "2020-01-01T00:00:00", Registrator: "CT_USED", Amount: 148 }
]
}
])
);
@@ -256,6 +271,10 @@ describe("assistant MCP discovery answer adapter", () => {
expect(draft.confirmed_lines.join("\n")).toContain("Профиль операционной активности");
expect(draft.confirmed_lines.join("\n")).toContain("ведущий тип документов Списание с расчетного счета");
expect(draft.confirmed_lines.join("\n")).toContain("ведущий раздел учета 60");
expect(draft.confirmed_lines.join("\n")).toContain("Профиль контрагентской базы");
expect(draft.confirmed_lines.join("\n")).toContain("412 контрагентов в базе");
expect(draft.confirmed_lines.join("\n")).toContain("Договорной профиль");
expect(draft.confirmed_lines.join("\n")).toContain("148 из 520 договоров используются");
expect(draft.inference_lines.join("\n")).toContain("Аналитический вывод по оборотам");
expect(draft.inference_lines.join("\n")).toContain("Концентрация входящего потока");
expect(draft.inference_lines.join("\n")).toContain("Концентрация исходящего потока");
@@ -270,10 +289,13 @@ describe("assistant MCP discovery answer adapter", () => {
expect(draft.must_not_claim).toContain("Do not present business overview yearly operating-flow breakdown as profit, financial result, or a complete annual P&L.");
expect(draft.must_not_claim).toContain("Do not present business overview supplier concentration as vendor-risk audit, procurement quality, or full expense structure.");
expect(draft.must_not_claim).toContain("Do not present business overview document/account-section activity profile as process quality, accounting correctness, or completeness of all 1C activity.");
expect(draft.must_not_claim).toContain("Do not present business overview counterparty or contract profile as CRM quality, counterparty due diligence, contract-risk audit, or legal completeness.");
expect(draft.reason_codes).toContain("answer_contains_business_overview");
expect(draft.reason_codes).toContain("answer_contains_business_overview_supplier_concentration");
expect(draft.reason_codes).toContain("answer_contains_business_overview_yearly_operating_breakdown");
expect(draft.reason_codes).toContain("answer_contains_business_overview_document_activity_profile");
expect(draft.reason_codes).toContain("answer_contains_business_overview_counterparty_profile");
expect(draft.reason_codes).toContain("answer_contains_business_overview_contract_usage_profile");
expect(draft.reason_codes).toContain("answer_contains_business_overview_analyst_synthesis");
});
@@ -161,6 +161,21 @@ describe("assistant MCP discovery pilot executor", () => {
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_DT_OPS", AccountDt: "60", Amount: 9 },
{ Period: "2020-01-01T00:00:00", Registrator: "SECTION_KT_OPS", AccountDt: "62", Amount: 6 }
]
},
{
rows: [
{ Period: "2020-01-01T00:00:00", Registrator: "CP_TOTAL", Amount: 412 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_CUSTOMER_ACTIVE", Amount: 145 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_SUPPLIER_ACTIVE", Amount: 94 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_MIXED_ACTIVE", Amount: 23 },
{ Period: "2020-01-01T00:00:00", Registrator: "CP_ACTIVE_UNION", Amount: 216 }
]
},
{
rows: [
{ Period: "2020-01-01T00:00:00", Registrator: "CT_TOTAL", Amount: 520 },
{ Period: "2020-01-01T00:00:00", Registrator: "CT_USED", Amount: 148 }
]
}
]);
@@ -227,10 +242,28 @@ describe("assistant MCP discovery pilot executor", () => {
operation_count: 9,
share_pct: 60
});
expect(result.derived_business_overview?.counterparty_profile).toMatchObject({
rows_matched: 5,
total_counterparties: 412,
active_counterparties: 216,
customer_only_count: 122,
supplier_only_count: 71,
mixed_role_count: 23,
other_or_inactive_count: 196
});
expect(result.derived_business_overview?.contract_usage_profile).toMatchObject({
rows_matched: 2,
total_contracts: 520,
used_contracts: 148,
unused_contracts: 372,
used_contract_share_pct: 28.46
});
expect(result.evidence.confirmed_facts.join("\n")).toContain("В 1С подтверждены входящие поступления");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Самый крупный подтвержденный поставщик");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Годовая раскладка операционного денежного потока");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Профиль операционной активности");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Профиль контрагентской базы");
expect(result.evidence.confirmed_facts.join("\n")).toContain("Договорной профиль");
expect(result.evidence.inferred_facts.join("\n")).toContain("procurement concentration proxy");
expect(result.evidence.inferred_facts.join("\n")).toContain("Самый сильный год по подтвержденным входящим поступлениям: 2021");
expect(result.evidence.unknown_facts).toContain(
@@ -240,7 +273,9 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_top_suppliers_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_yearly_operating_breakdown_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_document_activity_profile_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(4);
expect(result.reason_codes).toContain("pilot_derived_business_overview_counterparty_profile_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_contract_usage_profile_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(6);
});
it("adds a checked VAT/tax family to business overview only when an explicit period is available", async () => {
@@ -343,7 +378,7 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_tax_position_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_business_overview_trading_margin_query_mcp_executed");
expect(result.reason_codes).toContain("pilot_derived_business_overview_trading_margin_proxy_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(11);
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(13);
const taxCall = deps.executeAddressMcpQuery.mock.calls[2]?.[0];
const tradingMarginCall = deps.executeAddressMcpQuery.mock.calls[9]?.[0];
expect(String(taxCall?.query ?? "")).toContain("НДСЗаписиКнигиПродаж");
@@ -543,7 +578,7 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_open_settlement_quality_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_debt_age_signal_from_contract_dates");
expect(result.reason_codes).toContain("pilot_derived_business_overview_debt_staleness_risk_proxy_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(11);
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(13);
const receivablesCall = deps.executeAddressMcpQuery.mock.calls[3]?.[0];
const payablesCall = deps.executeAddressMcpQuery.mock.calls[4]?.[0];
const openContractsCall = deps.executeAddressMcpQuery.mock.calls[5]?.[0];
@@ -670,7 +705,7 @@ describe("assistant MCP discovery pilot executor", () => {
expect(result.reason_codes).toContain("pilot_derived_business_overview_inventory_position_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_inventory_turnover_proxy_from_confirmed_rows");
expect(result.reason_codes).toContain("pilot_derived_business_overview_inventory_staleness_risk_proxy_from_confirmed_rows");
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(11);
expect(deps.executeAddressMcpQuery).toHaveBeenCalledTimes(13);
const inventoryCall = deps.executeAddressMcpQuery.mock.calls[6]?.[0];
expect(inventoryCall?.account_scope).toContain("41.01");
});