Seed geo catalog images
Build and deploy Docker image / build (push) Successful in 1m35s

This commit is contained in:
Ruslan Bakiev
2026-06-11 15:34:10 +07:00
parent 41cc2d7886
commit 9aed152765
3 changed files with 56 additions and 8 deletions
+14
View File
@@ -12,8 +12,10 @@ type GeoNode = {
transport_types?: string[] transport_types?: string[]
product_uuid?: string product_uuid?: string
product_name?: string product_name?: string
product_image_url?: string
supplier_uuid?: string supplier_uuid?: string
supplier_name?: string supplier_name?: string
supplier_logo_url?: string
price_per_unit?: string price_per_unit?: string
currency?: string currency?: string
quantity?: string quantity?: string
@@ -31,6 +33,7 @@ type DemoProduct = {
uuid: string uuid: string
name: string name: string
unit: string unit: string
imageUrl: string
} }
type DemoSupplier = { type DemoSupplier = {
@@ -40,6 +43,7 @@ type DemoSupplier = {
longitude: number longitude: number
country: string country: string
country_code: string country_code: string
logoUrl: string
hubKey: string hubKey: string
} }
@@ -73,16 +77,19 @@ const products: DemoProduct[] = [
uuid: '55555555-1111-4111-8111-111111111111', uuid: '55555555-1111-4111-8111-111111111111',
name: 'Solar panels', name: 'Solar panels',
unit: 'pallet', unit: 'pallet',
imageUrl: 'https://images.unsplash.com/photo-1509391366360-2e959784a276?auto=format&fit=crop&w=900&q=80',
}, },
{ {
uuid: '55555555-1111-4111-8111-222222222222', uuid: '55555555-1111-4111-8111-222222222222',
name: 'Industrial pumps', name: 'Industrial pumps',
unit: 'unit', unit: 'unit',
imageUrl: 'https://images.unsplash.com/photo-1581092160607-ee22621dd758?auto=format&fit=crop&w=900&q=80',
}, },
{ {
uuid: '55555555-1111-4111-8111-333333333333', uuid: '55555555-1111-4111-8111-333333333333',
name: 'Soybean meal', name: 'Soybean meal',
unit: 'ton', unit: 'ton',
imageUrl: 'https://images.unsplash.com/photo-1625246333195-78d9c38ad449?auto=format&fit=crop&w=900&q=80',
}, },
] ]
@@ -152,6 +159,7 @@ const suppliers: DemoSupplier[] = [
longitude: 113.3831, longitude: 113.3831,
country: 'China', country: 'China',
country_code: 'CN', country_code: 'CN',
logoUrl: 'https://ui-avatars.com/api/?name=Guangzhou+Solar+Factory&background=0B6BFF&color=fff&bold=true',
hubKey: 'logistics-demo-hub-1', hubKey: 'logistics-demo-hub-1',
}, },
{ {
@@ -161,6 +169,7 @@ const suppliers: DemoSupplier[] = [
longitude: 114.0579, longitude: 114.0579,
country: 'China', country: 'China',
country_code: 'CN', country_code: 'CN',
logoUrl: 'https://ui-avatars.com/api/?name=Shenzhen+Pump+Works&background=9F1239&color=fff&bold=true',
hubKey: 'logistics-demo-hub-2', hubKey: 'logistics-demo-hub-2',
}, },
{ {
@@ -170,6 +179,7 @@ const suppliers: DemoSupplier[] = [
longitude: 126.6617, longitude: 126.6617,
country: 'China', country: 'China',
country_code: 'CN', country_code: 'CN',
logoUrl: 'https://ui-avatars.com/api/?name=Harbin+Agro+Export&background=0F8A6A&color=fff&bold=true',
hubKey: 'logistics-demo-hub-3', hubKey: 'logistics-demo-hub-3',
}, },
{ {
@@ -179,6 +189,7 @@ const suppliers: DemoSupplier[] = [
longitude: 131.8735, longitude: 131.8735,
country: 'Russia', country: 'Russia',
country_code: 'RU', country_code: 'RU',
logoUrl: 'https://ui-avatars.com/api/?name=Vladivostok+Timber+Terminal&background=C45125&color=fff&bold=true',
hubKey: 'logistics-demo-hub-4', hubKey: 'logistics-demo-hub-4',
}, },
] ]
@@ -201,6 +212,7 @@ const supplierNodes: GeoNode[] = suppliers.map(supplier => ({
longitude: supplier.longitude, longitude: supplier.longitude,
country: supplier.country, country: supplier.country,
country_code: supplier.country_code, country_code: supplier.country_code,
supplier_logo_url: supplier.logoUrl,
synced_at: now, synced_at: now,
})) }))
@@ -221,8 +233,10 @@ const offers: GeoNode[] = Array.from({ length: 24 }, (_, index) => {
country_code: supplier.country_code, country_code: supplier.country_code,
product_uuid: product.uuid, product_uuid: product.uuid,
product_name: product.name, product_name: product.name,
product_image_url: product.imageUrl,
supplier_uuid: supplier.uuid, supplier_uuid: supplier.uuid,
supplier_name: supplier.name, supplier_name: supplier.name,
supplier_logo_url: supplier.logoUrl,
price_per_unit: String(900 + (index % 8) * 55), price_per_unit: String(900 + (index % 8) * 55),
currency: 'USD', currency: 'USD',
quantity: String(500 + index * 25), quantity: String(500 + index * 25),
+41 -7
View File
@@ -83,12 +83,16 @@ export const typeDefs = `#graphql
type Product { type Product {
uuid: String uuid: String
name: String name: String
imageUrl: String
offersCount: Int offersCount: Int
} }
type Supplier { type Supplier {
uuid: String uuid: String
name: String name: String
country: String
countryCode: String
logoUrl: String
latitude: Float latitude: Float
longitude: Float longitude: Float
distanceKm: Float distanceKm: Float
@@ -98,8 +102,10 @@ export const typeDefs = `#graphql
uuid: String uuid: String
productUuid: String productUuid: String
productName: String productName: String
productImageUrl: String
supplierUuid: String supplierUuid: String
supplierName: String supplierName: String
supplierLogoUrl: String
latitude: Float latitude: Float
longitude: Float longitude: Float
country: String country: String
@@ -115,8 +121,10 @@ export const typeDefs = `#graphql
uuid: String uuid: String
productUuid: String productUuid: String
productName: String productName: String
productImageUrl: String
supplierUuid: String supplierUuid: String
supplierName: String supplierName: String
supplierLogoUrl: String
latitude: Float latitude: Float
longitude: Float longitude: Float
country: String country: String
@@ -182,8 +190,10 @@ function mapOffer(doc: ArangoDoc) {
uuid: doc._key, uuid: doc._key,
productUuid: doc.product_uuid ?? null, productUuid: doc.product_uuid ?? null,
productName: doc.product_name ?? null, productName: doc.product_name ?? null,
productImageUrl: doc.product_image_url ?? null,
supplierUuid: doc.supplier_uuid ?? null, supplierUuid: doc.supplier_uuid ?? null,
supplierName: doc.supplier_name ?? null, supplierName: doc.supplier_name ?? null,
supplierLogoUrl: doc.supplier_logo_url ?? null,
latitude: doc.latitude ?? null, latitude: doc.latitude ?? null,
longitude: doc.longitude ?? null, longitude: doc.longitude ?? null,
country: doc.country ?? null, country: doc.country ?? null,
@@ -610,7 +620,7 @@ export const resolvers = {
FILTER node.product_uuid != null FILTER node.product_uuid != null
COLLECT product_uuid = node.product_uuid INTO offers COLLECT product_uuid = node.product_uuid INTO offers
LET first_offer = FIRST(offers).node LET first_offer = FIRST(offers).node
RETURN { uuid: product_uuid, name: first_offer.product_name } RETURN { uuid: product_uuid, name: first_offer.product_name, imageUrl: first_offer.product_image_url }
`) `)
return cursor.all() return cursor.all()
}, },
@@ -653,8 +663,17 @@ export const resolvers = {
FOR node IN nodes FOR node IN nodes
FILTER node.node_type == 'offer' FILTER node.node_type == 'offer'
FILTER node.supplier_uuid != null FILTER node.supplier_uuid != null
COLLECT supplier_uuid = node.supplier_uuid COLLECT supplier_uuid = node.supplier_uuid INTO offers
RETURN { uuid: supplier_uuid } LET first_offer = FIRST(offers).node
RETURN {
uuid: supplier_uuid,
name: first_offer.supplier_name,
country: first_offer.country,
countryCode: first_offer.country_code,
logoUrl: first_offer.supplier_logo_url,
latitude: first_offer.latitude,
longitude: first_offer.longitude
}
`) `)
return cursor.all() return cursor.all()
}, },
@@ -668,7 +687,7 @@ export const resolvers = {
FILTER node.product_uuid != null FILTER node.product_uuid != null
COLLECT product_uuid = node.product_uuid INTO offers COLLECT product_uuid = node.product_uuid INTO offers
LET first_offer = FIRST(offers).node LET first_offer = FIRST(offers).node
RETURN { uuid: product_uuid, name: first_offer.product_name } RETURN { uuid: product_uuid, name: first_offer.product_name, imageUrl: first_offer.product_image_url }
`, { supplier_uuid: args.supplierUuid }) `, { supplier_uuid: args.supplierUuid })
return cursor.all() return cursor.all()
}, },
@@ -701,7 +720,7 @@ export const resolvers = {
FILTER dist <= @radius_km FILTER dist <= @radius_km
COLLECT product_uuid = node.product_uuid INTO offers COLLECT product_uuid = node.product_uuid INTO offers
LET first_offer = FIRST(offers).node LET first_offer = FIRST(offers).node
RETURN { uuid: product_uuid, name: first_offer.product_name } RETURN { uuid: product_uuid, name: first_offer.product_name, imageUrl: first_offer.product_image_url }
`, { lat: hub.latitude, lon: hub.longitude, radius_km: args.radiusKm ?? 500 }) `, { lat: hub.latitude, lon: hub.longitude, radius_km: args.radiusKm ?? 500 })
return cursor.all() return cursor.all()
}, },
@@ -714,7 +733,16 @@ export const resolvers = {
FILTER node.product_uuid == @product_uuid FILTER node.product_uuid == @product_uuid
FILTER node.supplier_uuid != null FILTER node.supplier_uuid != null
COLLECT supplier_uuid = node.supplier_uuid COLLECT supplier_uuid = node.supplier_uuid
RETURN { uuid: supplier_uuid } LET first_offer = FIRST(offers).node
RETURN {
uuid: supplier_uuid,
name: first_offer.supplier_name,
country: first_offer.country,
countryCode: first_offer.country_code,
logoUrl: first_offer.supplier_logo_url,
latitude: first_offer.latitude,
longitude: first_offer.longitude
}
`, { product_uuid: args.productUuid }) `, { product_uuid: args.productUuid })
return cursor.all() return cursor.all()
}, },
@@ -952,6 +980,9 @@ export const resolvers = {
RETURN { RETURN {
uuid: supplier_uuid, uuid: supplier_uuid,
name: supplier_node != null ? supplier_node.name : first_offer.supplier_name, name: supplier_node != null ? supplier_node.name : first_offer.supplier_name,
country: supplier_node != null ? supplier_node.country : first_offer.country,
countryCode: supplier_node != null ? supplier_node.country_code : first_offer.country_code,
logoUrl: supplier_node != null ? supplier_node.supplier_logo_url : first_offer.supplier_logo_url,
latitude: supplier_node != null ? supplier_node.latitude : first_offer.latitude, latitude: supplier_node != null ? supplier_node.latitude : first_offer.latitude,
longitude: supplier_node != null ? supplier_node.longitude : first_offer.longitude, longitude: supplier_node != null ? supplier_node.longitude : first_offer.longitude,
distanceKm: supplier_dist distanceKm: supplier_dist
@@ -1020,6 +1051,9 @@ export const resolvers = {
return nodes.map((n: ArangoDoc) => ({ return nodes.map((n: ArangoDoc) => ({
uuid: n._key, uuid: n._key,
name: n.name ?? null, name: n.name ?? null,
country: n.country ?? null,
countryCode: n.country_code ?? null,
logoUrl: n.supplier_logo_url ?? null,
latitude: n.latitude ?? null, latitude: n.latitude ?? null,
longitude: n.longitude ?? null, longitude: n.longitude ?? null,
distanceKm: null, distanceKm: null,
@@ -1039,7 +1073,7 @@ export const resolvers = {
LET first_offer = FIRST(offers).node LET first_offer = FIRST(offers).node
SORT first_offer.product_name ASC SORT first_offer.product_name ASC
LIMIT @offset, @limit LIMIT @offset, @limit
RETURN { uuid: product_uuid, name: first_offer.product_name } RETURN { uuid: product_uuid, name: first_offer.product_name, imageUrl: first_offer.product_image_url }
`, { offset: args.offset ?? 0, limit: args.limit ?? 50, ...bounds.vars }) `, { offset: args.offset ?? 0, limit: args.limit ?? 50, ...bounds.vars })
return cursor.all() return cursor.all()
}, },