refactor: remove all any types, add strict GraphQL scalar typing
All checks were successful
Build Docker Image / build (push) Successful in 4m3s
All checks were successful
Build Docker Image / build (push) Successful in 4m3s
- Add strictScalars: true to codegen.ts with proper scalar mappings (Date, Decimal, JSONString, JSON, UUID, BigInt → string/Record) - Replace all ref<any[]> with proper GraphQL-derived types - Add type guards for null filtering in arrays - Fix bugs exposed by typing (locationLatitude vs latitude, etc.) - Add interfaces for external components (MapboxSearchBox) This enables end-to-end type safety from GraphQL schema to frontend.
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
:key="option.sourceUuid ?? index"
|
||||
:location-name="getOfferData(option.sourceUuid)?.locationName"
|
||||
:product-name="productName"
|
||||
:price-per-unit="getOfferData(option.sourceUuid)?.pricePerUnit"
|
||||
:price-per-unit="parseFloat(getOfferData(option.sourceUuid)?.pricePerUnit || '0') || null"
|
||||
:currency="getOfferData(option.sourceUuid)?.currency"
|
||||
:unit="getOfferData(option.sourceUuid)?.unit"
|
||||
:stages="getRouteStages(option)"
|
||||
@@ -81,7 +81,8 @@ interface RoutePathType {
|
||||
totalTimeSeconds?: number | null
|
||||
stages?: (RouteStage | null)[]
|
||||
}
|
||||
import { GetOfferDocument, GetSupplierProfileByTeamDocument } from '~/composables/graphql/public/exchange-generated'
|
||||
import { GetOfferDocument, GetSupplierProfileByTeamDocument, type GetOfferQueryResult, type GetSupplierProfileByTeamQueryResult } from '~/composables/graphql/public/exchange-generated'
|
||||
import type { OfferWithRouteType, RouteStageType } from '~/composables/graphql/public/geo-generated'
|
||||
|
||||
const route = useRoute()
|
||||
const localePath = useLocalePath()
|
||||
@@ -90,12 +91,14 @@ const { execute } = useGraphQL()
|
||||
|
||||
const productName = computed(() => searchStore.searchForm.product || (route.query.product as string) || 'Товар')
|
||||
const locationName = computed(() => searchStore.searchForm.location || (route.query.location as string) || 'Назначение')
|
||||
const quantity = computed(() => (route.query.quantity as string) || (searchStore.searchForm as any)?.quantity)
|
||||
const quantity = computed(() => (route.query.quantity as string) || searchStore.searchForm.quantity)
|
||||
|
||||
// Offer data for prices
|
||||
const offersData = ref<Map<string, any>>(new Map())
|
||||
type OfferData = NonNullable<GetOfferQueryResult['getOffer']>
|
||||
const offersData = ref<Map<string, OfferData>>(new Map())
|
||||
// Supplier data for KYC profile UUID (by team_uuid)
|
||||
const suppliersData = ref<Map<string, any>>(new Map())
|
||||
type SupplierData = NonNullable<GetSupplierProfileByTeamQueryResult['getSupplierProfileByTeam']>
|
||||
const suppliersData = ref<Map<string, SupplierData>>(new Map())
|
||||
|
||||
const summaryTitle = computed(() => `${productName.value} → ${locationName.value}`)
|
||||
const summaryMeta = computed(() => {
|
||||
@@ -149,14 +152,16 @@ const fetchOffersByHub = async () => {
|
||||
const offers = offersResponse?.nearestOffers || []
|
||||
|
||||
// Offers already include routes from backend
|
||||
const offersWithRoutes = offers.map((offer: any) => ({
|
||||
sourceUuid: offer.uuid,
|
||||
sourceName: offer.productName,
|
||||
sourceLat: offer.latitude,
|
||||
sourceLon: offer.longitude,
|
||||
distanceKm: offer.distanceKm,
|
||||
routes: offer.routes || []
|
||||
}))
|
||||
const offersWithRoutes = offers
|
||||
.filter((offer): offer is NonNullable<OfferWithRouteType> => offer !== null)
|
||||
.map((offer) => ({
|
||||
sourceUuid: offer.uuid,
|
||||
sourceName: offer.productName,
|
||||
sourceLat: offer.latitude,
|
||||
sourceLon: offer.longitude,
|
||||
distanceKm: offer.distanceKm,
|
||||
routes: offer.routes || []
|
||||
}))
|
||||
|
||||
return { offersByHub: offersWithRoutes }
|
||||
}
|
||||
@@ -198,10 +203,12 @@ const mapRouteStages = (route: RoutePathType): RouteStageItem[] => {
|
||||
const getRouteStages = (option: ProductRouteOption) => {
|
||||
const route = option.routes?.[0]
|
||||
if (!route?.stages) return []
|
||||
return route.stages.filter(Boolean).map((stage: any) => ({
|
||||
transportType: stage?.transportType,
|
||||
distanceKm: stage?.distanceKm
|
||||
}))
|
||||
return route.stages
|
||||
.filter((stage): stage is NonNullable<RouteStageType> => stage !== null)
|
||||
.map((stage) => ({
|
||||
transportType: stage.transportType,
|
||||
distanceKm: stage.distanceKm
|
||||
}))
|
||||
}
|
||||
|
||||
// Get offer data for card
|
||||
@@ -233,8 +240,8 @@ const loadOfferDetails = async (options: ProductRouteOption[]) => {
|
||||
return
|
||||
}
|
||||
|
||||
const newOffersData = new Map<string, any>()
|
||||
const newSuppliersData = new Map<string, any>()
|
||||
const newOffersData = new Map<string, OfferData>()
|
||||
const newSuppliersData = new Map<string, SupplierData>()
|
||||
const teamUuidsToLoad = new Set<string>()
|
||||
|
||||
// First, load all offers
|
||||
|
||||
Reference in New Issue
Block a user