κ°λ¨ν κ°μΈ μ¬λ¬΄ κ΄λ¦¬ μΉ μ ν리μΌμ΄μ . React + Spring Boot + μλ² λλ H2 κΈ°λ°, Docker Composeλ‘ λ°°ν¬.
- λ μ§, κΈμ‘, μΉ΄ν κ³ λ¦¬, νκ·Έ, λ©λͺ¨, κ³ μ λΉ μ¬λΆλ₯Ό ν¬ν¨ν κ±°λ κΈ°λ‘
- λ€μ€ ν΅ν μ§μ (KRW, USD, EUR, JPY) β μν νμ° κΈμ‘ μλ μ μ₯
- μΉ΄ν κ³ λ¦¬ κ΄λ¦¬ (μμ μ§μ κ°λ₯)
- νκ·Έ μμ€ν (κ±°λλΉ μ¬λ¬ νκ·Έ, μμ μ§μ κ°λ₯)
- κΈ°κ°λ³, μ νλ³, μΉ΄ν κ³ λ¦¬λ³, νκ·Έλ³ νν°λ§
- μλ³ μΆμ΄ μ°¨νΈ: μμ /μ§μΆ λΌμΈ μ°¨νΈ (ν΄λ¦νμ¬ μ μ ν)
- μλ³ μΊλ¦°λ: μΌλ³ μμ /μ§μΆ ννΈλ§΅, νΈλ² μ μμΈ ν΄ν
- μΉ΄ν κ³ λ¦¬λ³ λΆμ: νμ΄ μ°¨νΈ
- νκ·Έλ³ λΆμ: λ° μ°¨νΈ
- Top κ±°λ: μμ 5건 μμ /μ§μΆ ν μ΄λΈ
- κ³ μ λΉ: λμ μ μΆμ‘ μ€νΈλ¦½ μμ κΊΎμμ + μ νν λ¬μ κ³ μ λΉ μ 체 λͺ©λ‘
- μλ² λλ H2 νμΌ λͺ¨λλ‘ μμ μ μ₯ (Docker λ³Όλ₯¨
cashlog-data) - λ³λ DB 컨ν μ΄λΒ·μ격μ¦λͺ λΆνμ
- CSV, Excel, PDF λ΄λ³΄λ΄κΈ°
- νκ΅μ΄ / English μ§μ
- λΌμ΄νΈ / λ€ν¬ ν λ§
| κΈ°μ | λ²μ |
|---|---|
| React | 18 |
| TypeScript | 5.3 |
| Vite | 5 |
| Tailwind CSS | 3.4 |
| Zustand | 4.5 |
| Chart.js | 4.4 |
| React Router | 6.22 |
| Nginx | Alpine (λ°°ν¬) |
| κΈ°μ | λ²μ |
|---|---|
| Java | 21 |
| Spring Boot | 3.2.2 |
| Spring Data JPA | - |
| Flyway | - |
| Apache POI | Excel λ΄λ³΄λ΄κΈ° |
| OpenCSV | CSV λ΄λ³΄λ΄κΈ° |
| iText 8 | PDF λ΄λ³΄λ΄κΈ° |
| SpringDoc OpenAPI | API λ¬Έμ |
| κΈ°μ | λ²μ |
|---|---|
| H2 (μλ² λλ) | 2.2 |
| Docker Compose | - |
| Nginx | Alpine |
cash-log/
βββ apps/
β βββ backend/ # Spring Boot REST API
β β βββ src/main/java/ # Controller, Service, Repository, Entity, DTO
β β βββ src/main/resources/ # application.yml, Flyway migrations
β β βββ Dockerfile
β β βββ pom.xml
β βββ frontend/ # React SPA
β βββ src/
β β βββ pages/ # DashboardPage, TransactionsPage, SettingsPage
β β βββ components/ # UI μ»΄ν¬λνΈ, μ°¨νΈ, λͺ¨λ¬
β β βββ lib/ # API ν΄λΌμ΄μΈνΈ, Zustand μ€ν μ΄, i18n
β β βββ types/ # TypeScript νμ
μ μ
β βββ nginx.conf
β βββ Dockerfile
βββ infrastructure/
β βββ scripts/ # μ΄μ μ€ν¬λ¦½νΈ (MySQLβH2 λ°μ΄ν° μ΄κ΄ λ±)
βββ docker-compose.yml # μ 체 μ€ν λ°°ν¬
βββ .env.example
- Docker Desktop 20.10+
- νκ²½ λ³μ μ€μ
cp .env.example .env
# .env νμΌμ νΈμ§νμ¬ λΉλ°λ²νΈ μ€μ - μ 체 μ€ν μ€ν
docker compose up --build -d- μ μ
- μΉ μ±: http://localhost
- API λ¬Έμ: http://localhost/swagger-ui/index.html
κ°λ° μμλ νλ‘ νΈμλμ λ°±μλλ₯Ό λ³λλ‘ μ€νν©λλ€. λ³λ DB 컨ν μ΄λλ νμνμ§ μμ΅λλ€.
- λ°±μλ μ€ν
cd apps/backend
./mvnw spring-boot:run # apps/backend/data/ μ H2 νμΌ μμ±
# λλ λ§€λ² μ΄κΈ°νλλ μΈλ©λͺ¨λ¦¬ DBλ‘ μ€ν
SPRING_PROFILES_ACTIVE=demo ./mvnw spring-boot:rundev νλ‘νλ‘ μ€ννλ©΄ H2 μ½μμ http://localhost:8080/h2-console μμ μ¬μ©ν μ μμ΅λλ€.
- νλ‘ νΈμλ μ€ν
cd apps/frontend
npm install
npm run dev- νλ‘ νΈμλ: http://localhost:5173
- λ°±μλ API: http://localhost:8080
- API λ¬Έμ: http://localhost:8080/swagger-ui.html
| 리μμ€ | λ©μλ | κ²½λ‘ | μ€λͺ |
|---|---|---|---|
| κ±°λ | POST | /api/transactions |
κ±°λ μμ± |
| GET | /api/transactions |
κ±°λ λͺ©λ‘ (λ μ§ νν° μ§μ) | |
| GET | /api/transactions/{id} |
κ±°λ μμΈ | |
| PUT | /api/transactions/{id} |
κ±°λ μμ | |
| DELETE | /api/transactions/{id} |
κ±°λ μμ | |
| μΉ΄ν κ³ λ¦¬ | GET/POST/PUT/DELETE | /api/categories |
CRUD |
| νκ·Έ | GET/POST/PUT/DELETE | /api/tags |
CRUD |
| λ΄λ³΄λ΄κΈ° | GET | /api/export/csv |
CSV λ€μ΄λ‘λ |
| GET | /api/export/excel |
Excel λ€μ΄λ‘λ | |
| GET | /api/export/pdf |
PDF λ€μ΄λ‘λ | |
| λΆμ | GET | /api/analytics/monthly-summary |
μλ³ μμ½ |
| μΈμ | GET/PUT | /api/session/{key} |
μ¬μ©μ μ€μ |
# λ°±μλ ν
μ€νΈ
cd apps/backend
./mvnw test
# νλ‘ νΈμλ ν
μ€νΈ
cd apps/frontend
npm testβββββββββββββββ ββββββββββββββββββββββββββββ
β Nginx ββββββΆβ Spring Boot β
β (port 80) β β (port 8080) β
β + React β β REST API + μλ² λλ H2 β
β SPA β β (νμΌ λͺ¨λ, /data) β
βββββββββββββββ ββββββββββββββββββββββββββββ
frontend backend
- Nginxκ° μ μ νμΌ(React SPA)μ μλΉνκ³ ,
/api/μμ²μ λ°±μλλ‘ νλ‘μ - λ°±μλλ Docker λ€νΈμν¬ λ΄λΆμμλ§ μ κ·Ό κ°λ₯ (νΈμ€νΈμ ν¬νΈ λ ΈμΆ μ ν¨)
- H2 λ°μ΄ν°λ² μ΄μ€ νμΌμ Docker λ³Όλ₯¨(
cashlog-data)μ μμ μ μ₯λλ©°, DB 컨ν μ΄λμ μ격μ¦λͺ μ΄ νμνμ§ μμ SPRING_PROFILES_ACTIVE=demoλ‘ μ€ννλ©΄ μΈλ©λͺ¨λ¦¬ H2λ₯Ό μ¬μ©ν΄ μ¬κΈ°λλ§λ€ μ΄κΈ°νλ¨ (λ°λͺ¨μ©)
H2 λ°μ΄ν°λ λ³Όλ₯¨ νλμ λͺ¨μ¬ μμ΄ νμΌ λ³΅μ¬λ‘ λ°±μ ν μ μμ΅λλ€.
docker compose stop backend # νμΌ λͺ¨λλ λ°°ν λ½μ μ¬μ©νλ―λ‘ λ¨Όμ μ μ§
docker run --rm -v cashlog-data:/data -v "$PWD":/out alpine \
tar czf /out/cashlog-h2-$(date +%Y%m%d).tar.gz -C /data .
docker compose start backendMIT License β LICENSE μ°Έμ‘°.
