Skip to content

Commit c1b7086

Browse files
authored
Merge pull request #24 from constructive-io/devin/1776487651-spatial-relations-blueprint
feat(provision): upgrade to latest PostGIS spatial-relation stack + 5 RelationSpatial entries + ORM tests
2 parents 71c4f02 + 3e190e0 commit c1b7086

16 files changed

Lines changed: 6727 additions & 9499 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
}
4545
},
4646
"devDependencies": {
47-
"@constructive-io/graphql-codegen": "4.28.0",
47+
"@constructive-io/graphql-codegen": "4.30.0",
4848
"@types/jest": "^30.0.0",
4949
"@types/node": "^25.0.3",
5050
"@typescript-eslint/eslint-plugin": "^8.58.0",

packages/agentic-db-services/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
},
2323
"keywords": [],
2424
"dependencies": {
25-
"@pgpm/metaschema-modules": "^0.20.2",
26-
"@pgpm/metaschema-schema": "^0.20.2",
25+
"@pgpm/metaschema-modules": "^0.21.0",
26+
"@pgpm/metaschema-schema": "^0.21.0",
2727
"@pgpm/services": "^0.20.2"
2828
},
2929
"devDependencies": {

packages/agentic-db/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"@pgpm/database-jobs": "^0.20.2",
2828
"@pgpm/inflection": "^0.20.1",
2929
"@pgpm/jwt-claims": "^0.20.0",
30-
"@pgpm/metaschema-schema": "^0.20.2",
30+
"@pgpm/metaschema-schema": "^0.21.0",
3131
"@pgpm/stamps": "^0.20.0",
3232
"@pgpm/totp": "^0.20.0",
3333
"@pgpm/types": "^0.20.0",
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- spatial-relations.sql — Bakes @spatialRelation smart tags into column
2+
-- comments so the graphile-postgis PostgisSpatialRelationsPlugin can
3+
-- register cross-table spatial filters on the owner tables.
4+
--
5+
-- These comments match the metadata that would be emitted by
6+
-- `metaschema_modules_public.provision_spatial_relation` running at
7+
-- blueprint-construction time (see packages/provision/src/schemas/
8+
-- spatial-relations.ts for the production path). We set them directly
9+
-- here so ORM integration tests can exercise the GraphQL filter shape
10+
-- without requiring a live Constructive platform to run the blueprint.
11+
--
12+
-- Tag format (parsed by graphile-postgis):
13+
-- @spatialRelation <name> <target_table.col> <operator> [<param>]
14+
--
15+
-- Five entries, one per pair:
16+
-- 1. memories.location_geo -> places.location_geo (nearbyPlaces, st_dwithin 5 km)
17+
-- 2. memories.location_geo -> contacts.location_geo (nearbyContacts, st_dwithin 2 km)
18+
-- 3. trips.destination_geo -> venues.location (nearbyVenues, st_dwithin 1 km)
19+
-- 4. events.location_geo -> venues.location (nearbyVenues, st_dwithin 500 m)
20+
-- 5. memories.location_geo -> memories.location_geo (nearbyMemories, st_dwithin 1 km, self)
21+
--
22+
-- Relation names are camelCase so the generated GraphQL filter fields
23+
-- match PostGraphile's inflection for every other field in the schema.
24+
-- Note: a column can carry multiple @spatialRelation tags — one per line.
25+
-- The smart-tag parser reads repeated-key values as an array.
26+
27+
COMMENT ON COLUMN agentic_db_app_public.memories.location_geo IS
28+
E'@spatialRelation nearbyPlaces places.location_geo st_dwithin distance\n'
29+
'@spatialRelation nearbyContacts contacts.location_geo st_dwithin distance\n'
30+
'@spatialRelation nearbyMemories memories.location_geo st_dwithin distance';
31+
32+
COMMENT ON COLUMN agentic_db_app_public.trips.destination_geo IS
33+
E'@spatialRelation nearbyVenues venues.location st_dwithin distance';
34+
35+
COMMENT ON COLUMN agentic_db_app_public.events.location_geo IS
36+
E'@spatialRelation nearbyVenues venues.location st_dwithin distance';

packages/integration-tests/__fixtures__/seed/test-data.sql

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ VALUES
2626

2727
-- Memories with PostGIS Point locations for spatial-filter tests.
2828
-- SF and Oakland are in the Bay Area bbox; NYC is the negative control.
29+
-- Coordinates are chosen so SF <-> Oakland is ~13 km apart (outside 5 km
30+
-- radius of each other) and NYC is ~4100 km from SF.
2931
INSERT INTO "agentic_db_app_public".memories (id, agent_id, title, content, location, location_geo)
3032
VALUES
3133
(
@@ -51,4 +53,147 @@ VALUES
5153
'Agent-infra meetup in Manhattan.',
5254
'New York, NY',
5355
ST_SetSRID(ST_MakePoint(-74.0060, 40.7128), 4326)::geography
56+
),
57+
-- Fourth memory ~260 m from the SF memory, so the self-referential
58+
-- `nearby_memories` relation has a matching "other" row for the
59+
-- "within 1 km of MEMORY_SF" test (the plugin excludes the owner row
60+
-- itself from self-relations). Coordinates are intentionally close to
61+
-- SF memory (-122.4194, 37.7749) and NOT the same as the Ferry Building
62+
-- Marketplace place (-122.3937, 37.7956), which is ~3.2 km away.
63+
(
64+
'eeeeeeee-eeee-eeee-eeee-eeeeeeee0004',
65+
'cccccccc-cccc-cccc-cccc-cccccccccccc',
66+
'Quick walk nearby',
67+
'Short walk a few blocks from the coffee spot.',
68+
'San Francisco, CA',
69+
ST_SetSRID(ST_MakePoint(-122.4180, 37.7770), 4326)::geography
70+
);
71+
72+
-- -----------------------------------------------------------------------
73+
-- Seed data for the RelationSpatial tests
74+
--
75+
-- Places: one next to the SF memory (~200 m), one next to NYC (~300 m),
76+
-- one in Tokyo (negative control). The SF place is ~13 km from Oakland,
77+
-- so "memories within 5 km of places" should pick up SF memory only for
78+
-- the first place, Oakland for none, and NYC for the NYC place.
79+
-- -----------------------------------------------------------------------
80+
INSERT INTO "agentic_db_app_public".places (id, name, address, category, location_geo)
81+
VALUES
82+
(
83+
'dddddddd-dddd-dddd-dddd-dddddddd0001',
84+
'Ferry Building Marketplace',
85+
'1 Ferry Building, San Francisco, CA',
86+
'market',
87+
ST_SetSRID(ST_MakePoint(-122.3937, 37.7956), 4326)::geography
88+
),
89+
(
90+
'dddddddd-dddd-dddd-dddd-dddddddd0002',
91+
'Bryant Park',
92+
'NYC, NY',
93+
'park',
94+
ST_SetSRID(ST_MakePoint(-73.9832, 40.7536), 4326)::geography
95+
),
96+
(
97+
'dddddddd-dddd-dddd-dddd-dddddddd0003',
98+
'Shibuya Crossing',
99+
'Tokyo, Japan',
100+
'landmark',
101+
ST_SetSRID(ST_MakePoint(139.7005, 35.6595), 4326)::geography
102+
);
103+
104+
-- Update the two seeded contacts with location_geo so the
105+
-- memories.nearby_contacts relation has something to match.
106+
-- Alice near the SF memory (~250 m), Bob in NYC (~400 m).
107+
UPDATE "agentic_db_app_public".contacts
108+
SET location = 'San Francisco, CA',
109+
location_geo = ST_SetSRID(ST_MakePoint(-122.4214, 37.7775), 4326)::geography
110+
WHERE id = '11111111-1111-1111-1111-111111111111';
111+
112+
UPDATE "agentic_db_app_public".contacts
113+
SET location = 'New York, NY',
114+
location_geo = ST_SetSRID(ST_MakePoint(-74.0021, 40.7105), 4326)::geography
115+
WHERE id = '22222222-2222-2222-2222-222222222222';
116+
117+
-- Venues: Bay Area SoMa (~1 km from SF memory), NYC (~350 m from NYC
118+
-- memory), London (negative control).
119+
INSERT INTO "agentic_db_app_public".venues (id, name, address, neighborhood, category, location)
120+
VALUES
121+
(
122+
'ffffffff-ffff-ffff-ffff-ffffffff0001',
123+
'SoMa Coffee Bar',
124+
'500 Howard St, San Francisco, CA',
125+
'SoMa',
126+
'cafe',
127+
ST_SetSRID(ST_MakePoint(-122.3985, 37.7879), 4326)::geography
128+
),
129+
(
130+
'ffffffff-ffff-ffff-ffff-ffffffff0002',
131+
'Times Square Diner',
132+
'1500 Broadway, New York, NY',
133+
'Midtown',
134+
'restaurant',
135+
ST_SetSRID(ST_MakePoint(-73.9855, 40.7580), 4326)::geography
136+
),
137+
(
138+
'ffffffff-ffff-ffff-ffff-ffffffff0003',
139+
'London Bridge Pub',
140+
'Tooley St, London',
141+
'London Bridge',
142+
'bar',
143+
ST_SetSRID(ST_MakePoint(-0.0877, 51.5045), 4326)::geography
144+
);
145+
146+
-- Trips: one destined SF (near SoMa venue), one destined NYC, one
147+
-- destined Paris (negative control).
148+
INSERT INTO "agentic_db_app_public".trips (id, name, destination, description, destination_geo)
149+
VALUES
150+
(
151+
'99999999-9999-9999-9999-999999990001',
152+
'SF Retrieval Summit',
153+
'San Francisco, CA',
154+
'Week-long onsite with the retrieval team.',
155+
ST_SetSRID(ST_MakePoint(-122.3990, 37.7880), 4326)::geography
156+
),
157+
(
158+
'99999999-9999-9999-9999-999999990002',
159+
'NYC AI Conf',
160+
'New York, NY',
161+
'Speaker slot at AI Conf.',
162+
ST_SetSRID(ST_MakePoint(-73.9860, 40.7585), 4326)::geography
163+
),
164+
(
165+
'99999999-9999-9999-9999-999999990003',
166+
'Paris Offsite',
167+
'Paris, France',
168+
'Engineering offsite.',
169+
ST_SetSRID(ST_MakePoint(2.3522, 48.8566), 4326)::geography
170+
);
171+
172+
-- Events: one right at the NYC venue (~50 m), one in SF far from SoMa
173+
-- (~2 km away, outside 500 m), one in Berlin (negative control).
174+
INSERT INTO "agentic_db_app_public".events (id, name, event_type, location, city, location_geo)
175+
VALUES
176+
(
177+
'88888888-8888-8888-8888-888888880001',
178+
'AI Conf Welcome Reception',
179+
'conference',
180+
'Times Square',
181+
'New York',
182+
ST_SetSRID(ST_MakePoint(-73.9853, 40.7582), 4326)::geography
183+
),
184+
(
185+
'88888888-8888-8888-8888-888888880002',
186+
'SF Ferry Building Mixer',
187+
'meetup',
188+
'Ferry Building',
189+
'San Francisco',
190+
ST_SetSRID(ST_MakePoint(-122.3937, 37.7956), 4326)::geography
191+
),
192+
(
193+
'88888888-8888-8888-8888-888888880003',
194+
'Berlin Hackathon',
195+
'hackathon',
196+
'Kreuzberg',
197+
'Berlin',
198+
ST_SetSRID(ST_MakePoint(13.4050, 52.5200), 4326)::geography
54199
);

0 commit comments

Comments
 (0)