17-Jan-2026 — Added reverse geocoding for walks missing locations ref: #104
Migrations performed
- Add migration to populate missing locations from lat/lng coordinates
- Uses postcodes.io reverse geocoding API
- Also populates grid references, locations, and incorrect end times if missing/invalid
Purpose: clarify what a Ramblers operator will see/address now that we tightened the “No location details” experience, OS Map styling, and location extraction.
No Location Details filter
- The advanced search now has a “No location details” checkbox. This checks for either a
start location (walks) or location (group events) fields for missing latitude/longitude/postcode/grid references.
- “No location details” means that the system cannot render a map for the event, or showing a pin for this event on a map view. When the checkbox is checked, the filter only matches walks truly lacking coordinates or postcodes.
- The backend now inspects
postcode + lat/lng and even grid references(6/8/10), so the search criteria that you set in the UI have the same expectations that the renderer (map view) has. Keep in mind the filter still behaves as before on
the UI
side: checking “No location details” hides walks that do not have a postcode or coordinates to show on the map.
Walks admin UX and data safety
- Walk edit history view was expanded for clearer event context (table layout and field display) so operators can diagnose location or migration changes without digging into raw JSON.
- WalksAndEventsService now consistently reads/deletes from the local store to avoid cross-population confusion for group walks vs socials.
- edit-group-event-images now guards against missing fields to avoid failures during edit flows.
Minor extras
- The location extraction tests now cover “Meet at…” phrasing (e.g., “Meet at Hitchin station”), and the extractor trims parentheses so the start location is stored cleanly.
- All shared helpers such as entries now live in functions/object-utils.ts, meaning components like AGM stats rely on the same helper and the functions folder is consolidated.
- You’ll still see the usual build/test warnings about deprecated Sass imports and CommonJS dependencies—they existed before this change and haven’t changed in behavior.
Walk navigation improvements
- Walk views now shows a “view” button on all walks for members with walk admin privileges. This provides a navigation to a read-only view of all the fields that NGX-Ramblers users see when they use the full "local" data population workflow. Of particular interest to this release is that the event history view (
walks/view/<slug>?tab=history). Data migrations now write events to history to show fields changed. This provides more insight in cases where a migration doesn't have the expected outcome e.g. geocoding failures are recorded here.
- Walk edit action row now groups copy-link / JSON utilities; input enablement respects view mode and walk write access.
Walk event history improvements
- Walk edit history rebuilt as an accordion with show/hide per entry.
- Added field-level change tables with from/to values and targeted change filtering for location/fix events.
- Added “revert to this version” for local walks with local walk population.
Refactor / code quality improvements
Location extraction is now consistent and DRY
- The data pipeline now uses the standardized GeocodeMatchType (kebab-case values only) everywhere, including the extracted-location type used in forms/transformations. That removes mismatched string literals and ensures the extractor and UI both understand whether a match
originated from a postcode, grid reference, or place name.
- The “ExtractedLocationType” union now explicitly restricts location fields to GeocodeMatchType.POSTCODE, .GRID_REFERENCE, or .PLACE_NAME. When you paste content into the page-transformation engine or walk editor, the system now enforces that rule, so you won’t accidentally
store
unsupported match types.
OS Map style selection is centralized
- Instead of hardcoded strings floating around, there is now a single OSMapStyle record with helper flags (is27700, is3857) and a lookup by key. Every map control/service (walk-edit map, walk list map, dynamic-content map, admin map controls, migration editors, etc.) now
consults
that record.
- If you switch to a “27700” basemap or the “outdoor” variant, the map controls, export links, and map overlays now all agree because they rely on the same constants and boolean helpers (OSMapStyle.is27700, OSMapStyle.is3857).
Mailchimp batch-subscribe compatibility cleaned up
- We now mirror the Mailchimp SDK’s Status type exactly (const object plus union type) so the backend can call lists.batchListMembers without type errors and still know which statuses/segments you’re targeting.
Admin/Migration UX polish
- Migration UI log timestamps now use DateUtils for consistent time values, and the migration history view is presented in a cleaner, more readable table.
- Migration runner now records startedAt alongside appliedAt so operators can see duration context for each migration attempt.
- Migrated enums/string unions (map providers, backup/session/status/payloads, markdown list types, route profiles, input sizes, Agm stats/tabs, sorting, migration/page-transformation modes, location/session statuses, etc.) into model files so the frontend and server share the same
types; enums now always use kebab-case values and are used everywhere (e.g., projects/ngx-ramblers/src/app/models/.ts, server/lib/mongo/models/.ts, admin pages, services, migration tools).
- Replaced the standalone entries helper with a consolidated implementation in projects/ngx-ramblers/src/app/functions/object-utils.ts (also updated to use keys from es-toolkit/compat), then cleaned imports such as agm-stats to reference the new helper.
- Updated Mailchimp type definitions to export const objects + union types so the backend code now accepts the same shape as the official SDK without introducing new string literals (projects/ngx-ramblers/src/app/models/mailchimp.model.ts, server/lib/mailchimp/lists/lists-batch-
subscribe.ts).
- Maintained DRY through shared model files for backup/session configs and ensured server imports only rely on frontend model definitions (no direct server/lib/... imports from the client).