17-verification-patterns
엔티티 신뢰도 검증 패턴 라이브러리.
Trust Score(가중치 기반 0~100 신뢰도 점수) 산출 + URL 안전성 검증(URLhaus + VirusTotal)을 통합하여
사업자, 서비스, 게시물 등 다양한 엔티티의 신뢰도를 종합 판정합니다.
파일 인덱스
| 파일 | 설명 |
|---|
types.ts | 공통 타입 정의 (TrustSignals, VerificationInput, VerificationResult 등) |
trust-score.ts | 가중치 기반 Trust Score 계산 엔진 |
url-verification.ts | URLhaus + VirusTotal 기반 URL 안전성 검증 |
index.ts | 통합 검증 오케스트레이터 + re-exports |
아키텍처
VerificationInput
│
▼
verifyEntity() ← 오케스트레이터 (index.ts)
│
├── verifyBusiness() ← 외부 주입 (config.verifyBusiness)
├── verifyUrl() ← URLhaus + VirusTotal (url-verification.ts)
├── checkKnownEntity() ← 외부 주입 (config.checkKnownEntity)
│
▼
TrustSignals 조합
│
▼
calculateTrustScore() ← 가중치 엔진 (trust-score.ts)
│
▼
VerificationResult
{ trustScore, verificationStatus, signals, ... }
사용법
기본 사용 (URL 검증만)
import { verifyEntity } from './17-verification-patterns';
const result = await verifyEntity({
entityName: '테스트 서비스',
sourceUrl: 'https://example.com',
deadline: '2026-12-31',
amount: 5_000_000,
});
console.log(result.trustScore); // 0~100
console.log(result.verificationStatus); // 'verified' | 'flagged' | 'blocked'
사업자 검증 + 기존 엔티티 확인 포함
import { verifyEntity } from './17-verification-patterns';
import type { VerificationConfig } from './17-verification-patterns';
const config: VerificationConfig = {
// 사업자 검증 함수 주입 (국세청 API, 자체 API 등)
verifyBusiness: async (bizNum) => {
const res = await fetch(`/api/verify-business?num=${bizNum}`);
return res.json();
},
// 기존 엔티티 확인 함수 주입
checkKnownEntity: async (entityId) => {
const res = await fetch(`/api/entities/${entityId}`);
return res.ok;
},
};
const result = await verifyEntity(
{
entityName: 'ABC 컴퍼니',
businessNumber: '123-45-67890',
sourceUrl: 'https://abc-company.com',
entityId: 'org_123',
amount: 10_000_000,
deadline: '2026-06-30',
},
config
);
Trust Score만 단독 사용
import { calculateTrustScore } from './17-verification-patterns';
import type { TrustSignals } from './17-verification-patterns';
const signals: TrustSignals = {
businessVerified: true,
businessChecked: true,
urlSafe: true,
urlChecked: true,
knownEntity: false,
hasDeadline: true,
reasonableAmount: true,
hasContactInfo: true,
reportCount: 0,
};
// 기본 가중치
const score = calculateTrustScore(signals);
// 커스텀 가중치
const customScore = calculateTrustScore(signals, {
weights: {
businessVerified: 40,
urlSafe: 25,
knownEntity: 10,
noReports: 15,
},
reportPenaltyPerCount: 5,
});
URL 검증만 단독 사용
import { verifyUrl } from './17-verification-patterns';
const result = await verifyUrl('https://suspicious-site.com');
if (!result.safe) {
console.log('위험 URL 감지');
console.log(`블랙리스트: ${result.blacklisted}`);
console.log(`악성 엔진: ${result.maliciousCount}/${result.totalEngines}`);
}
설정 옵션
Trust Score 가중치 (기본값, 총합 100)
| 시그널 | 가중치 | 설명 |
|---|
businessVerified | 30 | 사업자 검증 통과 |
urlSafe | 20 | URL 안전성 확인 |
knownEntity | 15 | 기존 DB 등록 엔티티 |
reasonableAmount | 10 | 금액 범위 합리성 |
hasContactInfo | 10 | 연락처/웹사이트 존재 |
noReports | 10 | 신고 0건 |
hasDeadline | 5 | 마감일 명시 |
검증 상태 임계값 (기본값)
| 상태 | 조건 |
|---|
verified | trustScore >= 70 |
flagged | 30 <= trustScore < 70 |
blocked | trustScore < 30 |
특수 규칙 (강제 상태 변경)
- 사업자 폐업 -> 강제
blocked
- 사업자 휴업 -> 강제
flagged
- URL 블랙리스트 매칭 -> 강제
blocked
검증 미실행 시그널 처리
- 사업자번호 미제공:
businessVerified 가중치의 50% 부여
- URL 미제공:
urlSafe 가중치의 50% 부여
환경변수
| 변수 | 필수 | 설명 |
|---|
VIRUSTOTAL_API_KEY | 선택 | VirusTotal API 키. 없으면 URLhaus만 사용 |
의존성
- fetch API - Node.js 18+ 내장 (별도 설치 불필요)
- 사업자 검증 함수는 외부 주입 방식이므로 특정 API에 의존하지 않음
출처
| 날짜 | 출처 | 비고 |
|---|
| 2026-03-08 | galaxy-con | 공모전 검증 시스템에서 범용화하여 추출 |