Skip to content

출석체크 사역자 관리 페이지 추가#76

Merged
iubns merged 22 commits into
deployfrom
dev
Apr 30, 2026
Merged

출석체크 사역자 관리 페이지 추가#76
iubns merged 22 commits into
deployfrom
dev

Conversation

@min1336
Copy link
Copy Markdown
Contributor

@min1336 min1336 commented Apr 29, 2026

No description provided.

iubns and others added 22 commits April 15, 2026 10:17
- /admin/soon/attendance 에 [조회] / [입력] 탭 분리
- [입력] 탭: 마을/다락방/순원 3열 리스트 + 모바일 드릴다운
- 상태 필터 5개 (전체/기록안됨/출석/결석/기타) + 이름 검색
- 그룹별 tri-state 체크박스 (마을/다락방/전체 선택)
- 하단 sticky bulk action bar (출석/결석/기타)
- 공통 사유 다이얼로그 + Undo 스낵바 (10초)
- 서버: /admin/soon/update-attendance 엔드포인트 + 권한 검증
  (Admin / VillageLeader / Leader 각자 스코프 내만 편집 가능)
- 부수: /leader/all-attendance 의 authUserData race condition 수정
- 필터 chip 가로 스크롤 (한 줄, 페이드 힌트)
- iPhone safe-area inset 적용 (bulk bar, snackbar, 스크롤 여백)
- 예배 select를 OS 네이티브 picker로 (iOS 휠 / Android 다이얼로그)
- 예배/필터/검색 헤더 sticky (리스트 스크롤해도 상단 고정)
- 상태 chip 말줄임 + hover tooltip (긴 memo 레이아웃 보호)
- bulk 버튼 아이콘화 (600px 미만에선 아이콘만, 이상은 텍스트+아이콘)
- AttendanceTable hydration mismatch 수정 (global.innerWidth → useMediaQuery)
statusLabel을 파일 하단에서 하위 컴포넌트 영역 위로 이동하여 사용처와의 거리를 줄였습니다. 자명한 주석 1줄만 제거하고 WHY를 설명하는 주석은 유지했습니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
403 응답 본문을 한국어 상세 설명에서 "Forbidden"으로 단축하여 엔드포인트의 권한 체크 로직이 외부로 추정되지 않도록 했습니다. 동일 엔드포인트의 401/400 응답 스타일과도 일관됩니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
isAttend가 AttendStatus enum 값인지 확인하고, memo의 타입과 길이(500자 이내)를 검증하여 데이터 무결성 훼손과 과대 입력을 방어합니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
페이지 접근 가드가 VillageLeader만 허용하므로 editable에 포함된 role.Leader는 실행에 도달하지 않는 죽은 조건입니다. 의도와 실제를 일치시키기 위해 제거했습니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
출석 편집은 /admin/soon/attendance 에서만 가능하도록 하기 위해 leader 페이지에 추가했던 editable 변수, handleSaveCell 핸들러, AttendanceTable의 편집 props를 걷어냈습니다. authUserData 로딩 타이밍 수정은 원래 있던 버그 수정이므로 유지합니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- canEditUserAttendance, isInSubtree를 server/src/model/attendance.ts로 이동 (라우터 슬림화)
- Leader는 자기 community만, VillageLeader는 subtree 전체로 권한 범위를 명시적으로 분리 (기존엔 둘 다 subtree 체크)
- isInSubtree에 id→node Map을 추가해 탐색을 O(1)로 개선
- memo 미전송 시 기존 memo가 빈 문자열로 덮어써지던 문제를 조건부 업데이트로 수정

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AttendCell(useState/Popover), AttendanceTable(useTheme/useMediaQuery)에 "use client" 지시어를 명시해 Next.js App Router 경계 규약을 충족
- /leader/all-attendance 에서 fetchCommunities 호출을 VillageLeader 체크 이후로 이동해 비권한 사용자가 불필요한 /admin/community 요청을 내지 않도록 함

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- client/src/util/attendanceError.ts 추가: 서버 에러 코드를 한국어 메시지로 매핑하는 유틸
- OverviewTab, EditTab의 에러 처리에서 이 유틸을 사용해 "Forbidden" 같은 서버 원문 대신 사용자 친화적 문구를 노출
- EditTab의 runBulkSave를 10개씩 배치로 Promise.allSettled 처리해 대량 선택 시 서버 과부하 및 브라우저 연결 한계를 완화
- 실패 발생 시 실패 건수뿐 아니라 첫 실패의 원인을 함께 표시
- EditTab에서 미사용 MUI 컴포넌트(Select/MenuItem/FormControl/InputLabel) import 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
출석 편집 요청마다 전체 community 테이블을 다시 로드하던 것을 모듈 레벨 Map에 TTL 30초로 캐시하여 반복 DB 조회를 제거합니다. 트리 구조 변경은 드물어 30초 지연이 허용됩니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AttendanceTable의 "SSR-safe" 주석을 "SSG"로 교정 (output:"export" 환경)
- AttendanceTable/AttendCell에 추가됐던 "use client"는 부모에서 상속되는 프로젝트 관례와 어긋나므로 제거
- worshipScheduleMap 루프에서 onSave prop 삼항식을 handleSave 변수로 추출해 가독성 개선

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
클라에서 10개씩 병렬 HTTP 요청을 나눠 보내던 runBulkSave와 handleUndo를 신설한 POST /update-attendance-bulk 한 번의 요청으로 통합합니다. 서버는 최대 100건까지 받아 각 아이템별로 검증·권한 체크·저장을 수행하고, 부분 실패 시 HTTP 207 Multi-Status와 per-item 결과를 반환합니다. 클라는 결과의 status 기반으로 성공 userId를 계산하고 첫 실패 사유를 토스트에 표시합니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EditTab의 runBulkSave/handleUndo 두 군데에 인라인으로 정의돼 있던 BulkAttendanceResponse 타입을 util/attendanceError.ts로 옮기고, 인라인 status 매핑(forbidden/invalid/error → 한국어)도 toBulkResultMessage 함수로 추출했습니다. 새 status 추가 시 매핑 테이블 한 곳만 수정하면 됩니다.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
add: 마을/다락방 출석 편집 기능 및 출석 API 보안 강화
새가족 생일 추가
- 기존: 마을→다락방→순원 3단 가정. 실제 데이터는 담당→마을→다락방→순원 4단이라 다락방 카운트가 0으로 표시되는 버그.
- 4단 trail-up 헬퍼(findDangId/findVillageId/findDarakId) 도입, 매핑을 leaf 기준으로 정정.
- 컬럼은 항상 3개로 보이게: 다락방 클릭 시 [마을, 다락방, 순원]으로 슬라이드, ← 버튼으로 [담당, 마을, 다락방] 복귀.
- 사역팀처럼 마을 단계가 없는 평탄한 담당은 다락방 컬럼에 순원을 직접 표시.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
출석 입력 4단(담당→마을→다락방→순원) drill-down + bulk 저장/UX 개선
@min1336
Copy link
Copy Markdown
Contributor Author

min1336 commented Apr 29, 2026

@iubns 이렇게 하는게 맞나요..?

Copy link
Copy Markdown
Member

@iubns iubns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@iubns iubns merged commit 031a345 into deploy Apr 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants