# 교사를 위한 첫 웹앱 만들기
## Codex로 만들고, GitHub에 저장하고, Vercel로 배포하기

- 강의: 2026년 9월 14일(월) 19:00–21:00 KST / 120분, 휴식 10분 포함
- 강사: 박권 · TechKwon · 호원중학교
- 대상: 초보 교사. 사전 설치는 Codex만 전제, 계정 가입·설치 권한·접속은 사전 확인 허용. Git CLI 설치·GitHub 인증은 수업 중 실시.
- 앱: Supabase Auth + RLS로 자기 기록만 저장·조회하는 수업 활동 기록 앱. 개인별 격리된 실습 프로젝트, 가상 기록만 사용.
- 사용 기술: Vite vanilla JavaScript, @supabase/supabase-js. Node.js 24 LTS는 앱 제작 구간에서 버전 확인·설치·터미널과 Codex 재시작. 사전 Node 설치는 전제하지 않음.
- 범위 밖: GitHub Desktop, 웹 파일 업로드 중심 경로, 학생 공개 회원가입, 공개 DB 쓰기, MCP 설치 실습, 복잡한 다중 브랜치.

## 학습 목표와 평가
1. Git·GitHub·Vercel 및 코드·DB 역할 구분 → 개념 퀴즈
2. Git CLI 설치와 본인 GitHub 인증 → 버전과 비공개 저장소 clone
3. Codex로 DB 앱 제작 → 실제 저장·새로고침·다른 창 재조회·권한 차단
4. 검토·Commit·Push·Vercel 배포 → 코드 커밋과 운영 URL 근거
5. 수정·Push 후 자동 배포 → 같은 운영 URL에서 새 제목과 DB 유지

## 120분 진행표
| 시간 | 활동 | 완료 기준 |
|---|---|---|
| 19:00–19:10 · 10분 | Git · GitHub · Vercel 역할 | Git·GitHub·Vercel과 코드·DB의 역할을 구분했습니다. |
| 19:10–19:25 · 15분 | Git CLI 설치와 GitHub 인증 | Git 버전, GCM 버전, 내 비공개 저장소 clone 성공을 확인했습니다. |
| 19:25–19:55 · 30분 | Codex로 DB 연결 앱 만들기 | 내 Supabase DB 저장·재조회·새로고침·사용자 분리를 직접 확인했습니다. |
| 19:55–20:05 · 10분 | 10분 휴식 | 쉬고 돌아와 변경 검토를 시작할 준비가 됐습니다. |
| 20:05–20:15 · 10분 | Codex 검토 → Commit → Push | GitHub에서 최신 커밋과 파일을 확인했고 비밀값은 제외했습니다. |
| 20:15–20:35 · 20분 | Vercel 배포와 실제 DB 검증 | 운영 URL에서 실제 Supabase 저장·조회·권한을 검증했습니다. |
| 20:35–20:55 · 20분 | 수정 → Commit → Push → 자동 배포 | 같은 운영 URL에서 새 제목과 DB 저장·조회 유지까지 확인했습니다. |
| 20:55–21:00 · 5분 | 산출물 확인과 마무리 | 산출물과 미확인 항목을 구분하고 다음 개선 한 가지를 적었습니다. |

## 강사 사전 점검과 현실적인 시간 운영
- Codex 설치판의 실제 작업 폴더 선택·승인 흐름을 운영체제별로 확인하되 추정 GUI를 가르치지 않는다.
- Git·GCM·Node.js 공식 설치 파일과 네트워크·관리자 권한을 미리 확인한다. 참여자에게 사전 Git·GCM·Node 설치를 요구하지 않는다. macOS 대용량 설치, 조직 인증, 프로젝트 생성 대기는 시간 초과 위험이며 지연 시 관찰·복구본을 사용하고 미확인으로 표시한다.
- Supabase 계정 가입은 사전 가능하지만 DB 프로젝트 생성·SQL·사용자·환경 변수 단계는 19:25 이후 제공 절차로 함께 한다. 강사는 본인 격리 프로젝트로 사용자 A/B와 익명·변조 요청 권한 검증을 사전 수행한다.
- 19:25–35 Node.js 24 LTS 설치·버전 확인·터미널과 Codex 재시작 10분, 19:35–45 DB·SQL·본인 A/B 준비 10분, 19:45–55 생성 또는 복구 앱 연결·핵심 저장 확인 10분. 7분 준비 완료나 전원 완주를 보장하지 않는다. 19:45 환경·DB 미완료자는 관찰·미확인 경로로 전환한다. 복구 ZIP은 설치가 끝난 코드 생성 지연자에게만 제공하며 Node 설치를 대체하지 않는다. 20:15–35 배포 구간에 권한 검증을 이어가고 20:35–45를 지연 복구에 우선 배정한다. 20:45–55 제목 한 가지 수정·재배포, 20:55–21:00 미확인 항목을 포함해 정리한다. 120분 밖 숨은 설치 과제나 휴식 시간 실습은 요구하지 않는다.
- Supabase 선택 이유: 관리형 PostgreSQL·Auth·RLS를 한 서비스에서 연결 가능. publishable key만 클라이언트에 쓰고 RLS로 행 소유권을 강제한다. 공식 quickstart의 공개 읽기 예제 정책은 본 수업에 복사하지 않는다. 요금·프로젝트 제한·지역·기관 정책은 계정에서 다시 확인한다.

