ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
장평중학교 1학년 정보과 수업 포털
Translation pending
EducationTypeScript · CSSGitHub @kuekkuek85-85OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
장평중학교 1학년 정보과 수업 포털 · 2026학년도 2학기 하나의 대문에 들어오면 오늘 자기 반 수업으로 바로 이어지는 웹앱. 설계 근거는 PRD.md에 있다. • 수업 진입점 — 코드 2자리 + 학번 5자리로 오늘 수업에 진입 • 감정 체크 — 무드미터 4사분면, 익명 집계는 교실 앞 화면에 공유 • 한 줄 성찰 — 차시별 질문, 입력 중 자동 임시저장, 학기 누적 기록 • 출석 확인 — 인증 완료 시각(접속 로그)으로 확정 • 교사 대시보드 — 접속자 명단, 감정·성찰 열람, 명렬표·차시·시간표 관리 기술 스택: Next.js 16 (App Router) · React 19 · Tailwind CSS 4 · Firebase Firestore · Vercel 학생 브라우저는 Firestore에 직접 접근하지 않는다. 학생 화면의 모든 읽기·쓰기는 Next.js Route Handler(서버)를 거치고, 서버만 Firebase Admin SDK를 쓴다. 그래서 firestore.rules를 전면 차단으로 둘 수 있고, 명렬표 112명이 클라이언트로 통째로 내려가는 경로가 아예 존재하지 않는다.Read the full README ↗
장평중학교 1학년 정보과 수업 포털 · 2026학년도 2학기
하나의 대문에 들어오면 오늘 자기 반 수업으로 바로 이어지는 웹앱. 설계 근거는 PRD.md에 있다.
기술 스택: Next.js 16 (App Router) · React 19 · Tailwind CSS 4 · Firebase Firestore · Vercel
학생 브라우저는 Firestore에 직접 접근하지 않는다. 학생 화면의 모든 읽기·쓰기는 Next.js
Route Handler(서버)를 거치고, 서버만 Firebase Admin SDK를 쓴다. 그래서
firestore.rules를 전면 차단으로 둘 수 있고, 명렬표 112명이 클라이언트로
통째로 내려가는 경로가 아예 존재하지 않는다.
코드를 학번보다 먼저 받는다. 학번이 규칙적(10209)이라 학번을 먼저 받으면 아무 숫자나
넣어 이름을 조회할 수 있다. 코드가 앞에 있으면 그 교실에 있는 학생만 이름 확인 화면에 도달한다.
수업 코드는 (날짜, 교시, 반)에 묶이므로 다른 반 코드를 알아내도 통과하지 못한다.
세션에 스냅샷을 복사한다. 교사는 1반 수업을 해보고 부족한 부분을 다음 반 수업 전에 고친다. 차시 계획만 수정하면 이미 끝난 1반 기록이 소급 변경되어 "1반은 어떤 질문에 답한 것인가"를 알 수 없게 된다. 그래서 세션 생성 시점에 슬라이드 URL·성찰 질문을 세션으로 복사하고, 수정은 아직 시작하지 않은 세션에만 반영한다.
공유 화면과 개별 열람 화면은 API부터 분리했다. 교실 앞에 띄우는
/teacher/board가 쓰는 /api/teacher/board 응답에는 학번·이름·이유가 아예 들어 있지 않다.
화면 코드가 실수해도 개인 응답이 뜰 수 없다.
Firebase 콘솔에서 프로젝트를 연다 (없으면 생성).
asia-northeast3 (서울). 생성 후 변경할 수 없다.firestore.rules 내용을 규칙 탭에 붙여넣고 게시.
서버는 Admin SDK로 접근하므로 이 규칙의 영향을 받지 않는다.</>) 추가 → firebaseConfig 값을 복사*.vercel.app 또는 사용할 도메인) 추가. localhost는 기본 포함.cp .env.example .env.local
.env.local을 열어 값을 채운다.
| 변수 | 어디서 얻는가 |
|---|---|
NEXT_PUBLIC_FIREBASE_API_KEY 등 | 2.1-3의 firebaseConfig |
FIREBASE_PROJECT_ID / CLIENT_EMAIL / PRIVATE_KEY | 2.1-6의 서비스 계정 JSON |
SESSION_SECRET | node -e "console.log(require('crypto').randomBytes(32).toString('base64'))" |
TEACHER_EMAILS | 교사 Google 계정 이메일 (쉼표로 구분) |
TEACHER_EMAILS가 비어 있으면 아무도 교사 화면에 들어올 수 없다. 열어두는 쪽이 더 위험하므로
의도한 기본값이다.
npm install
npm run dev # http://localhost:3000
npx vercel # 프리뷰
npx vercel --prod # 운영
.env.local의 모든 변수를 Vercel 프로젝트 환경변수에도 등록한다. FIREBASE_PRIVATE_KEY는
줄바꿈이 포함된 값이라 \n 이스케이프 그대로 붙여넣어도 된다 (서버에서 복원한다).
/teacher 접속 → Google 로그인학번,이름 CSV 업로드 (예: 10101,김철수)수업 중에는 대시보드에 접속자가 5초마다 갱신된다. 수업이 끝나면 수업 종료를 눌러 코드를 만료시키고, 감정 응답을 확인한 뒤 수업 후 메모를 남긴다. 다음 반 수업 전에 그 메모를 보는 것이 개선 루프의 출발점이다.
교사가 학생 화면을 직접 걸어보기 위해 각 반 30번을 테스트 계정으로 두었다.
| 학번 | 이름 | 반 |
|---|---|---|
10130 | 가길동 | 1반 |
10230 | 나길동 | 2반 |
10330 | 다길동 | 3반 |
10430 | 라길동 | 4반 |
30번을 쓰는 이유: 실제 학생은 128번까지라 겹치지 않고, 임시 번호(9099번)와 달리 정규 학생과
똑같은 경로로 진입하므로 학생이 실제로 겪는 화면을 그대로 볼 수 있다.
주의 — 출석 집계에 포함된다. 이 학생들도 명렬표에 있으므로 대시보드의 정원 수에 잡히고,
접속하지 않으면 "아직 안 들어온 학생"에 뜬다. 예를 들어 1반은 정원이 28명(실제 27 + 테스트 1)으로
표시된다. 수업 중 숫자가 헷갈리면 /teacher/students 에서 해당 학번을 삭제하면 된다.
/teacher/data에서 내려받는다./teacher/data에서 "감정 — 이유 한 줄"만 지운다. 아이콘·색은 남는다.students 학번(문서ID) · 이름 · 반 · 번호 · 임시여부
lessonPlans 차시번호 · 제목 · 슬라이드URL · 성찰질문 · 감정체크여부 ← 반과 무관, 4반 공용
classSessions 문서ID = 날짜__교시__반 · 수업코드 · 스냅샷 · 교사메모
codeReservations 문서ID = 날짜__코드 ← 코드 중복 발급 방지
attendance 학번 · sessionId · 접속시각 ← 출석
moodEntries 학번 · sessionId · 감정 · valence/arousal · 이유 · 확인여부
reflections 학번 · sessionId · 내용 · draft
meta/purgeLog 마지막 일괄 삭제 일자
활동 기록에는 학번만 저장한다. 이름은 students에만 있고 화면에 보여줄 때만 조인하므로,
기록 데이터가 유출되어도 숫자만 남는다.
문서 ID로 중복을 막는다. 세션 ID가 날짜__교시__반, 코드 예약 ID가 날짜__코드라서,
두 요청이 동시에 들어와도 Firestore가 뒤엣것을 거부한다. 조회 후 배정하는 방식이면 같은 날 두 반에
같은 코드가 나갈 수 있고, 그러면 한쪽 반 학생 전원이 반 불일치로 막힌다.
학번 범위: 정상 01~30번(정원 28명 + 전입 여유), 임시 90~99번. 그 사이(31~89)는 오타로
보고 거부한다.
PRD의 로드맵 중 이번 범위에 넣지 않은 것들: