C01 같은 앱의 저장 위치와 완료 기준 정하기
학생: 전날 수정·검색 앱을 열고 “이 브라우저 저장”과 “계정별 DB 저장”의 차이를 적는다. 오늘의 완료 기준은 회원가입→이메일 확인→로그인→내 과제 저장→새로고침·다른 브라우저 재조회→다른 계정 차단→공개 Vercel URL이다.

확인: 필수 범위는 이메일 로그인과 회원별 tasks CRUD다. Google·Kakao·Naver·MFA는 4일차에서 이어간다. 브라우저의 전날 목록은 자동 업로드하지 않으며 가상 과제를 새로 만든다.
강사: 1교시 도입8분 중 AI Studio는 선택 비교 시연5분만 사용한다. 주 실습은 Codex 경로다. 프런트엔드 HTML/CSS/JavaScript, Vite 빌드 도구, Supabase PostgreSQL·Auth·Data API의 역할을 실제 앱으로 비교한다. 별도 서버 언어를 새로 배우는 시간이 아니다.

C02 기능 브랜치와 Vite·공개 설정 준비
학생: 본인 저장소의 깨끗한 main을 최신화하고 feature/supabase-tasks를 만든다. Codex에 요청1을 입력해 기존 화면을 Vite 프로젝트로 구성한다. ZIP solution을 참고하면 index.html/styles.css/src/·package.json·lockfile·sql/을 저장소 루트에 둔다. .env.example을 .env.local로 복사해 본인 수업 프로젝트 URL과 publishable key를 입력하고 npm ci, npm run dev를 실행한다.
git status -sb
git switch main
git pull --ff-only origin main
git switch -c feature/supabase-tasks
node --version
npm ci
npm run dev
확인: Node는 설치 버전의 요구사항을 만족해야 한다(제공 예제는22.12이상). .env.local은 Git에서 무시된다. VITE_ 값은 브라우저에 포함되는 공개 설정이며 secret/service_role을 숨겨주는 기능이 아니다.
강사: 2일차에 clone한 폴더를 그대로 사용한다. Vite는 기존 HTML·JS를 빌드하는 도구다. ZIP의 solution 안 파일을 저장소 루트에 놓고 .git은 교체하지 않는다. GitHub Pages는 Vite 소스를 그대로 실행하지 못하므로 3일차 공개 주소는 Vercel로 기록한다. 이전 Pages 화면은 2일차 커밋에서 다시 확인할 수 있다.

C03 새 수업용 DB에 tasks·GRANT·RLS 적용
학생: 자신의 새 수업용 Supabase 프로젝트에서 SQL Editor를 열어 sql/setup.sql 전체를 한 번 실행한다. 기존 tasks가 있으면 구조와 정책부터 비교하고 임의로 삭제하지 않는다. sql/inspect.sql로 RLS·네 정책·authenticated의 접근 권한과 편집 가능한 열을 확인한다. Data API의 public 노출과 테이블 권한을 함께 확인한다.

확인: tasks.user_id는 auth.users.id와 연결된다. SELECT/DELETE는 소유자 USING, INSERT는 WITH CHECK, UPDATE는 USING+WITH CHECK다. anon에는 권한이 없다. 명시적 GRANT와 RLS는 각각 “테이블 접근”과 “행 접근”을 담당한다.
강사: 1교시50분은 도입8·프로젝트/환경10·스키마/RLS20·짝점검8·정리4다. 테이블이 보인다는 이유로 API 접근 성공을 단정하지 않는다. 최신 Supabase의 자동 노출 변화에 맞춰 명시적 GRANT를 사용한다. SQL Editor의 관리자 권한은 일반 사용자 RLS 검사를 대신하지 못한다. 프로젝트 생성·계정 준비는 수업 전에 마친다.

