Refactor catalog to use coordinate-based GraphQL endpoints
All checks were successful
Build Docker Image / build (push) Successful in 3m33s

Replace entity-specific queries (GetProductsNearHub, GetOffersByHub, GetHubsForProduct, GetSuppliersForProduct) with unified coordinate-based endpoints (NearestHubs, NearestOffers, NearestSuppliers, RouteToCoordinate). This simplifies backend architecture from 18 to 8 core endpoints while maintaining identical UI/UX behavior.

All composables and pages now use coordinates + client-side grouping instead of specialized backend queries. For global product filtering, uses center point (0,0) with 20000km radius.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Ruslan Bakiev
2026-01-25 17:39:33 +07:00
parent 7403d4f063
commit 50375f2a74
6 changed files with 372 additions and 93 deletions

View File

@@ -43,7 +43,7 @@
</template>
<script setup lang="ts">
import { GetNodeConnectionsDocument, GetProductsNearHubDocument } from '~/composables/graphql/public/geo-generated'
import { GetNodeConnectionsDocument, NearestOffersDocument } from '~/composables/graphql/public/geo-generated'
definePageMeta({
layout: 'topnav'
@@ -122,17 +122,45 @@ const getMockPriceHistory = (uuid: string): number[] => {
// Initial load
try {
const [{ data: connectionsData }, { data: productsData }] = await Promise.all([
useServerQuery('hub-connections', GetNodeConnectionsDocument, { uuid: hubId.value }, 'public', 'geo'),
useServerQuery('products-near-hub', GetProductsNearHubDocument, { hubUuid: hubId.value, radiusKm: 500 }, 'public', 'geo')
])
// First load hub connections to get coordinates
const { data: connectionsData } = await useServerQuery(
'hub-connections',
GetNodeConnectionsDocument,
{ uuid: hubId.value },
'public',
'geo'
)
hub.value = connectionsData.value?.nodeConnections?.hub || null
// Get products near this hub (from geo)
products.value = (productsData.value?.productsNearHub || [])
.filter((p): p is { uuid: string; name?: string | null } => p !== null && !!p.uuid)
.map(p => ({ uuid: p.uuid!, name: p.name || '' }))
// Load offers near hub and group by product
if (hub.value?.latitude && hub.value?.longitude) {
const { data: offersData } = await useServerQuery(
'offers-near-hub',
NearestOffersDocument,
{
lat: hub.value.latitude,
lon: hub.value.longitude,
radius: 500
},
'public',
'geo'
)
// Group offers by product
const productsMap = new Map<string, { uuid: string; name: string }>()
offersData.value?.nearestOffers?.forEach((offer: any) => {
if (offer?.productUuid) {
if (!productsMap.has(offer.productUuid)) {
productsMap.set(offer.productUuid, {
uuid: offer.productUuid,
name: offer.productName || ''
})
}
}
})
products.value = Array.from(productsMap.values())
}
} catch (error) {
console.error('Error loading hub:', error)
} finally {