ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
영어학원의 모든 것을 하나로 · 영어 수업부터 학원 운영까지
Translation pending
EducationTypeScript · JavaScriptGitHub @kmjh734-maxOnlineOwner 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.
정수학원 전용 LMS입니다. 강사는 Vimeo에 직접 영상을 업로드한 뒤 링크만 입력합니다 (Vimeo API 업로드 없음). • Next.js 15 (App Router) • TypeScript • Tailwind CSS • Supabase (Auth, DB, Storage, RLS) • Vercel 배포Read the full 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