포트폴리오 ↗
개인 프로젝트›데스크톱 앱1 / 7

Ledger오프라인 고정비 · 저축 가계부

·읽는 시간 약 8분
종류데스크톱 앱
스택
electronreacttypescriptvitewindows
GitHubMINI_Ledger ↗
목차 6개 단원
  1. ·서론
  2. 01왜 만들었나
  3. 02구조 및 아키텍처
  4. 03핵심 구현 디테일
  5. 04화면으로 보는 기능
  6. 05한계 · 설치 · 사용 흐름

서론

월세, 관리비, 통신비, 구독, 보험, 적금처럼 매달 정해진 날 빠져나가는 돈은 가계부 앱에 넣기엔 너무 반복적이고, 엑셀로 관리하기엔 “이번 달엔 뭐가 나가고 언제 나가는지”가 한눈에 안 보였습니다. 은행 · 카드 연동도 필요 없고, 내 PC에서만 가볍게 열어 보는 고정비 전용 장부가 있으면 좋겠다 싶어서 만들었습니다.

Ledger는 Windows Electron + React + Vite + TypeScript 기반의 오프라인 고정비 · 저축 가계부입니다. 항목을 주기별로 등록하고 세트로 묶어 달마다 적용하면, 이번 달 총액 · 수입 대비 · 남는 돈과 결제 일정을 한 화면에서 보여 줍니다. 데이터는 서버 없이 %APPDATA%의 JSON 파일 하나에만 저장됩니다.

Ledger 개요 화면 — 이번 달 총액, 수입 흐름, 날짜 눈금, 분류, 결제 리듬

1. 왜 만들었나

  • 고정비만 따로: 변동 지출까지 기록하는 가계부는 오래 못 썼습니다. 매달 반복되는 돈만 정확히 보고 싶었습니다.
  • 달마다 다른 구성: 이사, 약정 종료, 구독 해지처럼 달에 따라 나가는 항목이 바뀝니다. 그래서 항목을 세트로 묶고, 세트를 달마다 켜고 끄는 구조로 만들었습니다.
  • 저축은 지출과 다르게: 적금 · 청약은 매달 빠져나가지만 쓰는 돈이 아닙니다. 총액에는 넣되 고정 지출과 저축 · 투자를 나눠 보고 싶었습니다.
  • 오프라인 · 내 PC만: 금융 정보라 서버나 계정 없이 로컬 파일 하나로 끝나길 바랐습니다. 대신 파일이 깨지거나 날아가지 않게 저장만큼은 안전하게 만들었습니다.

2. 구조 및 아키텍처

Electron main이 JSON 저장소와 파일 대화상자를 맡고, renderer(React)는 window.ledger 브리지로만 데이터를 읽고 씁니다. 정규화 · 마이그레이션 · 세트 규칙은 src/ledgerData.ts에 두고 main의 저장소와 브라우저 목업이 같은 코드를 씁니다.

text
MINI_Ledger/
┣━━ 📂 electron/
┃   ┣━━ main.ts                 # 창 · IPC · 내보내기/가져오기 · 확인 대화상자
┃   ┣━━ preload.ts              # window.ledger / windowControls 브리지
┃   ┗━━ store.ts                # JSON 저장소 (원자적 쓰기 · .bak · 날짜별 백업)
┣━━ 📂 src/
┃   ┣━━ Overview.tsx            # 개요
┃   ┣━━ LedgerPage.tsx          # 장부 (작업대 · 세트 · 월 적용)
┃   ┣━━ IncomePage.tsx          # 수입 · 월별 흐름 차트
┃   ┣━━ 📂 overview/            # 날짜 눈금 · 분류 · 결제 리듬 · 다가오는 결제
┃   ┣━━ 📂 ledger/              # 입력 폼 · 납부 시점 선택 · 세트 작업대 훅
┃   ┣━━ schedule.ts             # 주기별 납부일 · 월 합계 · 지출/저축 집계
┃   ┣━━ ledgerData.ts           # 정규화 · 마이그레이션 · 세트 규칙 (store와 공용)
┃   ┗━━ devMock.ts              # 브라우저 개발용 샘플 데이터
┗━━ 📄 package.json

장부 파일 하나에 네 가지가 들어갑니다.

text
ledger.json
┣━━ items        # 항목: 이름 · 금액 · 주기 · 납부일/요일/월 · 분류 · 메모
┣━━ sets         # 세트: 이름 · 항목 id 목록
┣━━ assignments  # "2026-10" → 그 달에 적용된 항목 id 목록
┗━━ income       # 기본 월수입 + 달별 덮어쓰기

데이터 흐름은 대략 다음과 같습니다.

text
React UI ──window.ledger.*──▶ preload ──ipcRenderer.invoke──▶ main (store.ts)
store.ts ──read → 정규화(ledgerData) → 수정 → .bak · 백업 → 원자적 쓰기──▶ ledger.json
브라우저(Vite만) ──window.ledger 없음──▶ devMock (같은 ledgerData 규칙, 메모리 샘플)

