diff --git a/server/src/auth/auth.controller.spec.ts b/server/src/auth/auth.controller.spec.ts index 5c3541d..af190b8 100644 --- a/server/src/auth/auth.controller.spec.ts +++ b/server/src/auth/auth.controller.spec.ts @@ -5,11 +5,11 @@ import { getRepositoryToken } from '@nestjs/typeorm'; import { User } from 'src/entity/user.entity'; import { Repository } from 'typeorm'; import { JwtModule, JwtService } from '@nestjs/jwt'; -import { PlaylistService } from 'src/playlist/playlist.service'; import { Playlist } from 'src/entity/playlist.entity'; import { Music } from 'src/entity/music.entity'; import { Music_Playlist } from 'src/entity/music_playlist.entity'; -import { Logger, LoggerService } from '@nestjs/common'; +import { Logger } from '@nestjs/common'; +import { PassportModule } from '@nestjs/passport'; describe('AuthController', () => { let controller: AuthController; @@ -19,7 +19,7 @@ describe('AuthController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [JwtModule], + imports: [PassportModule.register({ defaultStrategy: 'jwt' }), JwtModule], controllers: [AuthController], providers: [ Logger, @@ -40,7 +40,6 @@ describe('AuthController', () => { provide: getRepositoryToken(Music_Playlist), useClass: Repository, }, - PlaylistService, ], }).compile(); diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index 10fa6de..2df4e86 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -7,10 +7,6 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from 'src/entity/user.entity'; import { AuthController } from './auth.controller'; import { AuthService } from './auth.service'; -import { PlaylistService } from 'src/playlist/playlist.service'; -import { Playlist } from 'src/entity/playlist.entity'; -import { Music } from 'src/entity/music.entity'; -import { Music_Playlist } from 'src/entity/music_playlist.entity'; import { Logger } from 'winston'; @Module({ @@ -24,9 +20,9 @@ import { Logger } from 'winston'; }), inject: [ConfigService], }), - TypeOrmModule.forFeature([User, Playlist, Music, Music_Playlist]), + TypeOrmModule.forFeature([User]), ], - providers: [JwtStrategy, AuthService, PlaylistService, Logger], + providers: [JwtStrategy, AuthService, Logger], exports: [JwtStrategy, PassportModule], controllers: [AuthController], }) diff --git a/server/src/auth/auth.service.spec.ts b/server/src/auth/auth.service.spec.ts index 26cc20e..6c63367 100644 --- a/server/src/auth/auth.service.spec.ts +++ b/server/src/auth/auth.service.spec.ts @@ -8,6 +8,7 @@ import { PlaylistService } from 'src/playlist/playlist.service'; import { Playlist } from 'src/entity/playlist.entity'; import { Music } from 'src/entity/music.entity'; import { Music_Playlist } from 'src/entity/music_playlist.entity'; +import { PassportModule } from '@nestjs/passport'; describe('AuthService', () => { let service: AuthService; @@ -17,7 +18,7 @@ describe('AuthService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [JwtModule], + imports: [PassportModule.register({ defaultStrategy: 'jwt' }), JwtModule], providers: [ AuthService, { diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts index 4315b7b..c2ee415 100644 --- a/server/src/auth/auth.service.ts +++ b/server/src/auth/auth.service.ts @@ -3,11 +3,9 @@ import { JwtService } from '@nestjs/jwt'; import { InjectRepository } from '@nestjs/typeorm'; import { CatchyException } from 'src/config/catchyException'; import { ERROR_CODE } from 'src/config/errorCode.enum'; -import { RECENT_PLAYLIST_NAME } from 'src/constants'; import { UserCreateDto } from 'src/dto/userCreate.dto'; import { User } from 'src/entity/user.entity'; import { HTTP_STATUS_CODE } from 'src/httpStatusCode.enum'; -import { PlaylistService } from 'src/playlist/playlist.service'; import { Repository } from 'typeorm'; import { v4 as uuid } from 'uuid'; @@ -17,7 +15,6 @@ export class AuthService { constructor( @InjectRepository(User) private userRepository: Repository, private jwtService: JwtService, - private readonly playlistService: PlaylistService, ) {} async login(email: string): Promise<{ accessToken: string }> { @@ -62,9 +59,6 @@ export class AuthService { }); await this.userRepository.save(newUser); - this.playlistService.createPlaylist(newUser.user_id, { - title: RECENT_PLAYLIST_NAME, - }); return this.login(email); } this.logger.error(`auth.service - signup : WRONG_TOKEN`); diff --git a/server/src/constants.ts b/server/src/constants.ts index c14d409..c5b49ce 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -14,7 +14,6 @@ export enum Genres { 'etc' = 'etc', } -export const RECENT_PLAYLIST_NAME = '최근 재생 목록'; export const keyFlags = ['user', 'cover']; export const contentTypeHandler: Record = { diff --git a/server/src/entity/music.entity.ts b/server/src/entity/music.entity.ts index fdbcea8..706bdec 100644 --- a/server/src/entity/music.entity.ts +++ b/server/src/entity/music.entity.ts @@ -12,6 +12,7 @@ import { import { User } from './user.entity'; import { Genres } from 'src/constants'; import { Music_Playlist } from './music_playlist.entity'; +import { Recent_Played } from './recent_played.entity'; @Entity({ name: 'music' }) export class Music extends BaseEntity { @@ -43,6 +44,9 @@ export class Music extends BaseEntity { @OneToMany(() => Music_Playlist, (music_playlist) => music_playlist.music) music_playlist: Music_Playlist[]; + @OneToMany(() => Recent_Played, (recent_played) => recent_played.music) + recent_played: Recent_Played[]; + static async getMusicListByUserId( userId: string, count: number, diff --git a/server/src/entity/music_playlist.entity.ts b/server/src/entity/music_playlist.entity.ts index 0285350..b811a89 100644 --- a/server/src/entity/music_playlist.entity.ts +++ b/server/src/entity/music_playlist.entity.ts @@ -8,7 +8,6 @@ import { } from 'typeorm'; import { Music } from './music.entity'; import { Playlist } from './playlist.entity'; -import { RECENT_PLAYLIST_NAME } from 'src/constants'; @Entity({ name: 'music_playlist' }) export class Music_Playlist extends BaseEntity { @@ -24,7 +23,7 @@ export class Music_Playlist extends BaseEntity { playlist: Playlist; @Column() - updated_at: Date; + created_at: Date; static async getMusicListByPlaylistId(playlistId: number): Promise { return this.find({ @@ -46,43 +45,11 @@ export class Music_Playlist extends BaseEntity { music_playlist_id: false, }, order: { - updated_at: 'DESC', + created_at: 'DESC', }, }).then((a: Music_Playlist[]) => a.map((b) => b.music)); } - static async getRecentPlayedMusicByUserId(userId: string): Promise { - return await this.find({ - relations: { - music: true, - }, - where: { - playlist: { - playlist_title: RECENT_PLAYLIST_NAME, - }, - music: { - user: { - user_id: userId, - }, - }, - }, - select: { - music_playlist_id: false, - music: { - music_id: true, - title: true, - music_file: true, - cover: true, - genre: true, - }, - }, - order: { - updated_at: 'DESC', - }, - take: 10, - }).then((a: Music_Playlist[]) => a.map((b) => b.music)); - } - static async getMusicCountByPlaylistId(playlist_id: number): Promise { return this.count({ where: { playlist: { playlist_id } } }); } @@ -94,7 +61,7 @@ export class Music_Playlist extends BaseEntity { relations: { music: true }, select: { music: { cover: true } }, where: { playlist: { playlist_id } }, - order: { updated_at: 'DESC' }, + order: { created_at: 'DESC' }, }); } } diff --git a/server/src/entity/recent_played.entity.ts b/server/src/entity/recent_played.entity.ts new file mode 100644 index 0000000..0d06966 --- /dev/null +++ b/server/src/entity/recent_played.entity.ts @@ -0,0 +1,61 @@ +import { + BaseEntity, + Column, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, +} from 'typeorm'; +import { Music } from './music.entity'; +import { User } from './user.entity'; + +@Entity({ name: 'recent_played' }) +export class Recent_Played extends BaseEntity { + @PrimaryGeneratedColumn() + recent_played_id: number; + + @ManyToOne(() => Music, (music) => music.recent_played) + @JoinColumn({ name: 'music_id' }) + music: Music; + + @ManyToOne(() => User, (user) => user.recent_played) + @JoinColumn({ name: 'user_id' }) + user: User; + + @Column() + played_at: Date; + + static async getRecentPlayedMusicByUserId( + user_id: string, + count: number, + ): Promise { + return await this.find({ + relations: { + music: { user: true }, + user: true, + }, + where: { + user: { + user_id, + }, + }, + select: { + recent_played_id: false, + music: { + music_id: true, + title: true, + music_file: true, + cover: true, + genre: true, + user: { user_id: true, nickname: true }, + }, + }, + order: { + played_at: 'DESC', + }, + take: count, + }).then((recent_played: Recent_Played[]) => + recent_played.map((recent) => recent.music), + ); + } +} diff --git a/server/src/entity/user.entity.ts b/server/src/entity/user.entity.ts index 5d56090..895d1d9 100644 --- a/server/src/entity/user.entity.ts +++ b/server/src/entity/user.entity.ts @@ -9,6 +9,7 @@ import { } from 'typeorm'; import { Playlist } from './playlist.entity'; import { Music } from './music.entity'; +import { Recent_Played } from './recent_played.entity'; @Entity({ name: 'user' }) export class User extends BaseEntity { @@ -33,6 +34,9 @@ export class User extends BaseEntity { @OneToMany(() => Playlist, (playlist) => playlist.user) playlists: Playlist[]; + @OneToMany(() => Recent_Played, (recent_played) => recent_played.user) + recent_played: Recent_Played[]; + static async getCertainUserByNickname(keyword: string): Promise { return this.find({ relations: { diff --git a/server/src/music/music.controller.spec.ts b/server/src/music/music.controller.spec.ts index c307388..c5f7513 100644 --- a/server/src/music/music.controller.spec.ts +++ b/server/src/music/music.controller.spec.ts @@ -8,16 +8,11 @@ import { ConfigService } from '@nestjs/config'; import { getRepositoryToken } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Music } from 'src/entity/music.entity'; -import { realMusicCreateInfo, user } from 'test/constants/music.mockData'; +import { user } from 'test/constants/music.mockData'; import { MusicController } from './music.controller'; -import * as request from 'supertest'; -import { HTTP_STATUS_CODE } from 'src/httpStatusCode.enum'; import { User } from 'src/entity/user.entity'; import { AuthService } from 'src/auth/auth.service'; import { JwtService } from '@nestjs/jwt'; -import { PlaylistService } from 'src/playlist/playlist.service'; -import { Playlist } from 'src/entity/playlist.entity'; -import { Music_Playlist } from 'src/entity/music_playlist.entity'; import { AuthGuard } from '@nestjs/passport'; import { GreenEyeService } from 'src/config/greenEye.service'; @@ -40,7 +35,6 @@ describe('UploadController', () => { ConfigService, GreenEyeService, AuthService, - PlaylistService, JwtService, { provide: getRepositoryToken(Music), @@ -50,14 +44,6 @@ describe('UploadController', () => { provide: getRepositoryToken(User), useClass: Repository, }, - { - provide: getRepositoryToken(Playlist), - useClass: Repository, - }, - { - provide: getRepositoryToken(Music_Playlist), - useClass: Repository, - }, ], }) .overrideGuard(AuthGuard) diff --git a/server/src/music/music.service.spec.ts b/server/src/music/music.service.spec.ts index 0f6fba8..0a32cd0 100644 --- a/server/src/music/music.service.spec.ts +++ b/server/src/music/music.service.spec.ts @@ -15,6 +15,7 @@ import { newMusicData, } from 'test/constants/music.mockData'; import { GreenEyeService } from 'src/config/greenEye.service'; +import { Recent_Played } from 'src/entity/recent_played.entity'; describe('UploadController', () => { let app: INestApplication; @@ -38,6 +39,10 @@ describe('UploadController', () => { provide: getRepositoryToken(Music), useClass: Repository, }, + { + provide: getRepositoryToken(Recent_Played), + useClass: Repository, + }, ], }).compile(); diff --git a/server/src/playlist/playlist.controller.ts b/server/src/playlist/playlist.controller.ts index cfefd39..3283902 100644 --- a/server/src/playlist/playlist.controller.ts +++ b/server/src/playlist/playlist.controller.ts @@ -5,8 +5,8 @@ import { HttpCode, Logger, Param, - Patch, Post, + Put, Req, UseGuards, UsePipes, @@ -22,9 +22,7 @@ import { Music } from 'src/entity/music.entity'; @Controller('playlists') export class PlaylistController { private readonly logger = new Logger('Playlist'); - constructor( - private playlistService: PlaylistService, - ) {} + constructor(private playlistService: PlaylistService) {} @Post() @UseGuards(AuthGuard()) @@ -90,35 +88,4 @@ export class PlaylistController { const userId: string = req.user.user_id; return await this.playlistService.getPlaylistMusics(userId, playlistId); } - - @Patch('recent-played') - @UseGuards(AuthGuard()) - @HttpCode(HTTP_STATUS_CODE.SUCCESS) - async updateRecentPlayMusic( - @Req() req, - @Body('musicId') music_id: string, - ): Promise<{ music_playlist_id: number }> { - this.logger.log( - `PATCH /playlists/recent-played - nickname=${req.user.nickname}, music_id=${music_id}`, - ); - const user_id: string = req.user.user_id; - const recentPlaylist: Playlist = - await this.playlistService.getRecentPlaylist(user_id); - const recentPlaylistId: number = recentPlaylist.playlist_id; - if (await this.playlistService.isAlreadyAdded(recentPlaylistId, music_id)) { - return { - music_playlist_id: await this.playlistService.updateRecentMusic( - music_id, - recentPlaylistId, - ), - }; - } - return { - music_playlist_id: await this.playlistService.addMusicToPlaylist( - user_id, - recentPlaylistId, - music_id, - ), - }; - } } diff --git a/server/src/playlist/playlist.service.ts b/server/src/playlist/playlist.service.ts index 5cefa37..4e9c1a5 100644 --- a/server/src/playlist/playlist.service.ts +++ b/server/src/playlist/playlist.service.ts @@ -2,7 +2,6 @@ import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { CatchyException } from 'src/config/catchyException'; import { ERROR_CODE } from 'src/config/errorCode.enum'; -import { RECENT_PLAYLIST_NAME } from 'src/constants'; import { PlaylistCreateDto } from 'src/dto/playlistCreate.dto'; import { Music } from 'src/entity/music.entity'; import { Music_Playlist } from 'src/entity/music_playlist.entity'; @@ -94,7 +93,7 @@ export class PlaylistService { this.music_playlistRepository.create({ music: { music_id: musicId }, playlist: { playlist_id: playlistId }, - updated_at: new Date(), + created_at: new Date(), }); const result: Music_Playlist = @@ -237,61 +236,4 @@ export class PlaylistService { ); } } - - async getRecentMusicsByUserId(userId: string) { - try { - return Music_Playlist.getRecentPlayedMusicByUserId(userId); - } catch { - this.logger.error( - `playlist.service - getRecentMusicsByUserId : SERVER_ERROR`, - ); - throw new CatchyException( - 'SERVER ERROR', - HTTP_STATUS_CODE.SERVER_ERROR, - ERROR_CODE.SERVER_ERROR, - ); - } - } - - async getRecentPlaylist(user_id: string): Promise { - try { - return await this.playlistRepository.findOne({ - where: { - user: { user_id }, - playlist_title: RECENT_PLAYLIST_NAME, - }, - }); - } catch { - this.logger.error(`playlist.service - getRecentPlaylist : QUERY_ERROR`); - throw new CatchyException( - 'QUERY_ERROR', - HTTP_STATUS_CODE.SERVER_ERROR, - ERROR_CODE.QUERY_ERROR, - ); - } - } - - async updateRecentMusic( - music_id: string, - playlist_id: number, - ): Promise { - try { - const music_playlist: Music_Playlist = - await this.music_playlistRepository.findOne({ - where: { music: { music_id }, playlist: { playlist_id } }, - }); - - music_playlist.updated_at = new Date(); - const savedData: Music_Playlist = - await this.music_playlistRepository.save(music_playlist); - return savedData.music_playlist_id; - } catch { - this.logger.error(`playlist.service - updateRecentMusic : SERVICE_ERROR`); - throw new CatchyException( - 'SERVICE_ERROR', - HTTP_STATUS_CODE.SERVER_ERROR, - ERROR_CODE.SERVICE_ERROR, - ); - } - } } diff --git a/server/src/user/user.controller.spec.ts b/server/src/user/user.controller.spec.ts index 275f626..868d4b0 100644 --- a/server/src/user/user.controller.spec.ts +++ b/server/src/user/user.controller.spec.ts @@ -4,15 +4,11 @@ import { UserService } from './user.service'; import { getRepositoryToken } from '@nestjs/typeorm'; import { User } from 'src/entity/user.entity'; import { Repository } from 'typeorm'; -import { PlaylistService } from 'src/playlist/playlist.service'; -import { Music } from 'src/entity/music.entity'; -import { Music_Playlist } from 'src/entity/music_playlist.entity'; -import { Playlist } from 'src/entity/playlist.entity'; +import { Recent_Played } from 'src/entity/recent_played.entity'; describe('UserController', () => { let controller: UserController; let userService: UserService; - let playlistService: PlaylistService; let userRepository: Repository; beforeEach(async () => { @@ -20,21 +16,12 @@ describe('UserController', () => { controllers: [UserController], providers: [ UserService, - PlaylistService, { provide: getRepositoryToken(User), useClass: Repository, }, { - provide: getRepositoryToken(Playlist), - useClass: Repository, - }, - { - provide: getRepositoryToken(Music), - useClass: Repository, - }, - { - provide: getRepositoryToken(Music_Playlist), + provide: getRepositoryToken(Recent_Played), useClass: Repository, }, ], @@ -42,7 +29,6 @@ describe('UserController', () => { controller = module.get(UserController); userService = module.get(UserService); - playlistService = module.get(PlaylistService); userRepository = module.get(getRepositoryToken(User)); }); diff --git a/server/src/user/user.controller.ts b/server/src/user/user.controller.ts index 2b735b6..b35efb2 100644 --- a/server/src/user/user.controller.ts +++ b/server/src/user/user.controller.ts @@ -9,6 +9,7 @@ import { Body, Query, Logger, + Put, } from '@nestjs/common'; import { UserService } from './user.service'; import { HTTP_STATUS_CODE } from 'src/httpStatusCode.enum'; @@ -21,9 +22,7 @@ import { User } from 'src/entity/user.entity'; @Controller('users') export class UserController { private readonly logger = new Logger('User'); - constructor( - private userService: UserService, - ) {} + constructor(private userService: UserService) {} @Get('duplicate/:name') @HttpCode(HTTP_STATUS_CODE.NOT_DUPLICATED_NICKNAME) @@ -45,11 +44,16 @@ export class UserController { @Get('recent-played') @UseGuards(AuthGuard()) @HttpCode(HTTP_STATUS_CODE.SUCCESS) - async getUserRecentPlayedMusics(@Req() req): Promise { + async getUserRecentPlayedMusics( + @Req() req, + @Query('count') count: number, + ): Promise { this.logger.log(`GET /users/recent-played - nickname=${req.user.nickname}`); const userId = req.user.userId; - const userMusicData = - await this.userService.getRecentPlayedMusicByUserId(userId); + const userMusicData = await this.userService.getRecentPlayedMusicByUserId( + userId, + count, + ); return userMusicData; } @@ -88,4 +92,37 @@ export class UserController { this.logger.log(`GET /users/search - keyword=${keyword}`); return this.userService.getCertainKeywordNicknameUser(keyword); } + + @Put('recent-played') + @UseGuards(AuthGuard()) + @HttpCode(HTTP_STATUS_CODE.SUCCESS) + async updateRecentPlayMusic( + @Req() req, + @Body('musicId') music_id: string, + ): Promise<{ recent_played_id: number }> { + this.logger.log( + `PUT /user/recent-played - nickname=${req.user.nickname}, music_id=${music_id}`, + ); + const user_id: string = req.user.user_id; + const recent_played_id: number = await this.userService.updateRecentMusic( + music_id, + user_id, + ); + return { recent_played_id }; + } + + @Get('recent-info') + @UseGuards(AuthGuard()) + @HttpCode(HTTP_STATUS_CODE.SUCCESS) + async getRecentPlaylistInfo( + @Req() req, + ): Promise<{ music_count: number; thumbnail: string }> { + const user_id: string = req.user.user_id; + this.logger.log(`GET /user/recent-info - nickname=${req.user.nickname}`); + const music_count: number = + await this.userService.getRecentPlaylistMusicCount(user_id); + const thumbnail: string = + await this.userService.getRecentPlaylistThumbnail(user_id); + return { music_count, thumbnail }; + } } diff --git a/server/src/user/user.module.ts b/server/src/user/user.module.ts index dc312e1..ecaff11 100644 --- a/server/src/user/user.module.ts +++ b/server/src/user/user.module.ts @@ -4,18 +4,12 @@ import { UserService } from './user.service'; import { TypeOrmModule } from '@nestjs/typeorm'; import { User } from 'src/entity/user.entity'; import { AuthModule } from 'src/auth/auth.module'; -import { PlaylistService } from 'src/playlist/playlist.service'; -import { Playlist } from 'src/entity/playlist.entity'; -import { Music_Playlist } from 'src/entity/music_playlist.entity'; -import { Music } from 'src/entity/music.entity'; import { Logger } from 'winston'; +import { Recent_Played } from 'src/entity/recent_played.entity'; @Module({ - imports: [ - TypeOrmModule.forFeature([User, Playlist, Music_Playlist, Music]), - AuthModule, - ], + imports: [TypeOrmModule.forFeature([User, Recent_Played]), AuthModule], controllers: [UserController], - providers: [UserService, PlaylistService, Logger], + providers: [UserService, Logger], }) export class UserModule {} diff --git a/server/src/user/user.service.spec.ts b/server/src/user/user.service.spec.ts index 93b2135..33aa0ed 100644 --- a/server/src/user/user.service.spec.ts +++ b/server/src/user/user.service.spec.ts @@ -3,42 +3,30 @@ import { UserService } from './user.service'; import { getRepositoryToken } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from '../entity/user.entity'; -import { Playlist } from 'src/entity/playlist.entity'; -import { Music } from 'src/entity/music.entity'; -import { Music_Playlist } from 'src/entity/music_playlist.entity'; -import { PlaylistService } from 'src/playlist/playlist.service'; +import { Recent_Played } from 'src/entity/recent_played.entity'; +import { PassportModule } from '@nestjs/passport'; describe('UserService', () => { let service: UserService; - let playlistService: PlaylistService; let userRepository: Repository; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ + imports: [PassportModule.register({ defaultStrategy: 'jwt' })], providers: [ UserService, - PlaylistService, { provide: getRepositoryToken(User), useClass: Repository, }, { - provide: getRepositoryToken(Playlist), - useClass: Repository, - }, - { - provide: getRepositoryToken(Music), - useClass: Repository, - }, - { - provide: getRepositoryToken(Music_Playlist), + provide: getRepositoryToken(Recent_Played), useClass: Repository, }, ], }).compile(); service = module.get(UserService); - playlistService = module.get(PlaylistService); userRepository = module.get(getRepositoryToken(User)); }); diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index ade6cfd..7647a15 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -4,16 +4,17 @@ import { User } from 'src/entity/user.entity'; import { Music } from 'src/entity/music.entity'; import { Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; -import { PlaylistService } from 'src/playlist/playlist.service'; import { CatchyException } from 'src/config/catchyException'; import { ERROR_CODE } from 'src/config/errorCode.enum'; +import { Recent_Played } from 'src/entity/recent_played.entity'; @Injectable() export class UserService { private readonly logger = new Logger('UserService'); constructor( @InjectRepository(User) private userRepository: Repository, - private playlistService: PlaylistService, + @InjectRepository(Recent_Played) + private recentPlayedRepository: Repository, ) {} async isDuplicatedUserEmail(userNickname: string): Promise { @@ -37,8 +38,22 @@ export class UserService { } } - async getRecentPlayedMusicByUserId(userId: string): Promise { - return await this.playlistService.getRecentMusicsByUserId(userId); + async getRecentPlayedMusicByUserId( + userId: string, + count: number, + ): Promise { + try { + return await Recent_Played.getRecentPlayedMusicByUserId(userId, count); + } catch { + this.logger.error( + `user.service - getRecentPlayedMusicByUserId : QUERY_ERROR`, + ); + throw new CatchyException( + 'QUERY_ERROR', + HTTP_STATUS_CODE.SERVER_ERROR, + ERROR_CODE.QUERY_ERROR, + ); + } } async updateUserImage(user_id: string, image_url: string): Promise { @@ -102,4 +117,108 @@ export class UserService { ); } } + + async isExistMusicInRecentPlaylist( + music_id: string, + user_id: string, + ): Promise { + try { + const musicCount: number = await this.recentPlayedRepository.count({ + where: { music: { music_id }, user: { user_id } }, + }); + return musicCount != 0; + } catch { + this.logger.error( + `user.service - isExistMusicInRecentPlaylist : QUERY_ERROR`, + ); + throw new CatchyException( + 'QUERY_ERROR', + HTTP_STATUS_CODE.SERVER_ERROR, + ERROR_CODE.QUERY_ERROR, + ); + } + } + + async updateRecentMusic(music_id: string, user_id: string): Promise { + try { + if (!(await Music.getMusicById(music_id))) { + this.logger.error( + `user.service - updateRecentMusic : NOT_EXIST_MUSIC_ID`, + ); + throw new CatchyException( + 'NOT_EXIST_MUSIC_ID', + HTTP_STATUS_CODE.BAD_REQUEST, + ERROR_CODE.NOT_EXIST_MUSIC_ID, + ); + } + if (!(await this.isExistMusicInRecentPlaylist(music_id, user_id))) { + const newRow: Recent_Played = this.recentPlayedRepository.create({ + music: { music_id }, + user: { user_id }, + played_at: new Date(), + }); + const addedRow: Recent_Played = + await this.recentPlayedRepository.save(newRow); + return addedRow.recent_played_id; + } + + const targetRow: Recent_Played = + await this.recentPlayedRepository.findOne({ + where: { music: { music_id }, user: { user_id } }, + }); + targetRow.played_at = new Date(); + const updatedRow: Recent_Played = + await this.recentPlayedRepository.save(targetRow); + return updatedRow.recent_played_id; + } catch (err) { + if (err instanceof CatchyException) throw err; + + this.logger.error(`user.service - updateRecentMusic : SERVICE_ERROR`); + throw new CatchyException( + 'SERVICE_ERROR', + HTTP_STATUS_CODE.SERVER_ERROR, + ERROR_CODE.QUERY_ERROR, + ); + } + } + + async getRecentPlaylistMusicCount(user_id: string): Promise { + try { + return await this.recentPlayedRepository.count({ + where: { user: { user_id } }, + }); + } catch { + this.logger.error( + `user.service - getRecentPlaylistMusicCount : QUERY_ERROR`, + ); + throw new CatchyException( + 'QUERY_ERROR', + HTTP_STATUS_CODE.SERVER_ERROR, + ERROR_CODE.QUERY_ERROR, + ); + } + } + + async getRecentPlaylistThumbnail(user_id: string): Promise { + try { + const recentMusic: Recent_Played = + await this.recentPlayedRepository.findOne({ + relations: { music: true, user: true }, + select: { music: { cover: true } }, + where: { user: { user_id } }, + order: { played_at: 'DESC' }, + }); + + return recentMusic.music.cover; + } catch { + this.logger.error( + `user.service - getRecentPlaylistThumbnail : QUERY_ERROR`, + ); + throw new CatchyException( + 'QUERY_ERROR', + HTTP_STATUS_CODE.SERVER_ERROR, + ERROR_CODE.QUERY_ERROR, + ); + } + } } diff --git a/server/test/constants/music.mockData.ts b/server/test/constants/music.mockData.ts index 1b7beb9..618766f 100644 --- a/server/test/constants/music.mockData.ts +++ b/server/test/constants/music.mockData.ts @@ -52,6 +52,7 @@ export const newMusicData: Music = { created_at: new Date(), } as User, music_playlist: [], + recent_played: [], hasId: () => true, save: async () => newMusicData, remove: async () => newMusicData,