This commit is contained in:
JongYeob Sheen 2023-11-23 00:30:50 +09:00
parent e8ddadfd0a
commit d354dbb27f
18 changed files with 1907 additions and 817 deletions

View File

@ -4,6 +4,7 @@ const (
BASE_URL = "http://localhost:3030"
PORT = ":3030"
DATABASE_URL = "learnsteam:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(localhost:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
//DATABASE_URL = "root:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(learnsteam-quiz-db:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
KAKAO_CLIENT_ID = "986830"
KAKAO_CLIENT_SECRET = "14f63a8e91c4e0fe88bc40e3ff348233"

View File

@ -3,8 +3,8 @@ package config
const (
BASE_URL = "http://localhost:3030"
PORT = ":3030"
//DATABASE_URL = "learnsteam:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(localhost:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
DATABASE_URL = "root:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(learnsteam-quiz-db:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
DATABASE_URL = "learnsteam:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(localhost:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
//DATABASE_URL = "root:fbOgZ6Xxn5VXBYihjqygRXyaK6ZUgKL6@tcp(learnsteam-quiz-db:3306)/learnsteam_quiz?charset=utf8&parseTime=True&loc=Local"
KAKAO_CLIENT_ID = "986830"
KAKAO_CLIENT_SECRET = "14f63a8e91c4e0fe88bc40e3ff348233"

View File

@ -20,7 +20,7 @@ const docTemplate = `{
"paths": {
"/auth/login": {
"post": {
"description": "username, password 를 입력하여 로그인",
"description": "사용자가 로그인합니다.",
"consumes": [
"application/json"
],
@ -30,24 +30,15 @@ const docTemplate = `{
"tags": [
"로그인"
],
"summary": "로그인",
"summary": "사용자 로그인 로그인",
"parameters": [
{
"description": "username",
"name": "username",
"description": "Login Body",
"name": "loginBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "비밀번호",
"name": "password",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.LoginRequest"
}
}
],
@ -76,30 +67,12 @@ const docTemplate = `{
"summary": "회원가입",
"parameters": [
{
"description": "username",
"name": "username",
"description": "Register Body",
"name": "registerBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "이름",
"name": "name",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "비밀번호",
"name": "password",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.RegisterRequest"
}
}
],
@ -113,6 +86,177 @@ const docTemplate = `{
}
}
},
"/exam": {
"get": {
"description": "응시 목록을 가져옵니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "응시 목록 가져오기",
"parameters": [
{
"type": "string",
"description": "검색어",
"name": "q",
"in": "query"
},
{
"type": "integer",
"description": "페이지",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "페이지 사이즈",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamListResponse"
}
}
}
},
"put": {
"description": "퀴즈 프로그램을 수정합니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "퀴즈 프로그램 수정",
"parameters": [
{
"description": "Exam Update Body",
"name": "examUpdateBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamUpdateRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
},
"post": {
"description": "응시 매칭을 만듭니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "응시 매칭 생성",
"parameters": [
{
"description": "Exam Body",
"name": "examBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
},
"patch": {
"description": "퀴즈 프로그램 정보를 변경합니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "퀴즈 프로그램 정보 변경",
"parameters": [
{
"description": "Exam Patch Body (변경할 필드만 입력)",
"name": "examPatchBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamPatchRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
}
},
"/exam/{id}": {
"get": {
"description": "ID로 응시 정보를 가져옵니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "응시(시험) 정보 가져오기",
"parameters": [
{
"type": "string",
"description": "응시 ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
}
},
"/program": {
"get": {
"description": "퀴즈 프로그램 목록을 가져옵니다.",
@ -175,60 +319,12 @@ const docTemplate = `{
"summary": "퀴즈 프로그램 수정",
"parameters": [
{
"description": "프로그램 제목",
"name": "subject",
"description": "Program Body",
"name": "programUpdateBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 코스",
"name": "course",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 내용",
"name": "content",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 태그",
"name": "tag",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "프로그램 상태 on 또는 off",
"name": "status",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 발행 날짜",
"name": "publish_at",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ProgramRequest"
}
}
],
@ -255,60 +351,12 @@ const docTemplate = `{
"summary": "퀴즈 프로그램 생성",
"parameters": [
{
"description": "프로그램 제목",
"name": "subject",
"description": "Program Body",
"name": "programBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 코스",
"name": "course",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 내용",
"name": "content",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 태그",
"name": "tag",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "프로그램 상태 on 또는 off",
"name": "status",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 발행 날짜",
"name": "publish_at",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ProgramRequest"
}
}
],
@ -417,88 +465,12 @@ const docTemplate = `{
"summary": "퀴즈 수정",
"parameters": [
{
"type": "string",
"description": "퀴즈 ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "프로그램 ID",
"name": "program_id",
"description": "Quiz Body",
"name": "quizBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 순서",
"name": "sequence",
"in": "body",
"required": true,
"schema": {
"type": "integer"
}
},
{
"description": "퀴즈 타입 : choice, check, ox, input",
"name": "quiz_type",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 문제",
"name": "question",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']",
"name": "choice",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 정답 : [1,3]",
"name": "answer",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 힌트",
"name": "hint",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 해설",
"name": "comment",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.QuizRequest"
}
}
],
@ -525,81 +497,12 @@ const docTemplate = `{
"summary": "퀴즈 생성",
"parameters": [
{
"description": "프로그램 ID",
"name": "program_id",
"description": "Quiz Body",
"name": "quizBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 순서",
"name": "sequence",
"in": "body",
"required": true,
"schema": {
"type": "integer"
}
},
{
"description": "퀴즈 타입 : choice, check, ox, input",
"name": "quiz_type",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 문제",
"name": "question",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']",
"name": "choice",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 정답 : [1,3]",
"name": "answer",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 힌트",
"name": "hint",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 해설",
"name": "comment",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.QuizRequest"
}
}
],
@ -756,6 +659,221 @@ const docTemplate = `{
}
},
"definitions": {
"learnsteam_learsteam-quiz-api_internal_models.Exam": {
"type": "object",
"properties": {
"end_at": {
"type": "string"
},
"id": {
"type": "string",
"example": "ef74c59a-c707-4162-a52b-455906c81ec1"
},
"name": {
"type": "string",
"example": "홍길순"
},
"program": {
"type": "string",
"example": "파이썬 초급 과정"
},
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"score": {
"type": "integer",
"example": 5
},
"start_at": {
"type": "string"
},
"status": {
"type": "string",
"example": "ready"
},
"subject": {
"type": "string",
"example": "출력 Print"
},
"total": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "string",
"example": "f95159dd-c42c-490d-ac6b-ca5d88a266bb"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamListResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.Exam"
}
},
"page": {
"type": "integer",
"example": 1
},
"pageSize": {
"type": "integer",
"example": 10
},
"total": {
"type": "integer",
"example": 999
},
"totalPage": {
"type": "integer",
"example": 99
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamPatchRequest": {
"type": "object",
"properties": {
"end_at": {
"type": "string",
"example": "2023-11-10T13:25:00+09:00"
},
"score": {
"type": "integer",
"example": 4
},
"start_at": {
"type": "string",
"example": "2023-11-10T13:10:00+09:00"
},
"status": {
"type": "string",
"example": "rating"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamRequest": {
"type": "object",
"properties": {
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"users": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamResponse": {
"type": "object",
"properties": {
"end_at": {
"type": "string",
"example": "2023-11-10T13:25:00+09:00"
},
"id": {
"type": "string",
"example": "ef74c59a-c707-4162-a52b-455906c81ec1"
},
"name": {
"type": "string",
"example": "홍길순"
},
"program": {
"type": "string",
"example": "파이썬 초급 과정"
},
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"score": {
"type": "integer",
"example": 5
},
"start_at": {
"type": "string",
"example": "2023-11-10T13:10:00+09:00"
},
"status": {
"type": "string",
"example": "ready"
},
"subject": {
"type": "string",
"example": "출력 Print"
},
"total": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "string",
"example": "f95159dd-c42c-490d-ac6b-ca5d88a266bb"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamUpdateRequest": {
"type": "object",
"properties": {
"end_at": {
"type": "string",
"example": "2023-11-10T13:25:00+09:00"
},
"name": {
"type": "string",
"example": "홍길순"
},
"program": {
"type": "string",
"example": "파이썬 초급 과정"
},
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"score": {
"type": "integer",
"example": 5
},
"start_at": {
"type": "string",
"example": "2023-11-10T13:10:00+09:00"
},
"status": {
"type": "string",
"example": "ready"
},
"subject": {
"type": "string",
"example": "출력 Print"
},
"total": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "string",
"example": "f95159dd-c42c-490d-ac6b-ca5d88a266bb"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.LoginRequest": {
"type": "object",
"properties": {
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.LoginResponse": {
"type": "object",
"properties": {
@ -834,6 +952,37 @@ const docTemplate = `{
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ProgramRequest": {
"type": "object",
"properties": {
"content": {
"type": "string",
"example": "코스 설명"
},
"course": {
"type": "string",
"example": "코스 이름"
},
"publish_at": {
"type": "string",
"example": "2023-11-10T00:00:00+09:00"
},
"status": {
"type": "string",
"example": "on"
},
"subject": {
"type": "string",
"example": "프로그램 제목"
},
"tag": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ProgramResponse": {
"type": "object",
"properties": {
@ -945,6 +1094,41 @@ const docTemplate = `{
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.QuizRequest": {
"type": "object",
"properties": {
"answer": {
"type": "array",
"items": {
"type": "integer"
}
},
"choice": {
"type": "array",
"items": {
"type": "integer"
}
},
"comment": {
"type": "string"
},
"hint": {
"type": "string"
},
"program_id": {
"type": "string"
},
"question": {
"type": "string"
},
"quiz_type": {
"type": "string"
},
"sequence": {
"type": "integer"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.QuizResponse": {
"type": "object",
"properties": {
@ -990,6 +1174,20 @@ const docTemplate = `{
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.RegisterRequest": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.RegisterResponse": {
"type": "object",
"properties": {

View File

@ -12,7 +12,7 @@
"paths": {
"/auth/login": {
"post": {
"description": "username, password 를 입력하여 로그인",
"description": "사용자가 로그인합니다.",
"consumes": [
"application/json"
],
@ -22,24 +22,15 @@
"tags": [
"로그인"
],
"summary": "로그인",
"summary": "사용자 로그인 로그인",
"parameters": [
{
"description": "username",
"name": "username",
"description": "Login Body",
"name": "loginBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "비밀번호",
"name": "password",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.LoginRequest"
}
}
],
@ -68,30 +59,12 @@
"summary": "회원가입",
"parameters": [
{
"description": "username",
"name": "username",
"description": "Register Body",
"name": "registerBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "이름",
"name": "name",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "비밀번호",
"name": "password",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.RegisterRequest"
}
}
],
@ -105,6 +78,177 @@
}
}
},
"/exam": {
"get": {
"description": "응시 목록을 가져옵니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "응시 목록 가져오기",
"parameters": [
{
"type": "string",
"description": "검색어",
"name": "q",
"in": "query"
},
{
"type": "integer",
"description": "페이지",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "페이지 사이즈",
"name": "limit",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamListResponse"
}
}
}
},
"put": {
"description": "퀴즈 프로그램을 수정합니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "퀴즈 프로그램 수정",
"parameters": [
{
"description": "Exam Update Body",
"name": "examUpdateBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamUpdateRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
},
"post": {
"description": "응시 매칭을 만듭니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "응시 매칭 생성",
"parameters": [
{
"description": "Exam Body",
"name": "examBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
},
"patch": {
"description": "퀴즈 프로그램 정보를 변경합니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "퀴즈 프로그램 정보 변경",
"parameters": [
{
"description": "Exam Patch Body (변경할 필드만 입력)",
"name": "examPatchBody",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamPatchRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
}
},
"/exam/{id}": {
"get": {
"description": "ID로 응시 정보를 가져옵니다.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Exam"
],
"summary": "응시(시험) 정보 가져오기",
"parameters": [
{
"type": "string",
"description": "응시 ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse"
}
}
}
}
},
"/program": {
"get": {
"description": "퀴즈 프로그램 목록을 가져옵니다.",
@ -167,60 +311,12 @@
"summary": "퀴즈 프로그램 수정",
"parameters": [
{
"description": "프로그램 제목",
"name": "subject",
"description": "Program Body",
"name": "programUpdateBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 코스",
"name": "course",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 내용",
"name": "content",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 태그",
"name": "tag",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "프로그램 상태 on 또는 off",
"name": "status",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 발행 날짜",
"name": "publish_at",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ProgramRequest"
}
}
],
@ -247,60 +343,12 @@
"summary": "퀴즈 프로그램 생성",
"parameters": [
{
"description": "프로그램 제목",
"name": "subject",
"description": "Program Body",
"name": "programBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 코스",
"name": "course",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 내용",
"name": "content",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 태그",
"name": "tag",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "프로그램 상태 on 또는 off",
"name": "status",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "프로그램 발행 날짜",
"name": "publish_at",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.ProgramRequest"
}
}
],
@ -409,88 +457,12 @@
"summary": "퀴즈 수정",
"parameters": [
{
"type": "string",
"description": "퀴즈 ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "프로그램 ID",
"name": "program_id",
"description": "Quiz Body",
"name": "quizBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 순서",
"name": "sequence",
"in": "body",
"required": true,
"schema": {
"type": "integer"
}
},
{
"description": "퀴즈 타입 : choice, check, ox, input",
"name": "quiz_type",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 문제",
"name": "question",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']",
"name": "choice",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 정답 : [1,3]",
"name": "answer",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 힌트",
"name": "hint",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 해설",
"name": "comment",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.QuizRequest"
}
}
],
@ -517,81 +489,12 @@
"summary": "퀴즈 생성",
"parameters": [
{
"description": "프로그램 ID",
"name": "program_id",
"description": "Quiz Body",
"name": "quizBody",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 순서",
"name": "sequence",
"in": "body",
"required": true,
"schema": {
"type": "integer"
}
},
{
"description": "퀴즈 타입 : choice, check, ox, input",
"name": "quiz_type",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 문제",
"name": "question",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']",
"name": "choice",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 정답 : [1,3]",
"name": "answer",
"in": "body",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
},
{
"description": "퀴즈 힌트",
"name": "hint",
"in": "body",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "퀴즈 해설",
"name": "comment",
"in": "body",
"required": true,
"schema": {
"type": "string"
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.QuizRequest"
}
}
],
@ -748,6 +651,221 @@
}
},
"definitions": {
"learnsteam_learsteam-quiz-api_internal_models.Exam": {
"type": "object",
"properties": {
"end_at": {
"type": "string"
},
"id": {
"type": "string",
"example": "ef74c59a-c707-4162-a52b-455906c81ec1"
},
"name": {
"type": "string",
"example": "홍길순"
},
"program": {
"type": "string",
"example": "파이썬 초급 과정"
},
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"score": {
"type": "integer",
"example": 5
},
"start_at": {
"type": "string"
},
"status": {
"type": "string",
"example": "ready"
},
"subject": {
"type": "string",
"example": "출력 Print"
},
"total": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "string",
"example": "f95159dd-c42c-490d-ac6b-ca5d88a266bb"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamListResponse": {
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/definitions/learnsteam_learsteam-quiz-api_internal_models.Exam"
}
},
"page": {
"type": "integer",
"example": 1
},
"pageSize": {
"type": "integer",
"example": 10
},
"total": {
"type": "integer",
"example": 999
},
"totalPage": {
"type": "integer",
"example": 99
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamPatchRequest": {
"type": "object",
"properties": {
"end_at": {
"type": "string",
"example": "2023-11-10T13:25:00+09:00"
},
"score": {
"type": "integer",
"example": 4
},
"start_at": {
"type": "string",
"example": "2023-11-10T13:10:00+09:00"
},
"status": {
"type": "string",
"example": "rating"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamRequest": {
"type": "object",
"properties": {
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"users": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamResponse": {
"type": "object",
"properties": {
"end_at": {
"type": "string",
"example": "2023-11-10T13:25:00+09:00"
},
"id": {
"type": "string",
"example": "ef74c59a-c707-4162-a52b-455906c81ec1"
},
"name": {
"type": "string",
"example": "홍길순"
},
"program": {
"type": "string",
"example": "파이썬 초급 과정"
},
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"score": {
"type": "integer",
"example": 5
},
"start_at": {
"type": "string",
"example": "2023-11-10T13:10:00+09:00"
},
"status": {
"type": "string",
"example": "ready"
},
"subject": {
"type": "string",
"example": "출력 Print"
},
"total": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "string",
"example": "f95159dd-c42c-490d-ac6b-ca5d88a266bb"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ExamUpdateRequest": {
"type": "object",
"properties": {
"end_at": {
"type": "string",
"example": "2023-11-10T13:25:00+09:00"
},
"name": {
"type": "string",
"example": "홍길순"
},
"program": {
"type": "string",
"example": "파이썬 초급 과정"
},
"program_id": {
"type": "string",
"example": "7f9329f5-2e36-4638-92d2-73064b7291a4"
},
"score": {
"type": "integer",
"example": 5
},
"start_at": {
"type": "string",
"example": "2023-11-10T13:10:00+09:00"
},
"status": {
"type": "string",
"example": "ready"
},
"subject": {
"type": "string",
"example": "출력 Print"
},
"total": {
"type": "integer",
"example": 5
},
"user_id": {
"type": "string",
"example": "f95159dd-c42c-490d-ac6b-ca5d88a266bb"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.LoginRequest": {
"type": "object",
"properties": {
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.LoginResponse": {
"type": "object",
"properties": {
@ -826,6 +944,37 @@
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ProgramRequest": {
"type": "object",
"properties": {
"content": {
"type": "string",
"example": "코스 설명"
},
"course": {
"type": "string",
"example": "코스 이름"
},
"publish_at": {
"type": "string",
"example": "2023-11-10T00:00:00+09:00"
},
"status": {
"type": "string",
"example": "on"
},
"subject": {
"type": "string",
"example": "프로그램 제목"
},
"tag": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.ProgramResponse": {
"type": "object",
"properties": {
@ -937,6 +1086,41 @@
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.QuizRequest": {
"type": "object",
"properties": {
"answer": {
"type": "array",
"items": {
"type": "integer"
}
},
"choice": {
"type": "array",
"items": {
"type": "integer"
}
},
"comment": {
"type": "string"
},
"hint": {
"type": "string"
},
"program_id": {
"type": "string"
},
"question": {
"type": "string"
},
"quiz_type": {
"type": "string"
},
"sequence": {
"type": "integer"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.QuizResponse": {
"type": "object",
"properties": {
@ -982,6 +1166,20 @@
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.RegisterRequest": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"password": {
"type": "string"
},
"username": {
"type": "string"
}
}
},
"learnsteam_learsteam-quiz-api_internal_models.RegisterResponse": {
"type": "object",
"properties": {

View File

@ -1,4 +1,158 @@
definitions:
learnsteam_learsteam-quiz-api_internal_models.Exam:
properties:
end_at:
type: string
id:
example: ef74c59a-c707-4162-a52b-455906c81ec1
type: string
name:
example: 홍길순
type: string
program:
example: 파이썬 초급 과정
type: string
program_id:
example: 7f9329f5-2e36-4638-92d2-73064b7291a4
type: string
score:
example: 5
type: integer
start_at:
type: string
status:
example: ready
type: string
subject:
example: 출력 Print
type: string
total:
example: 5
type: integer
user_id:
example: f95159dd-c42c-490d-ac6b-ca5d88a266bb
type: string
type: object
learnsteam_learsteam-quiz-api_internal_models.ExamListResponse:
properties:
data:
items:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.Exam'
type: array
page:
example: 1
type: integer
pageSize:
example: 10
type: integer
total:
example: 999
type: integer
totalPage:
example: 99
type: integer
type: object
learnsteam_learsteam-quiz-api_internal_models.ExamPatchRequest:
properties:
end_at:
example: "2023-11-10T13:25:00+09:00"
type: string
score:
example: 4
type: integer
start_at:
example: "2023-11-10T13:10:00+09:00"
type: string
status:
example: rating
type: string
type: object
learnsteam_learsteam-quiz-api_internal_models.ExamRequest:
properties:
program_id:
example: 7f9329f5-2e36-4638-92d2-73064b7291a4
type: string
users:
items:
type: integer
type: array
type: object
learnsteam_learsteam-quiz-api_internal_models.ExamResponse:
properties:
end_at:
example: "2023-11-10T13:25:00+09:00"
type: string
id:
example: ef74c59a-c707-4162-a52b-455906c81ec1
type: string
name:
example: 홍길순
type: string
program:
example: 파이썬 초급 과정
type: string
program_id:
example: 7f9329f5-2e36-4638-92d2-73064b7291a4
type: string
score:
example: 5
type: integer
start_at:
example: "2023-11-10T13:10:00+09:00"
type: string
status:
example: ready
type: string
subject:
example: 출력 Print
type: string
total:
example: 5
type: integer
user_id:
example: f95159dd-c42c-490d-ac6b-ca5d88a266bb
type: string
type: object
learnsteam_learsteam-quiz-api_internal_models.ExamUpdateRequest:
properties:
end_at:
example: "2023-11-10T13:25:00+09:00"
type: string
name:
example: 홍길순
type: string
program:
example: 파이썬 초급 과정
type: string
program_id:
example: 7f9329f5-2e36-4638-92d2-73064b7291a4
type: string
score:
example: 5
type: integer
start_at:
example: "2023-11-10T13:10:00+09:00"
type: string
status:
example: ready
type: string
subject:
example: 출력 Print
type: string
total:
example: 5
type: integer
user_id:
example: f95159dd-c42c-490d-ac6b-ca5d88a266bb
type: string
type: object
learnsteam_learsteam-quiz-api_internal_models.LoginRequest:
properties:
password:
type: string
username:
type: string
type: object
learnsteam_learsteam-quiz-api_internal_models.LoginResponse:
properties:
refresh_token:
@ -54,6 +208,28 @@ definitions:
example: 99
type: integer
type: object
learnsteam_learsteam-quiz-api_internal_models.ProgramRequest:
properties:
content:
example: 코스 설명
type: string
course:
example: 코스 이름
type: string
publish_at:
example: "2023-11-10T00:00:00+09:00"
type: string
status:
example: "on"
type: string
subject:
example: 프로그램 제목
type: string
tag:
items:
type: integer
type: array
type: object
learnsteam_learsteam-quiz-api_internal_models.ProgramResponse:
properties:
content:
@ -133,6 +309,29 @@ definitions:
example: 1
type: integer
type: object
learnsteam_learsteam-quiz-api_internal_models.QuizRequest:
properties:
answer:
items:
type: integer
type: array
choice:
items:
type: integer
type: array
comment:
type: string
hint:
type: string
program_id:
type: string
question:
type: string
quiz_type:
type: string
sequence:
type: integer
type: object
learnsteam_learsteam-quiz-api_internal_models.QuizResponse:
properties:
answer:
@ -165,6 +364,15 @@ definitions:
example: 5
type: integer
type: object
learnsteam_learsteam-quiz-api_internal_models.RegisterRequest:
properties:
name:
type: string
password:
type: string
username:
type: string
type: object
learnsteam_learsteam-quiz-api_internal_models.RegisterResponse:
properties:
refresh_token:
@ -222,20 +430,14 @@ paths:
post:
consumes:
- application/json
description: username, password 를 입력하여 로그인
description: 사용자가 로그인합니다.
parameters:
- description: username
- description: Login Body
in: body
name: username
name: loginBody
required: true
schema:
type: string
- description: 비밀번호
in: body
name: password
required: true
schema:
type: string
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.LoginRequest'
produces:
- application/json
responses:
@ -243,7 +445,7 @@ paths:
description: OK
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.LoginResponse'
summary: 로그인
summary: 사용자 로그인 로그인
tags:
- 로그인
/auth/register:
@ -252,24 +454,12 @@ paths:
- application/json
description: username, name, password 를 입력하여 회원가입
parameters:
- description: username
- description: Register Body
in: body
name: username
name: registerBody
required: true
schema:
type: string
- description: 이름
in: body
name: name
required: true
schema:
type: string
- description: 비밀번호
in: body
name: password
required: true
schema:
type: string
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.RegisterRequest'
produces:
- application/json
responses:
@ -280,6 +470,118 @@ paths:
summary: 회원가입
tags:
- 회원가입
/exam:
get:
consumes:
- application/json
description: 응시 목록을 가져옵니다.
parameters:
- description: 검색어
in: query
name: q
type: string
- description: 페이지
in: query
name: page
type: integer
- description: 페이지 사이즈
in: query
name: limit
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamListResponse'
summary: 응시 목록 가져오기
tags:
- Exam
patch:
consumes:
- application/json
description: 퀴즈 프로그램 정보를 변경합니다.
parameters:
- description: Exam Patch Body (변경할 필드만 입력)
in: body
name: examPatchBody
required: true
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamPatchRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse'
summary: 퀴즈 프로그램 정보 변경
tags:
- Exam
post:
consumes:
- application/json
description: 응시 매칭을 만듭니다.
parameters:
- description: Exam Body
in: body
name: examBody
required: true
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse'
summary: 응시 매칭 생성
tags:
- Exam
put:
consumes:
- application/json
description: 퀴즈 프로그램을 수정합니다.
parameters:
- description: Exam Update Body
in: body
name: examUpdateBody
required: true
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamUpdateRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse'
summary: 퀴즈 프로그램 수정
tags:
- Exam
/exam/{id}:
get:
consumes:
- application/json
description: ID로 응시 정보를 가져옵니다.
parameters:
- description: 응시 ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ExamResponse'
summary: 응시(시험) 정보 가져오기
tags:
- Exam
/program:
get:
consumes:
@ -317,44 +619,12 @@ paths:
- application/json
description: 퀴즈 프로그램을 만듭니다.
parameters:
- description: 프로그램 제목
- description: Program Body
in: body
name: subject
name: programBody
required: true
schema:
type: string
- description: 프로그램 코스
in: body
name: course
required: true
schema:
type: string
- description: 프로그램 내용
in: body
name: content
required: true
schema:
type: string
- description: 프로그램 태그
in: body
name: tag
required: true
schema:
items:
type: string
type: array
- description: 프로그램 상태 on 또는 off
in: body
name: status
required: true
schema:
type: string
- description: 프로그램 발행 날짜
in: body
name: publish_at
required: true
schema:
type: string
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ProgramRequest'
produces:
- application/json
responses:
@ -370,44 +640,12 @@ paths:
- application/json
description: 퀴즈 프로그램을 수정합니다.
parameters:
- description: 프로그램 제목
- description: Program Body
in: body
name: subject
name: programUpdateBody
required: true
schema:
type: string
- description: 프로그램 코스
in: body
name: course
required: true
schema:
type: string
- description: 프로그램 내용
in: body
name: content
required: true
schema:
type: string
- description: 프로그램 태그
in: body
name: tag
required: true
schema:
items:
type: string
type: array
- description: 프로그램 상태 on 또는 off
in: body
name: status
required: true
schema:
type: string
- description: 프로그램 발행 날짜
in: body
name: publish_at
required: true
schema:
type: string
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.ProgramRequest'
produces:
- application/json
responses:
@ -477,58 +715,12 @@ paths:
- application/json
description: 퀴즈를 만듭니다.
parameters:
- description: 프로그램 ID
- description: Quiz Body
in: body
name: program_id
name: quizBody
required: true
schema:
type: string
- description: 퀴즈 순서
in: body
name: sequence
required: true
schema:
type: integer
- description: '퀴즈 타입 : choice, check, ox, input'
in: body
name: quiz_type
required: true
schema:
type: string
- description: 퀴즈 문제
in: body
name: question
required: true
schema:
type: string
- description: '퀴즈 선택지 : [''선택1'',''선택2'',''선택3'', ''선택4'']'
in: body
name: choice
required: true
schema:
items:
type: string
type: array
- description: '퀴즈 정답 : [1,3]'
in: body
name: answer
required: true
schema:
items:
type: string
type: array
- description: 퀴즈 힌트
in: body
name: hint
required: true
schema:
type: string
- description: 퀴즈 해설
in: body
name: comment
required: true
schema:
type: string
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.QuizRequest'
produces:
- application/json
responses:
@ -544,63 +736,12 @@ paths:
- application/json
description: 퀴즈를 수정합니다.
parameters:
- description: 퀴즈 ID
in: path
name: id
required: true
type: string
- description: 프로그램 ID
- description: Quiz Body
in: body
name: program_id
name: quizBody
required: true
schema:
type: string
- description: 퀴즈 순서
in: body
name: sequence
required: true
schema:
type: integer
- description: '퀴즈 타입 : choice, check, ox, input'
in: body
name: quiz_type
required: true
schema:
type: string
- description: 퀴즈 문제
in: body
name: question
required: true
schema:
type: string
- description: '퀴즈 선택지 : [''선택1'',''선택2'',''선택3'', ''선택4'']'
in: body
name: choice
required: true
schema:
items:
type: string
type: array
- description: '퀴즈 정답 : [1,3]'
in: body
name: answer
required: true
schema:
items:
type: string
type: array
- description: 퀴즈 힌트
in: body
name: hint
required: true
schema:
type: string
- description: 퀴즈 해설
in: body
name: comment
required: true
schema:
type: string
$ref: '#/definitions/learnsteam_learsteam-quiz-api_internal_models.QuizRequest'
produces:
- application/json
responses:

View File

@ -34,9 +34,7 @@ func NewAuthController(service services.AuthService, tokenService services.Token
// @Accept json
// @Produce json
//
// @Param username body string true "username"
// @Param name body string true "이름"
// @Param password body string true "비밀번호"
// @Param registerBody body models.RegisterRequest true "Register Body"
//
// @Success 200 {object} models.RegisterResponse
// @Router /auth/register [post]
@ -69,8 +67,7 @@ func (controller *authController) Register(c *gin.Context) {
// @Accept json
// @Produce json
//
// @Param username body string true "username"
// @Param password body string true "비밀번호"
// @Param loginBody body models.LoginRequest true "Login Body"
//
// @Success 200 {object} models.LoginResponse
// @Router /auth/login [post]

View File

@ -0,0 +1,306 @@
package controllers
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"learnsteam/learsteam-quiz-api/internal/models"
"learnsteam/learsteam-quiz-api/internal/services"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type ExamController interface {
List(*gin.Context)
Find(*gin.Context)
Create(*gin.Context)
Update(*gin.Context)
Patch(*gin.Context)
}
type examController struct {
service services.ExamService
userService services.UserService
programService services.ProgramService
}
func NewExamController(service services.ExamService, userService services.UserService, programService services.ProgramService) ExamController {
return &examController{
service: service,
userService: userService,
programService: programService,
}
}
// Exam List
//
// @Summary 응시 목록 가져오기
// @Description 응시 목록을 가져옵니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param q query string false "검색어"
// @Param page query int false "페이지"
// @Param limit query int false "페이지 사이즈"
//
// @Success 200 {object} models.ExamListResponse
// @Router /exam [get]
func (controller *examController) List(c *gin.Context) {
q := c.DefaultQuery("q", "")
page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
if err != nil {
fmt.Println("error : page")
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
limit, err := strconv.Atoi(c.DefaultQuery("limit", "10"))
if err != nil {
fmt.Println("error : limit")
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
result, err := controller.service.List(q, page, limit)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
totalNumber, err := controller.service.Total(q)
if err != nil {
fmt.Println("error : list")
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
totalPage := int64(totalNumber/int64(limit) + 1)
response := models.ExamListResponse{
Data: *result,
Total: totalNumber,
Page: page,
TotalPage: totalPage,
PageSize: limit,
}
c.JSON(http.StatusOK, response)
}
// Get exam
//
// @Summary 응시(시험) 정보 가져오기
// @Description ID로 응시 정보를 가져옵니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param id path string true "응시 ID"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam/{id} [get]
func (controller *examController) Find(c *gin.Context) {
id := c.Param("id")
result, err := controller.service.Find(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, result)
}
// Create Exam
//
// @Summary 응시 매칭 생성
// @Description 응시 매칭을 만듭니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param examBody body models.ExamRequest true "Exam Body"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam [post]
func (controller *examController) Create(c *gin.Context) {
var request models.ExamRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("users", request.Users)
program, err := controller.programService.Find(request.ProgramID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var users []string
err = json.Unmarshal(request.Users, &users)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
count := 0
for _, user_id := range users {
user, err := controller.userService.Find(user_id)
if err != nil {
continue
}
exam := &models.Exam{
ID: uuid.NewString(),
ProgramID: program.ID,
UserID: user_id,
Subject: program.Subject,
Program: program.Course,
Name: user.Name,
Score: 0,
Total: 5,
Status: "ready",
}
_, err = controller.service.Create(exam)
if err != nil {
continue
}
count += 1
}
c.JSON(http.StatusOK, gin.H{"count": count})
}
// Update Exam
//
// @Summary 퀴즈 프로그램 수정
// @Description 퀴즈 프로그램을 수정합니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param examUpdateBody body models.ExamUpdateRequest true "Exam Update Body"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam [put]
func (controller *examController) Update(c *gin.Context) {
id := c.Param("id")
var request models.ExamUpdateRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("request", request)
exam, err := controller.service.Find(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
exam.ProgramID = request.ProgramID
exam.UserID = request.UserID
exam.Subject = request.Subject
exam.Program = request.Program
exam.Name = request.Name
exam.Status = request.Status
exam.Score = request.Score
exam.Total = request.Total
if request.StartAt != "" {
fmt.Println("request.StartAt", request.StartAt)
start_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.StartAt)
if err == nil {
exam.StartAt = &start_at
}
fmt.Println("start_at", start_at)
}
if request.EndAt != "" {
fmt.Println("request.EndAt", request.EndAt)
end_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.EndAt)
if err == nil {
exam.EndAt = &end_at
}
fmt.Println("end_at", end_at)
}
fmt.Println("exam", exam)
result, err := controller.service.Update(exam)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("result", result)
c.JSON(http.StatusOK, result)
}
// Patch Exam
//
// @Summary 퀴즈 프로그램 정보 변경
// @Description 퀴즈 프로그램 정보를 변경합니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param examPatchBody body models.ExamPatchRequest true "Exam Patch Body (변경할 필드만 입력)"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam [patch]
func (controller *examController) Patch(c *gin.Context) {
id := c.Param("id")
var request models.ExamPatchRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("request", request)
exam, err := controller.service.Find(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if request.Status != "" {
exam.Status = request.Status
}
if request.StartAt != "" {
fmt.Println("request.StartAt", request.StartAt)
start_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.StartAt)
if err == nil {
exam.StartAt = &start_at
}
fmt.Println("start_at", start_at)
}
if request.EndAt != "" {
fmt.Println("request.EndAt", request.EndAt)
end_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.EndAt)
if err == nil {
exam.EndAt = &end_at
}
fmt.Println("end_at", end_at)
}
fmt.Println("exam", exam)
result, err := controller.service.Update(exam)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("result", result)
c.JSON(http.StatusOK, result)
}

View File

@ -121,12 +121,7 @@ func (controller *programController) Find(c *gin.Context) {
// @Accept json
// @Produce json
//
// @Param subject body string true "프로그램 제목"
// @Param course body string true "프로그램 코스"
// @Param content body string true "프로그램 내용"
// @Param tag body []string true "프로그램 태그"
// @Param status body string true "프로그램 상태 on 또는 off"
// @Param publish_at body string true "프로그램 발행 날짜"
// @Param programBody body models.ProgramRequest true "Program Body"
//
// @Success 200 {object} models.ProgramResponse
// @Router /program [post]
@ -174,12 +169,7 @@ func (controller *programController) Create(c *gin.Context) {
// @Accept json
// @Produce json
//
// @Param subject body string true "프로그램 제목"
// @Param course body string true "프로그램 코스"
// @Param content body string true "프로그램 내용"
// @Param tag body []string true "프로그램 태그"
// @Param status body string true "프로그램 상태 on 또는 off"
// @Param publish_at body string true "프로그램 발행 날짜"
// @Param programUpdateBody body models.ProgramRequest true "Program Body"
//
// @Success 200 {object} models.ProgramResponse
// @Router /program [put]

View File

@ -112,14 +112,7 @@ func (controller *quizController) Find(c *gin.Context) {
// @Accept json
// @Produce json
//
// @Param program_id body string true "프로그램 ID"
// @Param sequence body int true "퀴즈 순서"
// @Param quiz_type body string true "퀴즈 타입 : choice, check, ox, input"
// @Param question body string true "퀴즈 문제"
// @Param choice body []string true "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']"
// @Param answer body []string true "퀴즈 정답 : [1,3]"
// @Param hint body string true "퀴즈 힌트"
// @Param comment body string true "퀴즈 해설"
// @Param quizBody body models.QuizRequest true "Quiz Body"
//
// @Success 200 {object} models.QuizResponse
// @Router /quiz [post]
@ -162,15 +155,7 @@ func (controller *quizController) Create(c *gin.Context) {
// @Accept json
// @Produce json
//
// @Param id path string true "퀴즈 ID"
// @Param program_id body string true "프로그램 ID"
// @Param sequence body int true "퀴즈 순서"
// @Param quiz_type body string true "퀴즈 타입 : choice, check, ox, input"
// @Param question body string true "퀴즈 문제"
// @Param choice body []string true "퀴즈 선택지 : ['선택1','선택2','선택3', '선택4']"
// @Param answer body []string true "퀴즈 정답 : [1,3]"
// @Param hint body string true "퀴즈 힌트"
// @Param comment body string true "퀴즈 해설"
// @Param quizBody body models.QuizRequest true "Quiz Body"
//
// @Success 200 {object} models.QuizResponse
// @Router /quiz [put]

View File

@ -40,5 +40,6 @@ func AutoMigrate() {
&models.Token{},
&models.Program{},
&models.Quiz{},
&models.Exam{},
)
}

70
internal/models/exam.go Normal file
View File

@ -0,0 +1,70 @@
package models
import (
"time"
"gorm.io/datatypes"
)
type Exam struct {
ID string `json:"id" db:"id" example:"ef74c59a-c707-4162-a52b-455906c81ec1" gorm:"column:id;size:255;primary_key;"`
ProgramID string `json:"program_id" db:"program_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4" gorm:"column:program_id;size:255;uniqueIndex:idx_exam;"`
UserID string `json:"user_id" db:"user_id" example:"f95159dd-c42c-490d-ac6b-ca5d88a266bb" gorm:"column:user_id;size:255;uniqueIndex:idx_exam;"`
Subject string `json:"subject" db:"subject" example:"출력 Print" gorm:"column:subject;size:255;index;"`
Program string `json:"program" db:"program" example:"파이썬 초급 과정" gorm:"column:program;size:255;index;"`
Name string `json:"name" db:"name" example:"홍길순" gorm:"column:name;size:255;index;"`
Score int `json:"score" db:"score" example:"5" gorm:"column:score;"`
Total int `json:"total" db:"total" example:"5" gorm:"column:total;"`
Status string `json:"status" example:"ready" gorm:"column:status;size:10;index;"`
StartAt *time.Time `json:"start_at" gorm:"column:start_at;index;"`
EndAt *time.Time `json:"end_at" gorm:"column:end_at;index;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;index;->:false"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index;->:false;<-:create"`
}
type ExamRequest struct {
ProgramID string `json:"program_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4"`
Users datatypes.JSON `json:"users"`
}
type ExamResponse struct {
ID string `json:"id" db:"id" example:"ef74c59a-c707-4162-a52b-455906c81ec1"`
ProgramID string `json:"program_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4"`
UserID string `json:"user_id" example:"f95159dd-c42c-490d-ac6b-ca5d88a266bb"`
Subject string `json:"subject" example:"출력 Print"`
Program string `json:"program" example:"파이썬 초급 과정"`
Name string `json:"name" example:"홍길순"`
Score int `json:"score" example:"5"`
Total int `json:"total" example:"5"`
Status string `json:"status" example:"ready"`
StartAt string `json:"start_at,omitempty" example:"2023-11-10T13:10:00+09:00"`
EndAt string `json:"end_at,omitempty" example:"2023-11-10T13:25:00+09:00"`
}
type ExamUpdateRequest struct {
ProgramID string `json:"program_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4"`
UserID string `json:"user_id" example:"f95159dd-c42c-490d-ac6b-ca5d88a266bb"`
Subject string `json:"subject" example:"출력 Print"`
Program string `json:"program" example:"파이썬 초급 과정"`
Name string `json:"name" example:"홍길순"`
Score int `json:"score" example:"5"`
Total int `json:"total" example:"5"`
Status string `json:"status" example:"ready"`
StartAt string `json:"start_at,omitempty" example:"2023-11-10T13:10:00+09:00"`
EndAt string `json:"end_at,omitempty" example:"2023-11-10T13:25:00+09:00"`
}
type ExamPatchRequest struct {
Score int `json:"score,omitempty" example:"4"`
Status string `json:"status,omitempty" example:"rating"`
StartAt string `json:"start_at,omitempty" example:"2023-11-10T13:10:00+09:00"`
EndAt string `json:"end_at,omitempty" example:"2023-11-10T13:25:00+09:00"`
}
type ExamListResponse struct {
Data []Exam `json:"data"`
Total int64 `json:"total" example:"999"`
Page int `json:"page" example:"1"`
TotalPage int64 `json:"totalPage" example:"99"`
PageSize int `json:"pageSize" example:"10"`
}

View File

@ -15,8 +15,8 @@ type Program struct {
Tags string `json:"-" db:"tags" gorm:"column:tags;index;"`
Status string `json:"status" example:"on" gorm:"column:status;size:10;index;"`
PublishAt time.Time `json:"publish_at" example:"2023-11-10T00:00:00+09:00" gorm:"column:publish_at;index;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;index;"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;index;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;index;->:false"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index;->:false;<-:create"`
}
type ProgramRequest struct {

View File

@ -16,8 +16,8 @@ type Quiz struct {
Answer datatypes.JSON `json:"answer" db:"answer" gorm:"column:answer;"`
Hint string `json:"hint" db:"hint" example:"퀴즈 힌트" gorm:"column:answer;size:1024;"`
Comment string `json:"comment" db:"comment" example:"퀴즈 해설" gorm:"column:comment;size:1024;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;index;"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;index;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;index;->:false"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index;->:false;<-:create"`
}
type QuizRequest struct {

View File

@ -8,8 +8,8 @@ type User struct {
Name string `json:"name" db:"name" example:"홍길동" gorm:"column:name;size:50;"`
Score int32 `json:"score" db:"score" example:"9999" gorm:"column:score;"`
Password string `json:"-" db:"password" gorm:"column:password;size:255;not null;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;index;"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;index;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;index;->:false"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index;->:false;<-:create"`
}
type UserListResponse struct {

View File

@ -0,0 +1,81 @@
package repositories
import (
"learnsteam/learsteam-quiz-api/internal/models"
"gorm.io/gorm"
)
type examRepository struct {
DB *gorm.DB
}
func NewExamRepository(db *gorm.DB) ExamRepository {
return &examRepository{
DB: db,
}
}
type ExamRepository interface {
List(string, int, int) (*[]models.Exam, error)
Total(string) (int64, error)
Find(string) (*models.Exam, error)
Create(*models.Exam) (*models.Exam, error)
Update(*models.Exam) (*models.Exam, error)
Delete(string) error
}
func (r *examRepository) List(q string, page int, limit int) (*[]models.Exam, error) {
var exams *[]models.Exam
var err error
offset := limit * (page - 1)
if q != "" {
err = r.DB.Offset(offset).Limit(limit).Order("created_at DESC").Where("subject LIKE ? OR program LIKE ? OR name LIKE ?", "%"+q+"%", "%"+q+"%", "%"+q+"%").Find(&exams).Error
} else {
err = r.DB.Offset(offset).Limit(limit).Order("created_at DESC").Find(&exams).Error
}
return exams, err
}
func (r *examRepository) Total(q string) (int64, error) {
var total int64
var err error
if q != "" {
err = r.DB.Model(&models.Exam{}).Where("subject LIKE ? OR program LIKE ? OR name LIKE ?", "%"+q+"%", "%"+q+"%", "%"+q+"%").Count(&total).Error
} else {
err = r.DB.Model(&models.Exam{}).Count(&total).Error
}
return total, err
}
func (r *examRepository) Find(id string) (*models.Exam, error) {
var exam *models.Exam
err := r.DB.Where("id = ?", id).First(&exam).Error
return exam, err
}
func (r *examRepository) Create(exam *models.Exam) (*models.Exam, error) {
err := r.DB.Create(&exam).Error
return exam, err
}
func (r *examRepository) Update(exam *models.Exam) (*models.Exam, error) {
var row *models.Exam
if err := r.DB.Where("id=?", exam.ID).First(&row).Error; err != nil {
return nil, err
}
err := r.DB.Model(&row).Select("*").Updates(&exam).Error
return row, err
}
func (r *examRepository) Delete(id string) error {
var exam *models.Exam
if err := r.DB.Where("id=?", id).First(&exam).Error; err != nil {
return err
}
err := r.DB.Delete(&exam).Error
return err
}

65
internal/routers/exam.go Normal file
View File

@ -0,0 +1,65 @@
package routers
import (
"learnsteam/learsteam-quiz-api/internal/controllers"
"learnsteam/learsteam-quiz-api/internal/middleware"
"learnsteam/learsteam-quiz-api/internal/repositories"
"learnsteam/learsteam-quiz-api/internal/services"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func InitExamRouter(db *gorm.DB, router *gin.Engine) {
r := NewExamRouter(db, router)
r.SetExamRouter(db, router)
}
type ExamRouter interface {
SetRouter(db *gorm.DB, router *gin.Engine)
}
type examRouter struct {
db *gorm.DB
repository repositories.ExamRepository
programRepository repositories.ProgramRepository
userRepository repositories.UserRepository
service services.ExamService
programService services.ProgramService
userService services.UserService
controller controllers.ExamController
router *gin.Engine
}
func NewExamRouter(db *gorm.DB, router *gin.Engine) *examRouter {
repository := repositories.NewExamRepository(db)
programRepository := repositories.NewProgramRepository(db)
tokenRepository := repositories.NewTokenRepository(db)
userRepository := repositories.NewUserRepository(db)
service := services.NewExamService(repository)
programService := services.NewProgramService(programRepository)
userService := services.NewUserService(userRepository, tokenRepository)
controller := controllers.NewExamController(service, userService, programService)
return &examRouter{
db: db,
repository: repository,
service: service,
controller: controller,
router: router,
}
}
func (r *examRouter) SetExamRouter(db *gorm.DB, router *gin.Engine) {
group := router.Group("/exam")
group.GET("", middleware.Auth(), r.controller.List)
group.GET("/:id", middleware.Auth(), r.controller.Find)
group.POST("", middleware.Auth(), r.controller.Create)
group.PUT("/:id", middleware.Auth(), r.controller.Update)
group.PATCH("/:id", middleware.Auth(), r.controller.Patch)
}

View File

@ -25,6 +25,7 @@ func Init() {
InitUserRouter(maindb, Router)
InitProgramRouter(maindb, Router)
InitQuizRouter(maindb, Router)
InitExamRouter(maindb, Router)
InitSwaggerRouter(Router)
}

56
internal/services/exam.go Normal file
View File

@ -0,0 +1,56 @@
package services
import (
"learnsteam/learsteam-quiz-api/internal/models"
"learnsteam/learsteam-quiz-api/internal/repositories"
)
type examService struct {
repository repositories.ExamRepository
}
type ExamService interface {
List(string, int, int) (*[]models.Exam, error)
Total(string) (int64, error)
Find(string) (*models.Exam, error)
Create(*models.Exam) (*models.Exam, error)
Update(*models.Exam) (*models.Exam, error)
Delete(string) error
}
func NewExamService(repository repositories.ExamRepository) ExamService {
return &examService{
repository: repository,
}
}
func (s *examService) List(q string, page int, limit int) (*[]models.Exam, error) {
return s.repository.List(q, page, limit)
}
func (s *examService) Total(q string) (int64, error) {
return s.repository.Total(q)
}
func (s *examService) Find(id string) (*models.Exam, error) {
return s.repository.Find(id)
}
func (s *examService) Create(exam *models.Exam) (*models.Exam, error) {
result, err := s.repository.Create(exam)
return result, err
}
func (s *examService) Update(exam *models.Exam) (*models.Exam, error) {
result, err := s.repository.Update(exam)
return result, err
}
func (s *examService) Delete(id string) error {
err := s.repository.Delete(id)
return err
}