Commit Graph

30 Commits

Author SHA1 Message Date
gnezim 0169f00328 ci: stop syncing CLAUDE.md and AGENTS.md to customer repo 2026-04-25 18:40:42 +03:00
gnezim a6293d9d56 ci: surface Jenkins console URL on build-timeout + document GITHUB_TOKEN auto-secret 2026-04-25 03:11:37 +03:00
gnezim 36ad9cac3d ci: audit-console-allowlist.sh — flag dead allowlist entries 2026-04-25 02:50:56 +03:00
gnezim 5dd6190650 ci: factor sync core into scripts/ci/sync-to-gitlab.sh
CI needs to sync to an arbitrary clone dir, not just the local sibling.
Extract the copy logic into sync-to-gitlab.sh (required target arg,
machine-friendly output); reduce sync-to-flights-front.sh to a thin
wrapper that supplies the local default and adds dev next-steps hints.
2026-04-25 02:49:35 +03:00
gnezim 648779bb69 ci: check-gitlab-project.sh — one-shot setup validator 2026-04-25 02:47:36 +03:00
gnezim 0cd8d0c102 ci: jenkins-trigger-and-wait.sh — fire job + poll for SUCCESS 2026-04-25 02:45:24 +03:00
gnezim cb494a4290 ci: deploy-container.sh — swap/rollback with dry-run tests 2026-04-25 02:41:51 +03:00
gnezim f97cb72e9e ci: install-htpasswd.sh — render nginx basic-auth file 2026-04-25 02:39:29 +03:00
gnezim 2727dead6a ci: wait-for-url.sh — curl with retry 2026-04-25 02:37:50 +03:00
gnezim 24358fd3e3 ci: notify-telegram.sh — append last 30 log lines on fail 2026-04-25 02:35:33 +03:00
gnezim 675be1f40f ci: notify-telegram.sh + dry-run tests 2026-04-25 02:33:09 +03:00
gnezim 8feb5de70e Dev-server: fall back between direct and HTTPS_PROXY transports
The local WAF is unpredictable: some windows the gost VPN tunnel at
127.0.0.1:8888 is 503-ing (direct must work), other windows the direct IP
is throttled to 403 by Ngenix (VPN must be used). The previous hardcoded
`--noproxy '*'` survived one of those states only, which is why the
dictionary load surfaced as console 403s as soon as the state flipped.

Try direct first (faster when it works, simpler cookie jar), fall back
through the system HTTPS_PROXY on 4xx/5xx or curl failure, keep a
separate cookie jar per transport so the Ngenix cookies don't cross-
contaminate edge nodes.
2026-04-22 11:44:46 +03:00
gnezim a4e8d87688 Fix dev-server proxy so API forwarding survives WAF cookie challenge
curl was inheriting HTTPS_PROXY=127.0.0.1:8888 (a local gost tunnel whose
upstream VPN intermittently 503s), making the app fail to load dictionaries
in dev. Upstream Ngenix WAF also newly requires a 307-to-self cookie
handshake (ngenix_valid) before issuing JSON. Bypass the system proxy
directly and keep a per-session cookie jar so the handshake only runs once.
2026-04-22 09:41:03 +03:00
gnezim 27b1ab1329 Schedule start: empty date-range placeholder
ScheduleStartPage now starts dateFrom/dateTo as null so the input
shows the `ДД.ММ.ГГГГ - ДД.ММ.ГГГГ` placeholder Angular ships
instead of pre-filling with the current week. The submit handler
defaults to current-week range when the user submits without
picking dates, preserving the legacy "find this week" UX.

Same pattern as the onlineboard date fix.
2026-04-19 21:52:03 +03:00
gnezim 64c86dcdd6 visual-diff: mask Angular-only test-env chrome
Paint 3 known noise regions white in both screenshots before pixel-
matching:
  - top-left ~200×90 (debug counter + orange `Тестовая версия` badge)
  - top-right ~240×50 (build tag like `rc/2026-04-06`)
  - bottom-right ~90×90 (chat-widget bubble)

These show only on the deployed Angular test env, not in the React
dev build, and were inflating every parity score by ~1-2pp.

