시스템 개요
고객 신용 리스크 점수 시스템은 Kotlin Multiplatform(KMP)과 OpenHarmony를 기반으로 구축된 크로스플랫폼 신용 관리 솔루션입니다. 이 시스템은 지급 준수율, 부도율, 거래 빈도, 평균 거래 금액, 신용 경력 등 다차원적인 신용 데이터를 실시간으로 수집·분석하여 기업의 리스크 관리 부서에 과학적이고 정량화된 의사결정 지원을 제공합니다.
전통적인 신용 심사는 주로 수작업과 정적 데이터에 의존하여 처리 속도가 느리고 기준이 불명확하며 실시간 리스크 탐지가 어렵다는 한계가 있습니다. 본 시스템은 KMP 아키텍처를 활용해 코어 알고리즘을 Kotlin으로 작성하고, 이를 JavaScript 및 ArkTS 환경에서 재사용함으로써 플랫폼 간 일관성 있는 신용 분석 기능을 구현합니다.
주요 기능
- 다중 지표 통합 모니터링: 5개 핵심 지표(지급 준수율, 부도율, 거래 빈도, 평균 거래 금액, 신용 경력)를 동시에 분석
- 가중치 기반 종합 평가: 각 지표에 가중치를 적용한 복합 점수 산출 (예: 지급 준수율 30%, 부도율 25%)
- 등급별 리스크 제안: AAA부터 BB까지 5단계 신용 등급에 따른 맞춤형 관리 전략 제공
- 크로스플랫폼 실행: 동일한 비즈니스 로직을 웹, 모바일, 임베디드 장치에서 공유
기술 스택 구성
시스템은 세 가지 계층으로 설계되었습니다:
- 코어 계층 (Kotlin): @JsExport 어노테이션을 사용해 JS로 노출 가능한 분석 함수 정의
- 인터페이스 계층 (JavaScript): 브라우저 호환성을 보장하는 중간 번역 계층
- 프레젠테이션 계층 (ArkTS): OpenHarmony UI 프레임워크를 활용한 인터랙티브 인터페이스
핵심 알고리즘 재설계
@JsExport
fun evaluateCustomerRisk(input: String): String {
val values = input.trim().split(" ").mapNotNull { it.toDoubleOrNull() }
if (values.size != 5) return "입력 오류: 5개의 숫자 값을 공백으로 구분하여 입력하세요."
val (timeliness, defaultRate, frequency, amount, history) = values
// 유효성 검사
if (!isValidRange(timeliness, 0.0, 100.0)) return "지급 준수율은 0~100 사이여야 합니다."
if (!isValidRange(defaultRate, 0.0, 100.0)) return "부도율은 0~100 사이여야 합니다."
if (!isValidRange(frequency, 0.0, 1000.0)) return "거래 빈도는 0~1000 사이여야 합니다."
if (!isValidRange(amount, 0.0, 10000.0)) return "평균 거래 금액은 0~10000 사이여야 합니다."
if (!isValidRange(history, 0.0, 100.0)) return "신용 경력은 0~100 사이여야 합니다."
// 점수 변환
val scores = mapOf(
"timeliness" to timeliness.toInt(),
"default" to scoreDefaultRate(defaultRate),
"frequency" to scoreTransactionFrequency(frequency),
"amount" to scoreAverageAmount(amount),
"history" to scoreCreditHistory(history)
)
// 가중 합산
val totalScore = calculateWeightedScore(scores)
// 결과 생성
return generateComprehensiveReport(scores, totalScore, timeliness, defaultRate, frequency, amount, history)
}
private fun isValidRange(value: Double, min: Double, max: Double) = value in min..max
private fun scoreDefaultRate(rate: Double) = when {
rate <= 1 -> 100
rate <= 3 -> 85
rate <= 5 -> 70
else -> 40
}
private fun scoreTransactionFrequency(freq: Double) = when {
freq >= 20 -> 100
freq >= 10 -> 85
freq >= 5 -> 70
else -> 40
}
private fun scoreAverageAmount(amount: Double) = when {
amount >= 100 -> 100
amount >= 50 -> 85
amount >= 20 -> 70
else -> 40
}
private fun scoreCreditHistory(years: Double) = when {
years >= 10 -> 100
years >= 5 -> 85
years >= 2 -> 70
else -> 40
}
private fun calculateWeightedScore(scores: Map<String, Int>) = (
scores["timeliness"]!! * 0.30 +
scores["default"]!! * 0.25 +
scores["frequency"]!! * 0.15 +
scores["amount"]!! * 0.15 +
scores["history"]!! * 0.15
).toInt()
private fun generateComprehensiveReport(
scores: Map<String, Int>,
total: Int,
timeliness: Double,
defaultRate: Double,
frequency: Double,
amount: Double,
history: Double
): String {
val level = when (total) {
in 90..100 -> "🟢 AAA (우수)"
in 80..89 -> "🟡 AA (좋음)"
in 70..79 -> "🟠 A (보통)"
in 60..69 -> "🔴 BBB (낮음)"
else -> "⚫ BB (고위험)"
}
val risk = when (total) {
in 90..100 -> "매우 낮음"
in 80..89 -> "낮음"
in 70..79 -> "중간"
in 60..69 -> "높음"
else -> "매우 높음"
}
val limit = when (total) {
in 90..100 -> 1000
in 80..89 -> 500
in 70..79 -> 200
in 60..69 -> 50
else -> 10
}
return buildString {
appendLine("╔══════════════════════════════════════╗")
appendLine("║ 🛡️ 고객 신용 평가 리포트 ║")
appendLine("╚══════════════════════════════════════╝\n")
appendLine("📈 입력 지표")
appendLine("──────────────────────────────────────")
appendLine("지급 준수율: ${"%.2f".format(timeliness)}%")
appendLine("부도율: ${"%.2f".format(defaultRate)}%")
appendLine("거래 빈도: ${"%.2f".format(frequency)}회/월")
appendLine("평균 거래액: ${"%.2f".format(amount)}만원")
appendLine("신용 경력: ${"%.2f".format(history)}년\n")
appendLine("⭐ 세부 점수")
appendLine("──────────────────────────────────────")
appendLine("지급 점수: ${scores["timeliness"]}점")
appendLine("부도 점수: ${scores["default"]}점")
appendLine("빈도 점수: ${scores["frequency"]}점")
appendLine("금액 점수: ${scores["amount"]}점")
appendLine("이력 점수: ${scores["history"]}점\n")
appendLine("🎯 종합 결과")
appendLine("──────────────────────────────────────")
appendLine("종합 점수: $total/100")
appendLine("신용 등급: $level")
appendLine("리스크 수준: $risk")
appendLine("권장 한도: ¥${limit}만원\n")
appendLine("💡 개선 방향")
appendLine("──────────────────────────────────────")
if (timeliness < 85) appendLine("⚠️ 지급 준수율 향상 필요")
if (defaultRate > 5) appendLine("🔴 부도율 관리 강화 요망")
if (frequency < 5) appendLine("📊 거래 활성화 필요")
if (amount < 20) appendLine("💰 거래 규모 확대 권장")
if (history < 2) appendLine("📅 신용 기록 축적 필요")
appendLine("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
appendLine("✅ 분석 완료 | ${System.currentTimeMillis()}")
}
}
ArkTS UI 통합 예제
OpenHarmony 앱에서는 아래와 같이 JavaScript 함수를 호출합니다:
import { evaluateCustomerRisk } from './riskEngine'
@Entry
@Component
struct CreditAssessmentView {
@State inputs: RiskInput = new RiskInput()
@State result: string = ''
@State loading: boolean = false
private submitAnalysis(): void {
this.loading = true
const inputStr = `${this.inputs.timeliness} ${this.inputs.defaultRate}
${this.inputs.frequency} ${this.inputs.amount} ${this.inputs.history}`
setTimeout(() => {
try {
this.result = evaluateCustomerRisk(inputStr)
} catch (e) {
this.result = `오류 발생: ${e}`
} finally {
this.loading = false
}
}, 300)
}
build() {
Column() {
// 입력 폼 및 결과 출력 UI 구성
this.renderForm()
this.renderResult()
}
}
@Builder
private renderForm() {
// 폼 요소들...
}
@Builder
private renderResult() {
// 결과 표시 영역...
}
}
배포 및 활용 시나리오
본 시스템은 다음 환경에서 효과적으로 운영될 수 있습니다:
- 금융기관의 자동 신용 심사 시스템
- 전자상거래 플랫폼의 리스크 관리 대시보드
- 공급망 관리(Supply Chain Management) 시스템 내 고객 평가 모듈
- 기업 내부 ERP 시스템과 연동된 자동 한도 산정 엔진
미래 발전 방향
향후 머신러닝 기반 예측 모델 도입, 실시간 트랜잭션 모니터링, 외부 신용정보 연동 등을 통해 더욱 정교한 평가 체계로 진화할 수 있습니다. 또한 KMP의 멀티플랫폼 특성을 최대한 활용해 iOS, Android, 웹, 데스크톱 간 동일한 알고리즘을 공유하는 통합 리스크 플랫폼으로 확장 가능합니다.