## 단계별 강사·참여자 진행안

### Git · GitHub · Vercel 역할 · 19:00–19:10 · 10분
Codex는 제작 도우미입니다. Git은 로컬 변경 기록, GitHub는 원격 코드, Vercel은 배포, Supabase는 데이터 저장을 맡습니다.
1. 완성 목표를 확인합니다: 로그인한 교사가 가상 활동 기록을 저장하고 목록을 조회하며 새로고침해도 유지합니다.
2. GitHub 저장소 주소와 Vercel 운영 주소를 구분합니다. 코드 파일이 올라가도 DB 기록까지 GitHub에 저장되는 것은 아닙니다.
3. 사전 설치는 Codex만 전제합니다. GitHub·Vercel·Supabase 계정 가입과 로그인 가능 여부, 설치 권한은 미리 확인합니다. Git과 인증은 다음 15분에 함께 합니다.

**왜 로그인까지 필요한가요?** — 공개 URL에 누구나 학생 기록을 쓰게 두지 않기 위해서입니다. 연습도 가상 데이터만 사용하며 로그인한 본인의 행만 허용합니다.

**시간이 부족하면** — macOS 설치 다운로드·조직 정책·네트워크는 15분을 넘을 수 있습니다. 설치 미완료자는 관찰 경로이며 복구 코드로 Node 설치를 대체할 수 없습니다. Git·Node 설치가 완료된 코드 생성 지연자만 별도 복구본을 사용합니다. 성공하지 않은 설치나 DB 검증을 통과로 기록하지 않습니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: Git·GitHub·Vercel과 코드·DB의 역할을 구분했습니다.

### Git CLI 설치와 GitHub 인증 · 19:10–19:25 · 15분
명령은 터미널에 한 줄씩 입력합니다. GitHub CLI(gh)는 Git과 다른 선택 도구이며 이번 기본 경로에서는 설치하거나 사용하지 않습니다.
1. Windows: https://git-scm.com/install/windows 에서 CPU에 맞는 Git for Windows 설치 파일 실행 → Git Credential Manager 기본 선택 유지 → 터미널을 새로 열고 git --version, git credential-manager --version 확인. 실습 명령은 Git Bash에서 진행합니다.
2. macOS: Terminal에서 xcode-select --install → 설치 창에서 완료까지 기다림 → 새 터미널에서 git --version. GCM은 https://github.com/git-ecosystem/git-credential-manager/releases/latest 의 macOS 설치 패키지(.pkg)를 별도로 설치하고 git credential-manager --version 확인합니다. 이미 Homebrew가 있다면 brew install --cask git-credential-manager도 가능합니다.
3. GitHub 웹에서 New repository → teacher-records → Private → Add README → Create repository. Code의 HTTPS clone 주소를 복사합니다. 파일 웹 업로드는 하지 않습니다.
4. 개인 실습 상위 폴더에서 git clone 뒤에 복사한 HTTPS 주소를 입력합니다. GCM 브라우저에서 본인이 GitHub 로그인·2단계 인증합니다. 비공개 저장소 clone 성공으로 읽기 인증을 확인하고 cd teacher-records, git status로 위치를 확인합니다. 쓰기 권한은 뒤의 Push에서 검증합니다.
5. 이 폴더 안에서 git config user.name "내 표시 이름" 및 git config user.email "GitHub에서 확인한 내 이메일"을 실행합니다. GitHub Settings → Emails의 본인 noreply 주소를 사용해도 됩니다. 예시를 실제 값으로 바꾸며 이 설정은 로그인이 아닙니다.

**GCM과 GitHub CLI의 차이** — GCM은 HTTPS 인증을 브라우저·OS 자격 증명 저장소와 연결합니다. gh를 쓰는 대안은 별도 설치와 gh auth login이 필요하지만 이번 과정에는 필요하지 않습니다.

**인증이 안 되면** — 브라우저 계정, 비공개 저장소 소유자, HTTPS 주소, GCM 설치를 확인합니다. GitHub 계정 비밀번호를 git의 Password 칸에 넣는 방식은 쓰지 않습니다. 토큰을 채팅에 붙여넣지 마세요.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: Git 버전, GCM 버전, 내 비공개 저장소 clone 성공을 확인했습니다.

