# Slim Budget — 백엔드 (sb_bt) Spring Boot 기반의 가계부·게시판 REST API 서버. ## 기술 스택 - **Spring Boot 3.5** / **Java 17** - **MyBatis** (XML 매퍼) + **MariaDB** - **Redis** (세션 저장) - **spring-security-crypto** (BCrypt 비밀번호 해시) - Lombok, Bean Validation ## 패키지 구조 ``` com.sb.web ├── account # 가계부 (controller / service / mapper / domain / dto) ├── auth # 인증 (로그인/세션, AuthInterceptor) ├── board # 게시판 ├── user # 사용자 ├── admin # 관리자 (태그 카테고리, 게시판 설정) └── common # 공통 (예외, 응답, 설정) ``` ## 스키마 자동 초기화 `spring.sql.init.schema-locations` 로 기동 시 적용 (멱등 — `CREATE TABLE IF NOT EXISTS`, `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`): ``` classpath:db/member.sql, db/board.sql, db/account.sql, db/dev-seed.sql ``` 주요 테이블: `member`, `wallet`, `account_entry`, `account_tag`, `account_entry_tag`, `account_category`, `budget`, `recurring`, `invest_holding`, `invest_trade`, `post`, `comment`, `tag`, `tag_category` 등. ## 인증 / 보안 - 로그인 시 토큰 발급, 이후 `Authorization: Bearer ` 로 인증 - `AuthInterceptor` 가 현재 사용자(`SessionUser`)를 요청 속성(`CURRENT_MEMBER`)으로 주입 - **모든 가계부 데이터는 `member_id`(소유자)로 격리** — 본인 데이터만 조회/수정 - DB 자격증명 등은 `.env`(gitignore)로 관리, `.env.example` 템플릿 제공 ## REST API 개요 ### 인증 · 사용자 · 관리자 - `POST /api/auth/login` 외 인증 엔드포인트 - `/api/users` — 사용자 관리 - `/api/admin/**` — 태그 카테고리·게시판 설정(관리자) - `/api/board/**` — 게시판(글/댓글/태그/열람제한) ### 가계부 `/api/account` | 메서드·경로 | 설명 | |---|---| | `GET/POST/PUT/DELETE /entries` | 내역 CRUD. 조회 필터: `year,month,type,category,walletId,keyword,tagId` | | `GET /summary` `GET /stats` | 월 요약 / 기간 버킷(일·주·월·년) 수입·지출 | | `GET /category-stats` | 분류별 합계 (파이차트) | | `GET/POST/PUT/DELETE /wallets` | 계좌/카드/대출/투자(BANK·CARD·LOAN·INVEST) | | `GET /networth` `GET /networth/trend` | 순자산 / 월별 순자산 추이 | | `GET /wallets/{id}/entries` `POST /repayment` | 계좌별 내역 / 상환·납부(원금=이체, 이자=지출) | | `GET/POST/PUT/DELETE /tags` | 사용자별 가계부 태그 | | `/api/account/categories` (+`/import`) | 분류 CRUD, 기존 내역에서 가져오기 | | `/api/account/budgets` (+`/status`,`/period`) | 예산 CRUD, 진행률, 기간별 | | `/api/account/recurrings` (+`/run`) | 정기 거래 규칙, 밀린 회차 자동 생성 | | `/api/account/invest/**` | 투자 포트폴리오(아래) | ### 잔액 · 순자산 모델 - 부호 모델: 자산(+) / 부채(−) - 지갑 잔액 = 개시잔액 + 수입 − 지출 − 이체출금 + 이체입금 (`WalletMapper.findBalances`) - 순자산 = Σ자산 − Σ부채. 투자계좌는 **예수금 + 주식 평가금액**으로 반영 - 순자산 추이: 현금흐름 누적(이체는 상쇄) + 투자 손익은 현재 시점에 가산 ### 정기 거래 (recurring) - 빈도(DAILY/WEEKLY/MONTHLY/YEARLY) + 일/요일/월 지정 - `last_run_date` 커서로 **중복 없이** 밀린 회차를 따라잡아 `account_entry` 생성 ### 투자 포트폴리오 (`/api/account/invest`) — 종목 단위(C) | 경로 | 설명 | |---|---| | `GET/POST/PUT/DELETE /holdings` | 보유 종목 (종목명·코드·현재가). 집계: 수량·평단·평가금액·평가손익·수익률·실현손익 | | `GET/POST /holdings/{id}/trades`, `DELETE /trades/{id}` | 매수/매도 이력 | - 매매이력(시간순)으로 **이동평균 평단**·실현손익·평가손익 산출 - 매수 시 평단 재계산 `(기존수량×평단 + 매수수량×단가 + 수수료)/총수량`, 매도 시 실현손익 = (매도가 − 평단)×수량 − 수수료 - 매도수량이 보유수량 초과 시 400 반환 - 투자계좌 가치 = 예수금(현금 ± 매매) + 주식평가, 순자산/추이에 연동 - 원화·정수 수량 기준 (해외주식 소수점/환율·자동 시세는 범위 외) ## 개발/실행 ```bash cp .env.example .env # DB/Redis 자격증명 입력 ./gradlew bootRun # http://localhost:8080 ```