Skip to content

feat(web): implement configurable facility geofence boundary lock on leaflet map (#114) - #143

Merged
Decuayer merged 2 commits into
mainfrom
feat/SDDC-78-facility-boundary-lock
Sep 1, 2026
Merged

feat(web): implement configurable facility geofence boundary lock on leaflet map (#114)#143
Decuayer merged 2 commits into
mainfrom
feat/SDDC-78-facility-boundary-lock

Conversation

@Decuayer

@Decuayer Decuayer commented Sep 1, 2026

Copy link
Copy Markdown
Owner

🎯 Jira / Task Reference

  • Jira Issue: SDDC-78
  • Component: web | backend

📝 Summary of Changes

Implements a configurable facility geofence boundary lock for the interactive Leaflet GIS map in the Dispatch Operator Web Panel. This feature restricts the map viewport to the defined coordinates of the SOCAR Aliağa / STAR Refinery plant boundaries, preventing operators from panning outside operational zones while providing a preference toggle to enable or disable the constraint dynamically.

  • Leaflet JS Interop (leafletMap.js):

    • Defined predefined bounding box (SOCAR_FACILITY_BOUNDS) encompassing the SOCAR Aliağa / STAR Refinery complex ([38.7650, 26.8900] to [38.8350, 26.9750]).
    • Implemented exported function setMapBoundaryLock(enabled, customBounds) applying map.setMaxBounds(bounds) with maxBoundsViscosity = 1.0 (rigid elasticity) and minZoom = 13.
    • Included automatic smooth camera return (panInsideBounds) if the viewport was outside plant borders upon activation.
    • Supported both live map (map) and settings preview mini-map (pickerMap).
  • Blazor Service Bridge (IMapService / MapService.cs / MapBoundsDto.cs):

    • Created MapBoundsDto for strongly-typed coordinate transfer.
    • Added Task SetMapBoundaryLockAsync(bool enabled, MapBoundsDto? customBounds = null) across the map service bridge.
  • Operator Settings & UI Controls (MapSettingsSection.razor & MapControlOverlay.razor):

    • Added "Lock Map to Facility Boundary" switch component using design system .sd-switch in MapSettingsSection.razor.
    • Persisted preference via UserPreferencesDto.LockMapToFacilityBoundary in LocalStorage.
    • Added quick-toggle control on MapControlOverlay.razor so operators can toggle boundary constraints directly from /map.
    • Automatically applies stored boundary lock on /map initial render via LeafletMap.razor.
  • Backend Concurrency Fix (UpdateIncidentCommandHandler.cs):

    • Resolved EF Core DbUpdateConcurrencyException when updating incident media attachments by explicitly managing _context.IncidentMedia.Remove and Add.
    • Added regression test in UpdateIncidentAuthorizationTests.cs.

🏷️ Type of Change

  • 🚀 Feature: New functionality or operational workflow
  • 🐛 Bug Fix: Non-breaking fix for an identified defect (Incident update media concurrency)
  • ♻️ Refactor: Code restructuring without behavior alteration
  • Performance: Speed, query, or memory consumption optimization
  • 🛠️ Chore / Infra: Dependencies, Docker, CI/CD, or tooling updates
  • 📖 Documentation: README, API specs, or code documentation updates
  • ⚠️ Breaking Change: Requires schema migration or API contract changes

🧪 Testing & Verification

Automated Tests

  • Backend unit/integration tests executed: dotnet test (130 tests passing, 0 failures)
  • Web build verified: dotnet build clients/web/SocarDispatch.Web/SocarDispatch.Web.csproj (0 errors, 0 warnings)

Manual Test Steps

  1. Navigate to /settings and toggle "Lock Map to Facility Boundary" switch. Verify mini-map viewport locks to STAR Refinery bounds and choice persists across page refreshes.
  2. Navigate to /map. Verify viewport is constrained to Aliağa Peninsula / STAR Refinery coordinates when boundary lock is active.
  3. Attempt to pan outside refinery perimeter into surrounding sea/mountains; verify rigid bounce behavior (maxBoundsViscosity = 1.0).
  4. Attempt to zoom out beyond facility borders; verify minZoom = 13 constraint blocks zoom-out beyond plant scale.
  5. Disable boundary lock from Map Layers overlay panel; verify viewport can freely pan regional map.
  6. Verify updating incident details with media attachments succeeds without concurrency errors.

📋 Pre-Merge Checklist

  • My code adheres to the project's Clean Architecture & style guidelines.
  • I have self-reviewed my own code before requesting review.
  • Database migrations are backwards-compatible (if applicable).
  • Sensitive secrets / tokens are NOT committed (verified .env exclusions).
  • Jira status updated to In Review.

Closes #114
Ref: SDDC-78

…leaflet map

- Define SOCAR Aliaga / STAR Refinery operational bounding box coordinates in MapBoundsDto
- Implement setMapBoundaryLock JS interop in leafletMap.js with rigid viscosity (1.0) and minZoom constraints
- Expose SetMapBoundaryLockAsync via IMapService and MapService in Blazor client
- Add 'Lock Map to Facility Boundary' preference toggle to MapSettingsSection.razor with LocalStorage persistence
- Add quick-toggle control item to MapControlOverlay.razor on live operator map page
- Automatically apply facility geofence lock on LeafletMap.razor initial render based on user preferences
- Fix EF Core collection replacement concurrency exception in UpdateIncidentCommandHandler and add regression test

Closes #114
Ref: SDDC-78
@Decuayer
Decuayer merged commit 86dca8a into main Sep 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SDDC-78] Implement Configurable Facility Geofence Boundary Lock on Leaflet Map

1 participant