V13-FE-006: consolidate approved UI and contract hardening
deploy / deploy (push) Successful in 1m52s
deploy / notify (push) Successful in 1s

This commit is contained in:
2026-08-13 02:41:00 +09:00
parent d79edae546
commit 3f293d8aa8
1278 changed files with 14384 additions and 1664 deletions
@@ -0,0 +1,6 @@
import type { KbxAiAnswer, KbxAiAskRequest } from '@kbx/contracts'
import { kbxApi } from '../http/generated/kbxApiClient'
export function askKbxAssistant(request: KbxAiAskRequest): Promise<KbxAiAnswer> {
return kbxApi.request<KbxAiAnswer, KbxAiAskRequest>('common.ai.ask', { body: request })
}
@@ -0,0 +1,6 @@
import type { KbxSuggestionRequest, KbxSuggestionResult } from '@kbx/contracts'
import { kbxApi } from '../http/generated/kbxApiClient'
export function submitKbxSuggestion(request: KbxSuggestionRequest): Promise<KbxSuggestionResult> {
return kbxApi.request<KbxSuggestionResult, KbxSuggestionRequest>('common.suggestions.submit', { body: request })
}
@@ -0,0 +1,64 @@
import { computed, ref } from 'vue'
import type { KbxAiAnswer, KbxAiScreenContext, KbxScreenDefinition, KbxSuggestionRequest } from '@kbx/contracts'
import { helpRegistry } from '../help/helpRegistry'
import { submitKbxSuggestion } from './suggestionApi'
import { askKbxAssistant } from './aiAssistantApi'
import { kbxAiCapabilities } from '../permissions/authorizationPolicy'
export interface KbxRuntimeContext {
route: string
appVersion: string
userRole: string
filters?: Record<string, unknown>
selectedIds?: string[]
entityId?: string
grantedPermissions?: string[]
}
export function useKbxScreenUtility(screen: KbxScreenDefinition, runtime: KbxRuntimeContext) {
const aiLoading = ref(false)
const aiAnswer = ref<KbxAiAnswer | null>(null)
const aiError = ref('')
const suggestionSubmitting = ref(false)
const help = computed(() => screen.helpKey ? helpRegistry[screen.helpKey] : undefined)
const aiContext = computed<KbxAiScreenContext>(() => ({
screenId: screen.id,
screenVersion: screen.version,
entityId: runtime.entityId,
selectedIds: runtime.selectedIds,
filters: runtime.filters,
allowedCapabilities: kbxAiCapabilities(runtime.grantedPermissions ?? [], ['explain', 'suggest', 'draft']),
}))
const suggestionContext = computed(() => ({
screenId: screen.id,
screenVersion: screen.version,
route: runtime.route,
appVersion: runtime.appVersion,
userRole: runtime.userRole,
activeFilters: runtime.filters ? Object.keys(runtime.filters).filter(k => runtime.filters?.[k] != null) : [],
}))
async function askAi(question: string) {
aiLoading.value = true
aiError.value = ''
try {
aiAnswer.value = await askKbxAssistant({ question, context: aiContext.value })
} catch {
aiError.value = '네트워크 상태를 확인한 후 다시 질문하세요.'
} finally {
aiLoading.value = false
}
}
async function submitSuggestion(request: KbxSuggestionRequest) {
suggestionSubmitting.value = true
try {
return await submitKbxSuggestion(request)
} finally {
suggestionSubmitting.value = false
}
}
return { help, aiContext, aiAnswer, aiLoading, aiError, suggestionContext, suggestionSubmitting, askAi, submitSuggestion }
}