Connect demo geo catalog graph
Build and deploy Docker image / build (push) Successful in 1m27s

This commit is contained in:
Ruslan Bakiev
2026-06-07 14:09:31 +07:00
parent 38972ebce7
commit 489f6dbf81
+173 -56
View File
@@ -21,6 +21,28 @@ type GeoNode = {
synced_at: string synced_at: string
} }
type DemoHub = GeoNode & {
_key: string
latitude: number
longitude: number
}
type DemoProduct = {
uuid: string
name: string
unit: string
}
type DemoSupplier = {
uuid: string
name: string
latitude: number
longitude: number
country: string
country_code: string
hubKey: string
}
async function upsertNode(doc: GeoNode) { async function upsertNode(doc: GeoNode) {
const { _key, ...patch } = doc const { _key, ...patch } = doc
await getDb().query(aql` await getDb().query(aql`
@@ -46,7 +68,25 @@ await ensureGraph()
const now = new Date().toISOString() const now = new Date().toISOString()
const hubs: GeoNode[] = [ const products: DemoProduct[] = [
{
uuid: '55555555-1111-4111-8111-111111111111',
name: 'Copper cathode',
unit: 'ton',
},
{
uuid: '55555555-1111-4111-8111-222222222222',
name: 'Aluminum ingot',
unit: 'ton',
},
{
uuid: '55555555-1111-4111-8111-333333333333',
name: 'Wheat',
unit: 'ton',
},
]
const hubs: DemoHub[] = [
{ {
_key: 'logistics-demo-hub-1', _key: 'logistics-demo-hub-1',
node_type: 'logistics', node_type: 'logistics',
@@ -82,86 +122,163 @@ const hubs: GeoNode[] = [
}, },
] ]
const offers: GeoNode[] = Array.from({ length: 24 }, (_, index) => ({ const suppliers: DemoSupplier[] = [
_key: `geo-demo-offer-${index + 1}`,
node_type: 'offer',
name: `Demo offer ${index + 1}`,
latitude: 43.238949 + (index % 6) * 0.12,
longitude: 76.889709 + Math.floor(index / 6) * 0.18,
country: index % 3 === 0 ? 'Kazakhstan' : index % 3 === 1 ? 'China' : 'Russia',
country_code: index % 3 === 0 ? 'KZ' : index % 3 === 1 ? 'CN' : 'RU',
product_uuid: ['55555555-1111-4111-8111-111111111111', '55555555-1111-4111-8111-222222222222', '55555555-1111-4111-8111-333333333333'][index % 3],
product_name: ['Copper cathode', 'Aluminum ingot', 'Wheat'][index % 3],
supplier_uuid: ['66666666-2222-4111-8111-111111111111', '66666666-2222-4111-8111-222222222222', '66666666-2222-4111-8111-333333333333'][index % 3],
supplier_name: ['Demo Supplier Almaty', 'Demo Supplier Urumqi', 'Demo Supplier Moscow'][index % 3],
price_per_unit: String(900 + (index % 8) * 55),
currency: 'USD',
quantity: String(500 + index * 25),
unit: 'ton',
synced_at: now,
}))
const suppliers: GeoNode[] = [
{ {
_key: 'geo-demo-supplier-1', uuid: '66666666-2222-4111-8111-111111111111',
node_type: 'supplier',
name: 'Demo Supplier Almaty', name: 'Demo Supplier Almaty',
latitude: 43.25667, latitude: 43.25667,
longitude: 76.92861, longitude: 76.92861,
country: 'Kazakhstan', country: 'Kazakhstan',
country_code: 'KZ', country_code: 'KZ',
synced_at: now, hubKey: 'logistics-demo-hub-1',
}, },
{ {
_key: 'geo-demo-supplier-2', uuid: '66666666-2222-4111-8111-222222222222',
node_type: 'supplier',
name: 'Demo Supplier Urumqi', name: 'Demo Supplier Urumqi',
latitude: 43.825592, latitude: 43.825592,
longitude: 87.616848, longitude: 87.616848,
country: 'China', country: 'China',
country_code: 'CN', country_code: 'CN',
synced_at: now, hubKey: 'logistics-demo-hub-3',
}, },
{ {
_key: 'geo-demo-supplier-3', uuid: '66666666-2222-4111-8111-333333333333',
node_type: 'supplier',
name: 'Demo Supplier Moscow', name: 'Demo Supplier Moscow',
latitude: 55.755826, latitude: 55.755826,
longitude: 37.6173, longitude: 37.6173,
country: 'Russia', country: 'Russia',
country_code: 'RU', country_code: 'RU',
synced_at: now, hubKey: 'logistics-demo-hub-2',
}, },
] ]
for (const node of [...hubs, ...offers, ...suppliers]) { function quoteUuid(index: number) {
return `77777777-3333-4${String(index).padStart(3, '0')}-8${String(index).padStart(3, '0')}-777777${String(index).padStart(6, '0')}`
}
function hubByKey(key: string) {
const hub = hubs.find(item => item._key === key)
if (!hub) throw new Error(`Unknown demo hub: ${key}`)
return hub
}
const supplierNodes: GeoNode[] = suppliers.map(supplier => ({
_key: supplier.uuid,
node_type: 'supplier',
name: supplier.name,
latitude: supplier.latitude,
longitude: supplier.longitude,
country: supplier.country,
country_code: supplier.country_code,
synced_at: now,
}))
const offers: GeoNode[] = Array.from({ length: 24 }, (_, index) => {
const product = products[index % products.length]
const supplier = suppliers[Math.floor(index / products.length) % suppliers.length]
const localIndex = Math.floor(index / suppliers.length)
const latitudeOffset = ((localIndex % 3) - 1) * 0.08
const longitudeOffset = (Math.floor(localIndex / 3) - 1) * 0.1
return {
_key: quoteUuid(index),
node_type: 'offer',
name: `${supplier.name} ${product.name}`,
latitude: supplier.latitude + latitudeOffset,
longitude: supplier.longitude + longitudeOffset,
country: supplier.country,
country_code: supplier.country_code,
product_uuid: product.uuid,
product_name: product.name,
supplier_uuid: supplier.uuid,
supplier_name: supplier.name,
price_per_unit: String(900 + (index % 8) * 55),
currency: 'USD',
quantity: String(500 + index * 25),
unit: product.unit,
synced_at: now,
}
})
for (const node of [...hubs, ...offers, ...supplierNodes]) {
await upsertNode(node) await upsertNode(node)
} }
await upsertEdge({ const hubLinks = [
_key: 'geo-demo-edge-1', {
_from: 'nodes/logistics-demo-hub-1', from: 'logistics-demo-hub-1',
_to: 'nodes/logistics-demo-hub-2', to: 'logistics-demo-hub-2',
to_uuid: 'logistics-demo-hub-2', distanceKm: 3950,
to_name: 'Demo Moscow Hub', travelTimeSeconds: 864000,
to_latitude: 55.755826, transportType: 'rail',
to_longitude: 37.6173, },
distance_km: 3950, {
travel_time_seconds: 864000, from: 'logistics-demo-hub-2',
transport_type: 'rail', to: 'logistics-demo-hub-1',
}) distanceKm: 3950,
travelTimeSeconds: 864000,
transportType: 'rail',
},
{
from: 'logistics-demo-hub-1',
to: 'logistics-demo-hub-3',
distanceKm: 1050,
travelTimeSeconds: 172800,
transportType: 'auto',
},
{
from: 'logistics-demo-hub-3',
to: 'logistics-demo-hub-1',
distanceKm: 1050,
travelTimeSeconds: 172800,
transportType: 'auto',
},
{
from: 'logistics-demo-hub-3',
to: 'logistics-demo-hub-2',
distanceKm: 4650,
travelTimeSeconds: 950400,
transportType: 'rail',
},
{
from: 'logistics-demo-hub-2',
to: 'logistics-demo-hub-3',
distanceKm: 4650,
travelTimeSeconds: 950400,
transportType: 'rail',
},
]
await upsertEdge({ for (const [index, link] of hubLinks.entries()) {
_key: 'geo-demo-edge-2', const toHub = hubByKey(link.to)
_from: 'nodes/logistics-demo-hub-1', await upsertEdge({
_to: 'nodes/logistics-demo-hub-3', _key: `geo-demo-hub-edge-${index + 1}`,
to_uuid: 'logistics-demo-hub-3', _from: `nodes/${link.from}`,
to_name: 'Demo Urumqi Hub', _to: `nodes/${link.to}`,
to_latitude: 43.825592, to_uuid: link.to,
to_longitude: 87.616848, to_name: toHub.name,
distance_km: 1050, to_latitude: toHub.latitude,
travel_time_seconds: 172800, to_longitude: toHub.longitude,
transport_type: 'auto', distance_km: link.distanceKm,
}) travel_time_seconds: link.travelTimeSeconds,
transport_type: link.transportType,
})
}
console.log(`Seeded geo demo data: hubs ${hubs.length}, offers ${offers.length}, suppliers ${suppliers.length}`) for (const [index, offer] of offers.entries()) {
const supplier = suppliers[Math.floor(index / products.length) % suppliers.length]
await upsertEdge({
_key: `geo-demo-offer-edge-${index + 1}`,
_from: `nodes/${supplier.hubKey}`,
_to: `nodes/${offer._key}`,
to_uuid: offer._key,
to_name: offer.name,
to_latitude: offer.latitude,
to_longitude: offer.longitude,
distance_km: Math.max(1, Math.round(Math.hypot((offer.latitude - supplier.latitude) * 111, (offer.longitude - supplier.longitude) * 75))),
travel_time_seconds: 3600 + index * 120,
transport_type: 'offer',
})
}
console.log(`Seeded geo demo data: hubs ${hubs.length}, offers ${offers.length}, suppliers ${suppliers.length}, edges ${hubLinks.length + offers.length}`)