### Codex로 DB 연결 앱 만들기 · 19:25–19:55 · 30분
19:25–35 Node.js 24 LTS 확인·설치·재시작에 10분, 19:35–45 개인 DB·SQL·A/B 사용자 준비에 10분, 19:45–55 생성 또는 복구 앱 연결·핵심 저장 확인에 10분을 배정합니다. 전원 설치를 7분 안에 끝낸다는 보장이 아닙니다. 19:45에 환경·DB 준비가 안 된 분은 강사 시연 관찰로 전환하고 미확인으로 기록합니다. 권한·다른 창 검증은 20:15–35 배포 구간에도 이어가고, 20:35–55 중 앞 10분은 지연 복구에 우선 사용합니다.
1. Codex에서 방금 clone한 teacher-records 폴더를 작업 대상으로 지정합니다. 실제 설치판의 폴더 선택 방법은 강사 화면으로 확인합니다. 추정한 Git GUI 버튼에 의존하지 않습니다. node --version과 npm --version으로 설치 여부와 버전을 확인합니다. 이 수업은 Node.js 24 LTS를 사용합니다. 미설치 또는 다른 버전이면 https://nodejs.org/en/download 에서 Node.js 24 LTS 설치 프로그램으로 설치한 뒤 터미널과 Codex를 모두 다시 열고 Node 24.x와 npm 버전을 재확인합니다. 사전 Node 설치는 전제하지 않습니다.
2. Supabase Dashboard에서 본인 organization → New project → 이름 teacher-records-lab, region, 강한 DB 비밀번호 설정 → 생성 완료까지 기다립니다. 운영 프로젝트를 재사용하지 않습니다. 요금·프로젝트 제한은 계정에서 확인합니다. DB 비밀번호는 앱에 넣지 않습니다.
3. 해당 프로젝트 SQL Editor → New query에 아래 SQL 원문을 붙여넣고 Run합니다. Table Editor의 activity_records와 정책을 확인합니다. Data API를 꺼두었다면 Integrations → Data API에서 활성화하고 public 스키마 노출을 확인합니다. 공개 읽기·쓰기 예제 정책은 추가하지 않습니다.
4. Authentication → Users → Add user → Create new user에서 각 참여자가 본인 소유의 동일한 Supabase 실습 프로젝트 안에 본인이 관리하는 서로 다른 이메일 두 개와 각각의 고유 비밀번호로 사용자 A와 B를 모두 만들고 Auto Confirm을 선택합니다. 비밀번호나 계정을 서로 공유하지 않습니다. 강사는 강사 소유의 별도 프로젝트에서 별도의 A/B로 시연합니다. Authentication 설정의 Allow new users to sign up을 끕니다. 앱은 로그인만 제공합니다. 화면 명칭이 다르면 공식 Auth 문서를 확인하며 관리자 API 키를 프론트에 넣는 우회는 하지 않습니다.
5. A 프롬프트를 Codex에 붙여넣습니다. 생성 대기 중 Connect 패널에서 Project URL과 publishable key를 확인하고 로컬 .env.local에 VITE_SUPABASE_URL, VITE_SUPABASE_PUBLISHABLE_KEY로 직접 입력합니다. 값은 채팅에 보내지 않습니다. 서버를 이미 실행했다면 재시작합니다.
6. npm install → npm run dev → 터미널에 표시된 localhost 주소로 접속합니다. 사용자 A로 로그인 → 활동명 ‘가상 토론’, 모둠 A, 메모 ‘의견 두 가지 정리’를 저장 → 새로고침 → 목록 유지 확인 → 다른 창에서 같은 계정 로그인·조회 → Table Editor의 실제 행 확인.
7. 로그아웃 후 목록·저장이 차단되는지 확인합니다. 본인이 만든 사용자 B로 별도 시크릿 창에서 같은 본인 프로젝트에 연결된 앱에 로그인합니다. B에게 A의 행이 보이지 않아야 합니다. 강사 프로젝트 계정으로 참여자 앱에 로그인하지 않습니다. 빈 입력과 연속 저장을 시험합니다. 실패하면 C 프롬프트로 수정하며 실제 DB 미연결을 데모 성공으로 대신하지 않습니다.

**왜 publishable key는 브라우저에 보이나요?** — VITE_ 변수는 빌드 결과에 공개됩니다. 공개 가능한 프로젝트 식별 값만 넣고 데이터 접근은 Auth 토큰과 DB RLS로 통제합니다. secret, service_role, DB 비밀번호를 넣으면 안 됩니다.

**DB와 브라우저 저장은 다른가요?** — localStorage나 IndexedDB의 새로고침 유지는 클라우드 DB 검증이 아닙니다. 실제 앱에서는 Supabase의 행과 다른 창의 재조회까지 확인해야 합니다. 아래 안내 사이트 데모는 가상 데이터의 브라우저 DB 체험으로 명확히 구분합니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: 내 Supabase DB 저장·재조회·새로고침·사용자 분리를 직접 확인했습니다.