3. 핵심 구현 디테일

① 주기 → 그 달의 납부일

schedule.ts의 occurrencesInMonth가 항목 하나를 그 달에 실제로 나가는 날짜 목록으로 바꿉니다. 매월은 납부일(말일 보정), 매주는 그 달의 해당 요일 전부, 분기는 3 · 6 · 9 · 12월처럼 기준 월에서 3개월 간격, 연간은 지정한 달 하나, 매일은 그 달 전체입니다. 그래서 같은 매주 항목도 달에 따라 4번 또는 5번 잡히고, 개요의 합계 · 날짜 눈금 · 다가오는 결제가 모두 이 목록에서 나옵니다. 장부 표의 Amount / mo는 비교용 월 환산 금액입니다.

② 세트와 월 적용

항목은 반드시 하나 이상의 세트에 들어가고, 세트를 달마다 켜면 그 달의 assignments에 항목 id가 들어갑니다. 적용한 달만 개요 · 수입 합계에 반영됩니다.

동작 규칙
세트 켜기 세트 항목을 그 달 목록에 추가
세트 끄기 다른 세트가 그 달에 완전히 적용돼 있고 그 항목도 갖고 있으면 남김
세트 구성 변경 이미 적용된 달에 새 항목을 넣고, 빠진 항목은 위 규칙대로 정리
세트 삭제 그 세트에만 있던 항목은 함께 삭제 (확인 창에서 개수 안내)
세트 없는 항목 가져오기 · 옛 데이터에서 생기면 기본 / 미저장 세트로 묶음

③ 고정 지출 · 저축 · 투자 분리

분류는 두 묶음으로 나뉩니다. 저축 · 투자 · 연금 · 청약은 저축으로, 대출 · 헌금 · 가족 용돈을 포함한 나머지는 고정 지출로 셉니다. 개요의 큰 숫자는 둘을 합친 이번 달 총액이고, 옆 막대가 수입을 고정 지출 / 저축 · 투자 / 남는 돈으로 나눠 보여 줍니다. 분류 도넛은 고정 지출만, 분류 목록은 두 묶음을 나눠 보여 줍니다.

④ 안전한 저장

로컬 파일 하나가 전부라, 저장이 실패해도 데이터가 사라지지 않게 하는 데 신경을 썼습니다.

장치 내용
원자적 쓰기 임시 파일에 쓰고 fsync 후 rename으로 교체 — 쓰다가 꺼져도 반쯤 쓴 파일이 남지 않음
직전본 저장할 때마다 이전 내용을 ledger.json.bak으로
날짜별 백업 그날 첫 저장 전 상태를 backups/ledger-YYYY-MM-DD.json으로, 최근 14개 유지
손상 파일 읽을 수 없으면 ledger.corrupt-<시각>.json으로 보관하고 이후 저장을 막음 (빈 장부로 덮어쓰지 않음)
시작 시 복구 본 파일이 깨졌고 .bak이 정상이면 .bak으로 복구
가져오기 막힌 상태에서도 Import로 장부를 통째로 바꿔 복구, 가져오기 창은 백업 폴더에서 열림

⑤ 브라우저 목업으로 개발

npm run dev는 Vite와 Electron을 같이 띄우지만, 화면 작업은 브라우저에서 하는 게 빠릅니다. Vite 개발 모드에서 window.ledger가 없으면 devMock.ts가 샘플 항목 · 세트 · 수입을 메모리에 만들어 같은 API를 흉내 냅니다. 세트 규칙은 ledgerData.ts를 그대로 써서 목업과 실제 저장소가 같은 결과를 냅니다. 이 글의 스크린샷도 모두 이 샘플 데이터입니다.

4. 화면으로 보는 기능

4.1 이번 달 총액 · 수입 흐름

개요 상단 — 이번 달 총액, 수입 대비, 남는 돈, 수입이 나가는 곳 막대
  • Monthly total: 고정 지출 + 저축 · 투자를 합친 이번 달 총액. 화살표로 다른 달로 이동합니다.
  • 수입 대비 · 남는 돈 · 적용 항목: 그 달 수입 기준 비율과 남는 금액.
  • Where income goes: 수입을 고정 지출 / 저축 · 투자(저축률) / 남는 돈으로 나눈 막대.

4.2 날짜 눈금

날짜 눈금 — 지난 결제와 남은 결제, 오늘 표시
  • Passed / Remaining: 오늘 기준 이미 나간 금액과 남은 금액.
  • 점 크기 = 금액: 같은 날은 위로 쌓이고, 저축 항목은 파란 점입니다. 점에 올리면 이름 · 금액 · 주기.
  • 매일 결제: 눈금에 찍지 않고 합계에만 넣습니다.

4.3 분류

분류 — 고정 지출 도넛과 묶음별 분류 목록
  • Spending share: 고정 지출만 분류별 도넛으로. 조각에 올리면 그 분류의 항목들이 보입니다.
  • By category: 고정 지출과 저축 · 투자를 나눠 분류별 금액 · 비율.

