Skip to content

Commit e4015b1

Browse files
Merge pull request #307 from sparcs-kaist/sandbox-251102
Sandbox 251102 (killerwhale)
2 parents 4abc92d + 8633b29 commit e4015b1

22 files changed

+2017
-7
lines changed

apps/server/docs/swagger.json

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5073,6 +5073,242 @@
50735073
"type": "object",
50745074
"required": ["year", "semester", "keyword"]
50755075
},
5076+
"ILectureV2.Classtime": {
5077+
"type": "object",
5078+
"properties": {
5079+
"day": {
5080+
"type": "number"
5081+
},
5082+
"begin": {
5083+
"type": "number"
5084+
},
5085+
"end": {
5086+
"type": "number"
5087+
},
5088+
"buildingCode": {
5089+
"type": "string"
5090+
},
5091+
"buildingName": {
5092+
"type": "string"
5093+
},
5094+
"roomName": {
5095+
"type": "string"
5096+
}
5097+
},
5098+
"required": ["day", "begin", "end", "buildingCode", "buildingName", "roomName"],
5099+
"additionalProperties": false
5100+
},
5101+
"ILectureV2.ExamTime": {
5102+
"type": "object",
5103+
"properties": {
5104+
"day": {
5105+
"type": "number"
5106+
},
5107+
"str": {
5108+
"type": "string"
5109+
},
5110+
"begin": {
5111+
"type": "number"
5112+
},
5113+
"end": {
5114+
"type": "number"
5115+
}
5116+
},
5117+
"required": ["day", "str", "begin", "end"],
5118+
"additionalProperties": false
5119+
},
5120+
"ILectureV2.Basic": {
5121+
"type": "object",
5122+
"properties": {
5123+
"id": {
5124+
"type": "number"
5125+
},
5126+
"courseId": {
5127+
"type": "number"
5128+
},
5129+
"classNo": {
5130+
"type": "string"
5131+
},
5132+
"name": {
5133+
"type": "string"
5134+
},
5135+
"code": {
5136+
"type": "string"
5137+
},
5138+
"department": {
5139+
"$ref": "#/components/schemas/IDepartmentV2.Basic"
5140+
},
5141+
"type": {
5142+
"type": "string"
5143+
},
5144+
"limitPeople": {
5145+
"type": "number"
5146+
},
5147+
"numPeople": {
5148+
"type": "number"
5149+
},
5150+
"credit": {
5151+
"type": "number"
5152+
},
5153+
"creditAU": {
5154+
"type": "number"
5155+
},
5156+
"averageGrade": {
5157+
"type": "number"
5158+
},
5159+
"averageLoad": {
5160+
"type": "number"
5161+
},
5162+
"averageSpeech": {
5163+
"type": "number"
5164+
},
5165+
"isEnglish": {
5166+
"type": "boolean"
5167+
},
5168+
"professors": {
5169+
"type": "array",
5170+
"items": {
5171+
"$ref": "#/components/schemas/IProfessorV2.Basic"
5172+
}
5173+
},
5174+
"classes": {
5175+
"type": "array",
5176+
"items": {
5177+
"$ref": "#/components/schemas/ILectureV2.Classtime"
5178+
}
5179+
},
5180+
"examTime": {
5181+
"anyOf": [
5182+
{
5183+
"$ref": "#/components/schemas/ILectureV2.ExamTime"
5184+
},
5185+
{
5186+
"type": "null"
5187+
}
5188+
]
5189+
}
5190+
},
5191+
"required": [
5192+
"id",
5193+
"courseId",
5194+
"classNo",
5195+
"name",
5196+
"code",
5197+
"department",
5198+
"type",
5199+
"limitPeople",
5200+
"numPeople",
5201+
"credit",
5202+
"creditAU",
5203+
"averageGrade",
5204+
"averageLoad",
5205+
"averageSpeech",
5206+
"isEnglish",
5207+
"professors",
5208+
"classes",
5209+
"examTime"
5210+
],
5211+
"additionalProperties": false
5212+
},
5213+
"ILectureV2.courseWrapped": {
5214+
"type": "object",
5215+
"properties": {
5216+
"courses": {
5217+
"type": "array",
5218+
"items": {
5219+
"type": "object",
5220+
"properties": {
5221+
"name": {
5222+
"type": "string"
5223+
},
5224+
"code": {
5225+
"type": "string"
5226+
},
5227+
"type": {
5228+
"type": "string"
5229+
},
5230+
"lectures": {
5231+
"type": "array",
5232+
"items": {
5233+
"$ref": "#/components/schemas/ILectureV2.Basic"
5234+
}
5235+
},
5236+
"completed": {
5237+
"type": "boolean"
5238+
}
5239+
},
5240+
"required": ["name", "code", "type", "lectures", "completed"],
5241+
"additionalProperties": false
5242+
}
5243+
}
5244+
},
5245+
"required": ["courses"],
5246+
"additionalProperties": false
5247+
},
5248+
"ILectureV2.getQuery": {
5249+
"properties": {
5250+
"keyword": {
5251+
"type": "string"
5252+
},
5253+
"type": {
5254+
"items": {
5255+
"type": "string",
5256+
"enum": ["ALL", "BR", "BE", "MR", "ME", "MGC", "HSE", "GR", "EG", "OE", "ETC"]
5257+
},
5258+
"type": "array"
5259+
},
5260+
"department": {
5261+
"items": {
5262+
"type": "integer"
5263+
},
5264+
"type": "array"
5265+
},
5266+
"level": {
5267+
"items": {
5268+
"type": "string",
5269+
"enum": ["ALL", "100", "200", "300", "400", "500", "600", "700", "800", "900"]
5270+
},
5271+
"type": "array"
5272+
},
5273+
"year": {
5274+
"maximum": 2100,
5275+
"type": "integer",
5276+
"minimum": 2000,
5277+
"not": {
5278+
"type": "null"
5279+
}
5280+
},
5281+
"semester": {
5282+
"maximum": 4,
5283+
"type": "integer",
5284+
"minimum": 1,
5285+
"not": {
5286+
"type": "null"
5287+
}
5288+
},
5289+
"day": {
5290+
"type": "number"
5291+
},
5292+
"begin": {
5293+
"type": "number"
5294+
},
5295+
"end": {
5296+
"type": "number"
5297+
},
5298+
"order": {
5299+
"type": "string",
5300+
"enum": ["code", "popular", "studentCount"]
5301+
},
5302+
"limit": {
5303+
"type": "number"
5304+
},
5305+
"offset": {
5306+
"type": "number"
5307+
}
5308+
},
5309+
"type": "object",
5310+
"required": ["year", "semester"]
5311+
},
50765312
"INotice.Basic": {
50775313
"type": "object",
50785314
"properties": {
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { ApiPropertyOptional } from '@nestjs/swagger'
2+
import { IProfessorV2 } from '@otl/server-nest/common/interfaces/IProfessorV2'
3+
import { Transform } from 'class-transformer'
4+
import {
5+
IsArray, IsIn, IsInt, IsNumber, IsOptional, IsString,
6+
} from 'class-validator'
7+
8+
import { IDepartmentV2 } from './IDepartmentV2'
9+
10+
export type CourseOrderQuery = 'code' | 'popular' | 'studentCount'
11+
export type level = 'ALL' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'
12+
export type CourseType = 'ALL' | 'BR' | 'BE' | 'MR' | 'ME' | 'MGC' | 'HSE' | 'GR' | 'EG' | 'OE' | 'ETC'
13+
14+
export namespace ICourseV2 {
15+
export interface Basic {
16+
id: number
17+
name: string // kr : title / en : title_en
18+
code: string // new_code
19+
type: string // kr, en 구분
20+
department: IDepartmentV2.Basic
21+
professors: IProfessorV2.Basic[]
22+
summary: string
23+
open: boolean // 현재학기 개설 여부
24+
completed: boolean // 수강 여부 (authorized 안되어 있으면 false)
25+
}
26+
27+
export interface Detail {
28+
id: number
29+
name: string
30+
code: string
31+
type: string
32+
department: IDepartmentV2.Basic
33+
// 개설 이력
34+
history: {
35+
year: number
36+
semester: number
37+
classes: {
38+
lectureId: number
39+
classNo: string // 분반
40+
professors: IProfessorV2.Basic[] // 해당 분반의 교수님
41+
}[]
42+
myProfessors: IProfessorV2.Basic[] // 본인이 수강한 학기의 경우, 수강한 분반의 교수님
43+
// 한 lecture에 여러명의 교수님이 존재할 수 있음
44+
}[]
45+
summary: string
46+
classDuration: number // 강의시간
47+
expDuration: number // 실험시간
48+
credit: number
49+
creditAU: number
50+
}
51+
52+
export class Query {
53+
@IsOptional()
54+
@Transform(({ value }) => (typeof value === 'string' ? [value] : value))
55+
@IsArray()
56+
@IsIn(['ALL', 'BR', 'BE', 'MR', 'ME', 'MGC', 'HSE', 'GR', 'EG', 'OE', 'ETC'], {
57+
each: true,
58+
message: 'type[] must be valid CourseType',
59+
})
60+
type?: CourseType[]
61+
62+
@IsOptional()
63+
@Transform(({ value }) => {
64+
if (Array.isArray(value)) return value.map(Number)
65+
if (typeof value === 'string') {
66+
try {
67+
// JSON 문자열 형태일 때
68+
if (value.startsWith('[') && value.endsWith(']')) {
69+
return JSON.parse(value).map(Number)
70+
}
71+
// 콤마 구분일 때
72+
return value.split(',').map(Number)
73+
}
74+
catch {
75+
return [Number(value)]
76+
}
77+
}
78+
return value
79+
})
80+
@IsArray()
81+
@IsInt({ each: true })
82+
@ApiPropertyOptional({ type: [Number], description: 'Department IDs' })
83+
department?: number[] // 각 department의 id
84+
85+
@IsOptional()
86+
@Transform(({ value }) => (typeof value === 'string' ? [value] : value))
87+
@IsArray()
88+
@IsIn(['ALL', '100', '200', '300', '400', '500', '600', '700', '800', '900'], {
89+
each: true,
90+
message: 'level[] must be one of \'ALL\' or \'100\'..\'900\'',
91+
})
92+
level?: level[]
93+
94+
@IsOptional()
95+
@Transform(({ value }) => (typeof value === 'string' ? [value] : value))
96+
@IsArray()
97+
@IsString({ each: true })
98+
term?: number // 과목 기간 (최근 n년 이내 검색)
99+
100+
@IsOptional()
101+
@IsString()
102+
keyword?: string // 검색어
103+
104+
@IsOptional()
105+
@IsString()
106+
@IsIn(['code', 'popular', 'studentCount'], { message: 'order must be one of \'code\', \'popular\', \'studentCount\'' })
107+
order?: CourseOrderQuery
108+
109+
@IsOptional()
110+
@IsNumber()
111+
@Transform(({ value }) => parseInt(value))
112+
offset?: number
113+
114+
@IsOptional()
115+
@IsNumber()
116+
@Transform(({ value }) => parseInt(value))
117+
limit?: number
118+
}
119+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export namespace IDepartmentV2 {
2+
export interface Basic {
3+
id: number
4+
name: string
5+
}
6+
}

0 commit comments

Comments
 (0)