import { afterEach, describe, expect, it, vi } from "vitest"; const { executeAddressMcpQueryMock } = vi.hoisted(() => ({ executeAddressMcpQueryMock: vi.fn() })); vi.mock("../src/services/addressMcpClient", async () => { const actual = await vi.importActual( "../src/services/addressMcpClient" ); return { ...actual, executeAddressMcpQuery: executeAddressMcpQueryMock }; }); import { AddressQueryService } from "../src/services/addressQueryService"; afterEach(() => { executeAddressMcpQueryMock.mockReset(); vi.restoreAllMocks(); }); describe("counterparty lifecycle organization scope regressions", () => { it("keeps carried organization scope without false empty-match when rows omit organization column", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 3, matched_rows: 3, raw_rows: [ { Period: "2020-01-15T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "62.01", AccountKt: "90.01", Amount: 12, Counterparty: 'ООО "Ромашка"' }, { Period: "2020-02-20T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "62.01", AccountKt: "90.01", Amount: 8, Counterparty: 'ООО "Ландыш"' }, { Period: "2020-03-10T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "62.01", AccountKt: "90.01", Amount: 4, Counterparty: 'ООО "Ромашка"' } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("какие клиенты заплатили больше всего денег за все время", { followupContext: { previous_intent: "vat_payable_forecast", previous_filters: { organization: 'ООО "Альтернатива Плюс"', period_from: "2020-01-01", period_to: "2020-03-31" }, previous_anchor_type: "organization", previous_anchor_value: 'ООО "Альтернатива Плюс"' } }); expect(result?.handled).toBe(true); expect(result?.reply_type).toBe("factual"); expect(result?.response_type).toBe("FACTUAL_LIST"); expect(result?.debug.detected_intent).toBe("customer_revenue_and_payments"); expect(result?.debug.selected_recipe).toBe("address_customer_revenue_and_payments_v1"); expect(result?.debug.extracted_filters?.organization).toBe('ООО "Альтернатива Плюс"'); expect(result?.debug.extracted_filters?.counterparty).toBeUndefined(); expect(result?.debug.match_failure_reason).toBeNull(); expect(result?.debug.rows_matched).toBe(3); expect(String(result?.reply_text ?? "")).toContain('ООО "Ромашка"'); }); it("does not turn 'за все время' into a bogus counterparty anchor for highest-value customer wording", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 2, matched_rows: 2, raw_rows: [ { Period: "2020-01-15T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "62.01", AccountKt: "90.01", Amount: 120, Counterparty: 'ООО "Ромашка"' }, { Period: "2020-02-20T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "62.01", AccountKt: "90.01", Amount: 80, Counterparty: 'ООО "Ландыш"' } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("какой у нас самый доходный клиент за все время"); expect(result?.handled).toBe(true); expect(result?.debug.detected_intent).toBe("customer_revenue_and_payments"); expect(result?.debug.selected_recipe).toBe("address_customer_revenue_and_payments_v1"); expect(result?.debug.extracted_filters?.counterparty).toBeUndefined(); expect(String(result?.reply_text ?? "")).toContain('ООО "Ромашка"'); }); it("routes who-is-the-highest-value-customer wording to revenue ranking, not lifecycle activity", async () => { executeAddressMcpQueryMock.mockResolvedValueOnce({ fetched_rows: 2, matched_rows: 2, raw_rows: [ { Period: "2021-01-15T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "51", AccountKt: "62.01", Amount: 150000, Counterparty: "Группа СВК" }, { Period: "2021-02-20T00:00:00Z", Registrator: "CP_CUSTOMER_ACTIVITY", AccountDt: "51", AccountKt: "62.01", Amount: 80000, Counterparty: "Чепурнов П.Д." } ], rows: [], error: null }); const service = new AddressQueryService(); const result = await service.tryHandle("кто у нас самый доходный клиент за все время"); expect(result?.handled).toBe(true); expect(result?.debug.detected_intent).toBe("customer_revenue_and_payments"); expect(result?.debug.selected_recipe).toBe("address_customer_revenue_and_payments_v1"); expect(String(result?.reply_text ?? "")).toContain("Самый доходный клиент"); expect(String(result?.reply_text ?? "")).toContain("Группа СВК"); }); });