Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-05-06 11:08:31 +03:00
parent 05a2a03a6a
commit 77fe2b04b6
38 changed files with 12676 additions and 8 deletions
+60 -1
View File
@@ -2,6 +2,7 @@ import axios from 'axios'
import qs from 'qs'
import { useAuthStore } from 'stores/authStore'
import { DEFAULT_LOCALE, normalizeLocale } from 'src/i18n/languages'
import { slog } from 'src/utils/slog'
const rawBaseUrl =
(typeof process !== 'undefined' && process.env?.VITE_API_BASE_URL) || '/api'
@@ -81,6 +82,20 @@ function getRequestLocale() {
return normalizeLocale(window.localStorage.getItem(LOCALE_STORAGE_KEY))
}
function extractTraceIdFromConfig(config) {
const rawTraceId =
config?.params?.trace_id ||
config?.headers?.['X-Trace-ID'] ||
config?.headers?.['x-trace-id'] ||
''
return String(rawTraceId || '').trim()
}
function shouldStructuredLogRequest(config) {
return extractTraceIdFromConfig(config) !== ''
}
api.interceptors.request.use((config) => {
const auth = useAuthStore()
const url = config.url || ''
@@ -92,6 +107,22 @@ api.interceptors.request.use((config) => {
config.headers ||= {}
config.headers['Accept-Language'] = getRequestLocale()
const traceId = extractTraceIdFromConfig(config)
config.__traceId = traceId
config.__startedAt = Date.now()
if (traceId) {
config.headers['X-Trace-ID'] = traceId
}
if (shouldStructuredLogRequest(config)) {
slog.info('production-product-costing.api', 'request:start', {
trace_id: traceId,
method: String(config.method || 'GET').toUpperCase(),
url,
params: config.params || {}
})
}
return config
})
@@ -148,7 +179,19 @@ function clearSessionAndRedirect() {
}
api.interceptors.response.use(
r => r,
(response) => {
const requestConfig = response?.config || {}
if (shouldStructuredLogRequest(requestConfig)) {
slog.info('production-product-costing.api', 'request:ok', {
trace_id: requestConfig.__traceId || extractTraceIdFromConfig(requestConfig),
method: String(requestConfig.method || 'GET').toUpperCase(),
url: String(requestConfig.url || ''),
status: response?.status || 200,
duration_ms: Math.max(0, Date.now() - Number(requestConfig.__startedAt || Date.now()))
})
}
return response
},
async (error) => {
const requestConfig = error?.config || {}
const status = error?.response?.status
@@ -169,6 +212,22 @@ api.interceptors.response.use(
console.error(`API ${status || '-'} ${method} ${requestUrl}: ${detail}`)
}
if (shouldStructuredLogRequest(requestConfig)) {
const detail = sanitizeApiErrorDetail(
await extractApiErrorDetail(error),
status
)
error.parsedMessage ||= detail
slog.error('production-product-costing.api', 'request:error', {
trace_id: requestConfig.__traceId || extractTraceIdFromConfig(requestConfig),
method: String(requestConfig.method || 'GET').toUpperCase(),
url: requestUrl,
status: status || 0,
duration_ms: Math.max(0, Date.now() - Number(requestConfig.__startedAt || Date.now())),
detail
})
}
const shouldTryRefresh =
status === 401 &&
!requestConfig._retry &&