Files
KArtSell.Aegis/docs/Design/kbx-foundation-v52-fe-operational-navigation-screen-anatomy/apps/web/src/http/kbxHttpClient.ts
T
kjh2064 c41e5063b7 chore: remove kbx-foundation-v36 reference (superseded by v4 implementation)
Removed entire kbx-foundation-v36 directory as it's been replaced by
the new KBX Foundation v4 patterns implemented in this session:
- Registry-driven screen definitions
- Density-aware UI adapter components
- Feature module templates (ShadowRun, Models)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-12 01:39:58 +09:00

64 lines
2.0 KiB
TypeScript

import axios, { AxiosError, type AxiosRequestConfig } from 'axios'
import { isKbxProblem, kbxUnexpectedProblem, type KbxProblem, type KbxSystemProblem } from '@kbx/contracts'
export const kbxHttp = axios.create({
timeout: 30_000,
headers: { 'X-KBX-Client': 'web' },
})
kbxHttp.interceptors.request.use(config => {
config.headers['X-Correlation-Id'] ??= crypto.randomUUID()
return config
})
kbxHttp.interceptors.response.use(
response => response,
(error: AxiosError) => {
const correlationId = String(error.config?.headers?.['X-Correlation-Id'] ?? crypto.randomUUID())
if (!error.response) {
const problem: KbxSystemProblem = {
type: 'system',
code: 'NETWORK_UNAVAILABLE',
title: '서버와 연결할 수 없습니다.',
detail: '입력한 내용은 유지됩니다. 네트워크 상태를 확인한 후 다시 시도하세요.',
correlationId,
retryable: true,
}
return Promise.reject(problem)
}
const data = error.response.data
if (isKbxProblem(data)) {
const problem: KbxProblem = {
...data,
correlationId: data.correlationId ?? correlationId,
}
return Promise.reject(problem)
}
if (error.response.status === 403) {
return Promise.reject({
type: 'permission', code: 'PERMISSION_DENIED', title: '이 작업을 수행할 권한이 없습니다.', correlationId,
} satisfies KbxProblem)
}
if (error.response.status === 404) {
return Promise.reject({
type: 'not-found', code: 'RESOURCE_NOT_FOUND', title: '요청한 데이터를 찾을 수 없습니다.', correlationId,
} satisfies KbxProblem)
}
return Promise.reject(kbxUnexpectedProblem(correlationId, `HTTP ${error.response.status}`, error.response.status >= 500))
},
)
export function withIdempotency(config: AxiosRequestConfig = {}, key = crypto.randomUUID()): AxiosRequestConfig {
return {
...config,
headers: {
...(config.headers ?? {}),
'Idempotency-Key': key,
},
}
}