ESP32-S3 Bench Guide
ESP32‑S3 N16R8 벤치 가이드: 실시간 핀아웃, 강의, 시뮬레이터 및 벤치 로그
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Intelligent Course Registration Assistant for Suleyman Demirel University — Next.js 16, real SDU SIS integration, AI recommendations & assistant
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Plan, validate and (from Sprint 5) submit course registration for Suleyman Demirel University students.
Stack: Next.js 16 (App Router, Turbopack) · React 19 · Tailwind CSS v4 · shadcn-style components · Lucide · Sonner toasts · Prisma 7 + PostgreSQL · Zod · jose (sessions) · Vitest.
Design: minimal, monotone, modern — neutral zinc surfaces, hairline borders, soft shadows, one restrained blue accent, generous whitespace. No gradients. Colour carries meaning only (emerald = passed/open, red = conflict/full, amber = limited). Design tokens live in app/globals.css.
Status: this is the first delivery. It covers the project skeleton, the database schema for all 7 sprints, the SDU integration service (mock and live adapters), and the main planner dashboard. The rule engine for Sprints 2–3 (credit limit, seat status, time conflicts, prerequisites) is already built into the dashboard, because the timetable can't be interactive without it.
Requires Node.js ≥ 20.9.
npm install
cp .env.example .env.local # defaults run fully offline against the mock SDU backend
npm run dev # http://localhost:3000 → sign in as a demo student
Tests and checks:
npm test # 31 unit/integration tests (rules, search, SDU client + mock)
npm run typecheck
npm run build
Database (optional for the dashboard in mock mode):
# set DATABASE_URL in .env.local first
npm run db:migrate # applies prisma/migrations (schema + CHECK constraints)
npm run db:seed # syncs departments, catalog, demo students via the SDU adapter
Demo accounts (mock SSO): 230107021, Aigerim Tulegenova, CS year 3 (has a failed course to retake); 240103118, Nursultan Abenov, IS year 2.
sdu-course-assistant/
├── app/
│ ├── layout.tsx Root layout: fonts (Onest + JetBrains Mono, Kazakh-ready), toaster
│ ├── globals.css Tailwind v4 theme tokens: navy / gold / emerald / crimson / cyan
│ ├── (auth)/login/page.tsx SSO sign-in (mock mode lists demo students)
│ ├── (app)/ Authenticated shell (header + nav)
│ │ ├── layout.tsx
│ │ ├── error.tsx "SDU unreachable" boundary with retry
│ │ ├── dashboard/ ★ Planner: search sidebar + timetable + plan
│ │ └── transcript/ Completed-course tracker
│ └── api/
│ ├── auth/{login,callback,logout}/route.ts CAS SSO flow → signed session cookie
│ ├── me/route.ts Profile + transcript sync
│ ├── courses/route.ts Multi-filter catalog search
│ └── sections/availability/route.ts Live seat counts (polled)
├── components/
│ ├── ui/ shadcn-style primitives (button, badge, card, input, meter…)
│ ├── layout/ App header, nav
│ ├── dashboard/ Workspace state owner, search sidebar, result cards,
│ │ plan panel, stat strip, live-seat + plan hooks
│ └── timetable/timetable-grid.tsx ★ Interactive Mon–Fri grid with lane layout & previews
├── lib/
│ ├── domain/ App-wide types + time helpers (decoupled from SDU wire format)
│ ├── registration/ ★ Pure rule engine: conflicts, prerequisites, credit policy
│ ├── catalog/search.ts Shared search/filter (API route and client use the same code)
│ ├── auth/ JWT session (token.ts is edge/proxy-safe)
│ ├── sync/sdu-sync.ts SDU → Postgres mirror (seed today, cron later)
│ ├── data/queries.ts Request-scoped RSC loaders
│ ├── api/http.ts Route wrapper: auth + SDU error mapping
│ ├── env.ts Zod-validated environment
│ └── db.ts Prisma client (pg driver adapter)
├── services/
│ ├── sduApi.ts ★ SDU integration service: client, transports, factory
│ └── sdu/
│ ├── endpoints.ts Endpoint map (single routing table for both modes)
│ ├── contracts.ts Zod wire schemas (snake_case, validated at the boundary)
│ ├── mappers.ts Wire → domain translation
│ ├── mock-server.ts In-process fake SDU backend (atomic batch submit, seat drift)
│ └── fixtures.ts Fictional catalog, instructors, students
├── prisma/
│ ├── schema.prisma ★ All tables for Sprints 1–7
│ ├── migrations/ init + integrity CHECK constraints
│ └── seed.ts
├── proxy.ts Next 16 "proxy" (formerly middleware): auth gate
└── prisma.config.ts
| Sprint | Adds |
|---|---|
| 4 | lib/recommendation/ (scoring against DegreeRequirement), app/api/recommendations/route.ts, recommendation rail in the sidebar |
| 5 | app/api/plan/route.ts (moves the plan from localStorage to StagedSelection), app/api/registration/submit/route.ts (wraps sdu.batchSubmit and records a RegistrationBatch), app/api/waitlist/route.ts, a submit bar in PlanPanel |
| 6 | components/chat/ floating assistant + app/api/chat/route.ts (grounded in catalog and plan data), app/(advisor)/reviews/… plus app/api/advisor/reviews/… (ScheduleReview) |
| 7 | app/(admin)/capacity/… + app/api/admin/sections/[id]/capacity (CapacityChange, pushed to SDU), app/api/advisor/overrides (PrerequisiteOverride, fed into evaluatePrerequisites(…, waived)) |
Roles: the session type currently has only STUDENT. Sprints 6 and 7 add ADVISOR and REGISTRAR claims from CAS attributes. They map to StaffMember.role and get their own route groups guarded in proxy.ts.
UI / routes ──► SduApiClient ──► SduTransport ─┬─► HttpSduTransport (SDU_API_MODE=live)
(zod parse + │ CAS + REST, OAuth2 client-credentials,
wire→domain map) │ retries w/ backoff, timeouts, Idempotency-Key
└─► MockSduTransport (SDU_API_MODE=mock, default)
in-process fake answering the same endpoint keys
The mock sits at the transport level, so in dev the client's parsing, mapping, pagination and error handling all run exactly as they would in production.
| Key | Method | Path | Notes |
|---|---|---|---|
casLogin | GET | /cas/login?service= | Browser redirect |
casServiceValidate | GET | /cas/p3/serviceValidate?format=JSON | CAS protocol v3 |
casLogout | GET | /cas/logout?service= | Single sign-out |
studentProfile | GET | /api/v1/students/:studentId/profile | GPA, program, completed_credits, advisor |
studentTranscript | GET | /api/v1/students/:studentId/transcript | transcript_data[] |
departments | GET | /api/v1/departments | |
termSections | GET | /api/v1/terms/:termCode/sections?cursor= | Paginated; available_seats, total_capacity, instructor_name, time_slots, classroom |
sectionAvailability | GET | /api/v1/terms/:termCode/sections/availability?ids= | Live seats |
batchSubmit | POST | /api/v1/registration/batch-submit | Atomic, all-or-nothing; Idempotency-Key header |
waitlistJoin | POST | /api/v1/sections/:sectionId/waitlist |
⚠️ Confirm with SDU IT before going live. The CAS paths follow the public CAS protocol. The REST paths and payload shapes are a proposed contract, not a published SDU spec. When SDU provides its real OpenAPI document, the expected changes are limited to
services/sdu/endpoints.ts,contracts.tsandmappers.ts.
/api/auth/login → CAS (/cas/login?service=…/api/auth/callback) → /api/auth/callback?ticket= → server-to-server serviceValidate → profile check (suspended or graduated accounts are refused) → HS256 session cookie (8 h, httpOnly). proxy.ts redirects signed-out page views, and API routes return 401.
lib/registration/)| Rule | Behaviour | Sprint |
|---|---|---|
| Already passed | Block | 1 |
| Section full | Block (waitlist in Sprint 5) | 2 |
| Credit limit | Block over limit; standard 30 ECTS, 35 at GPA ≥ 3.33, 20 on probation | 2 |
| Prerequisites | Block. Rules are AND-of-OR groups, e.g. CSS 225 and (MAT 201 or MAT 250), and support advisor waivers | 3 |
| Time conflict | Warn (sweep-line per day, exclusive end times); highlighted per meeting on the grid | 3 |
| Same course, other section | Treated as a swap, not extra credits | — |
CREDIT_POLICY values are placeholders. Confirm them with the Registrar; they all live in lib/registration/credits.ts. The mock SDU enforces the same rules server-side on batch submit, as the real registration engine should.
The ownership model is documented at the top of prisma/schema.prisma. SDU is the system of record: students, transcripts, the catalog and enrolments are mirrored locally, keyed by SDU ids. This app owns the planning state: staged selections, batches, waitlist, reviews, overrides and capacity changes.
| Group | Tables |
|---|---|
| Structure | terms, departments, programs, degree_requirements |
| People | students, staff_members (advisor / registrar / admin), instructors |
| Catalog | courses, prerequisites (CNF: groupNo), sections, meetings |
| Record | transcript_entries |
| Registration | staged_selections, registration_batches (idempotency key), enrollments, waitlist_entries |
| Advising / admin | schedule_reviews, prerequisite_overrides, capacity_changes |
Available seats are derived (totalCapacity − enrolledCount), never stored. The second migration adds CHECK constraints for time windows, seat counters, self-prerequisites and GPA range.
aria-disabled, so keyboard and screen-reader users hear why a section is locked.