Iframe embed for the Permitting app (LUPMIS2_Reusable_Mapping_Concept §3.2):
- public/embed.php — SSO + production gate + frame-ancestors CSP +
whitelisted URL params (mode, lon/lat/zoom, upn, basemap,
application_code); injects window.LUPMIS_SESSION + window.LUPMIS_EMBED.
- public/.htaccess — clean /embed URL (rewrite before the SPA fallback).
- src/embed-bridge.js — postMessage protocol: out ready / parcel:select /
parcel:cleared / error; in set:view / set:selected / clear:selected /
set:basemap. Visual highlight via a dedicated VectorLayer; pending-UPN
queue resolved as parcels stream in.
- main.js — reads window.LUPMIS_EMBED, gates the normal click/dblclick
handlers in permit mode, exposes parcelsLayer to module scope, makes
it visible and hands it to the bridge after loadParcels().
- index.html — CSS for body.embed-mode-permit hides navbar/dock/offcanvas
and lets the map fill the iframe.
- LUPMIS2_Permit_Map_Integration.docx — integration instructions for the
Permitting team (contract, show.blade.php changes, phasing).
Local lu_parcels structural refactor:
- src/database.js — parcels table now mirrors spatial.lu_parcels with
explicit columns (upn, style, landuse, zone_code/name, sector, block,
parcel_no, prop_no, st_name, prop_add, fac_name, min/max_height,
eff_date, lp_name, locality, mmda, last_update, remarks, geom→geometry_wkt,
created_at, updated_at, districtid) plus local-only status/fetched_at.
Drop-and-recreate migration off `upn` presence. saveParcels wraps the
~25k inserts in a transaction; numeric coercion via numOrNull.
updateParcel/insertNewParcel write individual columns.
- main.js parcelsToGeoJSON — handles GeoJSON `geom` object (API) and
`geometry_wkt` string (local cache); skips housekeeping fields.
Production access guard + no-district overlay:
- public/index.php — on *.lupmis4luspa.org, redirect to the SSO portal
if no session.
- src/remotedb.js resolveDistrictId — no silent fallback to '1' for an
authenticated user; dev mode (no session at all) keeps the fallback.
- main.js — blocking overlay if the session lacks district_id; init
aborts so no API call is made with the wrong scope.
LayerSwitcher ordering fix:
- MapView.initEditBar + MapTools — find the Overlays group by reference
/ title instead of assuming it's the last layer (the GPS layers
add-layered on top in the constructor broke that assumption).
Service Worker v8 → v9 to evict stale shell/module caches on deploy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Major:
- GPS trail recording: reusable, dependency-free engine in src/geotracker/
(GeoTracker + geo-utils) with pluggable storage/sync adapters; LUPMIS
wiring in src/geotracker-lupmis.js. Expandable My Location control
(Locate Me + Record Trail), live navbar GPS readout, on-map trail/position
rendering, gps_trails/gps_trail_points SQLocal tables, and store-and-forward
sync via pushGpsTrail() -> save_gps_trail.php (server side documented, not
yet built).
- SSO authentication: public/index.php entry point validates the LUSPA SSO
cookie and injects window.LUPMIS_SESSION; remotedb district_id is now a
session-resolved getter. Adds public/.htaccess (DirectoryIndex).
- Account menu offcanvas (navbar burger) with sign-in/out states.
UI / fixes:
- LayerSwitcher modernisation; base-map "None" option in picker + settings.
- Mobile drawing toolbar wraps to two rows below 576px and shows only in
Draw mode; second row right-aligned and clears the Select option bar.
- Safari bottom-dock clipping fixed (app-container 100dvh -> 100svh).
- Rename public/icons -> app-icons to dodge Apache's default /icons/ alias.
- Service Worker bumped to v8 (network-first HTML, per-provider tile clear).
Docs: reusable-mapping and OSM-3D-buildings concept notes; ignore Office
lock files (~$*). Rebuilt dist/.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>