"""
텍스트 분석 모듈
규제 텍스트를 구조화된 JSON으로 변환합니다.
"""
from typing import Dict, List
from ..utils.extractors import (
extract_regulation_id,
extract_requirements,
extract_keywords,
recommend_aws_services,
assess_difficulty,
estimate_implementation_days
)
def analyze_regulation_text(regulation_text: str) -> Dict:
"""
규제 텍스트를 분석하여 구조화된 JSON으로 변환합니다.
Args:
regulation_text: 분석할 규제 텍스트 원문
Returns:
dict: {
"regulation_id": str, # 예: "ISMS-P 2.8.1"
"title": str, # 규제 제목
"summary": str, # 한 줄 요약 (100자 이내)
"requirements": list[str], # 세부 요구사항 리스트
"technical_keywords": list[str], # 기술 키워드
"aws_services": list[str], # 추천 AWS 서비스
"difficulty": str, # "쉬움" | "보통" | "어려움"
"estimated_days": int # 예상 구현 일수
}
"""
# 빈 텍스트 처리
if not regulation_text or not regulation_text.strip():
return {
"regulation_id": "Unknown",
"title": "제목 없음",
"summary": "내용 없음",
"requirements": [],
"technical_keywords": ["일반"],
"aws_services": ["AWS Config"],
"difficulty": "보통",
"estimated_days": 5
}
# 1. 규제 ID 추출
regulation_id = extract_regulation_id(regulation_text)
# 2. 제목 추출 (첫 번째 비어있지 않은 줄)
lines = [line.strip() for line in regulation_text.split('\n') if line.strip()]
# 페이지 마커 제거 후 첫 줄을 제목으로
title_candidates = [
line for line in lines
if not line.startswith('[페이지') and not line.startswith('페이지')
]
title = title_candidates[0] if title_candidates else "제목 없음"
# 제목이 너무 길면 자르기
if len(title) > 100:
title = title[:97] + "..."
# 3. 요약 생성 (두 번째 의미 있는 문단, 최대 100자)
summary_text = ""
for line in title_candidates[1:]:
# 의미 있는 길이의 문장 찾기
if len(line) > 20 and not line.startswith('-') and not line.startswith('•'):
summary_text = line[:100] + "..." if len(line) > 100 else line
break
if not summary_text:
summary_text = "요약 정보를 추출할 수 없습니다."
# 4. 요구사항 추출
requirements = extract_requirements(regulation_text)
# 5. 기술 키워드 추출
keywords = extract_keywords(regulation_text)
# 6. AWS 서비스 추천
aws_services = recommend_aws_services(keywords)
# 7. 난이도 평가
difficulty = assess_difficulty(regulation_text)
# 8. 구현 일수 추정
estimated_days = estimate_implementation_days(difficulty)
return {
"regulation_id": regulation_id,
"title": title,
"summary": summary_text,
"requirements": requirements,
"technical_keywords": keywords,
"aws_services": aws_services,
"difficulty": difficulty,
"estimated_days": estimated_days
}
def compare_regulations(regulation_analyses: List[Dict]) -> Dict:
"""
여러 규제 분석 결과를 비교합니다.
Args:
regulation_analyses: analyze_regulation_text 결과 리스트
Returns:
dict: {
"regulations_compared": list[str],
"common_keywords": list[str],
"common_aws_services": list[str],
"all_requirements": dict,
"total_estimated_days": int,
"recommended_approach": str
}
"""
if not regulation_analyses:
return {
"error": "비교할 규제가 없습니다."
}
if len(regulation_analyses) == 1:
return {
"error": "비교를 위해 2개 이상의 규제가 필요합니다.",
"single_regulation": regulation_analyses[0]
}
# 규제 ID 목록
regulation_ids = [r.get("regulation_id", "Unknown") for r in regulation_analyses]
# 공통 키워드 찾기
all_keywords = [set(r.get("technical_keywords", [])) for r in regulation_analyses]
common_keywords = list(set.intersection(*all_keywords)) if all_keywords else []
# 모든 키워드 통합
union_keywords = list(set.union(*all_keywords)) if all_keywords else []
# 공통 AWS 서비스 찾기
all_services = [set(r.get("aws_services", [])) for r in regulation_analyses]
common_services = list(set.intersection(*all_services)) if all_services else []
# 모든 AWS 서비스 통합
union_services = list(set.union(*all_services)) if all_services else []
# 요구사항 통합
all_requirements = {
r.get("regulation_id", f"규제_{i}"): r.get("requirements", [])
for i, r in enumerate(regulation_analyses)
}
# 총 예상 일수 (병렬 작업 가정 시 최대값, 순차 작업 시 합계)
estimated_days_list = [r.get("estimated_days", 5) for r in regulation_analyses]
max_days = max(estimated_days_list)
total_days = sum(estimated_days_list)
# 추천 접근 방식 생성
approach_parts = []
if common_services:
approach_parts.append(f"공통 AWS 서비스({', '.join(common_services[:3])})를 우선 구현하세요.")
if len(union_services) > len(common_services):
unique_count = len(union_services) - len(common_services)
approach_parts.append(f"추가로 {unique_count}개의 서비스 구현이 필요합니다.")
approach_parts.append(f"병렬 작업 시 최소 {max_days}일, 순차 작업 시 {total_days}일이 예상됩니다.")
recommended_approach = " ".join(approach_parts) if approach_parts else "각 규제를 순차적으로 구현하세요."
return {
"regulations_compared": regulation_ids,
"common_keywords": common_keywords,
"all_keywords": union_keywords,
"common_aws_services": common_services,
"all_aws_services": union_services,
"all_requirements": all_requirements,
"estimated_days_parallel": max_days,
"estimated_days_sequential": total_days,
"recommended_approach": recommended_approach
}