### 10분 휴식 · 19:55–20:05 · 10분
파일을 저장하고 비밀값이 보이는 화면은 닫아 둡니다.
1. 노트북 화면에서 눈을 떼고 쉬어 갑니다.
2. 진도가 늦으면 디자인 확장은 생략합니다. 복구본을 썼다면 직접 생성한 결과와 구분합니다. DB 연결이 안 된 경우 미확인으로 남깁니다.

**돌아와서 할 일** — Codex의 설명과 git diff를 함께 읽고 변경한 파일만 커밋합니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: 쉬고 돌아와 변경 검토를 시작할 준비가 됐습니다.

### Codex 검토 → Commit → Push · 20:05–20:15 · 10분
Commit은 내 PC 기록, Push는 GitHub 업로드입니다. README를 clone한 main 브랜치에서 진행합니다.
1. D 프롬프트로 변경·보안·빌드를 검토합니다. git status, git diff를 읽고 .env.local이 제외됐는지 확인합니다. git check-ignore .env.local로 무시 여부도 확인합니다.
2. git add 뒤에 실제로 검토한 파일 경로만 지정합니다. 예: git add index.html src package.json package-lock.json .gitignore .env.example README.md (실제 생성 목록에 맞게 조정). git diff --cached --stat와 git diff --cached로 업로드 대상을 다시 확인합니다.
3. git commit -m "활동 기록 기본 기능 완성" → git push origin main. GCM 인증 창이 뜨면 본인이 로그인합니다. 실패 시 오류를 확인하고 강제 Push하지 않습니다.
4. GitHub 저장소 새로고침 → 새 커밋과 파일 확인. .env.local, node_modules, 비밀번호가 없어야 합니다. 커밋 작성자 이메일은 연결 GitHub 계정에서 확인한 주소를 사용합니다.

**실수로 비밀값을 올렸다면** — 파일 삭제만으로 과거 커밋에서 지워지지 않습니다. 즉시 해당 자격 증명을 폐기·교체하고 강사에게 비밀값 없이 상황을 알립니다. 공개 범위를 줄이고 저장소 이력 정리는 별도 지원으로 처리합니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: GitHub에서 최신 커밋과 파일을 확인했고 비밀값은 제외했습니다.

### Vercel 배포와 실제 DB 검증 · 20:15–20:35 · 20분
정적 파일 직접 열기와 다르게 Vite 빌드가 필요합니다. 로컬 환경 변수는 Vercel에 자동 복사되지 않습니다.
1. Vercel에서 새 프로젝트 → GitHub Import → teacher-records만 접근 허용 → 해당 저장소 선택.
2. Root Directory는 package.json이 있는 저장소 루트. Framework Preset Vite, Build Command npm run build, Output Directory dist, Install Command npm install을 확인합니다. 연결된 Production Branch는 main인지 확인합니다.
3. Environment Variables의 Production 범위에 VITE_SUPABASE_URL과 VITE_SUPABASE_PUBLISHABLE_KEY를 같은 실습 프로젝트 값으로 입력하고 Deploy합니다. Preview에는 실습 필요가 있을 때만 별도 설정합니다. 환경 변수를 바꾸면 새 배포가 필요합니다.
4. 완료 상태와 운영 URL을 확인합니다. 운영 URL에서 사용자 A 로그인 → 새 가상 기록 저장 → 새로고침 → 다른 창 같은 계정 조회 → Supabase Table Editor 행을 확인합니다.
5. 로그아웃 차단과 본인이 같은 본인 프로젝트에 만든 사용자 B의 분리도 시크릿 창에서 확인합니다. DB 키가 같아도 로그인 계정에 따라 보이는 행이 다릅니다. 운영 URL·커밋·테스트 결과를 기록합니다.

**주소가 로그인 화면을 보여요** — Vercel 배포 보호 화면과 앱의 Supabase 로그인 화면을 구분합니다. 운영 URL과 Preview URL을 확인하고 보안을 일괄 해제하지 않습니다.

**DB 오류가 나면** — 환경 변수 이름·Production 범위·새 배포 여부 → Supabase 프로젝트 상태 → 사용자 로그인 → grants/RLS 순서로 봅니다. DB를 공개 쓰기로 바꾸지 않습니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: 운영 URL에서 실제 Supabase 저장·조회·권한을 검증했습니다.

