diff --git a/docs/docs.go b/docs/docs.go
index 931199ff693e5055421c6601d9d533be163f6180..9e72b0b029a24d96014014b30d84b4ff9b06e6ad 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -1440,6 +1440,54 @@ const docTemplate = `{
                 }
             }
         },
+        "/course/{id}/quiz": {
+            "get": {
+                "description": "Get all cours",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "course"
+                ],
+                "summary": "Get Course quiz",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Course id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/web.BaseResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/quiz.Quiz"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
         "/material/{id}": {
             "get": {
                 "description": "Get material detail",
@@ -1645,6 +1693,51 @@ const docTemplate = `{
                 }
             }
         },
+        "/quiz/{id}": {
+            "get": {
+                "description": "Get Quiz Detail",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "quiz"
+                ],
+                "summary": "Get Quiz Detail",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Quiz id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/web.BaseResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "$ref": "#/definitions/quiz.Quiz"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
         "/reset/confirm": {
             "put": {
                 "description": "Do confirmation to reset password",
@@ -2156,6 +2249,23 @@ const docTemplate = `{
                 }
             }
         },
+        "quiz.Quiz": {
+            "type": "object",
+            "properties": {
+                "course_id": {
+                    "type": "string"
+                },
+                "creator_email": {
+                    "type": "string"
+                },
+                "id": {
+                    "type": "string"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "refresh.RefreshResponsePayload": {
             "description": "Refresh endpoint response when process success",
             "type": "object",
diff --git a/docs/swagger.json b/docs/swagger.json
index f9da30dc7f51afeb01e68dc5388c964419c1db75..07c6617ab34c4011a16323b020510a7289432e12 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -1432,6 +1432,54 @@
                 }
             }
         },
+        "/course/{id}/quiz": {
+            "get": {
+                "description": "Get all cours",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "course"
+                ],
+                "summary": "Get Course quiz",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Course id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/web.BaseResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "type": "array",
+                                            "items": {
+                                                "$ref": "#/definitions/quiz.Quiz"
+                                            }
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
         "/material/{id}": {
             "get": {
                 "description": "Get material detail",
@@ -1637,6 +1685,51 @@
                 }
             }
         },
+        "/quiz/{id}": {
+            "get": {
+                "description": "Get Quiz Detail",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "quiz"
+                ],
+                "summary": "Get Quiz Detail",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Quiz id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/web.BaseResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "$ref": "#/definitions/quiz.Quiz"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
         "/reset/confirm": {
             "put": {
                 "description": "Do confirmation to reset password",
@@ -2148,6 +2241,23 @@
                 }
             }
         },
+        "quiz.Quiz": {
+            "type": "object",
+            "properties": {
+                "course_id": {
+                    "type": "string"
+                },
+                "creator_email": {
+                    "type": "string"
+                },
+                "id": {
+                    "type": "string"
+                },
+                "name": {
+                    "type": "string"
+                }
+            }
+        },
         "refresh.RefreshResponsePayload": {
             "description": "Refresh endpoint response when process success",
             "type": "object",
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 0341f675c5fd29504631807c095716cdf5fb3c0b..ee7cc0f2bd3089513cd4d4688a70efda551cca03 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -298,6 +298,17 @@ definitions:
       upload_link:
         type: string
     type: object
+  quiz.Quiz:
+    properties:
+      course_id:
+        type: string
+      creator_email:
+        type: string
+      id:
+        type: string
+      name:
+        type: string
+    type: object
   refresh.RefreshResponsePayload:
     description: Refresh endpoint response when process success
     properties:
@@ -917,6 +928,35 @@ paths:
       summary: Get materials
       tags:
       - content
+  /course/{id}/quiz:
+    get:
+      consumes:
+      - application/json
+      description: Get all cours
+      parameters:
+      - description: Course id
+        format: uuid
+        in: path
+        name: id
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            allOf:
+            - $ref: '#/definitions/web.BaseResponse'
+            - properties:
+                data:
+                  items:
+                    $ref: '#/definitions/quiz.Quiz'
+                  type: array
+              type: object
+      summary: Get Course quiz
+      tags:
+      - course
   /course/faculty:
     get:
       description: Retrieves a list of all faculties
@@ -1438,6 +1478,33 @@ paths:
       summary: Delete Content
       tags:
       - content
+  /quiz/{id}:
+    get:
+      consumes:
+      - application/json
+      description: Get Quiz Detail
+      parameters:
+      - description: Quiz id
+        format: uuid
+        in: path
+        name: id
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            allOf:
+            - $ref: '#/definitions/web.BaseResponse'
+            - properties:
+                data:
+                  $ref: '#/definitions/quiz.Quiz'
+              type: object
+      summary: Get Quiz Detail
+      tags:
+      - quiz
   /reset/confirm:
     put:
       description: Do confirmation to reset password
diff --git a/handler/di.go b/handler/di.go
index 643a1fcfdc45a1bb37cd1e2e197932b5e320cb55..399ef81ecbb23c9d70b0431c6129610c92d5dadc 100644
--- a/handler/di.go
+++ b/handler/di.go
@@ -7,6 +7,7 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/handler/common"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/course"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/material"
+	"gitlab.informatika.org/ocw/ocw-backend/handler/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/reset"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/swagger"
 )
@@ -39,4 +40,8 @@ var HandlerSet = wire.NewSet(
 	// Material
 	wire.Struct(new(material.MaterialHandlerImpl), "*"),
 	wire.Bind(new(material.MaterialHandler), new(*material.MaterialHandlerImpl)),
+
+	// Quiz
+	wire.Struct(new(quiz.QuizHandlerImpl), "*"),
+	wire.Bind(new(quiz.QuizHandler), new(*quiz.QuizHandlerImpl)),
 )
diff --git a/handler/material/impl.go b/handler/material/impl.go
index 647ce941833b3c696b66271c41dd2565bb23a874..f8aab59ca45cb8ce12796599e6b197e1a0d8c418 100644
--- a/handler/material/impl.go
+++ b/handler/material/impl.go
@@ -12,7 +12,7 @@ type MaterialHandlerImpl struct {
 	material.MaterialService
 	material.MaterialContentService
 	httputil.HttpUtil
+	logger.Logger
 	wrapper.WrapperUtil
 	course.CourseRepository
-	logger.Logger
 }
diff --git a/handler/quiz/get.go b/handler/quiz/get.go
new file mode 100644
index 0000000000000000000000000000000000000000..799ca822a991240a0c6febccb29640720f1b5e67
--- /dev/null
+++ b/handler/quiz/get.go
@@ -0,0 +1,57 @@
+package quiz
+
+import (
+	"net/http"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+)
+
+// Index godoc
+//
+//	@Tags					quiz
+//	@Summary			Get Quiz Detail
+//	@Description	Get Quiz Detail
+//	@Produce			json
+//	@Accept				json
+//	@Param				id path string true "Quiz id" Format(uuid)
+//	@Success			200	{object}	web.BaseResponse{data=quiz.Quiz}
+//	@Router				/quiz/{id} [get]
+func (m QuizHandlerImpl) GetQuizDetail(w http.ResponseWriter, r *http.Request) {
+	quizId := chi.URLParam(r, "id")
+
+	if quizId == "" {
+		payload := m.WrapperUtil.ErrorResponseWrap("quiz id is required", nil)
+		m.HttpUtil.WriteJson(w, http.StatusUnsupportedMediaType, payload)
+		return
+	}
+
+	id, err := uuid.Parse(quizId)
+
+	if err != nil {
+		// invalid uuid
+		payload := m.WrapperUtil.ErrorResponseWrap(err.Error(), nil)
+		m.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	result, err := m.QuizService.GetQuizDetail(id)
+
+	if err != nil {
+		respErr, ok := err.(web.ResponseError)
+		if ok {
+			payload := m.WrapperUtil.ErrorResponseWrap(respErr.Error(), respErr)
+
+			m.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		} else {
+			payload := m.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+			m.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		}
+		return
+	}
+
+	responsePayload := m.WrapperUtil.SuccessResponseWrap(result)
+	m.HttpUtil.WriteSuccessJson(w, responsePayload)
+
+}
diff --git a/handler/quiz/impl.go b/handler/quiz/impl.go
new file mode 100644
index 0000000000000000000000000000000000000000..f95f7e5f0ca56fe2c605c5c3692eb5c4dab1008a
--- /dev/null
+++ b/handler/quiz/impl.go
@@ -0,0 +1,15 @@
+package quiz
+
+import (
+	"gitlab.informatika.org/ocw/ocw-backend/service/logger"
+	"gitlab.informatika.org/ocw/ocw-backend/service/quiz"
+	"gitlab.informatika.org/ocw/ocw-backend/utils/httputil"
+	"gitlab.informatika.org/ocw/ocw-backend/utils/wrapper"
+)
+
+type QuizHandlerImpl struct {
+	quiz.QuizService
+	wrapper.WrapperUtil
+	httputil.HttpUtil
+	logger.Logger
+}
diff --git a/handler/quiz/list.go b/handler/quiz/list.go
new file mode 100644
index 0000000000000000000000000000000000000000..544894fcc9985ee8ebea4f75fd3032da1ff0fd2d
--- /dev/null
+++ b/handler/quiz/list.go
@@ -0,0 +1,50 @@
+package quiz
+
+import (
+	"net/http"
+
+	"github.com/go-chi/chi/v5"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+)
+
+// Index godoc
+//
+//	@Tags					course
+//	@Summary			Get Course quiz
+//	@Description	Get all cours
+//	@Produce			json
+//	@Accept				json
+//	@Param				id path string true "Course id" Format(uuid)
+//	@Success			200	{object}	web.BaseResponse{data=[]quiz.Quiz}
+//	@Router				/course/{id}/quiz [get]
+func (m QuizHandlerImpl) GetAllQuizes(w http.ResponseWriter, r *http.Request) {
+	courseId := chi.URLParam(r, "id")
+
+	if courseId == "" {
+		payload := m.WrapperUtil.ErrorResponseWrap("course id is required", nil)
+		m.HttpUtil.WriteJson(w, http.StatusUnsupportedMediaType, payload)
+		return
+	}
+
+	result, err := m.QuizService.ListAllQuiz(courseId)
+
+	if err != nil {
+		respErr, ok := err.(web.ResponseError)
+		if ok {
+			payload := m.WrapperUtil.ErrorResponseWrap(respErr.Error(), respErr)
+
+			if respErr.Code != "NOT_OWNER" {
+				m.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+			} else {
+				m.HttpUtil.WriteJson(w, http.StatusForbidden, payload)
+			}
+		} else {
+			payload := m.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+			m.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		}
+		return
+	}
+
+	responsePayload := m.WrapperUtil.SuccessResponseWrap(result)
+	m.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
diff --git a/handler/quiz/type.go b/handler/quiz/type.go
new file mode 100644
index 0000000000000000000000000000000000000000..2c9d3e03d76b678496942f6101f39a27b074d2a3
--- /dev/null
+++ b/handler/quiz/type.go
@@ -0,0 +1,8 @@
+package quiz
+
+import "net/http"
+
+type QuizHandler interface {
+	GetAllQuizes(w http.ResponseWriter, r *http.Request)
+	GetQuizDetail(w http.ResponseWriter, r *http.Request)
+}
diff --git a/model/domain/quiz/answer.go b/model/domain/quiz/answer.go
new file mode 100644
index 0000000000000000000000000000000000000000..477b2039d253b51934420202f7e1c34adbb23dac
--- /dev/null
+++ b/model/domain/quiz/answer.go
@@ -0,0 +1,8 @@
+package quiz
+
+import "github.com/google/uuid"
+
+type Answer struct {
+	QuestionId uuid.UUID
+	OptionId   uuid.UUID
+}
diff --git a/model/domain/quiz/option.go b/model/domain/quiz/option.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f3af1fb082860285b9d141abb98245fe0d723f8
--- /dev/null
+++ b/model/domain/quiz/option.go
@@ -0,0 +1,9 @@
+package quiz
+
+import "github.com/google/uuid"
+
+type Option struct {
+	Id       uuid.UUID `json:"id"`
+	Text     string    `json:"text"`
+	IsAnswer bool      `json:"is_answer"`
+}
diff --git a/model/domain/quiz/options.go b/model/domain/quiz/options.go
deleted file mode 100644
index d2bdddbf7da440ce8b48385cd7a5d5b0f118bcef..0000000000000000000000000000000000000000
--- a/model/domain/quiz/options.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package quiz
-
-import "github.com/google/uuid"
-
-type AnswerOption struct {
-	Id            uuid.UUID `gorm:"primaryKey" json:"id"`
-	QuizProblemId uuid.UUID `gorm:"primaryKey" json:"problem_id"`
-	Statement     string    `json:"statement"`
-	IsAnswer      bool      `json:"isAnswer"`
-}
-
-func (AnswerOption) TableName() string {
-	return "quiz_choice_answer"
-}
diff --git a/model/domain/quiz/problem_type.go b/model/domain/quiz/problem_type.go
deleted file mode 100644
index c03621526c635dc524f1caee1518665931b80d10..0000000000000000000000000000000000000000
--- a/model/domain/quiz/problem_type.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package quiz
-
-import (
-	"database/sql/driver"
-	"encoding/json"
-	"errors"
-	"fmt"
-)
-
-type ProblemType int
-
-const (
-	Choice ProblemType = iota
-)
-
-var roleMapping = map[ProblemType]string{
-	Choice: "choice",
-}
-
-func (ur *ProblemType) Scan(value interface{}) error {
-	val := value.(string)
-
-	for key, label := range roleMapping {
-		if label == val {
-			*ur = key
-			return nil
-		}
-	}
-
-	return fmt.Errorf("invalid user role")
-}
-
-func (u ProblemType) Value() (driver.Value, error) {
-	value, ok := roleMapping[u]
-
-	if !ok {
-		return nil, fmt.Errorf("invalid user role")
-	}
-
-	return value, nil
-}
-
-func (u *ProblemType) UnmarshalJSON(b []byte) error {
-	var s string
-	if err := json.Unmarshal(b, &s); err != nil {
-		return err
-	}
-
-	for key, label := range roleMapping {
-		if label == s {
-			*u = key
-			return nil
-		}
-	}
-
-	return fmt.Errorf("unkown role, given %s", s)
-}
-
-func (u ProblemType) MarshalJSON() ([]byte, error) {
-	s, ok := roleMapping[u]
-
-	if !ok {
-		return nil, errors.New("unkown user role")
-	}
-
-	return json.Marshal(s)
-}
diff --git a/model/domain/quiz/question.go b/model/domain/quiz/question.go
new file mode 100644
index 0000000000000000000000000000000000000000..d8b5fdfea2ca012266489b05e2ced985cbdb75d2
--- /dev/null
+++ b/model/domain/quiz/question.go
@@ -0,0 +1,9 @@
+package quiz
+
+import "github.com/google/uuid"
+
+type Question struct {
+	Id          uuid.UUID `json:"id"`
+	Description string    `json:"string"`
+	Options     []Option  `json:"options"`
+}
diff --git a/model/domain/quiz/quiz.go b/model/domain/quiz/quiz.go
index f4dcce5a8155d1c0a670dd962bd549233d95b2d8..1300dbc89fddcec83976bbaa726125d1e7a13e86 100644
--- a/model/domain/quiz/quiz.go
+++ b/model/domain/quiz/quiz.go
@@ -2,18 +2,14 @@ package quiz
 
 import (
 	"github.com/google/uuid"
-	"gitlab.informatika.org/ocw/ocw-backend/model/domain/course"
-	"gitlab.informatika.org/ocw/ocw-backend/model/domain/user"
 )
 
 type Quiz struct {
-	Id           uuid.UUID     `gorm:"primaryKey" json:"id"`
-	Name         string        `json:"name"`
-	CourseId     string        `json:"course_id"`
-	CreatorEmail string        `json:"creator_email"`
-	Creator      user.User     `gorm:"foreignKey:CreatorEmail;references:Email" json:"creator"`
-	Course       course.Course `gorm:"foreignKey:CourseId;references:Id" json:"course"`
-	Problems     []QuizProblem `gorm:"foreignKey:QuizId;references:Id" json:"problems"`
+	Id           uuid.UUID `gorm:"primaryKey" json:"id"`
+	Name         string    `json:"name"`
+	CourseId     string    `json:"course_id"`
+	CreatorEmail string    `json:"creator_email"`
+	QuizPath     string    `json:"-"`
 }
 
 func (Quiz) TableName() string {
diff --git a/model/domain/quiz/quiz_problem.go b/model/domain/quiz/quiz_problem.go
deleted file mode 100644
index 1bcdcf880ad9eaeeadd164cf60d253fd9eedb8db..0000000000000000000000000000000000000000
--- a/model/domain/quiz/quiz_problem.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package quiz
-
-import "github.com/google/uuid"
-
-type QuizProblem struct {
-	Id        uuid.UUID      `gorm:"primaryKey" json:"id"`
-	Statement string         `json:"statement"`
-	Type      ProblemType    `json:"type"`
-	QuizId    uuid.UUID      `json:"quiz_id"`
-	Options   []AnswerOption `gorm:"foreignKey:QuizProblemId;references:Id" json:"options"`
-}
-
-func (QuizProblem) TableName() string {
-	return "quiz_problem"
-}
diff --git a/model/domain/quiz/take.go b/model/domain/quiz/take.go
index 2c707ab601da28e630420015393607aef0f9d228..399989d2db63432372643f615caecafee0cbc896 100644
--- a/model/domain/quiz/take.go
+++ b/model/domain/quiz/take.go
@@ -1,22 +1,18 @@
 package quiz
 
 import (
-	"os/user"
 	"time"
 
 	"github.com/google/uuid"
 )
 
 type QuizTake struct {
-	Id            uuid.UUID `gorm:"primaryKey" json:"id"`
-	QuizId        uuid.UUID `json:"quiz_id"`
-	Email         string    `json:"email"`
-	StartTime     time.Time `json:"start"`
-	IsFinished    bool      `json:"finished"`
-	Score         int       `json:"score"`
-	Quiz          `gorm:"foreignKey:QuizId;references:Id" json:"quiz"`
-	user.User     `gorm:"foreignKey:Email;references:Email" json:"user"`
-	ChoiceAnswers []TakeChoiceAnswer `gorm:"foreignKey:QuizTakeId;references:Id" json:"-"`
+	Id         uuid.UUID `gorm:"primaryKey" json:"id"`
+	QuizId     uuid.UUID `json:"quiz_id"`
+	Email      string    `json:"email"`
+	StartTime  time.Time `json:"start"`
+	IsFinished bool      `json:"finished"`
+	Score      int       `json:"score"`
 }
 
 func (QuizTake) TableName() string {
diff --git a/model/domain/quiz/take_choice_answer.go b/model/domain/quiz/take_choice_answer.go
deleted file mode 100644
index 25e76746d8951251d3dbdee694986205ce364d53..0000000000000000000000000000000000000000
--- a/model/domain/quiz/take_choice_answer.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package quiz
-
-import "github.com/google/uuid"
-
-type TakeChoiceAnswer struct {
-	QuizTakeId    uuid.UUID `gorm:"primaryKey"`
-	AnswerChoice  uuid.UUID
-	QuizProblemId uuid.UUID `gorm:"primaryKey"`
-	AnswerOption  `gorm:"foreignKey:AnswerChoice,QuizProblemId;references:Id,QuizProblemId"`
-}
-
-func (TakeChoiceAnswer) TableName() string {
-	return "quiz_take_choice_answer"
-}
diff --git a/repository/di.go b/repository/di.go
index 9136c031788ba4f56d8d3bfe4c46f2864b641571..b564bd5406f7d94427c5c0f80ccc518bc23fd5b2 100644
--- a/repository/di.go
+++ b/repository/di.go
@@ -2,12 +2,13 @@ package repository
 
 import (
 	"github.com/google/wire"
-	"gitlab.informatika.org/ocw/ocw-backend/repository/user"
-	"gitlab.informatika.org/ocw/ocw-backend/repository/course"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/cache"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/content"
+	"gitlab.informatika.org/ocw/ocw-backend/repository/course"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/material"
+	"gitlab.informatika.org/ocw/ocw-backend/repository/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/transaction"
+	"gitlab.informatika.org/ocw/ocw-backend/repository/user"
 )
 
 var RepositoryBasicSet = wire.NewSet(
@@ -37,6 +38,9 @@ var RepositoryBasicSet = wire.NewSet(
 	transaction.NewBuilder,
 	wire.Bind(new(transaction.Transaction), new(*transaction.TransactionRepositoryImpl)),
 	wire.Bind(new(transaction.TransactionBuilder), new(*transaction.TransactionBuilderImpl)),
+
+	quiz.New,
+	wire.Bind(new(quiz.QuizRepository), new(*quiz.QuizRepositoryImpl)),
 )
 
 var RepositorySet = wire.NewSet(
diff --git a/repository/quiz/impl.go b/repository/quiz/impl.go
new file mode 100644
index 0000000000000000000000000000000000000000..03665df4d4915b3c188da6e737bed27e7dc1582d
--- /dev/null
+++ b/repository/quiz/impl.go
@@ -0,0 +1,88 @@
+package quiz
+
+import (
+	"errors"
+	"time"
+
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/quiz"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/provider/db"
+	"gorm.io/gorm"
+)
+
+type QuizRepositoryImpl struct {
+	db *gorm.DB
+}
+
+func New(
+	db db.Database,
+) *QuizRepositoryImpl {
+	return &QuizRepositoryImpl{db.Connect()}
+}
+
+func (q *QuizRepositoryImpl) GetQuizes(courseId string) ([]quiz.Quiz, error) {
+	result := &[]quiz.Quiz{}
+	err := q.db.Where("course_id = ?", courseId).Find(result).Error
+
+	return *result, err
+}
+
+func (q *QuizRepositoryImpl) GetQuizDetail(quizId uuid.UUID) (*quiz.Quiz, error) {
+	result := &quiz.Quiz{}
+	err := q.db.Where("id = ?", quizId).First(result).Error
+
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		return nil, web.NewResponseError("Record not found", "ERR_NOT_FOUND")
+	}
+
+	return result, nil
+}
+
+func (q *QuizRepositoryImpl) UpdateScore(takeId uuid.UUID, score int) error {
+	return q.db.
+		Model(&quiz.QuizTake{}).
+		Update("score", score).
+		Update("is_finished", true).
+		Where("id = ?", takeId).Error
+}
+
+func (q *QuizRepositoryImpl) NewTake(quizId uuid.UUID, userEmail string) (uuid.UUID, error) {
+	id := uuid.New()
+	err := q.db.Create(
+		&quiz.QuizTake{
+			Id:         id,
+			Email:      userEmail,
+			StartTime:  time.Now(),
+			QuizId:     quizId,
+			IsFinished: false,
+			Score:      0,
+		},
+	).Error
+
+	return id, err
+}
+
+func (q *QuizRepositoryImpl) IsActiveTake(quizId uuid.UUID, userEmail string) (bool, error) {
+	result := struct{ cnt int }{}
+	err := q.db.
+		Select("COUNT(*) as cnt").
+		Where("quiz_id = ? AND email = ? AND is_finished = false", quizId, userEmail).
+		Find(result).
+		Error
+
+	if err != nil {
+		return false, nil
+	}
+
+	return result.cnt > 0, nil
+}
+
+func (q *QuizRepositoryImpl) GetAllTake(quizId uuid.UUID, userEmail string) ([]quiz.QuizTake, error) {
+	result := []quiz.QuizTake{}
+	err := q.db.
+		Where("quiz_id = ? AND email = ?", quizId, userEmail).
+		Find(result).Error
+
+	return result, err
+}
diff --git a/repository/quiz/type.go b/repository/quiz/type.go
new file mode 100644
index 0000000000000000000000000000000000000000..0fc33d4d153ff2f8eabaea5cc9b44be16be724e7
--- /dev/null
+++ b/repository/quiz/type.go
@@ -0,0 +1,15 @@
+package quiz
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/quiz"
+)
+
+type QuizRepository interface {
+	GetQuizes(courseId string) ([]quiz.Quiz, error)
+	GetQuizDetail(quizId uuid.UUID) (*quiz.Quiz, error)
+	UpdateScore(takeId uuid.UUID, score int) error
+	NewTake(quizId uuid.UUID, userEmail string) (uuid.UUID, error)
+	IsActiveTake(quizId uuid.UUID, userEmail string) (bool, error)
+	GetAllTake(quizId uuid.UUID, userEmail string) ([]quiz.QuizTake, error)
+}
diff --git a/routes/di.go b/routes/di.go
index e05148661337dd26d5400800ca389644f93aa3be..ddae40f95c5cde473aadc4f6d26a357c98b5f089 100644
--- a/routes/di.go
+++ b/routes/di.go
@@ -7,6 +7,7 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/routes/common"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/course"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/material"
+	"gitlab.informatika.org/ocw/ocw-backend/routes/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/reset"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/swagger"
 )
@@ -19,6 +20,7 @@ var routesCollectionSet = wire.NewSet(
 	wire.Struct(new(reset.ResetRoutes), "*"),
 	wire.Struct(new(course.CourseRoutes), "*"),
 	wire.Struct(new(material.MaterialRoutes), "*"),
+	wire.Struct(new(quiz.QuizRoutes), "*"),
 )
 
 var RoutesSet = wire.NewSet(
diff --git a/routes/quiz/route.go b/routes/quiz/route.go
new file mode 100644
index 0000000000000000000000000000000000000000..58dbb0deb323c33a1138db79b8692b79aad0c5c0
--- /dev/null
+++ b/routes/quiz/route.go
@@ -0,0 +1,15 @@
+package quiz
+
+import (
+	"github.com/go-chi/chi/v5"
+	"gitlab.informatika.org/ocw/ocw-backend/handler/quiz"
+)
+
+type QuizRoutes struct {
+	quiz.QuizHandler
+}
+
+func (q QuizRoutes) Register(r chi.Router) {
+	r.Get("/course/{id}/quiz", q.QuizHandler.GetAllQuizes)
+	r.Get("/quiz/{id}", q.QuizHandler.GetQuizDetail)
+}
diff --git a/routes/routes.go b/routes/routes.go
index 63e1d79fb448d35384bc6f062d360cdb2a7a258f..096f4d5005e2bfe01f82bfe53552edc99b1d0258 100644
--- a/routes/routes.go
+++ b/routes/routes.go
@@ -6,6 +6,7 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/routes/common"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/course"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/material"
+	"gitlab.informatika.org/ocw/ocw-backend/routes/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/reset"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/swagger"
 
@@ -19,6 +20,7 @@ type AppRouter struct {
 	common.CommonRoutes
 	auth.AuthRoutes
 	reset.ResetRoutes
+	quiz.QuizRoutes
 	course.CourseRoutes
 	material.MaterialRoutes
 
diff --git a/service/di.go b/service/di.go
index 6cdb051667f746ccdc3ff0244fd29bdf19f69561..3a133f5fc0ccdaba5c7260c52fa6a068306cf8a2 100644
--- a/service/di.go
+++ b/service/di.go
@@ -5,13 +5,14 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/service/admin"
 	"gitlab.informatika.org/ocw/ocw-backend/service/auth"
 	"gitlab.informatika.org/ocw/ocw-backend/service/common"
+	"gitlab.informatika.org/ocw/ocw-backend/service/course"
 	"gitlab.informatika.org/ocw/ocw-backend/service/logger"
 	"gitlab.informatika.org/ocw/ocw-backend/service/logger/hooks"
 	"gitlab.informatika.org/ocw/ocw-backend/service/material"
+	"gitlab.informatika.org/ocw/ocw-backend/service/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/service/reporter"
 	"gitlab.informatika.org/ocw/ocw-backend/service/reset"
 	"gitlab.informatika.org/ocw/ocw-backend/service/verification"
-	"gitlab.informatika.org/ocw/ocw-backend/service/course"
 )
 
 var ServiceTestSet = wire.NewSet(
@@ -64,6 +65,12 @@ var ServiceTestSet = wire.NewSet(
 		wire.Bind(new(material.MaterialContentService), new(*material.MaterialContentServiceImpl)),
 		wire.Bind(new(material.MaterialService), new(*material.MaterialServiceImpl)),
 	),
+
+	// Quiz service
+	wire.NewSet(
+		wire.Struct(new(quiz.QuizServiceImpl), "*"),
+		wire.Bind(new(quiz.QuizService), new(*quiz.QuizServiceImpl)),
+	),
 )
 
 var ServiceSet = wire.NewSet(
diff --git a/service/quiz/impl.go b/service/quiz/impl.go
new file mode 100644
index 0000000000000000000000000000000000000000..5bf6171e4d6fd4535810463b454f7bae90b93c9c
--- /dev/null
+++ b/service/quiz/impl.go
@@ -0,0 +1,19 @@
+package quiz
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/quiz"
+	quizRepo "gitlab.informatika.org/ocw/ocw-backend/repository/quiz"
+)
+
+type QuizServiceImpl struct {
+	quizRepo.QuizRepository
+}
+
+func (q QuizServiceImpl) ListAllQuiz(courseId string) ([]quiz.Quiz, error) {
+	return q.QuizRepository.GetQuizes(courseId)
+}
+
+func (q QuizServiceImpl) GetQuizDetail(quizId uuid.UUID) (*quiz.Quiz, error) {
+	return q.QuizRepository.GetQuizDetail(quizId)
+}
diff --git a/service/quiz/type.go b/service/quiz/type.go
new file mode 100644
index 0000000000000000000000000000000000000000..f7d0f72eb3a7a148c1e324a5ff800f99d38f5304
--- /dev/null
+++ b/service/quiz/type.go
@@ -0,0 +1,11 @@
+package quiz
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/quiz"
+)
+
+type QuizService interface {
+	ListAllQuiz(courseId string) ([]quiz.Quiz, error)
+	GetQuizDetail(quizId uuid.UUID) (*quiz.Quiz, error)
+}