@@ -82,12 +82,21 @@ export function SpendingFlow({
8282 // Target = daily budget (from cash flow simulation) * days in month
8383 const target = dailyBudget * daysInMonth ;
8484
85- // Cumulative target by day from frozen snapshots, falling back to live targetPerDay
86- // when a day has no snapshot yet (today and future)
85+ // Cumulative target by day. Past days lock to their snapshot, falling back to the
86+ // earliest known snapshot value when no snapshot exists for that day. Today and future
87+ // use live targetPerDay so the in-progress day reflects current state.
88+ const earliestSnapshotTarget = ( ( ) => {
89+ const sorted = Object . keys ( snapshotByDay ) . map ( Number ) . sort ( ( a , b ) => a - b ) ;
90+ for ( const d of sorted ) if ( snapshotByDay [ d ] > 0 ) return snapshotByDay [ d ] ;
91+ return targetPerDay ;
92+ } ) ( ) ;
8793 const cumulativeTargetByDay : Record < number , number > = { } ;
8894 let runningTarget = 0 ;
8995 for ( let d = 1 ; d <= daysInMonth ; d ++ ) {
90- const perDay = snapshotByDay [ d ] > 0 ? snapshotByDay [ d ] : targetPerDay ;
96+ let perDay : number ;
97+ if ( snapshotByDay [ d ] > 0 ) perDay = snapshotByDay [ d ] ;
98+ else if ( d < daysPassed ) perDay = earliestSnapshotTarget ;
99+ else perDay = targetPerDay ;
91100 runningTarget += perDay ;
92101 cumulativeTargetByDay [ d ] = runningTarget ;
93102 }
@@ -131,7 +140,9 @@ export function SpendingFlow({
131140 const cumulativeToToday = ( ( ) => {
132141 let sum = 0 ;
133142 for ( let d = 1 ; d <= daysPassed ; d ++ ) {
134- sum += snapshotByDay [ d ] > 0 ? snapshotByDay [ d ] : targetPerDay ;
143+ if ( snapshotByDay [ d ] > 0 ) sum += snapshotByDay [ d ] ;
144+ else if ( d < daysPassed ) sum += earliestSnapshotTarget ;
145+ else sum += targetPerDay ;
135146 }
136147 return sum ;
137148 } ) ( ) ;
0 commit comments