Mismatch deltas vs prior run:
  en-onlineboard-route       4.62% → 4.45%
  flight-details            11.24% → 10.82%
  mobile-flight-details     17.92% → 16.58%
  mobile-onlineboard-start  20.37% → 18.66%
  onlineboard-arrival        4.63% → 4.46%
  onlineboard-departure      5.03% → 4.86%
  onlineboard-route          4.78% → 4.60%
  onlineboard-start         14.52% → 13.77%
  schedule-route            12.47% → 11.87%
  schedule-start            13.39% → 12.86%
  flights-map               37.28% → 36.40%
2026-04-19 21:34:44 +03:00
gnezim 69706e023d Schedule + flights-map structural parity
- flights-map: default departure to Москва (MOW) when geolocation
  doesn't yield a city. Mirrors Angular which seeds the orange
  marker on Moscow regardless of geo permission. Hook now has two
  effects — a synchronous MOW fallback that fires once dictionaries
  load, and the existing geo callback that may upgrade to a closer
  city when permission is granted.
- Schedule: introduce DayGroupedFlightList. Buckets the flat result
  list by scheduled-departure date and renders each group under a
  `Воскресенье 19 Апреля`-style header (Intl-driven, weekday +
  genitive month). Single-day result skips the grouping noise.
- Schedule: introduce WeekTabs. Replaces the daily DayTabs in the
  schedule sticky-content with Monday-anchored 7-day windows like
  `13 апр - 19 апр`, matching Angular's week-tabs component.
  handleWeekChange recomputes both dateFrom (Monday) and dateTo
  (Sunday) when the tab changes.
