Keep Google nearby results out of places list
All checks were successful
Build and deploy Backend / build (push) Successful in 28s

This commit is contained in:
Ruslan Bakiev
2026-05-13 22:11:41 +07:00
parent 17d8580387
commit 0668660e85

View File

@@ -74,6 +74,9 @@ function serializePlace(place: PlaceWithRecentExperiences) {
export async function listPlaces() { export async function listPlaces() {
const places = await prisma.place.findMany({ const places = await prisma.place.findMany({
where: {
experiences: { some: {} },
},
include: { include: {
experiences: { experiences: {
orderBy: { createdAt: 'desc' }, orderBy: { createdAt: 'desc' },
@@ -139,10 +142,9 @@ export async function listNearbyPlaces(input: NearbyPlacesInput) {
} }
const payload = (await response.json()) as GoogleNearbyResponse; const payload = (await response.json()) as GoogleNearbyResponse;
const googlePlaces = parseGoogleNearbyPlaces(input, payload); return parseGoogleNearbyPlaces(input, payload).map((place) =>
await upsertGooglePlaces(googlePlaces); serializeGoogleNearbyPlace(place),
);
return listPersistedNearbyPlaces(input);
} }
export async function listVoiceExperiences() { export async function listVoiceExperiences() {
@@ -218,77 +220,15 @@ function parseGoogleNearbyPlaces(
return [...placesByGoogleId.values()]; return [...placesByGoogleId.values()];
} }
async function upsertGooglePlaces(places: PersistableGooglePlace[]) { function serializeGoogleNearbyPlace(place: PersistableGooglePlace) {
await Promise.all( return {
places.map((place) => id: place.googlePlaceId,
prisma.place.upsert({ googlePlaceId: place.googlePlaceId,
where: { googlePlaceId: place.googlePlaceId },
create: place,
update: {
name: place.name, name: place.name,
latitude: place.latitude, latitude: place.latitude,
longitude: place.longitude, longitude: place.longitude,
googlePrimaryType: place.googlePrimaryType, googlePrimaryType: place.googlePrimaryType,
googleTypes: place.googleTypes, googleTypes: place.googleTypes,
}, experiences: [],
}),
),
);
}
async function listPersistedNearbyPlaces(input: NearbyPlacesInput) {
const bounds = coordinateBounds(
input.latitude,
input.longitude,
input.radiusMeters,
);
const places = await prisma.place.findMany({
where: {
latitude: { gte: bounds.minLatitude, lte: bounds.maxLatitude },
longitude: { gte: bounds.minLongitude, lte: bounds.maxLongitude },
},
include: {
experiences: {
orderBy: { createdAt: 'desc' },
take: 10,
include: { user: true },
},
},
});
return places
.map((place) => ({
place,
distanceMeters: distanceMeters(
input.latitude,
input.longitude,
place.latitude,
place.longitude,
),
}))
.filter(({ distanceMeters }) => distanceMeters <= input.radiusMeters)
.sort((a, b) => a.distanceMeters - b.distanceMeters)
.map(({ place }) => serializePlace(place));
}
function coordinateBounds(
latitude: number,
longitude: number,
radiusMeters: number,
) {
const metersPerLatitudeDegree = 111320;
const latitudeDelta = radiusMeters / metersPerLatitudeDegree;
const longitudeScale = Math.max(
Math.cos(degreesToRadians(latitude)),
0.000001,
);
const longitudeDelta =
radiusMeters / (metersPerLatitudeDegree * longitudeScale);
return {
minLatitude: latitude - latitudeDelta,
maxLatitude: latitude + latitudeDelta,
minLongitude: longitude - longitudeDelta,
maxLongitude: longitude + longitudeDelta,
}; };
} }