🔥딱 8일간! 인프런x토스x허먼밀러 역대급 혜택

블로그

코드캠프

입문자도 가넝한 8주만에 개발자 되는 법

안녕하세요! 실무 코딩부트캠프, 코드캠프입니다 :)날씨가 조금씩 따뜻해지면서 식곤증이 부쩍 늘어나고 있지 않나요?(전지적 컴퓨터 시점)그래서 코드캠프가 눈이 번쩍! 뜨이는(👀) 강의 업데이트 소식을 준비해왔어요!특히 비전공이지만 개발 커리어에 관심이 있는 분들이라면, 주목해주셔도 좋아요 :)코딩을 몰라도(NEW!) 2개월만에 개발자가 되는 '관리형' 코딩 부트캠프인프런에 입성한지 얼마 되지 않았지만 뜨거운 관심과 애정 어린 피드백을 받으며, 더 나은 컨텐츠를 제공하기 위해 코드캠프도 열심히 성장 중인데요. (정말 감사합니다)그 중 사전 기초 지식 없이는 부트캠프 합류가 어려워 신청을 망설였던 분들을 많이 보았어요.그래서 상담 후 등록을 완료해주신 모든 분들께,[시작은 프리캠프], [강력한 CSS], [훈훈한 Javascript] 기초 강의를 무료로 제공합니다!사전 지식을 필요로 하시는 분들은 웹 개발의 기초를 습득하시고사전 지식이 이미 있으신 분들은 기초 내용을 복습하면서 튼튼하게 다져보세요 :)⚠️ 단, 기초 강의 수강 기간은 부트캠프 기간(8주)에 포함되지 않으므로 등록하신 기수의 개강 일정에 맞춰 수강해 주셔야 합니다!(MBTI가 P인 분들)개강 전 기초 강의 수강 계획을 짜기 힘드신 분들은 언제든 코드캠프에 문의해주세요!개강일에 맞춰 수강할 수 있도록 체계적인 시간표를 제공해드리겠습니다 😊👉 2기 일정 : 03.06 - 04.28 (선착순 모집) ▶ 20% 할인 중!👉 3기 일정 : 04.03 - 05.29 (선착순 모집) ▶ 20% 할인 중!

웹 개발웹개발프론트엔드백엔드부트캠프비전공자JavascriptNode.jsReactNext.jsNest.js

조내일

[국내 최초] 인프런 풀스택 클론코딩 Part 1 - Next.js x NestJS 후기

