- Flask Blueprint 아키텍처로 전환 (dashboard, upload, backup, status) - app.py 681줄 95줄로 축소 (86% 감소) - HTML 템플릿 모듈화 (base.html + 기능별 templates) - CSS/JS 파일 분리 (common + 기능별 파일) - 대시보드 기능 추가 (통계, 주간 예보, 방문객 추이) - 파일 업로드 웹 인터페이스 구현 - 백업/복구 관리 UI 구현 - Docker 배포 환경 개선 - .gitignore 업데이트 (uploads, backups, cache 등)
482 lines
14 KiB
Markdown
482 lines
14 KiB
Markdown
# First Garden 방문통계 분석 서비스 (Static Analysis Service)
|
|
|
|
[](https://www.python.org/downloads/)
|
|
[](https://www.docker.com/)
|
|
[](LICENSE)
|
|
|
|
> 퍼스트가든 방문객 데이터 자동 수집, DB 저장, 시계열 예측 분석 서비스
|
|
|
|
## 🚀 주요 기능
|
|
|
|
### 1. 자동 데이터 수집
|
|
- **기상청 ASOS 데이터**: 일별 기온, 강수량, 습도 등 수집
|
|
- **Google Analytics 4**: 웹 방문자 데이터 수집 및 분석
|
|
- **대기환경 정보**: 미세먼지(PM2.5) 등 대기질 데이터 수집
|
|
|
|
### 2. 웹 기반 파일 업로드 (포트 8889)
|
|
- **드래그 앤 드롭 파일 업로드**: 직관적인 파일 선택 및 업로드
|
|
- **다중 파일 지원**: 여러 POS 데이터 파일 일괄 처리
|
|
- **파일 형식 지원**:
|
|
- **OKPOS**: 일자별 상품별, 영수증별매출상세현황 파일
|
|
- **UPSOLUTION**: POS 데이터 파일
|
|
- **실시간 상태 모니터링**: 업로드, 검증, DB 저장 진행 상황 확인
|
|
- **데이터베이스 백업/복구**: 웹 인터페이스에서 간편한 백업 관리
|
|
|
|
### 3. 데이터베이스 관리
|
|
- MariaDB/MySQL 기반 데이터 적재
|
|
- 자동 중복 제거 및 데이터 검증
|
|
- 스케줄 기반 자동 업데이트 (매일 11:00 UTC)
|
|
- 웹 인터페이스를 통한 백업 및 복구
|
|
|
|
### 4. 방문객 예측 분석
|
|
- **Prophet 시계열 모델**: 장기 추세 및 계절성 반영
|
|
- **다중 외부 변수**: 기상, 대기질, 휴일 정보 포함
|
|
- **신뢰도 구간**: 상한/하한 예측값 제공
|
|
|
|
### 5. 컨테이너화 지원
|
|
- Docker & Docker Compose 완전 지원
|
|
- 모든 플랫폼(Linux, macOS, Windows)에서 실행 가능
|
|
- 헬스체크 및 자동 재시작 기능
|
|
- 실제 볼륨 마운트 (바인드 마운트) 지원
|
|
|
|
---
|
|
|
|
## 📋 사전 요구사항
|
|
|
|
### 로컬 실행
|
|
- Python 3.11 이상
|
|
- MariaDB 10.4 이상 또는 MySQL 5.7 이상
|
|
- pip (Python 패키지 관리자)
|
|
|
|
### Docker 실행
|
|
- Docker 20.10 이상
|
|
- Docker Compose 1.29 이상
|
|
|
|
---
|
|
|
|
## ⚙️ 설치 및 설정
|
|
|
|
### 1. 저장소 클론
|
|
```bash
|
|
git clone https://git.siane.kr/firstgarden/static.git
|
|
cd static
|
|
```
|
|
|
|
### 2. 환경 변수 설정
|
|
```bash
|
|
# .env 파일 생성 (템플릿 복사)
|
|
cp .env.example .env
|
|
|
|
# .env 파일 편집
|
|
nano .env
|
|
```
|
|
|
|
**.env 주요 변수:**
|
|
```env
|
|
# Database Configuration
|
|
DB_HOST=localhost
|
|
DB_PORT=3306
|
|
DB_NAME=firstgarden
|
|
DB_USER=firstgarden
|
|
DB_PASSWORD=your_secure_password
|
|
|
|
# API Keys (필수)
|
|
# service-account-credentials.json 경로는 conf/ 디렉토리에 저장
|
|
|
|
# Timezone
|
|
TZ=Asia/Seoul
|
|
```
|
|
|
|
### 3. 설정 파일 준비
|
|
|
|
#### conf/config.yaml
|
|
```yaml
|
|
database:
|
|
host: localhost
|
|
user: firstgarden
|
|
password: your_password
|
|
name: firstgarden
|
|
|
|
DATA_API:
|
|
serviceKey: "your_data_go_kr_api_key"
|
|
air:
|
|
station_name:
|
|
- "운정"
|
|
weather:
|
|
stnIds:
|
|
- 99
|
|
|
|
ga4:
|
|
property_id: your_ga4_property_id
|
|
service_account_file: "./service-account-credentials.json"
|
|
|
|
POS:
|
|
VISITOR_CA:
|
|
- 입장료
|
|
- 티켓
|
|
- 기업제휴
|
|
|
|
FORECAST_WEIGHT:
|
|
visitor_forecast_multiplier: 0.5
|
|
minTa: 1.0
|
|
maxTa: 1.0
|
|
sumRn: 10.0
|
|
avgRhm: 1.0
|
|
pm25: 1.0
|
|
is_holiday: 20
|
|
```
|
|
|
|
#### GA4 서비스 계정
|
|
1. Google Cloud Console에서 서비스 계정 생성
|
|
2. JSON 키 다운로드
|
|
3. `conf/service-account-credentials.json`에 저장
|
|
|
|
---
|
|
|
|
## 🚀 실행 방법
|
|
|
|
### 방법 1: Docker Compose (권장)
|
|
|
|
```bash
|
|
# 이미지 빌드 및 서비스 시작
|
|
docker-compose up -d
|
|
|
|
# 로그 확인
|
|
docker-compose logs -f fg-static
|
|
|
|
# 서비스 상태 확인
|
|
docker-compose ps
|
|
|
|
# 서비스 중지
|
|
docker-compose down
|
|
```
|
|
|
|
#### 웹 기반 파일 업로드 서버 접근
|
|
```bash
|
|
# 웹 브라우저에서 접근
|
|
http://localhost:8889
|
|
|
|
# 또는 Docker 컨테이너 내부에서
|
|
# http://fg-static-app:8889
|
|
```
|
|
|
|
**웹 인터페이스 기능:**
|
|
- 📁 드래그 앤 드롭 파일 업로드
|
|
- 📊 실시간 업로드 진행 상황 모니터링
|
|
- 💾 데이터베이스 백업 생성
|
|
- 🔄 백업 파일로부터 데이터베이스 복구
|
|
- ✅ 파일 검증 및 자동 처리
|
|
|
|
**API 엔드포인트:**
|
|
- `POST /api/upload` - 파일 업로드 처리
|
|
- `GET /api/status` - 시스템 상태 조회
|
|
- `POST /api/backup` - 데이터베이스 백업 생성
|
|
- `POST /api/restore` - 데이터베이스 복구
|
|
- `GET /api/backups` - 백업 목록 조회
|
|
|
|
**대시보드 API:**
|
|
- `GET /api/dashboard/okpos-product` - OKPOS 상품별 통계
|
|
- `GET /api/dashboard/okpos-receipt` - OKPOS 영수증 통계
|
|
- `GET /api/dashboard/upsolution` - UPSOLUTION 통계
|
|
- `GET /api/dashboard/weather` - 날씨 데이터 통계
|
|
- `GET /api/dashboard/weekly-forecast` - 주간 예보 및 방문객 예상
|
|
- `GET /api/dashboard/visitor-trend` - 방문객 추이 (날짜 범위 조절 가능)
|
|
|
|
|
|
### 방법 2: 로컬 Python 실행
|
|
|
|
```bash
|
|
# 의존성 설치
|
|
pip install -r requirements.txt
|
|
|
|
# 데이터 수집 스크립트 실행
|
|
python daily_run.py
|
|
|
|
# 방문객 예측 실행
|
|
python -m lib.weekly_visitor_forecast_prophet
|
|
```
|
|
|
|
### 방법 3: 크론 작업으로 자동 실행
|
|
|
|
```bash
|
|
# crontab 편집
|
|
crontab -e
|
|
|
|
# 매일 11:00에 실행하도록 추가
|
|
0 11 * * * cd /path/to/static && python daily_run.py >> logs/daily_run.log 2>&1
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 데이터 흐름
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 외부 API 데이터 수집 │
|
|
├──────────────────────────────────────────────────────────┤
|
|
│ • 기상청 ASOS (weather_asos.py) │
|
|
│ • 에어코리아 (air_quality.py) │
|
|
│ • Google Analytics 4 (ga4.py) │
|
|
│ • POS 시스템 (pos_update_*.py) │
|
|
└─────────────────┬──────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 데이터 저장 (MariaDB) │
|
|
├──────────────────────────────────────────────────────────┤
|
|
│ • fg_manager_static_weather (날씨 데이터) │
|
|
│ • fg_manager_static_air (대기질 데이터) │
|
|
│ • fg_manager_static_ga4_by_date (방문자 데이터) │
|
|
│ • fg_manager_static_pos (POS 데이터) │
|
|
└─────────────────┬──────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 시계열 분석 및 예측 │
|
|
├──────────────────────────────────────────────────────────┤
|
|
│ • 특성 공학 (lag features, moving averages) │
|
|
│ • Prophet 모델 훈련 │
|
|
│ • 미래 7일 방문객 예측 │
|
|
│ • 예측 결과 CSV 저장 (data/prophet_result.csv) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 📁 프로젝트 구조
|
|
|
|
```
|
|
static/
|
|
├── conf/ # 설정 및 DB 정의
|
|
│ ├── config.yaml # 애플리케이션 설정 (동적)
|
|
│ ├── config.sample.yaml # 설정 샘플
|
|
│ ├── db.py # SQLAlchemy 연결 설정
|
|
│ ├── db_schema.py # DB 테이블 정의
|
|
│ └── service-account-credentials.json # GA4 인증 (보안)
|
|
│
|
|
├── lib/ # 데이터 처리 및 분석 모듈
|
|
│ ├── common.py # 공통 함수 (로깅, 설정 로드)
|
|
│ ├── weather_asos.py # 기상청 데이터 수집
|
|
│ ├── weather_forecast.py # 날씨 예보 조회
|
|
│ ├── air_quality.py # 대기환경 데이터 수집
|
|
│ ├── ga4.py # Google Analytics 수집
|
|
│ ├── holiday.py # 한국 휴일 관리
|
|
│ ├── weekly_visitor_forecast_prophet.py # 방문객 예측 (Prophet)
|
|
│ ├── weekly_visitor_forecast.py # 방문객 분석
|
|
│ ├── pos_update_*.py # POS 데이터 업데이트
|
|
│ ├── file_watch.py # 파일 변경 감시
|
|
│ └── requests_utils.py # HTTP 요청 유틸
|
|
│
|
|
├── data/ # 데이터 저장소
|
|
│ ├── prophet_result.csv # 예측 결과
|
|
│ ├── sample.csv # 샘플 데이터
|
|
│ └── cache/ # API 캐시
|
|
│
|
|
├── output/ # 출력 파일
|
|
│ └── [분석 결과 저장]
|
|
│
|
|
├── build/ # Docker 빌드
|
|
│ └── Dockerfile # Docker 이미지 정의
|
|
│
|
|
├── daily_run.py # 일일 작업 실행 스크립트
|
|
├── docker-compose.yml # Docker Compose 설정
|
|
├── requirements.txt # Python 의존성
|
|
├── .env.example # 환경 변수 템플릿
|
|
├── .gitignore # Git 무시 파일
|
|
└── README.md # 본 문서
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 주요 모듈 설명
|
|
|
|
### daily_run.py
|
|
매일 정기적으로 실행되는 메인 스크립트
|
|
|
|
```bash
|
|
# 실행 명령
|
|
python daily_run.py
|
|
|
|
# 실행 순서
|
|
1. weather_asos.py - 기상 데이터 수집
|
|
2. ga4.py - Google Analytics 수집
|
|
3. air_quality.py - 대기질 데이터 수집
|
|
```
|
|
|
|
### lib/weekly_visitor_forecast_prophet.py
|
|
Prophet을 이용한 고급 시계열 예측
|
|
|
|
**특징:**
|
|
- 1년 이상의 과거 데이터 학습
|
|
- Lag features & Moving averages 포함
|
|
- 기상, 대기질, 휴일 변수 통합
|
|
- 신뢰도 구간(95%) 제공
|
|
|
|
**실행:**
|
|
```bash
|
|
python -m lib.weekly_visitor_forecast_prophet
|
|
```
|
|
|
|
**출력:**
|
|
- `data/prophet_result.csv` - 7일 예측 결과
|
|
- 예측값, 하한, 상한 포함
|
|
|
|
### lib/common.py
|
|
공통 유틸리티 함수
|
|
|
|
```python
|
|
from lib.common import setup_logging, load_config, retry_on_exception
|
|
|
|
# 로거 설정
|
|
logger = setup_logging('my_module', 'INFO')
|
|
|
|
# 설정 로드
|
|
config = load_config()
|
|
|
|
# 재시도 데코레이터
|
|
@retry_on_exception(max_retries=3, delay=1.0, backoff=2.0)
|
|
def api_call():
|
|
...
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 데이터베이스 스키마
|
|
|
|
### 주요 테이블
|
|
|
|
#### fg_manager_static_ga4_by_date
|
|
| 컬럼명 | 타입 | 설명 |
|
|
|--------|------|------|
|
|
| date | DATE | 기준 날짜 (PK) |
|
|
| activeUsers | INT | 활성 사용자 수 |
|
|
| screenPageViews | INT | 페이지뷰 |
|
|
| sessions | INT | 세션 수 |
|
|
|
|
#### fg_manager_static_weather
|
|
| 컬럼명 | 타입 | 설명 |
|
|
|--------|------|------|
|
|
| date | DATE | 기준 날짜 (PK) |
|
|
| stnId | INT | 관측소 ID (PK) |
|
|
| minTa | FLOAT | 최저 기온 (℃) |
|
|
| maxTa | FLOAT | 최고 기온 (℃) |
|
|
| sumRn | FLOAT | 강수량 (mm) |
|
|
| avgRhm | FLOAT | 평균 습도 (%) |
|
|
|
|
#### fg_manager_static_air
|
|
| 컬럼명 | 타입 | 설명 |
|
|
|--------|------|------|
|
|
| date | DATE | 기준 날짜 (PK) |
|
|
| station | VARCHAR | 측정소 이름 (PK) |
|
|
| pm25 | FLOAT | PM2.5 농도 (㎍/㎥) |
|
|
| pm10 | FLOAT | PM10 농도 (㎍/㎥) |
|
|
|
|
---
|
|
|
|
## 🐛 문제 해결
|
|
|
|
### Docker 실행 시 DB 연결 오류
|
|
```bash
|
|
# DB 컨테이너가 준비될 때까지 대기
|
|
docker-compose ps # 모든 서비스 상태 확인
|
|
|
|
# 로그 확인
|
|
docker-compose logs mariadb
|
|
```
|
|
|
|
### API 요청 실패
|
|
- API Key 및 권한 확인
|
|
- 네트워크 연결 상태 확인
|
|
- API 할당량 확인
|
|
|
|
### 데이터 동기화 오류
|
|
```bash
|
|
# 강제 재동기화
|
|
python daily_run.py
|
|
|
|
# 특정 데이터만 재수집
|
|
python -c "from lib.weather_asos import main; main()"
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 성능 최적화
|
|
|
|
### 데이터베이스
|
|
- 연결 풀링 활성화 (pool_size=10, max_overflow=20)
|
|
- 1시간마다 자동 재연결
|
|
- 인덱스 기반 쿼리 최적화
|
|
|
|
### API 요청
|
|
- 병렬 처리 (ThreadPoolExecutor)
|
|
- 재시도 메커니즘 (exponential backoff)
|
|
- 캐싱 (로컬 JSON 캐시)
|
|
|
|
### 모델 학습
|
|
- 충분한 메모리 할당 권장 (최소 2GB)
|
|
- GPU 미지원 (CPU 기반)
|
|
|
|
---
|
|
|
|
## 📈 개선 계획
|
|
|
|
- [ ] 실시간 대시보드 (Flask/React)
|
|
- [ ] REST API 엔드포인트
|
|
- [ ] 다중 예측 모델 앙상블
|
|
- [ ] 설명 가능한 AI (SHAP)
|
|
- [ ] 모바일 앱 연동
|
|
- [ ] 이상 탐지 (Anomaly Detection)
|
|
- [ ] AutoML 파이프라인
|
|
|
|
---
|
|
|
|
## 🔐 보안
|
|
|
|
### 민감한 정보
|
|
- `.env` 파일은 절대 커밋하지 않기
|
|
- API 키는 환경 변수로 관리
|
|
- `service-account-credentials.json` 보호
|
|
- 프로덕션 환경에서 강한 DB 비밀번호 사용
|
|
|
|
### 권장 사항
|
|
- HTTPS 통신 사용
|
|
- 네트워크 방화벽 설정
|
|
- 정기적인 백업
|
|
- 로그 모니터링
|
|
|
|
---
|
|
|
|
## 📝 라이선스
|
|
|
|
MIT License - [LICENSE](LICENSE) 파일 참조
|
|
|
|
---
|
|
|
|
## 👥 기여자
|
|
|
|
**개발**: First Garden Team
|
|
|
|
---
|
|
|
|
## 📞 지원 및 문의
|
|
|
|
**저장소**: [https://git.siane.kr/firstgarden/static](https://git.siane.kr/firstgarden/static)
|
|
|
|
**문제 보고**: Gitea Issues 탭에서 등록
|
|
|
|
**요청사항**: Discussions 탭에서 논의
|
|
|
|
---
|
|
|
|
## 📚 참고 자료
|
|
|
|
- [Prophet 공식 문서](https://facebook.github.io/prophet/)
|
|
- [SQLAlchemy 튜토리얼](https://docs.sqlalchemy.org/)
|
|
- [Google Analytics API](https://developers.google.com/analytics/devguides/reporting/data/v1)
|
|
- [데이터.고.kr API](https://www.data.go.kr/)
|
|
- [Docker 공식 문서](https://docs.docker.com/)
|
|
|
|
---
|
|
|
|
**마지막 업데이트**: 2025년 12월 26일
|