- 실시간 출석 현황을 학년별 섹션으로 묶어서 표시 (백엔드에 grade 필드 추가)
- 학생 계정 추가 폼에 학년 선택 드롭다운 추가
- 학생 계정 생성/삭제가 실제로는 존재하지 않는 엔드포인트를 호출하던
버그 수정 (/api/users/register-student, /api/users/delete/{id} →
/api/users/create, /api/users/delete)
- 학생 대시보드(개발자 모드) 카드 그리드가 넓은 화면에서 과도하게
커지던 레이아웃 버그 수정, 웹은 5열/폰은 2열로 반응형 처리
- 버전 1.2.0+6
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- iOS는 조도 센서/백그라운드 서비스가 불가능해서 근접센서(UIDevice
proximityMonitoring) + 가이드 접근 안내로 대체 구현 (Core NFC와 마찬가지로
네이티브 플러그인 필요해서 ProximityMonitorPlugin.swift 추가)
- 교사 대시보드 실시간 출석 현황: 모바일 리스트/데스크톱 표를 타일 그리드로
통일해서 한눈에 보기 쉽게 변경
- 서버를 학교 자체 서버(Cloudflare Tunnel, api.backsanhi.shop)로 이전하면서
기본 BASE_URL 갱신
- Firebase CLI 로컬 캐시(.firebase/)는 소스가 아니라 gitignore 처리
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- config.dart의 baseUrl/webVapidKey와 학교 이름을 String.fromEnvironment로 전환
- 기본값은 기존 백산고 값 그대로라 인자 없이 빌드하면 지금과 동일하게 동작
- 다른 학교는 --dart-define=BASE_URL=...=SCHOOL_NAME=...=WEB_VAPID_KEY=...로 빌드
하교 버튼을 누르면 반출 허용뿐 아니라, 그 시각을 기준선으로 삼아 대시보드의
"출석 완료" 표시도 미제출로 초기화되도록 함. 실제 출석 기록(attendance 테이블)은
삭제하지 않고, 대시보드가 "오늘 출석"으로 인정하는 기준 시각만 옮기는 방식이라
데이터 손실 없이 표시만 리셋된다.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 선생님 대시보드에 "하교" 버튼 추가: 시간 입력 없이 바로 전체 학생 반출 허용
(실수 클릭 방지를 위해 확인 다이얼로그 한 번 거침)
- 무단반출이 감지되면 클라이언트의 감시 상태를 해제해서, 다음 태깅이
체크아웃이 아니라 새 출석으로 처리되도록 수정
- 주머니 감시 화면에 있던 "폰 회수하고 감시 종료 (테스트용)" 버튼 제거
(정식 플로우는 재태깅으로만 체크아웃/재출석 처리)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- TeacherAttendancePage 앱바에 수동 새로고침 버튼 추가
- Firebase Hosting에서 index.html/flutter_service_worker.js/version.json을
no-cache로 설정해서, 재배포 후 브라우저가 예전 버전을 계속 들고 있는 문제 방지
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 실시간 출석 현황 화면(TeacherAttendancePage)에 데스크톱(웹 브라우저 800px+) 전용
레이아웃 추가: 통계 타일 3개 + 정식 DataTable. 교사 대시보드 메뉴 그리드도
데스크톱에서 카드가 지나치게 커지지 않도록 최대 너비 제한
- Firebase Hosting에 웹 빌드 배포 설정 추가 (firebase.json hosting 섹션),
https://school-display-ff28f.web.app 로 선생님이 브라우저에서 바로 접속 가능
- 무단 반출(/api/violations/active) 감지 시 대시보드에 빨간 표시 + "반출 허용" 버튼 추가
- 선생님이 개별 학생에게 N분간 반출 허용(/api/violations/allow), 또는 전체 학생에게
한 번에 반출 허용 시간대 설정(/api/permissions/window, 쉬는시간 등) 가능하도록 연동
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
## 릴리즈 빌드 준비
- android/app/build.gradle.kts: 디버그 키로 서명하던 release 빌드 타입을
android/key.properties 기반 정식 릴리즈 키스토어(upload-keystore.jks) 서명으로 변경
- applicationId를 com.example.school_attendance → com.backsanhighschool.app 로 변경
(com.example.* 패키지는 구글 플레이 업로드 자체가 거부되기 때문)
## Firebase 재등록
- 새 패키지명(com.backsanhighschool.app)으로 Firebase Android 앱을 새로 등록
- google-services.json, lib/firebase_options.dart, firebase.json을 새 앱 ID 기준으로 재생성
## HTTPS 전환
- lib/config.dart: baseUrl을 http:// → https:// 로 변경
(서버에 이미 발급되어 있었지만 프록시에 연결이 안 되어 있던 Let's Encrypt
인증서를 nginx-proxy-manager에 연결하고 HTTP→HTTPS 강제 리다이렉트 설정)
- AndroidManifest.xml: 더 이상 필요 없는 usesCleartextTraffic="true" 제거
## NFC 태그 쓰기 기능 (신규)
- lib/screens/nfc_tag_writer_screen.dart 추가: 관리자가 빈 NFC 스티커에
"POCKET_번호" 텍스트를 쓰고, 태그 하드웨어 UID를 서버(/api/pockets/register)에
등록해서 태그 복제(내용만 베낀 위조 태그)를 방지
- lib/nfc_poccket_checkin_screen.dart: 체크인 시 태그 UID를 함께 서버로 전송해서
등록된 진짜 주머니 번호로 검증하도록 변경
- lib/screens/student_dashboard.dart: 개발자 메뉴에 "NFC 태그 쓰기" 카드 추가,
기존 "가상 NFC 태깅" 카드는 "NFC 태그"로 이름 변경
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>