From f77f6c10c95433039269d9777ebb599fc3abac7b Mon Sep 17 00:00:00 2001
From: nart4hire <nart4hire@gmail.com>
Date: Wed, 26 Apr 2023 16:44:21 +0700
Subject: [PATCH] feat(lesson): added all routes

---
 docs/docs.go                                 | 981 +++++++++++++++----
 docs/swagger.json                            | 670 ++++++++++++-
 docs/swagger.yaml                            | 456 ++++++++-
 handler/di.go                                |   5 +
 handler/lesson/addLesson.go                  | 100 ++
 handler/lesson/addLessonMaterial.go          | 102 ++
 handler/lesson/deleteLesson.go               |  84 ++
 handler/lesson/deleteLessonMaterial.go       |  85 ++
 handler/lesson/getLesson.go                  |  55 ++
 handler/lesson/getLessonMaterial.go          |  55 ++
 handler/lesson/getLessonMaterialsByLesson.go |  55 ++
 handler/lesson/getLessonsByCourse.go         |  47 +
 handler/lesson/handler.go                    |  17 +
 handler/lesson/types.go                      |  23 +
 handler/lesson/updateLesson.go               | 114 +++
 handler/lesson/updateLessonMaterial.go       | 114 +++
 model/domain/course/course.go                |   4 +-
 model/domain/lesson/lesson.go                |  34 +
 model/web/course/faculty/request.go          |   2 +-
 model/web/course/major/request.go            |   2 +-
 model/web/course/request.go                  |   8 +-
 model/web/error_code.go                      |  22 +-
 model/web/lesson/materials/request.go        |  63 ++
 model/web/lesson/request.go                  |  68 ++
 repository/di.go                             |   8 +
 repository/lesson/lesson.go                  |  52 +
 repository/lesson/materials.go               |  52 +
 repository/lesson/type.go                    |  22 +
 routes/di.go                                 |   2 +
 routes/lesson/route.go                       |  28 +
 routes/routes.go                             |   2 +
 service/di.go                                |   7 +
 service/lesson/add.go                        |  68 ++
 service/lesson/delete.go                     |  57 ++
 service/lesson/get.go                        |  67 ++
 service/lesson/impl.go                       |  16 +
 service/lesson/type.go                       |  20 +
 service/lesson/update.go                     |  79 ++
 38 files changed, 3440 insertions(+), 206 deletions(-)
 create mode 100644 handler/lesson/addLesson.go
 create mode 100644 handler/lesson/addLessonMaterial.go
 create mode 100644 handler/lesson/deleteLesson.go
 create mode 100644 handler/lesson/deleteLessonMaterial.go
 create mode 100644 handler/lesson/getLesson.go
 create mode 100644 handler/lesson/getLessonMaterial.go
 create mode 100644 handler/lesson/getLessonMaterialsByLesson.go
 create mode 100644 handler/lesson/getLessonsByCourse.go
 create mode 100644 handler/lesson/handler.go
 create mode 100644 handler/lesson/types.go
 create mode 100644 handler/lesson/updateLesson.go
 create mode 100644 handler/lesson/updateLessonMaterial.go
 create mode 100644 model/domain/lesson/lesson.go
 create mode 100644 model/web/lesson/materials/request.go
 create mode 100644 model/web/lesson/request.go
 create mode 100644 repository/lesson/lesson.go
 create mode 100644 repository/lesson/materials.go
 create mode 100644 repository/lesson/type.go
 create mode 100644 routes/lesson/route.go
 create mode 100644 service/lesson/add.go
 create mode 100644 service/lesson/delete.go
 create mode 100644 service/lesson/get.go
 create mode 100644 service/lesson/impl.go
 create mode 100644 service/lesson/type.go
 create mode 100644 service/lesson/update.go

diff --git a/docs/docs.go b/docs/docs.go
index 49b75f3..98c0da8 100644
--- a/docs/docs.go
+++ b/docs/docs.go
@@ -1,4 +1,5 @@
-// Code generated by swaggo/swag. DO NOT EDIT
+// Code generated by swaggo/swag. DO NOT EDIT.
+
 package docs
 
 import "github.com/swaggo/swag"
@@ -1488,52 +1489,9 @@ const docTemplate = `{
                 }
             }
         },
-        "/material/{id}": {
-            "get": {
-                "description": "Get material detail",
-                "consumes": [
-                    "application/json"
-                ],
-                "produces": [
-                    "application/json"
-                ],
-                "tags": [
-                    "content"
-                ],
-                "summary": "Get material detail",
-                "parameters": [
-                    {
-                        "type": "string",
-                        "example": "IF3270",
-                        "description": "Material id",
-                        "name": "id",
-                        "in": "path",
-                        "required": true
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "description": "OK",
-                        "schema": {
-                            "allOf": [
-                                {
-                                    "$ref": "#/definitions/web.BaseResponse"
-                                },
-                                {
-                                    "type": "object",
-                                    "properties": {
-                                        "data": {
-                                            "$ref": "#/definitions/material.Material"
-                                        }
-                                    }
-                                }
-                            ]
-                        }
-                    }
-                }
-            },
-            "post": {
-                "description": "Add content of material",
+        "/lesson": {
+            "put": {
+                "description": "Add a new lesson with the given details",
                 "consumes": [
                     "application/json"
                 ],
@@ -1541,52 +1499,32 @@ const docTemplate = `{
                     "application/json"
                 ],
                 "tags": [
-                    "content"
+                    "lesson"
                 ],
