From 816028603beec1c6ee6d52eac9ef067f2235dfd7 Mon Sep 17 00:00:00 2001 From: gnezim Date: Tue, 21 Apr 2026 16:18:05 +0300 Subject: [PATCH] Populate full rule enumeration for P1 subsections 4.1.2/3/4/8 in TZ audit spec --- ...nline-board-schedule-tz-redesign-design.md | 89 +++++++++++++++++-- 1 file changed, 83 insertions(+), 6 deletions(-) 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 19c63c88..a67498b8 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 @@ -128,7 +128,7 @@ _Updated after each plan merges. Plan task: after every merge, append a row to t | Metric | Count | |---|---| -| Total rules extracted | (populated as subsections are filled) | +| Total rules extracted | 242 (4.1.1: 27, 4.1.2: 42, 4.1.3: 22, 4.1.4: 26, 4.1.5: 7, 4.1.6: 6, 4.1.7: 7, 4.1.8: 18, 4.1.9: 8 skeleton, 4.1.10: 5, 4.1.11: 6, 4.1.12: 3, 4.1.13: 5 skeleton, 4.1.14: 5 skeleton, 4.1.15: 11 skeleton, 4.1.16: 8 skeleton, 4.1.17: 4, 4.1.18: 3, 4.1.19: 6, 4.1.20: 4, 4.1.21: 5, 4.1.22: 4, 4.1.23: 3, 4.1.24: 7 skeleton) | | Implemented | — | | Partial | — | | Missing | — | @@ -209,8 +209,36 @@ URLs encode language, area (onlineboard/schedule/flights-map), mode (route / fli | 4.1.2-R10 | Unknown directory → 404 page (§4.1.21) | 4.1.2 ¶2 | all | `src/routes/error/[code]/*` | TBD | Verify 404 on bogus URLs. | P1 | | 4.1.2-R11 | Out-of-range date → redirect to the respective **start page** (not 404) | 4.1.2 ¶3–4 | all | — | TBD | Add date-window guard + redirect. | P1 | | 4.1.2-R12 | Date window constants: Online-Board `[-1, +14]`, Schedule `[-1, +330]`, Flight Map `[-1, +6 months]` | 4.1.2 ¶3–4 | all | — | TBD | Centralize as constants; reference from URL guards and filter validators. | P1 | - -**Remaining rules (language-suffix encoding, anchor fragments, query-string vs path style, deep-link behavior from email, etc.) → populated at P1 kickoff after full read of 4.1.2 text + Table 5 in detail.** +| 4.1.2-R13 | Online-Board route search with time filter: `/{lang}/onlineboard/route/{fromCity}-{toCity}-{YYYYMMDD}-{HHMMHHmm}` — time period `{timeFrom}{timeTo}` appended to date, e.g. `06002200` | 4.1.2 Table 5 row 3 | all | — | TBD | Implement time-period segment in route URL builder; verify round-trip parse. | P1 | +| 4.1.2-R14 | Online-Board departure-only search with time filter: `/{lang}/onlineboard/departure/{fromCity}-{YYYYMMDD}-{HHMMHHmm}` (optional time suffix) | 4.1.2 Table 5 row 4 | all | — | TBD | Verify optional time suffix handled; add parser test. | P1 | +| 4.1.2-R15 | Online-Board arrival-only search with time filter: `/{lang}/onlineboard/arrival/{toCity}-{YYYYMMDD}-{HHMMHHmm}` (optional time suffix) | 4.1.2 Table 5 row 5 | all | — | TBD | Verify optional time suffix handled. | P1 | +| 4.1.2-R16 | Online-Board details card — arrival-mode `?request=` param: `?request=onlineboard-arrival-{city}-{flightNumber}-{YYYYMMDD}` (without time) and `?request=onlineboard-arrival-{city}-{flightNumber}-{YYYYMMDD}-{HHMMHHmm}` (with time) | 4.1.2 Table 5 row 6 | all | — | TBD | Verify `?request=` builder for arrival mode; add test. | P1 | +| 4.1.2-R17 | Online-Board details card — departure-mode `?request=` param: `?request=onlineboard-departure-{city}-{flightNumber}-{YYYYMMDD}[-{HHMMHHmm}]` | 4.1.2 Table 5 row 6 | all | — | TBD | Verify `?request=` builder for departure mode. | P1 | +| 4.1.2-R18 | Online-Board details card — route-mode `?request=` param: `?request=onlineboard-route-{dep}-{arr}-{flightNumber}-{YYYYMMDD}[-{HHMMHHmm}]` | 4.1.2 Table 5 row 6 | all | — | TBD | Verify `?request=` builder for route mode. | P1 | +| 4.1.2-R19 | Online-Board details card — flight-number-mode `?request=` param: `?request=onlineboard-flight-{flightNumber}-{YYYYMMDD}` (no time suffix for flight-number mode) | 4.1.2 Table 5 row 6 | all | — | TBD | Verify flight-number mode `?request=` omits time suffix. | P1 | +| 4.1.2-R20 | Online-Board details base URL (same for all four `?request=` forms): `/{lang}/onlineboard/{flightNumber}-{YYYYMMDD}` | 4.1.2 Table 5 row 6 | all | — | TBD | Verify base-path uses padded 4-digit flight number (per R4 padding rule). | P1 | +| 4.1.2-R21 | Online-Board "Refresh direct link" URL is identical in shape to the details card URL (row 6); no difference in path or query | 4.1.2 Table 5 row 7 | all | — | TBD | Verify refresh loads same URL as card navigation; no mutation. | P1 | +| 4.1.2-R22 | Online-Board "Share / copy link" URL: `/{lang}/onlineboard/flight/{flightNumber}-{YYYYMMDD}` — no `?request=` param; always `flight` mode regardless of original search mode | 4.1.2 Table 5 row 8 | all | — | TBD | Verify share URL strips `?request=` and uses `/flight/` mode path. | P1 | +| 4.1.2-R23 | Schedule title page URL: `/{lang}/schedule` | 4.1.2 Table 5 row 9 | all | `src/routes/[lang]/schedule/page.tsx` | TBD | Verify route exists. | P1 | +| 4.1.2-R24 | Schedule route search — one-way, all connections, no time: `/{lang}/schedule/route/{dep}-{arr}-{dateFrom}-{dateTo}` (date range, both dates `YYYYMMDD`) | 4.1.2 Table 5 row 10 | all | — | TBD | Verify date-range URL format and parsing. | P1 | +| 4.1.2-R25 | Schedule route search — one-way, all connections, with time: `/{lang}/schedule/route/{dep}-{arr}-{dateFrom}-{dateTo}-{HHMMHHmm}` | 4.1.2 Table 5 row 10 | all | — | TBD | Verify time-period suffix appended after dateTo. | P1 | +| 4.1.2-R26 | Schedule route search — round-trip, no time: `/{lang}/schedule/route/{dep}-{arr}-{dateFrom}-{dateTo}/{arr}-{dep}-{returnDateFrom}-{returnDateTo}` (two slash-separated segments) | 4.1.2 Table 5 row 10 | all | — | TBD | Verify slash-delimited second segment for return leg. | P1 | +| 4.1.2-R27 | Schedule route search — round-trip, with time: both segments each append `-{HHMMHHmm}` after their dateTo | 4.1.2 Table 5 row 10 | all | — | TBD | Verify both segments carry independent time filters. | P1 | +| 4.1.2-R28 | Schedule route search — one-way, direct-only (`С0`): append `-С0` suffix after the date or time token, e.g. `…-{dateTo}-С0` or `…-{HHMMHHmm}-С0` | 4.1.2 Table 5 row 10 | all | — | TBD | Verify `-С0` suffix position in URL builder. | P1 | +| 4.1.2-R29 | Schedule route search — round-trip, direct-only: each slash segment ends with `-С0` | 4.1.2 Table 5 row 10 | all | — | TBD | Verify each return segment also has `-С0`. | P1 | +| 4.1.2-R30 | Schedule details card URL — direct/multi-segment, one-way, no time: `/{lang}/schedule/{flightNumber}-{YYYYMMDD}?request=schedule-route-{dep}-{arr}-{dateFrom}-{dateTo}` | 4.1.2 Table 5 row 11 | all | — | TBD | Verify `?request=` for schedule direct one-way. | P1 | +| 4.1.2-R31 | Schedule details card URL — direct/multi-segment, one-way, with time: `?request=schedule-route-{dep}-{arr}-{dateFrom}-{dateTo}-{HHMMHHmm}` | 4.1.2 Table 5 row 11 | all | — | TBD | Verify time suffix in schedule `?request=`. | P1 | +| 4.1.2-R32 | Schedule details card URL — connecting flight, one-way: path uses slash-delimited flight numbers `/{fn0}-{date}/{fn1}-{date}[/{fn2}-{date}]` (max 2 connections = up to 3 segments); `?request=` same as direct | 4.1.2 Table 5 row 11 | all | — | TBD | Verify multi-segment path with up to 3 flight-number-date pairs. | P1 | +| 4.1.2-R33 | Schedule details card URL — round-trip, no time: `?request=` encodes both outbound and return legs: `?request=schedule-route-{dep}-{arr}-{df}-{dt}-{arr}-{dep}-{rdf}-{rdt}` | 4.1.2 Table 5 row 11 | all | — | TBD | Verify concatenated return-leg parameters in `?request=`. | P1 | +| 4.1.2-R34 | Schedule details card URL — round-trip with connections filter (`С0`): `?request=` embeds `-С0` after each date-range block | 4.1.2 Table 5 row 11 | all | — | TBD | Verify `-С0` positions inside `?request=` for round-trip + direct filter. | P1 | +| 4.1.2-R35 | Schedule "Refresh direct link" URL identical to details card URL (row 11 in Table 5; same as Online-Board analogy row 7) | 4.1.2 Table 5 row 12 | all | — | TBD | Verify refresh reloads same URL without mutation. | P1 | +| 4.1.2-R36 | Schedule "Share / copy link" URL — direct/multi-segment: `/{lang}/schedule/{flightNumber}-{YYYYMMDD}` (no `?request=`) | 4.1.2 Table 5 row 13 | all | — | TBD | Verify share URL is clean path without `?request=`. | P1 | +| 4.1.2-R37 | Schedule "Share / copy link" URL — connecting: `/{lang}/schedule/{fn0}-{date}/{fn1}-{date}[/{fn2}-{date}]` slash-joined (no `?request=`) | 4.1.2 Table 5 row 13 | all | — | TBD | Verify connecting share URL uses slash-joined path. | P1 | +| 4.1.2-R38 | Flight Map title page URL: `/{lang}/flights-map` | 4.1.2 Table 5 (Map row 1) | all | `src/routes/[lang]/flights-map/page.tsx` | TBD | Verify route exists. | P1 | +| 4.1.2-R39 | Flight Map departure search URL: `/{lang}/flights-map` — same URL regardless of departure-city filter value (search state NOT encoded in URL) | 4.1.2 Table 5 (Map row 2) | all | — | TBD | Verify URL stays constant under filter changes. | P1 | +| 4.1.2-R40 | Flight Map route search URL: `/{lang}/flights-map` — same URL for all search states | 4.1.2 Table 5 (Map row 3) | all | — | TBD | Verify URL stays constant when both cities filled. | P1 | +| 4.1.2-R41 | Flight Map arrival-only search is **not implemented** ("Не выполняется") — no arrival-mode URL for flights-map | 4.1.2 Table 5 (Map row 4) | all | — | TBD | Assert no arrival-mode route exists; verify UI hides arrival mode on Map tab. | P1 | +| 4.1.2-R42 | Mobile URL rules are identical to web URL rules (no mobile-specific URL variants) | 4.1.2 ¶1 | mobile | — | TBD | Verify no mobile-specific routing divergence. | P1 | --- @@ -227,8 +255,22 @@ Each page in the section gets a TZ-prescribed title format driven by context (ar | 4.1.3-R4 | Search-result page titles per mode (route / flight-number / departure / arrival) | 4.1.3 | all | — | TBD | Populate. | P1 | | 4.1.3-R5 | Flight-details page title per TZ (direct / multi-segment / connecting) | 4.1.3 | all | — | TBD | Populate. | P1 | | 4.1.3-R6 | All titles translated for each of 9 languages | 4.1.3 | all | `src/i18n/*` | TBD | Add keys + verify per locale. | P1 | - -**Rules to populate at P1 kickoff after reading 4.1.3 tables in full.** +| 4.1.3-R7 | Online-Board start page title: `Онлайн-Табло` (no dynamic parts) | 4.1.3 Table 6 row 1 | all | — | TBD | Verify rendered H1/title matches exactly. | P1 | +| 4.1.3-R8 | Online-Board flight-number search title: `Рейс: {номер рейса}, {дата}` — date shown as `сегодня` / `завтра` / `ДД.ММ.ГГГГ` depending on flight date relative to today | 4.1.3 Table 6 row 2 | all | — | TBD | Verify date-relative label logic (today/tomorrow/formatted). | P1 | +| 4.1.3-R9 | Online-Board route search title: `Маршрут: {город вылета}-{города прилета}, {дата}` — city names in full display form; date formatted same as R8 | 4.1.3 Table 6 row 3 | all | — | TBD | Verify city names (not IATA codes) used; comma-separated date. | P1 | +| 4.1.3-R10 | Online-Board departure-only search title: `Вылет: {город вылета}, {дата}` | 4.1.3 Table 6 row 4 | all | — | TBD | Verify title shows only departure city. | P1 | +| 4.1.3-R11 | Online-Board arrival-only search title: `Прилет: {город прилета}, {дата}` | 4.1.3 Table 6 row 5 | all | — | TBD | Verify title shows only arrival city. | P1 | +| 4.1.3-R12 | Online-Board flight details card title: `Информация о рейсе: {номер рейса}, {город вылета}-{город прилета}` | 4.1.3 Table 6 row 6 | all | — | TBD | Verify format including comma after flight number. | P1 | +| 4.1.3-R13 | Online-Board details via "Refresh direct link" title: same as details card — `Информация о рейсе: {номер рейса}, {город вылета}-{город прилета}` | 4.1.3 Table 6 row 7 | all | — | TBD | Verify title preserved on page refresh (SSR must hydrate city names). | P1 | +| 4.1.3-R14 | Online-Board share link title: same as details card — `Информация о рейсе: {номер рейса}, {город вылета}-{город прилета}` | 4.1.3 Table 6 row 8 | all | — | TBD | Verify share URL renders same title. | P1 | +| 4.1.3-R15 | Schedule start page title: `Расписание` (no dynamic parts) | 4.1.3 Table 6 row 9 | all | — | TBD | Verify H1/title. | P1 | +| 4.1.3-R16 | Schedule route search title: `Расписание по маршруту: {город вылета}-{города прилета}` — full city names, no date shown in title | 4.1.3 Table 6 row 10 | all | — | TBD | Verify no date in schedule search title (differs from Online-Board). | P1 | +| 4.1.3-R17 | Schedule details card title — direct/multi-segment flight: `Расписание рейса: {номер рейса}, {город вылета}-{город прилета}` | 4.1.3 Table 6 row 11 | all | — | TBD | Verify singular "рейса" for direct/multi-segment. | P1 | +| 4.1.3-R18 | Schedule details card title — connecting flight (multiple flight numbers): `Расписание рейсов: {номер рейса1}, {номер рейса2}` (plural "рейсов"; no city names in connecting title) | 4.1.3 Table 6 row 11 | all | — | TBD | Verify plural form and absence of city names for connecting. | P1 | +| 4.1.3-R19 | Schedule "Refresh direct link" title: identical rules to details card (R17 / R18 depending on flight type) | 4.1.3 Table 6 row 12 | all | — | TBD | Verify SSR hydrates flight type to pick correct title form. | P1 | +| 4.1.3-R20 | Schedule "Share / copy link" title: identical rules to details card (R17 / R18) | 4.1.3 Table 6 row 13 | all | — | TBD | Verify share page renders correct title form. | P1 | +| 4.1.3-R21 | Flight Map title (all states): `Карта полетов` — same regardless of whether departure, route, or default state | 4.1.3 Table 6 (Map rows 1-3) | all | — | TBD | Verify title never changes on Flight Map. | P1 | +| 4.1.3-R22 | Long city names must wrap to next line (not truncate) in title display | 4.1.3 ¶1 | all | — | TBD | Verify CSS allows wrap; no `text-overflow: ellipsis` on title. | P1 | --- @@ -243,6 +285,28 @@ All pages in the section must have breadcrumbs; each crumb is a link except the | 4.1.4-R2 | Last crumb = non-link with `aria-current="page"` | 4.1.4 + CLAUDE.md a11y | all | (see commit `826a583`) | Implemented | — | P1 | | 4.1.4-R3 | Crumb labels translatable | 4.1.4 | all | `src/i18n/*` | TBD | Verify all locales. | P1 | | 4.1.4-R4 | Per-page crumb list per TZ Table (populate at P1 kickoff) | 4.1.4 | all | — | TBD | Populate. | P1 | +| 4.1.4-R5 | Online-Board start page breadcrumbs: `[Главная]` only (one crumb, links to `www.aeroflot.ru`) | 4.1.4 Table 7 row 1 | all | — | TBD | Verify single crumb on start page. | P1 | +| 4.1.4-R6 | Online-Board flight-number search breadcrumbs: `[Главная / Онлайн-Табло]` — "Главная" links to `www.aeroflot.ru`; "Онлайн-Табло" links to `/{lang}/onlineboard` | 4.1.4 Table 7 row 2 | all | — | TBD | Verify two-crumb trail for flight-number results page. | P1 | +| 4.1.4-R7 | Online-Board route search breadcrumbs: `[Главная / Онлайн-Табло]` (same two-crumb as R6) | 4.1.4 Table 7 row 3 | all | — | TBD | Verify. | P1 | +| 4.1.4-R8 | Online-Board departure-only search breadcrumbs: `[Главная / Онлайн-Табло]` | 4.1.4 Table 7 row 4 | all | — | TBD | Verify. | P1 | +| 4.1.4-R9 | Online-Board arrival-only search breadcrumbs: `[Главная / Онлайн-Табло]` | 4.1.4 Table 7 row 5 | all | — | TBD | Verify. | P1 | +| 4.1.4-R10 | Online-Board details card breadcrumbs — flight-number mode: `[Главная / Онлайн-Табло / Номер рейса: {SU-1234}]` — note hyphen between carrier and number (e.g. `SU-1234`) | 4.1.4 Table 7 row 6 | all | — | TBD | Verify leaf crumb uses hyphenated format `SU-NNNN` not `SUNNNN`. | P1 | +| 4.1.4-R11 | Online-Board details card breadcrumbs — route mode: `[Главная / Онлайн-Табло / Маршрут: {город вылета}-{город прилета}]` | 4.1.4 Table 7 row 6 | all | — | TBD | Verify route-mode leaf crumb uses city names. | P1 | +| 4.1.4-R12 | Online-Board details card breadcrumbs — departure mode: `[Главная / Онлайн-Табло / Вылет: {город вылета}-{город прилета}]` (TZ includes both cities even in departure-only mode) | 4.1.4 Table 7 row 6 | all | — | TBD | Verify both cities shown even when original search was departure-only. | P1 | +| 4.1.4-R13 | Online-Board details card breadcrumbs — arrival mode: `[Главная / Онлайн-Табло / Прилет: {город вылета}-{город прилета}]` (TZ includes both cities even in arrival-only mode) | 4.1.4 Table 7 row 6 | all | — | TBD | Verify both cities shown even when original search was arrival-only. | P1 | +| 4.1.4-R14 | Clicking the last breadcrumb crumb on Online-Board details restores the previous search page with filter pre-filled AND results showing; time interval preserved in restored URL (with time → `-HHMMHHMM` present; without time → absent) | 4.1.4 Table 7 row 6 (transitions) | all | — | TBD | Verify breadcrumb click navigates to restored search URL with time-interval. | P1 | +| 4.1.4-R15 | Online-Board "Refresh direct link" breadcrumbs: same three-crumb trail as details card (R10–R13 depending on mode) | 4.1.4 Table 7 row 7 | all | — | TBD | Verify breadcrumbs on refresh deep-link match card breadcrumbs. | P1 | +| 4.1.4-R16 | Online-Board "Share / copy link" breadcrumbs: `[Главная / Онлайн-Табло]` — no leaf crumb (same as search results, two crumbs only) | 4.1.4 Table 7 row 8 | all | — | TBD | Verify share URL renders only two crumbs, no leaf. | P1 | +| 4.1.4-R17 | Schedule start page breadcrumbs: `[Главная]` only | 4.1.4 Table 7 row 9 | all | — | TBD | Verify single crumb on schedule start page. | P1 | +| 4.1.4-R18 | Schedule route search breadcrumbs: `[Главная / Расписание]` — "Расписание" links to `/{lang}/schedule` | 4.1.4 Table 7 row 10 | all | — | TBD | Verify two-crumb trail for schedule results page. | P1 | +| 4.1.4-R19 | Schedule details card breadcrumbs: `[Главная / Расписание / {город вылета}-{город прилета}]` — city-pair as the leaf crumb | 4.1.4 Table 7 row 11 | all | — | TBD | Verify leaf crumb is city-pair (not flight number). | P1 | +| 4.1.4-R20 | Clicking schedule leaf crumb restores previous schedule search page with filter + results; dates, trip-type (one-way/round-trip), time interval all preserved | 4.1.4 Table 7 row 11 (transitions) | all | — | TBD | Verify restored schedule search URL encodes all previous filter state. | P1 | +| 4.1.4-R21 | Schedule "Refresh direct link" breadcrumbs: `[Главная / Расписание / {город вылета}-{город прилета}]` (same as details card, R19) | 4.1.4 Table 7 row 12 | all | — | TBD | Verify breadcrumbs on refresh deep-link. | P1 | +| 4.1.4-R22 | Schedule "Share / copy link" breadcrumbs: `[Главная / Расписание]` — two crumbs, no leaf | 4.1.4 Table 7 row 13 | all | — | TBD | Verify share page shows only two crumbs. | P1 | +| 4.1.4-R23 | Flight Map title page breadcrumbs: `[Главная]` only | 4.1.4 Table 7 (Map row 1) | all | — | TBD | Verify single crumb on map start page. | P1 | +| 4.1.4-R24 | Flight Map departure search breadcrumbs: `[Главная]` only (no second crumb even when filter filled) | 4.1.4 Table 7 (Map row 2) | all | — | TBD | Verify breadcrumbs never expand beyond `[Главная]` on Flight Map. | P1 | +| 4.1.4-R25 | Flight Map route search breadcrumbs: `[Главная]` only | 4.1.4 Table 7 (Map row 3) | all | — | TBD | Verify same single-crumb trail. | P1 | +| 4.1.4-R26 | "Главная" crumb always links to `www.aeroflot.ru` (external) on all pages | 4.1.4 Table 7 (all rows, transitions col) | all | — | TBD | Verify href targets external `www.aeroflot.ru`. | P1 | --- @@ -310,8 +374,21 @@ Switching tabs between Online-Board / Schedule / Flight Map preserves user input | 4.1.8-R3 | Tab switch to Flight Map does **not** inherit Board/Schedule filter (§4.1.1-R26 — independence) | 4.1.8 / 4.1.1 ¶12 | all | — | TBD | Verify. | P1 | | 4.1.8-R4 | Closing popovers on focus-change (4.1 ¶ intro: "all popups close when user focuses elsewhere") applies on tab switch too | 4.1 ¶ intro | desktop, tablet | — | TBD | Verify. | P1 | | 4.1.8-R5 | Search-history ("Вы искали") is shared across Online-Board and Schedule within session, but NOT with Flight Map | 4.1.8 / 4.1.9.5 | all | — | TBD | Verify scoping rules. | P1 | +| 4.1.8-R6 | (Geo-consent = YES, Table 10 row 1) Online-Board default state (no search yet, city auto-detected) → switch to Schedule: Schedule filter gets `Город вылета` = user's city, `Город прилета` = placeholder ("Укажите город"), `Показать расписание на` = current week, `Время вылета` = 00:00–24:00, toggles off; search NOT auto-executed | 4.1.8 Table 10 row 1 | all | — | TBD | Verify Schedule filter state after switching from Board default. | P1 | +| 4.1.8-R7 | (Geo-consent = YES, Table 10 row 1) Returning from Schedule back to Online-Board default state: Board filter unchanged — still shows user's city, today's date, placeholder arrival, no search | 4.1.8 Table 10 row 1 (return col) | all | — | TBD | Verify Board state not mutated by Schedule visit. | P1 | +| 4.1.8-R8 | (Geo-consent = YES, Table 10 row 2) Online-Board with search executed → switch to Schedule: Schedule gets `Город вылета` = user's city (from Board context, NOT the searched route), `Показать расписание на` = current week; Schedule does NOT copy Board's search date or arrival city | 4.1.8 Table 10 row 2 | all | — | TBD | Verify Schedule auto-fills departure city only (current week, not Board date). | P1 | +| 4.1.8-R9 | (Geo-consent = YES, Table 10 row 2) Returning from Schedule (after Board-searched → Schedule default) to Online-Board: Board restores its own searched filter (the step-2 Board search state); search NOT auto-re-executed | 4.1.8 Table 10 row 2 (return col) | all | — | TBD | Verify Board restores its own step-2 filter on return. | P1 | +| 4.1.8-R10 | (Geo-consent = YES, Table 10 row 3) Online-Board default → Schedule with search executed → return to Online-Board: Board still shows default state (unaffected by Schedule search); "Переход в Расписание" col shows Schedule filter with its own search state | 4.1.8 Table 10 row 3 | all | — | TBD | Verify Board remains at default; Schedule stores its own state. | P1 | +| 4.1.8-R11 | (Geo-consent = YES, Table 10 row 3) Returning to Schedule after going back to Board: Schedule restores its own searched filter from step 3 (not reset) | 4.1.8 Table 10 row 3 (return-Schedule col) | all | — | TBD | Verify Schedule own state survives Board round-trip. | P1 | +| 4.1.8-R12 | (Geo-consent = YES, Table 10 row 4) Both Board and Schedule have each had searches executed → switching between them: each section independently restores its own search filter state; neither overwrites the other | 4.1.8 Table 10 row 4 | all | — | TBD | Verify each section's search state is stored independently. | P1 | +| 4.1.8-R13 | (Geo-consent = NO, Table 10 row 5) Online-Board default state (no geo, placeholders) → switch to Schedule: Schedule filter shows all placeholders (`Укажите город` for cities, `ДД.ММ.ГГГГ-ДД.ММ.ГГГГ` for date range), toggles off; no search | 4.1.8 Table 10 row 5 | all | — | TBD | Verify no city auto-fill when geo-consent denied. | P1 | +| 4.1.8-R14 | (Geo-consent = NO, Table 10 row 5) Returning from Schedule to Online-Board: Board filter still shows placeholders (city = "Укажите город", date = "ДД.ММ.ГГГГ"), no mutation | 4.1.8 Table 10 row 5 (return col) | all | — | TBD | Verify Board placeholder state preserved. | P1 | +| 4.1.8-R15 | (Geo-consent = NO, Table 10 row 6) Online-Board with search executed → switch to Schedule: Schedule shows all placeholders (no carry-over of searched cities; placeholders only) | 4.1.8 Table 10 row 6 | all | — | TBD | Verify Schedule does NOT inherit Board search filter when geo-consent denied. | P1 | +| 4.1.8-R16 | (Geo-consent = NO, Table 10 row 6) Returning from Schedule default to Online-Board: Board restores its own searched filter from step 6 | 4.1.8 Table 10 row 6 (return col) | all | — | TBD | Verify Board step-6 search state persists. | P1 | +| 4.1.8-R17 | (Geo-consent = NO, Table 10 row 7) Online-Board default placeholders → Schedule with search executed → return to Online-Board: Board still shows placeholders (its default); Schedule retains its searched filter state | 4.1.8 Table 10 row 7 | all | — | TBD | Verify Board unaffected by Schedule search when geo-consent denied. | P1 | +| 4.1.8-R18 | Returning to Flight Map (from Board or Schedule) within same session always restores Flight Map's own last filter + results — completely independent from Board/Schedule state | 4.1.8 ¶ post-table (line 523) | all | — | TBD | Verify map state restoration is isolated from Board/Schedule filter carry-over. | P1 | -**Remaining rules at P1 kickoff.** +**Rules enumerated from Table 10 (all 7 rows) and post-table narrative.** ---