### 수정 → Commit → Push → 자동 배포 · 20:35–20:55 · 20분
20:35–45는 설치 완료자의 누락된 저장·권한 검증과 배포 복구에 우선 사용하고, 20:45–55는 제목 한 가지 수정·재배포에 사용합니다. 설치가 끝나지 않았으면 계속 관찰하며 미확인으로 남깁니다. 처음 받은 프로젝트 운영 URL을 계속 사용합니다. 개별 배포 URL은 특정 버전을 가리킬 수 있습니다.
1. E 프롬프트로 제목만 ‘우리 반 활동 기록’으로 바꿉니다. 로컬에서 기존 기록 조회·새 저장과 npm run build를 확인합니다.
2. git diff → 변경 파일만 git add → git diff --cached → git commit -m "활동 기록 제목 개선" → git push origin main 순서로 실행합니다.
3. GitHub 최신 커밋과 Vercel 새 배포의 커밋이 일치하는지 확인합니다. Git 연결·Production Branch·자동 배포 설정이 맞아야 Push가 운영 배포로 이어집니다.
4. 같은 프로젝트 운영 URL을 새로고침해 새 제목·기존 DB 기록·새 저장을 확인합니다. 수정 전후 화면과 커밋, 배포 상태를 기록합니다.

**제목이 그대로라면** — 파일 저장 → Commit → Push → main → 배포 성공 → 같은 운영 URL 순서로 확인합니다. 과거 개별 배포 주소와 캐시도 살펴봅니다. 성공 로그만으로 완료로 판단하지 않습니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: 같은 운영 URL에서 새 제목과 DB 저장·조회 유지까지 확인했습니다.

### 산출물 확인과 마무리 · 20:55–21:00 · 5분
앱·코드·데이터·운영 URL을 연결한 경험을 정리합니다. MCP는 참고 자료일 뿐 주 실습이 아닙니다.
1. DB 저장·조회 앱, GitHub 저장소·커밋, Vercel 운영 URL, 수정·재배포 근거를 확인합니다. 미확인 항목을 통과로 표시하지 않습니다.
2. 실제 학생 데이터를 쓰기 전 기관 정책·개인정보 처리·접근 권한·보관·삭제·백업·사용량을 별도로 검토합니다. 이번 실습은 개인별 가상 데이터 프로젝트입니다.
3. 수업 후 테스트 계정을 정리하고 실습 데이터 삭제 또는 프로젝트 종료 여부를 본인이 결정합니다. 공유 비밀번호를 만들지 않습니다.

**MCP 참고** — MCP는 AI와 외부 도구·자료를 연결하는 표준입니다. 별도 언어모델이 아니며 읽기와 쓰기·삭제 권한이 다릅니다. 오늘 설치·연결 실습은 하지 않습니다.

**최종 질문** — Commit만 하고 Push하지 않으면 운영 화면이 바뀔까요? 아니요. 환경 변수에 넣으면 VITE_ 값이 비밀이 될까요? 아니요. RLS와 인증이 데이터 권한을 지킵니다.

주의: 실제 학생 이름·평가·건강 정보는 입력하지 않습니다. 비밀번호·토큰·키를 AI 대화에 보내지 않습니다.

확인: 산출물과 미확인 항목을 구분하고 다음 개선 한 가지를 적었습니다.

## DB SQL 원문
새 실습 프로젝트의 SQL Editor에서 한 번 실행합니다. 이미 테이블이 있으면 덮어쓰거나 삭제하지 말고 대상 프로젝트를 확인하세요.

```sql
-- 개인별 새 실습 프로젝트에서 한 번 실행. 기존 운영 테이블에 실행하지 않기.
create table public.activity_records (
  id uuid primary key default gen_random_uuid(),
  user_id uuid not null references auth.users(id) default auth.uid(),
  activity text not null check (char_length(trim(activity)) between 1 and 60),
  group_name text not null check (group_name in ('가상 모둠 A','가상 모둠 B','가상 모둠 C')),
  note text not null check (char_length(trim(note)) between 1 and 200),
  created_at timestamptz not null default now()
);
alter table public.activity_records enable row level security;
revoke all on public.activity_records from anon, authenticated;
grant select, insert on public.activity_records to authenticated;
create policy own_read on public.activity_records for select to authenticated
  using ((select auth.uid()) = user_id);
create policy own_insert on public.activity_records for insert to authenticated
  with check ((select auth.uid()) = user_id);
```

## 복사해서 쓰는 프롬프트

