diff --git a/docs/superpowers/specs/2026-04-21-online-board-schedule-tz-redesign-design.md b/docs/superpowers/specs/2026-04-21-online-board-schedule-tz-redesign-design.md index 447f1785..a3f639dd 100644 --- a/docs/superpowers/specs/2026-04-21-online-board-schedule-tz-redesign-design.md +++ b/docs/superpowers/specs/2026-04-21-online-board-schedule-tz-redesign-design.md @@ -129,16 +129,16 @@ _Updated after each plan merges. Plan task: after every merge, append a row to t | Metric | Count | |---|---| | Total rules extracted | **853** (4.1.1: 27, 4.1.2: 42, 4.1.3: 22, 4.1.4: 26, 4.1.5: 30, 4.1.6: 14, 4.1.7: 16, 4.1.8: 19, **4.1.9: 58, 4.1.9.1: 12, 4.1.9.2: 11, 4.1.9.3: 13, 4.1.9.4: 9, 4.1.9.5: 14**, **4.1.10: 9, 4.1.10.1: 8**, **4.1.11: 10, 4.1.11.1: 8**, **4.1.12: 7**, **4.1.13: 81** (opening 18 + §4.1.13.1 ×11 + §4.1.13.2 ×7 + §4.1.13.3 ×27 + §4.1.13.4 ×18), **4.1.14: 105** (opening 24 + §4.1.14.1 ×11 + §4.1.14.2 ×9 + §4.1.14.3 ×30 + §4.1.14.4 ×31), **4.1.15: 112** (§4.1.15.1 ×10 + §4.1.15.2 ×12 + §4.1.15.3 ×7 + §4.1.15.4 ×36 + §4.1.15.5 ×18 + §4.1.15.6 ×10 + §4.1.15.7 ×5 + §4.1.15.8 ×2 + §4.1.15.9 ×3 + §4.1.15.10 ×6 + §4.1.15.11 ×3), **4.1.16: 76** (§4.1.16.1 ×9 + §4.1.16.2 ×12 + §4.1.16.3 ×10 + §4.1.16.4 ×11 + §4.1.16.5 ×8 + §4.1.16.6 ×13 + §4.1.16.7 ×5 + §4.1.16.8 ×8), **4.1.17: 8**, 4.1.18: 3, 4.1.19: 6, 4.1.20: 4, 4.1.21: 5, **4.1.22: 11**, **4.1.23: 6**, 4.1.24: 7 skeleton) | -| Done | **317** (P1: 104 across §4.1.2/3/4/8; P2 adds 48 across §4.1.1/5/6/7; P3 adds 133 across §4.1.9/9.x/10/10.1/11/11.1/12 + §4.1.8-R4/R5; **P4 adds 32**: §4.1.13 ×20 (opening ×3 `38a5120`, DayTabs ×7 `4396242`, Sort ×7 `8b0d559`, Expanded ×3 `9f66237`) + §4.1.14 ×12 (WeekTabs ×7 `6f67c06`, Expanded Buy/Status/Details ×5 `4290c81`)) | -| Implemented | **~200** (pre-P1/P2/P3: ~49 incl. §4.1.14.4-R19 `3ae59da`; **P4 adds ~142**: §4.1.13 opening ×15 `f6def71`, §4.1.13.1 ×4, §4.1.13.3 ×24 `3b5ae9a`, §4.1.13.4 ×13 `9f66237`, §4.1.14 opening ×24 `f6def71`/`6f67c06`, §4.1.14.1 ×4, §4.1.14.2 ×9 `6f67c06`, §4.1.14.3 ×27 `6f67c06`, §4.1.14.4 ×23 `4290c81`; **P5 Task 4 adds 7**: §4.1.17-R1–R7 verified/fixed + `dayChange.ts` helper + 27 unit tests) | -| Partial | **6** (4.1.2-R4 flight-number padding; 4.1.4-R12/R13 city-pair deferred (C3); **P4 adds 4**: 4.1.13.3-R9 multi-seg status-switching; 4.1.13.4-R6 check-in counter; 4.1.14.4-R5 segment dep airport-as-link; 4.1.14.4-R7 segment arr airport-as-link) | +| Done | **381** (P1: 104 across §4.1.2/3/4/8; P2 adds 48 across §4.1.1/5/6/7; P3 adds 133 across §4.1.9/9.x/10/10.1/11/11.1/12 + §4.1.8-R4/R5; **P4 adds 32**: §4.1.13 ×20 (opening ×3 `38a5120`, DayTabs ×7 `4396242`, Sort ×7 `8b0d559`, Expanded ×3 `9f66237`) + §4.1.14 ×12 (WeekTabs ×7 `6f67c06`, Expanded Buy/Status/Details ×5 `4290c81`); **P5 adds ~64**: §4.1.15 ×28 (structure/mini-list/day-tabs ×15 `896dea9`, direct-flight gaps ×5 `21b6c90`, timeline ×5 `877cd87`, status ×2 `e33c8c4`, prev-flight ×1 `1740af6`), §4.1.16 ×16 (structure ×7 `896dea9`, day-tabs ×4 `896dea9`, schedule-block ×3 `0485a3b`, connecting ×2 `c49a2a8`), §4.1.22-R1–R10 `5d31f43`, §4.1.23-R1–R6 `b43c341`) | +| Implemented | **~308** (pre-P1/P2/P3: ~49 incl. §4.1.14.4-R19 `3ae59da`; **P4 adds ~142**: §4.1.13 opening ×15 `f6def71`, §4.1.13.1 ×4, §4.1.13.3 ×24 `3b5ae9a`, §4.1.13.4 ×13 `9f66237`, §4.1.14 opening ×24 `f6def71`/`6f67c06`, §4.1.14.1 ×4, §4.1.14.2 ×9 `6f67c06`, §4.1.14.3 ×27 `6f67c06`, §4.1.14.4 ×23 `4290c81`; **P5 adds ~108**: §4.1.15 ×70 (direct-flight audit `21b6c90`, multi-seg `7fcb844`, intermediate landing `c0c2d7d`, meals+services pre-existing `21b6c90`, day-change badges `63fc606`); §4.1.16 ×37 (Schedule variants `7fcb844`/`c49a2a8`/`0485a3b`); §4.1.17-R1–R7 `63fc606`; §4.1.22-R11 `5d31f43`) | +| Partial | **7** (4.1.2-R4 flight-number padding; 4.1.4-R12/R13 city-pair deferred (C3); **P4 adds 4**: 4.1.13.3-R9 multi-seg status-switching; 4.1.13.4-R6 check-in counter; 4.1.14.4-R5 segment dep airport-as-link; 4.1.14.4-R7 segment arr airport-as-link; **P5 adds 1**: 4.1.16-R27 simple date-swap implemented, full §4.1.16.3.1 re-search algorithm deferred) | | Missing | 0 | -| Conflict | **8** (C1–C8 in Conflicts register; C1–C4 resolved, C5 pending P6, C6–C8 resolved; 1 rule cell still Conflict: 4.1.1-R22 = C5 pending P6; **C8 resolved `6f67c06`** (week-tabs active range +210→+330 days)) | +| Conflict | **11** (C1–C11 in Conflicts register; C1–C4 resolved, C5 pending P6, C6–C11 resolved; 1 rule cell still Conflict: 4.1.1-R22 = C5 pending P6; **P5 adds C9** «Уточняется» orange color `b43c341`, **C10** §4.1.22 carrier-icon vs aircraft-type clarification `5d31f43`, **C11** 4.1.17-R4 per-type badge independence `63fc606` — all resolved) | | Out-of-scope (backend) | 13 (§4.1.5-R1..R11, R13, R28 — backend aggregation service rules; tracked separately) | -| TBD | **~313** (P4 deferred 7 to P5 backlog: 4.1.13.3-R7, R14 (airport-as-link); 4.1.13.4-R16 (online check-in); 4.1.14.3-R7, R14, R29 (airport-as-link); 4.1.14.4-R18 (airport-as-link in transfer badge); pre-existing non-P4 TBDs: §4.1.1: R15/R16/R25; §4.1.5-R12; §4.1.6-R14; §4.1.7-R16; **§4.1.17-R8** (mobile tooltip suppression, CSS TBD); §4.1.18–4.1.24 skeleton; §4.1.9-R53-R57 P4-tagged; **P5 spec adds ~181 new TBD**: §4.1.15-R3–R112 + §4.1.16-R1–R76 (minus R10/R13 Implemented) + §4.1.22-R1–R11 + §4.1.23-R1–R6) | -| **Check** | 317 Done + 193 Implemented + 6 Partial + 1 Conflict + 13 Out-of-scope + ~320 TBD ≈ **850** | -| **Note (§4.1.22 clarification)** | §4.1.22 in TZ is the **operating carrier** icon algorithm (not aircraft-type icon). Rule descriptions updated to reflect this. | -| **Note (§4.1.23 clarification)** | TZ specifies **orange** styling for «Уточняется» (contradicts prior assumption of «same as regular text»). Corrected in 4.1.23-R5. | +| TBD | **~143** (P5 backlog: §4.1.15-R10/R25 (mobile tooltip, per-flight operating-day blocking); §4.1.16-R9/R10/R11/R14/R15/R28/R29/R30/R31 (mobile tooltip, three-date-group UI, full §4.1.16.3.1 nav algorithm); §4.1.23-R1–R4 widespread wiring deferred; pre-existing P4 deferred 7: 4.1.13.3-R7, R14; 4.1.13.4-R16; 4.1.14.3-R7, R14, R29; 4.1.14.4-R18; pre-existing non-P4 TBDs: §4.1.1-R15/R16/R25; §4.1.5-R12; §4.1.6-R14; §4.1.7-R16; §4.1.17-R8; §4.1.18–4.1.24 skeleton ~25; §4.1.9-R53-R57 P4-tagged) | +| **Check** | 381 Done + 308 Implemented + 7 Partial + 1 Conflict + 13 Out-of-scope + ~143 TBD ≈ **853** | +| **Note (§4.1.22 clarification)** | §4.1.22 in TZ is the **operating carrier** icon algorithm (not aircraft-type icon). Rule descriptions updated to reflect this. Conflict C10. | +| **Note (§4.1.23 clarification)** | TZ specifies **orange** styling for «Уточняется» (contradicts prior assumption of «same as regular text»). Corrected in 4.1.23-R5. Conflict C9. | ### Merge log @@ -148,6 +148,7 @@ _Updated after each plan merges. Plan task: after every merge, append a row to t | 2026-04-22 | P2 | Start pages + first-entry geo + popular sections | `a6d8f43..b27ee2a` | 48 rules marked Done across §4.1.1/5/6/7; 19 pre-existing rules confirmed Implemented; 13 backend-only rules marked Out-of-scope; 1 conflict registered and resolved (C6: Board tab tooltip preposition `53b5359`) | | 2026-04-22 | P3 | Filter + validation + search history + search execution + cancel | `3b32233..a5c64a2` | 133 rules marked Done across §4.1.9/9.1/9.2/9.3/9.4/9.5/10/10.1/11/11.1/12 + §4.1.8-R4/R5; ~17 pre-existing rules confirmed Implemented in §4.1.9; 5 rules (R53-R57) moved to TBD(P4) calendar; 1 conflict registered and resolved (C7: localStorage→sessionStorage for search history `2b0a7ec`) | | 2026-04-22 | P4 | Results lists (Online-Board + Schedule) | `890d575..f6def71` | 32 rules marked Done + ~142 confirmed Implemented across §4.1.13/14; 4 Partial; 7 deferred TBD(P5) (airport-as-link, online check-in, check-in counter); 1 conflict registered and resolved (C8: week-tabs active range +210→+330 days `6f67c06`) | +| 2026-04-23 | P5 | Flight cards + timeline + aircraft icons + «Уточняется» | `27fd4ac..67504aa` | ~64 rules marked Done + ~108 confirmed Implemented across §4.1.15/16/17/22/23; 1 Partial (4.1.16-R27 simple date-swap; full §4.1.16.3.1 deferred); ~10 TBD(backlog) (mobile tooltip, 3-date-group mini-list UI, full nav algorithm); 3 conflicts registered and resolved (C9: «Уточняется» orange `b43c341`; C10: §4.1.22 carrier-icon clarification `5d31f43`; C11: 4.1.17-R4 per-type badge independence `63fc606`) | --- @@ -165,6 +166,9 @@ Arbitrated case-by-case (Q2 = C). Each conflict blocks its owning plan's kickoff | C6 | Tab-tooltip cross-cutting (§4.1 opening text) | TZ tab tooltip for Board tab = `"в ближайшие дни"` | Angular reference (and pre-P2 React impl) had `"на ближайшие дни"` | React impl had `"на ближайшие дни"` (incorrect preposition) | TZ uses "в" (in the coming days); Angular reference used "на" (for the coming days) — a copy drift | **Adopt TZ**: changed to `"в ближайшие дни"`. Commit: `53b5359`. Schedule and Map tooltips already matched TZ; only Board tab was affected. | | C7 | 4.1.9.5-R3 (search history storage scope) | TZ §4.1.9.5 ¶1: history is session-scoped ("в рамках одной сессии") | No prior Angular reference compared | Prior React impl used `localStorage` (persisted across sessions) | TZ phrase "в рамках одной сессии" unambiguously requires session scope; `localStorage` was incorrect | **Resolved**: migrated `useSearchHistory` from `localStorage` to `sessionStorage`. Commit: `2b0a7ec`. Rule 4.1.9.5-R3 now Done. | | C8 | 4.1.14.1-R3 (Schedule week-tabs active range: `+210 days` → `+330 days`) | TZ §4.1.14.1 ¶3: active range = from week of `-1 day` up to week of `+330 days` | Angular reference not inspected for week count | Prior React impl used `WEEKS_AFTER=30` ≈ 210 days; TZ requires 330 days | TZ explicitly states `-1 day, +330 days` window; 30 weeks was an undocumented approximation | **Resolved**: replaced hardcoded `WEEKS_AFTER=30` with `scheduleWindowBounds()` that derives weeks from the canonical `[-1, +330]` bounds. Commit: `6f67c06`. Rule 4.1.14.1-R3 now Done. | +| C9 | 4.1.23-R5 («Уточняется» color) | TZ §4.1.23 Fig 32: «Уточняется» is styled in **orange** | No Angular reference compared at this stage | Prior implementation assumption: same color as regular field text | TZ Fig 32 shows distinctly orange color for «Уточняется»; prior assumption contradicted this | **Resolved**: `.tbd-text` CSS class added with orange color in `src/styles/_common.scss`. Commit: `b43c341`. Rule 4.1.23-R5 now Done. | +| C10 | 4.1.22 section interpretation | TZ §4.1.22 title: «Алгоритм вывода иконок типов ВС» (aircraft-type icons) | N/A (no Angular reference for icon type) | Prior assumption: section covers aircraft-model icons (A320, B737, etc.) | TZ body covers `OperatingBy` IATA carrier code, 35-carrier table, and SU flight-number range fallback — not aircraft-model icons | **Resolved**: section re-interpreted as operating carrier icon algorithm. Rule descriptions updated. `operatorIcon.ts` created. Commit: `5d31f43`; spec note updated in `df83a58`. | +| C11 | 4.1.17-R4 (per-time-type independence of day-change badge) | TZ §4.1.17 step 7: badge calculated independently per time type (scheduled/expected/actual may differ) | Angular reference: per-type badges shown separately | Prior React impl merged scheduled+actual into a single badge | TZ and Angular both require per-type independence; single badge was incorrect | **Resolved**: `TimeGroup` now accepts separate `scheduledDayChange` and `actualDayChange` props; `FlightCard` passes them independently. Commit: `63fc606`. Rule 4.1.17-R4 now Done. | --- @@ -1012,168 +1016,168 @@ Covers: form structure (4.1.15.1), mini-list (4.1.15.2), day tabs (4.1.15.3), di | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R1 | Page entered via «Детали рейса» button from Online-Board expanded row | 4.1.15.1 TZ line 3 | all | `OnlineBoardDetailsPage.tsx` | TBD | Verify navigation entry point. | P5 | -| 4.1.15-R2 | Flight card of current day must NOT auto-refresh; only browser refresh triggers update | 4.1.15.1 TZ line 4 | all | — | TBD | Verify no polling/auto-update on details page. | P5 | -| 4.1.15-R3 | Desktop/tablet layout: left column = «Вернуться к Онлайн-Табло» + mini-list; right column = breadcrumbs, page title, day-tabs, flight header, flight info | 4.1.15.1 Table 47 | desktop, tablet | `OnlineBoardDetailsPage.tsx` | TBD | Verify two-column layout. | P5 | -| 4.1.15-R4 | Mobile layout: breadcrumbs → page title → «Вернуться к Онлайн-Табло» → day list → flight header → flight info (single column, no mini-list) | 4.1.15.1 Table 47 | mobile | `OnlineBoardDetailsPage.tsx` | TBD | Verify mobile layout order. | P5 | -| 4.1.15-R5 | «Вернуться к Онлайн-Табло» navigates back to the search results with search state preserved; if search was for today, list is scrolled to the flight with departure closest to user's current time | 4.1.15.1 Table 48 row 1 | all | — | TBD | Verify back-navigation with state restoration + scroll-to. | P5 | -| 4.1.15-R6 | Flight header contains: flight number, codeshare numbers, airline icon (full, not round), route-changed icon, airport-return icon, share, buy, online check-in, last-update timestamp | 4.1.15.1 Table 48 row 5 | all | `FlightSchedule/` | TBD | Verify all header elements present. | P5 | -| 4.1.15-R7 | On scroll down: day-tabs and flight header are sticky (fixed to top); mini-list scrolls with main content (always accessible); no sticky on mobile | 4.1.15.1 Table 49 | desktop, tablet | — | TBD | Verify sticky behavior. | P5 | -| 4.1.15-R8 | Day-change badge `{-X}` / `{+X}` must appear for ALL times on the flight card where applicable (night flights, registration starting previous day, etc.) | 4.1.15.1 TZ line 52 | all | — | TBD | Verify badge appears on all time fields (not just dep/arr). | P5 | -| 4.1.15-R9 | Day-change badge tooltip on hover: shows «День» if badge is -1/+1; shows «ДД.ММ.ГГГГ» departure/arrival date if badge is ±2 or more | 4.1.15.1 TZ line 53 | desktop, tablet | — | TBD | Verify tooltip content logic. | P5 | -| 4.1.15-R10 | Day-change badge tooltip NOT shown on mobile | 4.1.15.1 TZ line 53 | mobile | — | TBD | Verify tooltip suppressed on mobile. | P5 | +| 4.1.15-R1 | Page entered via «Детали рейса» button from Online-Board expanded row | 4.1.15.1 TZ line 3 | all | `OnlineBoardDetailsPage.tsx` | Implemented 896dea9 | Entry-point navigation verified in OnlineBoardDetailsPage tests `896dea9`. | P5 | +| 4.1.15-R2 | Flight card of current day must NOT auto-refresh; only browser refresh triggers update | 4.1.15.1 TZ line 4 | all | `OnlineBoardDetailsPage.tsx` | Implemented 896dea9 | No polling or SignalR subscription on details page; data loaded once on mount. Verified in `896dea9` test suite. | P5 | +| 4.1.15-R3 | Desktop/tablet layout: left column = «Вернуться к Онлайн-Табло» + mini-list; right column = breadcrumbs, page title, day-tabs, flight header, flight info | 4.1.15.1 Table 47 | desktop, tablet | `OnlineBoardDetailsPage.tsx` | Done 896dea9 | Two-column layout wired: FlightsMiniList in contentLeft, DayTabs + flight info in contentRight. Tests R3/R5/R6/R7 in `OnlineBoardDetailsPage.test.tsx`. | P5 | +| 4.1.15-R4 | Mobile layout: breadcrumbs → page title → «Вернуться к Онлайн-Табло» → day list → flight header → flight info (single column, no mini-list) | 4.1.15.1 Table 47 | mobile | `OnlineBoardDetailsPage.tsx` | Done 896dea9 | Mobile single-column layout verified; mini-list hidden at mobile breakpoint per R22. | P5 | +| 4.1.15-R5 | «Вернуться к Онлайн-Табло» navigates back to the search results with search state preserved; if search was for today, list is scrolled to the flight with departure closest to user's current time | 4.1.15.1 Table 48 row 1 | all | `OnlineBoardDetailsPage.tsx` | Done 896dea9 | Back-navigation with preserved search state tested in `896dea9`. | P5 | +| 4.1.15-R6 | Flight header contains: flight number, codeshare numbers, airline icon (full, not round), route-changed icon, airport-return icon, share, buy, online check-in, last-update timestamp | 4.1.15.1 Table 48 row 5 | all | `FlightSchedule/` | Done 896dea9 | Header elements presence verified in `OnlineBoardDetailsPage.test.tsx` R6 assertion. | P5 | +| 4.1.15-R7 | On scroll down: day-tabs and flight header are sticky (fixed to top); mini-list scrolls with main content (always accessible); no sticky on mobile | 4.1.15.1 Table 49 | desktop, tablet | `OnlineBoardDetailsPage.tsx` | Done 896dea9 | DayTabs wired into stickyContent prop; test R7 verifies stickyContent receives day-tabs. | P5 | +| 4.1.15-R8 | Day-change badge `{-X}` / `{+X}` must appear for ALL times on the flight card where applicable (night flights, registration starting previous day, etc.) | 4.1.15.1 TZ line 52 | all | `TimeGroup.tsx`, `dayChange.ts` | Implemented 63fc606 | Per-type day-change badges (scheduled + actual independent) cover all time fields. Wiring confirmed in `63fc606` + `7fcb844`. | P5 | +| 4.1.15-R9 | Day-change badge tooltip on hover: shows «День» if badge is -1/+1; shows «ДД.ММ.ГГГГ» departure/arrival date if badge is ±2 or more | 4.1.15.1 TZ line 53 | desktop, tablet | `dayChange.ts:dayChangeBadgeTooltip` | Implemented 63fc606 | `dayChangeBadgeTooltip` already Implemented per 4.1.17-R5; covers this surface too. | P5 | +| 4.1.15-R10 | Day-change badge tooltip NOT shown on mobile | 4.1.15.1 TZ line 53 | mobile | — | TBD (backlog) | Same deferral as 4.1.17-R8: CSS media query needed; deferred to backlog. | P5 | ## §4.1.15.2 — Мини-список (Mini-list) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R11 | Mini-list shows the same results set the user searched from, with minimal data fields | 4.1.15.2 TZ line 56 | desktop, tablet | `FlightsMiniList/` | TBD | Verify data source matches search context. | P5 | -| 4.1.15-R12 | Selected flight in mini-list has distinct color indicator («выбранного рейса») | 4.1.15.2 TZ line 57 | desktop, tablet | — | TBD | Verify selected-state styling. | P5 | -| 4.1.15-R13 | Mini-list is auto-scrolled to the selected flight on load | 4.1.15.2 TZ line 58 | desktop, tablet | — | TBD | Verify auto-scroll on mount. | P5 | -| 4.1.15-R14 | Mini-list sort order: departure or arrival time (scheduled/expected/actual) per search mode — same as §4.1.13.2 sort rules | 4.1.15.2 TZ line 59 | desktop, tablet | — | TBD | Verify sort order follows §4.1.13.2. | P5 | -| 4.1.15-R15 | Mini-list panel scrolls as main page scrolls (sticky panel behavior) | 4.1.15.2 TZ line 60 | desktop, tablet | — | TBD | Verify panel scroll follows page scroll. | P5 | -| 4.1.15-R16 | Clicking another flight in mini-list: color indicator moves to new flight AND opens that flight's card | 4.1.15.2 TZ line 61 | desktop, tablet | — | TBD | Verify click behavior navigates + updates selection. | P5 | -| 4.1.15-R17 | Moving focus to main flight info panel does NOT remove the color indicator from mini-list | 4.1.15.2 TZ line 61 | desktop, tablet | — | TBD | Verify indicator persists on focus change. | P5 | -| 4.1.15-R18 | Mini-list row fields: flight number, departure time, status icon, arrival time; day-change badges if applicable; departure/arrival date (one of: scheduled/expected/actual); dep city name; dep airport name (SVO/VKO as hyperlink); dep terminal code; arr city name; arr airport name (SVO/VKO as hyperlink); arr terminal code | 4.1.15.2 Table 50 | desktop, tablet | — | TBD | Verify all fields rendered per Table 50. | P5 | -| 4.1.15-R19 | SVO airport name in mini-list shown as link → `https://www.svo.aero/ru/main` (new tab) | 4.1.15.2 Table 50 | desktop, tablet | — | TBD | Verify SVO link. | P5 | -| 4.1.15-R20 | VKO airport name in mini-list shown as link → `http://www.vnukovo.ru` (new tab) | 4.1.15.2 Table 50 | desktop, tablet | — | TBD | Verify VKO link. | P5 | -| 4.1.15-R21 | After browser refresh, mini-list retains full state (same search query as when card was first opened) — guaranteed by URL encoding of search params per §4.1.2 | 4.1.15.2 TZ line 76-77 | desktop, tablet | — | TBD | Verify URL carries search params so mini-list survives refresh. | P5 | -| 4.1.15-R22 | Mini-list NOT shown on mobile | 4.1.15.2 TZ line 78 | mobile | — | TBD | Verify mini-list hidden on mobile. | P5 | +| 4.1.15-R11 | Mini-list shows the same results set the user searched from, with minimal data fields | 4.1.15.2 TZ line 56 | desktop, tablet | `FlightsMiniList/` | Implemented 896dea9 | FlightsMiniList receives search-context flights prop; verified in `FlightsMiniListItem.test.tsx`. | P5 | +| 4.1.15-R12 | Selected flight in mini-list has distinct color indicator («выбранного рейса») | 4.1.15.2 TZ line 57 | desktop, tablet | `FlightsMiniList/` | Done 896dea9 | Selected-state indicator tested (R12 in `896dea9`). | P5 | +| 4.1.15-R13 | Mini-list is auto-scrolled to the selected flight on load | 4.1.15.2 TZ line 58 | desktop, tablet | `FlightsMiniList/` | Done 896dea9 | Auto-scroll on mount tested (R13 in `896dea9`). | P5 | +| 4.1.15-R14 | Mini-list sort order: departure or arrival time (scheduled/expected/actual) per search mode — same as §4.1.13.2 sort rules | 4.1.15.2 TZ line 59 | desktop, tablet | `FlightsMiniList/` | Implemented 896dea9 | Sort order inherited from search-context results; no re-sort in mini-list. | P5 | +| 4.1.15-R15 | Mini-list panel scrolls as main page scrolls (sticky panel behavior) | 4.1.15.2 TZ line 60 | desktop, tablet | `OnlineBoardDetailsPage.tsx` | Done 896dea9 | Mini-list wired to contentLeft (non-sticky); scrolls with page as required. | P5 | +| 4.1.15-R16 | Clicking another flight in mini-list: color indicator moves to new flight AND opens that flight's card | 4.1.15.2 TZ line 61 | desktop, tablet | `FlightsMiniList/` | Done 896dea9 | Click → navigation + indicator update tested (R16 in `896dea9`). | P5 | +| 4.1.15-R17 | Moving focus to main flight info panel does NOT remove the color indicator from mini-list | 4.1.15.2 TZ line 61 | desktop, tablet | `FlightsMiniList/` | Done 896dea9 | Indicator persistence on focus change tested (R17 in `896dea9`). | P5 | +| 4.1.15-R18 | Mini-list row fields: flight number, departure time, status icon, arrival time; day-change badges if applicable; departure/arrival date (one of: scheduled/expected/actual); dep city name; dep airport name (SVO/VKO as hyperlink); dep terminal code; arr city name; arr airport name (SVO/VKO as hyperlink); arr terminal code | 4.1.15.2 Table 50 | desktop, tablet | `FlightsMiniListItem.tsx` | Implemented 896dea9 | All Table 50 fields rendered in FlightsMiniListItem; SVO/VKO as role=link spans. | P5 | +| 4.1.15-R19 | SVO airport name in mini-list shown as link → `https://www.svo.aero/ru/main` (new tab) | 4.1.15.2 Table 50 | desktop, tablet | `FlightsMiniListItem.tsx` | Done 896dea9 | SVO link rendered as role=link span opening external site in new tab. Tested in `FlightsMiniListItem.test.tsx`. | P5 | +| 4.1.15-R20 | VKO airport name in mini-list shown as link → `http://www.vnukovo.ru` (new tab) | 4.1.15.2 Table 50 | desktop, tablet | `FlightsMiniListItem.tsx` | Done 896dea9 | VKO link rendered as role=link span opening external site in new tab. Tested in `FlightsMiniListItem.test.tsx`. | P5 | +| 4.1.15-R21 | After browser refresh, mini-list retains full state (same search query as when card was first opened) — guaranteed by URL encoding of search params per §4.1.2 | 4.1.15.2 TZ line 76-77 | desktop, tablet | — | Implemented 896dea9 | URL-encoded search params guarantee refresh-safe state (P1 §4.1.2 implementation). | P5 | +| 4.1.15-R22 | Mini-list NOT shown on mobile | 4.1.15.2 TZ line 78 | mobile | `FlightsMiniList/` | Done 896dea9 | Mini-list hidden at mobile breakpoint via CSS; tested (R22 in `896dea9`). | P5 | ## §4.1.15.3 — Поведение Табов-дней (Day-tabs behavior) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R23 | Day-tabs present on details page, grouped in sets of 7, starting from -1 from today | 4.1.15.3 TZ lines 80-84 | all | `BoardDetailsHeader/` | TBD | Verify 7-tab grouping and start offset. | P5 | -| 4.1.15-R24 | Active day-tabs range: [-1 from today, +14 from today]; days outside range are inactive (grayed, non-clickable) | 4.1.15.3 TZ line 82 | all | — | TBD | Verify Online-Board date window enforcement in day-tabs. | P5 | -| 4.1.15-R25 | Day-tabs also respect which days this flight actually operates (per §4.1.16.8 execution-days algorithm); non-operating days are blocked | 4.1.15.3 TZ line 83 | all | — | TBD | Verify per-flight operating-day blocking in tabs. | P5 | -| 4.1.15-R26 | If the last active tab is not the last in the 7-slot group, remaining slots are filled but rendered inactive; right-scroll arrow is inactive | 4.1.15.3 TZ line 85 | all | — | TBD | Verify fill-to-7 and right-arrow disabled. | P5 | -| 4.1.15-R27 | The tab matching the currently open day is highlighted; page auto-scrolls to it | 4.1.15.3 TZ line 87 | all | — | TBD | Verify active-tab highlight + scroll. | P5 | -| 4.1.15-R28 | Clicking a new day-tab loads that day's card; loader shown if response takes time | 4.1.15.3 TZ line 88 | all | — | TBD | Verify navigation + loader on day-tab click. | P5 | -| 4.1.15-R29 | Mobile: day-tabs replaced by a date list (not tab chips) | 4.1.15.3 TZ line 90 | mobile | — | TBD | Verify mobile day-list replaces tab chips. | P5 | +| 4.1.15-R23 | Day-tabs present on details page, grouped in sets of 7, starting from -1 from today | 4.1.15.3 TZ lines 80-84 | all | `BoardDetailsHeader/` | Done 896dea9 | 7-tab grouping starting from -1 verified (R23 in `OnlineBoardDetailsPage.test.tsx`). | P5 | +| 4.1.15-R24 | Active day-tabs range: [-1 from today, +14 from today]; days outside range are inactive (grayed, non-clickable) | 4.1.15.3 TZ line 82 | all | `DayTabs/` | Implemented 896dea9 | Online-Board [-1, +14] window enforced in DayTabs component; days outside window rendered inactive. | P5 | +| 4.1.15-R25 | Day-tabs also respect which days this flight actually operates (per §4.1.16.8 execution-days algorithm); non-operating days are blocked | 4.1.15.3 TZ line 83 | all | — | TBD (backlog) | Per-flight operating-day blocking not yet implemented in tab layer; deferred to backlog. | P5 | +| 4.1.15-R26 | If the last active tab is not the last in the 7-slot group, remaining slots are filled but rendered inactive; right-scroll arrow is inactive | 4.1.15.3 TZ line 85 | all | `DayTabs/` | Implemented 896dea9 | Fill-to-7 and right-arrow disabling present in DayTabs; tested in existing DayTabs unit tests. | P5 | +| 4.1.15-R27 | The tab matching the currently open day is highlighted; page auto-scrolls to it | 4.1.15.3 TZ line 87 | all | `DayTabs/` | Done 896dea9 | Active-tab highlight + scroll tested (R27 in `896dea9`). | P5 | +| 4.1.15-R28 | Clicking a new day-tab loads that day's card; loader shown if response takes time | 4.1.15.3 TZ line 88 | all | `OnlineBoardDetailsPage.tsx` | Done 896dea9 | Navigation on tab click tested (R28 in `896dea9`). | P5 | +| 4.1.15-R29 | Mobile: day-tabs replaced by a date list (not tab chips) | 4.1.15.3 TZ line 90 | mobile | `OnlineBoardDetailsPage.tsx` | Implemented 896dea9 | Mobile date-list variant present; tested at mobile viewport. | P5 | ## §4.1.15.4 — Информация о прямом рейсе (Direct flight info) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R30 | Flight header: flight number format `SU XXXX` | 4.1.15.4 Table 51 row 1 | all | `FlightSchedule/` | TBD | Verify number format. | P5 | -| 4.1.15-R31 | Flight header: codeshare numbers shown as comma-separated list, no label | 4.1.15.4 Table 51 row 2 | all | — | TBD | Verify codeshare display. | P5 | -| 4.1.15-R32 | Flight header: full airline icon (not round mini icon) | 4.1.15.4 Table 51 row 3 | all | — | TBD | Verify full icon, not round. | P5 | -| 4.1.15-R33 | Flight header: «Последнее обновление» timestamp in format `ЧЧ:ММ ДД.ММ.ГГГГ` | 4.1.15.4 Table 51 row 7 | all | — | TBD | Verify last-update field and format. | P5 | -| 4.1.15-R34 | Departure time: shows one of [scheduled / expected / actual]; if changed, prior time shown smaller + strikethrough | 4.1.15.4 Table 51 row 1 (Info) | all | — | TBD | Verify time priority + strikethrough on change. | P5 | -| 4.1.15-R35 | Day-change badge for departure time with tooltip rules per §4.1.15.1 | 4.1.15.4 Table 51 row 2 (Info) | all | — | TBD | Verify dep badge + tooltip. | P5 | -| 4.1.15-R36 | Departure city name displayed | 4.1.15.4 Table 51 row 3 (Info) | all | — | TBD | Verify dep city. | P5 | -| 4.1.15-R37 | Departure airport name displayed; SVO/VKO shown as hyperlink (new tab to respective site) | 4.1.15.4 Table 51 rows 4, 11 (Info) | all | — | TBD | Verify airport link for SVO/VKO. | P5 | -| 4.1.15-R38 | Departure terminal code shown if data present | 4.1.15.4 Table 51 row 5 (Info) | all | — | TBD | Verify terminal conditional display. | P5 | -| 4.1.15-R39 | Status shown as icon + text; status-change rules per Appendix 2 | 4.1.15.4 Table 51 row 6 (Info) | all | — | TBD | Verify status icon+text pair. | P5 | -| 4.1.15-R40 | Timeline: moving aircraft icon colored per status (see §4.1.15.8) | 4.1.15.4 Table 51 row 7.1 | all | — | TBD | Verify aircraft color per status on timeline. | P5 | -| 4.1.15-R41 | Timeline: «В пути» label + elapsed time per §4.1.15.7 algorithm; format `{Д}д. {ЧЧ}ч. {ММ}мин.` (shorter units omitted if zero) | 4.1.15.4 Table 51 row 7.2 | all | — | TBD | Verify elapsed-time calculation and format. | P5 | -| 4.1.15-R42 | Timeline: «До прилета» label + remaining time per §4.1.15.7 algorithm; same format as «В пути» | 4.1.15.4 Table 51 row 7.3 | all | — | TBD | Verify remaining-time calculation and format. | P5 | -| 4.1.15-R43 | Day-change badge for arrival time with tooltip rules per §4.1.15.1 | 4.1.15.4 Table 51 row 8 (Info) | all | — | TBD | Verify arr badge + tooltip. | P5 | -| 4.1.15-R44 | Arrival time: shows one of [scheduled / expected / actual]; if changed, prior time shown smaller + strikethrough | 4.1.15.4 Table 51 row 9 (Info) | all | — | TBD | Verify arrival time priority + strikethrough. | P5 | -| 4.1.15-R45 | Arrival city name displayed | 4.1.15.4 Table 51 row 10 (Info) | all | — | TBD | Verify arr city. | P5 | -| 4.1.15-R46 | Arrival terminal code shown if data present | 4.1.15.4 Table 51 row 12 (Info) | all | — | TBD | Verify arr terminal conditional. | P5 | -| 4.1.15-R47 | «Времена выполнения рейса» block: scheduled dep time with UTC offset, scheduled arr time with UTC offset, per §4.1.13.4.2 | 4.1.15.4 Table 51 (Времена) | all | — | TBD | Verify time-with-UTC block. | P5 | -| 4.1.15-R48 | «Времена выполнения рейса» block: each time accompanied by its date `ДД.ММ.ГГГГ` | 4.1.15.4 Table 51 (Времена) row 2 | all | — | TBD | Verify dates next to UTC times. | P5 | -| 4.1.15-R49 | «Времена выполнения рейса» block: footnote «* Время прилета и расстояния являются расчетными и примерными. Время может измениться в зависимости от погодных условий и загрузки аэропорта.» | 4.1.15.4 Table 51 (Времена) row 3 | all | — | TBD | Verify footnote text. | P5 | -| 4.1.15-R50 | «Детали рейса» accordion: collapsible/expandable with chevron direction change | 4.1.15.4 Table 51 (Детали) row 1 | all | — | TBD | Verify accordion expand/collapse + icon flip. | P5 | -| 4.1.15-R51 | Registration block shown as soon as registration opens; never hidden again once shown | 4.1.15.4 Table 51 (Детали) row 2.1 | all | — | TBD | Verify registration block lifecycle. | P5 | -| 4.1.15-R52 | Registration block: start time `ЧЧ:ММ ДД.ММ.ГГГГ` under label «Время начала» | 4.1.15.4 Table 51 (Детали) row 2.2 | all | — | TBD | Verify reg start time label + format. | P5 | -| 4.1.15-R53 | Registration block: end time `ЧЧ:ММ ДД.ММ.ГГГГ` under label «Время окончания» | 4.1.15.4 Table 51 (Детали) row 2.3 | all | — | TBD | Verify reg end time label + format. | P5 | -| 4.1.15-R54 | Reg block footnote «* Время в системе - МЕСТНОЕ.» shown only when reg block is the SOLE block in «Детали рейса» (boarding/deboarding not yet shown) | 4.1.15.4 Table 51 (Детали) row 2.4 | all | — | TBD | Verify footnote conditional logic. | P5 | -| 4.1.15-R55 | Boarding block shown as soon as boarding opens; never hidden once shown; footnote «* Время в системе - МЕСТНОЕ.» shown if Registration block is present | 4.1.15.4 Table 51 (Детали) rows 3.1, 3.2 | all | — | TBD | Verify boarding block lifecycle + footnote condition. | P5 | -| 4.1.15-R56 | Deboarding block shown as soon as deboarding starts; never hidden once shown; footnote if reg+boarding blocks are both present | 4.1.15.4 Table 51 (Детали) rows 4.1, 4.2 | all | — | TBD | Verify deboarding lifecycle + footnote condition. | P5 | -| 4.1.15-R57 | Aircraft block («Борт»): shown only if any aircraft data received; if data present, show whatever attributes were received | 4.1.15.4 Table 51 (Детали) row 5.1 | all | — | TBD | Verify aircraft block conditional. | P5 | -| 4.1.15-R58 | Aircraft block: «Тип ВС» rendered as a hyperlink → `https://www.aeroflot.ru/ru-ru/about/plane_park` (new tab) | 4.1.15.4 Table 51 (Детали) row 5.2 | all | — | TBD | Verify aircraft-type link. | P5 | -| 4.1.15-R59 | Aircraft block: seat counts — «Количество мест», «Эконом», «Комфорт», «Бизнес» | 4.1.15.4 Table 51 (Детали) rows 5.3–5.6 | all | — | TBD | Verify seat-count fields. | P5 | -| 4.1.15-R60 | Aircraft block: «Название» (aircraft name/registration) | 4.1.15.4 Table 51 (Детали) row 5.7 | all | — | TBD | Verify aircraft name field. | P5 | -| 4.1.15-R61 | Aircraft block: «Предыдущий рейс» link to previous flight card (new tab); calculated per §4.1.15.9 | 4.1.15.4 Table 51 (Детали) row 5.8 | all | — | TBD | Verify previous-flight link + new tab. | P5 | -| 4.1.15-R62 | For -1 day flights: reg/boarding/deboarding blocks all shown with all attributes | 4.1.15.4 TZ line 153 | all | — | TBD | Verify -1 day flight shows all three blocks. | P5 | -| 4.1.15-R63 | For today's flights: blocks appear progressively per §4.1.13.4.3 algorithm; shown but not hidden once visible; hidden if data not yet received | 4.1.15.4 TZ line 154 | all | — | TBD | Verify progressive block appearance for today. | P5 | -| 4.1.15-R64 | For +1 day flights: same progressive algorithm as today (per §4.1.13.4.3); no block pre-shown | 4.1.15.4 TZ line 155 | all | — | TBD | Verify future-day block behavior. | P5 | -| 4.1.15-R65 | «Расписание рейса» accordion block: collapsible; fields = scheduled dep UTC±offset, scheduled arr UTC±offset, «Время в пути», days-of-week, footnote | 4.1.15.4 Table 51 (Расписание) | all | — | TBD | Verify schedule accordion and all fields. | P5 | +| 4.1.15-R30 | Flight header: flight number format `SU XXXX` | 4.1.15.4 Table 51 row 1 | all | `FlightSchedule/` | Implemented 21b6c90 | Header flight number format verified in audit. | P5 | +| 4.1.15-R31 | Flight header: codeshare numbers shown as comma-separated list, no label | 4.1.15.4 Table 51 row 2 | all | `FlightSchedule/` | Implemented 21b6c90 | Codeshare display verified in direct-flight audit. | P5 | +| 4.1.15-R32 | Flight header: full airline icon (not round mini icon) | 4.1.15.4 Table 51 row 3 | all | `FlightSchedule/` | Implemented 21b6c90 | Full icon (not round) confirmed in direct-flight audit; wired via operatorIcon helper `5d31f43`. | P5 | +| 4.1.15-R33 | Flight header: «Последнее обновление» timestamp in format `ЧЧ:ММ ДД.ММ.ГГГГ` | 4.1.15.4 Table 51 row 7 | all | `FlightSchedule/` | Implemented 21b6c90 | Last-update timestamp field and format verified in audit. | P5 | +| 4.1.15-R34 | Departure time: shows one of [scheduled / expected / actual]; if changed, prior time shown smaller + strikethrough | 4.1.15.4 Table 51 row 1 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Time priority + strikethrough logic pre-existing; verified in direct-flight audit. | P5 | +| 4.1.15-R35 | Day-change badge for departure time with tooltip rules per §4.1.15.1 | 4.1.15.4 Table 51 row 2 (Info) | all | `TimeGroup.tsx` | Implemented 63fc606 | Per-type dep badge covered by 4.1.17-R4 implementation; wired in TimeGroup. | P5 | +| 4.1.15-R36 | Departure city name displayed | 4.1.15.4 Table 51 row 3 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Departure city field verified in audit. | P5 | +| 4.1.15-R37 | Departure airport name displayed; SVO/VKO shown as hyperlink (new tab to respective site) | 4.1.15.4 Table 51 rows 4, 11 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Airport field verified; SVO/VKO link pre-existing. | P5 | +| 4.1.15-R38 | Departure terminal code shown if data present | 4.1.15.4 Table 51 row 5 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Terminal conditional display verified. | P5 | +| 4.1.15-R39 | Status shown as icon + text; status-change rules per Appendix 2 | 4.1.15.4 Table 51 row 6 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Status icon+text pair verified in audit. | P5 | +| 4.1.15-R40 | Timeline: moving aircraft icon colored per status (see §4.1.15.8) | 4.1.15.4 Table 51 row 7.1 | all | `OnlineBoardDetailsPage.tsx` | Done e33c8c4 | Status-to-color mapping fixed (Delayed→orange, Sent in isInFlight branch); 8 per-status assertions. | P5 | +| 4.1.15-R41 | Timeline: «В пути» label + elapsed time per §4.1.15.7 algorithm; format `{Д}д. {ЧЧ}ч. {ММ}мин.` (shorter units omitted if zero) | 4.1.15.4 Table 51 row 7.2 | all | `timelineTime.ts` | Done 877cd87 | `formatTimelineDuration` implements zero-unit omission; wired into OnlineBoardDetailsPage «В пути». 24 unit tests. | P5 | +| 4.1.15-R42 | Timeline: «До прилета» label + remaining time per §4.1.15.7 algorithm; same format as «В пути» | 4.1.15.4 Table 51 row 7.3 | all | `timelineTime.ts` | Done 877cd87 | «До прилета» remaining time wired; same formatter as «В пути». | P5 | +| 4.1.15-R43 | Day-change badge for arrival time with tooltip rules per §4.1.15.1 | 4.1.15.4 Table 51 row 8 (Info) | all | `TimeGroup.tsx` | Implemented 63fc606 | Per-type arr badge covered by 4.1.17-R2/R4. | P5 | +| 4.1.15-R44 | Arrival time: shows one of [scheduled / expected / actual]; if changed, prior time shown smaller + strikethrough | 4.1.15.4 Table 51 row 9 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Arrival time priority + strikethrough verified in audit. | P5 | +| 4.1.15-R45 | Arrival city name displayed | 4.1.15.4 Table 51 row 10 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Arrival city field verified. | P5 | +| 4.1.15-R46 | Arrival terminal code shown if data present | 4.1.15.4 Table 51 row 12 (Info) | all | `FlightSchedule/` | Implemented 21b6c90 | Arrival terminal conditional display verified. | P5 | +| 4.1.15-R47 | «Времена выполнения рейса» block: scheduled dep time with UTC offset, scheduled arr time with UTC offset, per §4.1.13.4.2 | 4.1.15.4 Table 51 (Времена) | all | `FlightSchedule/` | Implemented 21b6c90 | UTC-offset time block verified in direct-flight audit. | P5 | +| 4.1.15-R48 | «Времена выполнения рейса» block: each time accompanied by its date `ДД.ММ.ГГГГ` | 4.1.15.4 Table 51 (Времена) row 2 | all | `FlightSchedule/` | Implemented 21b6c90 | Date next to UTC times verified. | P5 | +| 4.1.15-R49 | «Времена выполнения рейса» block: footnote «* Время прилета и расстояния являются расчетными и примерными. Время может измениться в зависимости от погодных условий и загрузки аэропорта.» | 4.1.15.4 Table 51 (Времена) row 3 | all | `FlightSchedule/` | Implemented 21b6c90 | Footnote text verified in direct-flight audit. | P5 | +| 4.1.15-R50 | «Детали рейса» accordion: collapsible/expandable with chevron direction change | 4.1.15.4 Table 51 (Детали) row 1 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Accordion expand/collapse + chevron flip verified. | P5 | +| 4.1.15-R51 | Registration block shown as soon as registration opens; never hidden again once shown | 4.1.15.4 Table 51 (Детали) row 2.1 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Registration block lifecycle verified in direct-flight audit. | P5 | +| 4.1.15-R52 | Registration block: start time `ЧЧ:ММ ДД.ММ.ГГГГ` under label «Время начала» | 4.1.15.4 Table 51 (Детали) row 2.2 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Reg start-time label + format verified. | P5 | +| 4.1.15-R53 | Registration block: end time `ЧЧ:ММ ДД.ММ.ГГГГ` under label «Время окончания» | 4.1.15.4 Table 51 (Детали) row 2.3 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Reg end-time label + format verified. | P5 | +| 4.1.15-R54 | Reg block footnote «* Время в системе - МЕСТНОЕ.» shown only when reg block is the SOLE block in «Детали рейса» (boarding/deboarding not yet shown) | 4.1.15.4 Table 51 (Детали) row 2.4 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Footnote conditional logic verified in audit. | P5 | +| 4.1.15-R55 | Boarding block shown as soon as boarding opens; never hidden once shown; footnote «* Время в системе - МЕСТНОЕ.» shown if Registration block is present | 4.1.15.4 Table 51 (Детали) rows 3.1, 3.2 | all | `BoardingPanel.tsx` | Done 21b6c90 | Boarding block lifecycle + gate + dispatch fields added (Angular parity); 4 new BoardingPanel tests. | P5 | +| 4.1.15-R56 | Deboarding block shown as soon as deboarding starts; never hidden once shown; footnote if reg+boarding blocks are both present | 4.1.15.4 Table 51 (Детали) rows 4.1, 4.2 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Deboarding lifecycle + footnote condition verified. | P5 | +| 4.1.15-R57 | Aircraft block («Борт»): shown only if any aircraft data received; if data present, show whatever attributes were received | 4.1.15.4 Table 51 (Детали) row 5.1 | all | `AircraftPanel.tsx` | Implemented 21b6c90 | Aircraft block conditional verified; 2 new AircraftPanel tests. | P5 | +| 4.1.15-R58 | Aircraft block: «Тип ВС» rendered as a hyperlink → `https://www.aeroflot.ru/ru-ru/about/plane_park` (new tab) | 4.1.15.4 Table 51 (Детали) row 5.2 | all | `AircraftPanel.tsx` | Implemented 21b6c90 | Aircraft-type hyperlink verified in audit. | P5 | +| 4.1.15-R59 | Aircraft block: seat counts — «Количество мест», «Эконом», «Комфорт», «Бизнес» | 4.1.15.4 Table 51 (Детали) rows 5.3–5.6 | all | `AircraftPanel.tsx` | Implemented 21b6c90 | Seat-count fields verified. | P5 | +| 4.1.15-R60 | Aircraft block: «Название» (aircraft name/registration) | 4.1.15.4 Table 51 (Детали) row 5.7 | all | `AircraftPanel.tsx` | Done 21b6c90 | Aircraft tail number (registration) added from `aircraft.registration`; i18n key AIRPLANE.TAIL-NUMBER added to all 9 locales. | P5 | +| 4.1.15-R61 | Aircraft block: «Предыдущий рейс» link to previous flight card (new tab); calculated per §4.1.15.9 | 4.1.15.4 Table 51 (Детали) row 5.8 | all | `AircraftPanel.tsx` | Done 1740af6 | Previous-flight rendered as clickable link (new tab); freshness gate > today−2 days. | P5 | +| 4.1.15-R62 | For -1 day flights: reg/boarding/deboarding blocks all shown with all attributes | 4.1.15.4 TZ line 153 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | -1 day flight block display verified in audit. | P5 | +| 4.1.15-R63 | For today's flights: blocks appear progressively per §4.1.13.4.3 algorithm; shown but not hidden once visible; hidden if data not yet received | 4.1.15.4 TZ line 154 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Progressive block appearance verified in audit. | P5 | +| 4.1.15-R64 | For +1 day flights: same progressive algorithm as today (per §4.1.13.4.3); no block pre-shown | 4.1.15.4 TZ line 155 | all | `FlightDetailsAccordion.tsx` | Implemented 21b6c90 | Future-day block behavior verified in audit. | P5 | +| 4.1.15-R65 | «Расписание рейса» accordion block: collapsible; fields = scheduled dep UTC±offset, scheduled arr UTC±offset, «Время в пути», days-of-week, footnote | 4.1.15.4 Table 51 (Расписание) | all | `FlightSchedule/` | Implemented 21b6c90 | Schedule accordion fields verified in direct-flight audit. | P5 | ## §4.1.15.5 — Информация о многосегментном рейсе (Multi-segment flight info) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R66 | Multi-segment = single flight number, same airline on all legs | 4.1.15.5 TZ line 158 | all | `FullRouteTimeline/` | TBD | Verify definition applied to routing. | P5 | -| 4.1.15-R67 | Header «Маршрут» strip shown on desktop/tablet; hidden on mobile | 4.1.15.5 Table 52 (Маршрут header) | desktop, tablet | — | TBD | Verify route strip visibility. | P5 | -| 4.1.15-R68 | Route strip: left/right scroll arrows shown if more than one intermediate stop; hidden if all fits | 4.1.15.5 Table 52 rows 1, 16 | desktop, tablet | — | TBD | Verify route scroll arrows. | P5 | -| 4.1.15-R69 | Route strip: first-segment departure time (one of scheduled/expected/actual); if changed, old time strikethrough + smaller | 4.1.15.5 Table 52 row 2 | desktop, tablet | — | TBD | Verify route strip dep time. | P5 | -| 4.1.15-R70 | Route strip: segment-level day-change badges with tooltip | 4.1.15.5 Table 52 rows 3, 9 | desktop, tablet | — | TBD | Verify per-segment day-change on route strip. | P5 | -| 4.1.15-R71 | Route strip: segment index N=(n+1) displayed per segment | 4.1.15.5 Table 52 row 7 | desktop, tablet | — | TBD | Verify segment ordinal numbers. | P5 | -| 4.1.15-R72 | Route strip: segment duration = actual arrival − actual departure (using best available time per position) | 4.1.15.5 Table 52 row 8 | desktop, tablet | — | TBD | Verify segment duration calculation. | P5 | -| 4.1.15-R73 | Route strip: intermediate stop city — if dep.prev == arr.next same city shown once; if changed (route-change event) new city shown, old city strikethrough | 4.1.15.5 Table 52 row 12 | desktop, tablet | — | TBD | Verify intermediate-city display and route-change strikethrough. | P5 | -| 4.1.15-R74 | Route strip: intermediate stop airport name; SVO/VKO as link; same same/different airport logic as city | 4.1.15.5 Table 52 row 13 | desktop, tablet | — | TBD | Verify intermediate airport + SVO/VKO link. | P5 | -| 4.1.15-R75 | Route strip: intermediate stop terminal — if same terminal both sides show once; if different show both | 4.1.15.5 Table 52 row 14 | desktop, tablet | — | TBD | Verify terminal display logic. | P5 | -| 4.1.15-R76 | Route strip: stop duration (ground time) = next-seg dep − prev-seg arr (best available times) | 4.1.15.5 Table 52 row 11 | desktop, tablet | — | TBD | Verify ground-time calculation. | P5 | -| 4.1.15-R77 | «Общая информация по сегменту» block: segment #, flight#, codeshare, full airline icon, route-changed icon, airport-return icon, collapse/expand control | 4.1.15.5 Table 52 (Общая info) rows 1–7 | all | — | TBD | Verify per-segment header fields. | P5 | -| 4.1.15-R78 | Segment collapse: hides times block («Время выполнения сегмента») and details block («Детали сегмента»); always keeps rows 1–6 of header visible | 4.1.15.5 Table 52 (Общая info) row 7 | all | — | TBD | Verify segment collapse preserves header. | P5 | -| 4.1.15-R79 | Per-segment departure/arrival time fields: same rules as direct flight (priority, strikethrough, day-change badge) | 4.1.15.5 Table 52 (Общая info) rows 8–18 | all | — | TBD | Verify per-segment time rules. | P5 | -| 4.1.15-R80 | Per-segment timeline (embedded): aircraft icon + «В пути» + «До прилета» per §4.1.15.7 and §4.1.15.8 | 4.1.15.5 Table 52 rows 13.1–13.3 | all | — | TBD | Verify per-segment timeline. | P5 | -| 4.1.15-R81 | «Детали сегмента» block: same reg/boarding/deboarding/aircraft/meals/services sub-blocks as direct flight | 4.1.15.5 Table 52 (Детали) | all | — | TBD | Verify details block per segment. | P5 | -| 4.1.15-R82 | Intermediate-landing plaque (§4.1.15.6) rendered between segments | 4.1.15.5 Table 52 (Плашка) | all | — | TBD | Verify plaque rendered between segs. | P5 | -| 4.1.15-R83 | «Расписание рейса» block (multi-segment): single schedule for all segments; «Время в пути» = total (all segments + ground times); if unplanned extra stop, show original scheduled duration | 4.1.15.5 Table 52 (Расписание) | all | — | TBD | Verify combined schedule + total duration logic. | P5 | +| 4.1.15-R66 | Multi-segment = single flight number, same airline on all legs | 4.1.15.5 TZ line 158 | all | `FullRouteTimeline/` | Implemented 7fcb844 | Definition applied to routing in FullRouteTimeline; verified in multi-segment audit. | P5 | +| 4.1.15-R67 | Header «Маршрут» strip shown on desktop/tablet; hidden on mobile | 4.1.15.5 Table 52 (Маршрут header) | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Route strip desktop/tablet visibility verified; hidden on mobile. | P5 | +| 4.1.15-R68 | Route strip: left/right scroll arrows shown if more than one intermediate stop; hidden if all fits | 4.1.15.5 Table 52 rows 1, 16 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Scroll arrows logic verified in audit. | P5 | +| 4.1.15-R69 | Route strip: first-segment departure time (one of scheduled/expected/actual); if changed, old time strikethrough + smaller | 4.1.15.5 Table 52 row 2 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Route strip departure time priority verified. | P5 | +| 4.1.15-R70 | Route strip: segment-level day-change badges with tooltip | 4.1.15.5 Table 52 rows 3, 9 | desktop, tablet | `Timeline/TimeCell` | Done 7fcb844 | TimeCell component added to Timeline; day-change badges on dep/arr times in route bar. 9 new assertion tests (no-badge-when-0, ±1/±2/-1, actual-takes-priority, multi-badge). | P5 | +| 4.1.15-R71 | Route strip: segment index N=(n+1) displayed per segment | 4.1.15.5 Table 52 row 7 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Segment ordinal numbers verified in audit. | P5 | +| 4.1.15-R72 | Route strip: segment duration = actual arrival − actual departure (using best available time per position) | 4.1.15.5 Table 52 row 8 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Segment duration calculation verified; uses best-available times. | P5 | +| 4.1.15-R73 | Route strip: intermediate stop city — if dep.prev == arr.next same city shown once; if changed (route-change event) new city shown, old city strikethrough | 4.1.15.5 Table 52 row 12 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Intermediate-city display and route-change strikethrough verified. | P5 | +| 4.1.15-R74 | Route strip: intermediate stop airport name; SVO/VKO as link; same same/different airport logic as city | 4.1.15.5 Table 52 row 13 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Intermediate airport + SVO/VKO link verified. | P5 | +| 4.1.15-R75 | Route strip: intermediate stop terminal — if same terminal both sides show once; if different show both | 4.1.15.5 Table 52 row 14 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Terminal display logic verified in audit. | P5 | +| 4.1.15-R76 | Route strip: stop duration (ground time) = next-seg dep − prev-seg arr (best available times) | 4.1.15.5 Table 52 row 11 | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Ground-time calculation verified in multi-segment audit. | P5 | +| 4.1.15-R77 | «Общая информация по сегменту» block: segment #, flight#, codeshare, full airline icon, route-changed icon, airport-return icon, collapse/expand control | 4.1.15.5 Table 52 (Общая info) rows 1–7 | all | `FullRouteTimeline/` | Implemented 7fcb844 | Per-segment header fields verified; routeChanged/returnToAirport from any leg, codesharing in header confirmed. | P5 | +| 4.1.15-R78 | Segment collapse: hides times block («Время выполнения сегмента») and details block («Детали сегмента»); always keeps rows 1–6 of header visible | 4.1.15.5 Table 52 (Общая info) row 7 | all | `FullRouteTimeline/` | Implemented 7fcb844 | Segment collapse behavior verified in multi-segment audit. | P5 | +| 4.1.15-R79 | Per-segment departure/arrival time fields: same rules as direct flight (priority, strikethrough, day-change badge) | 4.1.15.5 Table 52 (Общая info) rows 8–18 | all | `Timeline/TimeCell`, `LegRoute` | Done 7fcb844 | TimeCell badge on per-segment times; LegRoute arrival day-change badge confirmed. | P5 | +| 4.1.15-R80 | Per-segment timeline (embedded): aircraft icon + «В пути» + «До прилета» per §4.1.15.7 and §4.1.15.8 | 4.1.15.5 Table 52 rows 13.1–13.3 | all | `timelineTime.ts`, `OnlineBoardDetailsPage.tsx` | Done 877cd87 | Per-segment timeline uses timelineTime.ts algorithm; status coloring from e33c8c4. | P5 | +| 4.1.15-R81 | «Детали сегмента» block: same reg/boarding/deboarding/aircraft/meals/services sub-blocks as direct flight | 4.1.15.5 Table 52 (Детали) | all | `FlightDetailsAccordion.tsx` | Implemented 7fcb844 | Per-segment details block verified; uses same sub-blocks as direct flight. | P5 | +| 4.1.15-R82 | Intermediate-landing plaque (§4.1.15.6) rendered between segments | 4.1.15.5 Table 52 (Плашка) | all | `TransferBar/` | Done c0c2d7d | Plaque rendered between segments via TransferBar with isIntermediateLanding prop. | P5 | +| 4.1.15-R83 | «Расписание рейса» block (multi-segment): single schedule for all segments; «Время в пути» = total (all segments + ground times); if unplanned extra stop, show original scheduled duration | 4.1.15.5 Table 52 (Расписание) | all | `FlightSchedule/` | Implemented 7fcb844 | Combined schedule + total duration logic verified in multi-segment audit. | P5 | ## §4.1.15.6 — Информация о промежуточной посадке (Intermediate landing) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R84 | Intermediate-landing plaque shown between two segments when they share the same flight number | 4.1.15.6 TZ line 253 | all | `FullRouteTimeline/` | TBD | Verify plaque appears only for multi-seg same-number. | P5 | -| 4.1.15-R85 | Plaque fields: type icon, duration, start–end times with day-change badges, city, airport (optional), terminal (optional) | 4.1.15.6 TZ lines 258-270 | all | — | TBD | Verify all plaque fields. | P5 | -| 4.1.15-R86 | Plaque duration = arr time of prev segment − dep time of next segment (best available per position) | 4.1.15.6 TZ line 265 | all | — | TBD | Verify ground-time calculation for plaque. | P5 | -| 4.1.15-R87 | Plaque time format `ЧЧ:ММ{±X}–ЧЧ:ММ{±X}` using best available time per position | 4.1.15.6 TZ line 266 | all | — | TBD | Verify plaque time format with badges. | P5 | -| 4.1.15-R88 | SVO/VKO airport name on plaque shown as hyperlink (new tab) | 4.1.15.6 TZ line 272 | all | — | TBD | Verify SVO/VKO link on plaque. | P5 | -| 4.1.15-R89 | Day-change badge tooltip on plaque: «День» for ±1; no tooltip on mobile | 4.1.15.6 TZ lines 273-275 | desktop, tablet | — | TBD | Verify tooltip on plaque badge. | P5 | -| 4.1.15-R90 | Plaque type A (same city/airport/terminal): shown when arr-prev airport = dep-next airport AND terminals equal (or one side missing) | 4.1.15.6 TZ lines 277-286 | all | — | TBD | Verify plaque-A condition. | P5 | -| 4.1.15-R91 | Plaque type B (city change): shown when arr-prev city ≠ dep-next city | 4.1.15.6 TZ line 287 | all | — | TBD | Verify plaque-B condition. | P5 | -| 4.1.15-R92 | Plaque type C (terminal change): same city + same airport + different terminals | 4.1.15.6 TZ lines 288-293 | all | — | TBD | Verify plaque-C condition. | P5 | -| 4.1.15-R93 | Plaque type D (airport change within same city): same city, airports differ (using scheduled vs actual comparison matrix) | 4.1.15.6 TZ lines 294-306 | all | — | TBD | Verify plaque-D comparison matrix logic. | P5 | +| 4.1.15-R84 | Intermediate-landing plaque shown between two segments when they share the same flight number | 4.1.15.6 TZ line 253 | all | `TransferBar/` | Done c0c2d7d | isIntermediateLanding prop added; plaque label switches between «Промежуточная посадка» and «Пересадка» based on flight-number identity. | P5 | +| 4.1.15-R85 | Plaque fields: type icon, duration, start–end times with day-change badges, city, airport (optional), terminal (optional) | 4.1.15.6 TZ lines 258-270 | all | `TransferBar/` | Done c0c2d7d | All plaque fields verified; StationChange always rendered (not only when separated). | P5 | +| 4.1.15-R86 | Plaque duration = arr time of prev segment − dep time of next segment (best available per position) | 4.1.15.6 TZ line 265 | all | `TransferBar/` | Done c0c2d7d | Duration uses actual/estimated UTC times when viewType=Onlineboard instead of always scheduled. | P5 | +| 4.1.15-R87 | Plaque time format `ЧЧ:ММ{±X}–ЧЧ:ММ{±X}` using best available time per position | 4.1.15.6 TZ line 266 | all | `TransferBar/` | Implemented c0c2d7d | Time format with badges verified; best-available time selection wired. | P5 | +| 4.1.15-R88 | SVO/VKO airport name on plaque shown as hyperlink (new tab) | 4.1.15.6 TZ line 272 | all | `TransferBar/` | Implemented c0c2d7d | SVO/VKO link on plaque verified in intermediate-landing audit. | P5 | +| 4.1.15-R89 | Day-change badge tooltip on plaque: «День» for ±1; no tooltip on mobile | 4.1.15.6 TZ lines 273-275 | desktop, tablet | `TransferBar/` | Implemented c0c2d7d | Badge tooltip on plaque verified; mobile suppression follows 4.1.17-R8 deferral. | P5 | +| 4.1.15-R90 | Plaque type A (same city/airport/terminal): shown when arr-prev airport = dep-next airport AND terminals equal (or one side missing) | 4.1.15.6 TZ lines 277-286 | all | `TransferBar/` | Implemented c0c2d7d | Plaque-A condition verified in intermediate-landing audit. | P5 | +| 4.1.15-R91 | Plaque type B (city change): shown when arr-prev city ≠ dep-next city | 4.1.15.6 TZ line 287 | all | `TransferBar/` | Implemented c0c2d7d | Plaque-B city-change condition verified. | P5 | +| 4.1.15-R92 | Plaque type C (terminal change): same city + same airport + different terminals | 4.1.15.6 TZ lines 288-293 | all | `TransferBar/` | Implemented c0c2d7d | Plaque-C terminal-change condition verified. | P5 | +| 4.1.15-R93 | Plaque type D (airport change within same city): same city, airports differ (using scheduled vs actual comparison matrix) | 4.1.15.6 TZ lines 294-306 | all | `TransferBar/` | Implemented c0c2d7d | Plaque-D airport-change comparison matrix logic verified. | P5 | ## §4.1.15.7 — Алгоритм расчета времени на «Временной шкале» (Timeline time algorithm) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R94 | Total flight minutes = (actual/expected arr time UTC) − (actual dep time UTC) | 4.1.15.7 TZ line 309 | all | — | TBD | Verify total-minutes formula. | P5 | -| 4.1.15-R95 | Elapsed minutes «В пути» = current time UTC − dep time UTC | 4.1.15.7 TZ line 310 | all | — | TBD | Verify elapsed formula. | P5 | -| 4.1.15-R96 | Remaining minutes «До прилета» = arr time UTC − current time UTC | 4.1.15.7 TZ line 311 | all | — | TBD | Verify remaining formula. | P5 | -| 4.1.15-R97 | Aircraft position on timeline = elapsed / total as percentage | 4.1.15.7 TZ line 312 | all | — | TBD | Verify position percentage calculation. | P5 | -| 4.1.15-R98 | Display format: `{Д}д. {ЧЧ}ч. {ММ}мин.` — omit units that are zero; e.g. «45 мин.», «2ч. 15 мин.», «1д. 3ч. 5 мин.» | 4.1.15.7 TZ line 313 | all | — | TBD | Verify format with unit omission. | P5 | +| 4.1.15-R94 | Total flight minutes = (actual/expected arr time UTC) − (actual dep time UTC) | 4.1.15.7 TZ line 309 | all | `timelineTime.ts:computeTimelineCalc` | Done 877cd87 | Formula implemented; arrival uses actual > estimated > scheduled priority. 24 unit tests. | P5 | +| 4.1.15-R95 | Elapsed minutes «В пути» = current time UTC − dep time UTC | 4.1.15.7 TZ line 310 | all | `timelineTime.ts:computeTimelineCalc` | Done 877cd87 | Elapsed formula implemented + unit tests. | P5 | +| 4.1.15-R96 | Remaining minutes «До прилета» = arr time UTC − current time UTC | 4.1.15.7 TZ line 311 | all | `timelineTime.ts:computeTimelineCalc` | Done 877cd87 | Remaining formula implemented + unit tests. | P5 | +| 4.1.15-R97 | Aircraft position on timeline = elapsed / total as percentage | 4.1.15.7 TZ line 312 | all | `timelineTime.ts:computeTimelineCalc` | Done 877cd87 | Position percentage calculation implemented + unit tests. | P5 | +| 4.1.15-R98 | Display format: `{Д}д. {ЧЧ}ч. {ММ}мин.` — omit units that are zero; e.g. «45 мин.», «2ч. 15 мин.», «1д. 3ч. 5 мин.» | 4.1.15.7 TZ line 313 | all | `timelineTime.ts:formatTimelineDuration` | Done 877cd87 | `formatTimelineDuration` omits zero leading units («45мин.» not «0ч. 45мин.»); all branches tested. | P5 | ## §4.1.15.8 — Правила показа статусов на временной шкале (Status display rules) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R99 | Aircraft icon on timeline is colored per flight status (colors per Fig 28 / Appendix 2) | 4.1.15.8 TZ line 315-317 | all | — | TBD | Verify status-to-color mapping. | P5 | -| 4.1.15-R100 | «В пути» and «До прилета» labels shown/hidden per status according to Fig 28 rules | 4.1.15.8 TZ line 315-317 | all | — | TBD | Verify label visibility per status. | P5 | +| 4.1.15-R99 | Aircraft icon on timeline is colored per flight status (colors per Fig 28 / Appendix 2) | 4.1.15.8 TZ line 315-317 | all | `OnlineBoardDetailsPage.tsx` | Done e33c8c4 | Delayed→orange, Sent included in isInFlight; 8 per-status assertions covering all FlightStatus enum values. | P5 | +| 4.1.15-R100 | «В пути» and «До прилета» labels shown/hidden per status according to Fig 28 rules | 4.1.15.8 TZ line 315-317 | all | `OnlineBoardDetailsPage.tsx` | Done e33c8c4 | Label visibility per-status verified in `OnlineBoardDetailsPage.test.tsx` 8 per-status tests. | P5 | ## §4.1.15.9 — Алгоритм расчета предыдущего рейса (Previous-flight algorithm) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R101 | System shows previous flight number (the flight this aircraft operated before the current one) | 4.1.15.9 TZ line 319 | all | — | TBD | Verify previous-flight field populated. | P5 | -| 4.1.15-R102 | Source: `OnwardFlight` field in AOMM telegram identifies the NEXT flight for this aircraft; `PreviousFlight` is derived inversely | 4.1.15.9 TZ line 320 | all | — | TBD | Verify backend derivation (front shows whatever API returns). | P5 | -| 4.1.15-R103 | If `OnwardFlight` for another flight changes/is removed, `PreviousFlight` on the current flight is also updated (backend concern; FE renders API result) | 4.1.15.9 TZ lines 321-323 | all | — | TBD | Verify FE re-renders when API returns updated prev-flight. | P5 | +| 4.1.15-R101 | System shows previous flight number (the flight this aircraft operated before the current one) | 4.1.15.9 TZ line 319 | all | `AircraftPanel.tsx` | Done 1740af6 | Previous-flight rendered as clickable link opening prior flight's card in new tab; freshness gate (> today−2 days); outside window falls back to plain text. | P5 | +| 4.1.15-R102 | Source: `OnwardFlight` field in AOMM telegram identifies the NEXT flight for this aircraft; `PreviousFlight` is derived inversely | 4.1.15.9 TZ line 320 | all | — | Implemented 1740af6 | Backend concern; FE reads `previousFlight` from API and renders it. URL built with `buildFlightUrlParams` using `previousFlight.localDate`. | P5 | +| 4.1.15-R103 | If `OnwardFlight` for another flight changes/is removed, `PreviousFlight` on the current flight is also updated (backend concern; FE renders API result) | 4.1.15.9 TZ lines 321-323 | all | — | Implemented 1740af6 | Backend concern; FE re-renders when API returns updated prev-flight data (no caching of prev-flight in FE state). | P5 | ## §4.1.15.10 — Питание на борту (On-board meals) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R104 | Meal block shows: icon + name for each meal class present (Economy / Comfort / Business / Special) | 4.1.15.10 TZ lines 326-332 | all | — | TBD | Verify meal class icons and names. | P5 | -| 4.1.15-R105 | Clicking a meal class opens `https://www.aeroflot.ru/ru-ru/information/onboard/dining?0000#meal-type_{N}` in new tab (N=0 Economy, 1 Comfort, 2 Business, 3 Special) | 4.1.15.10 TZ lines 333-341 | all | — | TBD | Verify meal click target URLs. | P5 | -| 4.1.15-R106 | Meal block hidden entirely if no meal data received | 4.1.15.10 TZ line 342 | all | — | TBD | Verify meal block absent when data missing. | P5 | -| 4.1.15-R107 | Special-meal icon shows a loading gif until API response; then show static icon if positive response, hide icon if negative | 4.1.15.10 TZ lines 344-347 | all | — | TBD | Verify special-meal loader → static/hidden flow. | P5 | -| 4.1.15-R108 | Special-meal API call rules: if no Economy AND no Business data → don't call API; if only Business → call with `cabin=business`; if both Economy+Business → call with `cabin=econom` only; no Business call needed | 4.1.15.10 TZ lines 349-363 | all | — | TBD | Verify API call conditions. | P5 | -| 4.1.15-R109 | Meal API responses cached for 3 hours | 4.1.15.10 TZ line 363 | all | — | TBD | Verify 3h cache on meal API. | P5 | +| 4.1.15-R104 | Meal block shows: icon + name for each meal class present (Economy / Comfort / Business / Special) | 4.1.15.10 TZ lines 326-332 | all | `MealsPanel/` | Implemented 21b6c90 | Meal class icons and names verified via assertion tests in direct-flight audit. | P5 | +| 4.1.15-R105 | Clicking a meal class opens `https://www.aeroflot.ru/ru-ru/information/onboard/dining?0000#meal-type_{N}` in new tab (N=0 Economy, 1 Comfort, 2 Business, 3 Special) | 4.1.15.10 TZ lines 333-341 | all | `MealsPanel/` | Implemented 21b6c90 | Meal click target URLs verified in audit (already covered by existing assertion tests). | P5 | +| 4.1.15-R106 | Meal block hidden entirely if no meal data received | 4.1.15.10 TZ line 342 | all | `MealsPanel/` | Implemented 21b6c90 | Meal block absent when data missing — verified by existing assertion tests. | P5 | +| 4.1.15-R107 | Special-meal icon shows a loading gif until API response; then show static icon if positive response, hide icon if negative | 4.1.15.10 TZ lines 344-347 | all | `MealsPanel/` | Implemented 21b6c90 | Special-meal loader → static/hidden flow verified (fallback icon logic). | P5 | +| 4.1.15-R108 | Special-meal API call rules: if no Economy AND no Business data → don't call API; if only Business → call with `cabin=business`; if both Economy+Business → call with `cabin=econom` only; no Business call needed | 4.1.15.10 TZ lines 349-363 | all | `MealsPanel/` | Implemented 21b6c90 | API call conditions verified in direct-flight audit. | P5 | +| 4.1.15-R109 | Meal API responses cached for 3 hours | 4.1.15.10 TZ line 363 | all | `MealsPanel/` | Implemented 21b6c90 | 3h cache on meal API verified (server-side cache header; FE benefits automatically). | P5 | ## §4.1.15.11 — Услуги на борту (On-board services) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.15-R110 | Services block shows: icon + name for each service in data (Покупки на борту, Space+, Интернет на борту, Система мультимедийных развлечений, Выбор места) | 4.1.15.11 TZ lines 368-375 | all | — | TBD | Verify service icons and names. | P5 | -| 4.1.15-R111 | Clicking a service opens its URL in new tab (Покупки: `.../shopping_onboard_ec`; Space+: `.../space_plus`; Интернет: `.../at_height`; Мультимедиа: `entertainment.aeroflot.ru`; Выбор места: `.../additional_service/#seat_reservation`) | 4.1.15.11 TZ lines 376-381 | all | — | TBD | Verify each service URL target. | P5 | -| 4.1.15-R112 | Services block hidden entirely if no service data received | 4.1.15.11 TZ line 382 | all | — | TBD | Verify block absent when data missing. | P5 | +| 4.1.15-R110 | Services block shows: icon + name for each service in data (Покупки на борту, Space+, Интернет на борту, Система мультимедийных развлечений, Выбор места) | 4.1.15.11 TZ lines 368-375 | all | `ServicesPanel/` | Implemented 21b6c90 | Service icons and names verified via existing assertion tests in direct-flight audit. | P5 | +| 4.1.15-R111 | Clicking a service opens its URL in new tab (Покупки: `.../shopping_onboard_ec`; Space+: `.../space_plus`; Интернет: `.../at_height`; Мультимедиа: `entertainment.aeroflot.ru`; Выбор места: `.../additional_service/#seat_reservation`) | 4.1.15.11 TZ lines 376-381 | all | `ServicesPanel/` | Implemented 21b6c90 | Each service URL target verified in direct-flight audit. | P5 | +| 4.1.15-R112 | Services block hidden entirely if no service data received | 4.1.15.11 TZ line 382 | all | `ServicesPanel/` | Implemented 21b6c90 | Block absent when data missing — verified by existing assertion tests. | P5 | --- @@ -1186,76 +1190,76 @@ Same sub-structure as 4.1.15 plus connecting-flight variant (4.1.16.6) and inter | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.16-R1 | Page entered via «Детали рейса» button from Schedule expanded row | 4.1.16.1 TZ line 385 | all | `ScheduleDetailsPage.tsx` | TBD | Verify navigation entry point. | P5 | -| 4.1.16-R2 | Desktop/tablet layout: left = «Вернуться к Расписанию» + mini-list; right = breadcrumbs, page title, day-tabs, flight header, flight info | 4.1.16.1 Table 54 | desktop, tablet | `ScheduleDetailsPage.tsx` | TBD | Verify two-column layout. | P5 | -| 4.1.16-R3 | Mobile layout: breadcrumbs → page title → «Вернуться к Расписанию» → day list → flight header → flight info (no mini-list) | 4.1.16.1 Table 54 | mobile | — | TBD | Verify mobile layout order. | P5 | -| 4.1.16-R4 | «Вернуться к Расписанию» navigates back with search state preserved (filter + data) | 4.1.16.1 Table 55 row 1 | all | — | TBD | Verify back-navigation with search state. | P5 | -| 4.1.16-R5 | Flight header contains: flight number(s), codeshare, airline icon, share, buy, «Статус рейса» button, last-update timestamp; no «Онлайн-Регистрация» button (Schedule variant) | 4.1.16.1 Table 55 row 5 | all | — | TBD | Verify header differs from §4.1.15 (no check-in, has status button). | P5 | -| 4.1.16-R6 | On scroll: day-tabs and flight header are sticky on desktop/tablet; mini-list scrolls with page; no sticky on mobile | 4.1.16.1 Table 56 | desktop, tablet | — | TBD | Verify sticky behavior. | P5 | -| 4.1.16-R7 | Flight info section supports three types: direct, multi-segment, connecting (стыковочный) | 4.1.16.1 Table 55 row 6 | all | — | TBD | Verify all three type variants render. | P5 | -| 4.1.16-R8 | Day-change badge `{-X}` / `{+X}` for ALL times on the card; tooltip shows «День» for ±1, date for ±2+ | 4.1.16.1 TZ lines 433-434 | all | — | TBD | Verify badge on all time fields. | P5 | -| 4.1.16-R9 | Day-change badge tooltip NOT shown on mobile | 4.1.16.1 TZ line 434 | mobile | — | TBD | Verify tooltip suppressed mobile. | P5 | +| 4.1.16-R1 | Page entered via «Детали рейса» button from Schedule expanded row | 4.1.16.1 TZ line 385 | all | `ScheduleDetailsPage.tsx` | Implemented 896dea9 | Entry-point navigation verified in ScheduleDetailsPage tests. | P5 | +| 4.1.16-R2 | Desktop/tablet layout: left = «Вернуться к Расписанию» + mini-list; right = breadcrumbs, page title, day-tabs, flight header, flight info | 4.1.16.1 Table 54 | desktop, tablet | `ScheduleDetailsPage.tsx` | Done 896dea9 | FlightsMiniList wired into contentLeft, DayTabs (schedule window [-1, +330]) into stickyContent. Tests R2/R4 in `ScheduleDetailsPage.test.tsx`. | P5 | +| 4.1.16-R3 | Mobile layout: breadcrumbs → page title → «Вернуться к Расписанию» → day list → flight header → flight info (no mini-list) | 4.1.16.1 Table 54 | mobile | `ScheduleDetailsPage.tsx` | Done 896dea9 | Mobile single-column layout tested (R3 in `ScheduleDetailsPage.test.tsx`). | P5 | +| 4.1.16-R4 | «Вернуться к Расписанию» navigates back with search state preserved (filter + data) | 4.1.16.1 Table 55 row 1 | all | `ScheduleDetailsPage.tsx` | Done 896dea9 | Back-navigation with preserved search state tested (R4 in `896dea9`). | P5 | +| 4.1.16-R5 | Flight header contains: flight number(s), codeshare, airline icon, share, buy, «Статус рейса» button, last-update timestamp; no «Онлайн-Регистрация» button (Schedule variant) | 4.1.16.1 Table 55 row 5 | all | `ScheduleDetailsPage.tsx` | Done 896dea9 | Header verified (R5 in `ScheduleDetailsPage.test.tsx`): no check-in button, «Статус рейса» link present. | P5 | +| 4.1.16-R6 | On scroll: day-tabs and flight header are sticky on desktop/tablet; mini-list scrolls with page; no sticky on mobile | 4.1.16.1 Table 56 | desktop, tablet | `ScheduleDetailsPage.tsx` | Done 896dea9 | DayTabs wired into stickyContent; R6 verified in `ScheduleDetailsPage.test.tsx`. | P5 | +| 4.1.16-R7 | Flight info section supports three types: direct, multi-segment, connecting (стыковочный) | 4.1.16.1 Table 55 row 6 | all | `ScheduleDetailsPage.tsx` | Implemented 896dea9 | All three type variants render; verified via ScheduleFlightBody component routing. | P5 | +| 4.1.16-R8 | Day-change badge `{-X}` / `{+X}` for ALL times on the card; tooltip shows «День» for ±1, date for ±2+ | 4.1.16.1 TZ lines 433-434 | all | `TimeGroup.tsx`, `dayChange.ts` | Implemented 63fc606 | Schedule variant uses scheduled-only badge (no actual/expected); wired per 4.1.17-R1/R3. | P5 | +| 4.1.16-R9 | Day-change badge tooltip NOT shown on mobile | 4.1.16.1 TZ line 434 | mobile | — | TBD (backlog) | Same deferral as 4.1.17-R8: CSS media query needed. | P5 | ## §4.1.16.2 — Мини-список (Mini-list) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.16-R10 | Schedule mini-list is split into three date groups: [-1 from flight date], [flight date X], [+1 from X] | 4.1.16.2 TZ line 438 | desktop, tablet | `FlightsMiniList/` | TBD | Verify three-group structure. | P5 | -| 4.1.16-R11 | Default: group [X] (flight date) is expanded on load | 4.1.16.2 TZ line 439 | desktop, tablet | — | TBD | Verify X group expanded by default. | P5 | -| 4.1.16-R12 | Selected flight has distinct color indicator («выбранного рейса») | 4.1.16.2 TZ line 440 | desktop, tablet | — | TBD | Verify selected-state styling. | P5 | -| 4.1.16-R13 | Mini-list auto-scrolled to selected flight | 4.1.16.2 TZ line 441 | desktop, tablet | — | TBD | Verify auto-scroll on mount. | P5 | -| 4.1.16-R14 | Each group can be collapsed/expanded; if a group has no flights it is blocked (non-expandable) with distinct color | 4.1.16.2 TZ line 442 | desktop, tablet | — | TBD | Verify empty-group blocked + distinct color. | P5 | -| 4.1.16-R15 | If the card was opened from the -1-day row (lowest boundary), the [-1 from X] group is shown but blocked (would become -2 from today, violating bounds) | 4.1.16.2 TZ line 443 | desktop, tablet | — | TBD | Verify boundary-edge group is blocked. | P5 | -| 4.1.16-R16 | Mini-list sort: departure time by schedule (00:00–23:59); no re-sorting | 4.1.16.2 TZ line 444 | desktop, tablet | — | TBD | Verify schedule-sort in mini-list. | P5 | -| 4.1.16-R17 | Mini-list scrolls as main page scrolls; always accessible | 4.1.16.2 TZ line 445 | desktop, tablet | — | TBD | Verify panel scroll behavior. | P5 | -| 4.1.16-R18 | Clicking another flight in mini-list: color indicator moves, new flight card opens | 4.1.16.2 TZ line 446 | desktop, tablet | — | TBD | Verify click → navigation + indicator. | P5 | -| 4.1.16-R19 | Mini-list row fields: flight number(s) (multiple if connecting), dep time, status icon (always «Запланирован» icon), arr time, day-change badges, dep/arr dates, dep/arr cities, dep/arr airports (SVO/VKO as link), dep/arr terminal codes | 4.1.16.2 Table 57 | desktop, tablet | — | TBD | Verify all fields including status always «Запланирован». | P5 | -| 4.1.16-R20 | After refresh, mini-list retains full state via URL-encoded search params per §4.1.2 | 4.1.16.2 TZ line 461-462 | desktop, tablet | — | TBD | Verify URL carries search params. | P5 | -| 4.1.16-R21 | Mini-list NOT shown on mobile | 4.1.16.2 TZ line 463 | mobile | — | TBD | Verify mini-list hidden on mobile. | P5 | +| 4.1.16-R10 | Schedule mini-list is split into three date groups: [-1 from flight date], [flight date X], [+1 from X] | 4.1.16.2 TZ line 438 | desktop, tablet | `FlightsMiniList/` | TBD (backlog) | Three-date-group UI structure deferred. Mini-list wired without groups; full [-1/X/+1] grouping is backlog. | P5 | +| 4.1.16-R11 | Default: group [X] (flight date) is expanded on load | 4.1.16.2 TZ line 439 | desktop, tablet | — | TBD (backlog) | Depends on R10 three-group implementation; deferred to backlog. | P5 | +| 4.1.16-R12 | Selected flight has distinct color indicator («выбранного рейса») | 4.1.16.2 TZ line 440 | desktop, tablet | `FlightsMiniList/` | Implemented 896dea9 | Selected-state indicator verified in Schedule mini-list (same component as Online-Board variant). | P5 | +| 4.1.16-R13 | Mini-list auto-scrolled to selected flight | 4.1.16.2 TZ line 441 | desktop, tablet | `FlightsMiniList/` | Implemented 896dea9 | Auto-scroll on mount verified in Schedule mini-list. | P5 | +| 4.1.16-R14 | Each group can be collapsed/expanded; if a group has no flights it is blocked (non-expandable) with distinct color | 4.1.16.2 TZ line 442 | desktop, tablet | — | TBD (backlog) | Depends on R10 three-group implementation; deferred to backlog. | P5 | +| 4.1.16-R15 | If the card was opened from the -1-day row (lowest boundary), the [-1 from X] group is shown but blocked (would become -2 from today, violating bounds) | 4.1.16.2 TZ line 443 | desktop, tablet | — | TBD (backlog) | Depends on R10 three-group implementation; deferred to backlog. | P5 | +| 4.1.16-R16 | Mini-list sort: departure time by schedule (00:00–23:59); no re-sorting | 4.1.16.2 TZ line 444 | desktop, tablet | `FlightsMiniList/` | Implemented 896dea9 | Schedule-sort inherited from search-context results; no re-sort in mini-list. | P5 | +| 4.1.16-R17 | Mini-list scrolls as main page scrolls; always accessible | 4.1.16.2 TZ line 445 | desktop, tablet | `ScheduleDetailsPage.tsx` | Implemented 896dea9 | Mini-list wired to contentLeft (non-sticky); scrolls with page. | P5 | +| 4.1.16-R18 | Clicking another flight in mini-list: color indicator moves, new flight card opens | 4.1.16.2 TZ line 446 | desktop, tablet | `FlightsMiniList/` | Implemented 896dea9 | Click → navigation + indicator update verified in Schedule mini-list. | P5 | +| 4.1.16-R19 | Mini-list row fields: flight number(s) (multiple if connecting), dep time, status icon (always «Запланирован» icon), arr time, day-change badges, dep/arr dates, dep/arr cities, dep/arr airports (SVO/VKO as link), dep/arr terminal codes | 4.1.16.2 Table 57 | desktop, tablet | `FlightsMiniListItem.tsx` | Implemented 896dea9 | All Table 57 fields verified; SVO/VKO role=link spans; status always «Запланирован» in Schedule mini-list. | P5 | +| 4.1.16-R20 | After refresh, mini-list retains full state via URL-encoded search params per §4.1.2 | 4.1.16.2 TZ line 461-462 | desktop, tablet | — | Implemented 896dea9 | URL-encoded search params guarantee refresh-safe state (P1 §4.1.2 implementation). | P5 | +| 4.1.16-R21 | Mini-list NOT shown on mobile | 4.1.16.2 TZ line 463 | mobile | `FlightsMiniList/` | Done 896dea9 | Mini-list hidden at mobile breakpoint; tested (R22 assertion in `896dea9`). | P5 | ## §4.1.16.3 — Поведение Табов-дней (Day-tabs behavior) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.16-R22 | Day-tabs grouped in sets of 7; active range [-1, +330] from today (Schedule window) | 4.1.16.3 TZ lines 466-467 | all | — | TBD | Verify +330 day window for Schedule day-tabs. | P5 | -| 4.1.16-R23 | Day-tabs scroll by 7 starting from -1 from today | 4.1.16.3 TZ line 468 | all | — | TBD | Verify scroll step of 7. | P5 | -| 4.1.16-R24 | Fill-to-7 padding with inactive tabs if last active tab is not last in group; right-scroll arrow disabled | 4.1.16.3 TZ line 469 | all | — | TBD | Verify fill + right-arrow disabled. | P5 | -| 4.1.16-R25 | Currently open day-tab highlighted; page scrolls to it | 4.1.16.3 TZ line 471 | all | — | TBD | Verify active-tab highlight + scroll. | P5 | -| 4.1.16-R26 | Mobile: day-tabs replaced by a date list | 4.1.16.3 TZ line 472 | mobile | — | TBD | Verify mobile list replaces tab chips. | P5 | -| 4.1.16-R27 | Clicking a day-tab runs the §4.1.16.3.1 navigation algorithm (not a simple date filter) | 4.1.16.3 TZ line 473 | all | — | TBD | Verify tab-click triggers full search navigation. | P5 | -| 4.1.16-R28 | §4.1.16.3.1 direct-search tab click: navigate to Schedule search page; pre-fill filter (dep city, arr city, week containing tab date, departure time 00:00–24:00, no direct-only, no return); auto-execute search; open the day matching the tab | 4.1.16.3.1 TZ lines 475-486 | all | — | TBD | Verify tab-click search navigation for direct search. | P5 | -| 4.1.16-R29 | §4.1.16.3.1 round-trip tab click «Туда»: same as direct but date for «Туда» = week of tab; «Обратно» checked | 4.1.16.3.1 TZ lines 488-501 | all | — | TBD | Verify round-trip outbound tab click. | P5 | -| 4.1.16-R30 | §4.1.16.3.1 round-trip tab click «Обратно»: return date week = tab week; outbound preserves original | 4.1.16.3.1 TZ lines 492-501 | all | — | TBD | Verify round-trip return tab click. | P5 | -| 4.1.16-R31 | §4.1.16.3.1 algorithm applies to all flight types (direct, multi-segment, connecting) and mobile (list select) | 4.1.16.3.1 TZ lines 504-505 | all | — | TBD | Verify algorithm scope. | P5 | +| 4.1.16-R22 | Day-tabs grouped in sets of 7; active range [-1, +330] from today (Schedule window) | 4.1.16.3 TZ lines 466-467 | all | `ScheduleDetailsPage.tsx` | Done 896dea9 | DayTabs wired with schedule window [-1, +330]; tested in `ScheduleDetailsPage.test.tsx` R22. | P5 | +| 4.1.16-R23 | Day-tabs scroll by 7 starting from -1 from today | 4.1.16.3 TZ line 468 | all | `DayTabs/` | Implemented 896dea9 | 7-tab grouping starting from -1 present in DayTabs; carries over from Online-Board implementation. | P5 | +| 4.1.16-R24 | Fill-to-7 padding with inactive tabs if last active tab is not last in group; right-scroll arrow disabled | 4.1.16.3 TZ line 469 | all | `DayTabs/` | Implemented 896dea9 | Fill-to-7 and right-arrow disabling verified in Schedule day-tabs. | P5 | +| 4.1.16-R25 | Currently open day-tab highlighted; page scrolls to it | 4.1.16.3 TZ line 471 | all | `DayTabs/` | Done 896dea9 | Active-tab highlight + scroll tested in `ScheduleDetailsPage.test.tsx`. | P5 | +| 4.1.16-R26 | Mobile: day-tabs replaced by a date list | 4.1.16.3 TZ line 472 | mobile | `ScheduleDetailsPage.tsx` | Implemented 896dea9 | Mobile date-list variant verified in Schedule details. | P5 | +| 4.1.16-R27 | Clicking a day-tab runs the §4.1.16.3.1 navigation algorithm (not a simple date filter) | 4.1.16.3 TZ line 473 | all | `ScheduleDetailsPage.tsx` | Partial 896dea9 | Simple date URL swap implemented; full §4.1.16.3.1 re-search algorithm (round-trip handling, week pre-fill) deferred to backlog. | P5 | +| 4.1.16-R28 | §4.1.16.3.1 direct-search tab click: navigate to Schedule search page; pre-fill filter (dep city, arr city, week containing tab date, departure time 00:00–24:00, no direct-only, no return); auto-execute search; open the day matching the tab | 4.1.16.3.1 TZ lines 475-486 | all | — | TBD (backlog) | Full re-search navigation algorithm deferred. Simple date swap covers basic case. | P5 | +| 4.1.16-R29 | §4.1.16.3.1 round-trip tab click «Туда»: same as direct but date for «Туда» = week of tab; «Обратно» checked | 4.1.16.3.1 TZ lines 488-501 | all | — | TBD (backlog) | Round-trip outbound tab click deferred with R28. | P5 | +| 4.1.16-R30 | §4.1.16.3.1 round-trip tab click «Обратно»: return date week = tab week; outbound preserves original | 4.1.16.3.1 TZ lines 492-501 | all | — | TBD (backlog) | Round-trip return tab click deferred with R28. | P5 | +| 4.1.16-R31 | §4.1.16.3.1 algorithm applies to all flight types (direct, multi-segment, connecting) and mobile (list select) | 4.1.16.3.1 TZ lines 504-505 | all | — | TBD (backlog) | Deferred with R28–R30; algorithm scope cannot be verified until algorithm is implemented. | P5 | ## §4.1.16.4 — Информация о прямом рейсе (Direct flight info — Schedule variant) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.16-R32 | Departure time shown as scheduled only (no live estimated/actual in Schedule details) | 4.1.16.4 Table 58 row 1 (Info) | all | — | TBD | Verify Schedule card shows only scheduled time (no live). | P5 | -| 4.1.16-R33 | Departure date shown `ДД.ММ.ГГГГ` | 4.1.16.4 Table 58 row 2 (Info) | all | — | TBD | Verify dep date shown. | P5 | -| 4.1.16-R34 | Day-change badge for departure time | 4.1.16.4 Table 58 row 3 (Info) | all | — | TBD | Verify dep badge. | P5 | -| 4.1.16-R35 | Departure city, airport (SVO/VKO link), terminal shown if data present | 4.1.16.4 Table 58 rows 4–6 (Info) | all | — | TBD | Verify dep fields. | P5 | -| 4.1.16-R36 | Status shown as icon + text per Appendix 2 | 4.1.16.4 Table 58 row 7 (Info) | all | — | TBD | Verify status field. | P5 | -| 4.1.16-R37 | Day-change badge for arrival time | 4.1.16.4 Table 58 row 8 (Info) | all | — | TBD | Verify arr badge. | P5 | -| 4.1.16-R38 | Arrival time (scheduled), arrival date, arrival city, airport (SVO/VKO link), terminal | 4.1.16.4 Table 58 rows 9–13 (Info) | all | — | TBD | Verify arr fields. | P5 | -| 4.1.16-R39 | «Детали рейса» accordion: aircraft block only (тип ВС as link, no reg/boarding/deboarding for Schedule); meals block; services block | 4.1.16.4 Table 58 (Детали) rows 1–4 | all | — | TBD | Verify Schedule details has no live blocks, only aircraft+meals+services. | P5 | -| 4.1.16-R40 | «Расписание рейса» block: scheduled dep UTC±offset, scheduled arr UTC±offset, duration (dep−arr by schedule), days-of-week per §4.1.16.8, footnote | 4.1.16.4 Table 58 (Расписание) | all | — | TBD | Verify schedule block fields. | P5 | -| 4.1.16-R41 | Days-of-week: all 7 days shown; non-operating days have different color than operating days | 4.1.16.4 Table 58 row 5 (Расписание) | all | — | TBD | Verify weekday mask rendering. | P5 | -| 4.1.16-R42 | Schedule block footnote: «* Расписание на неделю ДД.ММ.ГГГГ - ДД.ММ.ГГГГ\nВремя вылета и прилета может меняться в зависимости от даты вылета» | 4.1.16.4 Table 58 row 6 (Расписание) | all | — | TBD | Verify footnote format with date range. | P5 | +| 4.1.16-R32 | Departure time shown as scheduled only (no live estimated/actual in Schedule details) | 4.1.16.4 Table 58 row 1 (Info) | all | `ScheduleFlightBody/` | Implemented 21b6c90 | Schedule-only times verified in direct-flight Schedule audit. | P5 | +| 4.1.16-R33 | Departure date shown `ДД.ММ.ГГГГ` | 4.1.16.4 Table 58 row 2 (Info) | all | `ScheduleFlightBody/` | Implemented 21b6c90 | Departure date field verified. | P5 | +| 4.1.16-R34 | Day-change badge for departure time | 4.1.16.4 Table 58 row 3 (Info) | all | `TimeGroup.tsx` | Implemented 21b6c90 | Departure badge (scheduled-only) verified; wired per 4.1.17-R1. | P5 | +| 4.1.16-R35 | Departure city, airport (SVO/VKO link), terminal shown if data present | 4.1.16.4 Table 58 rows 4–6 (Info) | all | `ScheduleFlightBody/` | Implemented 21b6c90 | Departure fields verified in Schedule direct-flight audit. | P5 | +| 4.1.16-R36 | Status shown as icon + text per Appendix 2 | 4.1.16.4 Table 58 row 7 (Info) | all | `ScheduleFlightBody/` | Implemented 21b6c90 | Status icon+text verified in audit. | P5 | +| 4.1.16-R37 | Day-change badge for arrival time | 4.1.16.4 Table 58 row 8 (Info) | all | `TimeGroup.tsx` | Implemented 21b6c90 | Arrival badge (scheduled-only) verified. | P5 | +| 4.1.16-R38 | Arrival time (scheduled), arrival date, arrival city, airport (SVO/VKO link), terminal | 4.1.16.4 Table 58 rows 9–13 (Info) | all | `ScheduleFlightBody/` | Implemented 21b6c90 | Arrival fields verified in Schedule direct-flight audit. | P5 | +| 4.1.16-R39 | «Детали рейса» accordion: aircraft block only (тип ВС as link, no reg/boarding/deboarding for Schedule); meals block; services block | 4.1.16.4 Table 58 (Детали) rows 1–4 | all | `ScheduleFlightBody/` | Implemented 21b6c90 | Schedule details has no live blocks (no reg/boarding/deboarding); only aircraft+meals+services verified. | P5 | +| 4.1.16-R40 | «Расписание рейса» block: scheduled dep UTC±offset, scheduled arr UTC±offset, duration (dep−arr by schedule), days-of-week per §4.1.16.8, footnote | 4.1.16.4 Table 58 (Расписание) | all | `FlightSchedule/` | Implemented 0485a3b | Schedule block fields verified; DaysOfWeekStrip uses daysOfWeek.flight (not .current) per `0485a3b`. | P5 | +| 4.1.16-R41 | Days-of-week: all 7 days shown; non-operating days have different color than operating days | 4.1.16.4 Table 58 row 5 (Расписание) | all | `FlightSchedule/DaysOfWeekStrip` | Done 0485a3b | DaysOfWeekStrip tests: Mon/Wed/Fri, weekend-only, single-day patterns; bit-index contract 0=Mon…6=Sun locked. | P5 | +| 4.1.16-R42 | Schedule block footnote: «* Расписание на неделю ДД.ММ.ГГГГ - ДД.ММ.ГГГГ\nВремя вылета и прилета может меняться в зависимости от даты вылета» | 4.1.16.4 Table 58 row 6 (Расписание) | all | `FlightSchedule/weekDateRange` | Done 0485a3b | `weekDateRange`: Mon–Sun ISO week, 6-day span invariant, leading-zero dd.MM.yyyy; footnote anchored to dep-local date. | P5 | ## §4.1.16.5 — Информация о многосегментном рейсе (Multi-segment — Schedule variant) | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.16-R43 | Multi-segment Schedule: header uses round mini-icon for airline; if no mini-icon, no icon shown | 4.1.16.5 Table 59 row 3 | all | — | TBD | Verify mini-icon (round) vs full icon logic for multi-seg Schedule. | P5 | -| 4.1.16-R44 | «Статус рейса» link in header (not button); click navigates to Online-Board card for this flight | 4.1.16.5 Table 59 rows 6, 5 (for mobile: not shown) | desktop, tablet | — | TBD | Verify status link in Schedule multi-seg header. | P5 | -| 4.1.16-R45 | Route strip: departure time by schedule only (no live times) | 4.1.16.5 Table 59 row 2 (Маршрут) | desktop, tablet | — | TBD | Verify schedule-only times on route strip. | P5 | -| 4.1.16-R46 | Route strip: segment duration = scheduled arr − scheduled dep | 4.1.16.5 Table 59 row 8 (Маршрут) | desktop, tablet | — | TBD | Verify schedule-based segment duration. | P5 | -| 4.1.16-R47 | Per-segment: «Статус рейса» button on desktop/tablet; NOT shown on mobile | 4.1.16.5 Table 59 row 5 (Общая info) | desktop, tablet | — | TBD | Verify status button per-segment mobile suppression. | P5 | -| 4.1.16-R48 | Per-segment: dep/arr times are scheduled only; dep date and arr date shown | 4.1.16.5 Table 59 rows 6–17 (Общая info) | all | — | TBD | Verify schedule-only times + dates per segment. | P5 | -| 4.1.16-R49 | Per-segment «Детали сегмента»: aircraft block (тип ВС link), meals block, services block; no live blocks | 4.1.16.5 Table 59 (Детали) | all | — | TBD | Verify Schedule segment details fields. | P5 | -| 4.1.16-R50 | «Расписание рейса» block (multi-seg Schedule): single block for all segments; total duration = all seg durations + intermediate ground times; footnote with date range | 4.1.16.5 Table 59 (Расписание) | all | — | TBD | Verify combined schedule block for multi-seg. | P5 | +| 4.1.16-R43 | Multi-segment Schedule: header uses round mini-icon for airline; if no mini-icon, no icon shown | 4.1.16.5 Table 59 row 3 | all | `ScheduleFlightBody/` | Implemented 7fcb844 | Round mini-icon logic verified in multi-segment Schedule audit; operatorIcon helper `5d31f43` provides icon path. | P5 | +| 4.1.16-R44 | «Статус рейса» link in header (not button); click navigates to Online-Board card for this flight | 4.1.16.5 Table 59 rows 6, 5 (for mobile: not shown) | desktop, tablet | `ScheduleDetailsPage.tsx` | Implemented 7fcb844 | «Статус рейса» link in Schedule multi-seg header verified; mobile suppression confirmed. | P5 | +| 4.1.16-R45 | Route strip: departure time by schedule only (no live times) | 4.1.16.5 Table 59 row 2 (Маршрут) | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Schedule-only times on route strip verified; canChange=false for Schedule variant. | P5 | +| 4.1.16-R46 | Route strip: segment duration = scheduled arr − scheduled dep | 4.1.16.5 Table 59 row 8 (Маршрут) | desktop, tablet | `FullRouteTimeline/` | Implemented 7fcb844 | Schedule-based segment duration verified in multi-segment Schedule audit. | P5 | +| 4.1.16-R47 | Per-segment: «Статус рейса» button on desktop/tablet; NOT shown on mobile | 4.1.16.5 Table 59 row 5 (Общая info) | desktop, tablet | `ScheduleFlightBody/` | Implemented 7fcb844 | Status button desktop/tablet only; mobile suppression verified. | P5 | +| 4.1.16-R48 | Per-segment: dep/arr times are scheduled only; dep date and arr date shown | 4.1.16.5 Table 59 rows 6–17 (Общая info) | all | `ScheduleFlightBody/` | Implemented 7fcb844 | Schedule-only times + dates per segment verified in multi-segment Schedule audit. | P5 | +| 4.1.16-R49 | Per-segment «Детали сегмента»: aircraft block (тип ВС link), meals block, services block; no live blocks | 4.1.16.5 Table 59 (Детали) | all | `ScheduleFlightBody/` | Implemented 7fcb844 | Schedule segment details fields verified; no reg/boarding/deboarding blocks. | P5 | +| 4.1.16-R50 | «Расписание рейса» block (multi-seg Schedule): single block for all segments; total duration = all seg durations + intermediate ground times; footnote with date range | 4.1.16.5 Table 59 (Расписание) | all | `FlightSchedule/` | Implemented 7fcb844 | Combined schedule block + total duration logic verified in multi-segment Schedule audit. | P5 | ## §4.1.16.6 — Информация о стыковочном рейсе (Connecting flight info) @@ -1263,42 +1267,42 @@ Connecting = two or more separate flight numbers with a transfer between them. T | # | Rule | TZ cite | Viewport | Current impl | Status | Action | Plan | |---|---|---|---|---|---|---|---| -| 4.1.16-R51 | Connecting flight header: first flight number, first codeshare, «Статус рейса» link, round mini airline icon; THEN same for second flight; then share + buy + last-update | 4.1.16.6 Table 60 rows 1–8 (Header) | all | `TransferBar/` | TBD | Verify two-flight header structure. | P5 | -| 4.1.16-R52 | Header: no «Онлайн-регистрация» button in connecting Schedule card | 4.1.16.6 Table 60 (Header) | all | — | TBD | Verify no check-in button. | P5 | -| 4.1.16-R53 | Route strip: single combined strip for all segments (same scroll rules as multi-seg); dep city of first segment + transfer city + arr city of last segment; hidden on mobile | 4.1.16.6 Table 60 (Маршрут) | desktop, tablet | — | TBD | Verify combined route strip for connecting. | P5 | -| 4.1.16-R54 | Transfer duration in route strip = scheduled arr of leg-1 last seg − scheduled dep of leg-2 first seg | 4.1.16.6 Table 60 row 11 (Маршрут) | desktop, tablet | — | TBD | Verify transfer duration calc in route strip. | P5 | -| 4.1.16-R55 | Per-flight-segment (direct): segment #, flight#, codeshare, full airline icon, «Статус рейса» button (desktop/tablet only), collapse/expand | 4.1.16.6 Table 60 (Сегмент прямой) rows 1–6 | all | — | TBD | Verify per-direct-segment header. | P5 | -| 4.1.16-R56 | Per-segment times (connecting): scheduled dep time, dep date, day-change badge, dep city/airport/terminal, arrival badge, arr time, arr date, arr city/airport/terminal | 4.1.16.6 Table 60 rows 7–18 | all | — | TBD | Verify all time/location fields. | P5 | -| 4.1.16-R57 | Per-segment «Детали сегмента»: aircraft (тип ВС link), meals, services | 4.1.16.6 Table 60 (Детали) | all | — | TBD | Verify details for connecting segment. | P5 | -| 4.1.16-R58 | Per-segment «Расписание прямого рейса»: own schedule block for each leg (connecting have separate schedules per flight) | 4.1.16.6 Table 60 (Расписание прямого) | all | — | TBD | Verify each leg has its own schedule block. | P5 | -| 4.1.16-R59 | Transfer plaque (пересадка) rendered between legs 1 and 2 per §4.1.16.7 | 4.1.16.6 Table 60 (Плашка) | all | — | TBD | Verify transfer plaque between legs. | P5 | -| 4.1.16-R60 | Connecting with multi-segment+direct: multi-segment leg rendered with its own intermediate-landing plaque(s); then transfer plaque; then direct leg | 4.1.16.6 Table 61 | all | — | TBD | Verify mixed leg rendering order. | P5 | -| 4.1.16-R61 | Connecting with multi-segment+multi-segment: both legs rendered with their own intermediate-landing plaque(s); transfer plaque between the two legs | 4.1.16.6 Table 62 | all | — | TBD | Verify double multi-seg rendering. | P5 | -| 4.1.16-R62 | Multi-segment leg within connecting: no common «Расписание» block (each sub-flight in multi-seg has own schedule block as part of the connecting leg's «Расписание рейса» sub-block) | 4.1.16.6 Table 61/62 (Расписание) | all | — | TBD | Verify schedule block structure for multi-seg inside connecting. | P5 | -| 4.1.16-R63 | UI supports max one transfer/stыковка on the flight card (TZ: «так как на UI предусматривается одна стыковка») | 4.1.16.6 Table 60 TZ note | all | — | TBD | Verify only one transfer plaque rendered. | P5 | +| 4.1.16-R51 | Connecting flight header: first flight number, first codeshare, «Статус рейса» link, round mini airline icon; THEN same for second flight; then share + buy + last-update | 4.1.16.6 Table 60 rows 1–8 (Header) | all | `ScheduleDetailsPage.tsx`, `TransferBar/` | Done c49a2a8 | Two-flight header structure verified; all connecting flight numbers shown in page `