24 KiB
24 KiB
전동차 업무 인수인계 및 고장관리 프로그램 아키텍처
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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 폰트 적용
- 현대적인 둥근 모서리
- 그라데이션 효과
- 애니메이션 전환