feat: implement session timeout countdown and UI optimization

This commit is contained in:
leeyj
2026-04-20 16:47:47 +09:00
parent ac58e14c8c
commit b376eedc48
15 changed files with 321 additions and 18 deletions
+21
View File
@@ -0,0 +1,21 @@
# Bug Report: 세션 타임아웃으로 인한 데이터 손실 방지 처리
## 1. 버그 내용
- **현상**: 세션 타임아웃이 발생한 상태에서 사용자가 메모를 저장하려고 하면 API 호출이 실패(401 Unauthorized)하고 로그인 페이지로 리다이렉트됨. 이 과정에서 사용자가 입력한 메모 내용이 보존되지 않고 소실되는 문제 발생.
- **원인**: 세션 타임아웃이 하드코딩(1시간)되어 있어 사용자가 인지하기 어렵고, 프론트엔드에서 세션 만료를 사전에 감지하는 로직이 부재함.
## 2. 조치 사항
- **백엔드 (Flask)**:
- `config.json`을 통해 세션 타임아웃 시간을 분 단위로 설정 가능하도록 변경 (`session_timeout` 필드 추가).
- 보안 및 안정성을 위해 최소 타임아웃 시간을 **10분**으로 제한 (백엔드 강제 적용 로직 포함).
- `/api/auth/status` 엔드포인트를 추가하여 세션 유효 여부를 즉시 확인할 수 있게 함.
- 설정 저장 시 `PERMANENT_SESSION_LIFETIME` 설정을 즉시 업데이트하여 서버 재시작 없이 반영되도록 처리.
- **프론트엔드 (JavaScript/i18n)**:
- 환경설정 모달에 세션 타임아웃 입력 필드 추가.
- 10분 미만 입력 시 경고 알림 및 저장 방지 로직 추가.
- **Heartbeat 기능 구현**: `AppService.startSessionHeartbeat()`를 통해 2분 간격으로 세션 상태를 체크하고, 만료 시 즉시 로그인 페이지로 튕기게(Bounce) 처리하여 저장 시점에 당황하는 상황을 방지함.
- 설정 관련 모든 API 호출을 `API.request`로 통합하여 공통 인증 처리를 수행함.
## 3. 향후 주의사항
- 세션 타임아웃 설정은 브라우저 쿠키의 생명주기와 관련이 있으므로, 설정을 변경한 직후에는 세션이 즉시 갱신되지 않을 수 있음(기존 쿠키 만료까지 대기). 설정 변경 후에는 가급적 로그아웃 후 재로그인을 권장함.
- Heartbeat 주기를 너무 짧게 설정할 경우 서버 트래픽이 증가할 수 있으므로, 현재 최소 타임아웃(10분)의 1/5 수준인 2분으로 유지함.
+18
View File
@@ -0,0 +1,18 @@
# [FEAT] 세션 타임아웃 카운트다운 타이머 구현
## 버그/기능 내용
- 세션이 소리 소문 없이 만료되어 작업 중인 내용이 저장되지 않는 문제를 방지하기 위해, 로그아웃 버튼에 실시간 남은 세션 시간을 표시하는 기능을 추가함.
- 버튼 크기 비대화를 방지하기 위해 "로그아웃" 텍스트를 "종료"(KO) / "EXIT"(EN)로 축약함.
## 조치 사항
1. **로케일 수정**: `static/locales/ko.json`, `en.json`에서 `nav_logout` 값을 축약형으로 변경.
2. **신규 컴포넌트**: `static/js/components/SessionManager.js` 생성.
- 서버 설정(`/api/settings`)의 `session_timeout` 값을 초 단위로 변환하여 관리.
- 1초마다 카운트다운을 수행하고 로그아웃 버튼의 텍스트(`span.text`)를 업데이트.
3. **사용자 활동 감지**: `mousedown`, `keydown`, `touchstart` 이벤트 발생 시 타이머를 원래 설정값으로 리셋.
4. **자동 로그아웃**: 카운트가 `00:00`에 도달하면 알림 표시 후 `/logout`으로 리다이렉트.
5. **통합**: `static/app.js`에서 초기화 코드 추가.
## 향후 주의 사항
- `I18nManager.applyTranslations()`가 실행될 때 `data-i18n` 속성에 의해 타이머 텍스트가 덮어씌워질 수 있으나, `SessionManager`가 1초 단위로 다시 그리므로 시각적 문제는 미미함.
- 브라우저 탭이 비활성 상태(Background)일 때 `setInterval`의 작동 주기가 느려질 수 있으나, 다시 포커스를 얻으면 실제 시간 흐름을 보정하거나 활동 시 리셋되므로 사용성에는 큰 문제가 없음.
+23
View File
@@ -0,0 +1,23 @@
# 프로젝트 추가 모듈화 및 리팩토링 계획
`memo.py` 모듈화 이후, 코드 품질 향상 및 유지보수성 확보를 위해 추가적으로 개선이 필요한 영역을 분석한 결과입니다.
## 📋 추가 모듈화 검토 대상 리스트
| 대상 영역 | 파일 위치 | 현재 상태 (Lines) | 문제점 및 개선 방향 | 우선순위 |
| :--- | :--- | :--- | :--- | :--- |
| **백엔드 코어** | `app/__init__.py` | 121 lines | `create_app` 함수에 보안, 로깅, CSP 설정이 집중됨. `app/core/`로 분리 필요. | **높음** |
| **프론트엔드 UI** | `static/js/ui.js` | 331 lines | 모든 UI 이벤트 및 렌더링이 집중된 God Object. 레이아웃과 렌더링 로직 분리 필요. | **높음** |
| **DB 스키마** | `app/database.py` | 88 lines | 연결 로직과 테이블 정의가 혼재됨. SQL 파일이나 전용 클래스로 스키마 관리 분리. | 보통 |
| **명령어 엔진** | `static/js/components/SlashCommand.js` | 352 lines | 명령어 데이터와 UI 제어 로직이 섞여 있음. 데이터 중심 구조로 개편 필요. | 보통 |
| **파일 서비스** | `app/routes/file.py` | 162 lines | `memo.py`처럼 Route에 로직이 포함됨. `FileService` 계층 신설 고려. | 보통 |
| **에디터 관리** | `static/js/editor.js` | 215 lines | Toast UI 설정과 커스텀 기능이 얽혀 있음. 플러그인 인터페이스 도입 필요. | 낮음 |
## 🛠️ 향후 작업 권고 단계
1. **1단계 (Core)**: `app/__init__.py`에서 로깅 및 보안 설정을 분리하여 서버 초기화 가독성 확보.
2. **2단계 (UI)**: `ui.js``layout.js``memos.js` 등으로 분리하여 프론트엔드 관리 효율화.
3. **3단계 (Data)**: `database.py` 내의 하드코딩된 스키마를 모델 정의 파일로 이동.
---
*작성일: 2026-04-20*