docs: Embedded Redis 반영 가이드 업데이트 + auth guard 경고 수정
- 설치가이드_OnPremise.pdf: Redis를 선택 사항으로 변경, Embedded Redis 안내 - 개발자가이드.pdf: Docker/Redis 필수 → 선택, Embedded Redis 자동 구동 안내 - 개발환경_사전설치_가이드.txt: Docker/Redis 섹션 Embedded Redis 기반으로 수정 - regenerate_pdfs.py: PDF 재생성 스크립트 추가 - auth.guard.ts: Vue Router deprecated next() 콜백 → return 방식으로 수정 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
이 Commit은 다음에 포함되어 있습니다:
바이너리 파일은 표시되지 않습니다.
바이너리 파일은 표시되지 않습니다.
372
wbx-spring-core/docs/regenerate_pdfs.py
일반 파일
372
wbx-spring-core/docs/regenerate_pdfs.py
일반 파일
@@ -0,0 +1,372 @@
|
|||||||
|
"""
|
||||||
|
WBX Spring Framework PDF 가이드 재생성 스크립트.
|
||||||
|
Docker/Redis → Embedded Redis 변경 사항 반영.
|
||||||
|
|
||||||
|
사용법: python regenerate_pdfs.py
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import copy
|
||||||
|
from PyPDF2 import PdfReader, PdfWriter
|
||||||
|
from fpdf import FPDF
|
||||||
|
|
||||||
|
DOCS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
FONT_PATH = r"C:\Windows\Fonts\malgun.ttf"
|
||||||
|
FONT_BOLD_PATH = r"C:\Windows\Fonts\malgunbd.ttf"
|
||||||
|
|
||||||
|
|
||||||
|
class KoreanPDF(FPDF):
|
||||||
|
"""Korean-capable PDF with consistent styling."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.add_font("malgun", "", FONT_PATH)
|
||||||
|
self.add_font("malgun", "B", FONT_BOLD_PATH)
|
||||||
|
self.set_auto_page_break(auto=True, margin=20)
|
||||||
|
|
||||||
|
def header_line(self, title):
|
||||||
|
self.set_font("malgun", "B", 9)
|
||||||
|
self.set_text_color(100, 100, 100)
|
||||||
|
self.cell(0, 6, title, ln=True)
|
||||||
|
self.set_draw_color(30, 60, 120)
|
||||||
|
self.set_line_width(0.5)
|
||||||
|
self.line(10, self.get_y(), 200, self.get_y())
|
||||||
|
self.ln(4)
|
||||||
|
|
||||||
|
def section_title(self, text):
|
||||||
|
self.set_font("malgun", "B", 14)
|
||||||
|
self.set_text_color(30, 60, 120)
|
||||||
|
self.cell(0, 10, text, ln=True)
|
||||||
|
self.ln(2)
|
||||||
|
|
||||||
|
def sub_title(self, text):
|
||||||
|
self.set_font("malgun", "B", 11)
|
||||||
|
self.set_text_color(40, 40, 40)
|
||||||
|
self.cell(0, 8, text, ln=True)
|
||||||
|
self.ln(1)
|
||||||
|
|
||||||
|
def body(self, text):
|
||||||
|
self.set_font("malgun", "", 10)
|
||||||
|
self.set_text_color(60, 60, 60)
|
||||||
|
self.multi_cell(0, 6, text)
|
||||||
|
self.ln(2)
|
||||||
|
|
||||||
|
def code_block(self, text):
|
||||||
|
self.set_fill_color(245, 245, 245)
|
||||||
|
self.set_font("malgun", "", 9)
|
||||||
|
self.set_text_color(40, 40, 40)
|
||||||
|
x = self.get_x()
|
||||||
|
self.set_x(x + 5)
|
||||||
|
self.multi_cell(180, 5.5, text, fill=True)
|
||||||
|
self.ln(3)
|
||||||
|
|
||||||
|
def bullet(self, text):
|
||||||
|
self.set_font("malgun", "", 10)
|
||||||
|
self.set_text_color(60, 60, 60)
|
||||||
|
x = self.get_x()
|
||||||
|
self.set_x(x + 5)
|
||||||
|
self.cell(5, 6, "\u2022")
|
||||||
|
self.multi_cell(170, 6, text)
|
||||||
|
|
||||||
|
def note_box(self, text):
|
||||||
|
self.set_fill_color(255, 248, 220)
|
||||||
|
self.set_draw_color(200, 180, 100)
|
||||||
|
self.set_font("malgun", "B", 9)
|
||||||
|
self.set_text_color(120, 90, 0)
|
||||||
|
y = self.get_y()
|
||||||
|
self.rect(12, y, 186, 20, style="DF")
|
||||||
|
self.set_xy(15, y + 3)
|
||||||
|
self.multi_cell(180, 5, text)
|
||||||
|
self.set_y(y + 23)
|
||||||
|
|
||||||
|
def page_number(self):
|
||||||
|
self.set_y(-15)
|
||||||
|
self.set_font("malgun", "", 8)
|
||||||
|
self.set_text_color(150, 150, 150)
|
||||||
|
self.cell(0, 10, f"- {self.page_no()} -", align="C")
|
||||||
|
|
||||||
|
|
||||||
|
def replace_pages(src_path, replacements, out_path):
|
||||||
|
"""Replace specific pages in a PDF with new fpdf2-generated pages.
|
||||||
|
|
||||||
|
replacements: dict of {page_index: fpdf_generation_function}
|
||||||
|
"""
|
||||||
|
reader = PdfReader(src_path)
|
||||||
|
writer = PdfWriter()
|
||||||
|
|
||||||
|
# Generate replacement pages
|
||||||
|
replacement_pages = {}
|
||||||
|
for page_idx, gen_func in replacements.items():
|
||||||
|
pdf = gen_func()
|
||||||
|
tmp = os.path.join(DOCS_DIR, f"_tmp_page_{page_idx}.pdf")
|
||||||
|
pdf.output(tmp)
|
||||||
|
tmp_reader = PdfReader(tmp)
|
||||||
|
replacement_pages[page_idx] = tmp_reader.pages[0]
|
||||||
|
|
||||||
|
# Build output
|
||||||
|
for i, page in enumerate(reader.pages):
|
||||||
|
if i in replacement_pages:
|
||||||
|
writer.add_page(replacement_pages[i])
|
||||||
|
else:
|
||||||
|
writer.add_page(page)
|
||||||
|
|
||||||
|
with open(out_path, "wb") as f:
|
||||||
|
writer.write(f)
|
||||||
|
|
||||||
|
# Cleanup temp files
|
||||||
|
for page_idx in replacements:
|
||||||
|
tmp = os.path.join(DOCS_DIR, f"_tmp_page_{page_idx}.pdf")
|
||||||
|
if os.path.exists(tmp):
|
||||||
|
os.remove(tmp)
|
||||||
|
|
||||||
|
print(f" [OK] {os.path.basename(out_path)}")
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 1. 설치가이드_OnPremise.pdf — Page 3 (requirements), Page 9 (Redis)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def onprem_page3():
|
||||||
|
"""Page 3: 사전 요구사항 - Redis를 선택으로 변경."""
|
||||||
|
pdf = KoreanPDF()
|
||||||
|
pdf.add_page()
|
||||||
|
pdf.header_line("WBX Spring Framework | On-Premise 설치 가이드")
|
||||||
|
pdf.section_title("1. 사전 요구사항 \u00b7 서버 사양")
|
||||||
|
|
||||||
|
pdf.sub_title("1-1. 최소 서버 사양")
|
||||||
|
pdf.body("항목 최소 사양 권장 사양\n"
|
||||||
|
"OS RHEL 8+ / Ubuntu 22.04+ RHEL 9 / Rocky Linux 9\n"
|
||||||
|
"CPU 4 vCPU 8 vCPU\n"
|
||||||
|
"RAM 8 GB 16 GB\n"
|
||||||
|
"Disk 50 GB SSD 100 GB SSD (RAID)\n"
|
||||||
|
"Network 1 Gbps 10 Gbps")
|
||||||
|
|
||||||
|
pdf.sub_title("1-2. 필수 소프트웨어")
|
||||||
|
pdf.body("소프트웨어 버전 용도\n"
|
||||||
|
"JDK 21 (Temurin LTS) Spring Boot 런타임\n"
|
||||||
|
"DB Oracle 19c+ 등 애플리케이션 데이터\n"
|
||||||
|
"Nginx 1.24+ 리버스 프록시, SSL")
|
||||||
|
|
||||||
|
pdf.sub_title("1-2b. 선택 소프트웨어")
|
||||||
|
pdf.body("소프트웨어 버전 용도\n"
|
||||||
|
"Redis 7.x 캐시 (미설치 시 Embedded Redis 자동 구동)")
|
||||||
|
pdf.note_box("NOTE: Redis를 별도 설치하지 않아도 WBX Spring에 내장된 Embedded Redis가\n"
|
||||||
|
"자동으로 시작됩니다. 운영 환경에서는 성능을 위해 외부 Redis 설치를 권장합니다.")
|
||||||
|
|
||||||
|
pdf.sub_title("1-3. 네트워크 포트")
|
||||||
|
pdf.body("포트 서비스 접근 범위 비고\n"
|
||||||
|
"443 HTTPS 외부 Nginx SSL\n"
|
||||||
|
"80 HTTP 외부->443 리다이렉트\n"
|
||||||
|
"8080 Spring Boot 내부 Nginx에서만 접근\n"
|
||||||
|
"8081 wtm-api 내부 WTM 프로젝트\n"
|
||||||
|
"3306 MySQL 내부 DB 선택에 따라\n"
|
||||||
|
"5432 PostgreSQL 내부 \n"
|
||||||
|
"1521 Oracle 내부 \n"
|
||||||
|
"1433 MSSQL 내부 \n"
|
||||||
|
"6379 Redis 내부 선택 (Embedded Redis 자동 대체)")
|
||||||
|
|
||||||
|
pdf.page_number()
|
||||||
|
return pdf
|
||||||
|
|
||||||
|
|
||||||
|
def onprem_page9():
|
||||||
|
"""Page 9: Redis 설치 섹션 재작성."""
|
||||||
|
pdf = KoreanPDF()
|
||||||
|
pdf.add_page()
|
||||||
|
pdf.header_line("WBX Spring Framework | On-Premise 설치 가이드")
|
||||||
|
pdf.section_title("5. Redis 설치 (선택)")
|
||||||
|
|
||||||
|
pdf.note_box("WBX Spring Framework에는 Embedded Redis가 내장되어 있어 별도 설치 없이도\n"
|
||||||
|
"앱이 정상 구동됩니다. 운영 환경에서 높은 성능이 필요한 경우에만 설치하세요.")
|
||||||
|
|
||||||
|
pdf.sub_title("5-1. Embedded Redis (기본 — 설치 불필요)")
|
||||||
|
pdf.body("앱 시작 시 다음 순서로 자동 동작합니다:")
|
||||||
|
pdf.bullet("외부 Redis 감지 시 -> 외부 Redis 사용 (운영 환경)")
|
||||||
|
pdf.bullet("외부 Redis 없음 -> Embedded Redis 자동 시작 (개발/소규모 운영)")
|
||||||
|
pdf.bullet("Embedded Redis 실패 -> 인메모리 캐시 전환 (최후 안전장치)")
|
||||||
|
pdf.ln(3)
|
||||||
|
|
||||||
|
pdf.sub_title("5-2. 외부 Redis 설치 (선택 — 대규모 운영 환경 권장)")
|
||||||
|
pdf.code_block(
|
||||||
|
"sudo dnf install -y redis\n"
|
||||||
|
"sudo systemctl enable --now redis\n\n"
|
||||||
|
"# 보안: bind + password\n"
|
||||||
|
"sudo sed -i 's/^bind .*/bind 127.0.0.1/' /etc/redis/redis.conf\n"
|
||||||
|
"echo 'requirepass RedisP@ss123' | sudo tee -a /etc/redis/redis.conf\n"
|
||||||
|
"sudo systemctl restart redis\n\n"
|
||||||
|
"# 확인\n"
|
||||||
|
"redis-cli -a RedisP@ss123 ping # PONG"
|
||||||
|
)
|
||||||
|
|
||||||
|
pdf.sub_title("5-3. .env 설정 (외부 Redis 사용 시)")
|
||||||
|
pdf.code_block(
|
||||||
|
"SPRING_DATA_REDIS_HOST=127.0.0.1\n"
|
||||||
|
"# 또는 원격 Redis 서버 주소\n"
|
||||||
|
"# SPRING_DATA_REDIS_HOST=redis.company.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
pdf.page_number()
|
||||||
|
return pdf
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 2. 개발자가이드.pdf — Page 3 (사전 준비), Page 4 (Docker Compose)
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def dev_page3():
|
||||||
|
"""Page 3: 개발환경 설정 - Docker/Redis 부분 수정."""
|
||||||
|
pdf = KoreanPDF()
|
||||||
|
pdf.add_page()
|
||||||
|
pdf.header_line("WBX Spring Framework | 개발자 가이드")
|
||||||
|
pdf.section_title("Chapter 0. 개발환경 설정 - IDE \u00b7 프로젝트 생성")
|
||||||
|
|
||||||
|
pdf.sub_title("0-1. 사전 준비")
|
||||||
|
pdf.bullet("JDK 21 설치 (Eclipse Temurin 권장)")
|
||||||
|
pdf.bullet("Git 설치 (git config user.name / user.email)")
|
||||||
|
pdf.bullet("Docker Desktop 설치 (선택 - 로컬 DB 컨테이너 사용 시에만)")
|
||||||
|
pdf.bullet("IDE 설치 (아래 택 1)")
|
||||||
|
pdf.ln(2)
|
||||||
|
|
||||||
|
pdf.note_box("NOTE: Redis는 Embedded Redis가 앱과 함께 자동 시작되므로 별도 설치가 필요\n"
|
||||||
|
"없습니다. Docker Desktop도 DB를 직접 설치하면 불필요합니다.")
|
||||||
|
|
||||||
|
pdf.sub_title("온보딩 플로우")
|
||||||
|
pdf.body("1) JDK 설치 -> 2) IDE 설정 -> 3) DB 준비 -> 4) 프로젝트 생성 -> 5) bootRun -> 6) Swagger 확인")
|
||||||
|
|
||||||
|
pdf.sub_title("0-2. IDE 선택 가이드")
|
||||||
|
pdf.body("IDE 권장 대상 핵심 장점\n"
|
||||||
|
"IntelliJ IDEA 메인 개발 Spring Boot 최적, 리팩터링, DB 브라우저\n"
|
||||||
|
"VS Code 경량/FE 병행 Extension Pack, DevContainer\n"
|
||||||
|
"Eclipse/STS 무료/레거시 Spring Tool Suite 플러그인")
|
||||||
|
|
||||||
|
pdf.sub_title("0-3. IntelliJ IDEA 필수 설정")
|
||||||
|
pdf.bullet("플러그인: Spring Boot, Lombok, JPA Buddy, GitToolBox, .env, SonarLint")
|
||||||
|
pdf.bullet("Annotation Processor 활성화 (Settings > Build > Compiler)")
|
||||||
|
pdf.bullet("Hot Reload: Build project automatically + Allow auto-make")
|
||||||
|
pdf.ln(1)
|
||||||
|
pdf.code_block(
|
||||||
|
"Run Configuration:\n"
|
||||||
|
" Main class: kr.co.accura.wbx.spring.WbxSpringCoreApplication\n"
|
||||||
|
" Env: JWT_SECRET=dev-secret-key"
|
||||||
|
)
|
||||||
|
|
||||||
|
pdf.sub_title("0-4. VS Code 필수 설정")
|
||||||
|
pdf.bullet("Extension: Java Pack, Spring Boot Pack, Lombok, Gradle, REST Client, GitLens")
|
||||||
|
pdf.bullet(".vscode/settings.json - Lombok, Gradle Wrapper, 포맷터 설정")
|
||||||
|
pdf.bullet(".vscode/launch.json - Spring Boot 디버깅 프로필 (local, test)")
|
||||||
|
|
||||||
|
pdf.page_number()
|
||||||
|
return pdf
|
||||||
|
|
||||||
|
|
||||||
|
def dev_page4():
|
||||||
|
"""Page 4: Docker Compose 및 프로젝트 생성 - Redis 부분 수정."""
|
||||||
|
pdf = KoreanPDF()
|
||||||
|
pdf.add_page()
|
||||||
|
pdf.header_line("WBX Spring Framework | 개발자 가이드")
|
||||||
|
|
||||||
|
pdf.code_block(
|
||||||
|
'// .vscode/launch.json\n'
|
||||||
|
'{\n'
|
||||||
|
' "type": "java",\n'
|
||||||
|
' "name": "App (Local)",\n'
|
||||||
|
' "mainClass": "kr.co.accura.wbx.spring.WbxSpringCoreApplication",\n'
|
||||||
|
' "env": {"JWT_SECRET": "dev-secret-key"}\n'
|
||||||
|
'}'
|
||||||
|
)
|
||||||
|
|
||||||
|
pdf.sub_title("0-5. Eclipse / STS 설정")
|
||||||
|
pdf.bullet("Spring Tools 4 플러그인 설치 (Eclipse Marketplace)")
|
||||||
|
pdf.bullet("Lombok 설치: java -jar lombok.jar -> Eclipse 경로 선택")
|
||||||
|
pdf.bullet("Gradle Import: File > Import > Existing Gradle Project")
|
||||||
|
pdf.bullet("Annotation Processor: Project Properties > Java Compiler 에서 활성화")
|
||||||
|
pdf.ln(2)
|
||||||
|
|
||||||
|
pdf.sub_title("0-6. 프로젝트 생성 (3가지 방법)")
|
||||||
|
pdf.body("방법 A: Spring Initializr (start.spring.io)")
|
||||||
|
pdf.code_block("Project: Gradle-Kotlin | Java: 21 | Boot: 3.5.0\n"
|
||||||
|
"Group: kr.co.accura | Artifact: {앱}-api\n"
|
||||||
|
"-> Generate -> 압축 해제 -> wbx-spring-starter 의존성 추가")
|
||||||
|
pdf.body("방법 B: Git Template Repository")
|
||||||
|
pdf.code_block("git clone https://git.wbx.kr/accura/wbx-spring-template.git my-app\n"
|
||||||
|
"cd my-app && ./init.sh --name my-app --group kr.co.accura")
|
||||||
|
|
||||||
|
pdf.sub_title("0-7. 설치 스크립트 (권장)")
|
||||||
|
pdf.body("프로젝트에 포함된 설치 스크립트가 JDK 자동 설치, Git 사전 검사, 빌드, .env 템플릿 생성을 자동 처리합니다.")
|
||||||
|
pdf.code_block("# Windows\nscripts\\install.bat\n\n# Linux/macOS\nchmod +x scripts/install.sh && ./scripts/install.sh")
|
||||||
|
pdf.body("TIP: JDK 미설치 시 스크립트가 자동으로 설치합니다.")
|
||||||
|
|
||||||
|
pdf.sub_title("0-8. 로컬 개발 인프라")
|
||||||
|
pdf.body("Redis는 Embedded Redis가 앱 시작 시 자동 구동되므로 별도 설치가 필요 없습니다.\n"
|
||||||
|
"DB만 Docker Compose 또는 직접 설치하면 됩니다.")
|
||||||
|
pdf.code_block("# Docker로 DB만 시작 (Redis 불필요)\n"
|
||||||
|
"docker compose -f docker-compose-dev.yml up -d mysql\n\n"
|
||||||
|
"# 또는 DB를 직접 설치한 경우 바로 앱 실행\n"
|
||||||
|
"gradlew.bat bootRun")
|
||||||
|
pdf.note_box("Embedded Redis 동작: 앱 시작 시 외부 Redis 감지 -> 없으면 자동 시작 -> 실패 시 인메모리 캐시")
|
||||||
|
|
||||||
|
pdf.page_number()
|
||||||
|
return pdf
|
||||||
|
|
||||||
|
|
||||||
|
def dev_page5():
|
||||||
|
"""Page 5: DevContainer + 코드 품질 도구 - Redis 부분 수정."""
|
||||||
|
pdf = KoreanPDF()
|
||||||
|
pdf.add_page()
|
||||||
|
pdf.header_line("WBX Spring Framework | 개발자 가이드")
|
||||||
|
|
||||||
|
pdf.sub_title("0-9. DevContainer (VS Code)")
|
||||||
|
pdf.body("devcontainer.json 으로 JDK 21 + DB가 포함된 완전한 개발 환경을 컨테이너로 제공합니다.\n"
|
||||||
|
"Redis는 Embedded Redis가 자동 구동되므로 DevContainer에 별도 포함하지 않아도 됩니다.\n"
|
||||||
|
"팀원 전체 동일 환경 보장.")
|
||||||
|
|
||||||
|
pdf.sub_title("0-10. 코드 품질 도구")
|
||||||
|
pdf.bullet("Spotless - 코드 포맷 자동화 (./gradlew spotlessApply)")
|
||||||
|
pdf.bullet("CheckStyle - 코드 규칙 검사")
|
||||||
|
pdf.bullet("JaCoCo - 테스트 커버리지 (최소 70%)")
|
||||||
|
pdf.bullet("SonarLint - IDE 실시간 코드 분석")
|
||||||
|
pdf.bullet(".editorconfig - IDE 공통 코드 스타일 (UTF-8, LF, 4 spaces)")
|
||||||
|
|
||||||
|
pdf.page_number()
|
||||||
|
return pdf
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Main
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("WBX Spring Framework PDF 가이드 재생성")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# 1. 설치가이드_OnPremise.pdf
|
||||||
|
print("\n[1] 설치가이드_OnPremise.pdf")
|
||||||
|
src = os.path.join(DOCS_DIR, "WBX_Spring_Framework_설치가이드_OnPremise.pdf")
|
||||||
|
out = os.path.join(DOCS_DIR, "WBX_Spring_Framework_설치가이드_OnPremise.pdf")
|
||||||
|
replace_pages(src, {
|
||||||
|
2: onprem_page3, # Page 3: 사전 요구사항 (Redis 선택으로)
|
||||||
|
8: onprem_page9, # Page 9: Redis 설치 (Embedded Redis 안내)
|
||||||
|
}, out)
|
||||||
|
|
||||||
|
# 2. 설치가이드_Cloud.pdf — 변경 없음 (클라우드 관리형 Redis 사용)
|
||||||
|
print("\n[2] 설치가이드_Cloud.pdf")
|
||||||
|
print(" [SKIP] 클라우드 환경은 관리형 Redis(Azure Cache/ElastiCache) 사용 - 변경 불필요")
|
||||||
|
|
||||||
|
# 3. 개발자가이드.pdf
|
||||||
|
print("\n[3] 개발자가이드.pdf")
|
||||||
|
src = os.path.join(DOCS_DIR, "WBX_Spring_Framework_개발자가이드.pdf")
|
||||||
|
out = os.path.join(DOCS_DIR, "WBX_Spring_Framework_개발자가이드.pdf")
|
||||||
|
replace_pages(src, {
|
||||||
|
2: dev_page3, # Page 3: 사전 준비 (Docker/Redis 선택)
|
||||||
|
3: dev_page4, # Page 4: Docker Compose (Redis 불필요)
|
||||||
|
4: dev_page5, # Page 5: DevContainer (Redis 제외)
|
||||||
|
}, out)
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("완료! 변경된 PDF:")
|
||||||
|
print(" - WBX_Spring_Framework_설치가이드_OnPremise.pdf (Page 3, 9)")
|
||||||
|
print(" - WBX_Spring_Framework_개발자가이드.pdf (Page 3, 4, 5)")
|
||||||
|
print(" - WBX_Spring_Framework_설치가이드_Cloud.pdf (변경 없음)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -81,9 +81,10 @@
|
|||||||
2. 선택 소프트웨어 (권장)
|
2. 선택 소프트웨어 (권장)
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
[2-1] Docker Desktop
|
[2-1] Docker Desktop (선택 — DB 컨테이너 사용 시에만 필요)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
용도: 로컬 개발용 DB(MySQL/PostgreSQL) + Redis를 컨테이너로 실행
|
용도: 로컬 개발용 DB(MySQL/PostgreSQL)를 컨테이너로 실행
|
||||||
|
※ Redis는 Embedded Redis가 자동 구동되므로 Docker 불필요
|
||||||
|
|
||||||
* Windows
|
* Windows
|
||||||
winget install --id Docker.DockerDesktop
|
winget install --id Docker.DockerDesktop
|
||||||
@@ -119,19 +120,19 @@
|
|||||||
GRANT ALL ON mos.* TO 'jsh'@'%';
|
GRANT ALL ON mos.* TO 'jsh'@'%';
|
||||||
|
|
||||||
|
|
||||||
[2-3] Redis
|
[2-3] Redis (설치 불필요)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
용도: 캐시, 세션 저장소
|
용도: 캐시, 세션 저장소
|
||||||
|
|
||||||
* Windows (Docker 권장, 네이티브 미지원)
|
※ WBX Spring Framework에 Embedded Redis가 내장되어 있어 별도 설치가
|
||||||
docker run -d -p 6379:6379 redis:7-alpine
|
필요하지 않습니다. 앱 시작 시 다음 순서로 자동 동작합니다:
|
||||||
|
|
||||||
* macOS
|
1) 외부 Redis 감지 → 그대로 사용 (운영 환경)
|
||||||
brew install redis && brew services start redis
|
2) 외부 Redis 없음 → Embedded Redis 자동 시작 (개발 환경)
|
||||||
|
3) Embedded Redis 실패 → 인메모리 캐시 전환 (최후 안전장치)
|
||||||
|
|
||||||
* Linux
|
운영 환경에서 외부 Redis를 사용하려면 .env에 설정:
|
||||||
sudo apt install -y redis-server (Ubuntu)
|
SPRING_DATA_REDIS_HOST=redis.company.com
|
||||||
sudo yum install -y redis (RHEL)
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@@ -151,7 +152,7 @@
|
|||||||
scripts\install.bat (Windows)
|
scripts\install.bat (Windows)
|
||||||
./scripts/install.sh (Linux/macOS)
|
./scripts/install.sh (Linux/macOS)
|
||||||
|
|
||||||
# 3) Docker로 MySQL + Redis 시작
|
# 3) Docker로 MySQL 시작 (Redis는 Embedded Redis 자동 구동)
|
||||||
docker compose -f docker-compose-dev.yml up -d
|
docker compose -f docker-compose-dev.yml up -d
|
||||||
|
|
||||||
# 4) .env 파일 수정 (DB 비밀번호를 docker-compose 설정에 맞춤)
|
# 4) .env 파일 수정 (DB 비밀번호를 docker-compose 설정에 맞춤)
|
||||||
@@ -185,13 +186,11 @@
|
|||||||
|
|
||||||
# 3) MySQL/PostgreSQL 설치 후 DB 생성
|
# 3) MySQL/PostgreSQL 설치 후 DB 생성
|
||||||
# 위 [2-2] 참고
|
# 위 [2-2] 참고
|
||||||
|
# (Redis는 Embedded Redis 자동 구동 — 설치 불필요)
|
||||||
|
|
||||||
# 4) Redis 설치
|
# 4) .env 파일을 실제 DB 정보에 맞게 수정
|
||||||
# 위 [2-3] 참고
|
|
||||||
|
|
||||||
# 5) .env 파일을 실제 DB 정보에 맞게 수정
|
# 5~6) 앱 실행 및 확인 (위와 동일)
|
||||||
|
|
||||||
# 6~7) 앱 실행 및 확인 (위와 동일)
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@@ -206,7 +205,7 @@
|
|||||||
| MySQL 8.0 | 3306 | jsh | PW: jsh@ (기본 프로필) |
|
| MySQL 8.0 | 3306 | jsh | PW: jsh@ (기본 프로필) |
|
||||||
| | | | root PW: rootpassword |
|
| | | | root PW: rootpassword |
|
||||||
| PostgreSQL 16 | 5432 | jsh | PW: jsh@ (--profile pg) |
|
| PostgreSQL 16 | 5432 | jsh | PW: jsh@ (--profile pg) |
|
||||||
| Redis 7 | 6379 | - | 인증 없음 (개발용) |
|
| Redis 7 | 6379 | - | Embedded Redis 자동 구동 |
|
||||||
+------------------+--------+----------+------------------------------+
|
+------------------+--------+----------+------------------------------+
|
||||||
|
|
||||||
프로필별 실행:
|
프로필별 실행:
|
||||||
@@ -250,7 +249,7 @@
|
|||||||
| 8081 | wtm-api | WTM API, Admin, Swagger |
|
| 8081 | wtm-api | WTM API, Admin, Swagger |
|
||||||
| 3306 | MySQL | 기본 DB (mysql 프로필) |
|
| 3306 | MySQL | 기본 DB (mysql 프로필) |
|
||||||
| 5432 | PostgreSQL | 대안 DB (postgresql 프로필) |
|
| 5432 | PostgreSQL | 대안 DB (postgresql 프로필) |
|
||||||
| 6379 | Redis | 캐시, 세션 |
|
| 6379 | Redis | Embedded Redis 자동 구동 (별도 설치 불필요)|
|
||||||
| 5173 | wtm-frontend | Vue 3 개발 서버 |
|
| 5173 | wtm-frontend | Vue 3 개발 서버 |
|
||||||
| 8001 | WBX FastAPI | 선택, 그룹웨어 동시 운영 시 |
|
| 8001 | WBX FastAPI | 선택, 그룹웨어 동시 운영 시 |
|
||||||
+--------+------------------+------------------------------------------+
|
+--------+------------------+------------------------------------------+
|
||||||
@@ -273,9 +272,10 @@
|
|||||||
2) .env 파일의 DB_HOST, DB_PORT, DB_PASS 확인
|
2) .env 파일의 DB_HOST, DB_PORT, DB_PASS 확인
|
||||||
3) telnet localhost 3306 으로 연결 가능 여부 확인
|
3) telnet localhost 3306 으로 연결 가능 여부 확인
|
||||||
|
|
||||||
Q: Redis 연결 실패
|
Q: Redis 관련 로그가 나옴
|
||||||
A: docker ps 에서 redis 컨테이너 실행 중인지 확인
|
A: Embedded Redis가 자동 구동됩니다. 별도 조치 불필요.
|
||||||
또는 Redis를 직접 설치하고 기본 포트(6379) 확인
|
로그에 "[WBX] Embedded Redis 시작" 출력 시 정상 동작.
|
||||||
|
포트 6379가 이미 사용 중이면 외부 Redis를 자동 감지하여 사용합니다.
|
||||||
|
|
||||||
Q: Lombok 관련 컴파일 에러
|
Q: Lombok 관련 컴파일 에러
|
||||||
A: IDE에서 Annotation Processor 활성화 필요
|
A: IDE에서 Annotation Processor 활성화 필요
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ import type { NavigationGuardWithThis } from 'vue-router';
|
|||||||
import { authService } from './auth.service';
|
import { authService } from './auth.service';
|
||||||
import { useAuthStore } from '@/modules/auth/auth.store';
|
import { useAuthStore } from '@/modules/auth/auth.store';
|
||||||
|
|
||||||
export const authGuard: NavigationGuardWithThis<undefined> = async (_to, _from, next) => {
|
export const authGuard: NavigationGuardWithThis<undefined> = async (_to, _from) => {
|
||||||
if (!authService.isAuthenticated()) {
|
if (!authService.isAuthenticated()) {
|
||||||
next({ name: 'login' });
|
return { name: 'login' };
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
@@ -13,5 +12,5 @@ export const authGuard: NavigationGuardWithThis<undefined> = async (_to, _from,
|
|||||||
await authStore.fetchMe();
|
await authStore.fetchMe();
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
새 Issue에서 참조
사용자 차단