### A. DB 연결 활동 기록 앱 제작
현재 teacher-records 작업 폴더에 교사용 ‘수업 활동 기록’ 앱을 만들어 주세요. 기존 README와 .git을 보존하세요.
Vite의 vanilla JavaScript와 @supabase/supabase-js를 사용하세요. node --version과 npm --version으로 설치 여부와 버전을 확인하세요. 이 수업은 Node.js 24 LTS를 사용합니다. 미설치 또는 다른 버전이면 공식 Node.js 24 LTS 설치 프로그램을 안내하고, 터미널과 Codex를 모두 다시 연 뒤 Node 24.x와 npm 버전을 재확인하세요. 선택한 Vite 패키지의 engines 요구사항도 확인하세요. 설치와 네트워크 사용 이유를 설명한 뒤 진행하세요.
이메일·비밀번호 로그인(signInWithPassword), 로그아웃, 활동명(1–60자), 가상 모둠 A/B/C 선택, 활동 메모(1–200자), 저장 버튼, 최신순 목록을 만드세요. 공개 회원가입 UI는 만들지 마세요. 각 참여자는 본인 소유의 동일한 Supabase 프로젝트에 본인이 관리하는 서로 다른 이메일과 고유 비밀번호로 A/B 두 사용자를 직접 준비합니다. 강사는 별도 강사 프로젝트로 시연하며 계정·비밀번호는 공유하지 않습니다. 로그인 비밀번호를 로그나 소스에 저장하지 마세요.
Supabase의 activity_records 테이블은 id, user_id, activity, group_name, note, created_at을 사용합니다. 제공 SQL의 RLS를 유지하세요. 저장 시 로그인한 user.id를 user_id에 넣고, 성공한 뒤 DB에서 목록을 다시 조회하세요. DB 오류를 성공으로 표시하거나 localStorage를 DB 대체로 쓰지 마세요.
.env.local의 VITE_SUPABASE_URL과 VITE_SUPABASE_PUBLISHABLE_KEY만 사용하세요. 값 없는 .env.example을 만들고 .env.local, .env.*, node_modules, dist를 .gitignore에 제외하되 .env.example은 허용하세요. 실제 값은 제가 로컬 파일에 직접 입력합니다. secret key, service_role, DB 비밀번호는 사용하지 마세요. VITE_ 값은 브라우저에 공개되므로 권한 보호는 Auth와 RLS가 담당합니다.
로그아웃 시 목록을 지우고 저장을 막으세요. 빈 입력·글자 제한·연속 저장 방지·네트워크 실패 안내·큰 글자·키보드·모바일을 구현하세요. 입력은 textContent로 표시하고 innerHTML로 삽입하지 마세요.
package.json에 dev/build/preview 명령을 만들고 npm install, npm run dev, npm run build 방법을 알려 주세요. 환경 변수가 없으면 설정 안내를 보여 주세요. HTML 파일을 직접 여는 방식은 쓰지 마세요.
공개 업로드·Push·배포·프로젝트 밖 변경은 하지 마세요. 생성 파일과 변경 이유를 설명하고 실제 실행한 테스트와 미확인 테스트를 구분하세요. 저장·새로고침·다른 창 조회·로그아웃 차단·다른 사용자 분리를 제가 확인할 체크리스트를 주세요.

### B. Git 설치와 인증 도움
저는 Codex만 설치한 초보입니다. 현재 운영체제와 git --version부터 확인해 주세요. Windows는 git-scm.com/install/windows의 Git for Windows와 기본 GCM, macOS는 xcode-select --install 후 Git 확인과 공식 GCM macOS 패키지 설치로 안내하세요. 설치 완료 전에는 다음 단계로 넘어가지 마세요. 별도 GitHub CLI는 이번 경로에서 사용하지 마세요.
GitHub에서 제가 만든 비공개 teacher-records 저장소의 HTTPS 주소로 git clone을 안내하세요. 실제 주소는 제가 확인해 입력합니다. 인증은 GCM이 여는 브라우저에서 제가 직접 로그인·2단계 인증합니다. Git user.name과 user.email은 작성자 정보이지 로그인 정보가 아님을 설명하세요. 비밀번호·토큰·인증 코드를 요청하거나 출력하지 마세요. clone 성공 후 폴더 위치와 git status를 확인하세요. Push는 지금 하지 마세요.

### C. 저장 오류 수정
실행 위치: [로컬 또는 Vercel 운영 URL]
재현 순서: [로그인 → 가상 기록 저장 → 새로고침]
기대한 결과: [DB 기록이 목록에 유지됨]
실제 결과: [오류 문구 또는 빈 목록, 개인정보·키 제거]
이 문제만 조사하고 수정해 주세요. 프로젝트 URL·환경 변수 이름·인증 상태·DB grants/RLS·브라우저 오류를 순서대로 확인하세요. RLS를 끄거나 공개 쓰기 정책을 추가하지 마세요. 원인과 수정 파일, 실제 실행한 검사, 제가 다시 확인할 항목을 구분하세요. 비밀값은 출력하지 마세요.

### D. Commit 전 검토와 배포 점검
현재 저장소의 git status와 git diff를 읽어 변경 파일을 설명하세요. 비밀값을 출력하지 말고 .env.local·인증 자료·학생 정보·node_modules·dist가 추적되지 않는지 확인하세요. .env.example에는 빈 값만 있어야 합니다.
npm run build를 실제 실행하고 결과를 보고하세요. 로그인·DB 저장/조회·RLS의 실제 실행 여부도 구분하세요. Vercel 설정이 Vite, npm run build, dist인지 확인하고 Production에 넣을 VITE_SUPABASE_URL, VITE_SUPABASE_PUBLISHABLE_KEY 이름만 안내하세요. secret/service_role 키는 필요하지 않습니다.
검토한 파일만 git add하는 명령을 제시하고, staged diff 확인 뒤 ‘활동 기록 기본 기능 완성’으로 Commit, git push origin main 하는 순서를 설명하세요. Commit과 Push는 제가 내용을 확인한 뒤 직접 실행합니다. 자동으로 Push·배포하지 마세요.

