πŸ“Œβ€œκ°•μ‚¬ μ „μš© κ°•μ˜ 관리 κΈ°λŠ₯, ν•œ ν™”λ©΄ μ•ˆμ— 담은 μœ μ§€λ³΄μˆ˜ν˜• UX μ•„ν‚€ν…μ²˜β€

πŸ—“ 2025λ…„ 4μ›” 30일 ✍️ by 박찬희

🧭 개발 λ°°κ²½ – β€œν•˜λ‚˜μ˜ ν™”λ©΄μ—μ„œ, λͺ¨λ“  κ°•μ˜ μ•‘μ…˜μ„β€

κ°•μ‚¬λŠ” μ½˜ν…μΈ  μ œμž‘μžμ΄μž μš΄μ˜μžλ‹€.

κ·Έλ“€μ—κ²ŒλŠ” 무엇보닀도 효율적인 β€œκ΄€λ¦¬ 도ꡬ”가 ν•„μš”ν•˜λ‹€.

이번 κΈ°λŠ₯의 λͺ©ν‘œλŠ” λͺ…ν™•ν–ˆλ‹€:

강사듀이 μžμ‹ μ˜ κ°•μ˜λ₯Ό ν•œ νŽ˜μ΄μ§€μ—μ„œ μ™„μ „ν•˜κ²Œ 관리할 수 μžˆλ„λ‘ ν•˜μž.

λ‹¨μˆœ 쑰회λ₯Ό λ„˜μ–΄ 필터링, μ •λ ¬, μˆ˜μ •, μƒνƒœ μ „ν™˜, μ‚­μ œ, λ³΅κ΅¬κΉŒμ§€ λͺ¨λ‘ ν•˜λ‚˜μ˜ ν™”λ©΄ μ•ˆμ—μ„œ μ²˜λ¦¬ν•  수 μžˆμ–΄μ•Ό ν–ˆλ‹€.


🎯 핡심 섀계 λͺ©ν‘œ

ν•­λͺ© 섀계 μ² ν•™
🎯 μ•„ν‚€ν…μ²˜ JSP 기반 MVC2 + DAO/Service λΆ„λ¦¬λ‘œ μœ μ§€λ³΄μˆ˜μ„± 확보
🧱 ν™•μž₯μ„± ν•„λ“œλͺ… 기반 μˆ˜μ • ꡬ쑰 β†’ μ‹ κ·œ ν•­λͺ© μΆ”κ°€ μ‹œ μ΅œμ†Œ λ³€κ²½
⚑ UX λ°˜μ‘μ„± 전체 νŽ˜μ΄μ§€ μƒˆλ‘œκ³ μΉ¨ 없이 AJAX 기반 μ‹€μ‹œκ°„ 동기화
πŸ§ͺ ν…ŒμŠ€νŠΈ 컨트둀러 β†’ μ„œλΉ„μŠ€ β†’ DAO β†’ DB 흐름 전체 검증 κ°€λŠ₯
🧩 UI 톡합 ν•„ν„°, μƒνƒœ μ „ν™˜, μˆ˜μ •, μ‚­μ œ, λ³΅κ΅¬κΉŒμ§€ ν•˜λ‚˜μ˜ 뷰에 배치

πŸ“Š 전체 흐름 ꡬ쑰 (Mermaid)

graph TD
  A[강사 둜그인] --> B[λ‚΄ κ°•μ˜ 관리 νŽ˜μ΄μ§€ μš”μ²­]
  B --> C[LectureManagementLectureService 호좜]
  C --> D[LectureManagementLectureDAO.selectLecturesByInstructor]
  D --> E[DBμ—μ„œ 쑰건별 κ°•μ˜ 쑰회]
  E --> F[JSP에 lecture λͺ©λ‘ 전달]
  F --> G[κ°•μ˜ λͺ©λ‘ UI λ Œλ”λ§]

  G --> H1[ν•„ν„°/μ •λ ¬ 처리]
  G --> H2[κ°•μ˜ ν•„λ“œ 인라인 μˆ˜μ •]
  G --> H3[곡개/λΉ„κ³΅κ°œ μƒνƒœ ν† κΈ€]
  G --> H4[μ‚­μ œ ν›„ Undo κΈ°λŠ₯]

  H1 --> I1["μƒˆ λͺ©λ‘ 쑰회 (AJAX)"]
  H2 --> I2[lecture/updateField β†’ DB 반영]
  H3 --> I3[lecture/toggleStatus β†’ μƒνƒœ μ „ν™˜]
  H4 --> I4[lecture/delete β†’ μ‚­μ œ 처리]


🧩 μ£Όμš” κΈ°λŠ₯ 섀계 μ „λž΅

1️⃣ κ°•μ˜ λͺ©λ‘ 쑰회 (검색 + ν•„ν„° + μ •λ ¬ 톡합)

βœ… 강사 ID 기반으둜만 λ™μž‘ν•΄, 인증 우회 및 κ³Όλ„ν•œ 데이터 λ…ΈμΆœ λ°©μ§€


2️⃣ 인라인 μˆ˜μ • κΈ°λŠ₯ (UX + μœ μ§€λ³΄μˆ˜μ˜ κ· ν˜•)

