Skip to content

feat: add generated area.geom column for improved geocode perfomance#307

Merged
joaquimds merged 1 commit intomainfrom
feat/geocode-performance
Feb 5, 2026
Merged

feat: add generated area.geom column for improved geocode perfomance#307
joaquimds merged 1 commit intomainfrom
feat/geocode-performance

Conversation

@joaquimds
Copy link
Member

No description provided.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a generated geom column to the area table to improve geocoding performance by converting the PostGIS geography column to a geometry column, achieving a reported 10x performance improvement with minimal accuracy loss.

Changes:

  • Added migration to create a generated geom column on the area table with a composite GIST index
  • Updated schema documentation to reflect the new column and indexes
  • Modified findAreasByPoint query to use ST_Covers on the geom column instead of ST_Intersects on the geography column

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
migrations/1770299199726_area_geom.ts Creates the generated geom column and composite GIST index for performance optimization
src/server/services/database/schema.ts Documents the new geom column, indexes, and updates metadata (also includes unrelated OrganisationUser changes)
src/server/repositories/Area.ts Updates findAreasByPoint to use ST_Covers on geom column instead of ST_Intersects on geography column

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +88 to +89
organisationId: string | null; // uuid, NULL
userId: string | null; // uuid, NULL
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The organisationId and userId columns in the OrganisationUser interface have been changed from NOT NULL to NULL. This change appears unrelated to the PR's stated purpose of adding the area.geom column for geocoding performance.

The original migration (migrations/1744117982427_organisation_user.ts) defines both columns as NOT NULL, and there's no migration file included in this PR that would alter these columns to be nullable. This suggests the schema documentation may be incorrect, or there's a missing migration that should be included in this PR.

Copilot uses AI. Check for mistakes.
*
* Last updated: 2026-01-15
* Last updated: 2026-02-05
* Based on migrations up to: 1764611637231_map_view_inspector_config.ts
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The schema documentation comment states "Based on migrations up to: 1764611637231_map_view_inspector_config.ts", but this PR adds a new migration file 1770299199726_area_geom.ts (with a later timestamp). The comment should be updated to reference the latest migration that this schema now reflects.

Suggested change
* Based on migrations up to: 1764611637231_map_view_inspector_config.ts
* Based on migrations up to: 1770299199726_area_geom.ts

Copilot uses AI. Check for mistakes.
}
return query
.where(sql<boolean>`ST_Intersects(geography, ST_GeomFromGeoJson(${point}))`)
.where(sql<boolean>`ST_Covers(geom, ST_GeomFromGeoJson(${point}))`)
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function has changed from using ST_Intersects on a geography column to ST_Covers on a geometry column. While both functions test spatial relationships, they have different semantics:

  • ST_Intersects returns true if the geometries/geographies share any space (including boundaries touching)
  • ST_Covers returns true only if every point of the second geometry is within or on the boundary of the first geometry

This means ST_Covers is more restrictive than ST_Intersects. A point that was previously found by ST_Intersects (e.g., on the boundary of an area) might not be found by ST_Covers, potentially changing the behavior of geocoding operations. This semantic difference should be verified to ensure it doesn't affect the correctness of the geocoding logic, particularly for edge cases where points fall on area boundaries.

Suggested change
.where(sql<boolean>`ST_Covers(geom, ST_GeomFromGeoJson(${point}))`)
.where(sql<boolean>`ST_Intersects(geom, ST_GeomFromGeoJson(${point}))`)

Copilot uses AI. Check for mistakes.
@joaquimds joaquimds merged commit d4e8f47 into main Feb 5, 2026
7 checks passed
@joaquimds joaquimds deleted the feat/geocode-performance branch February 5, 2026 14:51
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.

1 participant