### E. 수정하고 같은 URL로 재배포
화면 제목만 ‘우리 반 활동 기록’으로 바꾸세요. 로그인·저장·DB 조회·RLS 설정은 그대로 유지하세요. 바꾼 파일을 설명하고 npm run build를 실제 확인하세요. 로컬에서 기존 기록 조회와 새 기록 저장을 다시 시험하는 방법을 알려 주세요.
제가 git diff → 검토 파일 git add → git diff --cached → git commit → git push origin main 순서로 수행한 뒤 Vercel에서 새 커밋의 자동 배포 완료와 같은 운영 URL의 새 제목을 확인하도록 안내하세요. 직접 Push나 배포하지 마세요.

## 30장 슬라이드 구성

### 01. 교사를 위한 첫 웹앱 만들기
2026.09.14 · 19:00–21:00 | Codex로 만들고 GitHub에 기록하고 Vercel로 배포

### 02. 오늘의 완성품
수업 활동 기록 앱 | 로그인 → 저장 → 목록 → 새로고침 후 유지 | 가상 기록만

### 03. Git · GitHub · Vercel
Git: 내 PC 변경 기록 | GitHub: 원격 코드 저장 | Vercel: 앱 배포 | Codex: 제작 도움

### 04. 코드와 데이터는 다른 곳에
코드: GitHub | 활동 기록: Supabase DB | 사용하는 주소: Vercel

### 05. 120분의 여정
19:00 개념 · 19:10 설치·인증 · 19:25 DB 앱 | 19:55 휴식 · 20:05 Commit·Push | 20:15 배포 · 20:35 수정·재배포 · 20:55 정리

### 06. Windows에서 Git 설치
Git 공식 설치 페이지 → Git for Windows | GCM 기본 선택 유지 | 새 터미널에서 git --version

### 07. macOS에서 Git 설치
터미널: xcode-select --install | 설치 완료 후 git --version | GCM은 공식 macOS 패키지로 별도 설치

### 08. 작성자 정보는 로그인이 아니다
git config user.name / user.email: 커밋 작성자 | GitHub 인증: GCM 브라우저 로그인·2단계 인증 | 비밀번호를 AI에 보내지 않기

### 09. 내 저장소로 인증 확인
GitHub에 비공개 저장소 + README 생성 | HTTPS 주소 복사 → git clone | 비공개 저장소 clone 성공으로 읽기 인증 확인

### 10. Codex와 같은 폴더 열기
teacher-records 폴더 | git status로 위치 확인 | Node.js LTS 설치 확인: node --version / npm --version

### 11. Supabase 실습 프로젝트
개인별 새 프로젝트 생성 | 학교 운영 DB와 분리 | 프로젝트 URL과 publishable key 확인

### 12. 로그인한 내 기록만
Supabase Auth + RLS | 내 user_id만 SELECT·INSERT | 비로그인 차단 · 다른 계정 기록 차단

### 13. DB 준비 세 단계
SQL Editor에서 제공 SQL 실행 | Auth 사용자 생성·공개 가입 차단 | 실제 학생 이름·평가 정보 입력 금지

### 14. 첫 제작 프롬프트
Vite + Supabase | 이메일 로그인 · 활동명 · 가상 모둠 · 메모 | 저장 성공 뒤 DB 목록 다시 조회

### 15. 환경 변수는 어디에
로컬 .env.local | VITE_SUPABASE_URL | VITE_SUPABASE_PUBLISHABLE_KEY | secret·service_role·DB 비밀번호 금지

### 16. 실행하고 실제로 저장
npm install → npm run dev | 표시된 localhost 주소 열기 | 로그인 → 가상 기록 저장 → 목록 확인

### 17. 새로고침은 검증 도구
새로고침 후 기록 유지 | 같은 계정 다른 창에서 조회 | Supabase Table Editor에서 실제 행 확인

### 18. 권한과 오류도 시험하기
로그아웃: 조회·저장 차단 | 다른 사용자: 내 행이 안 보임 | 빈 입력·연속 저장·실패 안내 확인

### 19. 19:55–20:05 휴식
파일 저장 · 비밀값 화면 닫기 | 돌아오면 변경 검토부터 | 늦으면 디자인 확장 생략

### 20. Codex와 변경 검토
git status / git diff | 관계없는 파일·비밀값 제외 | 빌드·권한·저장 테스트의 실제 결과 확인

### 21. Commit과 Push
git add: 검토한 파일만 | git commit: 내 PC 기록 | git push origin main: GitHub 업로드

### 22. GitHub에서 읽어 확인
파일과 최신 커밋 확인 | .env.local은 없어야 함 | 비공개 코드와 웹사이트 공개 여부는 별개

