From 9b3d1df6074cb78ce9e6d9fbbee6be2de2be9756 Mon Sep 17 00:00:00 2001 From: lsabor Date: Sat, 1 Nov 2025 16:52:12 -0700 Subject: [PATCH] always give all user predictions to front end, remove some unused code, set last point of numeric timeline to actual close time if applicable --- front_end/src/components/charts/helpers.ts | 27 ++++++++++++++++++-- posts/models.py | 11 +++----- questions/serializers/aggregate_forecasts.py | 15 ----------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/front_end/src/components/charts/helpers.ts b/front_end/src/components/charts/helpers.ts index aec17f78b6..05c950acee 100644 --- a/front_end/src/components/charts/helpers.ts +++ b/front_end/src/components/charts/helpers.ts @@ -1,3 +1,4 @@ +import { isNil } from "lodash"; import { DomainTuple, VictoryThemeDefinition } from "victory"; import { @@ -126,9 +127,14 @@ export function buildNumericChartData({ }); const latestTimestamp = actualCloseTime - ? Math.min(actualCloseTime / 1000, Date.now() / 1000) + ? Math.max( + Math.min(actualCloseTime / 1000, Date.now() / 1000), + myForecasts?.latest ? myForecasts.latest.start_time : 0 + ) : Date.now() / 1000; - if (aggregation.latest?.end_time === null) { + if (isNil(actualCloseTime) && aggregation.latest?.end_time === null) { + // we don't have an actual close time and last aggregation hasn't ended, + // so put a point at the end of the timeline line.push({ x: latestTimestamp, y: aggregation.latest.centers?.[aggregationIndex] ?? 0, @@ -138,6 +144,23 @@ export function buildNumericChartData({ y0: aggregation.latest.interval_lower_bounds?.[aggregationIndex] ?? 0, y: aggregation.latest.interval_upper_bounds?.[aggregationIndex] ?? 0, }); + } else if ( + actualCloseTime && + (aggregation.latest?.end_time === null || + (aggregation.latest?.end_time && + aggregation.latest.end_time >= actualCloseTime)) + ) { + // we have an actual close time and the aggregation outlives it, + // trucate it to the actualCloseTime + line[line.length - 1] = { + x: actualCloseTime / 1000, + y: aggregation.latest.centers?.[aggregationIndex] ?? 0, + }; + area[area.length - 1] = { + x: actualCloseTime / 1000, + y0: aggregation.latest.interval_lower_bounds?.[aggregationIndex] ?? 0, + y: aggregation.latest.interval_upper_bounds?.[aggregationIndex] ?? 0, + }; } else if ( aggregation.latest?.end_time && aggregation.latest.end_time >= latestTimestamp diff --git a/posts/models.py b/posts/models.py index 635e4a93ce..9efdf45717 100644 --- a/posts/models.py +++ b/posts/models.py @@ -55,14 +55,9 @@ def prefetch_user_forecasts(self, user_id: int): prefetches += [ Prefetch( f"{rel}__user_forecasts", - # only retrieve forecasts that were made before question close - queryset=Forecast.objects.filter(author_id=user_id) - .annotate(actual_close_time=F("question__actual_close_time")) - .filter( - Q(actual_close_time__isnull=True) - | Q(start_time__lte=F("actual_close_time")) - ) - .order_by("start_time"), + queryset=Forecast.objects.filter(author_id=user_id).order_by( + "start_time" + ), to_attr="request_user_forecasts", ), Prefetch( diff --git a/questions/serializers/aggregate_forecasts.py b/questions/serializers/aggregate_forecasts.py index 716a261675..9943f3a5dc 100644 --- a/questions/serializers/aggregate_forecasts.py +++ b/questions/serializers/aggregate_forecasts.py @@ -92,21 +92,6 @@ def serialize_question_aggregations( "movement": None, } - # Debug method for building aggregation history from scratch - # Will be replaced in favour of aggregation explorer - if not minimize: - aggregate_forecasts_by_method = get_aggregation_history( - question, - aggregation_methods=[ - AggregationMethod.RECENCY_WEIGHTED, - AggregationMethod.UNWEIGHTED, - ], - minimize=False, - include_stats=True, - include_bots=question.include_bots_in_aggregates, - histogram=True, - ) - if question.is_cp_hidden: # don't show any forecasts aggregate_forecasts_by_method = {}