✨ 들어가며기존에 Supabase + Next.js 기반의 사이드 프로젝트를 진행하면서, Supabase에 대한 정보가 많지 않아 시행착오를 겪었습니다. 그러던 중 로펀님의[풀스택 입문] Firebase보다 10배 좋은 Supabase와[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)강의를 통해 제가 놓쳤던 부분들을 많이 보완할 수 있었고, 사이드 프로젝트에도 직접 적용해볼 수 있어 좋은 경험이 되었습니다.이후 이름만 들어봤던 NestJS와 Prisma를 활용한 백엔드 구성에 대해 궁금함이 생겼고, 실제 업무에서도 써볼 수 있을 것 같다는 판단이 들어 이 강의를 수강하게 되었습니다. 🧱 강의 소개- 강의명: [국내 최초] 인프런 풀스택 클론코딩 Part 1 - Next.js x NestJS - 강사: 로펀 - 기술 스택: Next.js 15 (App Router) + NestJS + PostgreSQL + Prisma + AWS S3/CloudFront + Shadcn/UI 등실제 인프런 사이트를 클론 코딩하면서 프론트엔드와 백엔드 구조 전반을 설계/개발하는 과정 중심으로 구성되어 있습니다.💻 프로젝트 결과물🧩 사용 기술 및 인사이트✅ NestJS & Prisma 백엔드 구성강의에서는 NestJS의 의존성 주입, 모듈화, 서비스/컨트롤러 구조를 활용한 확장성 있는 백엔드 설계를 다룹니다.또한 Prisma를 활용해 아래와 같이 모델을 정의하고 PostgreSQL과 연결하여 데이터베이스 연동을 진행했습니다./backend/prisma/schema.prismadatasource db { provider = "postgresql" url = env("DATABASE_URL") } generator prismaClassGenerator { provider = "prisma-class-generator" dryRun = "false" separateRelationFields = "false" } generator client { provider = "prisma-client-js" } model Account { id String @id @default(cuid()) userId String @map("user_id") type String provider String providerAccountId String @map("provider_account_id") refresh_token String? @db.Text access_token String? @db.Text expires_at Int? token_type String? scope String? id_token String? @db.Text session_state String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([provider, providerAccountId]) @@map("accounts") } model Session { id String @id @default(cuid()) sessionToken String @unique @map("session_token") userId String @map("user_id") expires DateTime user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("sessions") } model User { id String @id @default(cuid()) name String? email String? @unique emailVerified DateTime? @map("email_verified") hashedPassword String? @map("hashed_password") image String? bio String? accounts Account[] sessions Session[] courses Course[] courseEnrollments CourseEnrollment[] courseReviews CourseReview[] courseQuestions CourseQuestion[] courseComments CourseComment[] lectureActivities LectureActivity[] @@map("users") } model VerificationToken { identifier String token String expires DateTime @@unique([identifier, token]) @@map("verification_tokens") } model Course { id String @id @default(uuid()) slug String @unique title String shortDescription String? @map("short_description") description String? @map("description") thumbnailUrl String? @map("thumbnail_url") price Int @default(0) discountPrice Int? @map("discount_price") level String @default("BEGINEER") status String @default("DRAFT") instructorId String @map("instructor_id") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") sections Section[] lectures Lecture[] categories CourseCategory[] courseEnrollments CourseEnrollment[] instructor User @relation(fields: [instructorId], references: [id]) courseReviews CourseReview[] courseQuestions CourseQuestion[] @@map("courses") } model Section { id String @id @default(uuid()) title String description String? order Int courseId String @map("course_id") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) lectures Lecture[] @@map("sections") } model Lecture { id String @id @default(uuid()) title String description String? order Int duration Int? isPreview Boolean @default(false) @map("is_preview") sectionId String @map("section_id") courseId String @map("course_id") videoStorageInfo Json? @map("video_storage_info") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") section Section @relation(fields: [sectionId], references: [id], onDelete: Cascade) course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) activities LectureActivity[] @@map("lectures") } model CourseCategory { id String @id @default(uuid()) name String slug String @unique description String? createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") courses Course[] @@map("course_categories") } model CourseEnrollment { id String @id @default(uuid()) userId String @map("user_id") courseId String @map("course_id") enrolledAt DateTime @default(now()) @map("enrolled_at") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, courseId]) @@map("course_enrollments") } model CourseReview { id String @id @default(uuid()) content String rating Int userId String @map("user_id") courseId String @map("course_id") instructorReply String? @map("instructor_reply") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, courseId]) @@map("course_reviews") } model CourseQuestion { id String @id @default(uuid()) title String content String userId String @map("user_id") courseId String @map("course_id") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") course Course @relation(fields: [courseId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) courseComments CourseComment[] @@map("course_questions") } model CourseComment { id String @id @default(uuid()) content String userId String @map("user_id") questionId String @map("question_id") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") courseQuestions CourseQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("course_comments") } model LectureActivity { id String @id @default(uuid()) userId String @map("user_id") lectureId String @map("lecture_id") progress Int @default(0) isCompleted Boolean @default(false) @map("is_completed") lastWatchedAt DateTime @default(now()) @map("last_watched_at") user User @relation(fields: [userId], references: [id], onDelete: Cascade) lecture Lecture @relation(fields: [lectureId], references: [id], onDelete: Cascade) @@unique([userId, lectureId]) @@map("lecture_activities") } 이를 통해 관계형 데이터 설계 및 실제 쿼리 구현에 대한 감을 익힐 수 있었습니다. 🎨Shadcn UI + TailwindCSS + Cursor AI개인적으로는 TailwindCSS를 선호하지 않지만, 이번 강의에서 함께 다룬 Shadcn UI 라이브러리를 통해 Tailwind 기반 컴포넌트를 쉽고 빠르게 구성할 수 있다는 점을 새롭게 알게 되었습니다.실제로 로그인, 대시보드 UI 등을 구현할 때 Shadcn UI 컴포넌트를 활용해 프론트엔드를 빠르게 구성할 수 있었고, 컴포넌트의 재사용성이나 커스터마이징 측면에서도 꽤 실용적이라는 인상을 받았습니다.또한, Cursor AI의 에이전트 모드를 활용해 UI를 구현하는 노하우를 알게 되어, 실무에서도 개발 생산성을 크게 높일 수 있을 것이라는 기대감이 생겼습니다. ⚠ 시행착오 & 해결 방법NestJS를 사용하면서 Windows 환경에서 개행문자(EOL) 이슈가 발생했습니다.VSCode에서 줄 끝에 빨간 줄이 생기는 현상이 있었고, 다음과 같이 해결할 수 있었습니다.1. Ctrl + Shift + P 또는 F1 키 입력2. Change End Of Line Sequence 검색3. LF로 변경 🛫 S3 + CloudFront영상을 S3에 업로드 후 CloudFront를 통한 스트리밍 구현까지 다루어, 실제 서비스에서 사용되는 미디어 배포 방식을 경험할 수 있었습니다.✨ 느낀 점과 다음 목표이번 강의를 통해 기획 → DB 설계 → API 작성 → 프론트 연동 → 인프라(S3+ CloudFront)까지서비스 전체 흐름을 실습할 수 있었고, 프론트엔드 개발자로서의 시야를 한층 넓힐 수 있었습니다.NestJS와 Prisma를 통한 구조적인 백엔드 설계는 처음이었지만,이제는 스스로 서버를 설계할 수 있다는 자신감을 얻었습니다.✅ 마무리단순한 클론 코딩을 넘어서 실제 서비스에 근접한 구조와 스택을 경험할 수 있어 정말 유익한 강의였습니다.풀스택 개발을 지향하는 분들, 특히 프론트엔드 개발자 분들이 백엔드 기초를 잡아보기에 정말 좋은 강의입니다.👀 Part 2에서 강의 탐색·수강·수강평·Q&A 기능도 기대되며, 최종적으로 AWS 배포 강의도 무척 기대가 됩니다!

풀스택Nest.jsPrismaNext15ShadcnUITailwindCSS

채널톡 아이콘