C04 회원가입·메일 확인·로그인·로그아웃 연결
학생: 요청2를 Codex에 입력하고 Authentication의 Email 가입과 Confirm email을 확인한다. 비밀번호 최소12자 정책을 앱과 서버에서 맞춘다. URL Configuration의 Site URL과 Redirect URLs에 실제 로컬 루트(http://localhost:5173/ 등)를 설정한다. 수신 가능한 수업 계정 A로 가입하고 메일 확인 뒤 로그인·새로고침·로그아웃을 각각 시험한다.

확인: 가입 요청 성공과 메일 도착·확인·로그인 성공을 따로 기록한다. PKCE 확인 링크는 요청한 같은 브라우저에서 연다. 다른 브라우저에서 확인했다면 이메일 확인 완료 후 원래 앱에서 이메일/비밀번호 로그인을 다시 시도한다.
강사: 2교시 50분은 흐름8·Auth 구현22·메일/세션8·짝 검증8·정리4다. 기본 SMTP는 발송 대상과 사용량 제한이 있다. 강사는 Resend 검증 도메인·SMTP 또는 로컬 Mailpit를 사전 준비한다. 메일이 막히면 이메일 확인 기능을 끄지 않고 발송 경로를 고친다. 비밀번호 분실 복구·변경은 완성 예제와 F09~F14를 보충으로 사용한다.

C05 내 과제 CRUD를 DB에 저장하고 다시 읽기
학생: A로 로그인해 가상 과제 두 개를 DB에 추가한다. 완료 상태를 바꾸고 제목·과목·마감일을 수정한다. 새로고침과 새로 불러오기로 DB 값을 재조회하고 삭제/되돌리기도 확인한다. 제목·과목 검색과 완료 필터·오늘/기한 지남 집계가 현재 계정 목록에서 작동하는지 확인한다.

확인: insert/update/delete의 error와 반환 행을 확인해야 성공이다. 수정 후 id·done·created_at과 개수는 유지된다. 다른 기기에서 같은 계정으로 로그인한 뒤 다시 조회하면 같은 DB 목록을 읽는다. 이 예제의 새로 불러오기는 Realtime 자동 동기화가 아니다.
강사: 3교시 50분은 읽기/쓰기8·CRUD 구현18·계정/권한12·짝 검증8·정리4다. DB 저장에서는 비동기 오류와 인증 상태를 함께 다룬다. 저장 실패 때 입력값을 남기고 성공 안내를 보내지 않는지 보여준다. 예제는 최대1,000건을 조회하며 대량 데이터는 페이지 나누기를 추후 설계한다.

C06 A·B 계정과 미로그인으로 권한 검증
학생: 브라우저 일반 창의 A와 별도 프로필/다른 브라우저의 B로 각각 로그인한다. A의 과제 id를 가상 테스트 기록에만 적고, B의 Data API로 A id 조회·수정·삭제와 user_id 위조 INSERT를 검사한다. 로그아웃 직후 목록과 폼이 비워지는지도 확인한다. 상세 검증표의 실제 결과를 기록한다.

확인: A는 자기 행만 CRUD, B의 A 조회는0건, 수정·삭제는0건 또는 오류, 위조 INSERT·소유자 변경은거절되어야 한다. 미로그인도 데이터에 접근하지 못한다. 화면이 숨겨졌다는 이유만으로 RLS 통과라 하지 않는다.
강사: 완성 ZIP의 절차와 Codex 검증 요청을 사용한다. 토큰을 스크린샷이나 과제물에 넣지 않는다. 화면 검색으로 A의 과제를 숨기는 것과 DB가 접근을 거절하는 것은 다르다. 빈 목록이 테이블 권한 오류인지 정상 RLS 차단인지 구분한다. 계정을 바꾸는 동안 도착한 이전 요청의 응답도 다른 계정 화면에 나타나지 않아야 한다.

C07 Git PR → Vercel Vite 배포
학생: 아래처럼 소스·SQL·lockfile·환경 예시만 stage하고 diff를 검토해 commit·push한다. 본인 저장소의 main을 대상으로 PR을 만들고 검토·병합한다. Vercel Add New Project→본인 GitHub 저장소 Import에서 앱이 있는 Root Directory, Vite, npm run build, dist를 확인한다. 두 VITE 공개 변수를 Production과 필요한 Preview에 입력하고 Deploy한다.
npm run build
git status -sb
git add index.html styles.css src package.json package-lock.json .gitignore .env.example sql
git diff --cached
git commit -m "Add Supabase auth and per-user tasks"
git push -u origin feature/supabase-tasks
확인: solution 안 파일을 저장소 루트에 넣었다면 Root Directory는 루트다. solution 폴더 자체를 저장소에 넣었다면 실제 경로를 지정한다. Vercel이 Next.js 또는 public/을 빌드하도록 설정되어 있으면 고친다. DB 비밀번호나 service_role은 입력하지 않는다.
강사: 4교시 50분은 빌드/Git8·Vercel12·URL/메일10·공개 A/B 검증12·짝 확인/정리8이다. 전날의 PR 절차를 재사용한다. Framework 자동 감지 결과를 검토한다. 환경값은 빌드에 포함되므로 변경 후 재배포한다. 앱 배포와 DB 스키마 적용은 별개이며 Vercel이 SQL을 자동 실행하지 않는다.

C08 공개 URL·인증 복귀·DB 재조회 최종 확인
학생: Vercel의 실제 Production URL을 Supabase Site URL로 넣고 Redirect URLs에 정확한 공개 루트와 필요한 로컬/Preview 루트를 허용한다. 설정 변경 뒤 새 배포를 만들고 가입메일이 공개 앱으로 돌아오는지 확인한다. 공개 앱에서 추가·수정·검색·완료·로그아웃·새로고침·다른 브라우저 A 재조회·B 차단을 다시 검사한다.
git switch main
git pull --ff-only origin main
git log --oneline -3
확인: 제출: PR URL·main 커밋·배포 커밋·Vercel URL·Supabase 프로젝트 식별자(키 제외)·메일/로그인/DB/권한 체크표. READY는 빌드·배포 상태이며 실제 가입·저장 통과와 다르다. 대기나 미실행은 미확인으로 기록한다.
강사: Resend SMTP는 Supabase Auth 설정에 보관한다. 앱이 별도 메일을 보내지 않는다면 Resend 키를 Vercel 클라이언트 환경에 넣지 않는다. SNS와 MFA는4일차에 진행하고 오늘은 이메일·DB·배포를 완주한다. 강의자료의 배포 검증과 학생 개인 프로젝트의 실제 통합 검증을 구분한다.