phonebill/design/backend/database/bill-inquiry.md
2025-09-09 01:12:14 +09:00

224 lines
9.1 KiB
Markdown

# Bill-Inquiry 서비스 데이터 설계서
## 1. 개요
### 1.1 설계 목적
Bill-Inquiry 서비스의 요금 조회 기능을 위한 독립적인 데이터베이스 설계
### 1.2 설계 원칙
- **서비스 독립성**: Bill-Inquiry 서비스 전용 데이터베이스 구성
- **데이터 격리**: 타 서비스와 데이터 공유 금지, 캐시를 통한 성능 최적화
- **외래키 제한**: 서비스 내부에서만 FK 관계 설정
- **이력 관리**: 모든 요청/처리 이력의 완전한 추적
### 1.3 주요 기능
- UFR-BILL-010: 요금조회 메뉴 접근
- UFR-BILL-020: 요금조회 신청
- UFR-BILL-030: KOS 요금조회 서비스 연동
- UFR-BILL-040: 요금조회 결과 전송
## 2. 데이터베이스 구성
### 2.1 데이터베이스 정보
- **데이터베이스명**: bill_inquiry_db
- **DBMS**: PostgreSQL 14
- **문자셋**: UTF8
- **타임존**: Asia/Seoul
### 2.2 스키마 구성
- **public**: 기본 스키마 (비즈니스 테이블)
- **cache**: 캐시 데이터 스키마 (Redis 보조용)
- **audit**: 감사 및 이력 스키마
## 3. 테이블 설계
### 3.1 고객정보 테이블 (customer_info)
**목적**: 캐시에서 가져온 고객 기본 정보 임시 저장
| 컬럼명 | 타입 | 제약조건 | 설명 |
|--------|------|----------|------|
| customer_id | VARCHAR(50) | PRIMARY KEY | 고객 식별자 |
| line_number | VARCHAR(20) | NOT NULL | 회선번호 |
| customer_name | VARCHAR(100) | | 고객명 |
| status | VARCHAR(10) | NOT NULL DEFAULT 'ACTIVE' | 고객상태 (ACTIVE, INACTIVE) |
| operator_code | VARCHAR(10) | NOT NULL | 사업자 코드 |
| cached_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 캐시 저장 시각 |
| expires_at | TIMESTAMP | NOT NULL | 캐시 만료 시각 |
| created_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 생성일시 |
| updated_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 수정일시 |
### 3.2 요금조회 요청 이력 테이블 (bill_inquiry_history)
**목적**: MVNO에서 MP로의 요금조회 요청 이력 관리
| 컬럼명 | 타입 | 제약조건 | 설명 |
|--------|------|----------|------|
| id | BIGSERIAL | PRIMARY KEY | 이력 ID |
| request_id | VARCHAR(50) | NOT NULL UNIQUE | 요청 식별자 |
| user_id | VARCHAR(50) | NOT NULL | 요청 사용자 ID |
| line_number | VARCHAR(20) | NOT NULL | 회선번호 |
| inquiry_month | VARCHAR(7) | | 조회월 (YYYY-MM, null이면 당월) |
| request_time | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 요청일시 |
| process_time | TIMESTAMP | | 처리완료일시 |
| status | VARCHAR(20) | NOT NULL DEFAULT 'PROCESSING' | 처리상태 |
| result_summary | TEXT | | 결과 요약 |
| bill_info_json | JSONB | | 요금정보 JSON |
| error_message | TEXT | | 오류 메시지 |
| created_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 생성일시 |
| updated_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 수정일시 |
**인덱스**:
- `idx_bill_history_user_line`: (user_id, line_number)
- `idx_bill_history_request_time`: (request_time DESC)
- `idx_bill_history_status`: (status)
- `idx_bill_history_inquiry_month`: (inquiry_month)
**상태값 (status)**:
- `PROCESSING`: 처리중
- `COMPLETED`: 완료
- `FAILED`: 실패
- `TIMEOUT`: 타임아웃
### 3.3 KOS 연동 이력 테이블 (kos_inquiry_history)
**목적**: MP에서 KOS로의 요금조회 연동 이력 관리
| 컬럼명 | 타입 | 제약조건 | 설명 |
|--------|------|----------|------|
| id | BIGSERIAL | PRIMARY KEY | 이력 ID |
| bill_request_id | VARCHAR(50) | | 요금조회 요청 ID (FK) |
| line_number | VARCHAR(20) | NOT NULL | 회선번호 |
| inquiry_month | VARCHAR(7) | | 조회월 |
| request_time | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | KOS 요청일시 |
| response_time | TIMESTAMP | | KOS 응답일시 |
| result_code | VARCHAR(10) | | KOS 응답코드 |
| result_message | TEXT | | KOS 응답메시지 |
| kos_data_json | JSONB | | KOS 응답 데이터 JSON |
| error_detail | TEXT | | 오류 상세 정보 |
| retry_count | INTEGER | NOT NULL DEFAULT 0 | 재시도 횟수 |
| circuit_breaker_state | VARCHAR(20) | | Circuit Breaker 상태 |
| created_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 생성일시 |
| updated_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 수정일시 |
**인덱스**:
- `idx_kos_history_line_month`: (line_number, inquiry_month)
- `idx_kos_history_request_time`: (request_time DESC)
- `idx_kos_history_result_code`: (result_code)
- `idx_kos_history_bill_request`: (bill_request_id)
### 3.4 요금정보 캐시 테이블 (bill_info_cache)
**목적**: KOS에서 조회한 요금정보의 임시 캐시 (Redis 보조용)
| 컬럼명 | 타입 | 제약조건 | 설명 |
|--------|------|----------|------|
| cache_key | VARCHAR(100) | PRIMARY KEY | 캐시 키 (line_number:inquiry_month) |
| line_number | VARCHAR(20) | NOT NULL | 회선번호 |
| inquiry_month | VARCHAR(7) | NOT NULL | 조회월 |
| bill_info_json | JSONB | NOT NULL | 요금정보 JSON |
| cached_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 캐시 저장 시각 |
| expires_at | TIMESTAMP | NOT NULL | 캐시 만료 시각 |
| access_count | INTEGER | NOT NULL DEFAULT 1 | 접근 횟수 |
| last_accessed_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 최종 접근 시각 |
**인덱스**:
- `idx_cache_line_month`: (line_number, inquiry_month)
- `idx_cache_expires`: (expires_at)
### 3.5 시스템 설정 테이블 (system_config)
**목적**: Bill-Inquiry 서비스 관련 시스템 설정 관리
| 컬럼명 | 타입 | 제약조건 | 설명 |
|--------|------|----------|------|
| config_key | VARCHAR(100) | PRIMARY KEY | 설정 키 |
| config_value | TEXT | NOT NULL | 설정 값 |
| description | VARCHAR(500) | | 설정 설명 |
| config_type | VARCHAR(20) | NOT NULL DEFAULT 'STRING' | 설정 타입 |
| is_active | BOOLEAN | NOT NULL DEFAULT true | 활성화 여부 |
| created_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 생성일시 |
| updated_at | TIMESTAMP | NOT NULL DEFAULT CURRENT_TIMESTAMP | 수정일시 |
**설정 예시**:
- `bill.cache.ttl.hours`: 요금정보 캐시 TTL (기본 4시간)
- `kos.connection.timeout.ms`: KOS 연결 타임아웃
- `kos.retry.max.attempts`: KOS 최대 재시도 횟수
- `bill.inquiry.available.months`: 조회 가능한 개월 수
## 4. 외래키 관계
### 4.1 서비스 내부 관계
- `kos_inquiry_history.bill_request_id``bill_inquiry_history.request_id`
- KOS 연동 이력과 요금조회 요청 이력 연결
- ON DELETE CASCADE로 요금조회 이력 삭제 시 KOS 이력도 삭제
### 4.2 외부 서비스와의 관계
- **Auth 서비스**: user_id는 참조만 하고 FK 관계 설정하지 않음
- **캐시 데이터**: Redis를 통한 데이터 공유, DB 직접 참조 없음
## 5. 캐시 전략
### 5.1 Redis 캐시 키 전략
- **고객정보**: `customer:info:{user_id}` (TTL: 1시간)
- **요금정보**: `bill:info:{line_number}:{inquiry_month}` (TTL: 4시간)
- **가용조회월**: `bill:available:months` (TTL: 24시간)
### 5.2 캐시 무효화 정책
- 요금조회 완료 시: 해당 회선/월 캐시 갱신
- 고객정보 변경 시: 고객정보 캐시 삭제
- 시스템 설정 변경 시: 관련 캐시 전체 삭제
## 6. 데이터 보안
### 6.1 개인정보 보호
- **암호화 컬럼**: customer_name, bill_info_json
- **접근 제어**: 사용자별 회선번호 권한 확인
- **로그 마스킹**: 개인정보 포함 로그는 마스킹 처리
### 6.2 데이터 보관 정책
- **요금조회 이력**: 2년 보관 후 아카이브
- **KOS 연동 이력**: 1년 보관 후 삭제
- **캐시 데이터**: TTL 만료 후 자동 삭제
- **오류 로그**: 6개월 보관
## 7. 성능 최적화
### 7.1 인덱스 전략
- **복합 인덱스**: 자주 함께 조회되는 컬럼들
- **부분 인덱스**: 활성 데이터만 대상으로 하는 인덱스
- **JSONB 인덱스**: 요금정보 JSON 검색용 GIN 인덱스
### 7.2 파티셔닝 전략
- **bill_inquiry_history**: 월별 파티셔닝 (request_time 기준)
- **kos_inquiry_history**: 월별 파티셔닝 (request_time 기준)
### 7.3 통계 정보 관리
- **자동 통계 수집**: 주요 테이블 자동 분석
- **쿼리 플랜 모니터링**: 성능 저하 쿼리 식별
## 8. 모니터링 및 알람
### 8.1 성능 모니터링
- 테이블별 용량 및 성장률 추적
- 슬로우 쿼리 모니터링
- 캐시 히트율 모니터링
### 8.2 비즈니스 모니터링
- 요금조회 성공률
- KOS 연동 응답시간
- Circuit Breaker 상태
## 9. 데이터 백업 및 복구
### 9.1 백업 전략
- **전체 백업**: 주 1회 (일요일 새벽)
- **증분 백업**: 일 1회 (매일 새벽)
- **트랜잭션 로그 백업**: 15분마다
### 9.2 복구 전략
- **Point-in-Time 복구**: 특정 시점 데이터 복구
- **테이블 단위 복구**: 개별 테이블 복구
- **응급 복구**: 1시간 내 서비스 복구
## 10. 관련 산출물
- **ERD 설계서**: [bill-inquiry-erd.puml](./bill-inquiry-erd.puml)
- **스키마 스크립트**: [bill-inquiry-schema.psql](./bill-inquiry-schema.psql)
- **API 설계서**: [../api/bill-inquiry-service-api.yaml](../api/bill-inquiry-service-api.yaml)
- **클래스 설계서**: [../class/bill-inquiry.puml](../class/bill-inquiry.puml)