diff --git a/src/utils/opsEngine.js b/backend/utils/opsEngine.js similarity index 100% rename from src/utils/opsEngine.js rename to backend/utils/opsEngine.js diff --git a/src/components/CareerRoadmap.js b/src/components/CareerRoadmap.js index e486315..5fec7e7 100644 --- a/src/components/CareerRoadmap.js +++ b/src/components/CareerRoadmap.js @@ -34,6 +34,7 @@ import { Pencil } from 'lucide-react'; import ScenarioEditModal from './ScenarioEditModal.js'; import parseAIJson from "../utils/parseAIJson.js"; // your shared parser import InfoTooltip from "./ui/infoTooltip.js"; +import differenceInMonths from 'date-fns/differenceInMonths'; import './CareerRoadmap.css'; import './MilestoneTimeline.css'; @@ -918,7 +919,6 @@ useEffect(() => { return () => ctrl.abort(); }, [strippedSocCode, userState, apiURL]); - // 8) Build financial projection async function buildProjection(milestones) { if (!milestones?.length) return; @@ -948,7 +948,6 @@ useEffect(() => { }); setImpactsById(map); // <-- saves for the modal - const f = financialProfile; const financialBase = { currentSalary: parseFloatOrZero(f.current_salary, 0), @@ -1024,6 +1023,24 @@ useEffect(() => { parseFloatOrZero(c.expected_salary) || parseFloatOrZero(f.current_salary, 0) }; + +/* ── NEW: auto-extend horizon to cover furthest milestone ── */ +let horizonYears = simulationYears; // default from the input box +if (allMilestones.length) { + // last dated milestone → Date object + const last = allMilestones + .filter(m => m.date) + .reduce( + (max, m) => (new Date(m.date) > max ? new Date(m.date) : max), + new Date() + ); + + const months = Math.ceil((last - new Date()) / (1000 * 60 * 60 * 24 * 30.44)); + const years = Math.ceil(months / 12) + 1; // +1 yr buffer + horizonYears = Math.max(simulationYears, years); +} + + const mergedProfile = { currentSalary: financialBase.currentSalary, monthlyExpenses: scenarioOverrides.monthlyExpenses, @@ -1055,7 +1072,7 @@ useEffect(() => { expectedSalary: collegeData.expectedSalary, startDate: new Date().toISOString().slice(0, 10), - simulationYears, + simulationYears: horizonYears, milestoneImpacts: allImpacts, interestStrategy,