Skip to content
Merged
331 changes: 307 additions & 24 deletions apps/server/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,43 @@
]
}
},
"/session/register-oneapp": {
"post": {
"summary": "AuthController.registerOneApp",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"type": "{ isRegistered: boolean; mes: string; uid?: undefined; }"
},
{
"type": "{ isRegistered: boolean; mes: string; uid: string | null; }"
},
{
"type": "{ isRegistered: boolean; uid: string | null; mes?: undefined; }"
}
]
}
}
}
}
},
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IUser.SsoInfoOneApp"
}
}
}
}
}
},
"/session/refresh": {
"post": {
"summary": "AuthController.refreshToken",
Expand Down Expand Up @@ -251,7 +288,7 @@
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/{ subject_department: { name: string; id: number; code: string; num_id: string; name_en: string | null; visible: boolean; }; subject_classtime: { id: number; type: string; day: number; begin: Date; end: Date; building_id: string | null; building_full_name: string | null; building_full_name_en: string | null; room_name: string | null; unit_time: number | null; lecture_id: number | null; }[]; subject_examtime: { id: number; day: number; begin: Date; end: Date; lecture_id: number; }[]; subject_lecture_professors: ({ professor: { id: number; grade_sum: number; load_sum: number; speech_sum: number; grade: number; load: number; speech: number; review_total_weight: number; professor_id: number; professor_name: string; professor_name_en: string | null; major: string; }; } & { id: number; lecture_id: number; professor_id: number; })[]; } & { id: number; code: string; old_code: string; new_code: string; year: number; semester: number; department_id: number; class_no: string; title: string; title_en: string; type: string; type_en: string; audience: number; credit: number; num_classes: number; num_labs: number; credit_au: number; limit: number; num_people: number | null; is_english: boolean; deleted: boolean; course_id: number; grade_sum: number; load_sum: number; speech_sum: number; grade: number; load: number; speech: number; review_total_weight: number; class_title: string | null; class_title_en: string | null; common_title: string | null; common_title_en: string | null; title_no_space: string; title_en_no_space: string; level: string | null; }"
"$ref": "#/components/schemas/{ subject_department: { id: number; name: string; code: string; num_id: string; name_en: string | null; visible: boolean; }; subject_classtime: { id: number; type: string; day: number; begin: Date; end: Date; building_id: string | null; building_full_name: string | null; building_full_name_en: string | null; room_name: string | null; unit_time: number | null; lecture_id: number | null; }[]; subject_examtime: { id: number; day: number; begin: Date; end: Date; lecture_id: number; }[]; subject_lecture_professors: ({ professor: { id: number; grade_sum: number; load_sum: number; speech_sum: number; grade: number; load: number; speech: number; review_total_weight: number; professor_id: number; professor_name: string; professor_name_en: string | null; major: string; }; } & { id: number; lecture_id: number; professor_id: number; })[]; } & { id: number; department_id: number; code: string; old_code: string; new_code: string; year: number; semester: number; class_no: string; title: string; title_en: string; type: string; type_en: string; audience: number; credit: number; num_classes: number; num_labs: number; credit_au: number; limit: number; num_people: number | null; is_english: boolean; deleted: boolean; course_id: number; grade_sum: number; load_sum: number; speech_sum: number; grade: number; load: number; speech: number; review_total_weight: number; class_title: string | null; class_title_en: string | null; common_title: string | null; common_title_en: string | null; title_no_space: string; title_en_no_space: string; level: string | null; }"
}
}
}
Expand Down Expand Up @@ -4866,6 +4903,242 @@
"type": "object",
"required": ["year", "semester", "keyword"]
},
"ILectureV2.Classtime": {
"type": "object",
"properties": {
"day": {
"type": "number"
},
"begin": {
"type": "number"
},
"end": {
"type": "number"
},
"buildingCode": {
"type": "string"
},
"buildingName": {
"type": "string"
},
"roomName": {
"type": "string"
}
},
"required": ["day", "begin", "end", "buildingCode", "buildingName", "roomName"],
"additionalProperties": false
},
"ILectureV2.ExamTime": {
"type": "object",
"properties": {
"day": {
"type": "number"
},
"str": {
"type": "string"
},
"begin": {
"type": "number"
},
"end": {
"type": "number"
}
},
"required": ["day", "str", "begin", "end"],
"additionalProperties": false
},
"ILectureV2.Basic": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"courseId": {
"type": "number"
},
"classNo": {
"type": "string"
},
"name": {
"type": "string"
},
"code": {
"type": "string"
},
"department": {
"$ref": "#/components/schemas/IDepartmentV2.Basic"
},
"type": {
"type": "string"
},
"limitPeople": {
"type": "number"
},
"numPeople": {
"type": "number"
},
"credit": {
"type": "number"
},
"creditAU": {
"type": "number"
},
"averageGrade": {
"type": "number"
},
"averageLoad": {
"type": "number"
},
"averageSpeech": {
"type": "number"
},
"isEnglish": {
"type": "boolean"
},
"professors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IProfessorV2.Basic"
}
},
"classes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ILectureV2.Classtime"
}
},
"examTime": {
"anyOf": [
{
"$ref": "#/components/schemas/ILectureV2.ExamTime"
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"courseId",
"classNo",
"name",
"code",
"department",
"type",
"limitPeople",
"numPeople",
"credit",
"creditAU",
"averageGrade",
"averageLoad",
"averageSpeech",
"isEnglish",
"professors",
"classes",
"examTime"
],
"additionalProperties": false
},
"ILectureV2.courseWrapped": {
"type": "object",
"properties": {
"courses": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"code": {
"type": "string"
},
"type": {
"type": "string"
},
"lectures": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ILectureV2.Basic"
}
},
"completed": {
"type": "boolean"
}
},
"required": ["name", "code", "type", "lectures", "completed"],
"additionalProperties": false
}
}
},
"required": ["courses"],
"additionalProperties": false
},
"ILectureV2.getQuery": {
"properties": {
"keyword": {
"type": "string"
},
"type": {
"items": {
"type": "string",
"enum": ["ALL", "BR", "BE", "MR", "ME", "MGC", "HSE", "GR", "EG", "OE", "ETC"]
},
"type": "array"
},
"department": {
"items": {
"type": "integer"
},
"type": "array"
},
"level": {
"items": {
"type": "string",
"enum": ["ALL", "100", "200", "300", "400", "500", "600", "700", "800", "900"]
},
"type": "array"
},
"year": {
"maximum": 2100,
"type": "integer",
"minimum": 2000,
"not": {
"type": "null"
}
},
"semester": {
"maximum": 4,
"type": "integer",
"minimum": 1,
"not": {
"type": "null"
}
},
"day": {
"type": "number"
},
"begin": {
"type": "number"
},
"end": {
"type": "number"
},
"order": {
"type": "string",
"enum": ["code", "popular", "studentCount"]
},
"limit": {
"type": "number"
},
"offset": {
"type": "number"
}
},
"type": "object",
"required": ["year", "semester"]
},
"INotice.Basic": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -6908,6 +7181,16 @@
"type": "object",
"required": ["arrange_order"]
},
"IUser.SsoInfoOneApp": {
"type": "object",
"properties": {
"sso_info": {
"type": "string"
}
},
"required": ["sso_info"],
"additionalProperties": false
},
"IUser.TakenCoursesQueryDto": {
"properties": {
"order": {
Expand Down Expand Up @@ -7116,6 +7399,29 @@
],
"additionalProperties": false
},
"IUser.TokenDto": {
"properties": {
"token": {
"minLength": 1,
"type": "string"
}
},
"type": "object",
"required": ["token"]
},
"IUser.TokenResponse": {
"type": "object",
"properties": {
"accessToken": {
"type": "string"
},
"refreshToken": {
"type": "string"
}
},
"required": ["accessToken", "refreshToken"],
"additionalProperties": false
},
"IUser.SimpleProfile": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -7176,29 +7482,6 @@
],
"additionalProperties": false
},
"IUser.TokenDto": {
"properties": {
"token": {
"minLength": 1,
"type": "string"
}
},
"type": "object",
"required": ["token"]
},
"IUser.TokenResponse": {
"type": "object",
"properties": {
"accessToken": {
"type": "string"
},
"refreshToken": {
"type": "string"
}
},
"required": ["accessToken", "refreshToken"],
"additionalProperties": false
},
"IWishlist.WithLectures": {
"type": "object",
"properties": {
Expand Down
18 changes: 18 additions & 0 deletions apps/server/src/common/decorators/get-language.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createParamDecorator, ExecutionContext } from '@nestjs/common'

export const GetLanguage = createParamDecorator((_data, ctx: ExecutionContext): string => {
const req = ctx.switchToHttp().getRequest()
const acceptLanguageHeader = req.headers['accept-language']

if (typeof acceptLanguageHeader !== 'string' || !acceptLanguageHeader) {
return 'kr'
}

const languages = acceptLanguageHeader.split(',').map((langPart) => langPart.trim().split(';')[0].toLowerCase())

if (languages.some((lang) => lang.startsWith('ko'))) {
return 'kr'
}

return 'en'
})
Copy link

Choose a reason for hiding this comment

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

코드 검토 댓글

이 코드는 @nestjs/common에서 네스트JS 용으로 작성된 파라미터 데코레이터 GetLanguage를 정의하고 있습니다. 아래의 몇 가지 문제점과 개선 사항을 제시합니다:

  1. 기본 언어 설정: 현재 코드는 accept-language 헤더가 비어있거나 문자열이 아닐 경우 기본 언어로 'kr'을 반환합니다. 하지만, 다른 언어 선택이 필요할 수 있습니다. 이 기능에 대한 설정을 외부에서 주입할 수 있도록 고려해보세요.

  2. 헤더 검사: req.headers['accept-language']에서 직접 헤더를 가져오고 있지만, 'accept-language' 헤더가 아예 존재하지 않는 경우도 발생할 수 있습니다. 따라서 아래와 같은 변형을 고려해보세요:

    const acceptLanguageHeader = req.headers['accept-language'] || '';  

    이렇게 하면 기존 코드를 간단히 유지하면서 더 안전한 확인을 할 수 있습니다.

  3. 확장성 문제: 현재 코드는 한국어(kr)와 영어(en)만 지원하고 있습니다. 만약 다른 언어를 추가하게 된다면, this may lead to a complex condition structure or significant changes in the code. 이를 해결하기 위해 language mapping 시스템을 도입해보세요.

  4. 타입 안전성: TypeScript의 강점을 활용하여 acceptLanguageHeader의 타입을 더 명확히 해주는 것도 좋습니다. string | undefined와 같은 강력한 타입을 고려해보세요.

  5. 코드 문서화: 기능을 명시적으로 설명하는 주석을 추가하여 코드 유지보수성을 높여야 합니다. 특히 팀원이 이해하는 데 도움을 줄 수 있습니다.

이러한 점들을 개선하면 코드의 가독성과 유지보수성을 높일 수 있을 것입니다.

Copy link

Choose a reason for hiding this comment

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

코드 검토 댓글

이 코드는 @nestjs/common에서 네스트JS 용으로 작성된 파라미터 데코레이터 GetLanguage를 정의하고 있습니다. 아래의 몇 가지 문제점과 개선 사항을 제시합니다:

  1. 기본 언어 설정: 현재 코드는 accept-language 헤더가 비어있거나 문자열이 아닐 경우 기본 언어로 'kr'을 반환합니다. 하지만, 다른 언어 선택이 필요할 수 있습니다. 이 기능에 대한 설정을 외부에서 주입할 수 있도록 고려해보세요.

  2. 헤더 검사: req.headers['accept-language']에서 직접 헤더를 가져오고 있지만, 'accept-language' 헤더가 아예 존재하지 않는 경우도 발생할 수 있습니다. 따라서 아래와 같은 변형을 고려해보세요:

    const acceptLanguageHeader = req.headers['accept-language'] || '';  

    이렇게 하면 기존 코드를 간단히 유지하면서 더 안전한 확인을 할 수 있습니다.

  3. 확장성 문제: 현재 코드는 한국어(kr)와 영어(en)만 지원하고 있습니다. 만약 다른 언어를 추가하게 된다면, this may lead to a complex condition structure or significant changes in the code. 이를 해결하기 위해 language mapping 시스템을 도입해보세요.

  4. 타입 안전성: TypeScript의 강점을 활용하여 acceptLanguageHeader의 타입을 더 명확히 해주는 것도 좋습니다. string | undefined와 같은 강력한 타입을 고려해보세요.

  5. 코드 문서화: 기능을 명시적으로 설명하는 주석을 추가하여 코드 유지보수성을 높여야 합니다. 특히 팀원이 이해하는 데 도움을 줄 수 있습니다.

이러한 점들을 개선하면 코드의 가독성과 유지보수성을 높일 수 있을 것입니다.

Loading