ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
정수학원 전용 LMS입니다. 강사는 Vimeo에 직접 영상을 업로드한 뒤 링크만 입력합니다 (Vimeo API 업로드 없음). • Next.js 15 (App Router) • TypeScript • Tailwind CSS • Supabase (Auth, DB, Storage, RLS) • Vercel 배포檢視完整 README ↗
정수학원 전용 LMS입니다. 강사는 Vimeo에 직접 영상을 업로드한 뒤 링크만 입력합니다 (Vimeo API 업로드 없음).
video-app/
├── supabase/
│ └── migrations/
│ └── 001_initial_schema.sql # 테이블 + RLS + Storage
├── src/
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx # 역할별 대시보드로 redirect
│ │ ├── globals.css
│ │ ├── (auth)/login/page.tsx
│ │ ├── auth/callback/route.ts # OAuth 후 role redirect
│ │ ├── admin/ # 관리자
│ │ │ ├── layout.tsx
│ │ │ ├── page.tsx
│ │ │ ├── courses/
│ │ │ │ ├── page.tsx
│ │ │ │ ├── new/page.tsx
│ │ │ │ └── [courseId]/page.tsx
│ │ │ ├── students/page.tsx # 과정 배정
│ │ │ └── teachers/page.tsx
│ │ ├── teacher/ # 강사
│ │ │ ├── layout.tsx
│ │ │ ├── page.tsx
│ │ │ └── courses/[courseId]/page.tsx # 단원·강의 등록
│ │ └── student/ # 학생
│ │ ├── layout.tsx
│ │ ├── page.tsx # 진도율 카드
│ │ └── courses/
│ │ ├── [courseId]/page.tsx
│ │ └── [courseId]/lessons/[lessonId]/page.tsx
│ ├── components/
│ │ ├── admin/ CourseForm, EnrollmentForm
│ │ ├── auth/ LoginForm
│ │ ├── layout/ DashboardNav, SignOutButton
│ │ ├── lessons/ CompleteLessonButton
│ │ ├── teacher/ SectionForm, LessonForm
│ │ ├── ui/ ProgressBar
│ │ └── vimeo/ VimeoPlayer
│ ├── lib/
│ │ ├── auth/ roles.ts, get-profile.ts
│ │ ├── progress/ calculate.ts
│ │ ├── supabase/ client, server, middleware
│ │ └── vimeo/ parse-url.ts
│ ├── types/database.ts
│ └── middleware.ts # 로그인 + role 경로 보호
├── .env.local.example
└── package.json
| 경로 | 역할 | 설명 |
|---|---|---|
/login | 공개 | 이메일 로그인 |
/admin | admin | 관리자 대시보드 |
/admin/courses | admin | 과정 목록·생성·수정 |
/admin/students | admin | 학생 과정 배정 |
/admin/teachers | admin | 강사 목록 |
/teacher | teacher | 담당 과정 |
/teacher/courses/[id] | teacher | 단원·강의·Vimeo·PDF |
/student | student | 수강 과정 + 진도율 |
/student/courses/[id] | student | 강의 목록 |
/student/courses/[id]/lessons/[id] | student | 영상 시청·완료·자료 |
src/middleware.ts): 미로그인 → /login, 로그인 후 /·/login → 역할 대시보드profiles.role → /admin | /teacher | /student/admin, /teacher, /student 접두사는 해당 role만 허용supabase/migrations/001_initial_schema.sql 실행course-materials (마이그레이션에 포함).env.local 생성:NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
profiles에서 해당 사용자 role을 admin으로 수정강사: role = teacher
학생: 가입 시 기본 student (metadata role로 지정 가능)
npm install
npm run dev
듣기 문항 음원 생성은 ElevenLabs만 사용합니다. (OpenAI TTS는 사용하지 않음)
AI 문항 생성·리포트 등은 기존처럼 OPENAI_API_KEY를 사용할 수 있습니다.
NEXT_PUBLIC_ 금지)| 변수 | 설명 |
|---|---|
ELEVENLABS_API_KEY | ElevenLabs API 키 |
.env.local 예시:
ELEVENLABS_API_KEY=your-api-key
ANN/M/W voice_id를 직접 설정하지 않아도 됩니다.
시스템이 ElevenLabs voice 목록(GET /v1/voices)을 불러와 안내/남성/여성 음성을 자동 배정합니다.
필요하면 관리자 화면 고급 음성 설정에서 세트별로 직접 선택할 수 있습니다.
| 변수 | 설명 |
|---|---|
SAVE_TTS_SEGMENTS=true | segment별 mp3도 Storage에 저장 (기본: final.mp3만 저장) |
ELEVENLABS_VOICE_ANN | env로 ANN voice_id 고정 (세트·UI 설정보다 우선순위 낮음) |
ELEVENLABS_VOICE_M | env로 M voice_id 고정 |
ELEVENLABS_VOICE_W | env로 W voice_id 고정 |
listening_sets.voice_ann_id / voice_m_id / voice_w_id (고급 설정에서 저장)ELEVENLABS_VOICE_ANN / M / W 환경변수 (설정된 경우)selectVoices.ts)ELEVENLABS_API_KEY를 Production에 추가한 뒤 Redeploy하면 음원 생성이 동작합니다.
segments (ANN/M/W) 순서대로 ElevenLabs TTSlistening/{setId}/{questionId}/final.mp3 업로드listening_questions.audio_url 최종 mp3만 재생구현: src/lib/listening/elevenlabs/ · audioProviders/elevenlabsTts.ts
관리자·강사 학습 리포트 화면에서 학부모용 공개 링크를 만들고, 카카오 JavaScript SDK로 공유창을 열어 채팅방을 선택해 보냅니다. (특정 학부모에게 API로 자동 발송하는 기능은 아닙니다.)
https://engcore.co.kr (배포 URL)http://localhost:3000, http://localhost:3001https://engcore.co.kr (경로 없이 도메인만).env.local에 환경변수 추가:NEXT_PUBLIC_KAKAO_JAVASCRIPT_KEY=카카오_JavaScript_키
NEXT_PUBLIC_SITE_URL=https://engcore.co.kr
학부모 공개 링크용 테이블: supabase/migrations/021_shared_reports.sql
SQL Editor에서 020 이후 순서대로 적용해 주세요.
| 버튼 | 설명 |
|---|---|
| 학부모용 링크 생성 | shared_reports에 저장, /report/share/{token} URL 생성 (30일) |
| 카카오톡보내기 | 텍스트(URL 포함) → 스크랩 → 피드 순으로 공유창 |
| 카카오 붙여넣기용 복사 | 채팅에 붙여넣으면 URL이 항상 탭 가능 (권장) |
| 링크 열기 | 새 탭에서 공개 리포트 (로그인 불필요) |
| 링크 복사 | 공개 URL 클립보드 복사 |
| PDF 저장 / 인쇄 | A4 리포트 미리보기 후 인쇄 |
공유 실패 시 링크가 클립보드에 복사되며 안내 메시지가 표시됩니다.
main 브랜치에 푸시하면 프로덕션에 자동 배포되도록 설정합니다.
한 번만 설정: docs/VERCEL_AUTO_DEPLOY.md 참고
kmjh734-max/jeongsu-lms 연결 (Production Branch: main)NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, OPENAI_API_KEY, ELEVENLABS_API_KEY, NEXT_PUBLIC_SITE_URL, NEXT_PUBLIC_KAKAO_JAVASCRIPT_KEY (카카오톡보내기 사용 시)https://jeongsu-lms.vercel.app 추가git push origin main → Vercel Deployments에 새 빌드 표시(대안) GitHub Actions Deploy Hook: .github/workflows/deploy-production.yml + Secret VERCEL_DEPLOY_HOOK
profiles.role)vimeo_video_id 추출 저장)VimeoPlayer)enrollments)lesson_progress)calculateCourseProgress)공개된 강의(is_published = true) 수를 분모로, 해당 학생의 lesson_progress.is_completed = true 개수를 분자로 사용합니다.
progressPercent = round((completed / total) * 100)
구현: src/lib/progress/calculate.ts