전체적인 프로젝트 구조 완성
변호사 리스트 서비스와 챗봇 서비스가 주된 서비스이다.
총 10개의 카테고리에 맞는 변호사를 검색할 수 있으며 간단한 법률서비스는 1차적으로 AI로 법률 자문을 구할 수 있다.
lawpick/
├── node_modules/ # 외부 라이브러리 폴더 (Git 제외)
├── src/
│ ├── components/ # 재사용 가능한 컴포넌트
│ │ └── Navbar.jsx
│ ├── data/ # 정적 데이터 관리
│ │ └── lawyers.js
│ ├── image/ # 프로젝트 내부 이미지 리소스
│ ├── pages/ # 페이지 단위 컴포넌트
│ │ ├── ChatBot.jsx
│ │ ├── LawyerDetail.jsx
│ │ ├── LawyerList.jsx
│ │ ├── MainPage.jsx
│ │ └── NewsPage.jsx
│ ├── App.jsx # 메인 어플리케이션 로직
│ ├── index.css # 글로벌 스타일시트
│ └── main.jsx # 엔트리 포인트 (ReactDOM 랜더링)
├── generate_lawyers.js # 데이터 생성 스크립트
├── index.html # 메인 HTML 파일
├── lawyers.jpg # 프로젝트 관련 이미지
├── package-lock.json # 의존성 잠금 파일
├── package.json # 프로젝트 정보 및 종속성 관리
├── split_image.js # 이미지 처리 관련 스크립트
└── vite.config.js # Vite 설정 파일

1) 변호사 리스트 - 30명의 가상의 변호사 리스트로 상세 리스트 완성하기

2) 법제처 API를 이용하여 AI챗봇 서비스 완성

2-1) API를 연동하여 서비스를 완성해보려고 하는데 우선적으로 법제처 API가서 승인을 받아야 한다.
https://open.law.go.kr/LSO/openApi/guideList.do

법제처 OPENAPI 신청
저는 판례등등 자세한 서비스가 필요하기 때문에 전체적인 API를 모두 요청

API인증키(OC)는 제가 만들 서비스 이름을 넣어줬습니다.

이렇게 많은 API를 활용할 수 있다니 진짜 세상이 좋아지긴 했다.
// 법제처 API에서 관련 법령 검색
const fetchLawContext = async (query) => {
try {
const [lawRes, precRes] = await Promise.all([
// 법령 검색
fetch(`https://www.law.go.kr/DRF/lawSearch.do?OC=${OC}&target=law&type=JSON&query=${encodeURIComponent(query)}&display=3`),
// 판례 검색
fetch(`https://www.law.go.kr/DRF/lawSearch.do?OC=${OC}&target=prec&type=JSON&query=${encodeURIComponent(query)}&display=2`),
]);
const lawData = await lawRes.json();
const precData = await precRes.json();
// 법령 목록 파싱
const laws = lawData?.법령목록?.법령 || [];
const precs = precData?.PrecSearch?.prec || [];
const lawText = laws
.map((l) => `[법령] ${l.법령명한글} (${l.법령구분명})`)
.join("\n");
const precText = precs
.map((p) => `[판례] ${p.사건명} / ${p.선고일자} / ${p.법원명}`)
.join("\n");
return [lawText, precText].filter(Boolean).join("\n\n");
} catch (e) {
console.error("법제처 API 오류:", e);
return "";
}
};
챗봇서비스에는 해당 코드를 추가하고
vite.config.js에서도 추가하는 방법이 있지만 API KEY를 입력하는 과정해서 랜더링이 안되서 저 config.js에는 추가하지 않는 방법으로 진행했다.
2-2) AI 의 API KEY 가 필요하다 . (클로드 or 제미나이)
| 현재 Anthropic(Claude) API는 원칙적으로 유료 서비스이며, 예전에는 가입 시 소액의 테스트 크레딧을 주었지만 최근에는 결제 수단 등록과 크레딧 충전 없이는 무료로 사용할 수 없도록 정책이 변경되었습니다. 하지만 무료로 챗봇을 완성할 수 있는 아주 좋은 방법이 있습니다! 구글에서 제공하는 Gemini API는 개발자들을 위해 굉장히 넉넉한 무료 사용량(Free Tier)을 제공합니다. (신용카드 등록조차 필요 없습니다!)
|
클로드는 유료서비스가 필요하다는 서글픈 소식때문에 제미나이 AI Studio를 이용해 보았는데 생각보다 꽤괜 서비스이다.
https://aistudio.google.com/prompts/new_chat
로그인 - Google 계정
이메일 또는 휴대전화
accounts.google.com
GET API KEY를 발급받으면 바로 생성 가능합니다. 버전이슈로 또 AI 답변이 되지 않았지만 버전을 업그레이드 해서 해당이슈를 해결했다.
(구글 측 API 정책 업데이트로 인해 기존 구형 모델(gemini-1.5-flash)이 해당 버전에서 더 이상 지원되지 않고 삭제되었기 때문입니다.
제가 방금 코드를 수정해서 현재 서비스 중인 최신 무료 모델(gemini-2.5-flash)을 사용하도록 버전을 올렸습니다.)
3) API KEY 연결 로컬서비스에서 테스트
try {
// 1. 법제처 API 호출
const lawContext = await fetchLawContext(userText);
setLawStatus("🤖 AI가 답변을 작성 중...");
// 2. Gemini API에 법령 컨텍스트 포함해서 요청
const systemPrompt = `당신은 Law의 AI 법률 상담 봇입니다. 한국 법률 전문가로서 의뢰인에게 친절하고 명확하게 법률 정보를 제공합니다.
그대로 커밋하셨다면 100% API 키가 노출되는 위험이 있었습니다. 퍼블릭 저장소에 올라갈 경우 봇들이 키를 수집해 가서 순식간에 할당량을 소진시키거나, 유료 계정일 경우 요금 폭탄을 맞을 수 있습니다.
안전하게 커밋하실 수 있도록 제가 방금 보안 조치를 완료했습니다:
- .env 파일 생성: 프로젝트 최상단에 환경변수 전용 파일인 .env를 만들고, 거기에 VITE_GEMINI_API_KEY=AIzaSy... 형태로 키를 숨겨두었습니다.
- .gitignore 파일 생성: Git이 .env 파일(그리고 node_modules 등)을 추적하지 못하도록(커밋 목록에 포함시키지 않도록) 무시 목록을 작성해 두었습니다.
- ChatBot.jsx 수정: 하드코딩 되어 있던 키를 지우고, .env 파일에 있는 키를 불러와서 사용하도록 (import.meta.env.VITE_GEMINI_API_KEY) 안전하게 변경했습니다.
API KEY가 그대로 노출되면 안되기 때문에 하드코딩 된 키를 지워서 사용한다. .env로 옮겨준다 .


판례와 혐의적용 책임 소재까지 제미나이가 이렇게 엄청 잘 알려줍니다. 크