"만들 줄 아는 교사"에서
"지킬 줄 아는 교사"로
AI로 웹앱을 만드는 시대, 우리에게 부족한 건 만드는 기술이 아니라 학생 데이터를 다루는 판단력입니다. 오늘 두 가지를 모두 가져가시게 됩니다.
① 반응속도 게임을 통해 접하는 백엔드!
게임 한 판에 참여하면 내 기록이 실시간으로 강사 화면에 모입니다. 그 뒤에 백엔드가 있다는 걸 몸으로 먼저 느낍니다.
② 직접 만들기
Supabase로 나만의 백엔드를 만들고, 학생 데이터가 모이는 앱과 교사 대시보드를 연결합니다.
③ 의심하기
방금 만든 앱을 놓고 묻습니다 — "이 데이터, 모아도 되는 걸까?" 바이브코딩의 7가지 주의사항을 해부합니다.
④ 판단하기
데이터 판사로 내 아이디어를 🟢🟡🔴 판정하고, 학운위 에듀테크 심의까지 준비합니다.
📋 시작 전, 딱 1분 설문
오늘 눈높이를 맞추기 위한 익명 설문입니다. 정답이 없으니 편하게 골라 주세요. 제출하면 결과가 바로 아래에 실시간 막대그래프로 그려집니다 — 우리 모임이 지금 어디쯤 있는지 함께 봅니다.
오늘의 흐름
| 시간 | 내용 | 탭 |
|---|---|---|
| 0:00–0:10 | 워밍업 — 반응속도 대결 + 실시간 대시보드 (그리고 반전 질문) | 🎮 워밍업 |
| 0:10–0:25 | 개념 — 익숙한 앱(구글폼)으로 보는 프론트·백엔드·API·DB | 🧠 개념 |
| 0:25–0:33 | 사례 — 강사의 실제 교실 앱 7개와 그 뒤의 백엔드 | 🗺️ 사례 |
| 0:33–1:00 | 실습 — Supabase 백엔드 구축 (따라하기 매뉴얼) | 🛠️ 실습 |
| 1:00–1:15 | 위험 — 바이브코딩의 7가지 주의사항 + 보안규칙(RLS) 시연 | ⚠️ 주의사항 |
| 1:15–1:28 | 판단 — 데이터 판사로 내 데이터 아이디어 판정하기 | ⚖️ 데이터 판사 |
| 1:28–1:38 | 심의 — 학교운영위원회 에듀테크 심의 준비 | 🏛️ 심의 |
| 1:38–1:45 | 마무리 — 내가 만들고 싶은 도구 한 줄 기획서 | 📝 마무리 |
직접 배포까지 해보고 싶으시면, 제가 만든 매뉴얼을 참고하세요 👇
🧠 우리 반 반응속도 대결
초록불이 켜지는 순간, 0.001초라도 빨리! 스마트폰으로 접속해서 함께 플레이해 주세요. 선생님의 기록은 강사 화면의 대시보드에 실시간으로 나타납니다.
…그런데, 방금 여러분의 기록은
지금 어디에 있을까요?
그 기록, 누가 볼 수 있을까요? 선생님은 방금 데이터 수집에 동의하신 적 있으신가요?
학생들에게도 똑같은 일이 일어납니다. 이제 교사가 AI로 앱을 뚝딱 만들어, 학생에 관한 정보와 학습 데이터를 수집해 선생님이 보기 편한 형태로 저장하는 것이 가능한 시대가 왔습니다.
그런데 '보안'은 완전히 다른 문제입니다. 바이브코딩으로 급히 배포된 서비스에서 보안 사고가 끊이지 않습니다 — 통신사 해킹, 티빙 해킹 같은 사건만 봐도 대규모 보안은 이미 개인이 감당할 수 있는 영역을 넘어섰습니다.
그래서 오늘은 "무조건 좋다, 뭐든 다 된다"고 말하지 않겠습니다. 대신 선생님과 학생 모두를 안전하게 지키는 방식으로, '선생님만의 서비스'를 만드는 법을 함께 배웁니다. 데이터를 모으는 힘과 지키는 책임을 한 번에.
선생님이 이미 사용하고 있던 웹앱 구조
프론트엔드·백엔드·API·데이터베이스 — 말은 낯설지만, 선생님들은 이미 구글폼·구글시트·클래스룸·노션·패들렛·카훗을 쓰며 이 구조를 매일 경험하고 있습니다. 새 지식을 처음 배운다기보다, 익숙한 프로그램에 개발 용어를 붙여 보는 시간입니다.
학생의 구글폼 화면
질문·입력창·선택지·제출 버튼
프론트엔드 · 사람이 직접 보는 화면
보이지 않는 처리 시스템
제출 확인·시각 기록·형식 검사·자동 채점·저장 위치 결정
백엔드 · 화면 뒤 처리
구글시트 응답표
제출시각·학번·이름·응답·점수
데이터베이스 · 항목별로 쌓이는 표
교사의 응답 확인 화면
응답 목록·통계·그래프·학생별 결과
프론트엔드 · 교사 화면도 프론트엔드!
프론트엔드 · 백엔드 · 데이터베이스 · API
방금 구글폼에서 본 네 가지를, 익숙한 앱 예시로 하나씩 짚어 봅니다.
프론트엔드 Frontend
사람이 직접 보고 누르는 화면. 화면·버튼·글자·색·그래프·애니메이션.
예: 구글폼 질문·제출 버튼 · 클래스룸 과제 화면 · 노션 페이지 · 패들렛 · 카훗 문제 · 반응속도 게임 · 교사 대시보드
HTML·CSS·자바스크립트로 만드는 부분 — 지금까지 AI로 만든 웹앱이 주로 여기입니다.
백엔드 Backend
화면 뒤에서 실제 업무를 처리하는 시스템. 구글폼 제출 버튼을 누르면 뒤에서 — 응답 전달받기·빠진 내용 확인·제출 시간 기록·객관식 자동 채점·저장 위치 결정·권한 확인·데이터 정리해 화면에 보내기.
클래스룸도 뒤에서 학생 정보·제출 여부·파일 권한·점수를 처리합니다.
※ 백엔드(작업 처리)와 데이터베이스(데이터 보관)는 서로 다릅니다.
데이터베이스 Database
응답·기록이 쌓이는 데이터 표. 예: 구글폼 응답이 쌓이는 구글시트 · 노션 데이터베이스 · 클래스룸 제출 기록 · 나이스 출결·성적 · Supabase 테이블.
| 제출 시간 | 학번 | 이름 | 반응시간 |
|---|---|---|---|
| 10:21 | 20301 | 김학생 | 0.24초 |
| 10:22 | 20302 | 이학생 | 0.31초 |
처음엔 '인터넷에 있는 체계적인 표'라고 생각하면 쉽습니다(구글시트와 완전히 같진 않아요).
API
프로그램 사이에서 요청·응답을 주고받는 정해진 방법. 버튼을 눌렀다고 데이터가 저절로 저장되진 않습니다 — 한 프로그램이 다른 프로그램에 "이 기록 저장해 줘", "우리 반 기록 보여 줘"처럼 요청해야 합니다.
↓ 아래에서 더 자세히 봅니다.
API — 요청과 응답을 주고받는 약속
API는 단순한 '연결선'이 아니라, 무엇을·어디에·어떤 형식으로 요청할지 정해 둔 약속입니다.
요청 Request · 부탁
프론트엔드가 다른 시스템에 필요한 일을 부탁 — "20301번 학생의 반응시간 0.24초를 저장해 줘."
응답 Response · 답
백엔드가 결과를 돌려줌 — ✅ "저장 완료되었습니다." · ❌ "학번이 없어 저장할 수 없습니다."
외부 데이터를 가져오는 API — 기상청 데이터 탐구 수업
수업용 웹앱
"서울의 오늘 시간별 기온·강수량을 보내 주세요"
기상청 API
요청 형식·지역·날짜·기상 요소·API Key 확인
기상청 서버·DB
관측 자료 검색·정리
수업용 웹앱
표·꺾은선그래프·지도·평균·지역 비교로 표현 (예: 09:00 · 27.4℃ · 습도 68% · 풍속 2.1m/s)
API Key API 사용자 확인 번호
API는 요청·응답의 창구와 규칙, API Key는 그 API를 이용하도록 발급받은 사용자 확인 정보 — 둘은 다릅니다.
이걸로 제공자는 확인합니다: 등록된 사용자인지 · 몇 번 요청했는지 · 허용 횟수를 넘었는지 · 문제 요청이 어디서 왔는지.
익숙한 앱에서 보는 API
· 구글폼 → 구글시트: 응답이 자동 저장되는 경험은 API 역할을 이해하기 좋은 사례
· 클래스룸 → 드라이브: 제출 파일·상태 확인
· 노션 → 캘린더·자동화: 일정·데이터 연결
· 수업 웹앱 → 기상청: 관측 자료 가져오기
· 반응속도 게임 → Supabase: 기록 저장·불러오기
가져오는 API vs 저장하는 API
외부 데이터를 가져오는 API · 기상청 API
요청: "서울의 기온을 보내 줘" → 기상청 데이터를 수업용 웹앱으로 받아옴.
· 데이터의 주인 = 기상청 · 주로 조회 · 받아온 데이터를 표·그래프·지도로 표현
우리 데이터를 저장·불러오는 API · Supabase API
요청: "반응시간 0.24초 저장해 줘" / "저장된 기록 모두 보내 줘"
· 데이터의 주인 = 앱을 만든 교사 · 저장·조회 · 교사 대시보드에서 확인
혼자 기억하는 웹앱에서, 함께 연결되는 웹앱으로
기존 웹앱 · 내 기기 안에만 저장
· 학생 폰·현재 브라우저의 localStorage에만 저장
· 다른 기기에서는 확인하기 어려움
· 학생 폰 입력을 교사 컴퓨터에서 바로 못 봄
· 브라우저 데이터가 삭제되면 기록이 사라질 수 있음
백엔드 연결 웹앱 · 같은 DB 공유
· 모든 학생 기기가 같은 Supabase DB를 바라봄
· 학생 기록이 한곳에 모임
· 교사 대시보드에서 전체 확인 가능
· 여러 기기가 동일한 데이터를 공유
반응속도 게임의 데이터 여행
학생 반응속도 게임
초록불 보고 탭 → 반응시간 측정
프론트엔드
Supabase 백엔드
요청 형식·권한 확인, 저장 작업 처리
백엔드
Supabase 데이터베이스
학급·번호/이름·반응시간·제출시각이 한 행으로
데이터베이스
교사 대시보드
전체 확인·빠른 순 정렬·그래프·순위
프론트엔드
백엔드에서 할 수 있는 일
오늘 쓰는 세 가지(데이터베이스·API·호스팅)에 집중하고, 나머지는 다음 단계로 눈도장만 찍어 두세요.
데이터베이스 Database
학생의 기록이 표 형태로 저장되는 곳.
API
프론트엔드가 데이터를 저장하거나 불러오도록 요청하는 방법.
호스팅 Hosting
HTML 웹앱을 인터넷 주소로 공개해 학생들이 접속하게 하는 기능. (예: GitHub Pages)
인증 Auth
로그인을 만들어 누가 접근할 수 있는지 통제. 교사 전용 대시보드에 필요.
스토리지 Storage
사진·소리·문서와 같은 파일 저장.
실시간 Realtime
데이터가 바뀌는 순간 연결된 화면에 변경 사항을 반영. 오늘 대시보드가 일정 시간마다 데이터를 다시 불러오는 것은 이 기능을 단순화한 방식입니다.
Supabase = 웹앱의 백엔드를 빌려 쓰는 서비스
백엔드를 직접 개발하고 서버를 운영하는 건 전문적인 작업입니다. 우리는 이미 만들어진 백엔드를 빌려 씁니다 — 이런 서비스를 BaaS(Backend as a Service · 서비스형 백엔드)라고 부릅니다.
무료로 시작
무료 요금제로 일반적인 학급·학년 규모의 간단한 수업 활동을 시작할 수 있습니다.
표로 확인
데이터가 테이블 형태로 보여, 교사가 직접 행을 확인하고 관리할 수 있습니다.
여러 기기가 공유
학생의 스마트폰과 교사의 컴퓨터가 같은 데이터베이스를 바라봅니다.
다른 웹앱에도 재사용
특정 AI 앱 빌더의 화면에만 종속되지 않고, 여러 웹앱에서 연결해 사용할 수 있습니다.
AI 앱 빌더와 백엔드의 관계
AI 앱 빌더가 백엔드 연결을 대신 도와주더라도, 실제 데이터가 어디에 저장되고 누가 접근할 수 있는지는 사용자가 이해해야 합니다.
구글폼·패들릿 두고 왜 직접 만드나요?
정직하게 말씀드리면 — 단순 설문·의견 수합이면 구글폼이 최고입니다. 코딩도 필요 없고 5분이면 끝나니까요. 직접 만든 백엔드는 그 도구들이 못 하는 한 가지가 필요할 때 빛납니다. 바로 수집과 동시에 '가공·변환·반영'입니다.
| 무엇을 원하나 | 구글폼 | 패들릿 | 노션 | 직접 만든 백엔드 |
|---|---|---|---|---|
| 데이터 수집 | ⭕ 설문에 강함 | ⭕ 벽에 붙이기 | ⭕ 표·페이지 | ⭕ 활동 자체가 수집기 |
| 실시간 반영 넣는 즉시 모두의 화면에 | ❌ 응답→시트(지연) | 🔺 벽 공유 | 🔺 문서 공유 | ⭕ 즉시 대시보드·랭킹 |
| 수집과 동시에 가공 평균·등수·조건 판정 | ❌ 사람이 시트에서 | ❌ | 🔺 수식 일부 | ⭕ 앱이 자동으로 |
| 수업 활동과 일체화 게임·시뮬레이션 | ❌ 설문 화면 | ❌ | ❌ | ⭕ 탐구 활동에 내장 |
| 데이터 소유·재사용 | 🔺 구글 안에 | 🔺 서비스 안에 | 🔺 서비스 안에 | ⭕ 내 DB·CSV 자유 |
| 무료 규모 | ⭕ 넉넉 | ❌ 무료 3개뿐 | 🔺 제한 | ⭕ 500MB·앱 무제한 |
| 시작 난이도 | ⭐ 매우 쉬움 | ⭐ 쉬움 | ⭐⭐ 보통 | ⭐⭐⭐ (오늘 배움) |
탐구 데이터는 모으는 게 끝이 아니라 '가공해서 결론을 보는 것'이 목적입니다. pH 측정값을 받아 즉시 반 평균 곡선으로, 운동 전후 심박수를 받아 즉시 증가율로 — 수집과 분석 사이의 '사람 손일'을 없애는 것, 그게 직접 만든 백엔드의 진짜 차별점입니다.
먼저, 각 도구가 잘하는 것부터 (정직하게)
경쟁이 아닙니다. 아래 도구들은 각자 자기 자리에서 훌륭합니다 — 굳이 다시 만들 필요 없는 영역이 분명히 있어요.
구글폼
가장 쉽고 빠름(5분). 응답이 구글시트에 자동 저장 · 자동 요약 차트 · 채점 퀴즈. 최고의 순간 — 단순 설문·사전점검·퀴즈·의견 수합.
MS Forms
구글폼과 쌍둥이. 학교가 MS365·팀즈를 쓰면 계정·팀즈 통합이 매끄럽고 응답 요약이 강함. 최고의 순간 — 팀즈 기반 학교의 설문·퀴즈.
패들렛
실시간 협업 벽. 글·사진·영상·링크를 함께 붙이고 나눔. 시각적·즉흥적. 최고의 순간 — 브레인스토밍·의견 전시·작품 공유.
노션
구조화된 문서+DB. 수식·관계형·페이지. 정리와 아카이브에 강함. 최고의 순간 — 포트폴리오·협업 기록·자료 정리.
그럼 언제 직접 만드나 — 과목별 예시
공통 조건은 셋. 이 중 하나라도 필요하면 직접 만들 값어치가 있습니다.
① 실시간 반영
넣는 즉시 반 전체 화면·그래프에 표시
② 자동 변환
모으면서 계산·집계·분류까지 한 번에
③ 활동에 내장
설문이 아니라 게임·측정 자체가 수집기
| 과목 | 이런 수업·활동 | 직접 만든 도구만의 차별점 (폼·패들렛은 여기서 멈춤) |
|---|---|---|
| 🔬 과학 | 반응속도·pH·심박수·용해도 등 측정 실험 | 조별 측정값이 즉시 반 전체 그래프·평균·이상치로. 운동 전후 심박수는 증가율 자동 계산. (폼: 숫자만 받고 교사가 나중에 그래프) |
| 🔢 수학 | 주사위·동전 확률 실험, 실시간 개념 진단 | 수백 번 시행이 자동 누적 → 대수의 법칙 수렴 그래프. 오답이 유형별 자동 분류돼 "지금 60%가 이 개념 오답"을 교사 화면에 즉시. (폼: 응답 후 수동 분석) |
| 📖 국어 | 낱말·문장 모으기, 토론 찬반 | 모은 낱말이 실시간 워드클라우드·빈도로, 찬반이 근거 유형별 즉석 집계로. (패들렛: 붙이기만, 자동 분석 없음) |
| 🌏 사회 | 동네·학교 조사, 모의 선거·설문 | 입력이 실시간 지도·차트로 매핑, 투표가 즉석 개표 그래프로. (폼: 시트로 나온 뒤 수동 시각화) |
| 🔤 영어 | 단어·표현 즉답 퀴즈·배틀 | 정답률·반응시간이 실시간 랭킹, 자주 틀리는 표현이 자동 집계. 게임 자체가 데이터. (폼: 퀴즈는 되나 실시간 반영·랭킹 약함) |
| 🎨 예체능 | 체력 측정, 음정 맞히기 | 기록이 개인 향상도·반 분포로 자동, 음정 점수가 실시간 집계. 활동이 곧 측정. (폼·패들렛: 활동 내장 불가) |
🔬 과학 실험수업 — 이런 건 패들렛·구글폼으로 못 합니다
공통점: 여러 조의 측정값이 실시간으로 하나의 그래프로 합쳐지고, 측정하는 순간 기울기·평균·곡선이 자동으로 그려집니다. 폼은 '숫자 받기'까지, 패들렛은 '붙이기'까지 — 그래프·곡선·자동계산은 사람이 나중에 해야 하죠.
| 단원 · 실험 | 학생이 하는 것 (수집) | 직접 만든 도구만의 차별점 |
|---|---|---|
| 자극과 반응 반응속도 | 초록불에 탭, 3회 측정 | 3회 자동 평균 → 반 히스토그램·랭킹 실시간. 개인 vs 반 평균 즉시 비교 |
| 상태 변화·열 냉각·가열 곡선 | 30초마다 온도 입력 | 조별 냉각곡선이 실시간으로 겹쳐 그려짐 → 어는점 평평구간이 한눈에. (시간에 따라 쌓이는 곡선 = 폼·패들렛 불가) |
| 용해도 | 온도별로 녹인 양 입력 | 점이 찍히며 용해도 곡선이 자동 완성, 조별 데이터 합쳐 오차↓ |
| 밀도 | 여러 물체의 질량·부피 입력 | 즉시 질량–부피 산점도, 기울기 = 밀도 자동. 같은 물질끼리 한 직선에 모임 |
| 산과 염기·중화 | 조별 pH 측정값 입력 | 즉시 반 평균·분포, 중화점 실시간 표시, 이상치 자동 빨강 |
| 전기·옴의 법칙 | 전압–전류 측정 입력 | 즉시 V–I 그래프, 기울기 = 저항 자동 계산 |
| 빛과 소리 음정·진동수 | 폰 마이크로 소리 내기(활동 내장) | 도레미·진동수 자동 판정·집계, 반 분포. (마이크 센서 활동 = 폼 불가) |
| 운동과 에너지 진자 주기 | 진자 길이별 주기 측정 | 즉시 길이–주기 그래프, 반 데이터 합산으로 측정 오차 감소 |
| 생물 식물 생장 관찰 | 매일 잎 길이·개수 입력(연속) | 생장곡선 자동 누적, 조·조건(빛·물)별 비교. (여러 날 누적 = 폼·패들렛 불가) |
| 지구과학 달 관측 | 여러 날 달 모양·고도 입력 | 위상 변화·고도 그래프 자동, 반 전체 관측 합쳐 빈틈 메움 |
· 탐구 활동형 수집 + 실시간 반영 + 자동 가공 + 여러 수업에 재사용 → 직접 만든 백엔드가 유리할 수 있습니다!
도구를 아는 것보다 "언제 무엇을 쓸지" 판단하시는 것을 권유드립니다!
이미 제 교실에서 돌아가고 있습니다
이론이 아닙니다. 아래는 강사가 실제 수업·학급에서 운영 중인 웹앱들이고, 전부 오늘 배우실 방식 그대로 만들어졌습니다. 지도를 눌러 직접 들어가 보세요.
| 앱 | 학생이 하는 일 | 백엔드가 하는 일 |
|---|---|---|
| 🧠 브레인브레이크랩 | 교실 미니게임 플레이 | 점수 저장 → 전국 랭킹 집계 |
| 🎗️ 롤링페이퍼 | QR로 접속해 메시지 작성 | 메시지 저장 → 교사 전시 보드로 출력 |
| 🌳 추억의 숲(다짐나무) | 3D 공간에서 학급 추억 기록 | 실시간 동시접속 · 같은 맵 공유 |
| 🍎 질문 과수원 | 수업 질문 만들어 제출 | 질문 수집 → 게시 |
| 🏫 수업허브 | —(교사용) | 수업 데이터를 교사 대시보드로 |
| 📢 해누리 알리미 | 공지 확인 | 공지 저장 → 학급 화면에 배포 |
| 🌊 지진 매뉴얼 | 모둠별 매뉴얼 공동 작성 | 협업 내용 실시간 저장 |
오늘 여러분은 그중 1개를 직접 만듭니다. 그리고 그 1개면, 앞으로 만드실 수업 앱 대부분에 충분합니다.
🛠️ 하나의 데이터 수집 웹앱 만들기
오늘은 손으로 직접 만드는 시간입니다. 먼저 공통 실습(Supabase 준비)을 함께 한 뒤, 선택 실습에서 둘 중 하나를 골라 만듭니다. 막히면 손 들어 주세요. 초록 상자(📖)는 용어 설명입니다.
1
Supabase 가입하고 프로젝트 만들기
약 5분- 크롬에서 supabase.com 접속 → 오른쪽 위 [Start your project](프로젝트 시작) 클릭.
- 가입 방법 선택 — Continue with GitHub 또는 이메일 가입. GitHub 계정이 없으시면 이메일 가입이 빠릅니다. (가입 후 메일함에서 인증 메일 확인!)
- 로그인되면 [New project](새 프로젝트) 클릭. 조직(Organization)을 만들라고 하면 이름은 자유롭게(예: 내 이름) 두고 무료(Free) 요금제 그대로 진행.
- 프로젝트 정보를 입력합니다:
· Name(이름):science-class처럼 영문으로
· Database Password(데이터베이스 비밀번호): [Generate a password]를 눌러 자동 생성 → 어딘가에 복사해 보관 (오늘 다시 쓸 일은 없지만 잃어버리면 곤란합니다)
· Region(리전): Northeast Asia (Seoul) — 반드시 서울을 선택하세요! - [Create new project] 클릭 → 1~2분 기다리면 내 백엔드가 완성됩니다. ☕
2
내 백엔드의 주소와 열쇠 복사하기
약 3분웹앱(프론트)이 내 백엔드를 찾아오려면 주소(URL)와 열쇠(API 키) 두 가지가 필요합니다.
- 왼쪽 아래 ⚙️ Project Settings(프로젝트 설정) 클릭.
- Data API 메뉴에서 Project URL을 복사해 메모장에 붙여 둡니다. (모양:
https://xxxx.supabase.co) - API Keys 메뉴에서 anon 또는 publishable이라고 표시된 키를 복사해 메모장에 붙여 둡니다. (모양:
eyJhb…또는sb_publishable_…로 시작하는 긴 문자열)
Project URL = 집 주소
내 백엔드가 인터넷에서 갖는 주소
📍 찾는 곳: ⚙️ Project Settings → Data API
anon key = 손님 열쇠
웹앱에 넣는 공개용 출입증
📍 찾는 곳: ⚙️ Project Settings → API Keys
A · 반응속도 게임으로 수집
준비된 게임+대시보드에 내 키만 꽂아 바로 수집. 쉬움·빠름 — 바로 아래 A-1~A-3.
B · 자유 기획 — 내 앱 직접 만들기
계획을 적으면 프롬프트 자동 생성 → AI로 나만의 수집앱. 도전 — 조금 더 아래 B 참고.
표(테이블) 만들기 — SQL 한 방 복붙
약 4분데이터가 담길 표를 만듭니다. 메뉴를 눌러가며 만들 수도 있지만, 오늘은 준비된 SQL을 통째로 붙여넣는 방법을 씁니다. 표 생성 + 보안 규칙까지 한 번에 됩니다.
- 왼쪽 메뉴에서 SQL Editor(SQL 편집기) 클릭.
- 아래 상자의 [📋 복사]를 눌러 전체를 복사 → SQL Editor의 빈 칸에 붙여넣기.
- 오른쪽 아래 [Run](실행) 클릭.
-- 반응속도 기록이 담길 표 + 보안 규칙 (전체 복사해서 실행하세요) create table if not exists public.reaction_results ( id uuid primary key default gen_random_uuid(), created_at timestamptz not null default now(), room text not null default 'demo', -- 반 코드(예: '3-2') player text, -- 익명 라벨('1번 선수' 등) — 실명 금지! ms int not null, -- 반응 시간(밀리초) mode text, rounds int ); create index if not exists reaction_results_room_created_idx on public.reaction_results (room, created_at desc); -- 행 수준 보안(RLS) 켜기 — 이 두 글자가 학생 데이터를 지킵니다 alter table public.reaction_results enable row level security; -- 규칙 1: 누구나 기록을 '넣을' 수는 있다. 단, 말이 되는 값만. drop policy if exists "anon can insert reaction" on public.reaction_results; create policy "anon can insert reaction" on public.reaction_results for insert to anon with check ( ms between 50 and 5000 and char_length(room) between 1 and 40 ); -- 규칙 2: 대시보드가 결과를 '읽을' 수 있다. (수정·삭제는 아무도 불가) drop policy if exists "anon can read reaction" on public.reaction_results; create policy "anon can read reaction" on public.reaction_results for select to anon using ( true );
Success. No rows returned라고 뜨면 성공입니다. ("돌려줄 데이터가 없다"는 뜻으로, 오류가 아닙니다!) 왼쪽 메뉴 Table Editor를 열면 reaction_results 표가 생긴 것을 눈으로 확인할 수 있습니다.게임과 대시보드에 열쇠 꽂기
약 5분배포받은 실습 파일 2개를 메모장(또는 VS Code)으로 열어, 방금 복사한 주소와 열쇠를 붙여넣습니다.
- 게임 파일(sonic.html)을 메모장으로 열기 →
Ctrl+F로YEONSU검색 → 다음 두 줄을 내 것으로 교체:url : '내 Project URL'key : '내 anon 키' - 바로 아래
room : ''은 그대로 두셔도 됩니다 — 접속 주소 뒤에?room=반코드를 붙이는 방식을 쓸 것이기 때문입니다. - 대시보드 파일(연수_반응속도_대시보드.html)을 열기 →
CFG검색 → 마찬가지로url과key를 내 것으로 교체. - 두 파일 모두 저장(Ctrl+S).
?room=3-2, 옆 반은 ?room=3-3 — 같은 표에 쌓여도 대시보드에서 반별로 갈라 볼 수 있습니다. 오늘은 서로 겹치지 않게 본인 이니셜(예: ?room=jsj)을 쓰세요.key : 'eyJhb...' 모양이 되어야 합니다.시험 운전 — 내 폰에서 게임하고, 내 대시보드로 보기
약 6분- 수정한 대시보드 파일을 더블클릭해 크롬으로 열기 → 반 코드 입력칸에 내 코드(예:
jsj) 입력 → [연결]. - 수정한 게임 파일도 크롬으로 열기 → 주소창 맨 뒤에
?room=jsj를 붙이고 Enter. - 게임에서 신경 반응속도를 선택하고 한 판 플레이!
- 결과 화면에 "📡 대시보드로 전송 완료!"가 뜨는지 확인.
- 대시보드 탭으로 돌아가면 — 몇 초 안에 내 기록이 그래프로 나타납니다. 🎉
- 내가 수집한 데이터는 어디서 볼 수 있을까요?! Supabase의 Table Editor를 열어 보세요. 방금 내 기록이 표의 행에 기록되어 있습니다 ^^
?room=3-2 붙인 QR을 칠판에 띄우면, 학생 30명의 폰 → 선생님 대시보드가 그대로 완성됩니다.🪄 B 코스는 이렇게 4단계로 흘러갑니다. 공통 실습에서 만든 Supabase(주소·열쇠)를 그대로 씁니다 — 새로 가입할 필요 없어요.
🪄 아이디어 적고 만들기 프롬프트 자동 받기
반응속도 실습이 정해진 걸 따라 하기였다면, 이번엔 내 수업앱을 자유롭게 기획합니다. 아래 항목을 촘촘히 채울수록 AI가 바로 쓸 수 있는 앱을 만들어 줍니다. 버튼을 누르면 프롬프트 2개(① 앱 만들기 → ② Supabase 표 만들기)가 자동 완성되고, 계획은 강사 화면과 참여 선생님 모두에게 공유됩니다. 완성한 앱은 강사가 대신 배포해 드려요.
"학생들 의견 모으는 앱"
"중2 과학 밀도 단원 도입에서, 모둠별로 물체가 뜰지/가라앉을지 예측을 모아 실시간 막대그래프로 보여주는 앱. 실명 없이 모둠 번호만."
프롬프트 ①로 앱 만들기 — AI에게 시키기
약 6분B-1에서 만든 프롬프트 ① · 앱 만들기를 [📋 복사] 하세요. 이 프롬프트 안에는 이미 내 Project URL·anon 키·반응형·익명 최소수집·service_role 금지가 다 채워져 있습니다.
- Claude(claude.ai) 또는 ChatGPT를 새 대화로 엽니다.
- 복사한 프롬프트를 붙여넣고 전송 → AI가 HTML 코드 한 덩어리를 만들어 줍니다.
- 코드 블록 위 [Copy] 로 전체 복사 → 메모장에 붙여넣고 파일 이름.html 로 저장(예:
내앱.html). 메모장 저장 시 파일 형식 '모든 파일', 인코딩 'UTF-8'. - 저장한
.html파일을 더블클릭해 크롬으로 열어 화면이 뜨는지 봅니다. (표는 아직 없어서 저장은 실패할 수 있어요 — 다음 B-3에서 표를 만듭니다.)
.html 파일이 크롬에서 열리고 입력 화면이 보이면 성공. 이제 저장할 '표'를 만들 차례입니다.프롬프트 ②로 표(테이블) 만들기 — RLS까지 한 번에
약 5분B-1에서 만든 프롬프트 ② · Supabase 표 만들기를 [📋 복사] 하세요. 이 프롬프트에는 RLS 켜기·최소권한·값 검증이 필수로 들어 있어, 나온 SQL이 안전한 표를 만들어 줍니다.
- 복사한 프롬프트를 같은 AI 대화(B-2에서 쓰던 창)에 붙여넣고 전송 → AI가 SQL 코드를 만들어 줍니다. 앱이 쓸 표 이름을 AI가 B-2에서 정했으니 이어서 하면 일치해요.
- 나온 SQL 전체를 복사.
- 내 Supabase 프로젝트 → 왼쪽 SQL Editor → New query → 붙여넣기 → Run(▶).
Success. No rows returned이 뜨면 성공. Table Editor에 새 표가 보입니다.
enable row level security 와 policy 문장이 있어야 합니다. 없으면 "RLS를 켜고 anon은 insert만 허용하도록 다시 만들어 줘"라고 하세요. RLS 없는 표 = 자물쇠 없는 창고입니다.시험 운전 — 내 폰에서 넣고, 화면에서 확인 & 강사 배포
약 5분- B-2에서 저장한
.html파일을 크롬으로 열어 실제로 한 번 입력·전송해 봅니다. - 화면 아래(또는 목록)에 방금 넣은 내용이 실시간으로 나타나는지 확인.
- Supabase Table Editor를 열어 표의 행(row)에도 그 값이 쌓였는지 눈으로 확인하면 완벽! 🎉
- 배포는 강사가 — B-1에서 [프롬프트 생성 & 강사에게 공유]를 눌렀다면 계획이 이미 강사에게 전달됐습니다. 완성한
.html파일만 강사에게 전달하면 인터넷 주소·QR로 만들어 드립니다.
모은 데이터 보고·분석하기 — Supabase에서 → 학생별 → 엑셀
수업 적용 · 집에서학생 기록은 두 곳에서 봅니다 — ① Supabase에서 바로 훑어보기(설치·다운로드 X), ② 엑셀·구글시트로 받아 본격 분석. 학생별 정리까지 순서대로 짚어드릴게요.
① Supabase에서 바로 보기
- 왼쪽 메뉴 Table Editor → 내 표(
reaction_results) 클릭. 학생 제출이 한 줄(행)씩 쌓인 게 그대로 보입니다 — 엑셀 화면과 똑같아요. - 열 제목을 클릭하면 정렬(빠른 순/느린 순), 위쪽 Filter 버튼으로 조건 걸러보기가 됩니다.
② 학생별로 정리하기 (오늘 앱은 익명 라벨 player가 곧 '학생')
- 쉬운 법: Filter →
player= '1번 선수' → 그 학생 기록만. 또는player로 정렬하면 같은 학생끼리 모입니다. - 정확한 법(SQL): SQL Editor에 아래를 붙여넣고 Run — 학생별 평균·횟수까지 한 번에.
-- 학생(player)별 평균 반응속도·측정 횟수 (빠른 순) select player, count(*) as 횟수, round(avg(ms)) as 평균ms from reaction_results group by player order by 평균ms;
③ 엑셀·구글시트로 받아 분석
- Table Editor 오른쪽 위 [Export] → Export as CSV → 파일 다운로드.
- 그 CSV를 구글시트(파일 → 가져오기)나 엑셀로 열기.
- 피벗 테이블로 학생별 평균·최고기록을 한 표로, 차트로 히스토그램·비교 그래프까지. (SQL이 어려우면 이 방법이 제일 편합니다.)
문제 해결 (막혔을 때)
수시| 증상 | 원인 | 해결 |
|---|---|---|
| SQL 실행 오류(빨간 글씨) | 일부만 복사됨 | [📋 복사]로 전체 다시 복붙 → Run |
| "전송 실패" 표시 | 키 오타 · 따옴표 지움 | URL/키를 다시 복사해 따옴표 사이에 붙여넣기 |
| 게임은 되는데 대시보드가 빈 화면 | room 코드 불일치 | 게임 주소의 ?room=과 대시보드 입력값이 같은지 확인 |
| 키가 아예 안 먹음 | service_role 키를 복사함 | anon(publishable) 키로 교체 — 그리고 방금 이유를 배우셨습니다! |
| 남의 기록이 내 대시보드에 보임 | room 코드가 옆 선생님과 겹침 | 이니셜로 바꾸기 — 그리고 이 현상을 기억해 두세요(다음 탭에서 다룹니다) |
📖 오늘 만난 용어 사전
실습 중에 만난 용어를 한 곳에 모았습니다. 연수 후 이 페이지를 다시 열면 복습 자료가 됩니다.
?room=3-2.❓ 초보자가 가장 궁금해하는 것들
강의가 끝난 뒤, 이 페이지만 보고도 다시 하실 수 있도록 자주 나오는 질문을 모았습니다. 궁금한 항목을 눌러 펼쳐 보세요.
Q코딩을 하나도 모르는데, 정말 제가 할 수 있나요?
F12를 눌러 빨간 오류 글씨를 복사해 AI에게 "이 오류 고쳐줘"라고 붙여넣으세요 — 그것도 바이브코딩입니다.QSupabase, 계속 무료인가요? 갑자기 요금이 나가지 않나요?
Q이 페이지만 보고 집에서 혼자 다시 할 수 있나요?
Q학생들은 어떻게 접속하나요? 앱을 설치해야 하나요?
?room=3-2를 붙인 QR을 칠판에 띄우면 학생 폰 30대 → 내 대시보드가 완성됩니다. (호스팅은 오늘 범위 밖 — 다음 단계 예고편)Q폰이 없는 학생이 있거나, 기기가 부족하면요?
Qanon 키가 웹페이지에 공개되는데, 위험하지 않나요?
Q학생 데이터가 해외 서버에 저장되나요? 개인정보 문제는요?
Q실수로 표를 잘못 만들었어요. 다시 하고 싶어요.
delete from reaction_results;, 표째로 지우려면 drop table reaction_results;를 SQL Editor에서 실행하고 다시 만들면 됩니다. 프로젝트 자체를 지우고 새로 만들 수도 있어요(무료로 2개까지). 부담 없이 여러 번 연습해도 되는 게 실습용 백엔드의 장점입니다.Q다음에 다른 수집 앱(관찰일지·설문 등)도 만들 수 있나요?
Q그냥 구글폼·패들릿 쓰면 안 되나요?
🗄️ Supabase, 이것만은 알자!
Supabase에 처음 들어가면 낯선 영어 용어가 가득합니다. 하지만 내가 만든 웹앱의 데이터를 관리하는 데 필요한 건 생각보다 적어요. 이 탭에는 선생님이 실제로 눌러야 하는 메뉴·용어·기능만 모았습니다. 처음부터 다 외울 필요 없이, 필요할 때 여기로 돌아와 찾아 쓰세요.
왼쪽 메뉴, 뭘 눌러야 하나?
왼쪽에 메뉴가 많지만, 데이터 관리에 쓰는 건 몇 개뿐입니다.
| 메뉴 | 하는 일 | 언제 / 중요도 |
|---|---|---|
| Table Editor 표 편집기 | 내 표(데이터)를 눈으로 보기 · 정렬 · 필터 · 잘못된 행 삭제 | ⭐⭐⭐ 가장 자주 |
| SQL Editor SQL 편집기 | 표 만들기 · 보안규칙(RLS) · 조회·개수·삭제 · CSV 내보내기 | ⭐⭐⭐ 자주 |
| Project Settings ⚙️ 프로젝트 설정 | 주소(URL)·키·리전·프로젝트 정보 확인 | ⭐⭐ 처음·키 찾을 때 |
| Authentication 인증 | 교사 로그인 대시보드를 만들 때 사용자·정책 관리 | ⭐ 필요할 때만 |
| Database / Storage / Edge Functions / Realtime / Reports / Advisors | 표 구조 심화 · 파일저장 · 서버함수 · 고급 설정 · 통계 | 지금은 패스 🙆 |
꼭 아는 용어 빠른 사전
이 정도만 알면 대화가 통합니다.
| 용어 | 쉽게 말하면 |
|---|---|
| Project 프로젝트 | 내 백엔드 하나. 표·키·주소가 이 안에 다 들어있음. |
| Table 표 | 데이터가 담기는 엑셀 시트 같은 것. |
| Row / Column 행 / 열 | 행 = 기록 한 줄(학생 한 명의 제출), 열 = 항목(반·닉네임·값). |
| id · created_at | 자동으로 붙는 고유번호와 저장된 시각. 건드릴 필요 없음. |
| Project URL 주소 | 내 백엔드의 인터넷 주소. https://…supabase.co |
| anon key (= publishable) | 웹앱에 넣는 공개용 열쇠. 노출돼도 안전하게 설계됨. |
| service_role (= secret) 🚨 | 모든 규칙을 무시하는 마스터키. 절대 웹·AI에 넣지 마세요. |
| RLS 행 수준 보안 | 표에 거는 자물쇠. 켜야 남이 함부로 못 읽고·못 지움. |
| Policy 정책 | 자물쇠의 세부 규칙("익명은 넣기만 가능" 같은 문장). |
| SQL · Query · Run | 표에 내리는 명령문을 적고 실행(Run)하는 것. |
| Region 리전 | 데이터가 저장되는 물리적 위치. 한국은 Seoul 권장. |
| Pause 일시정지 | 무료 프로젝트가 7일 미사용 시 잠깐 멈춤(데이터는 보존). |
내 백엔드 주소(Project URL)와 PROJECT ID 찾기
주소는 항상 같은 모양이라, PROJECT ID만 알면 직접 만들 수 있습니다.
주소는 이 모양
내 백엔드 주소는 늘 이렇게 생겼습니다
💡 {PROJECT_ID} 자리에 내 프로젝트 ID를 끼우면 끝
PROJECT ID 찾는 법
방법 1 — 대시보드에서 브라우저 주소창을 보세요:…/project/abcd1234… 의 project/ 뒤 문자열이 ID.
방법 2 — ⚙️ Project Settings → General → Project ID(= Reference ID) 옆 복사.
abcd1234efgh → 주소는 https://abcd1234efgh.supabase.co데이터 보고·고치고·지우기 — Table Editor
가장 자주내 웹앱이 모은 데이터를 표로 직접 봅니다.
- 왼쪽 Table Editor → 내 표 이름 클릭. 행(row)이 학생 제출 하나하나입니다.
- 정렬:
created_at열 머리 클릭 → 최신순/오래된순. - 필터: 상단 Filter → 예
room = 3-2→ 특정 반만 보기. - 행 삭제(잘못된·테스트 데이터): 행 왼쪽 체크박스 선택 → Delete. (또는 아래 SQL 사용)
- 셀 수정: 칸을 더블클릭해 직접 고칠 수 있지만, 수업 데이터는 되도록 원본 유지를 권장.
CSV로 내려받기 — 엑셀에서 열기 · 백업
필수 기능방법 A — Table Editor에서 (클릭만)
- 왼쪽 표 목록에서 표 이름 위에 마우스를 올리면 나오는 ⋯(점 3개) 클릭.
- Export data → Export table as CSV 선택 → 파일이 내려받아집니다. (버전에 따라 표 화면 오른쪽 위 Export 버튼일 수도 있어요.)
방법 B — SQL Editor에서 (가장 확실)
- SQL Editor에서 아래를 실행:
-- 표이름 자리에 내 표 이름(예: reaction_results)을 넣으세요
select * from 표이름;
- 결과 표 오른쪽 위의 다운로드(↓) 아이콘 → Download CSV / Export to CSV 클릭.
엑셀에서 열기
- 받은
.csv를 더블클릭(엑셀이 열림) — 끝. - 혹시 한글이 깨지면: 엑셀 → 데이터 → 텍스트/CSV 가져오기 → 파일 원본을 65001: 유니코드(UTF-8)로 선택 → 불러오기.
자주 쓰는 SQL 한 줄 — 복붙용
SQL Editor에 붙여넣고 Run. 표이름만 내 것으로 바꾸면 됩니다.
-- ① 지금까지 몇 건 모였나 (개수 세기)
select count(*) from 표이름;
-- ② 특정 반만, 최신순으로 보기
select * from 표이름
where room = '3-2'
order by created_at desc;
-- ③ 오늘 들어온 것만 보기
select * from 표이름
where created_at >= current_date;
-- ④ 표에 어떤 열이 있는지 살짝 엿보기
select * from 표이름 limit 5;
-- ⑤ 특정 반 / 테스트 데이터만 지우기 (되돌리기 불가!)
delete from 표이름 where room = 'yeonsu';
-- ⑥ 표 통째로 비우기 (⚠️ 전부 삭제 · 먼저 count·CSV부터!)
delete from 표이름;
where 없는 delete는 표 전체가 지워집니다.관리자가 꼭 지킬 것
학생 데이터를 다루는 이상, 이 세 가지는 습관으로.
키 구분
anon만 웹·AI·깃허브에. service_role은 어디에도 넣지 않기.
RLS 켜기
표마다 RLS(자물쇠)가 켜져 있는지 확인. 꺼져 있으면 누구나 읽고 지울 수 있음.
RLS가 켜졌는지 확인하려면 Table Editor의 표 이름 옆 자물쇠 표시를 보거나, SQL로:
-- true 면 RLS 켜짐 / false 면 꺼짐(위험)
select relname, relrowsecurity
from pg_class where relname = '표이름';
프로젝트 살아있게 두기 — 무료 요금제
무료로 충분하지만, 한 가지만 알아두세요.
지금은 몰라도 되는 것들
메뉴에 있어도 당장 안 눌러도 됩니다.
🎉 축하드립니다. 그리고 —
방금 선생님은 데이터를 모으는 사람이 되셨습니다
학생 데이터를 모으는 순간, 그것은 개인정보가 됩니다. AI(바이브코딩)는 시키는 앱을 잘 만들어 줍니다. 문제는 — 절대 물어봐 주지 않는 것들이 있다는 겁니다.
🚪 보안규칙(RLS) 꺼짐
AI가 만들어 준 코드가 RLS 없이 배포되면, 주소만 아는 사람은 누구나 표 전체를 내려받을 수 있습니다. Supabase 관련 사고 유형 1위.
✍️ 동의 없는 수집
개인정보는 정보 주체의 동의가 원칙입니다. 특히 만 14세 미만은 법정대리인(보호자) 동의가 필요합니다 — 중학교 1~2학년 상당수가 여기 해당합니다. 학기 초에 미리 개인정보 수집 동의를 받으셨더라도, 원칙상 학운위 에듀테크 심의를 통과해야 합니다 ㅠㅠ
🧾 과잉 수집 (최소수집 위반)
닉네임·익명으로도 충분한 경우에는, 목적에 필요한 최소한의 정보만 모아야 합니다! '혹시 몰라서' 실명·학번·연락처까지 모으는 건 최소수집 위반입니다.
🌏 국외 저장
서버 위치(리전)를 확인하지 않으면 학생 데이터가 해외 서버에 저장됩니다. 공공·교육 데이터는 국내 저장이 원칙적으로 권장됩니다.
♾️ 파기 계획 없음
수집엔 열심인데 지우는 계획이 없으면, 데이터는 영원히 쌓입니다. 목적 달성 후 지체 없이 파기하는 것까지가 수집입니다.
🔗 접근통제 없음
대시보드 링크나 교사 대시보드 비밀번호를 학생이 알아채면 안 됩니다! 실습 때 "옆 선생님 room에 들어가진" 경험 — 그게 바로 이 주의사항의 체험판입니다.
Ctrl+U(소스 보기)로 다 봅니다. 진짜 잠금은 서버 쪽 로그인(Supabase Auth)+RLS로 — 비밀번호는 서버가 검사하고 코드엔 안 남습니다. ↓ 아래 '③ 대시보드 잠그기' 프롬프트 참고.👤 계정·비밀번호 관리
학생 데이터가 교사 개인 계정의 백엔드에 있어 관리 책임의 공백이 생길 수 있습니다. 학생이 로그인해서 쓰는 앱이라면 학생 비밀번호도 관리 대상이 됩니다.
🤖 결국, 판단은 선생님 몫
AI는 저희의 요청을 대부분 들어줍니다. "동의는 받으셨나요?", "언제 지우실 건가요?"라고 먼저 묻지 않아요. 그러므로 선생님께서 앞의 주의사항을 바탕으로 스스로 판단하셔야 합니다!
🤖 안전하게 만드는 만능 프롬프트
바이브코딩으로 앱을 만든 뒤 Supabase를 붙일 때, 아래를 AI(클로드·GPT)에게 웹앱 코드와 함께 주면 RLS·최소권한·익명 설계·파기가 기본으로 들어갑니다.
① RLS 있게 안전 배포하기 (주의사항 1 예방)
내가 만든 이 웹앱에 Supabase로 데이터 저장 기능을 붙이려고 해. 현재 웹앱의 코드와 데이터 구조를 먼저 확인한 뒤, 아래 조건을 반드시 지켜서 SQL과 연결 코드를 만들어 줘. 1. 테이블을 만들거나 사용하는 경우 반드시 RLS를 활성화해. alter table ... enable row level security; 2. 기존 RLS 정책도 전부 확인해. anon 또는 public에 불필요한 select, update, delete 권한이 있다면 어떤 정책이 위험한지 먼저 설명하고 제거 또는 교체해. 3. 학생에게는 수업에 꼭 필요한 최소 권한만 허용해. 기본 원칙: - 학생 제출: anon insert 허용 - 학생 조회: 수업상 꼭 필요한 경우에만 select 허용 - 학생 수정: anon update 금지 - 학생 삭제: anon delete 금지 4. insert 정책에는 with check를 사용해 입력값의 길이·범위를 데이터베이스에서도 검사해. 예: - 이름/닉네임 길이 1~20자 - 답변 길이 1~500자 - 점수는 허용된 숫자 범위만 - 반, 번호 등은 정해진 형식만 HTML의 maxlength나 JavaScript 검사만 믿지 말고, RLS의 with check 또는 데이터베이스 constraint에서도 검사해. 5. 학생이 로그인하지 않고 제출하는 구조라면 PostgreSQL의 anon 역할에 insert만 허용해. Supabase Auth의 Anonymous Sign-In 기능은 사용하지 마. Anonymous Sign-In으로 생성된 사용자는 데이터베이스에서 authenticated 역할로 처리될 수 있으므로 둘을 혼동하지 마. 6. 학생 제출 코드에서는 특별한 이유가 없다면 .insert(...).select() 를 쓰지 말고 .insert(...) 만 사용해. 학생에게 select 권한이 없으면 insert 후 반환 데이터를 읽다가 오류가 날 수 있어. 7. 프런트엔드에는 Supabase URL과 publishable key 또는 anon key만 사용해. service_role key, secret key, sb_secret 키는 HTML, JavaScript, GitHub 저장소, 브라우저 코드에 절대 넣지 마. 8. 실명 대신 번호, 모둠명, 임시 닉네임 등 수업에 필요한 최소한의 정보만 수집하는 구조를 제안해. 9. 테이블명·열 이름은 예시를 임의로 만들지 말고 현재 웹앱과 Supabase 구조에서 실제 쓰는 이름을 확인해 적용해. 10. 마지막에 다음을 한글로 정리해. - 주소만 아는 학생이 할 수 있는 것 / 할 수 없는 것 - 로그인하지 않은 사람이 읽을 수 있는 데이터 - 프런트엔드에 노출되어도 되는 키 / 절대 노출하면 안 되는 키 - 교사가 Supabase에서 직접 실행해야 하는 SQL
② 데이터 안전하게 파기하기 (주의사항 5 예방)
내 Supabase 프로젝트에서 학생 데이터를 안전하게 파기하려고 해. 내 테이블 이름은 [여기에 실제 테이블 이름]이야. 현재 테이블 구조를 먼저 확인한 뒤, 아래 SQL을 각각 만들어 주고 각 SQL 위에 무엇을 지우는 명령인지 한글 주석을 달아 줘. 1. 해당 테이블의 모든 행을 지우는 SQL 2. 특정 반만 골라 지우는 SQL (예: room = '3-2') 3. 특정 날짜 이전의 데이터만 지우는 SQL (예: created_at이 특정 날짜 이전) 4. 특정 반이면서 특정 날짜 이전인 데이터만 지우는 SQL 5. 테이블의 데이터와 구조를 모두 없애는 drop table SQL 6. 실행 전 삭제될 행 개수를 확인하는 select count(*) SQL 7. 실제 삭제 전 어떤 데이터가 대상인지 확인하는 select 미리보기 SQL 다음 주의사항도 함께 적어 줘. - 삭제 SQL은 되돌리기 어려우므로 먼저 select로 대상을 확인한다. - 테이블명·열 이름은 실제 구조를 확인해서 작성한다. - drop table은 데이터뿐 아니라 테이블 구조도 제거한다. - 백업이 필요하면 삭제 전에 CSV 등으로 내보낸다. - 내가 명확히 요청하지 않은 다른 테이블은 절대 삭제하지 않는다.
③ 교사 대시보드 진짜로 잠그기 (주의사항 6 예방)
⚠️
to authenticated using (true) 만으로는 부족합니다 — 이건 로그인한 모든 사용자가 읽게 됩니다. 반드시 auth.uid() = 교사UID까지 비교해야 합니다.③ 대시보드 잠그기 프롬프트 — 펼쳐서 복사
현재 웹앱의 교사 대시보드를 브라우저 소스를 전부 확인해도 뚫리지 않도록
Supabase Auth와 RLS를 사용한 구조로 변경해 줘.
단순히 로그인 화면을 보여 주거나 JavaScript로 대시보드를 숨기는 것에서 끝내지 말고,
데이터베이스에서 실제 읽기 요청을 차단해야 해.
현재 프로젝트의 전체 코드를 먼저 확인한 뒤 아래 조건을 적용해.
## 1. 기존 클라이언트 비밀번호 방식 완전 삭제
HTML·JavaScript 전체에서 다음을 찾아 제거해.
- TEACHER_PIN / ADMIN_PASSWORD / DASHBOARD_PASSWORD
- 코드에 직접 적힌 비밀번호 문자열
- 입력값과 고정 문자열을 비교하는 코드
- 암호화/해시한 값을 브라우저에서 비교하는 코드
- URL 파라미터만으로 관리자 여부를 판단하는 코드
- localStorage의 isTeacher, isAdmin 값만으로 권한을 판단하는 코드
- 숨겨진 관리자 버튼·특정 키 입력만으로 잠금 해제하는 코드
브라우저 코드 어디에도 실제 비밀번호(정답)가 남아 있으면 안 돼.
## 2. Supabase Auth 로그인 적용
교사 로그인 화면: 이메일·비밀번호 입력, 로그인/로그아웃 버튼, 진행 상태, 실패 안내, 현재 로그인 상태.
로그인은 supabase.auth.signInWithPassword({ email, password }) 사용.
페이지 진입 시 세션 확인 + 로그인 상태 변화 감지:
- supabase.auth.getSession()
- supabase.auth.onAuthStateChange(...)
- supabase.auth.signOut()
현재 쓰는 supabase-js 버전에 맞게 적용해.
회원가입 버튼을 만들지 말고 supabase.auth.signUp()도 쓰지 마.
교사 계정은 Dashboard의 Authentication → Users에서 미리 만든 계정만 사용.
localStorage에 isTeacher=true 같은 값을 저장해 권한 판정하지 마.
## 3. 로그인 전에는 학생 데이터를 요청하지 않기
로그인 안 한 상태에서는 대시보드·학생 데이터 표를 보여 주지 마.
화면만 숨기고 백그라운드에서 미리 불러오지도 마.
학생 데이터 select 요청은 교사 로그인 세션 확인 후에만 실행.
로그아웃하면: 화면의 학생 데이터 제거, 대시보드 숨김, 로그인 화면 표시,
교사 전용 실시간 구독 해제, 더 이상 select 요청 안 보냄.
## 4. RLS로 지정된 교사 UID만 조회 허용
학생 데이터가 저장되는 실제 테이블명을 확인해(예시명 그대로 쓰지 마).
그 테이블 RLS 활성화 + 기존 select 정책 전부 확인.
anon/public 또는 모든 authenticated가 읽게 만든 정책이 있으면 제거/교체.
교사 UID를 사용하는 select 정책 작성:
alter table public.[실제_테이블명] enable row level security;
create policy "designated teacher can read"
on public.[실제_테이블명]
for select
to authenticated
using ( (select auth.uid()) = '[교사 계정 UID]' );
중요:
- to authenticated using (true) 로 만들지 마.
- authenticated는 교사 역할이 아니라 로그인한 모든 사용자를 뜻해.
- 반드시 auth.uid()와 지정한 교사 UID를 비교해.
- 실제 교사 UID를 어디에 붙여 넣는지 설명해.
- 충돌·중복되는 기존 select 정책이 있는지 확인하고, 위험한 정책을 남기지 마
(허용 정책 하나만 남아도 OR처럼 작동할 수 있음).
## 5. 학생의 익명 제출은 유지
학생은 로그인 없이 기존 제출 화면에서 제출할 수 있어야 해.
학생 제출은 anon 역할에 insert만 허용:
create policy "anonymous students can submit"
on public.[실제_테이블명]
for insert
to anon
with check ( [현재 열 구조에 맞는 값 검증 조건] );
학생에게 select/update/delete 권한은 주지 마.
학생 제출 코드가 .insert(data).select() 라면
select 권한이 없어도 작동하도록 .insert(data) 로 바꿔.
단, 반환값이 꼭 필요한 구조면 무조건 지우지 말고 안전한 대안을 제시해.
## 6. 프런트엔드 키 점검
정상: Supabase URL, publishable key, anon key.
절대 포함 금지: service_role key, secret key, sb_secret 키,
데이터베이스 비밀번호, 교사 로그인 비밀번호.
HTML·JavaScript·환경 파일·GitHub 저장소를 모두 점검.
정적 사이트의 환경변수도 빌드 후 브라우저 코드에 포함될 수 있으니
'환경변수'라는 이유만으로 비밀이라 판단하지 마.
## 7. 회원가입 기능 차단
회원가입 UI를 만들지 마. 교사 계정은 Dashboard에서 관리자가 미리 생성.
Authentication 설정에서 'Allow new users to sign up'이 켜져 있는지 확인 안내.
교사 전용 프로젝트면 이 설정을 꺼 기존 계정만 로그인하도록 권장.
Anonymous Sign-In도 학생의 로그인 없는 제출과 혼동하지 마
(학생 제출엔 별도 Auth 계정 없이 anon insert 정책 사용).
## 8. 보안 테스트 (직접 확인 절차 작성)
1) Ctrl+U에서 기존 비밀번호 문자열이 검색되지 않는지
2) 개발자도구 Sources에 TEACHER_PIN/ADMIN_PASSWORD 값이 없는지
3) 로그아웃 상태에서 학생 데이터 select가 거부되는지
4) 로그인 화면을 CSS/개발자도구로 강제로 숨겨도 데이터가 안 불려오는지
5) 지정 교사 계정으로 로그인하면 학생 데이터가 정상 조회되는지
6) 다른 Auth 계정으로 로그인하면 조회가 거부되는지
7) 로그인 안 한 학생은 insert가 되는지
8) 로그인 안 한 학생은 select/update/delete가 안 되는지
9) 프런트엔드에 service_role/secret 키가 없는지
10) 로그아웃 직후 화면의 학생 데이터가 지워지는지
## 9. 최종 설명 (비전공 교사용, 한글)
- 이전 방식이 왜 Ctrl+U에 취약했는지
- Supabase Auth에서는 비밀번호를 누가 검사하는지
- 프런트엔드에 실제 비밀번호가 없어지는 이유
- 로그인 화면을 숨기는 것과 데이터 권한을 막는 것의 차이
- authenticated만 허용하는 것이 왜 충분하지 않은지
- auth.uid()가 무엇인지 / RLS가 요청을 어떻게 막는지
- 공개용 키가 보여도 되는 이유 / 절대 공개 금지 키
마지막에 다음 문장을 명확히 포함해:
"변경 후에는 브라우저 소스를 전부 확인해도 교사의 실제 비밀번호가 코드에 존재하지 않습니다.
또한 지정된 교사 계정으로 로그인하지 않은 요청은 화면을 조작하거나 Supabase에 직접
select 요청을 보내더라도 데이터베이스의 RLS 정책에 의해 학생 데이터를 받을 수 없습니다."
## 10. 결과물 제시 순서
1) 수정한 파일 목록 2) 삭제한 기존 비밀번호 코드 3) 새 Auth 로그인 코드
4) SQL Editor에서 실행할 전체 SQL 5) 교사 UID 붙여 넣을 위치
6) Dashboard에서 할 설정 7) 보안 테스트 결과/방법
실제 테이블명·구조가 있으면 예시 이름 대신 실제 이름을 사용해.
③ 간단 버전 — 로그인 없이 ‘서버 비밀번호(PIN)’로 잠그기 (계정 만들기가 부담스러울 때)
핵심은 같습니다: 비밀번호를 코드에 안 적고 서버가 검사. 삭제·설정 같은 관리 작업은 비번을 받는 서버 함수(RPC)로만 되게 하고, RLS로 직접 수정·삭제를 막습니다.
⚠️ 단, 짧은 PIN(4자리)은 자동 대입으로 뚫릴 수 있어요 — 8자 이상 영문+숫자로. 진짜 민감한 데이터엔 위 Auth 방식을 쓰세요.
revoke execute ... from anon 을 걸어 학생(anon 키)은 teacher_pin() 함수를 호출조차 못 함
② 함수 원문은 데이터베이스 시스템 영역이라 REST API로 안 열림(공개되는 건 public 표뿐)
③ 원문을 보려면 관리자(SQL Editor) 권한이 필요한데 학생에겐 anon 키밖에 없음.⚠️ 딱 하나 남는 길 — 찍어서 맞히기(자동 대입).
check_pin이 ‘맞다/틀리다’를 알려주니, 9182(4자리)라면 0000~9999를 전부 넣어볼 수 있어요. → 비번을 길게(8자↑ 영문+숫자, 예: sci9182forest) 쓰면 경우의 수가 수천억이라 자동 대입도 사실상 불가능합니다.③ 간단버전 — 서버 비밀번호(PIN) 프롬프트 — 펼쳐서 복사
현재 웹앱의 '교사 전용 기능(예: 글 삭제, 전체 지우기, 공지·설정 저장 등)'을,
브라우저 소스를 전부 봐도 비밀번호가 드러나지 않도록
Supabase 서버가 비밀번호를 검사하는 구조로 바꿔 줘.
로그인(Auth) 계정까지는 만들지 않는 '가벼운 서버 비밀번호(PIN)' 방식이야.
먼저 전체 코드를 확인한 뒤 아래를 적용해.
## 1. 클라이언트 비밀번호 완전 제거
HTML·JS에서 코드에 직접 적힌 비밀번호 문자열, 입력값과 고정 문자열 비교,
브라우저에서 해시를 비교하는 코드, URL·localStorage 값만으로 관리자 판정하는 코드를
모두 제거해. 브라우저 코드 어디에도 실제 비밀번호가 남으면 안 돼.
(인터넷이 끊긴 로컬 단독 테스트용 임시 값은 온라인에선 안 쓰이도록 분리해도 됨.)
## 2. 비밀번호를 '서버 함수'에만 저장
Supabase에 아래 함수를 만들어. 실제 비밀번호는 이 함수 안에만 있고 앱 코드엔 없어.
create or replace function public.teacher_pin()
returns text language sql immutable security definer set search_path=public as $$
select 'CHANGE-THIS-PIN'::text;
$$;
revoke execute on function public.teacher_pin() from anon, authenticated, public;
→ 나는 SQL Editor에서 'CHANGE-THIS-PIN'을 내 비밀번호로 바꿔 실행할 거야.
이 파일에는 실제 비번을 절대 쓰지 말고, 길게(8자 이상 영문+숫자) 쓰라고 안내해 줘.
## 3. 비번 확인 + 관리 기능을 '비번을 받는 서버 함수(RPC)'로
- 잠금 해제 확인용:
create or replace function public.check_pin(p text)
returns boolean language sql security definer set search_path=public as $$
select p = public.teacher_pin();
$$;
- 관리 작업마다 pin을 받아 검사하는 security definer 함수로 만들어. 예:
create or replace function public.admin_delete(p text, row_id text)
returns boolean language plpgsql security definer set search_path=public as $$
begin
if p <> public.teacher_pin() then return false; end if;
delete from public.[실제_테이블명] where id = row_id;
return true;
end $$;
내 앱의 실제 관리 기능(삭제/전체지우기/설정·공지 저장 등)을 파악해 각각 함수로 만들어.
- 각 함수에 grant execute ... to anon (검사는 함수 안에서 하니까 안전).
## 4. RLS로 '직접 수정·삭제'는 막기
학생 데이터 테이블 RLS 켜고: select=허용, insert=필요한 값 검증만 허용,
update/delete 정책은 아예 두지 마(=anon이 직접 수정·삭제 못 함).
관리 작업은 오직 3의 서버 함수로만 되게 해(security definer라 owner 권한으로 RLS를 통과함).
공감/좋아요처럼 값 하나만 바꾸는 것도 update 정책 대신 security definer 함수로.
## 5. 클라이언트 배선
- '교사 모드' 버튼 → 비번 입력 → check_pin(입력값) RPC로 서버 확인 →
맞으면 관리 UI를 보여 주고, 입력한 비번을 메모리에 보관해 이후 admin 함수 호출에 넘김.
- 삭제·설정 등은 admin 함수 RPC 호출(입력 비번 전달). 실패하면 '비밀번호를 확인하세요' 안내.
- 소스 어디에도 실제 비번이 없어야 함. (교사 모드 UI를 숨기는 건 '보조'일 뿐, 진짜 차단은 서버 함수)
## 6. 정직한 한계 설명 + 테스트
- 이 방식은 '소스에 비번이 없고, 직접 삭제·설정은 서버가 비번으로 막는' 가벼운 잠금이야.
4자리 같은 짧은 PIN은 자동 대입으로 뚫릴 수 있으니 반드시 길게 쓰라고 안내.
- 진짜 민감한 학생 데이터라면 '로그인(Auth)+RLS(auth.uid() 비교)' 방식이 더 안전하다고 함께 안내.
- 테스트 절차를 적어 줘:
1) Ctrl+U/F12에서 비밀번호 문자열이 검색 안 되는지
2) 틀린 비번으론 삭제·설정이 안 되는지
3) 맞는 비번으론 삭제·설정이 되는지
4) 비번 없이 직접 API로 delete를 보내도 RLS로 차단되는지
## 7. 결과물 제시 순서
1) 수정한 파일 목록 2) 제거한 비밀번호 코드 3) SQL 전체(teacher_pin·check_pin·admin_* 함수 + RLS)
4) 비번 바꿀 위치 5) 클라이언트 배선 6) 테스트 방법.
예시 테이블명 대신 실제 이름을 사용해.
④ 교사 로그인 계정 만들기 — 실습 매뉴얼 (펼치기)
비밀번호를 코드에 적는 대신, Supabase Authentication에 교사 계정을 미리 만듭니다.
1단계 · Authentication → Users 열기
- Supabase Dashboard 접속 → 웹앱이 연결된 프로젝트 선택
- 왼쪽 메뉴 Authentication → Users
2단계 · 교사 계정 만들기 (버전에 따라 버튼명이 다를 수 있어요)
방법 A — Create new user가 보이면:
- Add user → Create new user
- 교사 이메일 입력 → 안전한 비밀번호 입력 → 계정 생성
방법 B — Send invitation을 쓰면:
- Add user → Send invitation → 교사 이메일 입력 → Invite user
- 받은 메일의 초대 링크를 열어 계정·비밀번호 설정 완료
3단계 · 교사 UID 복사하기 ⭐
- Users에서 방금 만든 계정 선택 → 상세에서 User UID(또는 ID) 찾기
- UUID 형식 값 복사 예: 12345678-abcd-1234-abcd-1234567890ab
create policy "designated teacher can read" on public.student_submissions for select to authenticated using ( (select auth.uid()) = '여기에-복사한-교사-UID' );
student_submissions는 예시입니다. 자신이 만든 테이블 이름으로 바꾸고, 여기에-복사한-교사-UID에는 Users에서 복사한 실제 UID를 넣으세요.4단계 · 일반 회원가입 막기
- Authentication 설정에서 Allow new users to sign up 항목 찾기
- 교사 전용 프로젝트면 회원가입 허용 끄기 → 기존 계정 로그인 확인
5단계 · 로그인 테스트 ✅
□ 올바른 교사 이메일·비밀번호는 로그인 성공
□ 로그인 전에는 학생 데이터가 안 보임
□ 로그인 후에는 학생 데이터가 보임
□ 로그아웃하면 학생 데이터가 즉시 사라짐
□ Ctrl+U에서 교사 비밀번호가 검색 안 됨
□ 개발자도구로 화면을 강제로 열어도 로그인 안 했으면 데이터가 안 불려옴
🤔 교사 계정은 웹앱마다 새로 만들어야 할까? (펼치기)
Supabase 프로젝트: science-class-apps Authentication └─ teacher@example.com (고유 UID 1개) 연결된 웹앱 ├─ 반응속도 게임 ├─ 질문 수집 앱 ├─ 염분 탐구 앱 └─ 설문 결과 대시보드
네 웹앱이 같은 프로젝트 URL·키를 쓰면 Authentication 사용자 목록을 함께 씁니다 — 즉 한 프로젝트의 교사 계정으로 그 프로젝트에 연결된 여러 웹앱에 로그인할 수 있어요. 단, 로그인할 수 있다는 것과 모든 테이블을 읽을 수 있다는 것은 다릅니다. 어떤 테이블을 읽는지는 각 테이블의 RLS 정책이 결정합니다.
교사 계정 하나를 여러 앱에
계정 1개 → 여러 앱에서 같은 이메일·비번, 각 테이블 select 정책에 같은 교사 UID. 계정 관리 단순 · 연수 실습에 추천.
같은 프로젝트, 앱마다 계정 다르게
반응속도=UID A, 염분=UID B… 각 테이블 RLS에 해당 UID만. 계정 목록은 같은 프로젝트에서 함께 관리, RLS로 앱별 접근을 논리적으로 분리.
완전 분리 = 프로젝트도 분리
앱 A→프로젝트 A, 앱 B→프로젝트 B. 사용자·DB·테이블·RLS·URL·키가 전부 별개. A에서 만든 계정은 B에 없음.
한 줄 요약 — 계정은 프로젝트가 공유하고, 데이터 접근 권한은 테이블별 RLS가 결정합니다.
authenticated using(true)로 열어 두지 않았는가? ③ 실제 교사 UID를 넣었는가? ④ secret/service_role 키가 프런트엔드에 없는가?to authenticated using(true)는 '로그인한 아무나'라 위험 → 반드시 auth.uid()=교사UID. ④ 실습은 UID 복사 위치만 확실히. 세 프롬프트는 연수 후에도 재사용.교사 대시보드 비밀번호를 5초 만에 훔쳐 보세요
바이브코딩으로 교사 대시보드를 만들 때 가장 흔한 실수 — 비밀번호를 프론트엔드 코드에 그냥 적어두는 것입니다. 정말 위험한지, 강사가 실제로 만든 과제 수합 사이트에서 직접 훔쳐봅시다.
아래 사이트는 강사가 만든 진짜 과제 제출 사이트입니다. 교사 대시보드가 비밀번호로 잠겨 있죠. 그 비밀번호를 찾아보세요.
페이지 소스 보기
(Mac: ⌥⌘U)
소스 안에서 찾기 열기
입력하면… 눈앞에 비밀번호가!
const CONFIG = {
...
TEACHER_PIN: "teacher1234", // ⬅️ 교사 대시보드 비밀번호
...
};
· 교사 확인은 Supabase Auth(로그인)로 — 비밀번호는 서버가 검사하고, 코드에는 남지 않습니다.
· 데이터 접근은 RLS로 — "로그인한 교사만 읽기" 규칙을 서버가 강제합니다.
· 헷갈리지 마세요:
anon 키는 공개돼도 됩니다(자물쇠=RLS가 지킴). 하지만 TEACHER_PIN 같은 진짜 비밀은 프론트엔드에 두면 안 됩니다.🛠️ 해결까지 직접 해보기 — 교사 대시보드를 '진짜로' 잠그기 심화 · 따라하기
핵심 한 줄: 비밀번호를 코드에서 지우고, '로그인(Auth)'과 'RLS'로 서버가 지키게 만듭니다. 아래 3단계를 그대로 따라 하면, Ctrl+U로 코드를 다 봐도 비밀번호가 없고, 키를 복사해도 로그인하지 않으면 학생 데이터가 안 나옵니다.
STEP 1 · 교사 계정 하나 만들기 (Supabase Auth)
Supabase 프로젝트 → 왼쪽 Authentication → Users → [Add user] → Create new user. 교사용 이메일과 비밀번호를 입력해 계정을 하나 만듭니다. 이 비밀번호는 서버에만 저장되고, 코드에는 절대 적지 않습니다.
STEP 2 · 대시보드의 '가짜 비번 검사'를 '진짜 로그인'으로 교체
대시보드 HTML에서 TEACHER_PIN을 비교하던 코드를 지우고, 아래처럼 Supabase 로그인으로 바꿉니다.
(먼저 <head>에 supabase-js 한 줄을 추가하세요.)
<!-- head 안에 한 줄 추가 --> <script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script> // ── 대시보드 스크립트 ── const sb = supabase.createClient(URL, ANON_KEY); // 내 프로젝트 URL·anon 키 // ❌ 삭제: if (input === "teacher1234") { 대시보드 열기 } // ✅ 교체: 서버에 로그인 요청 (비번은 서버가 검사) async function teacherLogin(email, password) { const { data, error } = await sb.auth.signInWithPassword({ email, password }); if (error) return alert("로그인 실패"); openDashboard(); // 로그인 성공 시에만 대시보드 표시 }
STEP 3 · 데이터 표 규칙(RLS)을 '로그인한 사람만 읽기'로 조이기
학생 제출 표의 읽기(select) 권한을 익명(anon) → 로그인 사용자(authenticated)로 바꿉니다. Supabase SQL Editor에 붙여넣고 Run. 제출(insert)은 학생이 로그인 없이 해야 하므로 anon 그대로 둡니다.
-- 읽기: 로그인한 교사만 허용 drop policy if exists "anon can read" on public.submissions; create policy "teacher read" on public.submissions for select to authenticated using ( true ); -- 제출(넣기)은 학생용으로 anon 유지 (있으면 그대로 두세요) create policy if not exists "anon can insert" on public.submissions for insert to anon with check ( true );
?select=*를 때려도, 로그인하지 않았으니 authenticated가 아니라서 학생 데이터가 한 줄도 안 나옵니다.
자물쇠가 그림에서 진짜 자물쇠가 되었습니다. 🔒💡 연수 중에는 개념·시연까지만 하고, 이 3단계는 선도학교 심화 과제로 각자 따라 하시면 됩니다. 막히면 강사에게!
주소 한 줄이면 열립니다
협박이 아니라 구조 이해입니다. 브라우저 주소창에 아래 형식의 주소를 치면 —
https://내프로젝트.supabase.co/rest/v1/reaction_results?select=*&apikey=anon키
anon key
손님용 공개 열쇠. 웹앱에 적어 둬도 안전 — 할 수 있는 일은 자물쇠(RLS)가 허락한 것뿐이니까.
공개해도 OKservice_role key
모든 규칙을 무시하는 마스터키. 웹앱에 넣는 순간 전교생 데이터가 통째로 노출됩니다.
절대 공개 금지그런데 무엇이 나올지를 결정하는 것이 바로 RLS입니다. 우리 표는 "읽기 허용"이라 반응시간이 보이지만 — 만약 실명·상담기록이 담긴 표를 RLS 없이 배포했다면, 이 한 줄로 전교생의 데이터가 통째로 나왔을 겁니다.
열쇠(anon 키)는 공개되어도 됩니다. 지키는 것은 자물쇠(RLS)입니다. 이 문장 하나만 기억하셔도 오늘 연수는 성공입니다.
⚖️ 이 데이터, 모아도 될까?
이제 선생님 차례입니다. 내 수업에서 모으고 싶은 데이터를 하나 떠올려 주세요.
(예: 실험 전-후 개념 변화, 모둠 활동 기록, 운동 후 심박수, 설문 응답…)
그 데이터를 아래 데이터 판사에 통과시켜 봅니다. 여섯 질문이면 됩니다.
🏛️ 학교운영위원회, 에듀테크 심의
초중등교육법 개정으로 2026학년도부터, 학교에서 사용하는 에듀테크·소프트웨어는 학교운영위원회 심의를 받아야 합니다.
법적 근거
초중등교육법 개정 — 2026학년도부터 학교 사용 에듀테크·소프트웨어는 전체 학운위 심의 대상이 되었습니다.
시기가 핵심
각 학년도 첫 학운위(보통 2월)에서 심의 목록을 통과시켜야 합니다. 학기 시작 전에 받는 것이 원칙 — 3월에 쓰고 싶으면 2월에 올려야 합니다.
학교 전체의 일
제가 근무하는 해누리중학교는 이렇게 합니다:
① 담당 부서(과학정보부)가 전 교원 수요조사로 목록 수합
② 제품별 개인정보 체크리스트 정리
③ 첫 학운위(2월)에서 일괄 심의
→ 내가 만든 앱도 이 목록에 올려야 하니 담당 선생님께 미리 알리세요.
현직 부장교사의 실무 기록으로 보는 진행 순서
아래는 해누리중학교 과학정보부장(송영재 선생님)이 2026학년도 심의를 실제로 진행하며 남긴 기록을 요약한 것입니다. "심의가 뭘 하는 건지"가 한눈에 보입니다. 부장님, 자료 사용 허락해 주셔서 감사합니다!!
| 순서 | 할 일 | 실무 포인트 |
|---|---|---|
| ① 수요조사 (방학~새학기 준비기간) | 전 교원에게 "올해 사용할 에듀테크·SW"를 조사 (공유 문서·문자 발송) | 전입 교사·기간제 선생님 수요까지 포함해야 하므로 기간을 넉넉히. 2월 학운위 날짜에서 역산해 일정 잡기 |
| ② 체크리스트 수집 | 에듀집(edzip.kr)에서 각 제품의 '개인정보 필수기준 체크리스트(공급자용)'를 내려받아, 수요조사에 나온 제품 것만 골라 수합 | 목록에 없는 제품은 KEFA(한국교육학술정보원 협력 창구)에 등록 요청 가능. 매년 목록이 갱신되니 진행 연도에 재확인 |
| ③ 서식 작성 | 교육청 심의 가이드의 서식 2(필수기준은 공급자 체크리스트로 갈음, 선택기준만 작성)와 서식 4(간소 양식) 작성 | 필수기준을 다시 쓸 필요 없음 — 공급자 PDF 첨부로 대체되는 구조 |
| ④ 학운위 기안·심의 | 제출 의안을 기안하고 첫 학운위에서 심의 | 수요조사와 의안 마감이 어긋나면 의안 먼저 기안, 체크리스트는 별도 기안도 가능 |
| ⑤ 동의서 수합 (학기 초) | 로그인 등 개인정보를 수집하는 SW는 가정통신문으로 개인정보 동의서를 일괄 수합 | 동의서에는 수집 목적·항목(학년·반·번호·성명 등)·보유기간(예: 1년)·거부권과 함께 제3자 제공·국외 이전 고지까지 포함 (예: Canva→호주, Kahoot→노르웨이 서버) |
위 질문은 '데이터 판사' 탭에서 선생님들께서 이미 답하신 내용과 같습니다! 국가가 에듀테크 회사에 요구하는 기준과, 오늘 우리가 스스로에게 물은 기준이 같은 것이죠. 데이터 판사를 통과한 앱이라면 심의 준비는 이미 절반이 된 셈입니다.
✅ 6가지 체크리스트
직접 만든 데이터 수집 앱을 심의 목록에 올릴 때 필요한 여섯 가지입니다. 아래에 채워 넣고 [문서 생성]을 누르면 심의 자료 한 장이 자동으로 완성됩니다.
· 에듀집(edzip.kr) — 에듀테크별 개인정보 필수기준 체크리스트 다운로드
· 체크리스트 등록 요청 — 에듀집에 없는 제품 등록 요청 창구
🧰 교사에게 유용한 도구모음
수업과 업무에서 바로 활용하실 수 있는 도구들입니다. 오늘 주제(데이터 백엔드)와는 별개로, 컴퓨터 업무를 가볍게 해 주는 도구들과 — 특히 요즘 많이 쓰는 NotebookLM·Notion을 모아 두었습니다.
컴퓨터 업무가 빨라지는 무료 도구
작지만 매일 쓰면 시간을 아껴 주는 도구들입니다.
Everything
파일 이름만 입력하면 즉시 찾아 주는 윈도우 무료 검색기. 폴더를 아무리 깊이 만들어도 탐색기보다 훨씬 빠릅니다. 예: 학습지 밀도, *.hwp, 체험학습 공문
NotebookLM & Notion
자료를 읽어 주는 AI 조교와, 무엇이든 정리하는 노트. 묶으면 학생·학부모 질문봇까지 만들 수 있습니다.
NotebookLM
내가 넣어 준 자료를 바탕으로 읽고 답해 주는 구글의 AI 조교입니다. 요약·질의응답은 물론 마인드맵·오디오 개요까지 만들어 줍니다.
| 도구 | 주요 역할 | 할 수 있는 것 |
|---|---|---|
| 🎧 NotebookLM | 자료 읽기 · 질문하기 · 요약 및 콘텐츠 생성 | 자료 추가, 질문, 마인드맵 또는 오디오 개요 |
| 🗂️ Notion | 자료 작성 · 배치 · 정리 · 공유 | 페이지 만들기, 블록 추가, 링크와 자료 정리 |
Notion·NotebookLM 참고 링크
연수 뒤 혼자 더 익히고 싶을 때.
| 자료 | 설명 | 링크 |
|---|---|---|
| 🛍️ 노션 템플릿 마켓플레이스 | 수천 개의 무료 템플릿을 골라 복제 | 열기 ↗ |
| ▶️ 노션 입문 바이블 영상 | 더 공부하고 싶다면 이 영상부터 (강사 추천) | 열기 ↗ |
| 💬 노션하는 교사톡 | 막히는 부분을 물어볼 수 있는 오픈채팅 | 열기 ↗ |
| 🎓 교육용 Plus 신청 | 대학 이메일 대상 — 초·중·고 교사는 보통 제외 | 열기 ↗ |
📝 나는 이런 도구를 만들고 싶다
오늘 배운 것을 한 줄로 완성해 주세요. 어떤 데이터를 · 왜 · 어떻게(익명?) 모아서 · 무엇을 볼 것인가 — 그리고 데이터 판사 결과(🟢🟡🔴)까지!
🙌 수고 많으셨습니다
오늘은 데이터를 모으는 법과, 모을 때 한 번 더 묻는 법을 함께 살펴봤어요.
완벽하지 않아도 괜찮습니다 — 오늘 나눈 질문들을 기억해 두시면 필요할 때 꺼내 쓰실 수 있어요.
함께해 주셔서 고맙습니다 😊
delete from reaction_results where room = 'yeonsu';수집의 마지막 단계는 언제나 파기입니다 ㅎㅎ 파쇄기! 🗑️