v0.47.0
CSO(위탁영업) 업체가 제약사 정산 수수료를 조회하는 B2B 포털
제약사가 CSO(위탁영업) 업체에 지급하는 정산 수수료를 관리하는 포털입니다.
왜 만들었는가:
- 제약사 정산 데이터(SIT솔루션 Compare&Chart 다운로드 엑셀)를 수작업으로 각 CSO 업체에 개별 전달하는 비효율을 없애기 위해
- CSO 업체가 직접 로그인해서 자사 정산 데이터만 조회·다운로드할 수 있도록
- 업체명 ↔ 사업자번호 매칭을 체계적으로 관리하여 정산 누락을 방지하기 위해
핵심 메커니즘:
| 개념 | 설명 |
|---|---|
| 사업자등록번호 식별 | B2B이므로 이메일이 아닌 사업자번호가 사용자를 구분하는 핵심 키 |
| CSO 매칭 | 엑셀 속 텍스트 업체명 ↔ 회원 사업자번호를 연결하는 매핑 테이블 |
| 한글 컬럼명 | 제약업계 엑셀 양식 그대로 반영 (47개 컬럼) |
사용자 역할:
| 역할 | 할 수 있는 일 |
|---|---|
| 관리자 | SIT솔루션 Compare&Chart 엑셀 업로드, 회원 승인/관리, CSO 매칭 설정, 메일 발송 |
| 일반 회원 | 자사 사업자번호에 해당하는 정산 데이터 조회/다운로드 |
(맨 위로)
| 기술 | 역할 |
|---|---|
| App Router 기반 풀스택 프레임워크 (v14) | |
| 타입 안전성 (strict 모드) | |
| PostgreSQL + REST API (인증은 자체 JWT) | |
| 유틸리티 기반 스타일링 | |
| 프로덕션 자동 배포 (GitHub → main push) |
주요 라이브러리: Radix UI (컴포넌트), exceljs/xlsx (엑셀 파싱), jose (JWT), bcryptjs (해싱), resend (시스템 이메일), nodemailer (SMTP 워커), react-dropzone (업로드)
테스트: Vitest (유닛/통합/컴포넌트), Playwright (E2E), Testing Library (React 컴포넌트)
(맨 위로)
로컬 환경에서 프로젝트를 실행하는 방법입니다. 상세한 가이드는 ONBOARDING을 참고하세요.
- Node.js 18+
- npm
- Git
- Supabase 프로젝트 접근 권한 (기존 팀원에게 대시보드 초대 필요)
-
저장소 클론
git clone https://github.com/<org>/csoweb.git cd csoweb
-
의존성 설치
npm install
-
환경변수 설정
cp .env.local.example .env.local
.env.local을 열어 Supabase URL, 키, JWT 시크릿 등 8개 변수를 채웁니다. 각 변수의 설명과 획득 경로는 ONBOARDING을 참고하세요. -
개발 서버 실행
npm run dev
http://localhost:3000에서 로그인 화면이 나타나면 성공입니다. -
SMTP 메일머지 워커 실행 (선택 — SMTP 메일머지 사용 시)
cd worker && npm install && cd .. pm2 start ecosystem.config.cjs # 워커 시작 pm2 status # 상태 확인 pm2 logs csoweb-email-worker # 로그 확인
-
테스트 계정 설정
회원가입 후 Supabase 대시보드에서
is_approved = true로 변경하거나, 기존 테스트 계정을 사용합니다. 첫 로그인 시 비밀번호 변경이 강제됩니다.
(맨 위로)
SIT솔루션 Compare&Chart 엑셀 업로드 → 미리보기 확인 → DB 저장 확정
→ CSO 매칭 관리 (업체명 ↔ 사업자번호)
→ 회원 승인/관리
→ 정산 안내 메일 발송 (메일머지)
로그인 → 정산 데이터 조회 (월별 필터)
→ 엑셀 다운로드
→ 월별 합계 확인
자세한 API 엔드포인트는 API-DATABASE를, 코드 구조는 ARCHITECTURE를 참고하세요.
(맨 위로)
npm test # 전체 유닛+통합+컴포넌트 (184개 케이스)
npm run test:watch # 워치 모드
npm run test:unit # 유닛만 (lib/, application/)
npm run test:integration # API 통합만 (app/api/)
npm run test:component # 컴포넌트만 (.test.tsx)
npm run test:coverage # 커버리지 리포트 (v8)
npm run test:ui # Vitest UI (브라우저)
npm run test:e2e # Playwright E2E (dev server 자동 실행)
npm run test:e2e:headed # Playwright headed 모드| 카테고리 | 파일 수 | 케이스 수 | 대상 |
|---|---|---|---|
| Unit | 4 | 58 | lib/auth, lib/utils, lib/excel, lib/dashboard-utils |
| Application Use Case | 9 | 51 | application/user/*, application/settlement/*, application/cso-matching/*, application/auth/* |
| API 통합 | 13 | 63 | api/auth/*, api/users/*, api/settlements/*, api/columns |
| 컴포넌트 | 2 | 12 | AuthContext, Header |
| 합계 | 28 | 184 |
(맨 위로)
-
회원가입 / 로그인 / 비밀번호 관리
-
관리자 회원 승인/거부 흐름
-
SIT솔루션 Compare&Chart 엑셀 업로드 (미리보기 + 확정)
-
CSO 매칭 (업체명 ↔ 사업자번호)
-
정산 데이터 조회 / 엑셀 다운로드
-
월별 합계 및 통계
-
메일머지 (정산 안내 일괄 발송)
-
컬럼 표시 설정 (가시성, 순서)
-
CSO 매칭 무결성 검사
-
회원가입 사업자번호 국세청 실시간 인증 (계속사업자만 가입 허용)
-
이메일 듀얼 프로바이더 (Resend + SMTP 하이웍스)
-
메일머지 SSE 실시간 진행률 + 수신자 수 표시
-
대시보드 시스템 정보 강화 (SMTP/NTS 상태, 버전 동기화)
-
정산서 Notice 편집을 마스터조회 페이지로 이동 (사용 맥락에서 인라인 편집)
-
이메일 알림 유형별 ON/OFF 토글 (설정에서 5가지 유형별 발송 제어)
-
DDD 레이어 전환 완료 (
lib/db.ts호환 레이어 제거) -
테스트 인프라 구축 (Vitest + Playwright, 108개 케이스)
-
코드 품질 전면 리뷰 (v0.18.0) — XSS 방어, 빈 catch 해소, SRP 분리, 스켈레톤/Error Boundary, SEO, next/image
-
CSO 필터링
-
실시간 상담 시스템 (채널톡 유사, Supabase Realtime 기반)
Phase 1: 기본 채팅 인프라
- DB 설계: chat_rooms, chat_messages, chat_read_status, chat_tags, chat_templates 테이블 + RLS 정책
- Supabase Realtime 구독 설정 (Postgres Changes)
- 기존 자체 JWT 인증 연동
- DDD 레이어 구조 준수
Phase 2: CSO 업체(일반회원) 측 위젯
- 우하단 플로팅 채팅 버튼 (읽지 않은 메시지 수 배지)
- 채팅 위젯 UI (열기/닫기/최소화)
- 실시간 메시지 전송/수신
- 이전 대화 내역 무한 스크롤
- 메시지 읽음 표시
- 타이핑 인디케이터 (상대방 입력 중... 표시, Supabase Realtime Presence)
- 파일/이미지 첨부 (정산서 관련 문서 공유)
- 새 메시지 브라우저 알림 (Notification API)
- 로그인 상태에서만 표시, 관리자는 숨김
Phase 3: 관리자 상담 데스크 (/admin/chat)
- 좌측: 대화방 목록 (최신순, 읽지 않은 건 강조, 업체명/사업자번호 표시)
- 중앙: 채팅창 (선택한 대화방)
- 우측: 고객 정보 사이드바 (업체명, 사업자번호, 가입일, 최근 정산월, 상담 이력)
- 상담 상태 관리 (대기중/진행중/완료)
- 상담 이관 (다른 관리자에게 대화방 전달 + 이관 사유 기록)
- 상담 태그 시스템 (정산문의/매칭오류/계정문의/기타)
- 대화방 검색/필터 (업체명, 사업자번호, 태그, 상태)
- 대화방별 내부 메모 (고객에게 안 보이는 관리자 메모)
- 매크로/빠른 답변 템플릿 (자주 쓰는 답변 저장 후 클릭으로 전송)
Phase 4: 공지/안내 기능
- 전체 업체 공지 일괄 발송
- 선택 업체 그룹 발송
- 공지 메시지 구분 표시 (일반 메시지와 시각적 차별)
- 정산 엑셀 업로드 완료 시 해당 업체에 자동 알림
- 회원 승인/거부 시 자동 알림
Phase 5: FAQ & 자동 응답 (단계적 도입)
- Phase 5-1: FAQ 관리 (무료, API 불필요)
- FAQ 관리 페이지 (/admin/faq) — 질문/답변 등록, 카테고리 분류
- 채팅 시작 시 FAQ 자주 묻는 질문 버튼 노출 (클릭 → 자동 답변)
- 키워드 매칭 자동 응답 (DB 문자열 비교, API 비용 없음)
- 쌓인 질문 데이터 분석 → 반복 질문 파악 → FAQ 지속 보강
- Phase 5-2: AI 자동 응답 (Claude/OpenAI API + RAG, 별도 LLM 구축 불필요)
- FAQ + 정산 도움말을 지식 베이스로 활용
- FAQ로 해결 안 된 문의만 API 호출 (비용 최소화)
- 쌓인 chat_messages 질문 데이터를 AI 지식으로 활용
- AI 확신도 낮으면 관리자에게 자동 에스컬레이션
- AI 답변 전 "AI가 답변합니다" 안내 표시
Phase 6: 상담 자동화 워크플로우
- 자동 태그 부여 (메시지 키워드 기반)
- 상담 자동 배정 (태그별 담당자 매핑)
- 영업시간 외 자동 응답 ("영업시간 안내 + FAQ 안내")
- 미응답 알림 (일정 시간 초과 시 관리자에게 알림)
- 상담 종료 후 만족도 조사 (별점/한줄평)
Phase 7: 상담 분석 대시보드
- 일별/주별/월별 문의 건수 추이
- 평균 응답 시간, 평균 해결 시간
- 태그별 문의 분포 (정산문의/매칭오류/계정문의 등)
- FAQ 자동 처리율 → AI 자동 처리율 (단계별 추적)
- 만족도 통계
- 미응답/미해결 건수 현황
- 상담원별 처리 건수/응답 시간 통계
- 자주 묻는 질문 TOP 10 (chat_messages 기반 자동 집계)
-
SIT솔루션 API 연동 (엑셀 수동 업로드 → API 자동 통신 전환)
(맨 위로)
프로젝트에 기여하는 방법입니다.
- 저장소 Fork
- Feature 브랜치 생성 (
git checkout -b feature/amazing-feature) - 변경사항 커밋 (
git commit -m 'feat: 기능 설명') - 브랜치에 Push (
git push origin feature/amazing-feature) - Pull Request 생성
코드 작성 시 DDD 레이어 구조를 따라주세요. 자세한 내용은 ARCHITECTURE를 참고하세요.
(맨 위로)
비공개 프로젝트입니다. 무단 배포를 금지합니다.
(맨 위로)
영업관리팀 권대환 — qwer@ukp.co.kr
(맨 위로)
- Next.js Documentation
- Supabase Documentation
- Tailwind CSS Documentation
- Radix UI
- Resend Email API
- Best-README-Template
(맨 위로)