Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 4s
CI / AI Services (Python) — Smoke (push) Failing after 4s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 48s
Deploy / Build API Image (push) Failing after 5s
Deploy / Build Web Image (push) Failing after 4s
Deploy / Build AI Services Image (push) Failing after 5s
E2E Tests / Playwright E2E (push) Failing after 7s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 3s
Security Scanning / Trivy Scan — API Image (push) Failing after 31s
Security Scanning / Trivy Scan — Web Image (push) Failing after 40s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 40s
Security Scanning / Trivy Filesystem Scan (push) Failing after 25s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Security Scanning / Security Gate (push) Failing after 1s
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
First PR of the OSM-sync project. Adds the schema scaffolding so the
follow-up bulk-import PR can write OSM-sourced rows alongside the 50
hand-curated industrial parks already in the table without disturbing
public list/detail/map flows or the IndustrialListing FK relationship.
New enums:
- IndustrialParkOsmType: NODE | WAY | RELATION
- IndustrialParkDataSource:
MANUAL existing curated rows (default for the 50 backfilled)
OSM raw OSM import, hidden from public until promoted
OSM_PROMOTED admin-reviewed OSM row visible on the public list
New columns on IndustrialPark:
- dataSource — drives public visibility + sync policy
- isPublic — true for MANUAL, false for raw OSM
- osmType, osmId — link to OSM entity (osmId UNIQUE)
- osmVersion, osmTags — incremental sync state + raw tag bag (JSONB)
- boundary — PostGIS MultiPolygon for park outline (Point
centroid stays in `location` for low-zoom render)
- osmLocked — admin freeze flag; sync skips this row entirely
- lockedFields — per-field freeze list; sync preserves listed cols
- lastSyncedAt — last reconcile pass timestamp
New indexes:
- osmId — sync upsert lookup
- (dataSource, isPublic) — public list filter
- boundary GiST — viewport / bbox spatial queries
- lastSyncedAt — cron staleness scan
Backfill behaviour: existing 20 rows automatically get
dataSource=MANUAL, isPublic=true via column defaults — no breaking
change for current consumers (frontend list, detail, map, admin
moderation, IndustrialListing FK).
Manually written migration SQL because Prisma cannot manage the
PostGIS Geometry type — `boundary` is added via AddGeometryColumn().
Next PRs:
- PR 2: bulk-import script (Overpass + osmium fallback)
- PR 3: bbox spatial API + frontend Mapbox layer (cluster + outlines)
- PR 4: monthly sync cron + admin diff/promote UI
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>