- ScheduleFlightBody.tsx: hms regex capture uses `?? "0"` fallback;
inline IIFEs expose last-leg and transfer-to-next in narrowed scope.
- CityPickerPopup.tsx: row.city1/city2/city1Airports are lifted into
locals so the narrowing survives into JSX event handler closures.
Warning count: 55 → 41.
Replace `zoomLayers[c]![t]!` patterns with explicit null-guard
`continue` branches. The dimensions (2×5) are still initialized the
same way; the narrowing just makes the linter happy without changing
runtime behavior. Warning count: 65 → 55.
- eslint.config.js: disable no-non-null-assertion for *.test.ts/tsx and
tests/** (fixture-driven tests routinely use arr[0]! after a length
check — signal there is low).
- closestFlight.ts: replace flights.legs[0]! / flights[flights.length-1]!
with explicit null checks.
- FlightDetailsAccordion.tsx: refactor transition + meal/service
branches to use local consts narrowed by a preceding truthy check,
dropping the `leg.transition!.registration!` patterns.
Warning count: 190 → 65. Remaining warnings are pre-existing production-code
non-null assertions spread across the codebase.
- storage.ts: add sessionStore wrapper (getRaw/setRaw/delete/clear) so
transientPrefill + ScheduleStartPage tests don't trip the
no-restricted-globals rule.
- transientPrefill.ts + ScheduleStartPage.test.tsx: use sessionStore.
- closestFlight.ts: hoist bracket-index key so no newline-before-[ ASI.
- Test files: hoist typeof import(...) into named type alias with
type-only namespace import.
- Drop unused imports: FlightCard (Link, languageToLocale),
OnlineBoardDetailsPage (operatingCarrier),
ScheduleSearchPage (FlightList, inline import() types),
PageLayout (FeedbackButton).
- Drop react-hooks/exhaustive-deps disable comments for a rule not
registered in eslint.config.js.
Replace the inline 'Invalid parameters' fallbacks and the framework's
default '404' text with the existing Aeroflot 404 screen. Unknown
locale, malformed flight/route/station params, and unmatched URLs
(including bad paths like onlineboard//route/...) now all land on the
same ErrorPage component.
Angular's schedule renders 7 day pills ("20 пн … 26 вс") spanning the
active week, not weekly date ranges. Match that: tabs now render the
seven days of selectedMonday's week with day-num + weekday-abbr stack.
Prev/next arrows shift by full weeks. Day clicks scroll to the
matching day group in DayGroupedFlightList for the schedule UX.
Schedule list day accordion stays collapsed by default but auto-
opens the day matching today's date when it's in the visible week
window — mirrors Angular's p-accordion default-active behaviour
where today's flights are visible without a click. The user can
still collapse it; we never re-open after that for the same date.
Visual-diff URLs were hardcoded to a past date with the wrong React
URL format (Angular path-style /AAQ/16042026 instead of React's
single-segment /AAQ-20260420-00002400). Switch to dynamic
yyyyMMdd of today for onlineboard pages and Mon→Sun of the current
week for schedule. Schedule-route diff dropped from ~91% to ~28%
on desktop after these two fixes.
ANGULAR_BASE / ANGULAR_PATH_PREFIX / REACT_BASE / MOCK_ANGULAR /
MOCK_REACT env vars let the script target the live test env
(https://flights.test.aeroflot.ru/ru-ru) without code changes.
Used to rerun the Visual Parity Report against the live Angular
backend instead of a local ng serve.
Match Angular's p-accordion default-collapsed state on the schedule
results page. State now tracks expanded days (default empty)
instead of collapsed days (default empty), so the initial render
shows day headers only and the user clicks to reveal flights.
Schedule details page used to show only a one-line FlightCard and
stop. Reuse ScheduleFlightBody so each flight in the chain renders
the same per-leg layout the schedule results page uses (route
summary, leg cards, transit pill, share/Купить/Детали рейса
actions). Add a `Вернуться к Расписанию` back link to the header.
While here, fix the SEO title key — buildScheduleDetailsSeo was
calling SEO.SCHEDULE.DETAILS.TITLE with `flights={...}`, but the
i18n bundle only defines SEO.SCHEDULE.FLIGHT-DETAILS.TITLE with
`flightNumber={...}`. The unresolved key was leaking into the
document title as "SEO.SCHEDULE.DETAILS.TITLE".