StudentDashboard, TeacherDashboard, AdminDashboard(진입 라우팅)를
MainDashboard 하나로 합치고, 역할(role)에 따라 배너 색상/문구와
보이는 타일만 달라지게 함. 그리드 레이아웃/카드 디자인은 이제
한 곳에서만 관리되어, 앞으로 UI를 고치면 모든 역할에 자동 적용됨.
- 2061(개발자) 계정에 기존에 빠져있던 "스마트기기 반출 대장" 타일 추가
- role=='admin' 실 계정도 이제 학생 계정 관리/출석 확인 등 교사 기능에
접근 가능 (관리자는 교사 권한을 포함하는 것으로 정리)
- 작은 DB 초기화 전용 화면(admin_dashboard.dart)은 "서버 DB 제어"
타일의 목적지로만 유지, 로그인 직후 랜딩 화면 역할은 제거
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
자동 감지 하드웨어가 아직 없어서, 승인된(APPROVED) 요청에 선생님이
기기를 실제로 돌려받았을 때 누르는 "기기 반납 확인" 버튼을 추가.
누르면 상태가 반납완료로 바뀌어 10분 후 미반납 알림이 더 이상
가지 않는다 (백엔드는 별도 저장소에서 이미 배포 완료).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
계획 변경에 따라 저울/아두이노 기반 픽업·반납·무단반출 감지를 없애고
순수 시간 기반 알림만 남김 (백엔드는 별도 저장소에서 이미 배포 완료).
- 승인 시 현재 로그인한 선생님의 teacherId/teacherName을 서버에 함께
전송하여 저장하고, 대장에 "OOO 선생님이 허용했습니다" 표시
- 반납 시간 초과 알림은 승인한 선생님에게만 전송 (서버가 해당 선생님의
등록된 기기를 못 찾으면 전체 선생님에게 대체 발송)
- 대장 카드의 상태 표시에서 IN_USE/RETURNED(픽업 대기) 문구 제거
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
학생 타일의 이름/상태/학년칩 폰트와 아이콘 크기를 키워 가독성을
높이고, 계정 추가/엑셀 등록 정사각형 칸의 크기를 학생 목록 타일과
동일한 크기(tileSize)로 통일했다.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
계정 추가/엑셀 등록 정사각형 칸은 기존 크기의 25%로 축소하고,
학생 목록 타일은 기존보다 50% 더 큰 정사각형으로 확대. 목록 폭은
더 이상 위 두 칸 폭에 종속되지 않고 전체 폭을 사용하도록 변경.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
웹 넓은 화면에서 계정 추가/엑셀 일괄 등록을 정사각형 2칸으로
나란히 배치(왼쪽 계정 추가, 오른쪽 엑셀 등록)하고, 그 아래 학생
목록을 두 칸 합친 폭에 맞춘 타일 그리드로 변경. 각 타일은 아이콘/
이름/상태/액션 버튼을 모두 중앙 정렬. 폰 화면은 기존처럼 세로 스택
유지.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
웹(넓은 화면)에서 항상 2개씩 줄바꿈되던 버그 수정. 학생 대시보드와
동일하게 LayoutBuilder로 폭이 800 이상이면 한 줄에 5개, 좁으면
기존처럼 2개씩 보이도록 함.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
패드는 NFC를 못 쓰므로 학생이 사용 시간/목적을 신청하면 선생님이
대시보드의 반출 대장에서 승인/거절하는 흐름을 추가. 저울-아두이노
연동(무게 기반 픽업/반납 감지)은 백엔드에 구현되어 있으나 실기기
연동은 추후 진행.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 두 화면이 서로 다른 기능만 갖고 있던 문제 해결: 선생님 화면(엑셀 일괄등록,
학년 지정, 커스텀 초기비번)에 마스터 화면에만 있던 실시간 학생 목록 조회 +
기기 리셋(학생이 폰 바꿨을 때 재등록용) 기능을 합침
- 학번을 직접 타이핑하던 블라인드 학년변경/삭제 다이얼로그를 목록의
행별 액션(학년 칩, 기기 리셋 버튼, 삭제 버튼)으로 교체
- 계정 생성/삭제/학년변경 성공 시 목록 자동 새로고침
- 마스터(2061) 계정의 "학생 계정 관리" 카드도 이 통합 화면으로 연결하고,
중복되던 student_management_screen.dart / student_management_controller.dart 삭제
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 학생 계정 관리 화면에 드래그앤드롭/클릭 업로드 영역 추가
(excel, desktop_drop, file_picker 패키지 도입)
- .xlsx 파싱 → 미리보기 팝업 → 확인 후 한 명씩 순서대로 계정 생성,
결과(성공/실패)를 요약해서 보여줌. 초기 비밀번호는 1234 고정
- file_picker의 웹 구현체가 pickFile(s)를 아직 구현하지 않아서
(UnimplementedError) 웹에서는 package:web으로 직접 <input type=file>을
다뤄서 우회 (lib/function/excel_file_picker_web.dart), 다른 플랫폼은
기존 file_picker 사용 (excel_file_picker_io.dart)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 학생 계정 관리 화면에 학번으로 학년을 지정/변경하는 카드+다이얼로그 추가
- 계정 생성 성공 판정을 HTTP 상태코드가 아닌 응답 status 필드로 정확히 확인하도록 수정
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 실시간 출석 현황을 학년별 섹션으로 묶어서 표시 (백엔드에 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>