-                "summary": "Add Content",
+                "summary": "Add a new lesson",
                 "parameters": [
                     {
                         "type": "string",
-                        "description": "Access token",
+                        "description": "AddLessonToken",
                         "name": "Authorization",
                         "in": "header",
                         "required": true
                     },
                     {
-                        "description": "Add content request",
+                        "description": "Add Lesson payload",
                         "name": "data",
                         "in": "body",
                         "required": true,
                         "schema": {
-                            "$ref": "#/definitions/material.NewContentRequest"
+                            "$ref": "#/definitions/lesson.AddLessonRequestPayload"
                         }
-                    },
-                    {
-                        "type": "string",
-                        "format": "uuid",
-                        "description": "Material id",
-                        "name": "id",
-                        "in": "path",
-                        "required": true
                     }
                 ],
                 "responses": {
                     "200": {
-                        "description": "OK",
+                        "description": "Success",
                         "schema": {
-                            "allOf": [
-                                {
-                                    "$ref": "#/definitions/web.BaseResponse"
-                                },
-                                {
-                                    "type": "object",
-                                    "properties": {
-                                        "data": {
-                                            "$ref": "#/definitions/material.NewContentResponse"
-                                        }
-                                    }
-                                }
-                            ]
+                            "$ref": "#/definitions/web.BaseResponse"
                         }
                     },
                     "400": {
@@ -1600,33 +1538,42 @@ const docTemplate = `{
                         "schema": {
                             "$ref": "#/definitions/web.BaseResponse"
                         }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
                     }
                 }
-            },
-            "delete": {
-                "description": "Delete material",
-                "consumes": [
-                    "application/json"
-                ],
+            }
+        },
+        "/lesson/course/{id}": {
+            "get": {
+                "description": "Retrieve lesson data by course ID",
                 "produces": [
                     "application/json"
                 ],
                 "tags": [
-                    "content"
+                    "lesson"
                 ],
-                "summary": "Delete material",
+                "summary": "Get lesson by course ID",
                 "parameters": [
                     {
                         "type": "string",
-                        "description": "Access token",
-                        "name": "Authorization",
-                        "in": "header",
-                        "required": true
-                    },
-                    {
-                        "type": "string",
-                        "format": "uuid",
-                        "description": "Material id",
+                        "description": "Course ID",
                         "name": "id",
                         "in": "path",
                         "required": true
@@ -1634,7 +1581,25 @@ const docTemplate = `{
                 ],
                 "responses": {
                     "200": {
-                        "description": "OK",
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid ID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
                         "schema": {
                             "$ref": "#/definitions/web.BaseResponse"
                         }
@@ -1642,9 +1607,9 @@ const docTemplate = `{
                 }
             }
         },
-        "/material/{id}/content/{content-id}": {
-            "delete": {
-                "description": "Delete content of material",
+        "/lesson/material": {
+            "put": {
+                "description": "Add a new lesson material with the given details",
                 "consumes": [
                     "application/json"
                 ],
@@ -1652,37 +1617,60 @@ const docTemplate = `{
                     "application/json"
                 ],
                 "tags": [
-                    "content"
+                    "lesson"
                 ],
-                "summary": "Delete Content",
+                "summary": "Add a new lesson material",
                 "parameters": [
                     {
                         "type": "string",
-                        "description": "Access token",
+                        "description": "AddLessonMaterialsToken",
                         "name": "Authorization",
                         "in": "header",
                         "required": true
                     },
                     {
-                        "type": "string",
-                        "format": "uuid",
-                        "description": "Material id",
-                        "name": "id",
-                        "in": "path",
-                        "required": true
-                    },
-                    {
-                        "type": "string",
-                        "format": "uuid",
-                        "description": "Content id",
-                        "name": "content-id",
-                        "in": "path",
-                        "required": true
+                        "description": "Add Lesson Material payload",
+                        "name": "data",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/materials.AddLessonMaterialsRequestPayload"
+                        }
                     }
                 ],
                 "responses": {
                     "200": {
-                        "description": "OK",
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
                         "schema": {
                             "$ref": "#/definitions/web.BaseResponse"
                         }
@@ -1690,24 +1678,20 @@ const docTemplate = `{
                 }
             }
         },
-        "/quiz/{id}": {
+        "/lesson/material/lesson/{id}": {
             "get": {
-                "description": "Get Quiz Detail",
-                "consumes": [
-                    "application/json"
-                ],
+                "description": "Retrieve lesson materials data by lesson ID",
                 "produces": [
                     "application/json"
                 ],
                 "tags": [
-                    "quiz"
+                    "lesson"
                 ],
-                "summary": "Get Quiz Detail",
+                "summary": "Get lesson materials by lesson ID",
                 "parameters": [
                     {
                         "type": "string",
-                        "format": "uuid",
-                        "description": "Quiz id",
+                        "description": "Lesson ID (UUID)",
                         "name": "id",
                         "in": "path",
                         "required": true
@@ -1715,51 +1699,46 @@ const docTemplate = `{
                 ],
                 "responses": {
                     "200": {
-                        "description": "OK",
+                        "description": "Success",
                         "schema": {
-                            "allOf": [
-                                {
-                                    "$ref": "#/definitions/web.BaseResponse"
-                                },
-                                {
-                                    "type": "object",
-                                    "properties": {
-                                        "data": {
-                                            "$ref": "#/definitions/quiz.Quiz"
-                                        }
-                                    }
-                                }
-                            ]
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid UUID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
                         }
                     }
                 }
             }
         },
-        "/quiz/{id}/solution": {
+        "/lesson/material/{id}": {
             "get": {
-                "description": "Take a quiz",
-                "consumes": [
-                    "application/json"
-                ],
+                "description": "Retrieve lesson data by UUID",
                 "produces": [
                     "application/json"
                 ],
                 "tags": [
-                    "quiz"
+                    "lesson"
                 ],
-                "summary": "Get Quiz Solution",
+                "summary": "Get lesson by ID",
                 "parameters": [
                     {
                         "type": "string",
-                        "description": "Authenticate User (any role)",
-                        "name": "Authorization",
-                        "in": "header",
-                        "required": true
-                    },
-                    {
-                        "type": "string",
-                        "format": "uuid",
-                        "description": "Quiz id",
+                        "description": "Lesson ID (UUID)",
                         "name": "id",
                         "in": "path",
                         "required": true
@@ -1767,10 +1746,566 @@ const docTemplate = `{
                 ],
                 "responses": {
                     "200": {
-                        "description": "OK",
+                        "description": "Success",
                         "schema": {
-                            "allOf": [
-                                {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid UUID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "delete": {
+                "description": "Delete a lesson material with the specified ID",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Delete lesson material by id",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson Material ID",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "description": "DeleteLessonMaterialToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/lesson/{id}": {
+            "get": {
+                "description": "Retrieve lesson data by UUID",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Get lesson by ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson ID (UUID)",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid UUID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "delete": {
+                "description": "Delete a lesson with the specified ID",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Delete lesson by ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson ID",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "description": "DeleteLessonToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "patch": {
+                "description": "Update a lesson material with the given ID",
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Update a lesson material",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson Material ID (UUID)",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "description": "Update Lesson Materials Payload",
+                        "name": "payload",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/materials.UpdateLessonMaterialsRequestPayload"
+                        }
+                    },
+                    {
+                        "type": "string",
+                        "description": "UpdateLessonMaterialsToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/material/{id}": {
+            "get": {
+                "description": "Get material detail",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "content"
+                ],
+                "summary": "Get material detail",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "example": "IF3270",
+                        "description": "Material id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/web.BaseResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "$ref": "#/definitions/material.Material"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            },
+            "post": {
+                "description": "Add content of material",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "content"
+                ],
+                "summary": "Add Content",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Access token",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    },
+                    {
+                        "description": "Add content request",
+                        "name": "data",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/material.NewContentRequest"
+                        }
+                    },
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Material id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
+                                    "$ref": "#/definitions/web.BaseResponse"
+                                },
+                                {
+                                    "type": "object",
+                                    "properties": {
+                                        "data": {
+                                            "$ref": "#/definitions/material.NewContentResponse"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "delete": {
+                "description": "Delete material",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "content"
+                ],
+                "summary": "Delete material",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Access token",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Material id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/material/{id}/content/{content-id}": {
+            "delete": {
+                "description": "Delete content of material",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "content"
+                ],
+                "summary": "Delete Content",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Access token",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Material id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Content id",
+                        "name": "content-id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/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"
+                                        }
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+        },
+        "/quiz/{id}/solution": {
+            "get": {
+                "description": "Take a quiz",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "quiz"
+                ],
+                "summary": "Get Quiz Solution",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Authenticate User (any role)",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "format": "uuid",
+                        "description": "Quiz id",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "OK",
+                        "schema": {
+                            "allOf": [
+                                {
                                     "$ref": "#/definitions/web.BaseResponse"
                                 },
                                 {
@@ -2090,10 +2625,6 @@ const docTemplate = `{
                     "type": "string",
                     "example": "someone@example.com"
                 },
-                "id": {
-                    "description": "Course ID, Provided by query",
-                    "type": "string"
-                },
                 "lecturer": {
                     "description": "Course Lecturer",
                     "type": "string"
@@ -2150,10 +2681,6 @@ const docTemplate = `{
                     "description": "Faculty Name Abbreviation",
                     "type": "string"
                 },
-                "id": {
-                    "description": "Faculty ID, Provided by Query",
-                    "type": "string"
-                },
                 "name": {
                     "description": "Faculty Name",
                     "type": "string"
@@ -2164,6 +2691,68 @@ const docTemplate = `{
                 }
             }
         },
+        "lesson.AddLessonRequestPayload": {
+            "description": "Information that should be available when you add a lesson",
+            "type": "object",
+            "required": [
+                "course_id",
+                "name",
+                "order"
+            ],
+            "properties": {
+                "addLessonToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                },
+                "course_id": {
+                    "description": "Course ID",
+                    "type": "string"
+                },
+                "description": {
+                    "description": "Lesson Description (Can be left empty)",
+                    "type": "string"
+                },
+                "name": {
+                    "description": "Lesson Name",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Order",
+                    "type": "integer"
+                }
+            }
+        },
+        "lesson.UpdateLessonRequestPayload": {
+            "description": "Information that should be available when you update a lesson",
+            "type": "object",
+            "required": [
+                "course_id",
+                "name",
+                "order"
+            ],
+            "properties": {
+                "course_id": {
+                    "description": "Course ID",
+                    "type": "string"
+                },
+                "description": {
+                    "description": "Lesson Description (Can be left empty)",
+                    "type": "string"
+                },
+                "name": {
+                    "description": "Lesson Name",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Order",
+                    "type": "integer"
+                },
+                "updateLessonToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                }
+            }
+        },
         "login.LoginRequestPayload": {
             "description": "Information that should be available when do a login process",
             "type": "object",
@@ -2248,10 +2837,6 @@ const docTemplate = `{
                     "description": "Faculty Id, will be set by the server",
                     "type": "string"
                 },
-                "id": {
-                    "description": "Major ID, provided by query",
-                    "type": "string"
-                },
                 "name": {
                     "description": "Major Name",
                     "type": "string"
@@ -2359,6 +2944,68 @@ const docTemplate = `{
                 }
             }
         },
+        "materials.AddLessonMaterialsRequestPayload": {
+            "description": "Information that should be available when you add a lesson material",
+            "type": "object",
+            "required": [
+                "contents",
+                "lesson_id",
+                "order"
+            ],
+            "properties": {
+                "addLessonMaterialsToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                },
+                "contents": {
+                    "description": "Lesson Contents",
+                    "type": "string"
+                },
+                "lesson_id": {
+                    "description": "Lesson ID",
+                    "type": "string"
+                },
+                "material_id": {
+                    "description": "Lesson Material ID, optional",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Material Order",
+                    "type": "integer"
+                }
+            }
+        },
+        "materials.UpdateLessonMaterialsRequestPayload": {
+            "description": "Information that should be available when you update a lesson material",
+            "type": "object",
+            "required": [
+                "contents",
+                "lesson_id",
+                "order"
+            ],
+            "properties": {
+                "contents": {
+                    "description": "Lesson Contents",
+                    "type": "string"
+                },
+                "lesson_id": {
+                    "description": "Lesson ID",
+                    "type": "string"
+                },
+                "material_id": {
+                    "description": "Lesson Material ID, optional",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Material Order",
+                    "type": "integer"
+                },
+                "updateLessonMaterialsToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                }
+            }
+        },
         "quiz.AnswerOption": {
             "type": "object",
             "properties": {
diff --git a/docs/swagger.json b/docs/swagger.json
index 883d3d7..3a0ebf5 100644
--- a/docs/swagger.json
+++ b/docs/swagger.json
@@ -1480,6 +1480,540 @@
                 }
             }
         },
+        "/lesson": {
+            "put": {
+                "description": "Add a new lesson with the given details",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Add a new lesson",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "AddLessonToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    },
+                    {
+                        "description": "Add Lesson payload",
+                        "name": "data",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/lesson.AddLessonRequestPayload"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/lesson/course/{id}": {
+            "get": {
+                "description": "Retrieve lesson data by course ID",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Get lesson by course ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Course ID",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid ID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/lesson/material": {
+            "put": {
+                "description": "Add a new lesson material with the given details",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Add a new lesson material",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "AddLessonMaterialsToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    },
+                    {
+                        "description": "Add Lesson Material payload",
+                        "name": "data",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/materials.AddLessonMaterialsRequestPayload"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/lesson/material/lesson/{id}": {
+            "get": {
+                "description": "Retrieve lesson materials data by lesson ID",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Get lesson materials by lesson ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson ID (UUID)",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid UUID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/lesson/material/{id}": {
+            "get": {
+                "description": "Retrieve lesson data by UUID",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Get lesson by ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson ID (UUID)",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid UUID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "delete": {
+                "description": "Delete a lesson material with the specified ID",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Delete lesson material by id",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson Material ID",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "description": "DeleteLessonMaterialToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
+        "/lesson/{id}": {
+            "get": {
+                "description": "Retrieve lesson data by UUID",
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Get lesson by ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson ID (UUID)",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid UUID provided in request path",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "delete": {
+                "description": "Delete a lesson with the specified ID",
+                "consumes": [
+                    "application/json"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Delete lesson by ID",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson ID",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "type": "string",
+                        "description": "DeleteLessonToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            },
+            "patch": {
+                "description": "Update a lesson material with the given ID",
+                "tags": [
+                    "lesson"
+                ],
+                "summary": "Update a lesson material",
+                "parameters": [
+                    {
+                        "type": "string",
+                        "description": "Lesson Material ID (UUID)",
+                        "name": "id",
+                        "in": "path",
+                        "required": true
+                    },
+                    {
+                        "description": "Update Lesson Materials Payload",
+                        "name": "payload",
+                        "in": "body",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/materials.UpdateLessonMaterialsRequestPayload"
+                        }
+                    },
+                    {
+                        "type": "string",
+                        "description": "UpdateLessonMaterialsToken",
+                        "name": "Authorization",
+                        "in": "header",
+                        "required": true
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "Success",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "400": {
+                        "description": "Bad Request",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "401": {
+                        "description": "Unauthorized",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "403": {
+                        "description": "Forbidden",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "422": {
+                        "description": "Unprocessable Entity",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    },
+                    "500": {
+                        "description": "Internal Server Error",
+                        "schema": {
+                            "$ref": "#/definitions/web.BaseResponse"
+                        }
+                    }
+                }
+            }
+        },
         "/material/{id}": {
             "get": {
                 "description": "Get material detail",
@@ -2082,10 +2616,6 @@
                     "type": "string",
                     "example": "someone@example.com"
                 },
-                "id": {
-                    "description": "Course ID, Provided by query",
-                    "type": "string"
-                },
                 "lecturer": {
                     "description": "Course Lecturer",
                     "type": "string"
@@ -2142,10 +2672,6 @@
                     "description": "Faculty Name Abbreviation",
                     "type": "string"
                 },
-                "id": {
-                    "description": "Faculty ID, Provided by Query",
-                    "type": "string"
-                },
                 "name": {
                     "description": "Faculty Name",
                     "type": "string"
@@ -2156,6 +2682,68 @@
                 }
             }
         },
+        "lesson.AddLessonRequestPayload": {
+            "description": "Information that should be available when you add a lesson",
+            "type": "object",
+            "required": [
+                "course_id",
+                "name",
+                "order"
+            ],
+            "properties": {
+                "addLessonToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                },
+                "course_id": {
+                    "description": "Course ID",
+                    "type": "string"
+                },
+                "description": {
+                    "description": "Lesson Description (Can be left empty)",
+                    "type": "string"
+                },
+                "name": {
+                    "description": "Lesson Name",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Order",
+                    "type": "integer"
+                }
+            }
+        },
+        "lesson.UpdateLessonRequestPayload": {
+            "description": "Information that should be available when you update a lesson",
+            "type": "object",
+            "required": [
+                "course_id",
+                "name",
+                "order"
+            ],
+            "properties": {
+                "course_id": {
+                    "description": "Course ID",
+                    "type": "string"
+                },
+                "description": {
+                    "description": "Lesson Description (Can be left empty)",
+                    "type": "string"
+                },
+                "name": {
+                    "description": "Lesson Name",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Order",
+                    "type": "integer"
+                },
+                "updateLessonToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                }
+            }
+        },
         "login.LoginRequestPayload": {
             "description": "Information that should be available when do a login process",
             "type": "object",
@@ -2240,10 +2828,6 @@
                     "description": "Faculty Id, will be set by the server",
                     "type": "string"
                 },
-                "id": {
-                    "description": "Major ID, provided by query",
-                    "type": "string"
-                },
                 "name": {
                     "description": "Major Name",
                     "type": "string"
@@ -2351,6 +2935,68 @@
                 }
             }
         },
+        "materials.AddLessonMaterialsRequestPayload": {
+            "description": "Information that should be available when you add a lesson material",
+            "type": "object",
+            "required": [
+                "contents",
+                "lesson_id",
+                "order"
+            ],
+            "properties": {
+                "addLessonMaterialsToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                },
+                "contents": {
+                    "description": "Lesson Contents",
+                    "type": "string"
+                },
+                "lesson_id": {
+                    "description": "Lesson ID",
+                    "type": "string"
+                },
+                "material_id": {
+                    "description": "Lesson Material ID, optional",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Material Order",
+                    "type": "integer"
+                }
+            }
+        },
+        "materials.UpdateLessonMaterialsRequestPayload": {
+            "description": "Information that should be available when you update a lesson material",
+            "type": "object",
+            "required": [
+                "contents",
+                "lesson_id",
+                "order"
+            ],
+            "properties": {
+                "contents": {
+                    "description": "Lesson Contents",
+                    "type": "string"
+                },
+                "lesson_id": {
+                    "description": "Lesson ID",
+                    "type": "string"
+                },
+                "material_id": {
+                    "description": "Lesson Material ID, optional",
+                    "type": "string"
+                },
+                "order": {
+                    "description": "Lesson Material Order",
+                    "type": "integer"
+                },
+                "updateLessonMaterialsToken": {
+                    "description": "Web Token that was appended to the link",
+                    "type": "string"
+                }
+            }
+        },
         "quiz.AnswerOption": {
             "type": "object",
             "properties": {
diff --git a/docs/swagger.yaml b/docs/swagger.yaml
index 58ea934..ed665f4 100644
--- a/docs/swagger.yaml
+++ b/docs/swagger.yaml
@@ -103,9 +103,6 @@ definitions:
         description: Contributor Email
         example: someone@example.com
         type: string
-      id:
-        description: Course ID, Provided by query
-        type: string
       lecturer:
         description: Course Lecturer
         type: string
@@ -149,9 +146,6 @@ definitions:
       abbreviation:
         description: Faculty Name Abbreviation
         type: string
-      id:
-        description: Faculty ID, Provided by Query
-        type: string
       name:
         description: Faculty Name
         type: string
@@ -162,6 +156,52 @@ definitions:
     - abbreviation
     - name
     type: object
+  lesson.AddLessonRequestPayload:
+    description: Information that should be available when you add a lesson
+    properties:
+      addLessonToken:
+        description: Web Token that was appended to the link
+        type: string
+      course_id:
+        description: Course ID
+        type: string
+      description:
+        description: Lesson Description (Can be left empty)
+        type: string
+      name:
+        description: Lesson Name
+        type: string
+      order:
+        description: Lesson Order
+        type: integer
+    required:
+    - course_id
+    - name
+    - order
+    type: object
+  lesson.UpdateLessonRequestPayload:
+    description: Information that should be available when you update a lesson
+    properties:
+      course_id:
+        description: Course ID
+        type: string
+      description:
+        description: Lesson Description (Can be left empty)
+        type: string
+      name:
+        description: Lesson Name
+        type: string
+      order:
+        description: Lesson Order
+        type: integer
+      updateLessonToken:
+        description: Web Token that was appended to the link
+        type: string
+    required:
+    - course_id
+    - name
+    - order
+    type: object
   login.LoginRequestPayload:
     description: Information that should be available when do a login process
     properties:
@@ -221,9 +261,6 @@ definitions:
       faculty_id:
         description: Faculty Id, will be set by the server
         type: string
-      id:
-        description: Major ID, provided by query
-        type: string
       name:
         description: Major Name
         type: string
@@ -298,6 +335,52 @@ definitions:
       upload_link:
         type: string
     type: object
+  materials.AddLessonMaterialsRequestPayload:
+    description: Information that should be available when you add a lesson material
+    properties:
+      addLessonMaterialsToken:
+        description: Web Token that was appended to the link
+        type: string
+      contents:
+        description: Lesson Contents
+        type: string
+      lesson_id:
+        description: Lesson ID
+        type: string
+      material_id:
+        description: Lesson Material ID, optional
+        type: string
+      order:
+        description: Lesson Material Order
+        type: integer
+    required:
+    - contents
+    - lesson_id
+    - order
+    type: object
+  materials.UpdateLessonMaterialsRequestPayload:
+    description: Information that should be available when you update a lesson material
+    properties:
+      contents:
+        description: Lesson Contents
+        type: string
+      lesson_id:
+        description: Lesson ID
+        type: string
+      material_id:
+        description: Lesson Material ID, optional
+        type: string
+      order:
+        description: Lesson Material Order
+        type: integer
+      updateLessonMaterialsToken:
+        description: Web Token that was appended to the link
+        type: string
+    required:
+    - contents
+    - lesson_id
+    - order
+    type: object
   quiz.AnswerOption:
     properties:
       answer:
@@ -1417,6 +1500,361 @@ paths:
       summary: Get courses by major
       tags:
       - course
+  /lesson:
+    put:
+      consumes:
+      - application/json
+      description: Add a new lesson with the given details
+      parameters:
+      - description: AddLessonToken
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: Add Lesson payload
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/lesson.AddLessonRequestPayload'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Bad Request
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "403":
+          description: Forbidden
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "422":
+          description: Unprocessable Entity
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Add a new lesson
+      tags:
+      - lesson
+  /lesson/{id}:
+    delete:
+      consumes:
+      - application/json
+      description: Delete a lesson with the specified ID
+      parameters:
+      - description: Lesson ID
+        in: path
+        name: id
+        required: true
+        type: string
+      - description: DeleteLessonToken
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Bad Request
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "403":
+          description: Forbidden
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "422":
+          description: Unprocessable Entity
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Delete lesson by ID
+      tags:
+      - lesson
+    get:
+      description: Retrieve lesson data by UUID
+      parameters:
+      - description: Lesson ID (UUID)
+        in: path
+        name: id
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Invalid UUID provided in request path
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Get lesson by ID
+      tags:
+      - lesson
+    patch:
+      description: Update a lesson material with the given ID
+      parameters:
+      - description: Lesson Material ID (UUID)
+        in: path
+        name: id
+        required: true
+        type: string
+      - description: Update Lesson Materials Payload
+        in: body
+        name: payload
+        required: true
+        schema:
+          $ref: '#/definitions/materials.UpdateLessonMaterialsRequestPayload'
+      - description: UpdateLessonMaterialsToken
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Bad Request
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "403":
+          description: Forbidden
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "422":
+          description: Unprocessable Entity
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Update a lesson material
+      tags:
+      - lesson
+  /lesson/course/{id}:
+    get:
+      description: Retrieve lesson data by course ID
+      parameters:
+      - description: Course ID
+        in: path
+        name: id
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Invalid ID provided in request path
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Get lesson by course ID
+      tags:
+      - lesson
+  /lesson/material:
+    put:
+      consumes:
+      - application/json
+      description: Add a new lesson material with the given details
+      parameters:
+      - description: AddLessonMaterialsToken
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      - description: Add Lesson Material payload
+        in: body
+        name: data
+        required: true
+        schema:
+          $ref: '#/definitions/materials.AddLessonMaterialsRequestPayload'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Bad Request
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "403":
+          description: Forbidden
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "422":
+          description: Unprocessable Entity
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Add a new lesson material
+      tags:
+      - lesson
+  /lesson/material/{id}:
+    delete:
+      consumes:
+      - application/json
+      description: Delete a lesson material with the specified ID
+      parameters:
+      - description: Lesson Material ID
+        in: path
+        name: id
+        required: true
+        type: string
+      - description: DeleteLessonMaterialToken
+        in: header
+        name: Authorization
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Bad Request
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "403":
+          description: Forbidden
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "422":
+          description: Unprocessable Entity
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Delete lesson material by id
+      tags:
+      - lesson
+    get:
+      description: Retrieve lesson data by UUID
+      parameters:
+      - description: Lesson ID (UUID)
+        in: path
+        name: id
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Invalid UUID provided in request path
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Get lesson by ID
+      tags:
+      - lesson
+  /lesson/material/lesson/{id}:
+    get:
+      description: Retrieve lesson materials data by lesson ID
+      parameters:
+      - description: Lesson ID (UUID)
+        in: path
+        name: id
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: Success
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "400":
+          description: Invalid UUID provided in request path
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "401":
+          description: Unauthorized
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+        "500":
+          description: Internal Server Error
+          schema:
+            $ref: '#/definitions/web.BaseResponse'
+      summary: Get lesson materials by lesson ID
+      tags:
+      - lesson
   /material/{id}:
     delete:
       consumes:
diff --git a/handler/di.go b/handler/di.go
index 399ef81..aefdce3 100644
--- a/handler/di.go
+++ b/handler/di.go
@@ -6,6 +6,7 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/handler/auth"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/common"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/course"
+	"gitlab.informatika.org/ocw/ocw-backend/handler/lesson"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/material"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/handler/reset"
@@ -37,6 +38,10 @@ var HandlerSet = wire.NewSet(
 	wire.Struct(new(course.CourseHandlerImpl), "*"),
 	wire.Bind(new(course.CourseHandler), new(*course.CourseHandlerImpl)),
 
+	// Lesson
+	wire.Struct(new(lesson.LessonHandlerImpl), "*"),
+	wire.Bind(new(lesson.LessonHandler), new(*lesson.LessonHandlerImpl)),
+	
 	// Material
 	wire.Struct(new(material.MaterialHandlerImpl), "*"),
 	wire.Bind(new(material.MaterialHandler), new(*material.MaterialHandlerImpl)),
diff --git a/handler/lesson/addLesson.go b/handler/lesson/addLesson.go
new file mode 100644
index 0000000..162892b
--- /dev/null
+++ b/handler/lesson/addLesson.go
@@ -0,0 +1,100 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/go-playground/validator/v10"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+)
+
+// Index godoc
+//
+//	@Summary		Add a new lesson
+//	@Description	Add a new lesson with the given details
+//	@Tags			lesson
+//	@Accept			json
+//	@Produce		json
+//	@Param			Authorization	header		string							true	"AddLessonToken"
+//	@Param			data			body		lesson.AddLessonRequestPayload	true	"Add Lesson payload"
+//	@Success		200				{object}	web.BaseResponse				"Success"
+//	@Failure		400				{object}	web.BaseResponse				"Bad Request"
+//	@Failure		401				{object}	web.BaseResponse				"Unauthorized"
+//	@Failure		403				{object}	web.BaseResponse				"Forbidden"
+//	@Failure		422				{object}	web.BaseResponse				"Unprocessable Entity"
+//	@Failure		500				{object}	web.BaseResponse				"Internal Server Error"
+//	@Router			/lesson [put]
+func (l LessonHandlerImpl) AddLesson(w http.ResponseWriter, r *http.Request) {
+	payload := lesson.AddLessonRequestPayload{}
+
+	// Validate payload
+	if r.Header.Get("Content-Type") != "application/json" {
+		payload := l.WrapperUtil.ErrorResponseWrap("this service only receive json input", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnsupportedMediaType, payload)
+		return
+	}
+
+	if err := l.HttpUtil.ParseJson(r, &payload); err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid json input", err.Error())
+		l.HttpUtil.WriteJson(w, http.StatusUnprocessableEntity, payload)
+		return
+	}
+
+	validate := validator.New()
+	if err := validate.Struct(payload); err != nil {
+		if _, ok := err.(*validator.InvalidValidationError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(err.Error(), nil)
+			l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+			return
+		}
+
+		errPayload := web.NewResponseErrorFromValidator(err.(validator.ValidationErrors))
+		payload := l.WrapperUtil.ErrorResponseWrap(errPayload.Error(), errPayload)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	// Confirm Valid Website Token
+	validateTokenHeader := r.Header.Get("Authorization")
+	if validateTokenHeader == "" {
+		payload := l.WrapperUtil.ErrorResponseWrap("token is required", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+		return
+	}
+
+	token := strings.Split(validateTokenHeader, " ")
+	if len(token) != 2 {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+		return
+	}
+
+	if token[0] != "Bearer" {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+		return
+	}
+
+	payload.AddLessonToken = token[1]
+	err := l.LessonService.AddLesson(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(nil)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
\ No newline at end of file
diff --git a/handler/lesson/addLessonMaterial.go b/handler/lesson/addLessonMaterial.go
new file mode 100644
index 0000000..bd54902
--- /dev/null
+++ b/handler/lesson/addLessonMaterial.go
@@ -0,0 +1,102 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/go-playground/validator/v10"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+// Index godoc
+//
+//	@Summary		Add a new lesson material
+//	@Description	Add a new lesson material with the given details
+//	@Tags			lesson
+//	@Accept			json
+//	@Produce		json
+//	@Param			Authorization	header		string							true	"AddLessonMaterialsToken"
+//	@Param			data			body		materials.AddLessonMaterialsRequestPayload	true	"Add Lesson Material payload"
+//	@Success		200				{object}	web.BaseResponse				"Success"
+//	@Failure		400				{object}	web.BaseResponse				"Bad Request"
+//	@Failure		401				{object}	web.BaseResponse				"Unauthorized"
+//	@Failure		403				{object}	web.BaseResponse				"Forbidden"
+//	@Failure		422				{object}	web.BaseResponse				"Unprocessable Entity"
+//	@Failure		500				{object}	web.BaseResponse				"Internal Server Error"
+//	@Router			/lesson/material [put]
+func (l LessonHandlerImpl) AddLessonMaterial(w http.ResponseWriter, r *http.Request) {
+	payload := materials.AddLessonMaterialsRequestPayload{}
+
+	// Validate payload
+	if r.Header.Get("Content-Type") != "application/json" {
+		payload := l.WrapperUtil.ErrorResponseWrap("this service only receive json input", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnsupportedMediaType, payload)
+		return
+	}
+
+	if err := l.HttpUtil.ParseJson(r, &payload); err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid json input", err.Error())
+		l.HttpUtil.WriteJson(w, http.StatusUnprocessableEntity, payload)
+		return
+	}
+
+	validate := validator.New()
+	if err := validate.Struct(payload); err != nil {
+		if _, ok := err.(*validator.InvalidValidationError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(err.Error(), nil)
+			l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+			return
+		}
+
+		errPayload := web.NewResponseErrorFromValidator(err.(validator.ValidationErrors))
+		payload := l.WrapperUtil.ErrorResponseWrap(errPayload.Error(), errPayload)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	// Confirm Valid Website Token
+	validateTokenHeader := r.Header.Get("Authorization")
+
+	if validateTokenHeader == "" {
+		payload := l.WrapperUtil.ErrorResponseWrap("token is required", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+		return
+	}
+
+	token := strings.Split(validateTokenHeader, " ")
+
+	if len(token) != 2 {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+		return
+	}
+
+	if token[0] != "Bearer" {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+		return
+	}
+
+	payload.AddLessonMaterialsToken = token[1]
+	err := l.LessonService.AddLessonMaterial(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(nil)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
diff --git a/handler/lesson/deleteLesson.go b/handler/lesson/deleteLesson.go
new file mode 100644
index 0000000..e00f057
--- /dev/null
+++ b/handler/lesson/deleteLesson.go
@@ -0,0 +1,84 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+)
+
+// Index godoc
+//
+//	@Summary		Delete lesson by ID
+//	@Description	Delete a lesson with the specified ID
+//	@Tags			lesson
+//	@Accept			json
+//	@Produce		json
+//  @Param          id			  path        string                          true        "Lesson ID"
+//	@Param			Authorization	header		string							true	"DeleteLessonToken"
+//	@Success		200				{object}	web.BaseResponse				"Success"
+//	@Failure		400				{object}	web.BaseResponse				"Bad Request"
+//	@Failure		401				{object}	web.BaseResponse				"Unauthorized"
+//	@Failure		403				{object}	web.BaseResponse				"Forbidden"
+//	@Failure		422				{object}	web.BaseResponse				"Unprocessable Entity"
+//	@Failure		500				{object}	web.BaseResponse				"Internal Server Error"
+//	@Router			/lesson/{id} [delete]
+func (l LessonHandlerImpl) DeleteLesson(w http.ResponseWriter, r *http.Request) {
+	payload := lesson.DeleteByUUIDRequestPayload{}
+	validateTokenHeader := r.Header.Get("Authorization")
+
+	if validateTokenHeader == "" {
+		payload := l.WrapperUtil.ErrorResponseWrap("token is required", nil)
+		l.HttpUtil.WriteJson(w, http.StatusForbidden, payload)
+		return
+	}
+
+	token := strings.Split(validateTokenHeader, " ")
+
+	if len(token) != 2 {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	if token[0] != "Bearer" {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	payload.DeleteLessonToken = token[1]
+	payload.ID = id
+	err = l.LessonService.DeleteLesson(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(nil)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
\ No newline at end of file
diff --git a/handler/lesson/deleteLessonMaterial.go b/handler/lesson/deleteLessonMaterial.go
new file mode 100644
index 0000000..ee814d2
--- /dev/null
+++ b/handler/lesson/deleteLessonMaterial.go
@@ -0,0 +1,85 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+// Index godoc
+//
+//	@Summary		Delete lesson material by id
+//	@Description	Delete a lesson material with the specified ID
+//  @Tags			lesson
+//	@Accept			json
+//	@Produce		json
+//  @Param          id			  path        string                          true        "Lesson Material ID"
+//	@Param			Authorization	header		string							true	"DeleteLessonMaterialToken"
+//	@Success		200				{object}	web.BaseResponse				"Success"
+//	@Failure		400				{object}	web.BaseResponse				"Bad Request"
+//	@Failure		401				{object}	web.BaseResponse				"Unauthorized"
+//	@Failure		403				{object}	web.BaseResponse				"Forbidden"
+//	@Failure		422				{object}	web.BaseResponse				"Unprocessable Entity"
+//	@Failure		500				{object}	web.BaseResponse				"Internal Server Error"
+//	@Router			/lesson/material/{id} [delete]
+func (l LessonHandlerImpl) DeleteLessonMaterial(w http.ResponseWriter, r *http.Request) {
+	payload := materials.DeleteByUUIDRequestPayload{}
+	validateTokenHeader := r.Header.Get("Authorization")
+
+	if validateTokenHeader == "" {
+		payload := l.WrapperUtil.ErrorResponseWrap("token is required", nil)
+		l.HttpUtil.WriteJson(w, http.StatusForbidden, payload)
+		return
+	}
+
+	token := strings.Split(validateTokenHeader, " ")
+
+	if len(token) != 2 {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	if token[0] != "Bearer" {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+
+	payload.DeleteLessonMaterialsToken = token[1]
+	payload.ID = id
+	err = l.LessonService.DeleteLessonMaterial(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(nil)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
diff --git a/handler/lesson/getLesson.go b/handler/lesson/getLesson.go
new file mode 100644
index 0000000..6fe5656
--- /dev/null
+++ b/handler/lesson/getLesson.go
@@ -0,0 +1,55 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+)
+
+// Index godoc
+//
+//	@Summary		Get lesson by ID
+//	@Description	Retrieve lesson data by UUID
+//	@Tags			lesson
+//	@Produce		json
+//	@Param			id	path		string				true	"Lesson ID (UUID)"
+//	@Success		200	{object}	web.BaseResponse	"Success"
+//	@Failure		400	{object}	web.BaseResponse	"Invalid UUID provided in request path"
+//	@Failure		401	{object}	web.BaseResponse	"Unauthorized"
+//	@Failure		500	{object}	web.BaseResponse	"Internal Server Error"
+//	@Router			/lesson/{id} [get]
+func (l LessonHandlerImpl) GetLesson(w http.ResponseWriter, r *http.Request) {
+	payload := lesson.GetByUUIDRequestPayload{}
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	payload.ID = id
+	packet, err := l.LessonService.GetLesson(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(packet)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
\ No newline at end of file
diff --git a/handler/lesson/getLessonMaterial.go b/handler/lesson/getLessonMaterial.go
new file mode 100644
index 0000000..f6449cd
--- /dev/null
+++ b/handler/lesson/getLessonMaterial.go
@@ -0,0 +1,55 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+// Index godoc
+//
+//	@Summary		Get lesson by ID
+//	@Description	Retrieve lesson data by UUID
+//	@Tags			lesson
+//	@Produce		json
+//	@Param			id	path		string				true	"Lesson ID (UUID)"
+//	@Success		200	{object}	web.BaseResponse	"Success"
+//	@Failure		400	{object}	web.BaseResponse	"Invalid UUID provided in request path"
+//	@Failure		401	{object}	web.BaseResponse	"Unauthorized"
+//	@Failure		500	{object}	web.BaseResponse	"Internal Server Error"
+//	@Router			/lesson/material/{id} [get]
+func (l LessonHandlerImpl) GetLessonMaterial(w http.ResponseWriter, r *http.Request) {
+	payload := materials.GetByUUIDRequestPayload{}
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+	
+	payload.ID = id
+	packet, err := l.LessonService.GetLessonMaterial(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(packet)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
\ No newline at end of file
diff --git a/handler/lesson/getLessonMaterialsByLesson.go b/handler/lesson/getLessonMaterialsByLesson.go
new file mode 100644
index 0000000..dcb37eb
--- /dev/null
+++ b/handler/lesson/getLessonMaterialsByLesson.go
@@ -0,0 +1,55 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	
+	"github.com/go-chi/chi/v5"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+// Index godoc
+//
+//	@Summary		Get lesson materials by lesson ID
+//	@Description	Retrieve lesson materials data by lesson ID
+//	@Tags			lesson
+//	@Produce		json
+//	@Param			id	path		string				true	"Lesson ID (UUID)"
+//	@Success		200	{object}	web.BaseResponse	"Success"
+//	@Failure		400	{object}	web.BaseResponse	"Invalid UUID provided in request path"
+//	@Failure		401	{object}	web.BaseResponse	"Unauthorized"
+//	@Failure		500	{object}	web.BaseResponse	"Internal Server Error"
+//	@Router			/lesson/material/lesson/{id} [get]
+func (l LessonHandlerImpl) GetLessonMaterialsByLesson(w http.ResponseWriter, r *http.Request) {
+	payload := materials.GetByUUIDRequestPayload{}
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+	
+	payload.ID = id
+	packet, err := l.LessonService.GetLessonMaterials(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(packet)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
\ No newline at end of file
diff --git a/handler/lesson/getLessonsByCourse.go b/handler/lesson/getLessonsByCourse.go
new file mode 100644
index 0000000..fd2956b
--- /dev/null
+++ b/handler/lesson/getLessonsByCourse.go
@@ -0,0 +1,47 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/go-chi/chi/v5"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+)
+
+// Index godoc
+//
+//	@Summary		Get lesson by course ID
+//	@Description	Retrieve lesson data by course ID
+//	@Tags			lesson
+//	@Produce		json
+//	@Param			id	path		string				true	"Course ID"
+//	@Success		200	{object}	web.BaseResponse	"Success"
+//	@Failure		400	{object}	web.BaseResponse	"Invalid ID provided in request path"
+//	@Failure		401	{object}	web.BaseResponse	"Unauthorized"
+//	@Failure		500	{object}	web.BaseResponse	"Internal Server Error"
+//	@Router			/lesson/course/{id} [get]
+func (l LessonHandlerImpl) GetLessonsByCourse(w http.ResponseWriter, r *http.Request) {
+	payload := lesson.GetByStringRequestPayload{}
+
+	payload.ID = chi.URLParam(r, "id")
+	packet, err := l.LessonService.GetLessons(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[LESSON] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(packet)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
\ No newline at end of file
diff --git a/handler/lesson/handler.go b/handler/lesson/handler.go
new file mode 100644
index 0000000..874c8ea
--- /dev/null
+++ b/handler/lesson/handler.go
@@ -0,0 +1,17 @@
+package lesson
+
+import (
+	r "gitlab.informatika.org/ocw/ocw-backend/repository/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/service/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/service/logger"
+	"gitlab.informatika.org/ocw/ocw-backend/utils/httputil"
+	"gitlab.informatika.org/ocw/ocw-backend/utils/wrapper"
+)
+
+type LessonHandlerImpl struct {
+	r.LessonRepository
+	lesson.LessonService
+	httputil.HttpUtil
+	wrapper.WrapperUtil
+	logger.Logger
+}
\ No newline at end of file
diff --git a/handler/lesson/types.go b/handler/lesson/types.go
new file mode 100644
index 0000000..f04fef9
--- /dev/null
+++ b/handler/lesson/types.go
@@ -0,0 +1,23 @@
+package lesson
+
+import "net/http"
+
+type LessonHandler interface {
+	// Get
+	GetLesson(w http.ResponseWriter, r *http.Request)
+	GetLessonsByCourse(w http.ResponseWriter, r *http.Request)
+	GetLessonMaterial(w http.ResponseWriter, r *http.Request)
+	GetLessonMaterialsByLesson(w http.ResponseWriter, r *http.Request)
+
+	// Add (Put)
+	AddLesson(w http.ResponseWriter, r *http.Request)
+	AddLessonMaterial(w http.ResponseWriter, r *http.Request)
+
+	// Update
+	UpdateLesson(w http.ResponseWriter, r *http.Request)
+	UpdateLessonMaterial(w http.ResponseWriter, r *http.Request)
+
+	// Delete
+	DeleteLesson(w http.ResponseWriter, r *http.Request)
+	DeleteLessonMaterial(w http.ResponseWriter, r *http.Request)
+}
diff --git a/handler/lesson/updateLesson.go b/handler/lesson/updateLesson.go
new file mode 100644
index 0000000..5638be6
--- /dev/null
+++ b/handler/lesson/updateLesson.go
@@ -0,0 +1,114 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/go-playground/validator/v10"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+)
+
+// Index godoc
+//
+//	@Summary		Update a lesson
+//	@Description	Update a lesson with the given ID
+//	@Tags			lesson
+//	@Param			id				path		string								true	"Lesson ID (UUID)"
+//	@Param			payload			body		lesson.UpdateLessonRequestPayload	true	"Update Lesson Payload"
+//	@Param			Authorization	header		string								true	"UpdateLessonToken"
+//	@Success		200				{object}	web.BaseResponse					"Success"
+//	@Failure		400				{object}	web.BaseResponse					"Bad Request"
+//	@Failure		401				{object}	web.BaseResponse					"Unauthorized"
+//	@Failure		403				{object}	web.BaseResponse					"Forbidden"
+//	@Failure		422				{object}	web.BaseResponse					"Unprocessable Entity"
+//	@Failure		500				{object}	web.BaseResponse					"Internal Server Error"
+//	@Router			/lesson/{id} [patch]
+func (l LessonHandlerImpl) UpdateLesson(w http.ResponseWriter, r *http.Request) {
+	payload := lesson.UpdateLessonRequestPayload{}
+	validate := validator.New()
+
+	// Validate payload
+	if r.Header.Get("Content-Type") != "application/json" {
+		payload := l.WrapperUtil.ErrorResponseWrap("this service only receive json input", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnsupportedMediaType, payload)
+		return
+	}
+
+	if err := l.HttpUtil.ParseJson(r, &payload); err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid json input", err.Error())
+		l.HttpUtil.WriteJson(w, http.StatusUnprocessableEntity, payload)
+		return
+	}
+
+	if err := validate.Struct(payload); err != nil {
+		if _, ok := err.(*validator.InvalidValidationError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(err.Error(), nil)
+			l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+			return
+		}
+
+		errPayload := web.NewResponseErrorFromValidator(err.(validator.ValidationErrors))
+		payload := l.WrapperUtil.ErrorResponseWrap(errPayload.Error(), errPayload)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	// Confirm Valid Website Token
+	validateTokenHeader := r.Header.Get("Authorization")
+
+	if validateTokenHeader == "" {
+		payload := l.WrapperUtil.ErrorResponseWrap("token is required", nil)
+		l.HttpUtil.WriteJson(w, http.StatusForbidden, payload)
+		return
+	}
+
+	token := strings.Split(validateTokenHeader, " ")
+
+	if len(token) != 2 {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	if token[0] != "Bearer" {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	payload.UpdateLessonToken = token[1]
+	payload.ID = id
+	err = l.LessonService.UpdateLesson(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[RESET] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(nil)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
+
+	
\ No newline at end of file
diff --git a/handler/lesson/updateLessonMaterial.go b/handler/lesson/updateLessonMaterial.go
new file mode 100644
index 0000000..bb3689d
--- /dev/null
+++ b/handler/lesson/updateLessonMaterial.go
@@ -0,0 +1,114 @@
+package lesson
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/go-chi/chi/v5"
+	"github.com/go-playground/validator/v10"
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+// Index godoc
+//
+//	@Summary		Update a lesson material
+//	@Description	Update a lesson material with the given ID
+//	@Tags			lesson
+//	@Param			id				path		string								true	"Lesson Material ID (UUID)"
+//	@Param			payload			body		materials.UpdateLessonMaterialsRequestPayload	true	"Update Lesson Materials Payload"
+//	@Param			Authorization	header		string								true	"UpdateLessonMaterialsToken"
+//	@Success		200				{object}	web.BaseResponse					"Success"
+//	@Failure		400				{object}	web.BaseResponse					"Bad Request"
+//	@Failure		401				{object}	web.BaseResponse					"Unauthorized"
+//	@Failure		403				{object}	web.BaseResponse					"Forbidden"
+//	@Failure		422				{object}	web.BaseResponse					"Unprocessable Entity"
+//	@Failure		500				{object}	web.BaseResponse					"Internal Server Error"
+//	@Router			/lesson/{id} [patch]
+func (l LessonHandlerImpl) UpdateLessonMaterial(w http.ResponseWriter, r *http.Request) {
+	payload := materials.UpdateLessonMaterialsRequestPayload{}
+	validate := validator.New()
+
+	// Validate payload
+	if r.Header.Get("Content-Type") != "application/json" {
+		payload := l.WrapperUtil.ErrorResponseWrap("this service only receive json input", nil)
+		l.HttpUtil.WriteJson(w, http.StatusUnsupportedMediaType, payload)
+		return
+	}
+
+	if err := l.HttpUtil.ParseJson(r, &payload); err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid json input", err.Error())
+		l.HttpUtil.WriteJson(w, http.StatusUnprocessableEntity, payload)
+		return
+	}
+
+	if err := validate.Struct(payload); err != nil {
+		if _, ok := err.(*validator.InvalidValidationError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(err.Error(), nil)
+			l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+			return
+		}
+
+		errPayload := web.NewResponseErrorFromValidator(err.(validator.ValidationErrors))
+		payload := l.WrapperUtil.ErrorResponseWrap(errPayload.Error(), errPayload)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	// Confirm Valid Website Token
+	validateTokenHeader := r.Header.Get("Authorization")
+
+	if validateTokenHeader == "" {
+		payload := l.WrapperUtil.ErrorResponseWrap("token is required", nil)
+		l.HttpUtil.WriteJson(w, http.StatusForbidden, payload)
+		return
+	}
+
+	token := strings.Split(validateTokenHeader, " ")
+
+	if len(token) != 2 {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	if token[0] != "Bearer" {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid token", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	id, err := uuid.Parse(chi.URLParam(r, "id"))
+
+	if err != nil {
+		payload := l.WrapperUtil.ErrorResponseWrap("invalid id", nil)
+		l.HttpUtil.WriteJson(w, http.StatusBadRequest, payload)
+		return
+	}
+
+	payload.UpdateLessonMaterialsToken = token[1]
+	payload.ID = id
+	err = l.LessonService.UpdateLessonMaterial(payload)
+
+	if err != nil {
+		if errData, ok := err.(web.ResponseError); ok {
+			payload := l.WrapperUtil.ErrorResponseWrap(errData.Error(), errData)
+			l.HttpUtil.WriteJson(w, http.StatusUnauthorized, payload)
+			return
+		}
+
+		l.Logger.Error(
+			fmt.Sprintf("[RESET] some error happened when validating URL: %s", err.Error()),
+		)
+		payload := l.WrapperUtil.ErrorResponseWrap("internal server error", nil)
+		l.HttpUtil.WriteJson(w, http.StatusInternalServerError, payload)
+		return
+	}
+
+	responsePayload := l.WrapperUtil.SuccessResponseWrap(nil)
+	l.HttpUtil.WriteSuccessJson(w, responsePayload)
+}
+
+	
\ No newline at end of file
diff --git a/model/domain/course/course.go b/model/domain/course/course.go
index 17d592f..f57db68 100644
--- a/model/domain/course/course.go
+++ b/model/domain/course/course.go
@@ -13,7 +13,7 @@ type Major struct {
 	ID           uuid.UUID `json:"id" gorm:"primaryKey;type:uuid"`
 	Name         string    `json:"name"`
 	Fac_id       uuid.UUID `json:"fac_id" gorm:"type:uuid"`
-	Faculty      *Faculty  `json:"faculty" gorm:"foreignKey:Fac_id"`
+	Faculty      *Faculty  `json:"-" gorm:"foreignKey:Fac_id"`
 	Abbreviation string    `json:"abbreviation"`
 }
 
@@ -21,7 +21,7 @@ type Course struct {
 	ID           string    `json:"id" gorm:"primaryKey"`
 	Name         string    `json:"name"`
 	Major_id     uuid.UUID `json:"major_id" gorm:"type:uuid"`
-	Major        *Major    `json:"major" gorm:"foreignKey:Major_id"`
+	Major        *Major    `json:"-" gorm:"foreignKey:Major_id"`
 	Description  string    `json:"description"`
 	Email        string    `json:"email"`
 	Abbreviation string    `json:"abbreviation"`
diff --git a/model/domain/lesson/lesson.go b/model/domain/lesson/lesson.go
new file mode 100644
index 0000000..621295e
--- /dev/null
+++ b/model/domain/lesson/lesson.go
@@ -0,0 +1,34 @@
+package lesson
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/course"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/material"
+)
+
+type Lesson struct {
+	ID          uuid.UUID      `json:"id" gorm:"primaryKey;type:uuid"`
+	Name        string         `json:"name"`
+	CourseID    string         `json:"course_id"`
+	Course      *course.Course `json:"-" gorm:"foreignKey:CourseID"`
+	Order       int            `json:"order"`
+	Description string         `json:"description"`
+}
+
+type LessonMaterials struct {
+	ID         uuid.UUID          `json:"id" gorm:"primaryKey;type:uuid"`
+	LessonID   uuid.UUID          `json:"lesson_id"`
+	Lesson     *Lesson            `json:"-" gorm:"foreignKey:LessonID"`
+	Order      int                `json:"order"`
+	MaterialID uuid.UUID          `json:"material_id"`
+	Material   *material.Material `json:"-" gorm:"foreignKey:MaterialID"`
+	Contents   string             `json:"contents"`
+}
+
+func (Lesson) TableName() string {
+	return "lesson"
+}
+
+func (LessonMaterials) TableName() string {
+	return "lesson_materials"
+}
diff --git a/model/web/course/faculty/request.go b/model/web/course/faculty/request.go
index 1c08bdd..2233e13 100644
--- a/model/web/course/faculty/request.go
+++ b/model/web/course/faculty/request.go
@@ -22,7 +22,7 @@ type UpdateFacultyRequestPayload struct {
 	UpdateFacultyToken string
 
 	// Faculty ID, Provided by Query
-	ID uuid.UUID
+	ID uuid.UUID `json:"-" validate:"required"`
 
 	// Faculty Name
 	Name string `json:"name" validate:"required"`
diff --git a/model/web/course/major/request.go b/model/web/course/major/request.go
index 53bc733..1238cbf 100644
--- a/model/web/course/major/request.go
+++ b/model/web/course/major/request.go
@@ -29,7 +29,7 @@ type UpdateMajorRequestPayload struct {
 	UpdateMajorToken string
 
 	// Major ID, provided by query
-	ID uuid.UUID
+	ID uuid.UUID `json:"-" validate:"required"`
 
 	// Major Name
 	Name string `json:"name" validate:"required"`
diff --git a/model/web/course/request.go b/model/web/course/request.go
index 0fad2be..2604b10 100644
--- a/model/web/course/request.go
+++ b/model/web/course/request.go
@@ -37,7 +37,7 @@ type DeleteByStringRequestPayload struct {
 	DeleteCourseToken string
 
 	// Course ID, provided by query
-	ID string
+	ID string `json:"-" validate:"required"`
 }
 
 
@@ -45,14 +45,14 @@ type DeleteByStringRequestPayload struct {
 //	@Description	Information that should be available when you get using course id (string)
 type GetByStringRequestPayload struct {
 	// Course ID, provided by query
-	ID string
+	ID string `json:"-" validate:"required"`
 }
 
 // GetUUID Request Payload
 //	@Description	Information that should be available when you get using major/faculty id (string)
 type GetByUUIDRequestPayload struct {
 	// Major/Faculty ID, provided by query
-	ID uuid.UUID
+	ID uuid.UUID `json:"-" validate:"required"`
 }
 
 // UpdateCourse Request Payload
@@ -62,7 +62,7 @@ type UpdateCourseRequestPayload struct {
 	UpdateCourseToken string
 
 	// Course ID, Provided by query
-	ID string `json:"id"`
+	ID string `json:"-" validate:"required"`
 
 	// Course Name
 	Name string `json:"name" validate:"required"`
diff --git a/model/web/error_code.go b/model/web/error_code.go
index 9b29b2d..eb88b08 100644
--- a/model/web/error_code.go
+++ b/model/web/error_code.go
@@ -3,16 +3,18 @@ package web
 const (
 	InvalidInput string = "INVALID_INPUT"
 
-	InvalidLogin       string = "INVALID_LOGIN"
-	UnauthorizedAccess string = "UNAUTHORIZED"
-	InactiveUser       string = "INACTIVE_ACCOUNT"
-	EmailExist         string = "EMAIL_EXIST"
-	EmailNotExist      string = "EMAIL_NOT_EXIST"
-	LinkNotAvailable   string = "LINK_NOT_AVAILABLE"
-	FacultyNotExist    string = "FACULTY_NOT_EXIST"
-	MajorNotExist      string = "MAJOR_NOT_EXIST"
-	CourseNotExist     string = "COURSE_NOT_EXIST"
-	IDExists           string = "ID_ALREADY_EXISTS"
+	InvalidLogin           string = "INVALID_LOGIN"
+	UnauthorizedAccess     string = "UNAUTHORIZED"
+	InactiveUser           string = "INACTIVE_ACCOUNT"
+	EmailExist             string = "EMAIL_EXIST"
+	EmailNotExist          string = "EMAIL_NOT_EXIST"
+	LinkNotAvailable       string = "LINK_NOT_AVAILABLE"
+	FacultyNotExist        string = "FACULTY_NOT_EXIST"
+	MajorNotExist          string = "MAJOR_NOT_EXIST"
+	CourseNotExist         string = "COURSE_NOT_EXIST"
+	LessonNotExist         string = "LESSON_NOT_EXIST"
+	LessonMaterialNotExist string = "LESSON_MATERIAL_NOT_EXIST"
+	IDExists               string = "ID_ALREADY_EXISTS"
 
 	TokenError string = "TOKEN_ERROR"
 )
diff --git a/model/web/lesson/materials/request.go b/model/web/lesson/materials/request.go
new file mode 100644
index 0000000..b20dcbb
--- /dev/null
+++ b/model/web/lesson/materials/request.go
@@ -0,0 +1,63 @@
+package materials
+
+import (
+	"github.com/google/uuid"
+)
+
+// AddLessonMaterials Request Payload
+//	@Description	Information that should be available when you add a lesson material
+type AddLessonMaterialsRequestPayload struct {
+	// Web Token that was appended to the link
+	AddLessonMaterialsToken string
+
+	// Lesson ID
+	LessonID uuid.UUID `json:"lesson_id" validate:"required"`
+
+	// Lesson Material Order
+	Order int `json:"order" validate:"required"`
+
+	// Lesson Material ID, optional
+	MaterialID uuid.UUID `json:"material_id"`
+
+	// Lesson Contents
+	Contents string `json:"contents" validate:"required"`
+}
+
+// DeleteLessonMaterials Request Payload
+//	@Description	Information that should be available when you delete using lesson material id (uuid)
+type DeleteByUUIDRequestPayload struct {
+	// Web Token that was appended to the link
+	DeleteLessonMaterialsToken string
+
+	// Lesson Material ID, provided by query
+	ID uuid.UUID `json:"-" validate:"required"`
+}
+
+// UpdateLessonMaterials Request Payload
+//	@Description	Information that should be available when you update a lesson material
+type UpdateLessonMaterialsRequestPayload struct {
+	// Web Token that was appended to the link
+	UpdateLessonMaterialsToken string
+
+	// Lesson Material ID, provided by query
+	ID uuid.UUID `json:"-" validate:"required"`
+
+	// Lesson ID
+	LessonID uuid.UUID `json:"lesson_id" validate:"required"`
+
+	// Lesson Material Order
+	Order int `json:"order" validate:"required"`
+
+	// Lesson Material ID, optional
+	MaterialID uuid.UUID `json:"material_id"`
+
+	// Lesson Contents
+	Contents string `json:"contents" validate:"required"`
+}
+
+// GetUUID Request Payload
+//	@Description	Information that should be available when you get using id or lesson id (uuid)
+type GetByUUIDRequestPayload struct {
+	// Lesson ID, provided by query
+	ID uuid.UUID `json:"-" validate:"required"`
+}
\ No newline at end of file
diff --git a/model/web/lesson/request.go b/model/web/lesson/request.go
new file mode 100644
index 0000000..4a999f7
--- /dev/null
+++ b/model/web/lesson/request.go
@@ -0,0 +1,68 @@
+package lesson
+
+import "github.com/google/uuid"
+
+// AddLesson Request Payload
+//	@Description	Information that should be available when you add a lesson
+type AddLessonRequestPayload struct {
+	// Web Token that was appended to the link
+	AddLessonToken string
+
+	// Lesson Name
+	Name string `json:"name" validate:"required"`
+
+	// Course ID
+	CourseID string `json:"course_id" validate:"required"`
+	
+	// Lesson Order
+	Order int `json:"order" validate:"required"`
+
+	// Lesson Description (Can be left empty)
+	Description string `json:"description"`
+}
+
+// DeleteLesson Request Payload
+//	@Description	Information that should be available when you delete using lesson id (uuid)
+type DeleteByUUIDRequestPayload struct {
+	// Web Token that was appended to the link
+	DeleteLessonToken string
+
+	// Lesson ID, provided by query
+	ID uuid.UUID `json:"-" validate:"required"`
+}
+
+// UpdateLesson Request Payload
+//	@Description	Information that should be available when you update a lesson
+type UpdateLessonRequestPayload struct {
+	// Web Token that was appended to the link
+	UpdateLessonToken string
+
+	// Lesson ID, provided by query
+	ID uuid.UUID `json:"-" validate:"required"`
+
+	// Lesson Name
+	Name string `json:"name" validate:"required"`
+
+	// Course ID
+	CourseID string `json:"course_id" validate:"required"`
+
+	// Lesson Order
+	Order int `json:"order" validate:"required"`
+
+	// Lesson Description (Can be left empty)
+	Description string `json:"description"`
+}
+
+// GetUUID Request Payload
+//	@Description	Information that should be available when you get using lesson id (uuid)
+type GetByUUIDRequestPayload struct {
+	// Lesson ID, provided by query
+	ID uuid.UUID `json:"-" validate:"required"`
+}
+
+// GetID Request Payload
+//	@Description	Information that should be available when you get using course id (string)
+type GetByStringRequestPayload struct {
+	// Course ID, provided by query
+	ID string `json:"-" validate:"required"`
+}
diff --git a/repository/di.go b/repository/di.go
index b564bd5..9a418dc 100644
--- a/repository/di.go
+++ b/repository/di.go
@@ -5,6 +5,7 @@ import (
 	"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/lesson"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/material"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/repository/transaction"
@@ -24,6 +25,13 @@ var RepositoryBasicSet = wire.NewSet(
 	cache.New,
 	wire.Bind(new(cache.CacheRepository), new(*cache.CacheRepositoryImpl)),
 
+	// Lesson Repository
+	lesson.NewLesson,
+	lesson.NewLessonMaterials,
+	wire.Bind(new(lesson.LessonRepository), new(*lesson.LessonRepositoryImpl)),
+	wire.Bind(new(lesson.LessonMaterialsRepository), new(*lesson.LessonMaterialsRepositoryImpl)),
+
+	// Material Repository
 	material.NewMaterial,
 	material.NewMaterialContent,
 
diff --git a/repository/lesson/lesson.go b/repository/lesson/lesson.go
new file mode 100644
index 0000000..e3e1002
--- /dev/null
+++ b/repository/lesson/lesson.go
@@ -0,0 +1,52 @@
+package lesson
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/provider/db"
+	"gorm.io/gorm"
+)
+
+type LessonRepositoryImpl struct {
+	db *gorm.DB
+}
+
+func NewLesson(
+	db db.Database,
+) *LessonRepositoryImpl {
+	return &LessonRepositoryImpl{db.Connect()}
+}
+
+func (repo LessonRepositoryImpl) GetLesson(id uuid.UUID) (*lesson.Lesson, error) {
+	result := &lesson.Lesson{}
+	err := repo.db.First(result, "id = ?", id).Error
+
+	if err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
+func (repo LessonRepositoryImpl) GetLessons(courseId string) ([]lesson.Lesson, error) {
+	var result []lesson.Lesson
+	err := repo.db.Where("course_id = ?", courseId).Find(&result).Error
+
+	if err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
+func (repo LessonRepositoryImpl) AddLesson(lesson lesson.Lesson) error {
+	return repo.db.Create(lesson).Error
+}
+
+func (repo LessonRepositoryImpl) UpdateLesson(lesson lesson.Lesson) error {
+	return repo.db.Save(lesson).Error
+}
+
+func (repo LessonRepositoryImpl) DeleteLesson(id uuid.UUID) error {
+	return repo.db.Delete(&lesson.Lesson{}, id).Error
+}
diff --git a/repository/lesson/materials.go b/repository/lesson/materials.go
new file mode 100644
index 0000000..d0e5ea7
--- /dev/null
+++ b/repository/lesson/materials.go
@@ -0,0 +1,52 @@
+package lesson
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/provider/db"
+	"gorm.io/gorm"
+)
+
+type LessonMaterialsRepositoryImpl struct {
+	db *gorm.DB
+}
+
+func NewLessonMaterials(
+	db db.Database,
+) *LessonMaterialsRepositoryImpl {
+	return &LessonMaterialsRepositoryImpl{db.Connect()}
+}
+
+func (repo LessonMaterialsRepositoryImpl) GetLessonMaterial(id uuid.UUID) (*lesson.LessonMaterials, error) {
+	result := &lesson.LessonMaterials{}
+	err := repo.db.First(result, "id = ?", id).Error
+
+	if err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
+func (repo LessonMaterialsRepositoryImpl) GetLessonMaterials(lessonId uuid.UUID) ([]lesson.LessonMaterials, error) {
+	var result []lesson.LessonMaterials
+	err := repo.db.Where("lesson_id = ?", lessonId).Find(&result).Error
+
+	if err != nil {
+		return nil, err
+	}
+
+	return result, nil
+}
+
+func (repo LessonMaterialsRepositoryImpl) AddLessonMaterial(lessonMaterial lesson.LessonMaterials) error {
+	return repo.db.Create(lessonMaterial).Error
+}
+
+func (repo LessonMaterialsRepositoryImpl) UpdateLessonMaterial(lessonMaterial lesson.LessonMaterials) error {
+	return repo.db.Save(lessonMaterial).Error
+}
+
+func (repo LessonMaterialsRepositoryImpl) DeleteLessonMaterial(id uuid.UUID) error {
+	return repo.db.Delete(&lesson.LessonMaterials{}, id).Error
+}
diff --git a/repository/lesson/type.go b/repository/lesson/type.go
new file mode 100644
index 0000000..4925c01
--- /dev/null
+++ b/repository/lesson/type.go
@@ -0,0 +1,22 @@
+package lesson
+
+import (
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"github.com/google/uuid"
+)
+
+type LessonRepository interface {
+	GetLesson(id uuid.UUID) (*lesson.Lesson, error)
+	GetLessons(courseId string) ([]lesson.Lesson, error)
+	AddLesson(lesson lesson.Lesson) error
+	UpdateLesson(lesson lesson.Lesson) error
+	DeleteLesson(id uuid.UUID) error
+}
+
+type LessonMaterialsRepository interface {
+	GetLessonMaterial(id uuid.UUID) (*lesson.LessonMaterials, error)
+	GetLessonMaterials(lessonId uuid.UUID) ([]lesson.LessonMaterials, error)
+	AddLessonMaterial(lessonMaterial lesson.LessonMaterials) error
+	UpdateLessonMaterial(lessonMaterial lesson.LessonMaterials) error
+	DeleteLessonMaterial(id uuid.UUID) error
+}
\ No newline at end of file
diff --git a/routes/di.go b/routes/di.go
index ddae40f..d3129d3 100644
--- a/routes/di.go
+++ b/routes/di.go
@@ -6,6 +6,7 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/routes/auth"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/common"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/course"
+	"gitlab.informatika.org/ocw/ocw-backend/routes/lesson"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/material"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/reset"
@@ -19,6 +20,7 @@ var routesCollectionSet = wire.NewSet(
 	wire.Struct(new(admin.AdminRoutes), "*"),
 	wire.Struct(new(reset.ResetRoutes), "*"),
 	wire.Struct(new(course.CourseRoutes), "*"),
+	wire.Struct(new(lesson.LessonRoutes), "*"),
 	wire.Struct(new(material.MaterialRoutes), "*"),
 	wire.Struct(new(quiz.QuizRoutes), "*"),
 )
diff --git a/routes/lesson/route.go b/routes/lesson/route.go
new file mode 100644
index 0000000..7d19720
--- /dev/null
+++ b/routes/lesson/route.go
@@ -0,0 +1,28 @@
+package lesson
+
+import (
+	"github.com/go-chi/chi/v5"
+	"gitlab.informatika.org/ocw/ocw-backend/handler/lesson"
+)
+
+type LessonRoutes struct {
+	lesson.LessonHandler
+}
+
+func (l LessonRoutes) Register(r chi.Router) {
+	r.Route("/lesson", func(r chi.Router) {
+		r.Get("/{id}", l.LessonHandler.GetLesson)
+		r.Get("/course/{id}", l.LessonHandler.GetLessonsByCourse)
+		r.Get("/material/{id}", l.LessonHandler.GetLessonMaterial)
+		r.Get("/material/lesson/{id}", l.LessonHandler.GetLessonMaterialsByLesson)
+
+		r.Put("/", l.LessonHandler.AddLesson)
+		r.Put("/material", l.LessonHandler.AddLessonMaterial)
+
+		r.Post("/{id}", l.LessonHandler.UpdateLesson)
+		r.Post("/material/{id}", l.LessonHandler.UpdateLessonMaterial)
+
+		r.Delete("/{id}", l.LessonHandler.DeleteLesson)
+		r.Delete("/material/{id}", l.LessonHandler.DeleteLessonMaterial)
+	})
+}
diff --git a/routes/routes.go b/routes/routes.go
index 096f4d5..34e2036 100644
--- a/routes/routes.go
+++ b/routes/routes.go
@@ -5,6 +5,7 @@ import (
 	"gitlab.informatika.org/ocw/ocw-backend/routes/auth"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/common"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/course"
+	"gitlab.informatika.org/ocw/ocw-backend/routes/lesson"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/material"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/quiz"
 	"gitlab.informatika.org/ocw/ocw-backend/routes/reset"
@@ -22,6 +23,7 @@ type AppRouter struct {
 	reset.ResetRoutes
 	quiz.QuizRoutes
 	course.CourseRoutes
+	lesson.LessonRoutes
 	material.MaterialRoutes
 
 	// Utility
diff --git a/service/di.go b/service/di.go
index 3a133f5..88695f6 100644
--- a/service/di.go
+++ b/service/di.go
@@ -6,6 +6,7 @@ import (
 	"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/lesson"
 	"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"
@@ -71,6 +72,12 @@ var ServiceTestSet = wire.NewSet(
 		wire.Struct(new(quiz.QuizServiceImpl), "*"),
 		wire.Bind(new(quiz.QuizService), new(*quiz.QuizServiceImpl)),
 	),
+
+	// Lesson Service
+	wire.NewSet(
+		wire.Struct(new(lesson.LessonServiceImpl), "*"),
+		wire.Bind(new(lesson.LessonService), new(*lesson.LessonServiceImpl)),
+	),
 )
 
 var ServiceSet = wire.NewSet(
diff --git a/service/lesson/add.go b/service/lesson/add.go
new file mode 100644
index 0000000..9258dcb
--- /dev/null
+++ b/service/lesson/add.go
@@ -0,0 +1,68 @@
+package lesson
+
+import (
+	domLesson "gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/user"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/auth/token"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+func (l LessonServiceImpl) AddLesson(payload lesson.AddLessonRequestPayload) error {
+	// Validate Role
+	claim, err := l.TokenUtil.Validate(payload.AddLessonToken, token.Access)
+
+	// Invalid Token
+	if err != nil {
+		return web.NewResponseErrorFromError(err, web.TokenError)
+	}
+
+	// Unauthorized Role
+	if claim.Role == user.Student {
+		return web.NewResponseErrorFromError(err, web.UnauthorizedAccess)
+	}
+
+	err = l.LessonRepository.AddLesson(domLesson.Lesson{
+		Name:        payload.Name,
+		CourseID:    payload.CourseID,
+		Order:       payload.Order,
+		Description: payload.Description,
+	})
+
+	if err != nil {
+		// Some uncaught error
+		return err
+	}
+
+	return nil
+}
+
+func (l LessonServiceImpl) AddLessonMaterial(payload materials.AddLessonMaterialsRequestPayload) error {
+	// Validate Role
+	claim, err := l.TokenUtil.Validate(payload.AddLessonMaterialsToken, token.Access)
+
+	// Invalid Token
+	if err != nil {
+		return web.NewResponseErrorFromError(err, web.TokenError)
+	}
+
+	// Unauthorized Role
+	if claim.Role == user.Student {
+		return web.NewResponseErrorFromError(err, web.UnauthorizedAccess)
+	}
+
+	err = l.LessonMaterialsRepository.AddLessonMaterial(domLesson.LessonMaterials{
+		LessonID:   payload.LessonID,
+		Order:      payload.Order,
+		MaterialID: payload.MaterialID,
+		Contents:   payload.Contents,
+	})
+
+	if err != nil {
+		// Some uncaught error
+		return err
+	}
+
+	return nil
+}
diff --git a/service/lesson/delete.go b/service/lesson/delete.go
new file mode 100644
index 0000000..187b6d0
--- /dev/null
+++ b/service/lesson/delete.go
@@ -0,0 +1,57 @@
+package lesson
+
+import (
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/user"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/auth/token"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+func (l LessonServiceImpl) DeleteLesson(payload lesson.DeleteByUUIDRequestPayload) error {
+	// Validate Role
+	claim, err := l.TokenUtil.Validate(payload.DeleteLessonToken, token.Access)
+
+	// Invalid Token
+	if err != nil {
+		return web.NewResponseErrorFromError(err, web.TokenError)
+	}
+
+	// Unauthorized Role
+	if claim.Role == user.Student {
+		return web.NewResponseErrorFromError(err, web.UnauthorizedAccess)
+	}
+
+	err = l.LessonRepository.DeleteLesson(payload.ID)
+
+	if err != nil {
+		// Uncaught error
+		return err
+	}
+
+	return nil
+}
+
+func (l LessonServiceImpl) DeleteLessonMaterial(payload materials.DeleteByUUIDRequestPayload) error {
+	// Validate Role
+	claim, err := l.TokenUtil.Validate(payload.DeleteLessonMaterialsToken, token.Access)
+
+	// Invalid Token
+	if err != nil {
+		return web.NewResponseErrorFromError(err, web.TokenError)
+	}
+
+	// Unauthorized Role
+	if claim.Role == user.Student {
+		return web.NewResponseErrorFromError(err, web.UnauthorizedAccess)
+	}
+
+	err = l.LessonMaterialsRepository.DeleteLessonMaterial(payload.ID)
+
+	if err != nil {
+		// Uncaught error
+		return err
+	}
+
+	return nil
+}
\ No newline at end of file
diff --git a/service/lesson/get.go b/service/lesson/get.go
new file mode 100644
index 0000000..3b3798b
--- /dev/null
+++ b/service/lesson/get.go
@@ -0,0 +1,67 @@
+package lesson
+
+import (
+	"errors"
+
+	domLesson "gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+	"gorm.io/gorm"
+)
+
+func (l LessonServiceImpl) GetLesson(payload lesson.GetByUUIDRequestPayload) (*domLesson.Lesson, error) {
+	packet, err := l.LessonRepository.GetLesson(payload.ID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return nil, web.NewResponseErrorFromError(err, web.LessonNotExist)
+		}
+		// Some Uncaught error
+		return nil, err
+	}
+	
+	return packet, nil
+}
+
+func (l LessonServiceImpl) GetLessons(payload lesson.GetByStringRequestPayload) ([]domLesson.Lesson, error) {
+	packet, err := l.LessonRepository.GetLessons(payload.ID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return nil, web.NewResponseErrorFromError(err, web.LessonNotExist)
+		}
+		// Some Uncaught error
+		return nil, err
+	}
+	
+	return packet, nil
+}
+
+func (l LessonServiceImpl) GetLessonMaterial(payload materials.GetByUUIDRequestPayload) (*domLesson.LessonMaterials, error) {
+	packet, err := l.LessonMaterialsRepository.GetLessonMaterial(payload.ID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return nil, web.NewResponseErrorFromError(err, web.LessonMaterialNotExist)
+		}
+		// Some Uncaught error
+		return nil, err
+	}
+	
+	return packet, nil
+}
+
+func (l LessonServiceImpl) GetLessonMaterials(payload materials.GetByUUIDRequestPayload) ([]domLesson.LessonMaterials, error) {
+	packet, err := l.LessonMaterialsRepository.GetLessonMaterials(payload.ID)
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return nil, web.NewResponseErrorFromError(err, web.LessonMaterialNotExist)
+		}
+		// Some Uncaught error
+		return nil, err
+	}
+	
+	return packet, nil
+}
\ No newline at end of file
diff --git a/service/lesson/impl.go b/service/lesson/impl.go
new file mode 100644
index 0000000..835b27a
--- /dev/null
+++ b/service/lesson/impl.go
@@ -0,0 +1,16 @@
+package lesson
+
+import (
+	"gitlab.informatika.org/ocw/ocw-backend/repository/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/utils/token"
+	"gitlab.informatika.org/ocw/ocw-backend/service/logger"
+	"gitlab.informatika.org/ocw/ocw-backend/utils/env"
+)
+
+type LessonServiceImpl struct {
+	lesson.LessonRepository
+	lesson.LessonMaterialsRepository
+	*env.Environment
+	token.TokenUtil
+	logger.Logger
+}
\ No newline at end of file
diff --git a/service/lesson/type.go b/service/lesson/type.go
new file mode 100644
index 0000000..3cdae1a
--- /dev/null
+++ b/service/lesson/type.go
@@ -0,0 +1,20 @@
+package lesson
+
+import (
+	domLesson "gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+)
+
+type LessonService interface {
+	GetLesson(payload lesson.GetByUUIDRequestPayload) (*domLesson.Lesson, error)
+	GetLessons(payload lesson.GetByStringRequestPayload) ([]domLesson.Lesson, error)
+	AddLesson(payload lesson.AddLessonRequestPayload) error
+	UpdateLesson(payload lesson.UpdateLessonRequestPayload) error
+	DeleteLesson(payload lesson.DeleteByUUIDRequestPayload) error
+	GetLessonMaterial(payload materials.GetByUUIDRequestPayload) (*domLesson.LessonMaterials, error)
+	GetLessonMaterials(payload materials.GetByUUIDRequestPayload) ([]domLesson.LessonMaterials, error)
+	AddLessonMaterial(payload materials.AddLessonMaterialsRequestPayload) error
+	UpdateLessonMaterial(payload materials.UpdateLessonMaterialsRequestPayload) error
+	DeleteLessonMaterial(payload materials.DeleteByUUIDRequestPayload) error
+}
\ No newline at end of file
diff --git a/service/lesson/update.go b/service/lesson/update.go
new file mode 100644
index 0000000..4d80a4e
--- /dev/null
+++ b/service/lesson/update.go
@@ -0,0 +1,79 @@
+package lesson
+
+import (
+	"errors"
+
+	domLesson "gitlab.informatika.org/ocw/ocw-backend/model/domain/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/domain/user"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/auth/token"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson"
+	"gitlab.informatika.org/ocw/ocw-backend/model/web/lesson/materials"
+	"gorm.io/gorm"
+)
+
+func (l LessonServiceImpl) UpdateLesson(payload lesson.UpdateLessonRequestPayload) error {
+	// Validate Role
+	claim, err := l.TokenUtil.Validate(payload.UpdateLessonToken, token.Access)
+
+	// Invalid Token
+	if err != nil {
+		return web.NewResponseErrorFromError(err, web.TokenError)
+	}
+
+	// Unauthorized Role
+	if claim.Role == user.Student {
+		return web.NewResponseErrorFromError(err, web.UnauthorizedAccess)
+	}
+
+	err = l.LessonRepository.UpdateLesson(domLesson.Lesson{
+		ID:          payload.ID,
+		Name:        payload.Name,
+		CourseID:    payload.CourseID,
+		Order:       payload.Order,
+		Description: payload.Description,
+	})
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return web.NewResponseErrorFromError(err, web.LessonNotExist)
+		}
+		// Uncaught error
+		return err
+	}
+
+	return nil
+}
+
+func (l LessonServiceImpl) UpdateLessonMaterial(payload materials.UpdateLessonMaterialsRequestPayload) error {
+	// Validate Role
+	claim, err := l.TokenUtil.Validate(payload.UpdateLessonMaterialsToken, token.Access)
+
+	// Invalid Token
+	if err != nil {
+		return web.NewResponseErrorFromError(err, web.TokenError)
+	}
+
+	// Unauthorized Role
+	if claim.Role == user.Student {
+		return web.NewResponseErrorFromError(err, web.UnauthorizedAccess)
+	}
+
+	err = l.LessonMaterialsRepository.UpdateLessonMaterial(domLesson.LessonMaterials{
+		ID:         payload.ID,
+		LessonID:   payload.LessonID,
+		Order:      payload.Order,
+		MaterialID: payload.MaterialID,
+		Contents:   payload.Contents,
+	})
+
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return web.NewResponseErrorFromError(err, web.LessonMaterialNotExist)
+		}
+		// Uncaught error
+		return err
+	}
+
+	return nil
+}
-- 
GitLab