ARCH: удержать year-switch после contracts pivot

This commit is contained in:
2026-04-23 20:01:03 +03:00
parent 0c4b53ccc6
commit 84beaf5540
7 changed files with 279 additions and 10 deletions
@@ -2274,6 +2274,56 @@ function applyFutureDatedRowsGuard(
};
}
function applyExplicitPeriodWindowFilter(
rows: NormalizedAddressRow[],
filters: AddressFilterSet
): { rows: NormalizedAddressRow[]; droppedCount: number; applied: boolean } {
const periodFrom = typeof filters.period_from === "string" ? filters.period_from.trim() : "";
const periodTo = typeof filters.period_to === "string" ? filters.period_to.trim() : "";
if (!periodFrom && !periodTo) {
return {
rows,
droppedCount: 0,
applied: false
};
}
const periodFromTs = periodFrom ? parseIsoDateUtcTimestamp(periodFrom) : null;
const periodToTs = periodTo ? parseIsoDateUtcTimestamp(periodTo) : null;
if ((periodFrom && periodFromTs === null) || (periodTo && periodToTs === null)) {
return {
rows,
droppedCount: 0,
applied: false
};
}
const keptRows: NormalizedAddressRow[] = [];
let droppedCount = 0;
for (const row of rows) {
const rowTs = parseIsoDateUtcTimestamp(row.period);
if (rowTs === null) {
droppedCount += 1;
continue;
}
if (periodFromTs !== null && rowTs < periodFromTs) {
droppedCount += 1;
continue;
}
if (periodToTs !== null && rowTs > periodToTs) {
droppedCount += 1;
continue;
}
keptRows.push(row);
}
return {
rows: keptRows,
droppedCount,
applied: true
};
}
function hasExplicitPeriodWindow(filters: AddressFilterSet): boolean {
return (
(typeof filters.period_from === "string" && filters.period_from.trim().length > 0) ||
@@ -2295,6 +2345,7 @@ function canAutoBroadenPeriodWindow(intent: AddressIntent, filters: AddressFilte
return (
intent === "list_documents_by_counterparty" ||
intent === "bank_operations_by_counterparty" ||
intent === "list_contracts_by_counterparty" ||
intent === "list_documents_by_contract" ||
intent === "bank_operations_by_contract" ||
intent === "inventory_purchase_provenance_for_item" ||
@@ -4082,7 +4133,8 @@ export class AddressQueryService {
});
let anchorFilter = applyAddressFilters(normalizedRows, filtersForMatching);
let filterByAnchors = anchorFilter.rows;
let filteredRowsBeforeFutureGuard = applyIntentSpecificFilter(intent.intent, filterByAnchors);
let explicitPeriodWindowFilter = applyExplicitPeriodWindowFilter(filterByAnchors, executionFilters);
let filteredRowsBeforeFutureGuard = applyIntentSpecificFilter(intent.intent, explicitPeriodWindowFilter.rows);
let filteredRowsFutureGuard = applyFutureDatedRowsGuard(
filteredRowsBeforeFutureGuard,
intent.intent,
@@ -4130,7 +4182,8 @@ export class AddressQueryService {
}
anchorFilter = applyAddressFilters(normalizedRows, filtersForMatching);
filterByAnchors = anchorFilter.rows;
filteredRowsBeforeFutureGuard = applyIntentSpecificFilter(intent.intent, filterByAnchors);
explicitPeriodWindowFilter = applyExplicitPeriodWindowFilter(filterByAnchors, executionFilters);
filteredRowsBeforeFutureGuard = applyIntentSpecificFilter(intent.intent, explicitPeriodWindowFilter.rows);
filteredRowsFutureGuard = applyFutureDatedRowsGuard(
filteredRowsBeforeFutureGuard,
intent.intent,
@@ -4147,6 +4200,19 @@ export class AddressQueryService {
baseReasons.push("future_rows_excluded_from_response");
}
}
if (explicitPeriodWindowFilter.applied) {
if (!baseReasons.includes("explicit_period_window_post_filter_applied")) {
baseReasons.push("explicit_period_window_post_filter_applied");
}
if (explicitPeriodWindowFilter.droppedCount > 0) {
if (!filters.warnings.includes("rows_outside_explicit_period_window_excluded")) {
filters.warnings.push("rows_outside_explicit_period_window_excluded");
}
if (!baseReasons.includes("rows_outside_explicit_period_window_excluded")) {
baseReasons.push("rows_outside_explicit_period_window_excluded");
}
}
}
const rowDiagnostics = deriveRowStageDiagnostics(mcp.raw_rows, normalizedRows.length, normalizedRows.length);
const stageStatus = deriveMcpStageStatus({
rawRowsReceived: mcp.raw_rows.length,
@@ -4599,7 +4665,14 @@ export class AddressQueryService {
});
const expandedAnchorFilter = applyAddressFilters(expandedNormalizedRows, expandedFiltersForMatching);
const expandedRowsByAnchor = expandedAnchorFilter.rows;
const expandedFilteredRowsBeforeFutureGuard = applyIntentSpecificFilter(intent.intent, expandedRowsByAnchor);
const expandedExplicitPeriodWindowFilter = applyExplicitPeriodWindowFilter(
expandedRowsByAnchor,
expandedLimitFilters
);
const expandedFilteredRowsBeforeFutureGuard = applyIntentSpecificFilter(
intent.intent,
expandedExplicitPeriodWindowFilter.rows
);
const expandedFutureGuard = applyFutureDatedRowsGuard(
expandedFilteredRowsBeforeFutureGuard,
intent.intent,
@@ -4859,7 +4932,14 @@ export class AddressQueryService {
});
const historicalAnchorFilter = applyAddressFilters(historicalNormalizedRows, historicalFiltersForMatching);
const historicalRowsByAnchor = historicalAnchorFilter.rows;
const historicalFilteredRowsBeforeFutureGuard = applyIntentSpecificFilter(intent.intent, historicalRowsByAnchor);
const historicalExplicitPeriodWindowFilter = applyExplicitPeriodWindowFilter(
historicalRowsByAnchor,
historicalFilters
);
const historicalFilteredRowsBeforeFutureGuard = applyIntentSpecificFilter(
intent.intent,
historicalExplicitPeriodWindowFilter.rows
);
const historicalFutureGuard = applyFutureDatedRowsGuard(
historicalFilteredRowsBeforeFutureGuard,
intent.intent,
@@ -895,7 +895,7 @@ const BASE_RECIPES: AddressRecipeDefinition[] = [
intent: "list_contracts_by_counterparty",
purpose: "List contracts by counterparty from contract catalog",
required_filters: ["counterparty"],
optional_filters: ["limit", "sort"],
optional_filters: ["period_from", "period_to", "as_of_date", "organization", "limit", "sort"],
default_limit: 300,
account_scope_mode: "preferred",
query_template: "contracts_by_counterparty_profile"