Skip to content

Commit

Permalink
feat(laws): law 상세 조회 시 저장(북마크) 여부 데이터 전송
Browse files Browse the repository at this point in the history
  • Loading branch information
IsthisLee committed Aug 18, 2023
1 parent f74a9f0 commit dd81d14
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 7 deletions.
18 changes: 18 additions & 0 deletions src/apis/auth/security/guards/only-get-access-token-value.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Observable } from 'rxjs';
import { ExecutionContext, Injectable, CanActivate } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class OnlyGetAccessTokenValueGuard extends AuthGuard('jwt-access') implements CanActivate {
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
return super.canActivate(context);
}

// Override the handleRequest method to not throw an error
handleRequest(err, user, info) {
if (err || info || !user) {
return {};
}
return user;
}
}
41 changes: 41 additions & 0 deletions src/apis/laws/dtos/prec.response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ApiProperty } from '@nestjs/swagger';
import { PrecDetailData } from 'src/common/types';
import * as v from 'class-validator';

export class ResponsePrecDto implements PrecDetailData {
@ApiProperty()
@v.IsNumber()
판례정보일련번호: number;

@ApiProperty()
@v.IsString()
사건번호: string;

@ApiProperty()
@v.IsString()
사건종류명: string;

@ApiProperty()
@v.IsString()
판결유형: string;

@ApiProperty()
@v.IsString()
선고: string;

@ApiProperty()
@v.IsString()
법원명: string;

@ApiProperty()
@v.IsString()
선고일자: string;

@ApiProperty()
@v.IsString()
사건명: string;

@ApiProperty()
@v.IsString()
판례내용: string;
}
141 changes: 141 additions & 0 deletions src/apis/laws/dtos/statute.response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import {
StatuteDetailData,
StatuteArticle,
StatuteAddendum,
StatuteParagraph,
StatuteSubparagraph,
Statuteitem,
} from 'src/common/types';
import { ApiExtraModels, ApiProperty, ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger';
import * as v from 'class-validator';

export class StatuteItemDTO implements Statuteitem {
@ApiProperty()
@v.IsString()
목번호: string;

@ApiProperty()
@v.IsString()
목내용: string;
}

export class StatuteSubparagraphDTO implements StatuteSubparagraph {
@ApiProperty()
@v.IsString()
호번호: string;

@ApiProperty()
@v.IsString()
호내용: string;

@ApiPropertyOptional({ type: [StatuteItemDTO] })
@v.IsOptional()
?: StatuteItemDTO | StatuteItemDTO[];
}

export class StatuteParagraphDTO implements StatuteParagraph {
@ApiProperty()
항번호: string;

@ApiProperty()
항내용: string;

@ApiPropertyOptional({ type: [StatuteSubparagraphDTO] })
?: StatuteSubparagraphDTO | StatuteSubparagraphDTO[];
}

export class StatuteArticleDTO implements StatuteArticle {
@ApiProperty()
조문키: string;

@ApiProperty()
조문번호: number;

@ApiProperty()
조문여부: string;

@ApiPropertyOptional()
조문제목?: string;

@ApiProperty()
조문시행일자: number;

@ApiProperty()
조문내용: string;

@ApiPropertyOptional({ type: [StatuteParagraphDTO] })
?: StatuteParagraphDTO | StatuteParagraphDTO[];

@ApiPropertyOptional({ type: [String] })
조문참고자료?: string | string[];
}

export class StatuteAddendumDTO implements StatuteAddendum {
@ApiProperty()
부칙키: string;

@ApiProperty()
부칙공포일자: number;

@ApiProperty()
부칙공포번호: number;

@ApiProperty({ type: [String] })
부칙내용: string[];
}

@ApiExtraModels(StatuteAddendumDTO, StatuteArticleDTO)
export class ResponseStatuteDto implements StatuteDetailData {
@ApiProperty({
properties: {
법령ID: {
type: 'number',
},
법령명: {
type: 'string',
},
시행일자: {
type: 'number',
},
},
})
기본정보: {
법령ID: number;
법령명: string;
시행일자: number;
};

@ApiProperty({
oneOf: [
{
$ref: getSchemaPath(StatuteArticleDTO),
},
{
type: 'array',
items: {
$ref: getSchemaPath(StatuteArticleDTO),
},
},
],
})
조문: {
조문단위: StatuteArticleDTO | StatuteArticleDTO[];
};

@ApiProperty({
oneOf: [
{
$ref: getSchemaPath(StatuteAddendumDTO),
},
{
type: 'array',
items: {
$ref: getSchemaPath(StatuteAddendumDTO),
},
},
],
})
부칙: {
부칙단위: StatuteAddendumDTO | StatuteAddendumDTO[];
};
}
45 changes: 41 additions & 4 deletions src/apis/laws/laws.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
ApiCreatedResponse,
ApiBearerAuth,
ApiOkResponse,
getSchemaPath,
ApiExtraModels,
} from '@nestjs/swagger';
import { GetLawListDto } from './dtos/get-laws.dto';
import { RequestSummaryDto } from './dtos/request-summary.dto';
Expand All @@ -30,16 +32,20 @@ import {
StatuteDetailData,
PrecDetailData,
LawSummaryResponseData,
JwtPayloadInfo,
} from 'src/common/types';
import { Throttle } from '@nestjs/throttler';
import { OpenaiService } from 'src/shared/services/openai.service';
import { Stream } from 'openai/streaming';
import { ChatCompletionChunk } from 'openai/resources/chat';
import { JwtUserPayload } from 'src/common/decorators/jwt-user.decorator';
import { JwtPayloadInfo } from 'src/common/types';
import { AuthGuard } from '@nestjs/passport';
import { GetBookmarkLawListDto } from './dtos/get-bookmark-laws.dto';
import { Response } from 'express';
import { OnlyGetAccessTokenValueGuard } from '../auth/security/guards/only-get-access-token-value.guard';
import { LawBookmark } from '@prisma/client';
import { ResponsePrecDto } from './dtos/prec.response.dto';
import { ResponseStatuteDto } from './dtos/statute.response.dto';