4.4 결제 리듬 · 다가오는 결제

결제 리듬 주간 막대와 다가오는 결제 목록
  • Payment rhythm: 주차별 결제 금액, 다음 7일 · 이번 달 남은 결제 · 결제가 몰린 날.
  • Upcoming: 이번 달 남은 결제와 다음 달 첫 주. 매일 결제는 기간 · 횟수 · 합계 한 줄로 묶습니다.

4.5 장부 작업대

장부 — 세트 수정 중 작업대 표, 이름 · 분류 · 주기 · 월 환산 금액
  • 작업대: 새로 추가한 항목이나 수정 중인 세트의 항목을 표로 보고 정렬 · 수정 · 삭제합니다.
  • 월 환산: 주간 · 분기 · 연간 항목도 Amount / mo로 비교하고, 아래에 실제 금액과 납부 시점을 함께 씁니다.

4.6 항목 입력 · 분류

항목 입력 폼과 분류 선택 — 저축 · 투자 분류는 파란 표시
  • 입력: 이름 · 금액 · 주기 · 납부 시점(날짜 / 요일 / 월) · 분류 · 메모.
  • 분류: 고정 지출 분류가 먼저, 저축 · 투자 · 연금 · 청약은 파란 표시로 따로 모여 있습니다.

4.7 세트 · 월 적용

세트 선택 — 월별 적용 칸, 세트 항목, 묶음별 월 금액
  • 월 칸 클릭: 그 달에 세트를 켜고 끕니다. 개요 · 수입에 바로 반영됩니다.
  • 세트 요약: 항목 수와 고정 지출 · 저축 · 투자의 월 환산 금액.
  • 수정 / 삭제: 수정은 항목을 작업대로 불러오고, 삭제는 함께 지워질 항목 수를 확인 창으로 알려 줍니다.

4.8 수입

수입 — 달별 수입 칸, 연간 합계, 월별 흐름 차트와 툴팁
  • 기본 월수입 + 달별 덮어쓰기: 다른 달만 칸을 눌러 금액을 바꿉니다 (점 표시).
  • 달별 막대: 수입 대비 고정 지출 · 저축 비율. 세트를 적용하지 않은 달은 세트 미적용.
  • 연간 합계: 수입 · 고정 지출 · 저축 · 투자(저축률) · 남는 돈 — 적용한 달만 셉니다.
  • Monthly flow: 수입 · 고정 지출 · 저축 · 투자 · 남는 돈 선 그래프, 달에 올리면 상세.

5. 한계 · 설치 · 사용 흐름

한계 (중요)

  • 고정비 장부입니다. 카드 · 은행 내역 연동이나 변동 지출 기록은 없습니다.
  • 세트를 적용한 달만 합계에 들어갑니다. 새 달이 되면 장부에서 세트를 켜 줘야 합니다.
  • 저장소는 이 PC 한 곳입니다. 동기화가 없고 백업도 같은 디스크에 남으니, 다른 곳에 두려면 Export를 쓰세요.
  • Windows 기준으로 빌드 · 확인했습니다. 코드 사이닝이 없어 SmartScreen 경고가 날 수 있습니다.

사전 요구

항목 설명
OS Windows 10 / 11
Node.js 개발 · 빌드용

설치 · 실행

bash
git clone https://github.com/Hyeonseok93/MINI_Ledger.git
cd MINI_Ledger
npm install
npm run dev

실행 파일 빌드: npm run build:exe → release/win-unpacked/Ledger.exe. 폴더 전체를 배포하세요. .exe만 복사하면 Electron 런타임이 없어 실행되지 않습니다.

저장 경로: %APPDATA%/ledger/store/ (ledger.json, ledger.json.bak, backups/).

사용 흐름

  1. 장부에서 고정비 · 저축 항목을 주기 · 납부 시점 · 분류와 함께 추가합니다.
  2. 작업대 항목을 이름 붙여 세트로 저장합니다.
  3. 세트를 눌러 적용할 달을 켭니다.
  4. 수입에서 기본 월수입과 다른 달 금액을 맞춥니다.
  5. 개요에서 이번 달 총액 · 남는 돈 · 남은 결제를 확인합니다.
  6. 가끔 Export로 장부를 다른 곳에 보관합니다.
데스크톱 앱개인 프로젝트 · 7개 중 1번째프로젝트 전체 →
  1. Ledger오프라인 고정비 · 저축 가계부
  2. NetSentinelWindows 개인용 네트워크 모니터
  3. Repeat Music Player트랙별 개별 반복 재생 & 통합 오디오 병합 유틸리티
  4. Monitor Coordinate System모니터 절대 좌표, 픽셀 거리 & 각도 측정 유틸리티
  5. Image Zoomer픽셀 이미지 뷰어 & 정밀 확대 유틸리티
  6. Image Converter다중 포맷 일괄 이미지 변환 & 품질 최적화 유틸리티
  7. Color Picker정사각형 돋보기 & 다중 포맷 컬러 픽커 유틸리티