Files
sb-front/docs/release-2026-06-06.md
T
2026-06-28 00:12:59 +09:00

223 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Slim Budget — 변경 내역 (2026-06-06 배포)
이번 작업 세션에서 추가·수정한 기능 정리. (프론트 `sb_pt`, 백엔드 `sb_bt`, 안드로이드 앱 포함)
---
## 1. 홈 대시보드
- **일별 수입·지출 캘린더** 추가 (예산 대비 지출 아래). 날짜를 **탭하면 그 날의 내역을 팝업(모달)으로** 표시(시인성 개선·단일 탭 동작).
## 2. 투자 / 계좌
- **시세 자동조회**: 종목코드(6자리)로 네이버 금융에서 현재가 자동 갱신. 투자 탭 진입·포트폴리오 펼침 시 자동, "↻ 시세 갱신" 버튼도 제공.
- **퇴직연금·연금 등 평가액 직접입력형 계좌**: 종목 없이 현재 평가액만 입력해 관리(누적 적립원금 대비 손익% 표시).
- 보유 종목 표기 2줄 정리(수량 / 평단·현재가).
- **계좌번호 암호화**: DB에 AES-256-GCM으로 저장(키는 서버 `.env` `ACCOUNT_CRYPTO_KEY`). 화면에서는 **끝 4자리만 노출 + 👁 전체보기 토글**로 마스킹.
## 3. 가계부 내역 / 고정 지출
- "정기 거래" → **"고정 지출"** 명칭 변경, 월간/년간 분리·카테고리 소계/합계.
- 내역·고정지출 추가 시 계좌 종류 **라디오 + 셀렉트** 패턴, 저장 버튼 sticky.
## 4. 카드 결제 알림 자동인식 (버그 수정)
- **현금으로 잘못 선택되던 문제**: 알림 자동인식(pending) 건은 매칭 실패해도 계좌 종류를 **'카드'로 기본 선택**. 백엔드 카드 매칭을 양방향 부분일치(`KB국민↔국민`) + 카드가 1개뿐이면 자동 매칭으로 개선.
- **광고 푸시 오인식 차단**: 강한 승인신호(승인/출금/취소/환불) 없이 광고성 표현(이벤트·할인·적립·포인트·캐시백·쿠폰 등)이 있으면 결제로 보지 않음. 네이티브 1차 필터에서 '카드' 키워드 제거.
- 확인(확정) 실패 시 **HTTP 상태코드 노출** + 즉시 UI 반영.
## 5. 게시판
- "자유게시판" → **커뮤니티 / 짠테크 수다방 / 재테크 팁** 3개 게시판으로 분리(카테고리).
- 사이드바를 **가계부 / 게시판 / 관리자 영역 구분선**으로 정리.
- 글 번호 컬럼 미노출.
## 6. 회원가입 / 인증
- **이용약관·개인정보 수집 동의**(필수 체크) 추가.
- **관리자 회원가입 제한 토글**: 회원 관리 화면에서 신규 가입 on/off. 제한 시 가입 진입(랜딩·로그인·가입 팝업)부터 차단.
- **봇 가입 차단**: 허니팟(숨김 필드) + IP 레이트리밋(Redis, 1시간 5회). *Cloudflare Turnstile은 앱 환경 제약으로 제외.*
- **모바일 웹 새로고침 시 로그아웃 버그 수정**: 세션 복원을 localStorage 우선으로(Preferences 예외에 견고).
- **세션 유실(주기적 로그아웃) 해결**: Redis AOF 활성화로 재시작에도 세션 영속(서버 설정).
## 7. 웹 접근 정책
- **PC·모바일 웹은 안내 페이지만** 노출(앱 다운로드 안내). 실제 이용은 **앱(Capacitor)에서만**. 개발 모드(`npm run dev`)는 예외로 전체 앱 표시.
---
# (이어진 작업) 앱 UX · 보안 · 품질 강화
## 8. 앱 하단 내비게이션
- 화면 **하단 고정 아이콘 바**(뒤로 · 앞으로 · 홈 · 새로고침 · 설정). 스크롤과 무관하게 항상 노출, **안드로이드 소프트키 위** 안전영역에 배치.
- 사이드바의 '홈' 메뉴 제거(하단 내비로 대체). 로그인 전에는 햄버거 메뉴·네이버 로그인 버튼 숨김.
## 9. 설정 / 계정정보
- **설정 화면**(하단 내비 → 설정): 계정정보 · 앱 버전(`v1.0.0`) · **App Data 삭제**(로그인/캐시 초기화 후 재시작).
- **계정정보 상세 → 정보변경**: 비밀번호 재인증 후 **이름 · 이메일 · 비밀번호를 한 화면에서** 변경. 헤더의 비밀번호 변경 아이콘·모달은 제거(진입점 일원화).
- **로그인 후 대시보드(`/`)로 이동** 통일.
## 10. 투자 매매내역
- 종목별 매매이력을 **인라인 최근 5건 + "전체 N건 보기" 스크롤 모달**로 정리(길어짐 방지).
- **매매 수정 기능** 추가(`PUT /api/account/invest/trades/{id}`). 수정 시 시점별 시뮬레이션으로 **보유수량 음수 방지** 검증.
## 11. 보안 / 인증 (백엔드)
- **세션 DB 이중 저장**(`auth_session`): Redis 유실·재시작에도 로그인 유지(Redis 미스 시 DB에서 복원·재수화).
- **무차별 대입 방지**: 실패한 시도만 카운트 — 로그인 IP당 10회/10분, 비밀번호 재인증 회원당 5회/10분 초과 시 429.
- **인터셉터 보호 경로 누락 수정**: `verify-password`·`profile`이 인증 없이 500 나던 문제 → 401 정상화.
- **전역 예외 처리 강화**: 미처리 500 로그에 메서드+경로 기록(추적성), 잘못된 JSON은 400.
## 12. 품질 / 배포 파이프라인
- **자동화 테스트 도입**: 프론트 **Vitest 32**(스토어·API·로그인 플로우), 백엔드 **JUnit 34**(단위 + `@WebMvcTest` 통합).
- **테스트 게이트**: CI와 **배포 워크플로 모두 테스트 실패 시 배포 중단**. 백엔드 배포에 CI와 동일한 MariaDB/Redis 서비스 추가.
- 번들: 마크다운 에디터는 라우트 지연 청크임을 명시(경고 한도 현실화).
## 13. 안드로이드
- 에지투에지(`targetSdk 36`) 대응: **콘텐츠 루트에 시스템 바 인셋 패딩** 적용 → 헤더는 상태바 아래, 하단 내비는 소프트키 위.
## 14. PC 데스크톱 클라이언트 (Electron)
- **Windows 설치형 `.exe`** — 번들 dist 대신 **라이브 사이트(app.sblog.kr) 직접 로드** → 프론트 변경이 **재설치 없이** 앱 재시작만으로 반영. 시작 시 `clearCache()`로 옛 HTML 캐시 방지.
- 창 크기/위치/최대화 상태 **기억**(다음 실행 복원). 로그인 전 빈 사이드바 숨김(콘텐츠 중앙 정렬).
- 웹 안내페이지에 **PC 버전 다운로드 링크**(`/download/SlimBudget-Setup.exe`).
- ⚠️ 게시판 위지윅 에디터는 **Windows IME 첫 자음 중복**(tui.editor 업스트림 버그) — PC에선 감수(일반 입력칸은 정상).
## 15. 브랜드 앱 아이콘
- 기본 Capacitor 아이콘 → **브랜드(초록 #00bc7e + 흰 막대 차트) 적응형 아이콘**(전 해상도, `@capacitor/assets`).
## 16. 홈 캘린더 · 계좌 · 카드
- **홈 일별 캘린더**: 하단 인라인 패널 → **탭 시 팝업(모달)** 표시(시인성·단일 탭).
- **계좌 이용내역 월별 표시**: 계좌 펼치면 `◀ YYYY.MM ▶` + 그 달 합계, 데이터 있는 달만 이동(긴 스크롤 해소).
- **카드 알림 계좌 자동매칭 유연화**: 카드사 표기 차이 흡수(`KB/국민/국민카드/KB카드`, `농협/NH`, `비씨/BC`, `씨티/시티`) — 어떻게 등록해도 매칭.
## 17. 게시판 이미지 / 에디터
- **인라인 이미지 = base64 → 서버 업로드(DB 저장)**: `POST /api/board/images`(로그인) → `GET /api/images/{id}`(공개). **절대 URL** 반환(앱은 출처가 localhost 라 상대경로 불가). 업로드 전 1280px·JPEG 압축.
- **에디터 이미지 버튼**: Toast UI 기본 팝업 제거 → 클릭 시 **바로 파일선택→업로드**(작은 댓글창에서 팝업 OK 잘림 회피).
- **모바일 에디터 팝업(표·링크 등)**: 화면 **중앙 모달**로(Toast UI 의 `margin-left:-150px` 로 좌측 잘리던 문제 해결).
---
# (이어진 작업 2) 알림 분류 · 투자 · 상환 (2026-06-12)
## 18. 투자 계좌 단순화 (종목 관리 제거)
- 투자 계좌를 **퇴직연금식으로 통일**: 종목(매수·매도·현재가) 관리 UI 제거, **투자금(투입원금) + 현재 평가액**만 입력 → 손익·수익률 자동 계산. (위 2번의 시세 자동조회·보유 종목 표기는 본 변경으로 대체)
- 계좌 펼침: **투자금 / 평가액 / 손익(%)** 요약 카드. 투자 탭 진입 시 자동 시세갱신 제거(불필요).
## 19. 알림 자동인식 — 입금·출금 분류
- 카드: **승인=지출 / 취소·환불=수입**, 은행: **입금=수입 / 출금·이체=지출** 로 정리(은행 이체 알림이 지출로만 잡히던 문제 해결). 네이티브 1차 필터에 입금/이체/송금 키워드 추가.
- 미확인(pending) 기본 계좌종류: 수입(입금)=은행, 지출(카드결제)=카드.
## 20. 광고 푸시·문자 오등록 차단 강화
- 기존 광고 차단이 **죽은 코드**(강신호가 이미 보장된 지점이라 한 번도 실행 안 됨)였던 것 수정 → 승인/입금 신호가 있으면 광고어가 섞여도 등록되던 원인 제거.
- 광고어 2단계 분리:
- **무조건 차단**(이벤트·쿠폰·혜택·당첨·응모·프로모션·배너·세일·수신거부·바로가기 등): 거래신호가 있어도 제외.
- **약한 광고어**(적립·포인트·할인·캐시백·마일리지 등): `결제`만 있고 명확한 거래신호(승인/입출금/취소)가 **없을 때만** 제외 → 실거래 영수증의 '포인트 적립'은 보존. `결제`는 광고 문구에도 흔해 **약신호로 강등**.
## 21. 자동인식 분류 학습
- 알림 자동등록 시 **메모(가맹점) 키워드가 과거 확정 내역과 일치하면 그 분류를 자동 선반영**(가장 많이 쓴 분류, `스타벅스``스타벅스 강남점` 포함관계 매칭, 같은 수입/지출만). 안전상 **'확인 필요' 상태는 유지**(무검토 오확정 방지) — 확정이 쌓일수록 정확도 상승.
## 22. 상환/납부 수정 가능
- '상환/납부'(원금=이체 · 이자=지출 분리)를 **신규 등록뿐 아니라 수정 시에도** 선택 가능. 수정 시 상환 2건 생성 후 원본 1건 삭제(생성 성공 후 삭제 → 중간 실패 시 원본 보존). 잘못 넣은 단순 이체/지출을 **원금·이자 분리 상환으로 정정** 가능.
---
# (이어진 작업 3) 현금 계좌 · 통계 · 가계부 UX (2026-06-22)
## 23. 상환/납부 — 연회비(카드)
- 카드 상환 시 **연회비**도 분리 입력(대상이 카드일 때만 노출). 원금=이체 · 이자=지출(분류 '이자') · **연회비=지출(분류 '연회비')**. 대출엔 연회비 입력 불가.
## 24. 현금 계좌
- **계좌 관리에 '현금' 유형 추가**(이름·초기 잔액만). 순자산 계산에 **자산으로 합산**(BANK와 동일 취급).
- **가계부 입력**: 현금 선택 시 등록된 현금 계좌를 고를 수 있고, 없으면 종전처럼 '미지정'으로 기록(하위호환).
- **이체에도 현금 지원**: 출금/입금 종류에 현금 포함 → **ATM 출금(은행→현금)·현금 입금(현금→은행)** 등 현금 계좌 이체 가능. 중복되던 별도 '현금' 라디오 제거(일반 계좌 종류로 통합).
## 25. 고정 지출 — '확인 필요(pending)'로 생성
- 자동 생성되는 고정지출 내역을 **'확인 필요'**로 만들어, 실제 결제·이체를 확인한 뒤 **'확인'으로 확정**(카드 알림과 동일 흐름). 메모 없으면 제목으로 채워 식별 쉽게. → "실제 처리 여부"를 사용자가 판단 가능.
## 26. 가계부 내역 → 고정지출 바로 등록
- 내역 **수정 모달에 「🔁 이 내역을 고정지출로 등록」** 버튼. 현재 항목의 종류·금액·분류·메모·계좌로 **매월** 고정지출 생성(일자=내역 날짜, 시작=다음날로 이번 회차 중복 방지). 주기는 고정지출 화면에서 변경.
## 27. 통계 — 순자산 추이 주간화
- 순자산 추이를 **최근 3개월·주간(월요일 기준 13주)**으로 변경. 백엔드 `weeklyWalletFlow` + `netWorthTrendWeekly` 추가, `/networth/trend?unit=WEEK&weeks=N`. x축 라벨은 격주 표기(겹침 방지).
## 28. 통계 — 이번달 예상 지출(월말 추정)
- 대시보드 '수입 대비 지출'에 **예상 지출** 표시: `현재까지 지출 ÷ 경과일 × 그 달 총일수`(run-rate). 이번 달에만 표시, 예산 대비 %도 함께.
## 29. 통계 — 지난달 대비 이번달 지출
- 같은 패널에 **「지난달 대비」** 행: `±차액 (±%)`(늘면 빨강·줄면 초록), 기준 '지난달 N원' 표기. 선택 월 기준으로 직전 달과 비교.
## 30. 가계부 — 날짜별 접기/펴기
- 내역이 많을 때를 위해 **날짜 그룹 접기/펴기**. 기본은 **접힘 + 오늘만 펼침**(날짜 요약 = 날짜·건수·일 합계), 헤더 탭으로 개별 토글, 상단 **「모두 펴기/접기」** 토글. 월 이동 시 초기화, 내역 편집 시엔 펼침 상태 유지.
## 31. 앱(안드로이드) — 키보드가 입력폼 가리던 문제
- 에지투에지 환경에서 **IME(키보드) 인셋을 콘텐츠 패딩에 반영** → 키보드가 뜨면 WebView가 키보드 위로 줄어들어 입력 모달이 가려지지 않음(`windowSoftInputMode=adjustResize` + 인셋 리스너). 모든 모달 입력 공통.
## 32. 계좌 관리 — 탭 한 줄
- 계좌 종류 탭(은행/현금/카드/대출/투자)이 두 줄로 줄바꿈되던 것 → **한 줄(넘치면 가로 스크롤)**. 버튼 글자 줄바꿈 방지.
## 33. 분류 — 대분류/소분류(2단계)
- **분류를 대분류 아래 소분류로 묶기**(2단계). `account_category.parent_id` 추가(멱등 마이그레이션). 기존 분류는 모두 대분류로 시작 → 분류 관리에서 소분류로 재배치.
- **소분류 이름 기반 유지**(내역·예산·고정지출·통계 무변경) — 같은 소분류 이름 중복은 불가, 예산·통계는 **소분류 기준**.
- 분류 관리: 행별 대분류 선택·소분류 들여쓰기, 드래그 정렬 유지. 자식 있는 대분류는 소분류화·삭제 차단.
- 입력/예산/고정지출 드롭다운: **대분류 optgroup** 그룹핑(값은 소분류명).
- 대시보드 통계: 파이는 소분류 기준 + 아래 **대분류 합계** 롤업 표시.
---
# (이어진 작업 4) 구글 로그인 · 다크모드 · UI 개편 (2026-06-28)
## 34. 구글 로그인/가입 (소셜 로그인)
- **웹/PC/앱 3플랫폼 구글 로그인**: 웹·PC(Electron)는 **Google Identity Services(GIS)** ID 토큰, 앱(안드로이드)은 **네이티브 플러그인 `@capawesome/capacitor-google-sign-in`**(Credential Manager). 모두 ID 토큰을 백엔드 `POST /api/auth/google` 로 전달 → **tokeninfo 로 검증(aud=웹 클라이언트 ID)** 후 세션 발급.
- **PC(Electron) 팝업 수정**: `accounts.google.com` 팝업을 외부 브라우저로 보내 결과가 안 돌아오던 문제 → **앱 내부 자식 창**으로 열어 opener 로 credential 전달.
- **같은 이메일 자동 연결**: 구글 로그인 시 `member.google_id`(신규 컬럼)로 조회, 없으면 **검증된 동일 이메일의 기존 계정에 연결**(provider 유지 → 아이디 로그인/프로필 편집 보존), 그래도 없으면 신규 생성.
- 설정 필요: Google Cloud **웹 + Android OAuth 클라이언트**(패키지 `kr.sblog.slimbudget` + 서명 SHA-1), 서버 `.env` `GOOGLE_CLIENT_ID`.
## 35. 구글 전용 로그인 (아이디 로그인/회원가입 숨김)
- `src/config/features.js` `ID_LOGIN_ENABLED=false` 플래그로 **아이디/비번 폼·회원가입 UI 숨김**(로그인 모달·홈 랜딩). 백엔드 `/auth/login`·`/signup` 은 비상용으로 유지(복구 가능).
## 36. 브랜딩 — 돈돼지 가계부
- 앱/파비콘/PC 아이콘을 **돈돼지(투명 배경)** 로 교체, 헤더 로고·런처 라벨 정리. 런처 라벨 `돈돼지가계부`(한 줄), 앱 표시명 `돈돼지 가계부`.
## 37. PC 설치파일 (Electron)
- 산출물명 `SlimBudget-Setup.exe`**`DonDwaeji-Setup.exe`**, 다운로드 URL `/download/DonDwaeji-Setup.exe`.
- **사용자 폴더 설치**(`%LOCALAPPDATA%\Programs\DonDwaeji`, `build/installer.nsh`)로 변경 → **관리자 권한(UAC) 프롬프트 제거**. (게시자 미서명 경고/SmartScreen 은 인증서 없이는 잔존)
## 38. 게시판 공지 기능 (관리자)
- `post.notice` 컬럼(멱등 ALTER), 목록 **정렬 `notice DESC, id DESC`(공지 최상단)**, 목록·상세 **공지 배지**.
- 공지 설정은 **글 작성/수정 시 체크박스**로 일원화(커뮤니티+관리자). 상세의 공지 토글 버튼 제거, **목록 이동 아이콘** 추가.
## 39. 라이트/다크 테마
- 설정 화면에 **시스템 / 라이트 / 다크** 선택. `base.css`**`data-theme` 기반 수동 다크 + 시스템 폴백**으로 전환, `theme.js` 유틸 + ui 스토어 상태, `main.js` 시작 시 즉시 적용(깜빡임 방지).
## 40. 사이드바/헤더 개편 · 레이아웃 정리
- 사이드바 상단에 **돼지 로고 + '돈돼지 가계부'**(메뉴 텍스트 대체), 사이드바 **메뉴 아이콘**(lucide) 추가. **헤더는 현재 화면 타이틀** 표시(돼지 로고 제거).
- **PC 레이아웃**: 그리드 `'left top'` → 사이드바가 **좌측 상단(헤더 행)까지** 차지, 헤더는 우측 콘텐츠 영역만.
- **화면 내 페이지 타이틀(`<h1>`) 제거 → 헤더로 일원화**, **화면 내 뒤로가기 버튼 제거**(하단 내비 뒤로가기만 유지).
- **전 화면 본문 폭 통일**: `--page-max`(760px) + `.layout-body > *` 전역 규칙(뷰별 제각각 max-width 대체).
## 41. 화면별 액션 아이콘 위치 정리
- 가계부/예산 **month-nav**: 좌 spacer + 우 액션으로 **월 변경은 가운데, 추가·검색/필터는 우측**. 고정지출: 안내문구 아래. 커뮤니티 글쓰기: 태그 필터와 같은 줄. 분류: 지출/수입 탭과 같은 줄.
- **커뮤니티 검색 모달**: input `min-width:0` 으로 **검색 버튼이 모달 밖으로 밀리던 문제** 수정.
## 42. 자주 쓰는 내역 UX 정리
- 등록 모달의 **'자주 쓰는 내역 불러오기' 버튼·피커 모달 제거**(번거로운 3단계 해소, 저장 기능은 유지). 가계부 quick-bar 에 **'⭐ 자주 쓰는 내역' 라벨** 추가.
- 빠른등록(`useQuick`) **등록 성공과 목록 갱신 분리** — 갱신 오류가 '등록 실패'로 오인되던 케이스 방지.
## 43. 계정정보 단순화 · 구글 계정 이름 변경
- 계정정보에서 **아이디·가입유형 행 제거**(이름/이메일/권한만). **소셜(구글) 계정도 비밀번호 재인증 없이 이름만 변경** 가능(ProfileEdit), 백엔드 `updateProfile` 그대로.
## 44. PC 화면 해상도 변경
- Electron **preload(`window.desktop`) + IPC(`window:setSize`)** 추가, 설정 화면(PC)에 **창 크기 프리셋**(1024×720 ~ 1920×1080). 선택 크기는 Electron 창 상태 저장으로 다음 실행에도 유지.
## 45. 기타
- 통계 '분류별 지출/수입'을 **대분류 기준 집계**(소분류 펼침 제거로 스크롤 단축).
- 게시판 작성일: 1시간 이내 'N분 전' / 1일 이내 'N시간 전' / 그 이상 **`YYYY.MM.DD`**.
- 웹 안내 페이지 한국어 줄바꿈 **절(어절) 단위**(`word-break: keep-all` + inline-block 묶음).
---
## 운영 반영 시 체크
- 서버 `/opt/sb-backend/.env`
- `ACCOUNT_CRYPTO_KEY` — 계좌번호 암호화를 켤 때만(미설정 시 평문, 깨지지 않음).
- `GOOGLE_CLIENT_ID` — 구글 로그인 웹 클라이언트 ID(미설정 시 구글 버튼 미노출). **앱 구글 로그인**은 Google Cloud 에 **Android OAuth 클라이언트**(패키지 `kr.sblog.slimbudget` + 서명 SHA-1) 등록 필요.
- `member.google_id`(계정 연결) · `post.notice`(공지) 컬럼 — 기동 시 **멱등 ALTER** 자동 적용.
- `app_setting` · `auth_session` · `board_image` 테이블 — 배포 시 `member.sql`/`board.sql` 초기화로 자동 생성(가입 허용 / 세션 DB 백업 / 게시글 이미지).
- Redis `appendonly yes` — 세션 영속(이미 적용). 단, 세션 DB 이중 저장으로 Redis 유실에도 로그인 유지.
- 서버 `.env`/환경변수 `PUBLIC_URL`(기본 `https://app.sblog.kr`) — 업로드 이미지 절대 URL 베이스(앱에서 이미지 로드에 필요).
- **nginx**(`deploy/nginx-sb-front.conf` 참고): `location /``Cache-Control no-cache`(진입 HTML 최신화), `location /download/``/var/www/sb-downloads`(설치파일, 배포에 안 지워지는 영속 경로).
- 앱 버전 표기는 `package.json``version`(현재 `1.0.0`)을 단일 출처로 사용.
- **PC 설치파일**: `npm run electron:build``release-desktop/DonDwaeji-Setup.exe`(**사용자 폴더 설치=UAC 없음**, 미서명 → SmartScreen 경고 정상). 서버는 `/var/www/sb-downloads/DonDwaeji-Setup.exe` 로 업로드.
- 배포는 `main` 푸시 → CI·Deploy 워크플로 모두 **테스트 통과해야 진행**(Gitea Actions).