| μˆ˜μ • ν•„λ“œ | 검증 κ·œμΉ™ | | β€” | β€” | | κ°•μ˜λͺ… | 2자 이상 | | μ„€λͺ… | μ œν•œ μ—†μŒ | | 가격 | 숫자, 0 이상 | | μΉ΄ν…Œκ³ λ¦¬ | Drop-down 선택 μ œν•œ |

public boolean updateLectureField(Long id, String field, String value)

⚠ SQL Injection λ°©μ§€λ₯Ό μœ„ν•΄ field에 λŒ€ν•΄ whitelist 체크 ν•„μˆ˜


3️⃣ 곡개/λΉ„κ³΅κ°œ μƒνƒœ μ „ν™˜ (ν† κΈ€ UI + μ‹€μ‹œκ°„ 반영)

βœ… 전체 λͺ©λ‘ μƒˆλ‘œκ³ μΉ¨ 없이 UX 흐름 μœ μ§€


4️⃣ κ°•μ˜ μ‚­μ œ + Undo κΈ°λŠ₯ (ν”„λ‘ νŠΈ 쀑심 μž„μ‹œ 볡ꡬ)


🧱 λ°±μ—”λ“œ ꡬ쑰 (MVC2 + DAO/Service Layer)

계측 μ—­ν• 
Controller μš”μ²­ λΆ„κΈ° 및 νŒŒλΌλ―Έν„° μˆ˜μ§‘
Service λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 β†’ DAO 호좜 뢄리
DAO DB 쿼리 μ‹€ν–‰ (MyBatis 기반)
DTO 데이터 객체 (LectureManagementLectureDTO)
JSP λ·° λ Œλ”λ§ + AJAX 이벀트 처리

🎨 UI & UX μ „λž΅ μš”μ•½

μš”μ†Œ μ„€λͺ…
βœ… 인라인 μˆ˜μ • 클릭 μ‹œ μ¦‰μ‹œ μˆ˜μ • κ°€λŠ₯, blur둜 μ €μž₯
βœ… μƒνƒœ badge 곡개/λΉ„κ³΅κ°œ μƒνƒœ 색상 + ν…μŠ€νŠΈ ν‘œμ‹œ
βœ… λ°˜μ‘ν˜• ν…Œμ΄λΈ” λͺ¨λ°”일 λŒ€μ‘ (@media)
βœ… Spinner ν‘œμ‹œ AJAX μš”μ²­ 쀑 λ‘œλ”© μ‹œκ°ν™”
βœ… Toast λ©”μ‹œμ§€ κ²°κ³Ό λ©”μ‹œμ§€ ν”Όλ“œλ°±
βœ… λͺ¨λ‹¬ μ‚­μ œ 확인 μ‹œ UX 뢄리 및 μ‹€μˆ˜ λ°©μ§€

βš™οΈ 기술적 ν•˜μ΄λΌμ΄νŠΈ

πŸ”„ 동적 ν•„λ“œ μˆ˜μ • ꡬ쑰

// Service
public boolean updateLectureField(Long lectureId, String field, String value)

βœ… μƒˆλ‘œμš΄ ν•„λ“œκ°€ 좔가돼도 μž¬μ‚¬μš© κ°€λŠ₯ν•œ ꡬ쑰


πŸ” 싀무 κ°œμ„ /ν™•μž₯ μ œμ•ˆ

ν•­λͺ© κ°œμ„  포인트
πŸ”’ λ³΄μ•ˆ κ°•ν™” CSRF 토큰, 강사 κΆŒν•œ 체크, 둜그인 μ„Έμ…˜ 검증
🌐 κ΅­μ œν™” JSTL i18n λ„μž…μœΌλ‘œ λ‹€κ΅­μ–΄ 지원
πŸ“ˆ μ„±λŠ₯ μ΅œμ ν™” Lazy Loading λ˜λŠ” νŽ˜μ΄μ§€λ„€μ΄μ…˜
πŸ“Š 톡계 연동 μˆ˜κ°•μƒ 수, 쑰회 수 컬럼 ν‘œμ‹œ
β™» Undo 고도화 λ°±μ—”λ“œμ— Redis TTL 기반 soft delete ꡬ쑰 λ„μž…

βœ… κ²°κ³Ό μš”μ•½ 및 회고

이번 κΈ°λŠ₯은 λ‹¨μˆœν•œ CRUD의 λ‚˜μ—΄μ΄ μ•„λ‹ˆλΌ,

β€œμ‚¬μš©μžμ˜ 관리 νš¨μœ¨μ„±κ³Ό 개발자의 μœ μ§€λ³΄μˆ˜μ„±β€μ„ λͺ¨λ‘ λ§Œμ‘±μ‹œν‚€λŠ” μ•„ν‚€ν…μ²˜λ₯Ό λͺ©ν‘œλ‘œ ν–ˆλ‹€.

β€œκ°•μ‚¬ 관리 νŽ˜μ΄μ§€λŠ” λ‹¨μˆœν•œ ν…Œμ΄λΈ”μ΄ μ•„λ‹ˆλΌ,

λΉ„μ¦ˆλ‹ˆμŠ€ μš”κ΅¬λ₯Ό ν’ˆμ€ UX 섀계 곡간이닀.”

β€” κΈ°λŠ₯λ³„λ‘œ μͺΌκ°  게 μ•„λ‹ˆλΌ, μ‚¬μš©μž νλ¦„μœΌλ‘œ ν†΅ν•©ν•œ ꡬ쑰의 νž˜μ„ λŠκΌˆλ‹€.