다른 명령
DBA Tunes
- 프로그램 수정 가이드 - 핵심 요약
프로그램 구조
app.py # Flask 백엔드 서버 (API, 데이터베이스) templates/index_ag.html # 프론트엔드 메인 페이지 instance/sql_tuning.db # SQLite 데이터베이스 uploads/ # 첨부파일 저장 폴더 DBATunePjt/ ├── app.py # Flask 백엔드 애플리케이션 메인 파일 ├── requirements.txt # Python 의존성 패키지 목록 ├── init_db.py # 데이터베이스 초기화 스크립트 ├── reset_db.py # 데이터베이스 초기화/리셋 스크립트 │ ├── templates/ # HTML 템플릿 디렉토리 (백엔드에서 렌더링) │ ├── index_ag.html # ⭐ 메인 UI (AG Grid 사용) │ └── index_simple.html # 간단한 대체 UI │ ├── static/ # 정적 리소스 디렉토리 │ └── luckysheet/ # Luckysheet 라이브러리 (현재 미사용) │ ├── instance/ # 인스턴스 데이터 디렉토리 │ └── sql_tuning.db # SQLite 데이터베이스 파일
## 🔧 핵심 파일 상세 설명
### 1. **app.py** ⭐ (백엔드 핵심)
**역할**: Flask 웹 애플리케이션 서버 및 REST API 제공
#### 주요 구성 요소:
##### 📦 데이터베이스 모델 (ORM)
**TuningRequest 클래스** (`TN_REQ 테이블`)
- 튜닝 요청 정보를 저장하는 메인 테이블
- 필드 분류:
- **기본 정보**: `REQ_NO` (PK), `REQ_USER`, `REQ_DT`, `DB_NAME`
- **프로그램 정보**: `SQL_PROGRAM_ID`, `BUSINESS_TYPE`, `COLLECTION_TYPE`, `APP_SCREEN`
- **실행 정보**: `ONLINE_BATCH`, `EXECUTION_FREQUENCY`, `DYNAMIC_SQL`
- **SQL 정보**: `REQ_SQL_TEXT` (요청 SQL), `TUNED_SQL_TEXT` (완료 SQL)
- **실행 계획**: `REQ_EXECUTION_PLAN`, `TUNED_EXECUTION_PLAN`
- **성능 지표**: `TIME_BEFORE`, `TIME_AFTER` (응답속도), `BLOCKS_BEFORE`, `BLOCKS_AFTER`
- **튜닝 상태**: `IMPROVEMENT_STATUS`, `HINT_APPLIED`, `INDEX_CREATED`, `SQL_CHANGED`
- **개선율**: `IMPROVEMENT_RATE`, `COMPLETION_DATE`
**TuningAction 클래스** (`TN_ACTN 테이블`)
- 각 튜닝 요청에 대한 액션 내역 기록
##### 🔌 REST API 엔드포인트
| 메서드 | 엔드포인트 | 기능 |
|--------|----------|------|
| `GET` | `/` | 메인 페이지 (index.html) 렌더링 |
| `GET` | `/ag` | AG Grid 메인 페이지 (index_ag.html) 렌더링 |
| `GET` | `/api/requests` | 모든 튜닝 요청 조회 |
| `POST` | `/api/requests` | 새 튜닝 요청 생성 |
| `PUT` | `/api/requests/<id>` | 특정 튜닝 요청 업데이트 |
| `DELETE` | `/api/requests/<id>` | 특정 튜닝 요청 삭제 |
| `GET` | `/api/actions` | 모든 액션 조회 |
| `POST` | `/api/actions` | 새 액션 생성 |
| `POST` | `/api/init-sample` | 샘플 데이터 초기화 |
##### 🚀 애플리케이션 시작 로직
```python
if __name__ == '__main__':
with app.app_context():
db.create_all() # 데이터베이스 테이블 생성
# 데이터가 없으면 샘플 데이터 자동 추가
if TuningRequest.query.count() == 0:
# 샘플 데이터 삽입
app.run(debug=True, host='0.0.0.0', port=5000)
```
**특징**:
- 자동 데이터베이스 초기화
- 서버 시작 시 샘플 데이터 자동 생성
- UTF-8 인코딩 지원 (한글 처리)
- CORS 활성화 (크로스 도메인 요청 허용)
---
### 2. **templates/index_ag.html** ⭐ (프론트엔드 핵심)
**역할**: 메인 UI 인터페이스 (AG Grid 데이터 그리드 기반)
#### 주요 기능:
##### 🎨 UI 컴포넌트
1. **헤더 (Header)**
- 애플리케이션 제목: `[DBAWorks] SQL 튜닝 관리`
- 네비게이션 메뉴: SQL 튜닝, 성능 관리, 디스크 관리, 오브젝트 관리, 권한 관리, 시스템 관리
2. **도구모음 (Toolbar)**
- 새 요청 추가: 새로운 튜닝 요청 추가
- 저장: 그리드 변경사항 저장
- 새로고침: 데이터 다시 로드
- CSV 내보내기: 데이터 내보내기
- 샘플 데이터 초기화: 샘플 데이터 다시 로드
- **동적 컬럼 표시 버튼**:
- 요청정보 확인: 요청 관련 컬럼만 표시
- 튜닝결과 확인: 결과 관련 컬럼만 표시
- 전체보기: 모든 컬럼 표시
- 검색박스: 데이터 검색 기능
3. **데이터 그리드 (AG Grid)**
- 다중 선택 가능
- 셀 편집 가능
- 정렬/필터링 지원
- 동적 컬럼 표시
4. **상세 정보 패널 (Detail Panel)**
- 📋 요청 정보: 요청자, DB명, 프로그램ID, 비즈니스 유형 등
- 💾 SQL 정보 (편집 가능):
- 튜닝 요청 SQL
- 튜닝 요청 SQL 실행계획
- 튜닝 완료 SQL
- 튜닝 완료 SQL 실행계획
- 성능 개선 지표 (응답속도, Block 수)
- 🔧 튜닝 정보 (편집 가능):
- 개선여부
- 힌트적용
- INDEX생성
- SQL변경
5. **모달 윈도우 (Modal)**
- **새 요청 추가 모달**: 새로운 튜닝 요청 입력
- 요청자, DB명, 프로그램ID 등 입력
- SQL 입력 영역 (화면 50% 이상)
- 닫기 버튼으로만 닫기 가능 (외부 클릭 시 닫히지 않음)
##### 📊 컬럼 정의 (columnDefs)
**기본 컬럼**:
- 선택 체크박스
- 상세보기 버튼
- 요청번호 (REQ_NO)
- 요청자 (REQ_USER)
- 요청일시 (REQ_DT)
- 개선여부 (IMPROVEMENT_STATUS)
**요청정보 컬럼**:
- DB명, 프로그램ID, 비즈니스 유형, 수집 유형, 애플리케이션 화면, 온라인/배치, 실행 빈도, 동적SQL
**튜닝결과 컬럼**:
- 개선여부, 힌트적용, INDEX생성, SQL변경, Block 전/후, 응답속도 전/후, 개선율, 완료일
##### ⚙️ 주요 JavaScript 함수
| 함수 | 설명 |
|------|------|
| `loadData()` | `/api/requests`에서 데이터 로드 (에러 처리 포함) |
| `addRow()` | 새 요청 추가 모달 열기 |
| `saveNewRequest()` | 새 요청 저장 (POST 요청) |
| `saveChanges()` | 그리드 변경사항 저장 (PUT 요청) |
| `saveDetailChanges()` | 상세 패널 변경사항 저장 |
| `showDetailPanel(rowData)` | 상세 정보 패널 표시 |
| `closeDetailPanel()` | 상세 정보 패널 닫기 |
| `showRequestColumns()` | 요청정보 컬럼만 표시 |
| `showResultColumns()` | 튜닝결과 컬럼만 표시 |
| `showAllColumns()` | 모든 컬럼 표시 |
| `reloadData()` | 데이터 새로고침 |
| `exportCsv()` | CSV로 내보내기 |
| `initSample()` | 샘플 데이터 초기화 |
##### 🎨 CSS 스타일
**색상 스킴**:
- 헤더 배경: `#243447` (어두운 파란색)
- 강조 색상: `#2563eb` (파란색)
- 성공 색상: `#10b981` (초록색)
- 경고 색상: `#ec4899` (분홍색)
**주요 클래스**:
- `.header`: 상단 헤더 스타일
- `.toolbar`: 도구 버튼 영역
- `.detail-panel`: 상세 정보 패널
- `.modal`: 모달 윈도우
- `.form-group`: 폼 입력 그룹
---
### 3. **run.bat** (Windows 실행 파일)
**역할**: Windows에서 프로그램을 쉽게 실행
#### 기능:
1. UTF-8 인코딩 설정 (한글 표시)
2. Python 설치 여부 확인
3. 가상환경 자동 생성/활성화
4. 필요한 패키지 자동 설치 (`requirements.txt`)
5. 애플리케이션 자동 시작
6. 사용자 친화적 메시지 출력 (4단계 진행률 표시)
#### 사용 방법:
```bash
더블클릭 또는 PowerShell에서:
run.bat
```
---
### 4. **run.sh** (macOS/Linux 실행 파일)
**역할**: macOS 및 Linux에서 프로그램을 쉽게 실행
#### 기능:
- Windows의 `run.bat`와 동일한 기능을 쉘 스크립트로 구현
- `python3` 및 `python` 자동 감지
- 가상환경 자동 설정
- ANSI 색상 코드로 다양한 메시지 표시
#### 사용 방법:
```bash
chmod +x run.sh # 실행 권한 부여 (첫 번째만)
./run.sh # 실행
```
---
### 5. **requirements.txt** (의존성 파일)
**역할**: Python 패키지 버전 명시
#### 주요 패키지:
```
Flask==2.3.3 # 웹 프레임워크
Flask-CORS==4.0.0 # CORS 지원
Flask-SQLAlchemy==3.0.5 # ORM 라이브러리
SQLAlchemy==2.0.21 # 데이터베이스 관리
```
---
### 6. **init_db.py** (데이터베이스 초기화)
**역할**: 데이터베이스 수동 초기화
#### 기능:
- 데이터베이스 테이블 생성
- 초기 샘플 데이터 삽입
#### 사용 방법:
```bash
python init_db.py
```
---
### 7. **reset_db.py** (데이터베이스 리셋)
**역할**: 데이터베이스 초기화 및 재설정
#### 기능:
- 기존 데이터베이스 삭제
- 새 데이터베이스 생성
- 샘플 데이터 다시 삽입
#### 사용 방법:
```bash
python reset_db.py
```
---
## 🗄️ 데이터베이스 구조
### TN_REQ 테이블 (튜닝 요청)
| 컬럼명 | 데이터타입 | 설명 | 예시 |
|--------|-----------|------|------|
| REQ_NO | INTEGER (PK) | 요청 번호 | 1 |
| REQ_USER | VARCHAR(100) | 요청자 | Kim |
| REQ_DT | DATETIME | 요청 일시 | 2024-11-12 10:30:00 |
| DB_NAME | VARCHAR(50) | 데이터베이스명 | Oracle |
| SQL_PROGRAM_ID | VARCHAR(200) | 프로그램ID | PGM001 |
| BUSINESS_TYPE | VARCHAR(50) | 비즈니스 유형 | Sales |
| COLLECTION_TYPE | VARCHAR(100) | 수집 유형 | Real-time |
| APP_SCREEN | VARCHAR(100) | 애플리케이션 화면 | Main |
| ONLINE_BATCH | VARCHAR(20) | 온라인/배치 | Online |
| EXECUTION_FREQUENCY | VARCHAR(50) | 실행 빈도 | Daily |
| DYNAMIC_SQL | VARCHAR(1) | 동적SQL 여부 | Y/N |
| REQ_SQL_TEXT | TEXT | 요청 SQL | SELECT * FROM ... |
| REQ_EXECUTION_PLAN | TEXT | 요청 SQL 실행계획 | EXPLAIN 결과 |
| TUNED_SQL_TEXT | TEXT | 튜닝 완료 SQL | SELECT ... WHERE ... |
| TUNED_EXECUTION_PLAN | TEXT | 완료 SQL 실행계획 | EXPLAIN 결과 |
| TIME_BEFORE | FLOAT | 응답속도 (전) | 1.5 초 |
| TIME_AFTER | FLOAT | 응답속도 (후) | 0.3 초 |
| BLOCKS_BEFORE | INTEGER | Block 수 (전) | 100 |
| BLOCKS_AFTER | INTEGER | Block 수 (후) | 50 |
| IMPROVEMENT_RATE | VARCHAR(50) | 개선율 | 5배 |
| IMPROVEMENT_STATUS | VARCHAR(1) | 개선 완료 여부 | Y/N |
| HINT_APPLIED | VARCHAR(1) | 힌트 적용 | Y/N |
| INDEX_CREATED | VARCHAR(1) | 인덱스 생성 | Y/N |
| SQL_CHANGED | VARCHAR(1) | SQL 변경 | Y/N |
| COMPLETION_DATE | DATE | 완료 날짜 | 2024-11-12 |
### TN_ACTN 테이블 (액션 내역)
| 컬럼명 | 데이터타입 | 설명 |
|--------|-----------|------|
| REQ_NO | INTEGER (FK) | 요청 번호 (참조) |
| ACTION_ID | INTEGER (PK) | 액션 ID |
| ACTION_TYPE | VARCHAR(50) | 액션 유형 |
| ACTION_DESC | TEXT | 액션 설명 |
| ACTION_DT | DATETIME | 액션 일시 |
---
## 🔄 데이터 흐름 (Data Flow)
```
┌─────────────┐
│ 브라우저 │ (http://localhost:5000)
└──────┬──────┘
│ JavaScript Fetch API
▼
┌─────────────────────────────────────┐
│ Flask 백엔드 (app.py) │
│ ┌─────────────────────────────────┤
│ │ REST API Endpoints: │
│ │ • GET /api/requests │
│ │ • POST /api/requests │
│ │ • PUT /api/requests/<id> │
│ │ • DELETE /api/requests/<id> │
│ └─────────────────────────────────┤
└──────┬──────────────────────────────┘
│ SQL Queries
▼
┌─────────────────────────────┐
│ SQLite 데이터베이스 │
│ ┌──────────────────────┐ │
│ │ TN_REQ 테이블 │ │
│ │ (튜닝 요청) │ │
│ ├──────────────────────┤ │
│ │ TN_ACTN 테이블 │ │
│ │ (액션 내역) │ │
│ └──────────────────────┘ │
└─────────────────────────────┘
```
### 상세 데이터 흐름:
1. **데이터 조회**:
```
브라우저 → loadData() → GET /api/requests → DB 쿼리
→ JSON 응답 → AG Grid 표시
```
2. **새 요청 추가**:
```
모달 입력 → saveNewRequest() → POST /api/requests
→ DB INSERT → 그리드 새로고침
```
3. **데이터 업데이트**:
```
그리드/패널 편집 → saveChanges()/saveDetailChanges()
→ PUT /api/requests/<id> → DB UPDATE → 반영
```
---
## 🚀 애플리케이션 시작 프로세스
```
┌─────────────────────────────────────┐
│ run.bat / run.sh 실행 │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ [1/4] Python 설치 확인 │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ [2/4] 가상환경 생성/활성화 │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ [3/4] 패키지 설치 (requirements.txt) │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ [4/4] app.py 실행 │
│ ├─ db.create_all() │
│ ├─ 샘플 데이터 확인 │
│ └─ Flask 서버 시작 (포트 5000) │
└────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ http://localhost:5000 접속 가능 │
└─────────────────────────────────────┘
```
---
## 📱 주요 기능 설명
### 1. 새 요청 추가 프로세스
```
1. "새 요청 추가" 버튼 클릭
↓
2. 모달 윈도우 열기 (addRequestModal)
├─ 요청자 입력
├─ DB명 입력
├─ 프로그램ID 입력
├─ 비즈니스 유형 선택
├─ ... (기타 필드)
├─ SQL 입력 (화면 50% 이상)
│
3. "저장" 버튼 클릭
├─ 입력값 검증
├─ POST /api/requests 요청
├─ DB 저장
│
4. 그리드 자동 새로고침
```
### 2. 상세 정보 확인 및 편집
```
1. 그리드에서 행 선택 또는 "상세보기" 버튼 클릭
↓
2. 상세 정보 패널 표시
├─ 📋 요청 정보 (읽기 전용)
├─ 💾 SQL 정보 (편집 가능)
│ ├─ SQL 텍스트
│ ├─ 실행 계획
│ └─ 성능 지표
├─ 🔧 튜닝 정보 (편집 가능)
│
3. 필요시 값 편집
↓
4. "💾 저장" 버튼 클릭
├─ 변경사항 수집
├─ PUT /api/requests/<id> 요청
├─ DB 업데이트
│
5. 저장 완료 알림
```
### 3. 동적 컬럼 표시
```
"요청정보 확인" 버튼 클릭
├─ 기본 컬럼 유지
├─ 요청정보 컬럼만 표시
│ └─ DB명, 프로그램ID, 비즈니스 유형 등
│
"튜닝결과 확인" 버튼 클릭
├─ 기본 컬럼 유지
├─ 결과 컬럼만 표시
│ └─ 개선여부, 힌트적용, INDEX생성 등
│
"전체보기" 버튼 클릭
└─ 모든 컬럼 표시
```
---
## 🔐 보안 기능
1. **CORS 활성화**
- Cross-Origin 요청 지원
- 프론트엔드와 백엔드 분리 가능
2. **UTF-8 인코딩**
- 한글 문자 안전 처리
- 터미널 및 데이터베이스에서 정상 표시
3. **SECRET_KEY**
- Flask 세션 보안
- 쿠키 암호화
---
## 🐛 에러 처리
### 백엔드 (app.py)
```python
try:
# API 로직
data = [req.to_dict() for req in requests]
return jsonify(data)
except Exception as e:
# 오류 로깅
print(f'[오류] {str(e)}')
return jsonify({'error': str(e)}), 500
```
### 프론트엔드 (index_ag.html)
```javascript
try {
const r = await fetch('/api/requests');
if (!r.ok) {
const errorText = await r.text();
alert('데이터 로드 실패: ' + r.status);
return;
}
const data = await r.json();
gridOptions.api.setRowData(data);
} catch (err) {
alert('오류 발생: ' + err.message);
console.error(err);
}
```
---
## 📊 시스템 요구사항
### 최소 요구사항
- **OS**: Windows 10, macOS 10.14+, Linux (Ubuntu 18.04+)
- **Python**: 3.8 이상
- **RAM**: 512MB 이상
- **디스크**: 200MB 이상
### 권장 사양
- **OS**: Windows 11, macOS 12+, Ubuntu 22.04+
- **Python**: 3.10 이상
- **RAM**: 2GB 이상
- **디스크**: 1GB 이상
### 필요한 소프트웨어
- Python 3.8+
- 웹 브라우저 (Chrome, Firefox, Safari, Edge)
---
## 📝 파일별 수정 이력
### app.py
- UTF-8 인코딩 추가
- 새로운 컬럼 추가 (REQ_EXECUTION_PLAN, TUNED_EXECUTION_PLAN)
- 에러 처리 강화
- 자동 샘플 데이터 초기화
### index_ag.html
- AG Grid 도입
- 모달 기반 새 요청 추가
- 상세 정보 패널 (편집 가능)
- 동적 컬럼 관리
- 한글 입출력 지원
### run.bat
- UTF-8 인코딩 설정 (chcp 65001)
- 4단계 진행 표시
- Python 버전 감지
- 가상환경 자동 관리
### run.sh
- macOS/Linux 호환성
- Python3 자동 감지
- ANSI 색상 코드 사용
---
## 🎯 주요 API 응답 형식
### GET /api/requests 응답
```json
[
{
"REQ_NO": 1,
"REQ_USER": "Kim",
"REQ_DT": "2024-11-12 10:30:00",
"DB_NAME": "Oracle",
"SQL_PROGRAM_ID": "PGM001",
"REQ_SQL_TEXT": "SELECT * FROM ...",
"TUNED_SQL_TEXT": "SELECT ... WHERE ...",
"REQ_EXECUTION_PLAN": "EXPLAIN 결과",
"TUNED_EXECUTION_PLAN": "EXPLAIN 결과",
"TIME_BEFORE": 1.5,
"TIME_AFTER": 0.3,
"BLOCKS_BEFORE": 100,
"BLOCKS_AFTER": 50,
"IMPROVEMENT_STATUS": "Y",
...
}
]
```
### POST /api/requests 요청
```json
{
"REQ_USER": "Kim",
"DB_NAME": "Oracle",
"SQL_PROGRAM_ID": "PGM001",
"REQ_SQL_TEXT": "SELECT * FROM ...",
...
}
```
### PUT /api/requests/<id> 요청
```json
{
"TUNED_SQL_TEXT": "SELECT ... WHERE ...",
"REQ_EXECUTION_PLAN": "EXPLAIN 결과",
"TIME_BEFORE": 1.5,
"TIME_AFTER": 0.3,
"IMPROVEMENT_STATUS": "Y",
...
}
```
---
## 🤝 개발 팀 노트
### 주요 설계 원칙
1. **모듈화**: 각 기능을 독립적으로 개발/유지보수
2. **확장성**: 새로운 기능 추가 용이
3. **사용자 친화**: 직관적인 UI/UX
4. **성능**: 빠른 데이터 로드 및 응답
### 향후 개선 계획
- 다중 언어 지원 (영어, 중국어 등)
- 고급 분석 및 리포팅
- 사용자 권한 관리
- 변경 이력 추적
- API 인증 (JWT)
- 데이터 내보내기 다양화 (Excel, PDF 등)
---
## 📞 문제 해결
### 포트 5000이 이미 사용 중인 경우
```bash
# 포트 변경
# app.py의 마지막 줄:
app.run(debug=True, host='0.0.0.0', port=5001)
```
### 데이터베이스 손상 시
```bash
python reset_db.py
```
### 패키지 설치 오류
```bash
pip install --upgrade pip
pip install -r requirements.txt --force-reinstall
```
### 한글 출력 오류 (Windows)
- `run.bat`는 자동으로 UTF-8 설정
- 수동 설정: `chcp 65001`
---
## 📚 참고 자료
### 사용 라이브러리 문서
- [Flask 공식 문서](https://flask.palletsprojects.com/)
- [SQLAlchemy 공식 문서](https://docs.sqlalchemy.org/)
- [AG Grid 공식 문서](https://www.ag-grid.com/)
- [Flask-CORS](https://flask-cors.readthedocs.io/)
### 튜토리얼
- Flask 기초: https://flask.palletsprojects.com/tutorial/
- SQLAlchemy 기초: https://docs.sqlalchemy.org/tutorial/
- AG Grid 시작: https://www.ag-grid.com/getting-started/
---
**마지막 수정**: 2024-11-12
**버전**: 1.0.0
**작성자**: DBAWorks Team
주요 수정 포인트
A. 데이터베이스 필드 추가
위치: `app.py` 24-82줄 (TuningRequest 클래스)
# 1. 필드 추가
class TuningRequest(db.Model):
# ... 기존 필드들
NEW_FIELD = db.Column(db.String(100)) # 새 필드 추가
# 2. to_dict() 메서드에 추가
def to_dict(self):
return {
# ... 기존 필드들
'NEW_FIELD': self.NEW_FIELD,
}
- B. 프론트엔드 컬럼 추가
위치: `index_ag.html` 227-238줄 (basicColumnDefs)
const basicColumnDefs = [
// ... 기존 컬럼들
{ headerName: '새 컬럼', field: 'NEW_FIELD', width: 100, editable: true },
];
- C. 새 요청 모달에 입력 필드 추가
위치: `index_ag.html` 113-197줄 (새 요청 추가 모달)
<div class="form-field">
<label>새 필드</label>
<input type="text" id="formNewField" placeholder="새 필드 입력">
</div>
- D. 파일 크기 제한 변경
위치: `app.py` 15줄
app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 50MB로 변경
- E. 파일 타입 제한 추가
위치: `app.py` 276-318줄 (upload_attachment 함수)
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'sql'}
file_extension = os.path.splitext(original_filename)[1][1:].lower()
if file_extension not in ALLOWED_EXTENSIONS:
return jsonify({'error': '허용되지 않는 파일 타입입니다.'}), 400
주요 함수 위치
- 백엔드 (app.py)
- 요청 생성: 156-188줄 (`create_request`) - 요청 수정: 190-225줄 (`update_request`) - 요청 삭제: 227-232줄 (`delete_request`) - 파일 업로드: 276-318줄 (`upload_attachment`) - 파일 다운로드: 329-341줄 (`download_attachment`) - 파일 삭제: 343-361줄 (`delete_attachment`)
- 프론트엔드 (index_ag.html)
- 데이터 로드: 342-397줄 (`loadData`) - 새 요청 추가: 402-425줄 (`addRow`) - 새 요청 저장: 497-579줄 (`saveNewRequest`) - 파일 업로드: 471-495줄 (`uploadFiles`) - 상세 패널 표시: 809-1016줄 (`showDetailPanel`) - 상세 정보 저장: 757-807줄 (`saveDetailChanges`)
스타일 수정
위치: `index_ag.html` 9-76줄 (`<style>` 섹션)
/* 색상 변경 */
.btn-primary {
background:#2563eb; /* 파란색 */
}
/* 폰트 크기 변경 */
body {
font-size: 14px;
}
API 엔드포인트 목록
GET /api/requests # 요청 목록 조회 POST /api/requests # 새 요청 생성 PUT /api/requests/<req_no> # 요청 수정 DELETE /api/requests/<req_no> # 요청 삭제 GET /api/requests/<req_no>/sql-text # SQL 텍스트 조회 PUT /api/requests/<req_no>/sql-text # SQL 텍스트 수정 POST /api/requests/<req_no>/attachments # 파일 업로드 GET /api/requests/<req_no>/attachments # 파일 목록 조회 GET /api/attachments/<attach_no> # 파일 다운로드 DELETE /api/attachments/<attach_no> # 파일 삭제 POST /api/init-data # 샘플 데이터 초기화
데이터베이스 테이블
- TN_REQ (TuningRequest)
- 주요 필드: REQ_NO, REQ_USER, REQ_DT, SQL_PROGRAM_ID 등 - 관계: 첨부파일(1:N), 액션(1:1)
- TN_ATTACH (Attachment)
- 주요 필드: ATTACH_NO, REQ_NO, ORIGINAL_FILENAME, STORED_FILENAME - 관계: 요청(N:1)
- TN_ACTN (TuningAction)
- 주요 필드: REQ_NO, ACTION_DATE, ACTION_USER - 관계: 요청(1:1)
수정 시 주의사항
1. 데이터베이스 필드 추가 시
- 기존 데이터는 NULL로 설정됨 - 백업 후 수정 권장
2. 파일 업로드 시
- 파일 크기 제한 확인 (기본 16MB) - 업로드 폴더 권한 확인
3. 프론트엔드 수정 시
- JavaScript 함수명 중복 주의 - HTML ID 중복 주의
4. API 수정 시
- 응답 형식 일관성 유지 - 에러 처리 추가 권장
빠른 수정 예시
- 예시 1: 새 필드 추가
# app.py - TuningRequest 클래스에 필드 추가
PRIORITY = db.Column(db.String(10)) # 우선순위
# app.py - to_dict() 메서드에 추가
'PRIORITY': self.PRIORITY,
# index_ag.html - 컬럼 추가
{ headerName: '우선순위', field: 'PRIORITY', width: 100, editable: true },
# index_ag.html - 모달에 입력 필드 추가
<div class="form-field">
<label>우선순위</label>
<select id="formPriority">
<option value="높음">높음</option>
<option value="보통">보통</option>
<option value="낮음">낮음</option>
</select>
</div>
- 예시 2: 파일 타입 제한
# app.py - upload_attachment 함수에 추가
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'sql', 'jpg', 'png'}
file_extension = os.path.splitext(original_filename)[1][1:].lower()
if file_extension not in ALLOWED_EXTENSIONS:
return jsonify({'error': f'{file_extension} 파일은 허용되지 않습니다.'}), 400