10-Mar-2026 — map hang, GPX route parsing, mail API resilience, walk search layout
GPX Parser: Support Route Elements
- Root cause: GPX parser only handled
<trk>/<trkpt> (track)
elements but ignored <rte>/<rtept> (route) elements. 37 of 39
Sevenoaks walking route GPX files use <rte> format, so only 2
routes were rendering on the map
- Fix: added
parseRoute() and parseRoutePoints() methods to
convert <rte>/<rtept> elements into renderable GpxTrack objects
alongside existing <trk> parsing
- Waypoint dedup: changed
parseWaypoints() from selecting
"wpt, rtept" to just "wpt" — <rtept> elements are now parsed
as route tracks, not waypoints, preventing duplicate rendering
Map Viewport Hang Fix
- Root cause: Dragging/zooming the map triggered an infinite feedback
loop —
moveend → loadRoutes() → layer reassignment + fitBounds
→ Leaflet re-render → moveend again
- Debounced viewport handler: 300ms debounce on
moveend/zoomend
prevents rapid-fire reloads during panning
- Re-entrancy guard:
loadRoutesInProgress flag skips concurrent
loadRoutes() calls
- Suppress programmatic events:
suppressViewportHandler flag
prevents layer/bounds assignment from re-triggering the viewport
handler (cleared after 200ms)
- Skip fitBounds on viewport reloads:
loadRoutes(skipFitBounds)
parameter prevents calculateFitBounds on user-initiated pan/zoom,
which was the primary loop trigger
- Removed cache eviction on viewport change: the viewport filtering
already uses
currentBounds.intersects() on cached data, so deleting
and re-fetching GPX on every drag was unnecessary
Mail API Resilience (No API Key / Invalid Key)
- Short-circuit when no API key:
MailMessagingService.initialise()
checks mailConfig.apiKey after loading config — if absent, skips all
Brevo API calls (account, lists, folders, templates) and sets safe
empty defaults. Zero 401 errors in the console
- Short-circuit on account error: if the account query fails (invalid
key), remaining Brevo calls are skipped with empty defaults
- Senders list guard:
MailSendersListComponent waits for the
mailMessagingConfig via the events() observable before calling
senders/domain APIs — skips if accountError is set
- Create-or-amend sender guard: checks
brevoAccountConfigured()
before calling querySenders()
- Mail provider stats guard:
calculateMailProviderStats() handles
this.list being undefined when Brevo lists fail to load, showing
"No Brevo lists available" instead of crashing
- List key values null safety: added
?. and || [] fallback when
brevo.lists.lists is undefined
- Alert icon: changed error alert icon from
faCircleCheck to
faExclamationTriangle for the account error panel
CommonDataService Double HTTP Request Fix
- Root cause:
responseFrom() used .subscribe() + .toPromise()
on a shared observable, causing two subscriptions and duplicate HTTP
requests
- Fix: replaced with single
firstValueFrom() call — one
subscription, one HTTP request, proper error propagation via throw
Config Save: Allow Clearing Sensitive Fields
- Root cause:
restoreSensitiveFields() in the backend config
controller treated both missing keys AND falsy values ("", null)
as "restore from DB", making it impossible to clear the API key
- Fix: changed condition from
!(k in incoming) || !incoming[k] to
!(k in incoming) — only restores when the key is truly absent
(redacted), not when explicitly cleared
Mail Settings: Prevent Config Overwrite During Editing
- Root cause:
MailMessagingService.initialise() created new
subscriptions to committeeConfig and systemConfigService on every
call, causing accumulated subscriptions that re-emitted config and
overwrote unsaved edits
- Fix: moved one-time subscriptions to the constructor;
acceptNextConfigEmission flag in MailSettingsComponent prevents
subscription emissions from overwriting local edits except after
save or undo
Domain API URL Refactor
- Changed domain endpoints from path parameters
(
/domains/:domainName/configuration) to query parameters
(/domains/configuration?domainName=...) across backend routes and
frontend service
Walk Search Layout
- Alert inline when default filtering, own row with pagination/filters
- Clear filters resets to default preset
- Bug button hidden by default
Events
- Bug button visibility fix