Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/37 guest can see released #39

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
587 changes: 283 additions & 304 deletions dist/swagger.json

Large diffs are not rendered by default.

50 changes: 16 additions & 34 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,25 @@ model Animation {
rating Rating
primaryKeyword String
status Status
isReleased Boolean @default(false)
viewCount Int @default(0)
reviewCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?

seasonYear Int @default(dbgenerated("DATE_PART('year', now())"))
seasonQuarter Int @default(dbgenerated("CEIL(DATE_PART('month', now()) / 4)"))
seriesGroup String? /// ํŠน์ •์‹œ๋ฆฌ์ฆˆ ์ด๋ฆ„. ๊ฐ€์žฅ ๋Œ€ํฌ์ ์ธ ์ด๋ฆ„. [์‚ฌ์ด๋ฒ„ํฌ๋ฎฌ๋Ÿฌ11, zero, ์‹ ....] -> ์‚ฌ์ด๋ฒ„ํฌ๋ฎฌ๋Ÿฌ | [์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ Q, ํŒŒ, ์˜ค๋ฆฌ์ง€๋„...] -> ์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ

isReleased Boolean @default(false)
viewCount Int @default(0)
reviewCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
deletedAt DateTime?

studios AnimationStudio[]
genres AnimationGenre[]
voiceActors AnimationVoiceActor[]
originalWorkers AnimationOriginalWorker[]
keywords Keyword[]
seasons Season[]
bookmarks Bookmark[]

bookmarks Bookmark[]
}

