@@ -204,6 +204,22 @@ RESULT:
204204
205205 // === UTILITY CALCULATION METHODS ===
206206
207+ /**
208+ * Type-safe parsing of numeric values that might be strings or numbers
209+ * @param value The value to parse (string | number | null | undefined)
210+ * @param defaultValue The default value to use if parsing fails
211+ * @returns A valid number
212+ */
213+ private parseNumericValue ( value : string | number | null | undefined , defaultValue : number ) : number {
214+ if ( value == null ) return defaultValue ;
215+ if ( typeof value === 'number' ) return isNaN ( value ) ? defaultValue : value ;
216+ if ( typeof value === 'string' ) {
217+ const parsed = parseFloat ( value ) ;
218+ return isNaN ( parsed ) ? defaultValue : parsed ;
219+ }
220+ return defaultValue ;
221+ }
222+
207223 /**
208224 * Round a number to a specified number of decimal places
209225 * @param value The number to round
@@ -702,8 +718,8 @@ RESULT:
702718 const userTimeSavings = distinctUsers . map ( userId => {
703719 const userSurveys = this . surveysWeekly . filter ( survey => survey . userId === userId ) ;
704720 const totalPercent = userSurveys . reduce ( ( sum , survey ) => {
705- // Always parse percentTimeSaved as float
706- const percentTimeSaved = survey . percentTimeSaved != null ? parseFloat ( survey . percentTimeSaved as any ) : 0 ;
721+ // Use type-safe parsing for percentTimeSaved
722+ const percentTimeSaved = this . parseNumericValue ( survey . percentTimeSaved , 0 ) ;
707723 return sum + percentTimeSaved ;
708724 } , 0 ) ;
709725 return totalPercent / userSurveys . length ; // Average percent time saved per user
@@ -712,17 +728,17 @@ RESULT:
712728 // Average across all users
713729 const avgPercentTimeSaved = userTimeSavings . reduce ( ( sum , percent ) => sum + percent , 0 ) / userTimeSavings . length ;
714730
715- // Convert settings values to numbers (parse from string if needed)
716- const hoursPerYear = this . settings . hoursPerYear != null ? parseFloat ( this . settings . hoursPerYear as any ) : 2000 ;
717- const percentCoding = this . settings . percentCoding != null ? parseFloat ( this . settings . percentCoding as any ) : 50 ;
731+ // Convert settings values to numbers using type-safe parsing
732+ const hoursPerYear = this . parseNumericValue ( this . settings . hoursPerYear , 2000 ) ;
733+ const percentCoding = this . parseNumericValue ( this . settings . percentCoding , 50 ) ;
718734
719735 // Calculate weekly hours saved based on settings and average percent
720736 const weeklyHours = hoursPerYear / 50 ; // Assuming 50 working weeks
721737 const weeklyDevHours = weeklyHours * ( percentCoding / 100 ) ;
722738 const avgWeeklyTimeSaved = weeklyDevHours * ( avgPercentTimeSaved / 100 ) ;
723739
724740 // Calculate max based on settings
725- const maxPercentTimeSaved = this . settings . percentTimeSaved != null ? parseFloat ( this . settings . percentTimeSaved as any ) : 20 ;
741+ const maxPercentTimeSaved = this . parseNumericValue ( this . settings . percentTimeSaved , 20 ) ;
726742 const maxWeeklyTimeSaved = weeklyDevHours * ( maxPercentTimeSaved / 100 ) ;
727743
728744 // Use default value of 2 if calculated value is 0 or very small
@@ -794,11 +810,11 @@ RESULT:
794810 const adoptedDevs = this . calculateAdoptedDevs ( ) . current ;
795811 const weeklyTimeSavedHrs = this . calculateWeeklyTimeSavedHrs ( ) . current ; // This now includes default of 2 if needed
796812
797- // Always parse settings values as numbers (from string if needed)
798- const hoursPerYear = this . settings . hoursPerYear != null ? parseFloat ( this . settings . hoursPerYear as any ) : 2000 ;
813+ // Use type-safe parsing for settings values
814+ const hoursPerYear = this . parseNumericValue ( this . settings . hoursPerYear , 2000 ) ;
799815 const weeksInYear = Math . round ( hoursPerYear / 40 ) || 50 ; // Calculate weeks and ensure it's a number
800816
801- const devCostPerYear = this . settings . devCostPerYear != null ? parseFloat ( this . settings . devCostPerYear as any ) : 0 ;
817+ const devCostPerYear = this . parseNumericValue ( this . settings . devCostPerYear , 0 ) ;
802818 const hourlyRate = devCostPerYear > 0 ? ( devCostPerYear / hoursPerYear ) : 50 ;
803819
804820 const annualSavings = weeklyTimeSavedHrs * weeksInYear * hourlyRate * adoptedDevs ;
@@ -834,8 +850,8 @@ RESULT:
834850 const adoptedDevs = this . calculateAdoptedDevs ( ) . current ;
835851 const weeklyTimeSavedHrs = this . calculateWeeklyTimeSavedHrs ( ) . current ; // This now includes default of 2 if needed
836852
837- // Always parse hours per year as number
838- const hoursPerYear = this . settings . hoursPerYear != null ? parseFloat ( this . settings . hoursPerYear as any ) : 2000 ;
853+ // Use type-safe parsing for hours per year
854+ const hoursPerYear = this . parseNumericValue ( this . settings . hoursPerYear , 2000 ) ;
839855 const hoursPerWeek = hoursPerYear / 50 || 40 ; // Default to 40 if undefined
840856
841857 // Calculate productivity boost factor (not percentage)
0 commit comments