Prerequisite for re-enabling e2e in ci-deploy. Identifies the new Date()
class as the highest-impact fix and proposes hoisting today/now to the
route loader so SSR and CSR see identical values via _ROUTER_DATA.
Two design pivots discovered during Phase B prerequisites:
Routing: Replace static-route + NAT plan with persistent ssh -L tunnel
from pve-201 to webzavod (deployment/systemd/flights-tim-tunnel.service).
nginx proxies /api/ and /map/api/ to https://127.0.0.1:8443 with SNI/Host
overrides so cert validation still targets the real hostname. No webzavod
kernel changes (no ip_forward/MASQUERADE), no /etc/hosts pin needed.
Workflow B: Drop Jenkins trigger/poll automation (operator lacks Jenkins
job-configure access and user API token access). release.yml now stops
after MR merge with a Telegram message containing the Jenkins job URL.
release-verify.yml (new, workflow_dispatch only) runs the customer-URL
e2e suite once the operator has triggered Jenkins manually and it has
completed.
Other:
- SSR loopback port 8081 -> 3002 (8081 was taken by openwebui on pve-201)
- notify-telegram.sh skips cleanly when TG secrets unset (was: hard-fail)
- README + spec addendum cover the new prereqs and removed steps
Captures the agreed two-workflow shape (push-deploy + manual release)
so the implementation plan has an unambiguous source of truth before
touching scripts, Dockerfile build-args, or nginx config.
Client makes no stale-serving assumptions: every Online-Board and Schedule
search triggers a fresh upstream fetch; dictionaries are loaded once per
session. Cache-Control TTLs (≤1 min board, ≤10 min schedule) and ETag/304
for dictionary endpoints are set by the backend HTTP layer. CachedApiClient
/ ServerLruCache infrastructure exists in src/shared/api/ for future SSR
caching if needed. All three 4.1.18 rules marked Out-of-scope (backend) in
the spec; coverage counters updated (13 → 16 out-of-scope, TBD −3).
R4 gap fixed: TimeGroup now accepts scheduledDayChange + actualDayChange props
separately so each time type renders its own independent badge. FlightCard
updated to pass them independently (scheduled vs actual/estimated); expanded
row time block also now shows per-type badges.
R5 tooltip fixed: dayChangeBadgeTooltip() uses string-based date extraction
(no TZ reprojection via new Date()) — avoids viewer-TZ shift for SSR and
cross-TZ correctness. Returns "День" for ±1, DD.MM.YYYY for ±2+.
New shared helper dayChange.ts exports computeDayChange(), dayChangeBadgeTooltip(),
formatDayChangeBadge(). 27 unit tests cover +0/+1/+2/-1/-2, null, malformed
input, month/year boundaries, and per-time-type independence (R4).
R1–R3, R6 confirmed correct (API supplies dayChange per ITimesSet; badge
adjacent to time; hidden when 0). R8 (mobile tooltip suppression) deferred.
Companion markdown to the comparison-report/visual/report.html with
the same coverage matrix and per-page findings. Useful for git-based
review without serving the HTML.
Also adds AGENTS.md (subagent role definitions for future sessions)
and the modernjs-v3-upgrade plan stub from the earlier scoping.
Final C-gap sub-feature: calendarRange pure helpers
(getMinDate/getMaxDate/buildDisabledDates/findNextEnabledDate), snap-to-
nearest-enabled effect in FlightsMapFilter, and useGeolocationDefault
hook that pre-fills departure from browser position on mount when no
dep/arr is already set.
Covers the final four Angular-parity gaps: filterRoutes pure helper,
buildBuyTicketUrl + escapeHtml, routesToPolylines/intermediateCityIds
airport→city normalization, and FlightsMapStartPage wiring for the
auto-fallback effect plus departure/arrival buy-ticket popups.
Six TDD tasks covering the routes-to-polylines pure helper, IMapPolyline
reshape to cityIds, MapCanvas polyline sync with visibility filtering,
intermediate-tooltip force-open pass, page wiring, and integration tests.
Tasks 1-3 share a commit due to coupling between type and consumer.
Covers the polyline layer: routesToPolylines pure function, city-code-
based IMapPolyline shape, MapCanvas polyline sync via markerIndexRef
with visibility filtering, intermediate-city tooltip force-open pass.
Captures the data-layer scope for the flights-map rebuild: useDictionaries
hook, parallel fetch of world_regions/countries/cities/airports, transform
rules matching Angular DictionariesService, and the testing contract.