This commit is contained in:
+173
-56
@@ -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}`)
|
||||||
|
|||||||
Reference in New Issue
Block a user