Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
dd0a987
feat: Youtube 영상 검색 api 구현
ekdbss Jul 19, 2025
00866f8
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Jul 23, 2025
468b6d6
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Jul 24, 2025
f05c17f
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Jul 24, 2025
73c20f8
feat: YouTube 영상 상세 조회 API 구현 및 DB 저장 기능 추가
ekdbss Jul 25, 2025
f3e296c
Fix: Add authentication middleware (requireAuth) to search route
ekdbss Jul 25, 2025
247790a
Chore: remove unnecessary folder
ekdbss Jul 26, 2025
14292ac
Chore: format code using Prettier
ekdbss Jul 26, 2025
62715a1
Merge branch 'main' into main
DongilMin Jul 26, 2025
533f93e
Update src/controllers/youtubeDetailController.ts
ekdbss Jul 26, 2025
9ee4d5a
Chore: format code using Prettier
ekdbss Jul 26, 2025
6570822
fix: add .js extensions to import paths in controller and route for d…
ekdbss Jul 26, 2025
75c89cc
Fix: merge conflict resolved from upstream main
ekdbss Jul 28, 2025
469a2aa
Fix: resolved merge conflict after pulling from upstream main
ekdbss Jul 28, 2025
4bcfb35
Merge remote-tracking branch 'upstream/main'
ekdbss Jul 29, 2025
09d063b
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Jul 29, 2025
7f14ccc
Merge remote-tracking branch 'upstream/main'
ekdbss Jul 29, 2025
fd10f1f
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Jul 31, 2025
7aae32a
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Aug 1, 2025
c611ef9
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Aug 6, 2025
eba55a4
feat: Youtube 영상 검색 api 구현
ekdbss Jul 19, 2025
007165a
feat: YouTube 영상 상세 조회 API 구현 및 DB 저장 기능 추가
ekdbss Jul 25, 2025
36a8c72
Fix: Add authentication middleware (requireAuth) to search route
ekdbss Jul 25, 2025
47a2c52
Chore: remove unnecessary folder
ekdbss Jul 26, 2025
e6b86c2
Chore: format code using Prettier
ekdbss Jul 26, 2025
e8ef12f
Update src/controllers/youtubeDetailController.ts
ekdbss Jul 26, 2025
d270b19
Chore: format code using Prettier
ekdbss Jul 26, 2025
dba47d0
fix: add .js extensions to import paths in controller and route for d…
ekdbss Jul 26, 2025
3c38a3b
Fix: resolved merge conflict after pulling from upstream main
ekdbss Jul 28, 2025
24fe5e0
Feat: bookmark API 개발 및 schema 수정
ekdbss Jul 30, 2025
cfcff45
Feat: Bookmark message, timeline parsing을 위한 util 함수 추가
ekdbss Jul 30, 2025
7692c40
Fix: 북마크 생성 시 parsing 함수 적용 및 timeline 분리 처리
ekdbss Jul 30, 2025
d09a695
Update src/dtos/bookmarkDto.ts
ekdbss Jul 30, 2025
8ee9f11
Update src/controllers/bookmarkController.ts
ekdbss Jul 30, 2025
92833dc
Refactor: 북마크 기반 방 생성 로직 정리 및 유효성 검사 강화
ekdbss Jul 31, 2025
2d39a0a
feat: Add validation for maxParticipants in createRoomFromBookmark
ekdbss Jul 31, 2025
487a5ff
Add /api prefix to bookmark-related endpoints
ekdbss Jul 31, 2025
c34ab21
Refactor: Move Prisma client import to lib/prisma.js
ekdbss Jul 31, 2025
1d3353e
Feat: 사용자 추천 관련 api 구현
ekdbss Jul 31, 2025
7f82c06
Feat: add search user status interface (#65)
DongilMin Jul 31, 2025
cbe2453
DOCS: README.md에 Swagger 접속 경로 추가 (#60)
DongilMin Jul 31, 2025
1f69f8e
Feat/search user interface (#69)
DongilMin Jul 31, 2025
66df72b
feat: 특정 방의 상세정보 조회 api 구현 (#68)
gaaahee Jul 31, 2025
ad78593
Chore: Remove unintended sharedCollection-related files
ekdbss Jul 31, 2025
814179b
Feat: 공유받은 컬렉션 목록 조회 API 구현 및 upstream main 병합
ekdbss Jul 31, 2025
70ffc5d
feat: 특정 방 상세정보 조회 api - duration 형식 변환 적용 (#70)
gaaahee Jul 31, 2025
268151f
fix: npm run build 에러 해결 (#73)
gaaahee Jul 31, 2025
0e08568
fix: npm run build 에러 해결 (#74)
gaaahee Jul 31, 2025
0d1e5f9
feat: 방 설정 수정 api 구현 (#75)
gaaahee Jul 31, 2025
f8abc5e
feat: 활성화된 방 목록 조회 api 구현 (#77)
gaaahee Aug 1, 2025
1b90d87
feat: 방 기존 설정 값 가져오는 api 구현 (#78)
gaaahee Aug 1, 2025
f70ce3b
feat: 활성화된 방 목록 조회 api 일부 수정 (#79)
gaaahee Aug 1, 2025
2c22164
Fix: Remove unrelated code for collection acceptance/rejection, keep …
ekdbss Aug 1, 2025
7c3d125
Feat/s3 upload (#80)
DongilMin Aug 1, 2025
16b3c2e
Feat/ai summary (#81)
DongilMin Aug 3, 2025
94b3173
Feat: Add Bedrock Claude Sonnet v1
DongilMin Aug 3, 2025
b6177f6
Feat/ai summary (#82)
DongilMin Aug 3, 2025
d7387cf
Feature: bookmark 관련 api 개발 및 prisma 수정 (#66)
ekdbss Aug 5, 2025
d6ab9fc
Feature: 사용자 recommendation 관련 api 구현 (#67)
ekdbss Aug 6, 2025
e7c8824
Feat: 공유 컬렉션 수락/거절 API 구현
ekdbss Aug 6, 2025
66270d4
chore: resolve merge conflict with upstream main
ekdbss Aug 6, 2025
00f80fb
Feature: sharedCollection 목록 조회 api 구현 (#72)
ekdbss Aug 6, 2025
a712700
chore: resolve merge conflict with upstream main
ekdbss Aug 6, 2025
f538714
chore: fix conflicts and finalize rebase
ekdbss Aug 6, 2025
1b8d955
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Aug 9, 2025
ab4b022
chore: resolve merge conflicts after pulling upstream main
ekdbss Aug 9, 2025
0db5445
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js
ekdbss Aug 9, 2025
3313440
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 12, 2025
e973e57
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 14, 2025
0908b65
fix: bookmarkRoute.ts 충돌 해결
ekdbss Aug 14, 2025
7f078ab
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 14, 2025
7240c38
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 17, 2025
710bed6
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 18, 2025
13ecaa3
fix: 라우트 순서 문제로 인한 북마크 조회 API 응답 오류 수정
ekdbss Aug 19, 2025
4765ac5
fix: 라우트 순서 충돌로 컬렉션 순서 변경 API 동작 문제 해결
ekdbss Aug 19, 2025
5090aee
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 19, 2025
72ed297
Merge branch 'feature/collection-api' of https://github.com/ekdbss/ON…
ekdbss Aug 19, 2025
fb5fa85
chore: format code using project formatter
ekdbss Aug 19, 2025
3ca87fa
chore: sync Prisma schema and regenerate client
ekdbss Aug 19, 2025
5e65019
Merge branch 'main' of https://github.com/ON-AIR-mate/Node.js into fe…
ekdbss Aug 20, 2025
7d88be8
fix: Prisma relation 필드명 변경(video → youtube_videos)으로 인한 타입 에러 수정
ekdbss Aug 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ model Room {
messages RoomMessage[]
participants RoomParticipant[]
host User @relation("HostUser", fields: [hostId], references: [userId], onDelete: Cascade)
video YoutubeVideo @relation("VideoOnRoom", fields: [videoId], references: [videoId])
youtube_videos YoutubeVideo @relation(fields: [videoId], references: [videoId])

Comment on lines +125 to 126
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

관계 필드 네이밍 불일치(youtube_videos → youtubeVideo) 및 onDelete 명시 권장

  • 단수(1) → 단수(1) 관계 필드를 복수형(youtube_videos)으로 네이밍한 점이 혼동을 유발합니다. 프로젝트 전반(CamelCase + @Map으로 스네이크케이스 매핑)과도 일관되지 않습니다. 이 필드는 DB 컬럼이 아닌 Prisma 관계 필드이므로 안전하게 리네이밍 가능합니다(클라이언트 타입만 변경).
  • videoId가 NOT NULL이므로 참조 대상(YoutubeVideo) 삭제 시 의도된 동작을 명확히 하려면 onDelete 정책을 명시해 주세요. 보통 제한(RESTRICT)이 자연스럽습니다. 만약 SET NULL을 원한다면 videoId를 옵셔널로 바꾸는 스키마 변경이 선행되어야 합니다.

제안 diff:

-  youtube_videos      YoutubeVideo      @relation(fields: [videoId], references: [videoId])
+  youtubeVideo        YoutubeVideo      @relation(fields: [videoId], references: [videoId], onDelete: Restrict)

검증 스크립트(레거시 참조 정리: Room.video, youtube_videos, VideoOnRoom 등):


🏁 Script executed:

#!/bin/bash
# 레거시 필드/관계명 사용 여부 확인
# 참고: node_modules 등은 기본적으로 미존재 환경이므로 별도 제외 옵션은 생략

# Room.video 또는 새/구 관계 필드 사용 흔적
rg -n -C2 -S '\broom\.(video|youtube_videos|youtubeVideo)\b' --type=ts

# Prisma select/include 등에서의 필드명 사용 흔적
rg -n -C3 -S '\b(video|youtube_videos|youtubeVideo)\s*:' --type=ts

# 기존 명시적 관계명 사용 흔적
rg -n -C2 -S '\bVideoOnRoom\b'

Length of output: 11187


스키마 파일에서 실제 youtube_videos 필드 존재 여부를 확인하기 위해 아래 스크립트를 실행해주세요:


🏁 Script executed:

#!/bin/bash
rg -n 'youtube_videos' -C2 prisma/schema.prisma

Length of output: 442


Prisma 스키마: 관계 필드 youtube_videos → youtubeVideo로 변경 및 onDelete 정책 명시

Prisma 스키마에서 관계 필드명이 복수형·스네이크케이스(youtube_videos)로 정의되어 있어, 프로젝트의 CamelCase 규칙과 불일치합니다. 또한 onDelete 행동이 명시되어 있지 않아 암묵적 DB 기본값(NO ACTION/RESTRICT)이 적용되는데, 추후 혼동을 방지하려면 명시하는 것이 좋습니다.

  • prisma/schema.prisma
    • Room 모델의 관계 필드명을 youtube_videosyoutubeVideo(singular CamelCase)로 변경
    • @relationonDelete: Restrict 추가
    • (DB 컬럼명(videoId), 테이블 매핑(@@Map) 등은 그대로 유지됩니다)

제안 diff:

 model Room {
   participants        RoomParticipant[]
   host                User              @relation("HostUser", fields: [hostId], references: [userId], onDelete: Cascade)
-  youtube_videos      YoutubeVideo      @relation(fields: [videoId], references: [videoId])
+  youtubeVideo        YoutubeVideo      @relation(fields: [videoId], references: [videoId], onDelete: Restrict)
 
   @@index([hostId], map: "rooms_host_id_fkey")
 }
  • TS 서비스 코드
    위 스키마 변경에 따라 Prisma 클라이언트 타입이 바뀌므로, 다음 패턴을 전역 검색·교체해야 합니다.
    • include/ select 구문에서
      { video: true }{ youtubeVideo: true }
    • 조회·처리 로직에서
      room.videoroom.youtubeVideo
    • 관련 타입 정의(예: BookmarkWithRelations, CollectionWithRelations, 메시지 페이로드 등)도 동일하게 업데이트

이 변경은 Prisma 클라이언트 API가 깨지는 브레이킹 체인지이므로, 코드 전반에 걸쳐 반드시 리팩터링을 적용해 주세요.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
youtube_videos YoutubeVideo @relation(fields: [videoId], references: [videoId])
model Room {
participants RoomParticipant[]
host User @relation("HostUser", fields: [hostId], references: [userId], onDelete: Cascade)
youtubeVideo YoutubeVideo @relation(fields: [videoId], references: [videoId], onDelete: Restrict)
@@index([hostId], map: "rooms_host_id_fkey")
}
🤖 Prompt for AI Agents
In prisma/schema.prisma around lines 125-126, rename the Room model relation
field from youtube_videos to youtubeVideo and add an explicit relation policy by
updating the @relation to include onDelete: Restrict while keeping the
underlying DB column names and @@map unchanged; after applying the schema
change, run prisma generate and update all TypeScript usages: replace
include/select { video: true } with { youtubeVideo: true }, replace room.video
references with room.youtubeVideo, and update related type names (e.g.,
BookmarkWithRelations, CollectionWithRelations, message payloads) to match the
new Prisma client types across the codebase to avoid breaking changes.

@@index([hostId], map: "rooms_host_id_fkey")
@@index([videoId], map: "rooms_video_id_fkey")
Expand Down Expand Up @@ -306,7 +306,7 @@ model YoutubeVideo {
duration String? @db.VarChar(20)
uploadedAt DateTime? @map("uploaded_at")
createdAt DateTime @default(now()) @map("created_at")
rooms Room[] @relation("VideoOnRoom")
rooms Room[]

@@map("youtube_videos")
}
Expand Down
71 changes: 45 additions & 26 deletions src/routes/collectionRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,51 @@ router.get('/', requireAuth, collectionController.getCollections);
*/
router.get('/:collectionId', requireAuth, collectionController.getCollectionDetail);

/**
* @swagger
* /api/collections/order:
* put:
* summary: 컬렉션 순서 변경
* tags: [Collections]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ReorderCollectionsDto'
* example:
* collectionOrders:
* - collectionId: 123
* order: 1
* - collectionId: 124
* order: 2
* responses:
* 200:
* description: 컬렉션 순서 변경 성공
*
* components:
* schemas:
* ReorderCollectionsDto:
* type: object
* properties:
* collectionOrders:
* type: array
* items:
* type: object
* properties:
* collectionId:
* type: integer
* example: 123
* order:
* type: integer
* example: 1
* required:
* - collectionOrders
*/
router.put('/order', requireAuth, collectionController.updateCollectionOrder);

/**
* @swagger
* /api/collections/{collectionId}:
Expand Down Expand Up @@ -154,32 +199,6 @@ router.put('/:collectionId', requireAuth, collectionController.updateCollection)
*/
router.delete('/:collectionId', requireAuth, collectionController.deleteCollection);

/**
* @swagger
* /api/collections/order:
* put:
* summary: 컬렉션 순서 변경
* tags: [Collections]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ReorderCollectionsDto'
* example:
* collectionOrders:
* - collectionId: 123
* order: 1
* - collectionId: 124
* order: 2
* responses:
* 200:
* description: 컬렉션 순서 변경 성공
*/
router.put('/order', requireAuth, collectionController.updateCollectionOrder);

/**
* 컬렉션 공유하기
*/
Expand Down
12 changes: 6 additions & 6 deletions src/services/bookmarkService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type BookmarkWithRelations = Prisma.BookmarkGetPayload<{
include: {
room: {
include: {
video: true; // Room.video (YoutubeVideo)
youtube_videos: true; // Room.video (YoutubeVideo)
};
};
collection: {
Expand Down Expand Up @@ -71,7 +71,7 @@ export const getBookmarks = async (userId: number, options: GetBookmarksOptions)
const rows: BookmarkWithRelations[] = await prisma.bookmark.findMany({
where: baseWhere,
include: {
room: { include: { video: true } },
room: { include: { youtube_videos: true } },
collection: { select: { title: true } },
},
orderBy: { createdAt: 'desc' },
Expand Down Expand Up @@ -108,8 +108,8 @@ export const getBookmarks = async (userId: number, options: GetBookmarksOptions)
for (const b of list) {
const roomId = b.roomId;
const roomName = b.room?.roomName ?? null;
const videoTitle = b.room?.video?.title ?? null;
const videoThumbnail = b.room?.video?.thumbnail ?? null;
const videoTitle = b.room?.youtube_videos?.title ?? null;
const videoThumbnail = b.room?.youtube_videos?.thumbnail ?? null;
const bookmarkCollectionTitle = b.collection?.title ?? null;

let idx = map.get(roomId);
Expand Down Expand Up @@ -246,7 +246,7 @@ export const createRoomFromBookmark = async (
include: {
room: {
include: {
video: true,
youtube_videos: true,
},
},
},
Expand All @@ -256,7 +256,7 @@ export const createRoomFromBookmark = async (
throw new Error('해당 북마크에 대한 권한이 없습니다.');
}

const videoThumbnail = bookmark.room?.video?.thumbnail ?? '';
const videoThumbnail = bookmark.room?.youtube_videos?.thumbnail ?? '';
const startTime = startFrom === 'BOOKMARK' ? (bookmark?.timeline ?? 0) : 0;

if (!bookmark.room?.videoId) {
Expand Down
6 changes: 3 additions & 3 deletions src/services/collectionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const getCollectionDetailById = async (
include: {
room: {
include: {
video: true,
youtube_videos: true,
},
},
},
Expand Down Expand Up @@ -107,8 +107,8 @@ export const getCollectionDetailById = async (
acc[room.roomId] = {
roomId: room.roomId,
roomTitle: room.roomName,
videoTitle: room.video.title,
videoThumbnail: room.video.thumbnail || '',
videoTitle: room.youtube_videos.title,
videoThumbnail: room.youtube_videos.thumbnail || '',
bookmarks: [],
};
}
Expand Down
Loading