# St. Andrews Park

A Shiny mobile app for residents of St. Andrews Park, Venice, Florida.

## What it does

- Maps 388 property owners across 14 subdivisions
- Search owners by name, address, or subdivision
- Shows Venice city boundary and demographic facts
- Lists nearby EPA-monitored beach conditions
- Links to city services, county resources, and community documents

## Data sources

- **Owners** — Sarasota County Property Appraiser (SCPA); updated weekly via `data-raw/update_owners.R`
- **Subdivision boundaries** — Sarasota County GIS plat layer
- **Venice boundary** — Sarasota County GIS municipal boundary layer
- **Beaches** — EPA beach monitoring data

## Weekly update

```r
source("./data-raw/update_owners.R")
```

Downloads fresh SCPA data, joins to stable geometry, overwrites `data/owners.rds`.

## Geometry

Owner point locations were geocoded via Google API, manually corrected in QGIS
(multi-unit buildings share a street address and required individual point placement),
and saved as `data-raw/addresses/owners_moved.gpkg`. This file is the stable geometry
source. Account numbers follow the property, so only ownership attributes need
refreshing weekly.

## Deployment problems and solutions

**1. Workflow YAML syntax error**
The SSH heredoc (`<< 'EOF'`) inside a YAML `run:` block conflicted with YAML parsing — red triangle in Gitea, no logs.
→ Replaced with a quoted multiline SSH string.

**2. Runner not picking up jobs**
The workflow used `container: debian:bookworm-slim` just to get SSH, forcing the runner to pull a Docker image on every run.
→ Removed the container block, reverted to `runs-on: ubuntu-latest` using the cached runner image.

**3. Runner was repo-scoped, not user-scoped**
The act_runner was registered specifically for another repo. stAndrews showed zero runners and jobs stayed queued forever.
→ Re-registered the runner at the user level via Gitea User Settings → Actions → Runners.

**4. Two runner instances competing**
A manual `pkill` + manual restart created a second runner process alongside the systemd service, both sharing the same UUID.
→ Killed the duplicate, leaving only the systemd-managed instance.

**5. Gateway Caddyfile `import` silently failing**
The `import /data/projects/r/*/Caddyfile.snippet` directive was never evaluated — the gateway container only mounts the Caddyfile itself, not the project directories.
→ Added the stAndrews route directly to the gateway Caddyfile.

**6. renv activating inside the container**
The volume mount `.:/srv/shiny-server` put `.Rprofile` into the container, triggering renv to try installing its own library and conflicting with packages already installed in the image.
→ Switched to selective mounts (`./data` and `./www` only). App code is baked into the image; only runtime data is volume-mounted.

**7. `owners.rds` deleted from disk**
`git rm --cached data/owners.rds` removed it from git tracking but also wiped the file from the filesystem.
→ Ran `update_owners.R` inside the rstudio container to rebuild it from the SCPA source.

## Note: building footprints not used

Sarasota County publishes a building footprint GIS layer that could derive accurate
centroids without geocoding. However the footprint layer carries only a street number
(`buildingid`) with no street name — making a direct attribute join to SCPA records
ambiguous across multiple streets. A spatial join via street centerlines would resolve
this but adds complexity. Since accurate geometry already exists in `owners_moved.gpkg`
and St. Andrews is a built-out community with no new construction, the footprint
approach was deferred. It remains the right path if the app is ever extended to
additional subdivisions.