@Controller({ path: 'laws' })
@ApiTags('Laws')
Expand Down Expand Up @@ -85,6 +91,8 @@ export class LawsController {
}

@Get(':type/:id')
@UseGuards(OnlyGetAccessTokenValueGuard)
@ApiBearerAuth('access-token')
@ApiOperation({ summary: '판례/법령 상세 조회' })
@ApiParam({
name: 'type',
Expand All @@ -96,12 +104,41 @@ export class LawsController {
type: 'number',
description: '판례 또는 법령의 ID(판례일련번호/법령ID)',
})
getLawDetail(
@ApiExtraModels(ResponsePrecDto, ResponseStatuteDto)
@ApiOkResponse({
description: 'Successfule response',
schema: {
properties: {
lawInfo: {
oneOf: [{ $ref: getSchemaPath(ResponsePrecDto) }, { $ref: getSchemaPath(ResponseStatuteDto) }],
},
isBookmarked: {
type: 'boolean',
},
},
},
})
async getLawDetail(
@JwtUserPayload() jwtUser: JwtPayloadInfo,
@Param('type', new ParseEnumPipe(SearchTabEnum))
type: SearchTabEnum,
@Param('id', new ParseIntPipe()) id: number,
): Promise<StatuteDetailData | PrecDetailData> {
return this.lawsService.getLawDetail(type, id.toString());
): Promise<{
lawInfo: StatuteDetailData | PrecDetailData;
isBookmarked: boolean;
}> {
const bookmarkedLawPromise: Promise<LawBookmark> = this.lawsService.getBookmarkedLawInfo(
jwtUser.userId,
id.toString(),
type,
);
const lawDetailPromise = this.lawsService.getLawDetail(type, id.toString());
const [bookmarkedLaw, lawDetail] = await Promise.all([bookmarkedLawPromise, lawDetailPromise]);

return {
lawInfo: lawDetail,
isBookmarked: !!bookmarkedLaw,
};
}

@Post(':type/:id/summary')
Expand Down
17 changes: 16 additions & 1 deletion src/apis/laws/laws.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { GetLawListDto } from './dtos/get-laws.dto';
import { OpenaiService } from 'src/shared/services/openai.service';
import { ChatCompletionMessage } from 'openai/resources/chat';
import { PrismaService } from 'src/common/prisma/prisma.service';
import { Prisma } from '@prisma/client';
import { Prisma, LawBookmark } from '@prisma/client';
import { GetBookmarkLawListDto } from './dtos/get-bookmark-laws.dto';

@Injectable()
Expand Down Expand Up @@ -108,6 +108,21 @@ export class LawsService {
};
}

async getBookmarkedLawInfo(userId: number, lawId: string, lawType: SearchTabEnum): Promise<LawBookmark> | null {
if (!userId || !lawId || !lawType) return null;

const bookmarkedLaw = await this.prismaService.lawBookmark.findFirst({
where: {
userId,
lawId,
lawType,
deletedAt: null,
},
});

return bookmarkedLaw;
}

async createLawAdditionalSummary(
type: SearchTabEnum,
id: string,
Expand Down
2 changes: 2 additions & 0 deletions src/common/types/auth.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Request } from 'express';

export interface JwtPayloadInfo {
userId: number;
iat?: number;
exp?: number;
}

export interface CreateUserInfo {
Expand Down
4 changes: 4 additions & 0 deletions src/common/types/law.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,8 @@ export {
StatuteDetailData,
StatuteArticle,
LawSummaryResponseData,
StatuteAddendum,
StatuteParagraph,
StatuteSubparagraph,
Statuteitem,
};
3 changes: 1 addition & 2 deletions src/shared/services/openai.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { BadRequestException, Injectable, MessageEvent } from '@nestjs/common';
import { BadRequestException, Injectable } from '@nestjs/common';
import { OpenAI } from 'openai';
import { Stream } from 'openai/streaming';
import { ChatCompletionChunk, ChatCompletionMessage, ChatCompletion } from 'openai/resources/chat';
import { ConfigService } from '@nestjs/config';
import { encoding_for_model } from '@dqbd/tiktoken';
import { TiktokenModel } from '@dqbd/tiktoken';
import { Response } from 'express';
import { Observable, Subscriber } from 'rxjs';

@Injectable()
export class OpenaiService {
Expand Down

0 comments on commit dd81d14

Please sign in to comment.