Files
flights_web/docs/superpowers/plans/2026-04-15-phase-5-popular-requests-master.md
T
gnezim 7d202b9436 Add Phase 5 Popular Requests master plan
Documents the Angular feature analysis and sub-plan breakdown for
porting popular-requests to React with useSearchHistory hook.
2026-04-15 09:58:14 +03:00

6.5 KiB

Phase 5 — Popular Requests MASTER Plan

This document is a plan INDEX, not an executable plan. It lists the Phase 5 sub-plans, their dependency order, the contracts each sub-plan exports for downstream sub-plans to consume, and the shared files that cross sub-plan boundaries.

Goal of Phase 5: Port the Popular Requests feature from Angular to React, wire it into existing route pages, implement the useSearchHistory hook backed by @/shared/storage, and verify SEO + parity. Popular Requests is an embedded component (not a standalone routed page) — used inside the OnlineBoard and Schedule start pages. It also includes the language switcher (ported from Angular layout) and a per-language-namespaced search history hook.

Phase 5 exit gate (must pass before next phase starts):

  • PopularRequestsPanel renders correctly with all 5 request modes: FlightNumber, Route, Arrival, Departure, RouteWithBack.
  • usePopularRequests hook calls GET /Requests/1/getpopular and handles loading/error states.
  • useSearchHistory hook persists search history via @/shared/storage with per-language namespacing (afl_history_{lang}).
  • No direct localStorage access outside src/shared/storage.ts (enforced by ESLint no-restricted-globals).
  • MF expose PopularRequests.tsx upgraded from stub to real component.
  • Feature barrel src/features/popular-requests/index.ts exports all public surface.
  • pnpm typecheck && pnpm lint && pnpm test && pnpm build:standalone all green.

Angular source analyzed:

  • API: GET /api/Requests/1/getpopular returns IPopularRequest[] (union of 4 discriminated types keyed by RequestMode).
  • Types: RequestMode enum: FlightNumber | Route | RouteWithBack | Departure | Arrival. IPopularRequestType: 'Schedule' | 'Onlineboard'. IPopularRequest = union of IPopularRouteRequest | IPopularArrivalRequest | IPopularDepartureRequest | IPopularFlightNumberRequest.
  • Components: PopularRequestsComponent (container, fetches data, handles clicks + navigation), PopularRequestComponent (switch by mode), ArrivalRequestComponent, DepartureRequestComponent, FlightNumberRequestComponent, RouteRequestComponent, RequestInfoComponent (styled clickable span).
  • Behavior: On click, populates filter state in OnlineBoardFiltersStateService / ScheduleFiltersStateService and navigates to onlineboard or schedule route. Uses cityName pipe (maps IATA code to city name via dictionaries).
  • Search History: SearchHistoryService — in-memory array of ISearchHistoryItem with dedup-by-URL and prepend logic. Displayed on start pages. React version should persist to localStorage via @/shared/storage.
  • No dedicated route — embedded inside OnlineBoardStartPage and ScheduleStartPage.

Sub-plan inventory

ID Sub-plan Estimated size Description
5A Types + API + hooks Small (8-12 tasks) PopularRequest types, getPopularRequests API fn, usePopularRequests hook
5B Route page + components Medium (12-18 tasks) PopularRequestsPanel, mode-specific sub-components, MF expose update
5C SEO + parity + integration tests Small (6-10 tasks) Verify no SEO regression, integration tests for the panel
5D Search history hook Small (8-12 tasks) useSearchHistory with per-language localStorage namespacing via @/shared/storage

Dependency graph

    ┌──────────────────────────────┐
    │  5A  Types + API + hooks     │
    │  src/features/popular-       │
    │  requests/{types,api,hooks}  │
    └──────────────┬───────────────┘
                   │
    ┌──────────────▼───────────────┐
    │  5B  Components + MF expose  │◄── depends on 5A types/hooks
    │  src/features/popular-       │
    │  requests/components/        │
    │  src/mf/expose/              │
    └──────────────┬───────────────┘
                   │
    ┌──────────────▼───────────────┐
    │  5C  SEO + parity + tests    │◄── depends on 5B components
    └──────────────────────────────┘

    ┌──────────────────────────────┐
    │  5D  useSearchHistory hook   │  (independent of 5A-5C)
    │  src/shared/hooks/           │
    └──────────────────────────────┘

5D is independent and can be executed in parallel with 5A-5C.


Contracts exported per sub-plan

5A — Types + API + hooks

Files created:

  • src/features/popular-requests/types.tsRequestMode, PopularRequestType, PopularRequest union, sub-types
  • src/features/popular-requests/api.tsgetPopularRequests(client: ApiClient): Promise<PopularRequest[]>
  • src/features/popular-requests/api.test.ts — API function tests
  • src/features/popular-requests/hooks/usePopularRequests.ts — React hook wrapping the API call
  • src/features/popular-requests/index.ts — barrel update

Consumed by: 5B (types + hook), 5C (tests)

5B — Components + MF expose

Files created:

  • src/features/popular-requests/components/PopularRequestsPanel.tsx — container component
  • src/features/popular-requests/components/PopularRequestItem.tsx — mode-switching renderer
  • src/features/popular-requests/components/RequestInfo.tsx — styled clickable span

Files modified:

  • src/mf/expose/PopularRequests.tsx — stub replaced with real component
  • src/features/popular-requests/index.ts — barrel update

Consumed by: 5C (integration tests), route pages (OnlineBoardStartPage, ScheduleStartPage)

5C — SEO + parity + integration tests

Files created:

  • src/features/popular-requests/components/PopularRequestsPanel.test.tsx — component tests

Consumed by: Exit gate verification

5D — Search history hook

Files created:

  • src/shared/hooks/useSearchHistory.ts — hook with per-language localStorage namespacing
  • src/shared/hooks/useSearchHistory.test.ts — hook tests

Files modified:

  • src/features/popular-requests/index.ts — re-export if appropriate

Consumed by: Start pages (OnlineBoardStartPage, ScheduleStartPage) in future integration