### 23. Vercel에 저장소 연결
새 프로젝트 → GitHub Import | teacher-records만 접근 허용 | Vite · npm run build · dist

### 24. 배포 환경 변수 설정
Production에 URL·publishable key 입력 | .env.local은 자동 업로드되지 않음 | 환경 변수 변경 뒤 새 배포 필요

### 25. 운영 주소에서 DB 검증
운영 URL 열기 → 로그인 → 가상 기록 저장 | 새로고침·다른 창 조회 | DB 실제 행 확인

### 26. 한 가지 개선 요청
제목을 우리 반 활동 기록으로 | 저장·로그인·RLS 유지 | 로컬에서 기존 기록과 새 저장 재검사

### 27. 수정 → Commit → Push
git diff → 검토한 파일 add → commit → push | main의 새 커밋 확인 | Vercel 자동 배포 완료 확인

### 28. 같은 주소가 새 버전으로
프로젝트 운영 URL 새로고침 | 새 제목·기존 DB 기록·새 저장 확인 | 과거 개별 배포 URL과 구분

### 29. MCP는 참고만
AI와 외부 도구를 연결하는 표준 | 오늘 설치·연결 실습 없음 | 읽기와 쓰기·삭제 권한 구분

### 30. 내가 만들고 배포했다
DB 저장·조회 앱 / GitHub 커밋 / Vercel 운영 URL | 수정 후 같은 주소 / 권한 테스트 | 실제 학생 적용은 별도 보안 검토

## 개인 활동지·검증 기록
- 실습 프로젝트: ______ / GitHub 저장소: ______ / Vercel 프로젝트 운영 URL: ______
- 첫 커밋: ______ / 수정 커밋: ______ / 연결된 배포: ______
- 수정 전후 화면과 같은 URL: ______ / 다음 개선: ______

| 항목 | 통과·수정필요·미확인 | 근거 |
|---|---|---|
| Git·GCM 버전 / 비공개 clone | | |
| npm run build | | |
| Supabase 실제 저장 및 Table Editor 행 | | |
| 새로고침·다른 창 같은 계정 조회 | | |
| 비로그인 SELECT·INSERT 거부 | | |
| 사용자 B에게 A의 행 안 보임 | | |
| 다른 user_id INSERT 거부 | | |
| 빈 입력·연속 저장·네트워크 실패 | | |
| GitHub 파일·커밋 / .env.local 제외 | | |
| Production 환경 변수 / 운영 URL DB 저장 | | |
| Push 후 같은 URL 새 제목·기존 DB 기록 | | |

## 권한 검증 주의
UI에서 버튼을 감춘 것만으로 DB 보안 검증이 되지 않습니다. 강사는 실제 Data API로 익명 SELECT·INSERT 거부, A의 자기 INSERT·SELECT 허용, A가 B의 user_id를 넣은 INSERT 거부, B의 A행 SELECT 빈 결과를 확인합니다. UPDATE·DELETE는 grants를 주지 않았으므로 거부되어야 합니다. 정책을 통과시키기 위해 RLS를 끄지 않습니다. 실제 Supabase 프로젝트 접근 없이는 이 항목을 미확인으로 둡니다.

## 공식 근거
확인: 2026-09-08. 설치·서비스 화면은 강의 직전에 다시 확인합니다.
- Git Windows: https://git-scm.com/install/windows
- Git macOS: https://git-scm.com/install/mac
- GitHub HTTPS 인증: https://docs.github.com/en/get-started/git-basics/caching-your-github-credentials-in-git
- GCM 설치: https://github.com/git-ecosystem/git-credential-manager/blob/release/docs/install.md
- Node.js LTS 설치: https://nodejs.org/en/download
- Supabase 시작·Vite 환경 변수: https://supabase.com/docs/guides/getting-started/quickstarts/reactjs
- Supabase RLS: https://supabase.com/docs/guides/database/postgres/row-level-security
- Supabase 이메일 로그인: https://supabase.com/docs/guides/auth/passwords
- Vercel 환경 변수: https://vercel.com/docs/environment-variables
- Vercel GitHub 자동 배포: https://vercel.com/docs/git/vercel-for-github
- Codex 공식 안내: https://developers.openai.com/codex/app
- MCP 참고만: https://developers.openai.com/learn/docs-mcp

## 안내 사이트와 실습 앱의 구분
이 Netlify 사이트는 강의 자료 안내·퀴즈·체크·슬라이드 뷰어입니다. 화면 데모는 정해진 가상 기록만 브라우저 IndexedDB에 저장하는 실제 동작 체험이며 Supabase 연결이나 사용자 권한 검증의 증거가 아닙니다. 실습 앱은 다운로드 복구 코드 또는 Codex 신규 생성 코드에 본인 Supabase 설정을 연결하고 Vercel에 배포합니다. DB 프로젝트와 Vercel 계정에 실제 연결하지 않은 검증은 미확인으로 표시합니다.
