517 lines
24 KiB
Markdown
517 lines
24 KiB
Markdown
# 전동차 업무 인수인계 및 고장관리 프로그램 아키텍처
|
|
|
|
## 1. 프로젝트 개요
|
|
|
|
### 1.1 목적
|
|
- 전동차 운용실의 24시간 교대 근무 환경에서 업무 인수인계 및 고장관리를 위한 윈도우 데스크톱 애플리케이션
|
|
- 기존 엑셀 매크로 기반 시스템을 현대적인 GUI 애플리케이션으로 대체
|
|
|
|
### 1.2 기술 스택
|
|
- **Frontend**: PySide6 (Qt for Python)
|
|
- **Database**: SQLite (로컬) → Supabase (원격, 추후 연동)
|
|
- **Font**: GmarketSans
|
|
- **Platform**: Windows Native
|
|
|
|
### 1.3 설계 원칙
|
|
- 모듈화된 구조로 유지보수성 확보
|
|
- 상속 기반 확장성 설계
|
|
- 상세한 로깅 및 주석
|
|
- 현대적이고 미려한 커스텀 UI
|
|
|
|
---
|
|
|
|
## 2. 프로젝트 구조
|
|
|
|
```
|
|
handover/
|
|
├── main.py # 진입점
|
|
├── requirements.txt # 의존성 패키지
|
|
├── ARCHITECTURE.md # 아키텍처 문서
|
|
├── config.ini # 설정 파일
|
|
├── assets/ # 리소스
|
|
│ ├── fonts/ # 폰트 파일
|
|
│ │ └── GmarketSans/
|
|
│ ├── icons/ # 아이콘
|
|
│ ├── images/ # 이미지
|
|
│ └── styles/ # QSS 스타일시트
|
|
│ ├── dark_theme.qss
|
|
│ └── light_theme.qss
|
|
│
|
|
├── core/ # 핵심 모듈
|
|
│ ├── __init__.py
|
|
│ ├── constants.py # 상수 정의
|
|
│ ├── config.py # 설정 관리
|
|
│ ├── logger.py # 로깅 시스템
|
|
│ ├── signals.py # 전역 시그널
|
|
│ └── exceptions.py # 커스텀 예외
|
|
│
|
|
├── database/ # 데이터베이스 모듈
|
|
│ ├── __init__.py
|
|
│ ├── db_manager.py # DB 연결 관리
|
|
│ ├── models.py # 데이터 모델 정의
|
|
│ ├── crud.py # CRUD 연산
|
|
│ ├── migrations.py # DB 마이그레이션
|
|
│ └── sync_manager.py # 원격 DB 동기화 (추후)
|
|
│
|
|
├── services/ # 비즈니스 로직
|
|
│ ├── __init__.py
|
|
│ ├── auth_service.py # 인증/권한 서비스
|
|
│ ├── weather_service.py # 날씨 정보 서비스
|
|
│ ├── update_service.py # 업데이트 서비스
|
|
│ ├── backup_service.py # 백업 서비스
|
|
│ └── notification_service.py # 알림 서비스
|
|
│
|
|
├── ui/ # UI 모듈
|
|
│ ├── __init__.py
|
|
│ ├── main_window.py # 메인 윈도우
|
|
│ │
|
|
│ ├── base/ # 기본 UI 컴포넌트
|
|
│ │ ├── __init__.py
|
|
│ │ ├── base_widget.py # 기본 위젯 클래스
|
|
│ │ ├── base_dialog.py # 기본 다이얼로그 클래스
|
|
│ │ ├── base_section.py # 기본 섹션 클래스
|
|
│ │ └── base_table.py # 기본 테이블 클래스
|
|
│ │
|
|
│ ├── components/ # 재사용 가능 컴포넌트
|
|
│ │ ├── __init__.py
|
|
│ │ ├── custom_button.py # 커스텀 버튼
|
|
│ │ ├── custom_input.py # 커스텀 입력 필드
|
|
│ │ ├── custom_table.py # 커스텀 테이블
|
|
│ │ ├── custom_calendar.py # 커스텀 캘린더
|
|
│ │ ├── toggle_switch.py # 토글 스위치
|
|
│ │ ├── dropdown.py # 드롭다운
|
|
│ │ ├── splitter.py # 분리바
|
|
│ │ ├── popup_widget.py # 팝업 위젯
|
|
│ │ └── train_info_popup.py # 편성 정보 팝업
|
|
│ │
|
|
│ ├── panels/ # 패널 (영역별 UI)
|
|
│ │ ├── __init__.py
|
|
│ │ ├── info_bar.py # 상단 인포바 (10%)
|
|
│ │ ├── status_bar.py # 하단 상태바 (10%)
|
|
│ │ ├── content_panel.py # 중앙 컨텐츠 (80%)
|
|
│ │ ├── section_panel.py # 왼쪽 섹션 패널 (70%)
|
|
│ │ └── todo_panel.py # 오른쪽 Todo 패널 (30%)
|
|
│ │
|
|
│ ├── sections/ # 섹션별 UI
|
|
│ │ ├── __init__.py
|
|
│ │ ├── instruction_section.py # 지시 섹션
|
|
│ │ ├── fault_section.py # 고장 섹션
|
|
│ │ ├── work_section.py # 작업 섹션
|
|
│ │ └── misc_section.py # 기타 섹션
|
|
│ │
|
|
│ ├── dialogs/ # 다이얼로그
|
|
│ │ ├── __init__.py
|
|
│ │ ├── login_dialog.py # 로그인 다이얼로그
|
|
│ │ ├── settings_dialog.py # 설정 다이얼로그
|
|
│ │ ├── user_management_dialog.py # 사용자 관리
|
|
│ │ ├── input_dialog.py # 입력 다이얼로그
|
|
│ │ ├── train_input_dialog.py # 편성 입력 다이얼로그
|
|
│ │ ├── todo_input_dialog.py # Todo 입력 다이얼로그
|
|
│ │ └── memo_input_dialog.py # 메모 입력 다이얼로그
|
|
│ │
|
|
│ └── widgets/ # Todo/메모 관련 위젯
|
|
│ ├── __init__.py
|
|
│ ├── daily_inspection.py # 일상검수 편성 위젯
|
|
│ ├── todo_list.py # 할일 목록 위젯
|
|
│ └── memo_widget.py # 메모 위젯
|
|
│
|
|
└── utils/ # 유틸리티
|
|
├── __init__.py
|
|
├── helpers.py # 헬퍼 함수
|
|
├── validators.py # 유효성 검사
|
|
├── formatters.py # 포맷터
|
|
└── common_methods.py # 공통 메서드 (편성 팝업 등)
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 모듈 의존성 다이어그램
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ main.py │
|
|
│ (Application Entry) │
|
|
└──────────────────────────────────┬──────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ MainWindow (UI) │
|
|
│ ui/main_window.py │
|
|
└──────┬───────────────────────────┬──────────────────────────────────────┘
|
|
│ │
|
|
▼ ▼
|
|
┌──────────────┐ ┌─────────────────────────────────────────────────┐
|
|
│ Services │ │ UI Modules │
|
|
│ ────────── │ │ ───────────────────────────────────────────── │
|
|
│ auth_service │◄────────┤ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
|
|
│ weather_srv │ │ │ info_bar │ │ sections │ │ todo_panel │ │
|
|
│ update_srv │ │ └──────────┘ └──────────┘ └──────────────┘ │
|
|
│ backup_srv │ │ │ │ │ │
|
|
└──────┬───────┘ │ ▼ ▼ ▼ │
|
|
│ │ ┌─────────────────────────────────────────┐ │
|
|
│ │ │ Base Components │ │
|
|
│ │ │ base_widget, base_section, base_table │ │
|
|
│ │ └─────────────────────────────────────────┘ │
|
|
│ └─────────────────────────┬───────────────────────┘
|
|
│ │
|
|
▼ ▼
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ Core Module │
|
|
│ config, logger, constants, signals │
|
|
└──────────────────────────────────┬──────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ Database Module │
|
|
│ db_manager, models, crud, sync │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 4. UI 레이아웃 구조
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ Title Bar │
|
|
│ [앱 아이콘] 전동차 인수인계 시스템 [─][□][X] │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ Menu Bar │
|
|
│ [파일] [편집] [보기] [설정] [도움말] │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ INFO BAR (10%) │
|
|
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────────┐ │
|
|
│ │ 2026.01.03 │ A팀 │ 주간 │ 팀변경 │ 🌤 서울 -3°C 맑음 │ │
|
|
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └──────────────────┘ │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ CONTENT AREA (80%) │
|
|
│ ┌───────────────────────────────────┬─────────────────────────────┐ │
|
|
│ │ SECTION PANEL (70%) │ TODO PANEL (30%) │◄──┼── Splitter
|
|
│ │ ┌───────────────────────────┐ │ ┌───────────────────────┐ │ │
|
|
│ │ │ [지시][고장][작업][기타] │ │ │ 일상검수 (30%) │ │ │
|
|
│ │ │ ─────────────────────────│ │ │ ┌─────┬─────────────┐│ │ │
|
|
│ │ │ 날짜 │팀│내용 │확인 │ │ │ │주간 │①②③④⑤ ││ │ │
|
|
│ │ │──────┼──┼────────┼─────│ │ │ │야간 │①②③④⑤ ││ │ │
|
|
│ │ │01/03 │A │지시내용1│✓✓✓ │ │ │ └─────┴─────────────┘│ │ │
|
|
│ │ │01/02 │B │지시내용2│✓✓✗ │ │ ├───────────────────────┤ │ │
|
|
│ │ │... │ │ │ │ │ │ 할일 목록 (35%) │ │ │
|
|
│ │ └───────────────────────────┘ │ │ ┌─────────────────┐ │ │ │
|
|
│ │ │ │ │□ 점검 사항 1 │ │ │ │
|
|
│ │ │ │ │☑ 점검 사항 2 │ │ │ │
|
|
│ │ │ │ └─────────────────┘ │ │ │
|
|
│ │ │ ├───────────────────────┤ │ │
|
|
│ │ │ │ 메모 (35%) │ │ │
|
|
│ │ │ │ ┌─────────────────┐ │ │ │
|
|
│ │ │ │ │ 메모 내용... │ │ │ │
|
|
│ │ │ │ └─────────────────┘ │ │ │
|
|
│ │ │ └───────────────────────┘ │ │
|
|
│ └───────────────────────────────────┴─────────────────────────────┘ │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ STATUS BAR (10%) │
|
|
│ [접속자: 홍길동(검수팀)] [DB상태: 정상] [마지막 동기화: 10:30] [v1.0.0] │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 5. 데이터베이스 스키마
|
|
|
|
### 5.1 사용자 테이블 (users)
|
|
```sql
|
|
CREATE TABLE users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
username TEXT UNIQUE NOT NULL,
|
|
password_hash TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
department TEXT NOT NULL, -- 검수팀, 운전팀, 차량팀 등
|
|
role TEXT NOT NULL, -- admin, editor, viewer
|
|
is_active BOOLEAN DEFAULT 1,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### 5.2 팀 테이블 (teams)
|
|
```sql
|
|
CREATE TABLE teams (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL, -- A팀, B팀, C팀, D팀
|
|
shift_type TEXT, -- 주간, 야간
|
|
is_active BOOLEAN DEFAULT 1,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### 5.3 지시 섹션 (instructions)
|
|
```sql
|
|
CREATE TABLE instructions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
created_date DATE NOT NULL,
|
|
created_team TEXT NOT NULL,
|
|
instructor TEXT, -- 지시자
|
|
instruction_content TEXT NOT NULL, -- 지시내용
|
|
instruction_date DATE, -- 지시일자
|
|
is_continuous BOOLEAN DEFAULT 0, -- 지속여부
|
|
team_confirmations TEXT, -- JSON: {"A": true, "B": false, ...}
|
|
is_completed BOOLEAN DEFAULT 0,
|
|
completed_at DATETIME,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.4 고장 섹션 (faults)
|
|
```sql
|
|
CREATE TABLE faults (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
created_date DATE NOT NULL,
|
|
created_team TEXT NOT NULL,
|
|
occurrence_date DATE, -- 발생일자
|
|
train_number TEXT, -- 편성
|
|
car_number TEXT, -- 호차
|
|
fault_code TEXT, -- 고장코드
|
|
device_category TEXT, -- 장치분류
|
|
occurrence_station TEXT, -- 발생역
|
|
occurrence_time TIME, -- 발생시간
|
|
fault_content TEXT, -- 고장내용
|
|
action_content TEXT, -- 조치내용
|
|
action_team TEXT, -- 조치팀
|
|
team_confirmations TEXT, -- JSON
|
|
is_completed BOOLEAN DEFAULT 0,
|
|
completed_at DATETIME,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.5 작업 섹션 (works)
|
|
```sql
|
|
CREATE TABLE works (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
created_date DATE NOT NULL,
|
|
created_team TEXT NOT NULL,
|
|
work_date DATE, -- 작업일정
|
|
work_entity TEXT, -- 작업주체
|
|
target_train TEXT, -- 대상편성
|
|
target_device TEXT, -- 대상기기
|
|
work_content TEXT, -- 작업내용
|
|
remarks TEXT, -- 특이사항
|
|
team_confirmations TEXT, -- JSON
|
|
is_completed BOOLEAN DEFAULT 0,
|
|
completed_at DATETIME,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.6 기타 섹션 (miscs)
|
|
```sql
|
|
CREATE TABLE miscs (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
created_date DATE NOT NULL,
|
|
created_team TEXT NOT NULL,
|
|
reporter TEXT, -- 전달자
|
|
report_content TEXT, -- 전달내용
|
|
remarks TEXT, -- 특이사항
|
|
related_document TEXT, -- 관련문서
|
|
team_confirmations TEXT, -- JSON
|
|
is_completed BOOLEAN DEFAULT 0,
|
|
completed_at DATETIME,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.7 일상검수 (daily_inspections)
|
|
```sql
|
|
CREATE TABLE daily_inspections (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
inspection_date DATE NOT NULL,
|
|
shift_type TEXT NOT NULL, -- 주간, 야간
|
|
slot_number INTEGER NOT NULL, -- 1~5
|
|
train_number TEXT, -- 편성번호
|
|
cleaning_type TEXT, -- 없음, 중청소, 대청소
|
|
has_work BOOLEAN DEFAULT 0, -- 작업 여부
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.8 할일 목록 (todos)
|
|
```sql
|
|
CREATE TABLE todos (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
todo_date DATE NOT NULL,
|
|
target_train TEXT, -- 대상편성
|
|
schedule TEXT, -- 일정
|
|
content TEXT NOT NULL, -- 내용
|
|
is_completed BOOLEAN DEFAULT 0,
|
|
completed_at DATETIME,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.9 메모 (memos)
|
|
```sql
|
|
CREATE TABLE memos (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
memo_date DATE NOT NULL,
|
|
content TEXT NOT NULL,
|
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
created_by INTEGER REFERENCES users(id)
|
|
);
|
|
```
|
|
|
|
### 5.10 설정 (settings)
|
|
```sql
|
|
CREATE TABLE settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT,
|
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 클래스 상속 구조
|
|
|
|
### 6.1 위젯 상속 구조
|
|
```
|
|
QWidget
|
|
└── BaseWidget
|
|
├── InfoBar
|
|
├── StatusBar
|
|
├── ContentPanel
|
|
│ ├── SectionPanel
|
|
│ └── TodoPanel
|
|
└── BaseSection
|
|
├── InstructionSection
|
|
├── FaultSection
|
|
├── WorkSection
|
|
└── MiscSection
|
|
```
|
|
|
|
### 6.2 다이얼로그 상속 구조
|
|
```
|
|
QDialog
|
|
└── BaseDialog
|
|
├── LoginDialog
|
|
├── SettingsDialog
|
|
├── UserManagementDialog
|
|
└── InputDialog
|
|
├── TrainInputDialog
|
|
├── TodoInputDialog
|
|
└── MemoInputDialog
|
|
```
|
|
|
|
### 6.3 테이블 상속 구조
|
|
```
|
|
QTableWidget
|
|
└── BaseTable
|
|
└── SectionTable
|
|
├── InstructionTable
|
|
├── FaultTable
|
|
├── WorkTable
|
|
└── MiscTable
|
|
```
|
|
|
|
---
|
|
|
|
## 7. 권한 시스템
|
|
|
|
### 7.1 부서별 권한
|
|
| 부서 | 역할 | 권한 |
|
|
|------|------|------|
|
|
| 검수팀 | admin | 모든 CRUD 가능, 사용자 관리, 설정 변경 |
|
|
| 기타 부서 | viewer | 조회만 가능 |
|
|
|
|
### 7.2 권한 확인 플로우
|
|
```
|
|
사용자 로그인
|
|
↓
|
|
권한 확인 (department, role)
|
|
↓
|
|
UI 요소 활성화/비활성화
|
|
↓
|
|
DB 작업 시 권한 재확인
|
|
```
|
|
|
|
---
|
|
|
|
## 8. 공통 메서드 (편성 팝업 등)
|
|
|
|
### 8.1 TrainInfoMixin
|
|
```python
|
|
class TrainInfoMixin:
|
|
"""편성 정보 관련 공통 기능을 제공하는 Mixin 클래스"""
|
|
|
|
def show_train_popup(self, train_number: str, position: QPoint):
|
|
"""마우스 호버 시 편성의 최근 고장 목록을 팝업으로 표시"""
|
|
pass
|
|
|
|
def get_recent_faults(self, train_number: str, limit: int = 10) -> List[dict]:
|
|
"""특정 편성의 최근 고장 목록 조회"""
|
|
pass
|
|
|
|
def open_train_detail(self, train_number: str):
|
|
"""편성 상세 정보 다이얼로그 열기"""
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
## 9. 업데이트 시스템
|
|
|
|
### 9.1 업데이트 플로우
|
|
```
|
|
앱 시작
|
|
↓
|
|
버전 확인 (주기적: 1시간마다)
|
|
↓
|
|
새 버전 발견 시 알림
|
|
↓
|
|
사용자 확인 후 다운로드
|
|
↓
|
|
앱 재시작 후 업데이트 적용
|
|
```
|
|
|
|
---
|
|
|
|
## 10. 로깅 시스템
|
|
|
|
### 10.1 로그 레벨
|
|
- DEBUG: 상세 디버그 정보
|
|
- INFO: 일반 정보
|
|
- WARNING: 경고
|
|
- ERROR: 오류
|
|
- CRITICAL: 심각한 오류
|
|
|
|
### 10.2 로그 저장
|
|
- 파일: logs/app_YYYYMMDD.log
|
|
- 최대 보관: 30일
|
|
- 로테이션: 일별
|
|
|
|
---
|
|
|
|
## 11. 테마 시스템
|
|
|
|
### 11.1 지원 테마
|
|
- Light Theme: 밝은 테마
|
|
- Dark Theme: 어두운 테마
|
|
|
|
### 11.2 커스텀 스타일
|
|
- GmarketSans 폰트 적용
|
|
- 현대적인 둥근 모서리
|
|
- 그라데이션 효과
|
|
- 애니메이션 전환
|
|
|
|
|