사이트픽 블로그
← 목록으로

개발일지 2026-07-12

피아노 학원 플랫폼 개발일지 (2026-07-12)

개요

악보 관리 시스템의 그룹(곡) 관리 + 변형(PDF) 추가 기능을 완성하고, 학생/공개 악보 탐색 사이트의 상세 페이지 UI를 와이어프레임에 맞춰 대폭 개선했다. 미리보기 설정·프린트 제한 등 운영 설정 화면도 DB 연동으로 전환하고, 아티스트 상세 페이지를 신규 구현했다.

수정/생성 파일 목록

백엔드 (piano-backend)

  • AdminSheetItemRow.java (수정) — pdfFilename 필드 추가
  • AdminSheetSong.java (수정) — categoryIds, titleMainEn, artistMainEn 필드 추가
  • AdminSheetSongController.java (수정) — 변형 추가 엔드포인트 POST /sheet-songs/{id}/items
  • AdminSheetSongService.java (수정) — addItem(), categoryNames 직접 수정, pdf_filename 최대값+1 채번
  • AdminSheetSongMapper.java (수정) — updateCategoryNames, findByArtistPaged, countByArtist 추가
  • AdminSheetSongMapper.xml (수정) — itemRowMap에 pdf_filename 매핑, 검색조건에 pdf_filename 추가, song_code 숫자정렬, categoryNames/categoryIds 상세 반환
  • SheetSongUpdateRequest.java (수정) — categoryNames 필드 추가
  • SheetItemCreateRequest.java (신규) — 변형 추가 요청 DTO
  • StudentSheetSongMapper.xml (수정) — category_names 컬럼 반환, 아티스트별 조회 쿼리
  • PublicSheetSongController.java (수정) — GET /by-artist 엔드포인트 추가
  • PublicSheetSongService.java (수정) — listByArtist(), registrationInfo 매핑
  • PublicSongRow.java (수정) — categoryNamesText 필드 추가
  • SheetSong.java (수정) — registrationInfo 필드 추가
  • PrintLimitController.java (신규) — 프린트 제한 CRUD API
  • PrintLimit.java (신규) — 프린트 제한 엔티티
  • PrintLimitMapper.java (신규) — 프린트 제한 매퍼
  • PrintLimitMapper.xml (신규) — 프린트 제한 SQL
  • SheetPreviewController.java (신규) — 미리보기 설정 조회/수정 API
  • SheetPreviewSettings.java (신규) — 미리보기 설정 엔티티
  • SheetPreviewMapper.java (신규) — 미리보기 설정 매퍼
  • SheetPreviewMapper.xml (신규) — 미리보기 설정 SQL
  • migration-20260712c-print-limits.sql (신규) — print_limits 테이블
  • migration-20260712d-print-limit-codes.sql (신규) — 공통코드(printMonthlyLimit, printExceedPolicy)
  • migration-20260712e-sheet-preview-settings.sql (신규) — sheet_preview_settings 테이블 + 공통코드(watermarkType, watermarkPosition, watermarkOpacity)

프론트 — 관리자 (admin)

  • SheetGroups.tsx (신규) — 악보 그룹관리 목록. 서버 페이징, 체크박스 선택 삭제, 그룹코드 링크
  • SheetGroupDetail.tsx (신규) — 악보 그룹 상세. sheet_songs 직접 편집, category_names 드래그 정렬
  • SheetSongs.tsx (수정) — 곡코드 링크, 체크박스 삭제, 서버 페이징, 엑셀 다운로드
  • SheetCategories.tsx (수정) — 체크박스 선택 삭제, 제목 클릭 수정, 행별 버튼 제거
  • SheetPreview.tsx (수정) — DB 연동 + 공통코드 + 워터마크 시뮬레이션
  • PrintLimits.tsx (수정) — DB 연동 + 공통코드
  • SheetItemAdd.tsx (신규) — 변형 추가 팝업 (PDF 업로드 + 난이도/편성/KOMCA)
  • sheetSongs.ts (수정) — addSheetItem, SheetItemCreateForm 등 API 추가
  • sheetPreview.ts (신규) — 미리보기 설정 API
  • printLimits.ts (신규) — 프린트 제한 API
  • DataTable.tsx (수정) — 서버 페이징 props, 헤더 무조건 중앙정렬
  • Sidebar.tsx (수정) — 메뉴 클릭 시 resetSearch state 전달
  • usePersistedSearch.ts (수정) — resetSearch 감지해 검색 조건 초기화
  • AuthContext.tsx (수정) — 로그인 시 sessionStorage/localStorage 초기화
  • pageRegistry.ts (수정) — sheet-groups 등록
  • popup/registry.ts (수정) — SheetItemAdd 등록

