АРЧ АП11 - Архитектура после регресса: Архитектура: сделать counterparty и contract ranking-ответы business-first без отчетного preamble

This commit is contained in:
2026-04-18 15:32:05 +03:00
parent a51fc2a70d
commit 0c6440fc5e
4 changed files with 35 additions and 40 deletions
@@ -304,14 +304,12 @@ function composeCounterpartyAnalyticsReply(intent, rows, options = {}, deps) {
}
const lines = longevityQuestion
? [
`Заказчиков с самым длинным горизонтом сотрудничества: ${counterparties.length}.`,
"Собран профиль длительности сотрудничества по годам и частоте активности.",
`Строк агрегата: ${rows.length}.`
`Коротко: заказчиков с самым длинным горизонтом сотрудничества — ${counterparties.length}.`,
`Оценка собрана по подтвержденной активности в 1С: ${rows.length} строк в выборке.`
]
: [
`Активные заказчики ${scopeLabel}: ${counterparties.length}.`,
"Собран профиль активности заказчиков по платежным документам.",
`Строк агрегата: ${rows.length}.`
`Коротко: активных заказчиков ${scopeLabel} — ${counterparties.length}.`,
`Оценка собрана по подтвержденным платежным документам: ${rows.length} строк в выборке.`
];
if (counterparties.length === 0) {
lines.push(longevityQuestion
@@ -351,9 +349,8 @@ function composeCounterpartyAnalyticsReply(intent, rows, options = {}, deps) {
? `Использованных договоров: ${usedContracts} из ${totalContracts}${usedShare ? ` (${usedShare})` : ""}.`
: `Использованных договоров с подтвержденной связью с операциями: ${usedContracts}.`;
const lines = [
usageLead,
"Профиль договорной базы собран по справочнику и подтвержденным операциям.",
`Строк агрегата: ${rows.length}.`
`Коротко: ${usageLead.replace(/\.$/, "")}.`,
`Что видно по договорной базе: ${rows.length} строк в подтвержденной выборке.`
];
if (totalContracts > 0) {
lines.push(`Всего договоров в базе: ${totalContracts}.`);
@@ -454,10 +451,9 @@ function composeCounterpartyAnalyticsReply(intent, rows, options = {}, deps) {
.sort((a, b) => a.amount - b.amount || (a.period ?? "").localeCompare(b.period ?? ""));
const lines = [
isSupplier
? "Собран профиль выплат поставщикам по платежным документам."
: "Собран профиль поступлений от заказчиков по платежным документам.",
`Строк источника: ${rows.length}.`,
`Уникальных контрагентов: ${profileRows.length}.`
? `Коротко: в выборке ${profileRows.length} поставщиков по ${rows.length} подтвержденным платежным строкам.`
: `Коротко: в выборке ${profileRows.length} заказчиков по ${rows.length} подтвержденным платежным строкам.`,
`Подтвержденный денежный поток в выборке: ${deps.formatMoneyRub(totalFlow)}.`
];
if (profileRows.length === 0) {
lines.push("По выбранному окну данных платежные строки не найдены.");
@@ -614,10 +610,8 @@ function composeCounterpartyAnalyticsReply(intent, rows, options = {}, deps) {
.filter((item) => item.docs > 0 && item.turnover > 0)
.sort((a, b) => a.turnover - b.turnover || b.docs - a.docs || a.contract.localeCompare(b.contract));
const lines = [
`Активных договоров: ${contractRows.length}.`,
"Собран профиль договоров по обороту и подтвержденным операциям.",
`Строк источника: ${rows.length}.`,
`Договорных агрегатов: ${contractRows.length}.`
`Коротко: активных договоров в выборке — ${contractRows.length}.`,
`Подтвержденных операций по договорам: ${rows.length}.`
];
if (contractRows.length === 0) {
lines.push("В выбранном окне не найдено операций, связанных с договорами.");
@@ -631,7 +625,7 @@ function composeCounterpartyAnalyticsReply(intent, rows, options = {}, deps) {
}
if (focus === "bottom_by_turnover_active") {
const visible = rankedBottomActive.slice(0, limit);
lines.unshift(`Топ-${visible.length} активных договоров с минимальным оборотом:`);
lines.unshift(`Топ-${visible.length} активных договоров с минимальным бюджетом:`);
lines.push(...visible.map((item, index) => `${index + 1}. ${item.contract} | оборот: ${deps.formatMoneyRub(item.turnover)} | операций: ${item.docs} | последняя активность: ${formatOptionalDate(item.lastPeriod, deps.formatDateRu)}`));
return (0, replyContracts_1.buildFactualListReply)(lines);
}