- Schedule: aircraft model now visible in the collapsed FlightCard
  row when `direction === "schedule"` (Sukhoi SuperJet 100 / Airbus
  A321 etc., per Angular's operator-logo-and-model column).
- FlightCard / FlightList: extend `direction` union with `"schedule"`.

Tests updated: useGeolocationDefault tests now assert the MOW
fallback fires when permission is denied / API missing / arrival
already set (was previously expected to no-op).
2026-04-19 20:52:41 +03:00
gnezim e7cf11e799 Visual parity fixes — drop pixel mismatch on 6+ pages
- OperatorLogo: accept BCP-47 codes (`ru-ru`) by trimming to first 2
  chars before picking the en/ru asset variant. Fixes the Russian
  flight-details page rendering ROSSIYA (Latin) instead of РОССИЯ.
- FlightCard / FlightList: thread `direction` from the search page so
  arrival results show Высадка (deboarding) instead of Посадка
  (boarding) — Angular parity. The arrival side reads from
  arrivalLeg.transition.deboarding when direction === 'arrival'.
- OnlineBoardFilter:
  - Дата рейса starts blank with `ДД.ММ.ГГГГ` placeholder; submit
    handler defaults to today on empty.
  - Город вылета / Город прилета placeholders flip to
    `Все направления` when the opposite-direction field is filled.
  - Filter content row now flows with $space-l vertical gap to match
    Angular's accordion-content rhythm (was ~6 px tighter).
- FlightsMiniList: `display: none` on mobile. Avoids the duplicate
  summary card that was floating above the main details on small
  viewports — Angular hides the sidebar mini-list there.
- FlightsMap calendar trigger: override PrimeReact's filled-blue
  button to a transparent outline so it reads as a glyph (matches
  Angular's outline calendar icon).

Pixel-mismatch results (re-diffed via scripts/visual-diff.mjs):
  en-onlineboard-route       5.50% → 4.62%
  onlineboard-arrival        5.53% → 4.63%
  onlineboard-departure      5.92% → 5.03%
  onlineboard-route          5.16% → 4.78%
  mobile-onlineboard-start  23.51% → 20.37%
  mobile-flight-details     18.82% → 17.92%
  flight-details            carrier-logo verified visually; pixel
                            count unchanged (height delta dominates)
  onlineboard-start         14.56% → 14.52%

Larger remaining mismatches (schedule-route 14%, flights-map 34%,
flight-details 11%) are dominated by structural Angular features the
React port doesn't yet ship (day grouping, code-share bundling on
schedule; geo-driven origin marker on map; height-delta on details).
Tracked as P1 follow-ups in the comparison report.
2026-04-19 20:18:15 +03:00
gnezim 496a72e7d7 Track k8s manifest; teach make sync to mirror deployment/
CI / ci (push) Failing after 32s
Deploy / build-and-deploy (push) Failing after 5s
The flights-front deploy repo ships k8s manifests at deployment/k8s/,
a sibling of Aeroflot.Flights.Front/. Previously the sync script only
copied the app source, so any env change landed on the k8s side had
to be hand-edited in the deploy repo and was never reflected back.

- Bring deployment/k8s/flights-ui.yaml into this repo (with the new
  MAP_TILE_URL env pointing at flights.test.aeroflot.ru) so the
  cluster config lives next to the code that reads it.
- sync-to-flights-front.sh resolves the deploy-repo root from the
  target path and mirrors this repo's deployment/ directory there,
  mkdir'ing and copying contents without wiping unrelated files.
- Bump step numbering (1/6..6/6) and the summary now lists the synced
  deployment files in addition to the app files.
2026-04-18 22:51:26 +03:00
gnezim 5551cb1821 Fix flights-map date format and dev proxy empty-body status parsing
Upstream /destinations and /days endpoints expect yyyy-MM-DD (dashed),
matching Angular's ApiFormatterService.formatDateOnly output. React was
sending the internal compact yyyyMMdd, triggering silent 400s.

Also fix dev-server.mjs status-code parsing: empty-body curl responses
start with the appended "\n%{http_code}" separator at index 0, so
`lastNewline > 0` mis-treated the status as body and defaulted to 200,
hiding real upstream 4xx/5xx responses. Changed to `>= 0`.
2026-04-17 22:25:48 +03:00
gnezim c8d0caa9cf Fix five console-level issues surfaced by live-deploy Playwright audit
1. FlightsMap tiles didn't render: MapCanvas inline height:100% resolved
   to 0 against min-height parents. Hand sizing to consumer CSS so
   .flights-map-start__map height:500px wins.

2. FlightsMap /map/api/tile/{z}/{x}/{y}.jpeg requests fell through to
   Modern.js SSR (HTML body). Dev proxy now forwards /map/* to the
   test env via curl with image headers and binary-safe piping.

3. PopularRequestsPanel duplicate React key (Route-SVO-LED appears
   twice in upstream). Suffix the key with the visible index.

4. OnlineBoardDetailsPage /onlineboard/details 400. Upstream expects
   an ISO datetime (yyyy-MM-DDTHH:mm:ss), matching Angular's
   ApiFormatterService.formatDate. Append T00:00:00.

5. Browser-level SignalR CORS errors on every details page: the
   default SIGNALR_HUB_URL pointed at an unreachable placeholder.
   Default to empty + skip the connection in useLiveFlights when
   blank. Also configureLogging(LogLevel.None) so SignalR stops
   writing its own negotiation failures to console. Live updates
   re-enable by setting SIGNALR_HUB_URL on a deployment.
2026-04-17 21:55:44 +03:00
gnezim 2ae59d2074 Propagate Modern.js publicDir assets through sync + Docker build
The config/public/ directory (fonts, images, leaflet icons, favicons) is
Modern.js's publicDir convention — copied into dist/standalone/public/ at
build time. Two pre-existing gaps caused this to break on the deployed
SSR image and any fresh sync:

- scripts/sync-to-flights-front.sh did not copy config/ to the target
  repo, so the flights-front tree was missing /assets/** entirely.
- Dockerfile.react only copied src/, skipping config/; pnpm
  build:standalone ran without a publicDir source.

Result was that every /assets/** URL served the SSR HTML index with
Content-Type: text/html, producing OTS font-parse errors
(sfntVersion 1008821359 == '<!DT') and silently broken images.

Fix mirrors what was applied ad-hoc in Aeroflot.Flights.Front; this makes
future syncs and Docker builds carry the assets automatically.
2026-04-17 17:18:51 +03:00
gnezim 10dfc8609d Revert API_BASE_URL default: keep same-origin proxy for client-side CORS
Commit e20ef94 set the default to https://flights.test.aeroflot.ru/api,
which broke the browser client (no CORS headers on the test env;
scripts/dev-server.mjs is the only layer that can bypass it).

Keep PROD_ORIGIN pointing at the test env for SEO, but restore
API_BASE_URL default to http://localhost:8080/api with a comment
explaining the proxy chain: dev → Express+curl → flights.test.aeroflot.ru.
Production deployments continue to set API_BASE_URL explicitly.
2026-04-17 15:46:34 +03:00
gnezim e20ef940f8 Default API_BASE_URL and PROD_ORIGIN to the test environment
Previously API_BASE_URL defaulted to http://localhost:8080/api, which
only works inside the dev server proxy. For standalone/SSR runs without
the proxy, the default now points to https://flights.test.aeroflot.ru.

Dev continues to use the same-origin proxy because scripts/dev-server.mjs
explicitly injects API_BASE_URL=http://localhost:8080/api into the
Modern.js child process env, keeping browser fetches CORS/WAF safe.
2026-04-17 15:31:03 +03:00
gnezim dfe32fdee1 Add Makefile and sync script for flights-front deployment repo 2026-04-16 18:17:42 +03:00
gnezim 50f50eeae4 Add visual parity screenshot diff tool and mock appSettings in dev server
Add pixelmatch-based screenshot comparison script that captures Angular
(:4200) and React (:8080) at every route and generates pixel diff images.

Dev server: add mock /api/appSettings endpoint so Angular can bootstrap
when WAF blocks the real API.
2026-04-16 09:03:13 +03:00
gnezim d9bcccc1c5 Fix all e2e failures, sass warnings, and HMR websocket errors
CI / ci (push) Failing after 38s
Deploy / build-and-deploy (push) Failing after 6s
- Restructure OnlineBoardFilter to use radio tabs (flight/departure/
  arrival/route) with dynamic fields matching e2e test expectations
- Fix error page e2e tests to use client-side navigation (SSR renders
  empty outside [lang]/layout) and use specific CSS class locators
- Replace deprecated transparentize() with rgba() in _shadows.scss
- Handle WebSocket upgrades explicitly in dev-server to prevent HMR
  reconnection spam
- Resolve DEP0190 by spawning modern binary directly without shell
- Add tests/e2e-angular to tsconfig excludes
2026-04-16 00:23:10 +03:00
gnezim 20c19d15f4 Add standalone API proxy via curl (bypasses WAF TLS fingerprinting)
CI / ci (push) Failing after 23s
Deploy / build-and-deploy (push) Failing after 5s
Modern.js SSR intercepts all routes before any Express middleware,
so the API proxy runs as a separate Express server on port 8080.
Modern.js runs on 8081. The proxy uses curl subprocesses which go
through the system HTTPS proxy (GOST) with a proper TLS fingerprint
that the Aeroflot WAF accepts.

Usage: node scripts/dev-server.mjs (replaces pnpm dev for full-stack)

Also: remove stray e2e-angular test directory, fix env default to
same-origin /api.
2026-04-15 23:04:24 +03:00
gnezim e7c20c3d2d Fix API integration: proxy via Angular, date format, root redirect
CI / ci (push) Failing after 36s
Deploy / build-and-deploy (push) Failing after 5s
- Point API_BASE_URL to localhost:4200 (Angular's dev proxy) which
  correctly forwards to flights.test.aeroflot.ru with proper headers
- Convert URL date format (yyyyMMdd) to API format (yyyy-MM-ddT00:00:00)
  matching Angular's ApiFormatterService behavior
- Add standalone api-proxy.mjs script for running without Angular
- Root page redirect uses both loader and client-side navigate
- SignalR hub URL points to platform.yc.webzavod.ru/tracker/hub
- Remove broken server/modern-js.server.ts (proxy handled externally)
2026-04-15 22:08:54 +03:00
gnezim 003054460b Add coverage delta check script
CI / ci (push) Failing after 35s
Deploy / build-and-deploy (push) Failing after 6s
2026-04-15 16:33:01 +03:00
gnezim 1b0f15b082 Add bundle-size gate script for CI 2026-04-15 16:20:55 +03:00