프론트 — 악보 사이트 (sheets)

  • SongCard.tsx (수정) — 와이어프레임 스타일 카드 (썸네일 + 편성/난이도 태그 + 아티스트 링크)
  • songs/page.tsx (수정) — 상세 히어로 영역 (커버 + 정보카드 + 분류정보), 편성별 그룹 섹션
  • artist/page.tsx (신규) — 아티스트 상세 페이지 (헤더 + 관련곡 그리드)
  • sheetSongs.ts (수정) — registrationInfo, getSheetSongsByArtist API 추가
  • globals.css (수정) — 카드 썸네일, 태그, 히어로, 섹션 테이블, 아티스트 페이지 스타일
  • .env.local (신규) — 로컬 개발 시 localhost:8080으로 API 연결

주요 작업 상세

1. 악보 그룹관리 (sheet_songs 단위)

기존 악보목록은 변형(sheet_items) 단위로만 보여줬는데, 곡(sheet_songs) 단위로 관리하는 그룹관리 화면을 추가했다.

  • 목록: 그룹코드(songCode) 링크 클릭 → 상세 이동, 서버 페이징(DataTable 서버 페이징 props 신규), 체크박스 선택 삭제
  • 상세: sheet_songs 컬럼을 직접 편집하는 폼. category_names는 Chip 태그로 추가/삭제/드래그 정렬 가능
// 드래그로 등록정보 순서 변경
<Chip draggable onDragStart={() => setDragIdx(i)}
  onDrop={() => {
    const next = [...prev];
    const [moved] = next.splice(dragIdx, 1);
    next.splice(i, 0, moved);
    return next;
  }} />

2. 변형(PDF) 추가 기능

기존에는 곡+변형을 동시에 등록하는 것만 가능했는데, 기존 곡에 변형만 추가하는 API + 팝업을 만들었다.

  • POST /admin/sheet-songs/{id}/items — pdf_filename은 같은 곡의 기존 변형 중 최대 순번+1로 자동 채번
  • 팝업에서 PDF 드래그 업로드, 난이도/편성/KOMCA 입력 후 추가
// pdf_filename 자동 채번: 기존 최대값 + 1
for (AdminSheetItem ex : existing) {
    int n = Integer.parseInt(ex.getPdfFilename().substring(prefix.length()));
    if (n > maxSeq) maxSeq = n;
}
String pdfFilename = prefix + String.format("%04d", maxSeq + 1);

3. DataTable 서버 페이징

DataTable 공통 컴포넌트에 serverTotal, serverPage, onServerPageChange props를 추가해서, 페이지 번호/크기 변경 시 서버 API를 호출하도록 했다.

<DataTable serverTotal={total} serverPage={page - 1}
  onServerPageChange={(p, size) => { setPage(p + 1); setPageSize(size); }} />

4. 미리보기 설정 + 프린트 제한 — DB 연동

두 화면 모두 목업에서 실제 DB 테이블 + API로 전환했다.

  • sheet_preview_settings 테이블: 공개 페이지 범위, 워터마크 설정
  • print_limits 테이블: 월 허용 횟수, 초과 정책
  • 셀렉트박스 옵션은 공통코드(watermarkType, printMonthlyLimit 등)에서 로드

5. 악보 사이트 — 와이어프레임 UI 적용

곡 카드: 썸네일(베이지 배경 + 곡명/아티스트) + 편성/난이도 태그를 와이어프레임과 동일하게 구현

곡 상세 히어로: 좌측 커버아트 + 우측 정보카드(아티스트/작곡가 pill 클릭 → 아티스트 페이지) + 분류정보 태그

편성별 그룹 섹션: 변형 목록을 formMinor(멜로디/2단/3단/포핸즈)별로 그룹핑. 각 섹션에 난이도/Key/가사/페이지/설명/미리보기·출력 버튼

6. 아티스트 상세 페이지

아티스트/작곡가 이름 클릭 시 /artist?name=Yiruma 형태로 이동. 해당 인물의 관련 곡/등록 악보/카테고리 수를 보여주고, 곡 카드 그리드로 목록 표시.

  • 백엔드: GET /public/sheet-songs/by-artist?artist=... — artist 또는 composer 일치 조회

트러블슈팅

배포 경로 오류 발견 및 수정

nginx root가 /var/www/piano이고 location이 /admin이므로 실제 서빙 경로는 /var/www/piano/admin/인데, deploy-prod 스킬이 /var/www/piano/piano-admin/에 배포하고 있었다. 배포해도 반영이 안 되는 원인이었고, 스킬 설정을 올바른 경로로 수정했다.

백엔드 포트 충돌 (systemd restart loop)

systemd Restart=on-failure 설정으로 인해 이전 프로세스가 죽지 않은 채로 새 프로세스가 계속 기동 시도 → 포트 8080 충돌 반복. systemctl stop → reset-failed → kill -9 → 포트 확인 → start 순서로 해결.

결론

악보 관리의 곡 그룹/변형 체계가 완성되었고, 공개 악보 사이트의 UI가 와이어프레임 수준으로 올라왔다. 미리보기·프린트 제한 같은 운영 설정도 DB 기반으로 전환되어 관리자가 직접 조정할 수 있게 되었다. 아티스트 상세 페이지까지 추가되어 악보 탐색 UX가 한층 풍부해졌다.

댓글 0

  • 첫 번째 댓글을 남겨보세요.