---
name: deliveries-audit-open-items
description: Remaining unfixed audit findings on the Evolution deliveries/runsheet page after the 2026-06-15 fix session
metadata: 
  node_type: memory
  type: project
  originSessionId: 06f2152f-bcef-4a7e-aa14-5d9a28811a92
---

Audit of `?modules=projects&page=deliveries` (Evolution). As of 2026-06-15 the CRITICALs + several UX items are FIXED and committed; the items below are still OPEN.

**Fixed/committed this session:** SQL injection (parameterized all `$date`/`$branch`/`$newdate` interpolation across ajax.php, deliveries.php, deliveries-includes.php; added `$date` format validation); missing permission gate (added `mod_jc >= 1` gate in `app/templates/ajax.php` for runsheet handlers — admin OR mod_jc>=1); duplicate HTML `id="auto_manage_<id>"` (removed from View Map button in deliveries-includes.php:447, switched JS to class selectors w/ null guards); accordion-item flush packing + delivery-row gap removal (CSS in deliveries.php); dropMessage-jumps-during-drag (added `items: '> .delivery-row'` to all 4 `.assignment` sortable inits in assets/js/modules/deliveries.js).

**Fixed in a later session (2026-06-15, map robustness pass — code done, NOT yet verified in live app because the geocode key is IP-restricted to prod):**
- Geocode-false → broken JS (was deliveries.php:542): root cause was `$brch_geocode` (branch geocode) echoed into JS unguarded — `false[0]` → empty echo → `["", , ]` malformed arrays + broken map center. Now: single `$brch_has_geo` flag guards every branch-geo emission; `branch_geo`/delivery stops emitted via `json_encode` (also fixes addresses with apostrophes/quotes breaking the JS string). `loadmap()` rewritten to validate finite lat/lng, fall back to address-string routing when coords missing, frame via fitBounds on placed markers, and route in a SINGLE waypoint Directions request chunked at 25 stops (was per-leg loop). Error handler no longer references undefined `start`/`end`/`nextAddress` (those threw a ReferenceError, masking the real status). Branch geocode now DB-cached on a NEW `branches.geolocation` column (varchar(400), serialized [lat,lng,formatted_address] — same convention as jobs/sites/dispatch): `get_branch_geocode($brch,$address)` in deliveries-includes.php reads the column, geocodes+persists on first use (success only), reused thereafter; replaced the earlier session-based `geocode_cached()`. `branchaddsave.php` blanks geolocation on save so an edited branch address re-geocodes. Green start/finish pin (branch) vs default delivery pins; when branch has no coords the green pin is derived from the Directions result's first leg start / last leg end (no Geocoding-API dependency). Migration `migrations/branches_geolocation.sql` (ADD COLUMN IF NOT EXISTS, idempotent, per-tenant) — APPLIED dev + tenant-wide by Shane 2026-06-15. Schema doc `.claude/schema/tables/85-1384947162/branches.md` hand-updated.

KEY GOTCHA: `branches.geolocation` only populates when server-side `geocode()` SUCCEEDS, but `$googleGeocodeKey` is IP-restricted and DENIES the dev/code-server host IP 202.153.211.134 (confirmed REQUEST_DENIED). So on dev the column stays empty (map still works via client-side address-string fallback + green pin derived from Directions result). Chosen fix: authorize the server egress IP on the geocode key in Google Cloud Console (no code change); populates on prod where IP is already allowed. `geocode()` also still uses the LEGACY `maps.google.com` host (deliveries-includes.php:315) vs functions.php getGeocodeData() on `maps.googleapis.com` — works, align someday.

Drag/drop REORDER grey-map FIXED: `reload_map()` in assets/js/modules/deliveries.js rebuilt to reorder from in-memory `delivery_locations` (keyed by activity id == row data-id) instead of re-geocoding each row. Root cause was the ajax `get_delivery_location_via_ajax` handler (app/templates/ajax.php:210) calling live `geocode($address)` — denied on dev → empty newlocations → new map had no centre → grey. Also dropped the stale 3-arg `loadmap(id,locations,addr)` call (loadmap is now 2-arg). All files `php -l` / `node --check` clean.

**Still OPEN — High severity:**
- `return_delivery_row` called with wrong args at `app/modules/projects/deliveries/deliveries-includes.php:159` — signature is `return_delivery_row($date, $d, $runsheet_id, $drag=false, $map=false)`.
- Undefined `$runsheet->id` at `app/modules/projects/deliveries/deliveries-includes.php:513`.

**Still OPEN — optional hardening:**
- Tighter write=admin split: mutating AJAX handlers currently allowed at `mod_jc >= 1`; could require `mod_jc == 2` for writes (chose >=1 to match the page's existing exposure / not break level-1 users).

See [[evolution_ajax_save_auth_gate]] and [[evolution_permission_system]] for the auth model.
