Files
flights_web/docs/superpowers/plans/2026-04-15-phase-4-flights-map-master.md
T
gnezim 8dde2db9d2 Add Phase 4 master plan and install leaflet dependency
Write the flights-map master plan covering sub-plans 4A-4D.
Add leaflet + @types/leaflet to support the map canvas component.
2026-04-15 09:44:01 +03:00

3.4 KiB

Phase 4 -- Flights Map (Master Plan)

Goal

Port the Angular flights-map feature (single /flights-map route) to the React/ModernJS codebase as a Module Federation remote component. The map uses Leaflet for interactive marker/polyline rendering and is behind the flightsMap feature flag.

Angular analysis summary

  • Route: /flights-map (start page with embedded Leaflet map)
  • Feature flag: flightsMap (env-based)
  • APIs: destinations/v1 (search routes by departure/arrival), days/.../flights-map/v1 (calendar availability)
  • Leaflet map: markers (blue default, blue-small zoom-dependent, orange selected), polylines (solid direct, dashed connecting), popups, tooltips, zoom-aware layer visibility
  • Components: start page container, map body (sole Leaflet consumer), filter panel, meta tags, loader/empty overlays
  • No SignalR -- data is static, fetched on filter change
  • SEO: meta tags only in Angular; design spec requires JSON-LD WebPage schema

Sub-plans

4A -- Types + API + Hooks

Files: src/features/flights-map/types.ts, api.ts, api.test.ts, hooks/useFlightsMapSearch.ts, hooks/useFlightsMapCalendar.ts

  • Define IFlightRoute, IMapMarker, IMapPolyline, FlightsMapSearchParams, FlightsMapCalendarParams
  • Define IDestinationsResponse, IFlightsMapDaysResponse
  • API: searchDestinations(client, params) -> GET destinations/1, getFlightsMapCalendar(client, params) -> GET days/{date}/200/{route}/flights-map/v1
  • Hooks: useFlightsMapSearch(params), useFlightsMapCalendar(params)
  • Feature flag: useFeatureFlag("flightsMap") via env config
  • TDD: ~10 tests for API functions

4B -- Leaflet Map Wrapper

File: src/features/flights-map/components/MapCanvas.tsx

  • Only file that imports leaflet (design spec constraint)
  • Wrapped in React.lazy() + <ClientOnly> (SSR-safe)
  • Accepts markers, polylines, onMarkerClick etc. as props -- does not own state
  • Renders markers (blue/orange icons), polylines (solid/dashed), popups, tooltips
  • Great-circle arc calculation for polyline rendering
  • Install leaflet + @types/leaflet
  • No TDD (Leaflet requires real DOM)

4C -- Route Pages + Feature Components

Files:

  • src/routes/[lang]/flights-map/page.tsx -- route page with SEO + feature flag guard
  • src/features/flights-map/components/FlightsMapStartPage.tsx -- container (filter + map + loading/empty states)
  • src/features/flights-map/components/FlightsMapFilter.tsx -- search filter (departure, arrival, connections, domestic/international toggles, date picker)
  • src/features/flights-map/components/ClientOnly.tsx -- SSR-safe wrapper

4D -- SEO + JSON-LD + Parity

Files:

  • src/features/flights-map/seo.ts -- buildFlightsMapSeo(t, locale, canonicalOrigin)
  • src/features/flights-map/json-ld.ts -- JSON-LD WebPage schema builder
  • src/features/flights-map/seo.test.ts -- ~5 integration tests
  • Update barrel src/features/flights-map/index.ts
  • Update src/mf/expose/FlightsMap.tsx from stub to real

Dependency graph

4A (types/api/hooks) --> 4B (map canvas, needs types)
                     --> 4C (pages/components, needs hooks)
4A + 4B + 4C --------> 4D (SEO + barrel + MF expose update)

Verification

pnpm typecheck && pnpm lint && pnpm test && pnpm build:standalone

Constraints

  • Do NOT touch ClientApp/, ASP.NET, wwwroot/
  • No Co-Authored-By lines in commits
  • ~8-12 commits total