법률 서비스를 왜 디지털화해야 하나
개인회생·파산은 복잡한 법률 절차입니다. 전문가를 찾기 어렵고, 비용도 천차만별이며, 어떤 전문가가 좋은지 판단하기도 힘듭니다. 이 불투명함을 IT로 해결하는 프로젝트를 진행했습니다.
서비스 핵심 기능 설계
전문가 매칭 시스템
단순 목록 나열이 아닙니다. 사용자의 상황에 맞는 전문가를 추천해야 합니다.
python
def calculate_match_score(case: UserCase, expert: Expert) -> float:
score = 0.0
# 전문 분야 매칭 (40점)
if case.case_type in expert.specialties:
score += 40
elif "general" in expert.specialties:
score += 20
# 지역 매칭 (30점)
if expert.region == case.region:
score += 30
elif expert.region == "전국":
score += 15
# 경험 지수 (30점)
# 처리 건수 기반, 최대 30점
score += min(expert.case_count / 10, 30)
return score
def get_recommended_experts(case: UserCase, db: Session) -> List[Expert]:
experts = db.query(Expert).filter(
Expert.is_active == True,
Expert.is_verified == True
).all()
scored = [(e, calculate_match_score(case, e)) for e in experts]
return [e for e, s in sorted(scored, key=lambda x: x[1], reverse=True)][:10]
실시간 채팅 상담
법률 상담은 민감한 개인정보를 다룹니다. 보안이 최우선입니다.
python
@router.websocket("/ws/{room_id}")
async def websocket_endpoint(
websocket: WebSocket,
room_id: int,
token: str,
db: Session = Depends(get_db)
):
# 1. JWT 토큰 검증
user = verify_websocket_token(token, db)
if not user:
await websocket.close(code=4001)
return
# 2. 채팅방 접근 권한 확인
room = db.query(ChatRoom).filter(ChatRoom.id == room_id).first()
if user.id not in [room.user_id, room.expert_id] and not user.is_admin:
await websocket.close(code=4003)
return
# 3. 연결 및 메시지 처리
await manager.connect(websocket, room_id, user)
try:
while True:
data = await websocket.receive_json()
message = save_message(db, room_id, user.id, data)
await manager.broadcast(room_id, message)
except WebSocketDisconnect:
manager.disconnect(websocket, room_id)
광고 시스템 + 토스페이먼츠
전문가들이 광고 위치를 직접 구매하는 자체 광고 시스템을 구축했습니다.
javascript
// 토스페이먼츠 결제 위젯
const tossPayments = TossPayments(TOSS_CLIENT_KEY);
const payment = tossPayments.widgets({ customerKey });
await payment.renderPaymentMethods({
selector: "#payment-widget",
variantKey: "DEFAULT"
});
// 결제 요청
await payment.requestPayment({
orderId: generateOrderId(),
orderName: `${placementName} ${months}개월`,
successUrl: `${location.origin}/ads/payment/success`,
failUrl: `${location.origin}/ads/payment/fail`,
});
어려웠던 기술적 도전
전문가 자격 검증
변호사, 법무사 자격증 진위 확인이 필요했습니다. 대한변호사협회·법무사협회 공개 정보를 크롤링해 자동 검증 로직을 구현했습니다.
채팅 메시지 암호화
법률 상담 내용은 민감 개인정보입니다. 서버 저장 시 AES-256 암호화, 전송 시 WSS(WebSocket Secure)를 적용했습니다.
지역 기반 검색
PostgreSQL의 PostGIS 확장 없이도 위도/경도 기반 가까운 전문가 검색을 구현했습니다.
python
# Haversine 공식으로 두 좌표 간 거리 계산
def haversine_distance(lat1, lon1, lat2, lon2) -> float:
R = 6371 # 지구 반지름 (km)
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon/2)**2
return R * 2 * asin(sqrt(a))
출시 후 성과
- 등록 전문가: 50명+
- 월간 상담 요청: 200건+
- 사용자 만족도: 4.7/5.0
- 전문가 재이용률: 78%
코드벤터는 법률, 교육, 물류 등 도메인 전문성이 필요한 복잡한 서비스를 디지털화하는 데 강합니다. 단순히 코드를 작성하는 것이 아니라 비즈니스 로직을 깊이 이해하고 최적의 구조로 설계합니다.