From ba20d9e5ab33d7290aac54216385346a0d0ec3ef Mon Sep 17 00:00:00 2001 From: Marko Djordjevic Date: Wed, 18 Feb 2026 20:25:50 +0100 Subject: [PATCH] code-review-fix task 9.8: replace any types with proper interfaces Co-Authored-By: Claude Sonnet 4.6 --- src/app/page.tsx | 17 ++++++++++------- src/components/CandleChart.tsx | 6 +++--- src/components/SpanAnnotationManager.tsx | 22 ++++++++++++---------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 4c7a857..36aa872 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -13,8 +13,9 @@ import { ThemeToggle } from '@/components/ThemeToggle'; import KeyboardShortcutsModal from '@/components/KeyboardShortcutsModal'; import { useTheme } from 'next-themes'; import { Settings, Tag, Layers } from 'lucide-react'; -import type { PredictionState, PredictionSpan, ModelInfoResponse, Disagreement, DisagreementType, PredictionSummary } from '@/types/predictions'; -import type { SpanAnnotation, SpanLabelType } from '@/types'; +import type { PredictionState, PredictionSpan, PerCandlePrediction, ModelInfoResponse, Disagreement, DisagreementType, PredictionSummary } from '@/types/predictions'; +import type { Candle, SpanAnnotation, SpanLabelType } from '@/types'; +import type { Geometry } from '@/types/annotations'; /** * Calculate overlap between two time ranges @@ -136,7 +137,7 @@ interface Annotation { timestamp: number; label_type: string; color: string | null; - geometry: any; + geometry: Geometry | null; created_at: number; } @@ -174,7 +175,7 @@ export default function Home() { // Prediction cache: Map const predictionCacheRef = useRef>(new Map()); @@ -483,7 +484,7 @@ export default function Home() { }, []); // Fetch predictions for visible candles - const fetchPredictions = useCallback(async (candles: any[]) => { + const fetchPredictions = useCallback(async (candles: Candle[]) => { if (!activeChartId || candles.length === 0) return; const currentModelInfo = modelInfoRef.current; @@ -528,7 +529,8 @@ export default function Home() { if (cacheKey) { const cache = predictionCacheRef.current; if (cache.size >= 100) { - cache.delete(cache.keys().next().value); + const firstKey = cache.keys().next().value; + if (firstKey !== undefined) cache.delete(firstKey); } cache.set(cacheKey, { spans: data.spans, @@ -654,7 +656,8 @@ export default function Home() { if (cacheKey) { const cache = predictionCacheRef.current; if (cache.size >= 100) { - cache.delete(cache.keys().next().value); + const firstKey = cache.keys().next().value; + if (firstKey !== undefined) cache.delete(firstKey); } cache.set(cacheKey, { spans: data.spans, diff --git a/src/components/CandleChart.tsx b/src/components/CandleChart.tsx index 6289646..e8759f8 100644 --- a/src/components/CandleChart.tsx +++ b/src/components/CandleChart.tsx @@ -1,7 +1,7 @@ 'use client'; import { useEffect, useRef, useState, useImperativeHandle, forwardRef } from 'react'; -import { createChart, IChartApi, ISeriesApi, CandlestickData, HistogramData, Time, SeriesMarker } from 'lightweight-charts'; +import { createChart, IChartApi, ISeriesApi, CandlestickData, HistogramData, Time, SeriesMarker, MouseEventParams } from 'lightweight-charts'; import { useTheme } from 'next-themes'; import SpanAnnotationManager from './SpanAnnotationManager'; import { TrendLine } from '@/plugins/trend-line'; @@ -589,7 +589,7 @@ const CandleChart = forwardRef( return distance <= ENDPOINT_CLICK_TOLERANCE_PX; }; - const handleClick = async (param: any) => { + const handleClick = async (param: MouseEventParams) => { if (!param.point) return; const timeCoordinate = param.point.x; @@ -997,7 +997,7 @@ const CandleChart = forwardRef( if (drawingState && !previewPrimitiveRef.current) return; let isUpdating = false; - const handleCrosshairMove = (param: any) => { + const handleCrosshairMove = (param: MouseEventParams) => { if (isUpdating) return; if (!param.point) return; diff --git a/src/components/SpanAnnotationManager.tsx b/src/components/SpanAnnotationManager.tsx index 5d4281e..c80bcbd 100644 --- a/src/components/SpanAnnotationManager.tsx +++ b/src/components/SpanAnnotationManager.tsx @@ -1,7 +1,7 @@ 'use client'; import { useEffect, useState, useRef, useCallback } from 'react'; -import { IChartApi, ISeriesApi, Time } from 'lightweight-charts'; +import { IChartApi, ISeriesApi, Time, MouseEventParams } from 'lightweight-charts'; import { SpanRectanglePrimitive, SpanData } from './SpanRectanglePrimitive'; import SpanPopover from './SpanPopover'; import type { Candle, SpanAnnotation, SpanLabelType } from '@/types'; @@ -176,11 +176,12 @@ export default function SpanAnnotationManager({ setEndCandle(null); } - const handleClick = (param: any) => { + const handleClick = (param: MouseEventParams) => { if (!param.point) return; + const point = param.point; - const time = chart.timeScale().coordinateToTime(param.point.x); - const price = series.coordinateToPrice(param.point.y); + const time = chart.timeScale().coordinateToTime(point.x); + const price = series.coordinateToPrice(point.y); if (!time || !price) return; // Handle span tool two-click interaction @@ -194,7 +195,7 @@ export default function SpanAnnotationManager({ // Check if clicking on existing span for selection let clickedSpanId: number | null = null; primitivesRef.current.forEach((primitive, spanId) => { - if (primitive.hitTest(param.point.x, param.point.y)) { + if (primitive.hitTest(point.x, point.y)) { clickedSpanId = spanId; } }); @@ -228,7 +229,7 @@ export default function SpanAnnotationManager({ // Delete span on click with delete tool let clickedSpanId: number | null = null; primitivesRef.current.forEach((primitive, spanId) => { - if (primitive.hitTest(param.point.x, param.point.y)) { + if (primitive.hitTest(point.x, point.y)) { clickedSpanId = spanId; } }); @@ -240,7 +241,7 @@ export default function SpanAnnotationManager({ // Click to select span when no tool is active let clickedSpanId: number | null = null; primitivesRef.current.forEach((primitive, spanId) => { - if (primitive.hitTest(param.point.x, param.point.y)) { + if (primitive.hitTest(point.x, point.y)) { clickedSpanId = spanId; } }); @@ -271,7 +272,7 @@ export default function SpanAnnotationManager({ return; } - const handleMouseMove = (param: any) => { + const handleMouseMove = (param: MouseEventParams) => { if (!param.point) return; const time = chart.timeScale().coordinateToTime(param.point.x); @@ -542,12 +543,13 @@ export default function SpanAnnotationManager({ useEffect(() => { if (!chart) return; - const handleDblClick = (param: any) => { + const handleDblClick = (param: MouseEventParams) => { if (!param.point) return; + const point = param.point; let clickedSpanId: number | null = null; primitivesRef.current.forEach((primitive, spanId) => { - if (primitive.hitTest(param.point.x, param.point.y)) { + if (primitive.hitTest(point.x, point.y)) { clickedSpanId = spanId; } });