2026-09-25 PulseUp 작업일지입니다. 오늘은 21건의 작업을 진행했습니다.
앱 잔여 범위·심박계 DB 저장 검토 (`mobile-app`, `api-server`, `electron-app`)
현상/기능
- 전체 앱을 확인했을때 추가로 필요한 부분이 있는지 줘. 그리고, 앱과 심박계연결을 해서 DB 로 보내는 부분에 대해 기능이 가능한지 검토
- 일단 지금 내용은 저장해놔.
수정한 테이블
- 없음 (검토만 기록. 구현하지 않음)
검토 결과 — 아직 비어 있는 부분
- 회원: 출석 내역, 센터 문의, 코치에게 심박존 조정 요청은 `ProfilePlaceholderScreen` (“곧 제공됩니다”)만 있음. 조회·등록 API 없음.
- 인바디: 운동기록 카드가 최신 1건만 표시. `inbody_measurements` 조회는 `memberWorkoutRecords.service`에 있음. 측정값 입력 화면·API 없음.
- 수업 대기 순번 없음. 자리 없으면 예약이 닫힘.
- 푸시: 설정 저장과 서버 발송(`member-alert.service`, 수업·수강권·공지)은 있음. Expo Go는 기기 토큰을 받지 않음. 실제 알림은 개발 빌드·스토어 빌드에서만 동작.
- 지점 관리: 신청 승인, 회원·결제, 수업·출석·심박 배정, 공지, 심박계, 홍보, 수입, 월간프로그램 조회는 앱에 있음.
- 월간프로그램은 조회·영상 재생. 운동 편집·복사·Electron 재생은 웹·Electron.
- 본사 전용(지점 마스터, 계정 승인, 공통코드, 메뉴)은 웹 범위.
- 기본 운영 우선순위: 출석 내역 → 인바디 입력 → 실기기 푸시. 문의·코치 요청은 그다음.
검토 결과 — 심박계를 앱에서 연결해 DB에 저장
- 수업 중 저장은 Electron ANT+로 이미 동작. 휴대폰 경로가 아님.
- 흐름: 지점 PC Electron이 ANT+ 동글로 수신(기기명 `ant-10084`, `HW9 10084`의 끝 숫자로 회원 매칭) → 수업 시작으로 `workout_history_master` 생성 → `POST /api/heart-rate/save-batch` (최대 200건) → 배정된 심박계는 해당 회원, 미배정은 운동을 연 계정으로 `heart_rate_data` 저장 (`heartrate.service`).
- 휴대폰 앱에 BLE 스캔·연결 코드 없음. `react-native-ble-plx` 없음. 설계 문서의 `POST /api/heart-rate/live`(휴대폰 → 서버 → Electron 화면)는 미구현.
- 휴대폰 저장이 되려면: BLE 심박 표준(`0x180D`) 밴드만 읽기 가능(지점 ANT+ 스트랩은 휴대폰이 같은 방식으로 읽지 못함). Expo Go 불가, 개발 빌드 필요. 화면 꺼짐 시 iOS 백그라운드 모드·Android 포그라운드 알림 추가. `save-batch`는 로그인만으로 호출 가능하나 진행 중 운동기록 ID가 필요하고, 기기 ID·이름이 배정 심박계 끝 숫자와 맞아야 그 회원 기록으로 들어감. 체육관 화면 표시는 Electron 로컬. DB 저장과 별개.
- 다음 구현 시 필요: 새 화면, BLE 모듈, “지금 수업의 운동기록 ID + 내 기기”를 잇는 API.
지난 수업 참석자 표기 (`mobile-app`)
현상/기능
- 수업예약에서 지나간 수업은 예약자가 아니라 참석자 로 변경
수정한 소스·기능
- `classManageUtils.isPastSlot` — 종료 시각이 지난 수업
- `SlotCard` — 지난 수업 버튼 문구를 참석자로 변경
- `AttendanceModal` — 지난 수업 화면 제목과 빈 목록 문구를 참석자로 변경
운동상세 영상 (`mobile-app`)
현상/기능
- 운동상세에서 운동명을 클릭하면 해당 영상이 나오게
수정한 테이블
- 없음 (`sp_GetWorkoutExercises`, `sp_GetWorkoutHistoryDetail`이 이미 `video_url`을 내려줌)
수정한 소스·기능
- `monthProgramTypes`, `monthProgramApi` — 운동 상세·실행 순서에 `videoUrl`, `videoStartTime` 전달
- `monthProgramVideo`, `ExerciseVideoPopup` — 운동명을 누르면 웹처럼 화면 가운데 팝업에서 영상을 재생. Vimeo는 pulsebox.co.kr 페이지 안 iframe으로 재생하고 하단 컨트롤 바는 숨긴다. 영상 칸은 16:9, 제목 칸 높이 32.
운동기록 상세 표 (`mobile-app`)
현상/기능
- 운동기록 상세를 수정한다. 1R, 2R 이부분은 테이블 형태로 하나로 만들어 주고, DS -> Main 운동 -> CD 도 테이블 형태로 변경하는데 DS, Main운동, CD 는 타이틀이 들어가게
수정한 소스·기능
- `month-program/MonthProgramDetail` — 라운드 계획은 라운드·운동·휴식·물 표 하나. 운동 목록은 DS, Main 운동, CD 제목 아래 각각 표. Main 운동만 라운드 열을 둠
대시보드 숫자 카드 명칭 (`mobile-app`)
현상/기능
- 대시보드 위에 4개의 카드에 대해 어떤 내용인지 명칭을 적어줘
수정한 소스·기능
- `ui/AdminStatTile` — 명칭을 숫자 위로 올려 카드가 무엇을 세는지 먼저 보이게 함
- `BranchDashboardScreen` — 네 카드 명칭: 오늘 수업, 대기 신청, 만료 임박, 이용중 회원
대시보드 공지 카드·팝업 정리 (`mobile-app`)
현상/기능
- 대시보드의 공지사항은 긴급/시스템 등은 아이콘 형태로 보이고, 제목도 같은 라인에 배치해서 카드 높이를 줄여줘. 공지 팝업은 닫기 버튼 없애기. 상단 공지사항 타이틀은 해당 공지사항의 제목과 날짜로 하고, 본문은 날짜와 제목은 뺀다.
수정한 소스·기능
- `dashboard/BranchAnnouncementsCard` — 구분은 아이콘 대신 '시스템'·'지점'·'관리자'·'긴급' 글자. 제목은 같은 줄
- `AnnouncementDetailModal` — 닫기 버튼 제거. 헤더 왼쪽은 제목, 오른쪽은 날짜. 본문은 내용만. 팝업 높이는 화면의 62%로 고정. 바깥을 누르면 닫힘. 중요 공지의 확인·목록 보기는 유지
대시보드 공지 제목·앱 공지 등록 (`mobile-app`, `api-server`)
현상/기능
- 대시보드에서 오늘 수업 하단에 수업목록이 나오고 공지사항은 목록과 같이 포함되어 타이틀 위치가 다르다. 공지사항은 앱에서 등록이 안되네? 지점 관리자가 추가/등록/삭제 되어야 한다. 시스템 관리자는 시스템으로 등록되어야 한다.
수정한 테이블
- `announcements` (기존 등록·삭제 프로시저 사용)
수정한 프로시저
- 없음 (`sp_CreateAnnouncement`, `sp_DeleteAnnouncement` 그대로 호출)
수정한 소스·기능
- `dashboard/BranchAnnouncementsCard` — 공지 제목을 오늘 수업과 같이 목록 밖으로 빼고, 공지는 카드로 한 건씩 표시
- `BranchAnnouncementsScreen`, `announcements/AnnouncementEditorSheet` (신규) — 지점 관리자는 지점 공지, 시스템 관리자는 시스템 공지를 등록·삭제. 다른 구분 공지는 보기만
- `app/(branch)/` — 관리자 공지 화면으로 연결
- `announcementsApi` — `POST/DELETE /api/admin/announcements`
- `admin.routes` — 시스템 관리자 등록은 `target_audience=all`, 지점 관리자는 자기 지점. 삭제도 같은 범위만 허용
수업예약 예약자 화면 정리 (`mobile-app`)
현상/기능
- 관리자 화면에서 수업예약에서 예약자 클릭하면 데이터가 어지럽게 나온다. 화면이동을 하더라도 좀 더 쉽게 확인 및 저장할 수 있도록 수정해.
수정한 프로시저
- 없음 (기존 API 그대로: `fetchSlotBookings`, `updateBookingAttendance`, `syncSlotHeartRateAssignments`, `fetchClassDateWorkouts`, `fetchActiveHeartRateDevices`, `fetchParticipantSummary`, `upsertHeartRateParticipants`, `deactivateHeartRateParticipant`)
수정한 소스·기능
- `classes/AttendanceModal` — 가운데 팝업 속 표 두 개를 없애고 전체 화면 시트(`AdminSheet`)로 변경. 수업 정보와 예약·출석·노쇼·심박계 숫자 4칸, '출석 | 심박계' 탭. 당겨서 새로고침. 두 탭은 계속 떠 있어 탭을 오가도 고르던 심박계가 남음
- `classes/AttendanceMemberCard` (신규) — 회원 카드. 예약중/출석/노쇼 큰 버튼을 누르면 바로 저장. 취소 예약은 상태만 표시
- `classes/AttendanceHeartRatePanel` — 7칸 표 대신 1단계 자동배정 → 2단계 운동 칩 선택 → 3단계 한 번에 반영 순서 카드와 회원별 카드. `Alert` 대신 화면 안내 문구. `refreshKey`로 새로고침 연동
- `classes/HeartRateMemberCard` (신규) — 회원별 예약 배정 기기, 선택 심박계, 현재·평균·최고 심박, 저장/해제. 저장된 기기와 같으면 '저장됨'
- `classes/DevicePickerSheet` (신규) — 아래에서 올라오는 심박계 선택 창. 다른 회원에게 배정된 기기는 흐리게 막음. 바깥 누르면 닫힘
- `classes/attendanceTableCells` — 사용처가 없어져 삭제
- `classes/attendanceHeartRateModel` — 요약의 사용처만 갱신
지점 상단 종 표시 (`mobile-app`)
현상/기능
- 앱 우측 상단의 종에 마크가 안사라진다.
수정한 소스·기능
- `BranchTopBar` — 읽지 않은 공지가 없으면 파란 점을 숨김. 미읽음이 있을 때만 개수 배지
본사 수정 제한·개인정보 색 (`mobile-app`, `api-server`)
현상/기능
- super admin 은 1. 수업예약시 수정/삭제 할 수 없다. 2. 회원관리에서 회원정보클릭하면 회원 상세 정보 안나오게 한다. 3. 결제 및 홍보에 저장 버튼 안보이게 한다. 개인정보 수정은 붉은 색으로 나오는데 사용자는 붉은색, 관리자(super admin 포함) 는 파란색으로 한다.
수정한 소스·기능
- 수업 카드 — 본사는 수정·삭제 숨김. API PATCH/DELETE 도 거절
- 회원 카드 — 본사는 눌러도 상세 시트를 열지 않음
- 결제 및 홍보 — 본사는 저장 버튼 숨김. API 저장도 거절
- `ProfileEditScreen` — 회원은 분홍, 지점관리자·본사는 파랑
공지 팝업 바깥 터치로 닫기 (`mobile-app`)
현상/기능
- 공지사항 클릭시 공지 내용이 팝업으로 나오는데 닫기 안하고 화면 아무곳이나 눌러도 팝업이 사라지게 해
수정한 소스·기능
- `AnnouncementDetailModal` — 어두운 배경을 누르면 닫힘. 본문 영역은 그대로 스크롤
본사 지점 선택 (`mobile-app`, `api-server`)
현상/기능
- 추가로 Super admin 인 경우 대시보드에서 지점을 선택할 수 있도록 하고 선택하면 다른 페이지 내용도 선택한 지점으로 나오게 단, super admin 은 회원 등록이나 수업등록은 할 수 없도록 한다.
수정한 소스·기능
- `AdminBranchContext` — 본사가 고른 지점을 기억. API 요청에 `branchId`(심박계는 `branch_id`)를 붙임
- 대시보드 — 지점 선택. 신청·회원·수업·심박계·홍보·수입은 그 지점 기준
- 본사 로그인 후 지점 탭으로 이동
- 회원 등록(방문확인 승인)·수업 등록은 화면과 API에서 막음
- `resolveActorBranchId` — 지점관리자는 토큰 지점만, 본사는 요청의 지점
지점관리자 앱 화면 모바일 단순화 (`mobile-app`)
현상/기능
- 이제 관리자페이지를 수정한다. 전체 페이지들이 모바일 답지 않다. 모바일에서 의미 없는 정보들은 과감하게 제거 또는 사용자 페이지 처럼 심플하게 원하는 기능만 추가되게 전체 페이지 내용을 수정 푸른색 계열등 레이아웃은 유지 한다.
수정한 소스·기능
- `branch-admin/ui` — AdminCard·AdminChips·AdminSheet·AdminStatTile·AdminSubHeader
- 대시보드 — 오늘 수업·대기 신청·만료 임박·이용중 타일과 공지 3건
- 신청·수업예약·월간프로그램·회원관리 — 표 대신 카드. 상세는 시트
- 더보기 — 메뉴 목록. 심박계·결제홍보·수입분석은 숨김 라우트
- 수입분석 — 기간 프리셋·요약 3장·월별 매출 차트 1종
지점관리자 단순화 점검·보완 (`mobile-app`)
현상/기능
- plan 기준으로 진행한것도 다시 확인하는 것부터 진행
수정한 소스·기능
- 계획 대비 전 화면 점검, 삭제 파일 참조 없음·타입 검사 확인
- `BranchDashboardScreen` — 오늘 수업 카드의 중복 날짜 제거
- `MemberDetailSheet` — `banner`·`children` 추가. 연장결제·결제취소·개인 심박계·정지 모달을 시트 안에 띄움(iOS 형제 Modal 미표시 대응)
- `BranchMembersScreen` — `AdminSubHeader` 뒤로 가기, 안내 문구를 시트에도 표시
- `(branch)/` — `backBehavior="history"`. 더보기 하위 화면 뒤로 가기가 대시보드 대신 직전 화면으로
탈퇴 전 환불 규정 확인 (`mobile-app`, `web-app`)
현상/기능
- 회원탈퇴시 환불관련 규정 확인 후 탈퇴하도록 한다.
수정한 소스·기능
- `WithdrawConfirmModal`, `WithdrawConfirmDialog` — 지점 환불 안내를 보여주고, 확인 체크 전에는 탈퇴할 수 없음
마이 회원탈퇴 (`mobile-app`)
현상/기능
- 사용자 메뉴에서 회원탈퇴하는게 안 보인다.
수정한 소스·기능
- `ProfileScreen` — 로그아웃 아래 회원탈퇴. 비밀번호 확인 후 `POST /api/auth/withdraw`
내 예약 취소 숨김 (`mobile-app`)
현상/기능
- 내 예약에서 취소한 운동은 안 보이게 한다.
수정한 소스·기능
- `reservationUtils` — 예정·지난 목록에서 `cancelled` 예약을 제외
월간 운동기록 색 구분 (`mobile-app`)
현상/기능
- 월간 화면도 수업별 화면처럼 색상을 넣어서 구별되게 한다.
수정한 소스·기능
- `MonthlyRecordPanel` — 평균 분홍, 최고 주황, 수업 카드는 평균 심박 존 색
- `recordZoneUtils` — 존 색 조회 `getZoneColor`
월간 운동기록 빈 카드 (`mobile-app`)
현상/기능
- 월간에도 운동기록이 없는데 카드가 계속 생긴다.
수정한 소스·기능
- `useWorkoutRecords` — 월간 목록은 `workoutId`가 있는 수업만 전달
- `WorkoutRecordsScreen` — 월간 패널에 그 목록을 넘김
출석·심박계 수업 후 수정 허용 (`/booking/manage`)
현상/기능
- booking/manage 예약자를 클릭하면 예약자 출석체크 하는데 시간만 지나면 disable 된다.
- 나중에라도 출석처리 할 수 있도록 하루 이내는 수정할 수 있도록 한다. 심박계도 마찮가지.
수정한 소스·기능
- 최종: 시간 기한 잠금을 모두 제거. 취소된 예약은 출석체크 목록에서 숨김(요청: "취소한 내용은 안보이게 해.")
- 출석·심박계 Select 시간 잠금 제거
- (앱) — 출석·심박계 시간 잠금과 안내 문구 제거
- 출석 변경·심박계 자동배정 시간 검증 제거
- 참가자 매핑 저장 시간 검증 제거
- / / — `canEditClassAttendance` 유틸은 남아 있으나 호출처 없음
- — 앱 출석 화면 동일
수업 알림 운동명 컬럼 (`api-server`)
현상/기능
- 알림 예약 확인이 `Unknown column 'wc.name'` 로 실패한다.
수정한 테이블
- 없음. `workout_categories.major_category_name`, `class_slots.title` 조회
수정한 소스·기능
- `member-alert-scheduler`, `member-alert.service` — 수업명을 `wc.name` 대신 대분류명·슬롯 제목으로 조회