model AnimationGenre {
Expand Down Expand Up @@ -121,9 +126,9 @@ model AnimationOriginalWorker {
}

model Genre {
id Int @id @default(autoincrement())
type GenreType @unique
createdAt DateTime @default(now())
id Int @id @default(autoincrement())
name String @unique
createdAt DateTime @default(now())

animations AnimationGenre[]
}
Expand Down Expand Up @@ -159,15 +164,6 @@ model Keyword {
animation Animation @relation(fields: [animationId], references: [id])
}

model Season {
id Int @id @default(autoincrement())
animationId Int
year Int @default(0)
quarter Int @default(0)
createdAt DateTime @default(now())
animation Animation @relation(fields: [animationId], references: [id], onDelete: Cascade)
}

model Review {
id Int @id @default(autoincrement())
memberId Int
Expand Down Expand Up @@ -298,20 +294,6 @@ enum Status {
UNKNOWN
}

enum GenreType {
FANTASY
SF
ROMANCE
ACTION
ADVANTURE
ANOTHER_WORLD
FAMILY
GAG
TOUCHING
CRIME
DRAMA
}

enum ReviewType {
SHORT
LONG
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { PrismaModule } from './global/database/prisma/prisma.module';
import { HttpExceptionFilter } from './global/common/filter/http-exception.filter';
import { PrismaExceptionFilter } from './global/common/filter/prisma-exception.filter';
import { BookmarkModule } from './domain/bookmark/bookmark.module';
import { GenreModule } from './domain/genre/genre.module';

@Module({
imports: [
Expand All @@ -32,6 +33,7 @@ import { BookmarkModule } from './domain/bookmark/bookmark.module';
MemberModule,
AnimationModule,
StudioModule,
GenreModule,
ReviewsModule,
BookmarkModule,
],
Expand Down
11 changes: 7 additions & 4 deletions src/domain/animation/admin.animation.controller.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { Controller, UseGuards } from '@nestjs/common';
import { Controller, HttpCode, UseGuards } from '@nestjs/common';
import { AnimationService } from './animation.service';
import { TypedBody, TypedParam, TypedRoute } from '@nestia/core';
import { Animation, Role } from '@prisma/client';
import { AnimationReqDto, AnimationUpdateDto } from './dto/animation.req.dto';
import { AnimationItemResDto } from './dto/animation.res.dto';
import { Roles } from '../../global/common/decoratror/roles.decorator';
import { RolesGuard } from '../../global/auth/guard/roles.guard';
import { ApiNoContentResponse } from '@nestjs/swagger';

@Controller('/animation')
export class AdminAnimationController {
constructor(private readonly service: AnimationService) {}

/**
* @tag admin/animation
* @enum season.quarter: [1, 2, 3, 4]
* @enum seasonQuarter: [1, 2, 3, 4]
* @seriesGroup ์‹œ๋ฆฌ์ฆˆ์ธ ๊ฒฝ์šฐ ๋Œ€ํ‘œ์ ์ธ ์ด๋ฆ„. ex) [์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ ์„œ, ํŒŒ, Q] -> ์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ
*/
@TypedRoute.Post('/')
// @UseGuards(RolesGuard)
Expand All @@ -33,17 +35,18 @@ export class AdminAnimationController {
async update(
@TypedParam('id') id: number,
@TypedBody() body: AnimationReqDto,
): Promise<Animation> {
): Promise<AnimationItemResDto> {
return this.service.updateById(id, body);
}

/**
* @tag admin/animation
*/
@TypedRoute.Delete('/:id')
@HttpCode(204)
// @UseGuards(RolesGuard)
// @Roles(Role.ADMIN)
async destroy(@TypedParam('id') id: number): Promise<Animation> {
async destroy(@TypedParam('id') id: number): Promise<void> {
return this.service.destroyById(id);
}
}
4 changes: 0 additions & 4 deletions src/domain/animation/animation.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export class AnimationController {
*/
@TypedRoute.Get('/')
@ApiOperation({ summary: 'animation list' })
@UseGuards(RolesGuard)
@Roles(Role.MEMBER, Role.ADMIN)
async getList(
@User() user: MemberProfile,
@TypedQuery() query: AnimationListDto,
Expand All @@ -32,8 +30,6 @@ export class AnimationController {
* @tag animation
*/
@TypedRoute.Get('/:id')
@UseGuards(RolesGuard)
@Roles(Role.MEMBER, Role.ADMIN)
async show(
@User() user: MemberProfile,
@TypedParam('id') id: number,
Expand Down
41 changes: 15 additions & 26 deletions src/domain/animation/animation.repository.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../global/database/prisma/prisma.service';
import { AnimationListDto } from './dto/animation.req.dto';
import { AnimationReqDto } from './dto/animation.req.dto';
Expand Down Expand Up @@ -32,7 +32,6 @@ export class AnimationRepository {
},
},
// TODO: keywords
seasons: true,
};
}

Expand All @@ -42,7 +41,6 @@ export class AnimationRepository {
genres,
voiceActors,
originalWorkers,
seasons,
...animationBody
} = body;

Expand All @@ -65,8 +63,8 @@ export class AnimationRepository {
create: genres.map((g) => ({
genre: {
connectOrCreate: {
where: { type: g },
create: { type: g },
where: { name: g },
create: { name: g },
},
},
})),
Expand All @@ -93,13 +91,6 @@ export class AnimationRepository {
},
})),
},
seasons: {
deleteMany: id ? { animationId: id } : undefined,
create: seasons.map((s) => ({
year: s.year,
quarter: s.quarter,
})),
},
// TODO: keywords
};
}
Expand All @@ -108,6 +99,7 @@ export class AnimationRepository {
const search = {
OR: [
{ name: { contains: params.search ?? '' } },
{ seriesGroup: { contains: params.search ?? '' } },
{ plot: { contains: params.search ?? '' } },
{ primaryKeyword: { contains: params.search ?? '' } },
],
Expand All @@ -118,6 +110,7 @@ export class AnimationRepository {
return this.prisma.animation.findMany({
skip: params.lastId ? 1 : 0,
take: params.pageSize ?? 20,
cursor: params.lastId ? { id: params.lastId } : undefined,
orderBy: {
[params.sortBy ?? 'createdAt']: params.sortOrder ?? Sort.DESC,
},
Expand All @@ -127,15 +120,13 @@ export class AnimationRepository {
}

async getAnimationById(role: Role, id: number) {
const animation = await this.prisma.animation.findFirst({
where: { id },
return this.prisma.animation.findFirstOrThrow({
where: {
id,
isReleased: role === Role.ADMIN ? {} : true,
},
include: this.makeCommonIncludeQuery(),
});

if (role !== Role.ADMIN && !animation?.isReleased)
throw new UnauthorizedException('NotReleased');

return animation;
}

async storeAnimation(body: AnimationReqDto) {
Expand All @@ -146,16 +137,14 @@ export class AnimationRepository {
}

async updateAnimation(id: number, body: AnimationReqDto) {
return this.prisma.$transaction(async (tx) => {
return tx.animation.update({
where: { id },
data: this.makeCommonBodyQuery(body, id),
include: this.makeCommonIncludeQuery(),
});
return this.prisma.animation.update({
where: { id },
data: this.makeCommonBodyQuery(body, id),
include: this.makeCommonIncludeQuery(),
});
}

async destroyById(id: number) {
return this.prisma.animation.delete({ where: { id } });
await this.prisma.animation.delete({ where: { id } });
}
}
25 changes: 12 additions & 13 deletions src/domain/animation/animation.service.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import { AnimationRepository } from './animation.repository';
import {
Animation,
Genre,
MemberProfile,
OriginalWorker,
Season,
Studio,
VoiceActor,
} from '@prisma/client';
import { AnimationListDto } from './dto/animation.req.dto';
import { AnimationReqDto, AnimationUpdateDto } from './dto/animation.req.dto';
import { AnimationReqDto } from './dto/animation.req.dto';
import { AnimationItemResDto } from './dto/animation.res.dto';

@Injectable()
Expand All @@ -22,35 +21,35 @@ export class AnimationService {
query: AnimationListDto,
): Promise<AnimationItemResDto[]> {
const items = await this.repository.getAnimations(user.role, query);
return this.flattenStudios(items);
return this.flattenRelations(items);
}

async getOneById(user: MemberProfile, id: number) {
const item = await this.repository.getAnimationById(user.role, id);

if (!item) throw new NotFoundException();

return this.flattenStudios([item])[0];
return this.flattenRelations([item])[0];
}

async store(body: AnimationReqDto) {
const item = await this.repository.storeAnimation(body);
return this.flattenStudios([item])[0];
return this.flattenRelations([item])[0];
}

async updateById(id: number, body: AnimationReqDto): Promise<Animation> {
async updateById(
id: number,
body: AnimationReqDto,
): Promise<AnimationItemResDto> {
const item = await this.repository.updateAnimation(id, body);
return this.flattenStudios([item])[0];
return this.flattenRelations([item])[0];
}

async destroyById(id: number): Promise<Animation> {
async destroyById(id: number): Promise<void> {
return await this.repository.destroyById(Number(id));
}

private flattenStudios(
private flattenRelations(
items: (Animation & {
studios: { studio: Studio }[];
seasons: Season[];
genres: { genre: Genre }[];
voiceActors: { voiceActor: VoiceActor }[];
originalWorkers: { originalWorker: OriginalWorker }[];
Expand Down
27 changes: 19 additions & 8 deletions src/domain/animation/dto/animation.req.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BroadcastType, GenreType, Rating, Status } from '@prisma/client';
import { BroadcastType, Rating, Status } from '@prisma/client';

export interface AnimationListDto {
/**
Expand Down Expand Up @@ -40,16 +40,10 @@ export interface AnimationRelationDto {
* */
studioNames: string[];

/**
* @default ๊ฐ€์ด๋‚™์Šค
* */
seasons: { year: number; quarter: number }[];

/**
* @default FANTASY
* @enum GenreType
* */
genres: GenreType[];
genres: string[];

/**
* @default ํƒ€๋„ค๋‹ค ๋ฆฌ์‚ฌ
Expand Down Expand Up @@ -101,6 +95,23 @@ export interface AnimationBaseDto {
* */
status: Status;

/**
* @default 2023
* */
seasonYear: number;

/**
* @default 1
* @enum [1, 2, 3, 4]
* */
seasonQuarter: number;

/**
* @default ์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ
* @description ์‹œ๋ฆฌ์ฆˆ์ธ ๊ฒฝ์šฐ ๋Œ€ํ‘œ์ ์ธ ์ด๋ฆ„. ex) [์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ ์„œ, ํŒŒ, Q] -> ์—๋ฐ˜๊ฒŒ๋ฆฌ์˜จ
* */
seriesGroup: string | null;

/**
* @default true
* */
Expand Down
Loading