handOver2/ARCHITECTURE.md

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 폰트 적용
  • 현대적인 둥근 모서리
  • 그라데이션 효과
  • 애니메이션 전환