Skip to content

Commit

Permalink
Merge pull request #50 from modern-agile-team/feat/#49/section-partst…
Browse files Browse the repository at this point in the history
…atus-api

section/{id}/users/{id}/part-status  API 작성
  • Loading branch information
dg1418 authored Dec 23, 2024
2 parents 8b658ca + c6cc94a commit 340d301
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 8 deletions.
7 changes: 3 additions & 4 deletions src/part-progress/dto/create-part-progress.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ApiProperty } from '@nestjs/swagger';
import { PartStatus } from '../entities/part-progress.entity';
import { PartStatus, PartStatusValues } from '../entities/part-progress.entity';
import { IsEnum } from 'class-validator';
import { CategoryValues } from 'src/quizzes/entities/quizzes.entity';

export class CreatePartProgressDto {
@ApiProperty({
Expand All @@ -13,8 +12,8 @@ export class CreatePartProgressDto {
4. COMPLETED
`,
example: 'LOCKED',
enum: CategoryValues,
enum: PartStatusValues,
})
@IsEnum(CategoryValues, { message: 'bad status value' })
@IsEnum(PartStatusValues, { message: 'bad status value' })
readonly status: PartStatus;
}
3 changes: 1 addition & 2 deletions src/sections/dto/res-section.dto.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ApiProperty } from '@nestjs/swagger';
import { ResPartDto } from 'src/parts/dto/res-part.part.dto';
import { Part } from 'src/parts/entities/part.entity';

export class ResSectionDto {
@ApiProperty({ example: 1 })
Expand All @@ -10,7 +9,7 @@ export class ResSectionDto {
readonly name: string;

@ApiProperty({ type: [ResPartDto], example: [] })
readonly part?: Part[];
readonly part?: ResPartDto[];

constructor({ id, name, part }: ResSectionDto) {
this.id = id;
Expand Down
11 changes: 11 additions & 0 deletions src/sections/sections.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ export class SectionsController {
return new ResSectionDto(sectionWithParts);
}

@ApiSections.findOneWithStatus()
@Get(':id/users/:userId/part-status')
async findOneWithStatus(
@Param('userId', PositiveIntPipe) userId: number,
@Param('id', PositiveIntPipe) id: number,
) {
const sectionWithParts =
await this.sectionsService.findOneWithPartsAndStatus(userId, id);
return new ResSectionDto(sectionWithParts);
}

@ApiSections.create()
@Post()
@HttpCode(204)
Expand Down
19 changes: 18 additions & 1 deletion src/sections/sections.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateSectionDto } from './dto/create-section.dto';
import { Section } from './entities/section.entity';
import { ResSectionDto } from './dto/res-section.dto';

@Injectable()
export class SectionsRepository {
Expand All @@ -17,13 +18,29 @@ export class SectionsRepository {
});
}

async findSectionWithPartsById(id: number): Promise<Section> {
async findSectionWithPartsById(id: number): Promise<ResSectionDto> {
return this.prisma.section.findUnique({
where: { id },
include: { part: true },
});
}

async findSectionWithPartStatus(userId: number, id: number) {
return this.prisma.section.findUnique({
where: { id },
include: {
part: {
include: {
PartProgress: {
where: { userId },
select: { status: true },
},
},
},
},
});
}

async findOneSectionByName(name: string): Promise<Section> {
return this.prisma.section.findUnique({
where: { name },
Expand Down
28 changes: 27 additions & 1 deletion src/sections/sections.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CreateSectionDto } from './dto/create-section.dto';
import { SectionsRepository } from './sections.repository';
import { PartsRepository } from 'src/parts/parts.repository';
import { Section } from './entities/section.entity';
import { ResSectionDto } from './dto/res-section.dto';

@Injectable()
export class SectionsService {
Expand All @@ -29,7 +30,7 @@ export class SectionsService {
return section;
}

async findOneWithParts(id: number): Promise<Section> {
async findOneWithParts(id: number): Promise<ResSectionDto> {
const sectionWithParts =
await this.sectionsRepository.findSectionWithPartsById(id);

Expand All @@ -40,6 +41,31 @@ export class SectionsService {
return sectionWithParts;
}

async findOneWithPartsAndStatus(
userId: number,
id: number,
): Promise<ResSectionDto> {
const { part, ...section } =
await this.sectionsRepository.findSectionWithPartStatus(userId, id);

if (!section) {
throw new NotFoundException();
}

// ropository에서 받은 값 중 part를 정리하는 코드
const newParts = part.map(
({ PartProgress, createdAt, updatedAt, ...orders }) => ({
...orders,
status: PartProgress[0]?.status,
}),
);

return {
...section,
part: newParts,
};
}

async create(body: CreateSectionDto): Promise<Section> {
const { name } = body;
const section = await this.sectionsRepository.findOneSectionByName(name);
Expand Down
45 changes: 45 additions & 0 deletions src/sections/sections.swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,51 @@ export const ApiSections = {
}),
);
},
findOneWithStatus: () => {
return applyDecorators(
ApiOperation({
description: `
section id와 유저 id로 조회
1. 단일 section 정보
2. 관련 part들의 정보
3. part내부에 진행도와 관련된 status항목을 추가함
4. status값이 없으면 유저가 그 파트에 대한 진행도 사항이 undefind인 오류 상황임`,
}),
ApiResponse({
status: 200,
description:
'특정 section의 id param값을 통해 id, nmae 값을 조회 또한 id를 참조하는 part객체들을 배열로 보냄',
content: {
JSON: {
example: {
id: 1,
name: '변수',
part: [
{
id: 1,
sectionId: 1,
name: '변수명',
status: 'LOCKED',
},
{
id: 2,
sectionId: 1,
name: 'const',
status: 'LOCKED',
},
{
id: 3,
sectionId: 1,
name: 'let',
status: 'LOCKED',
},
],
},
},
},
}),
);
},
update: () => {
return applyDecorators(
ApiOperation({
Expand Down

0 comments on commit 340d301

Please sign in to comment.