refactor: remove all any types, add strict GraphQL scalar typing
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:
Ruslan Bakiev
2026-01-27 11:34:12 +07:00
parent ff34c564e1
commit 2dbe600d8a
42 changed files with 614 additions and 324 deletions

View File

@@ -24,7 +24,7 @@
<Card v-for="request in kycRequests" :key="request.uuid" padding="lg">
<Stack gap="3">
<Stack direction="row" gap="2" align="center" justify="between">
<Heading :level="4" weight="semibold">{{ request.companyName || t('kycOverview.list.unnamed') }}</Heading>
<Heading :level="4" weight="semibold">{{ request.teamName || t('kycOverview.list.unnamed') }}</Heading>
<Pill :variant="getStatusVariant(request)" :tone="getStatusTone(request)">
{{ getStatusText(request) }}
</Pill>
@@ -32,8 +32,8 @@
<Text tone="muted" size="base">
{{ t('kycOverview.list.submitted') }}: {{ formatDate(request.createdAt) }}
</Text>
<Text v-if="request.inn" tone="muted" size="base">
{{ t('kycOverview.list.inn') }}: {{ request.inn }}
<Text tone="muted" size="base">
{{ t('kycOverview.list.country') }}: {{ request.countryCode }}
</Text>
</Stack>
</Card>
@@ -91,7 +91,9 @@
</template>
<script setup lang="ts">
import { GetKycRequestsRussiaDocument } from '~/composables/graphql/user/kyc-generated'
import { GetKycRequestsRussiaDocument, type GetKycRequestsRussiaQueryResult } from '~/composables/graphql/user/kyc-generated'
type KycRequest = NonNullable<NonNullable<GetKycRequestsRussiaQueryResult['kycRequests']>[number]>
definePageMeta({
layout: 'topnav',
@@ -102,7 +104,7 @@ const { t } = useI18n()
const loading = ref(true)
const error = ref<string | null>(null)
const kycRequests = ref<any[]>([])
const kycRequests = ref<KycRequest[]>([])
const selectCountry = (country: string) => {
if (country === 'russia') {
@@ -110,21 +112,18 @@ const selectCountry = (country: string) => {
}
}
const getStatusVariant = (request: any) => {
const getStatusVariant = (request: KycRequest) => {
if (request.approvedAt) return 'primary'
if (request.rejectedAt) return 'outline'
return 'outline'
}
const getStatusTone = (request: any) => {
const getStatusTone = (request: KycRequest) => {
if (request.approvedAt) return 'success'
if (request.rejectedAt) return 'error'
return 'warning'
}
const getStatusText = (request: any) => {
const getStatusText = (request: KycRequest) => {
if (request.approvedAt) return t('kycOverview.list.status.approved')
if (request.rejectedAt) return t('kycOverview.list.status.rejected')
return t('kycOverview.list.status.pending')
}
@@ -143,10 +142,10 @@ const loadKYCStatus = async () => {
if (kycError.value) throw kycError.value
const requests = data.value?.kycRequests || []
// Сортируем по дате создания (новые первые)
kycRequests.value = [...requests].sort((a: any, b: any) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
)
} catch (err: any) {
kycRequests.value = [...requests]
.filter((r): r is KycRequest => r !== null)
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
} catch (err: unknown) {
error.value = t('kycOverview.errors.load_failed')
} finally {
loading.value = false

View File

@@ -57,24 +57,39 @@ const submitting = ref(false)
const submitError = ref<string | null>(null)
const submitSuccess = ref(false)
const handleSubmit = async (formData: any) => {
interface KycFormData {
company_name?: string
company_full_name?: string
inn?: string
kpp?: string
ogrn?: string
address?: string
bank_name?: string
bik?: string
correspondent_account?: string
contact_person?: string
contact_email?: string
contact_phone?: string
}
const handleSubmit = async (formData: KycFormData) => {
try {
submitting.value = true
submitError.value = null
const submitData = {
companyName: formData.company_name,
companyFullName: formData.company_full_name,
inn: formData.inn,
companyName: formData.company_name || '',
companyFullName: formData.company_full_name || '',
inn: formData.inn || '',
kpp: formData.kpp || '',
ogrn: formData.ogrn || '',
address: formData.address,
bankName: formData.bank_name,
bik: formData.bik,
address: formData.address || '',
bankName: formData.bank_name || '',
bik: formData.bik || '',
correspondentAccount: formData.correspondent_account || '',
contactPerson: formData.contact_person,
contactEmail: formData.contact_email,
contactPhone: formData.contact_phone,
contactPerson: formData.contact_person || '',
contactEmail: formData.contact_email || '',
contactPhone: formData.contact_phone || '',
}
const result = await mutate(CreateKycApplicationRussiaDocument, { input: submitData }, 'user', 'kyc')
@@ -85,8 +100,8 @@ const handleSubmit = async (formData: any) => {
} else {
throw new Error(t('kycRussia.errors.create_failed'))
}
} catch (err: any) {
submitError.value = err.message || t('kycRussia.errors.submit_failed')
} catch (err: unknown) {
submitError.value = err instanceof Error ? err.message : t('kycRussia.errors.submit_failed')
} finally {
submitting.value = false
}