diff --git a/src/database/Database.go b/src/database/Database.go
index 1ef3b733ef12a291d93001137bb2fcddf929ef72..ff271cbb6f8f3e66d21f4f0ce671a42588d1ff98 100644
--- a/src/database/Database.go
+++ b/src/database/Database.go
@@ -40,6 +40,7 @@ func initialize() {
 
 	dbInstance.AutoMigrate(&models.SystemLogs{})
 	dbInstance.AutoMigrate(&models.BimbinganLogs{})
+	dbInstance.AutoMigrate(&models.Topics{})
 	dbInstance.AutoMigrate(&models.BatchSeminar{})
 	dbInstance.AutoMigrate(&models.BatchSidang{})
 	dbInstance.AutoMigrate(&models.JadwalSidang{})
diff --git a/src/handler/handler.go b/src/handler/handler.go
index a232a8c59a01405f636b89b7a2d7da3a719814eb..d7c8ee8d99483060de631af54349d9a3eca63715 100644
--- a/src/handler/handler.go
+++ b/src/handler/handler.go
@@ -16,16 +16,19 @@ import (
 	statusMahasiswaTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/status_mahasiswa/transport"
 	systemLogConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/system_log/config"
 	systemLogTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/system_log/transport"
+	topicAllocationConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/config"
+	topicAllocationTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/transport"
 )
 
 type Service struct {
-	InternalSystemLogHandler    *systemLogTransport.InternalSystemLogHandler
-	AdminSytemLogHandler        *systemLogTransport.AdminSystemLogHandler
+	InternalSystemLogHandler *systemLogTransport.InternalSystemLogHandler
+	AdminSytemLogHandler     *systemLogTransport.AdminSystemLogHandler
+	AdminBimbinganLogHandler *bimbinganLogTransport.AdminBimbinganLogHandler
+	AdminTopicAllocationHandler *topicAllocationTransport.AdminTopicAllocationHandler
 	BatchSeminarHandler         *batchSeminarTransport.AdminBatchSeminarHandler
 	BatchSidangHandler          *batchSidangTransport.AdminBatchSidangHandler
 	JadwalSidangHandler         *jadwalSidangTransport.AdminJadwalSidangHandler
 	JadwalSeminarHandler        *jadwalSeminarTransport.AdminJadwalSeminarHandler
-	AdminBimbinganLogHandler    *bimbinganLogTransport.AdminBimbinganLogHandler
 	AdminStatusMahasiswaHandler *statusMahasiswaTransport.AdminStatusMahasiswaHandler
 }
 
@@ -45,6 +48,10 @@ func MakeHandler() *Service {
 		DBWrite: dbWrite,
 		DBRead:  dbRead,
 	})
+	AdminTopicAllocationHandler := topicAllocationTransport.NewAdminTopicAllocationHandler(topicAllocationConfig.TopicAllocationTransportConfig{
+		DBWrite: dbWrite,
+		DBRead: dbRead,
+	})
 	AdminBatchSeminarHandler := batchSeminarTransport.NewAdminBatchSeminarHandler(batchSeminarConfig.BatchSeminarTransportConfig{
 		DBWrite: dbWrite,
 		DBRead:  dbRead,
@@ -65,15 +72,17 @@ func MakeHandler() *Service {
 		DBWrite: dbWrite,
 		DBRead:  dbRead,
 	})
-
+	
 	return &Service{
-		InternalSystemLogHandler:    InternalSystemLogHandler,
-		AdminSytemLogHandler:        AdminSystemLogHandler,
-		AdminBimbinganLogHandler:    AdminBimbinganLogHandler,
+		InternalSystemLogHandler: InternalSystemLogHandler,
+		AdminSytemLogHandler:     AdminSystemLogHandler,
+		AdminBimbinganLogHandler: AdminBimbinganLogHandler,
+		AdminTopicAllocationHandler: AdminTopicAllocationHandler,
 		BatchSeminarHandler:         AdminBatchSeminarHandler,
 		BatchSidangHandler:          AdminBatchSidangHandler,
 		JadwalSidangHandler:         AdminJadwalSidangHandler,
 		JadwalSeminarHandler:        AdminJadwalSeminarHandler,
 		AdminStatusMahasiswaHandler: AdminStatusMahasiswaHandler,
+	
 	}
 }
diff --git a/src/handler/server.go b/src/handler/server.go
index 005522dc8c8e8a799bd6bb7d148ae79eee9bf275..3fb18a9e2dd02bb812ad7e9f975d38c0ff603db0 100644
--- a/src/handler/server.go
+++ b/src/handler/server.go
@@ -23,6 +23,7 @@ func (s *Service) InitializeRoutes() *echo.Echo {
 	adminGroup.Use(middleware.BearerAuth("TIMTA"))
 	s.AdminSytemLogHandler.MountAdmin(adminGroup)
 	s.AdminBimbinganLogHandler.MountAdmin(adminGroup)
+	s.AdminTopicAllocationHandler.MountAdmin(adminGroup)
 	s.BatchSeminarHandler.MountAdmin(adminGroup)
 	s.BatchSidangHandler.MountAdmin(adminGroup)
 	s.JadwalSeminarHandler.MountAdmin(adminGroup)
diff --git a/src/models/Topics.go b/src/models/Topics.go
new file mode 100644
index 0000000000000000000000000000000000000000..b82cb698d787ff921bd20d14ff59ae9f33de8f7c
--- /dev/null
+++ b/src/models/Topics.go
@@ -0,0 +1,10 @@
+package models
+
+type Topics struct {
+	ID          string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" json:"id"`
+	ImgUrl      string `gorm:"column:img_url" json:"imgUrl"`
+	IDLecturer  string `gorm:"column:id_lecturer" json:"id_lecturer"`
+	LectName 	string `gorm:"column:lect_name" json:"lect_name"`
+	Title       string `gorm:"column:title" json:"Title"`
+	Description string `gorm:"column:description" json:"description"`
+}
\ No newline at end of file
diff --git a/src/module/topic_allocation/config/common.go b/src/module/topic_allocation/config/common.go
new file mode 100644
index 0000000000000000000000000000000000000000..a471c3472521bafe00e451e2b6ecc807c41f2cca
--- /dev/null
+++ b/src/module/topic_allocation/config/common.go
@@ -0,0 +1,8 @@
+package config
+
+import "gorm.io/gorm"
+
+type TopicAllocationTransportConfig struct {
+	DBWrite *gorm.DB
+	DBRead  *gorm.DB
+}
diff --git a/src/module/topic_allocation/entity/topic_allocation.go b/src/module/topic_allocation/entity/topic_allocation.go
new file mode 100644
index 0000000000000000000000000000000000000000..339cf4f53530a1b71cb8a81e6b4c9ef33ced9add
--- /dev/null
+++ b/src/module/topic_allocation/entity/topic_allocation.go
@@ -0,0 +1,13 @@
+package entity
+
+type Topic struct {
+	ID          string `json:"id"`
+	IDLecturer  string `json:"id_lecturer"`
+	Title       string `json:"Title"`
+	Description string `json:"description"`
+}
+
+type ParamValues struct {
+	Limit  int
+	Offset int
+}
\ No newline at end of file
diff --git a/src/module/topic_allocation/internal/repository/topic_allocation.go b/src/module/topic_allocation/internal/repository/topic_allocation.go
new file mode 100644
index 0000000000000000000000000000000000000000..af99a75de91b8b5dea5e4e08a6ee68588473efbf
--- /dev/null
+++ b/src/module/topic_allocation/internal/repository/topic_allocation.go
@@ -0,0 +1,98 @@
+package repository
+
+import (
+	"github.com/google/uuid"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity"
+	"gorm.io/gorm"
+)
+
+type TopicAllocationRepo struct {
+	DBWrite *gorm.DB
+	DBRead  *gorm.DB
+}
+
+func NewTopicAllocationRepository(dbWrite *gorm.DB, dbRead *gorm.DB) *TopicAllocationRepo {
+	return &TopicAllocationRepo{
+		DBWrite: dbWrite,
+		DBRead:  dbRead,
+	}
+}
+
+func (repo *TopicAllocationRepo) NewTopic(topic entity.Topic) (output entity.Topic, err error) {
+	topic.ID = uuid.New().String()
+
+	result := repo.DBWrite.Create(&topic)
+	if result.Error != nil {
+		return entity.Topic{}, result.Error
+	}
+
+	return topic, nil
+}
+
+func (repo *TopicAllocationRepo) GetTopic(page int, limit int, search string, id string) (output []entity.Topic, err error) {
+	var topics []entity.Topic
+
+	result := repo.DBRead.Find(&topics)
+	if search != "" {
+		result = result.Where("Title LIKE ?", "%" + search + "%").Find(&topics)
+		if result.Error != nil {
+			return nil, result.Error
+		}
+	}
+	
+	if id != "" {
+		result = result.Where("id_lecturer = ?", id).Find(&topics)
+		if result.Error != nil {
+			return nil, result.Error
+		}
+	}
+	
+	if page != 0 {
+		result = result.Offset((page - 1) * limit).Find(&topics)
+		if result.Error != nil {
+			return nil, result.Error
+		}
+	}
+
+	if limit != 0 {
+		result = result.Limit(limit).Find(&topics)
+		if result.Error != nil {
+			return nil, result.Error
+		}
+	}
+
+	return topics, nil
+}
+
+func (repo *TopicAllocationRepo) GetTopicByID(ID string) (output entity.Topic, err error) {
+	var topic entity.Topic
+
+	result := repo.DBRead.Where("ID = ?", ID).First(&topic)
+	if result.Error != nil {
+		return entity.Topic{}, result.Error
+	}
+
+	return topic, nil
+}
+
+func (repo *TopicAllocationRepo) UpdateTopic(topic entity.Topic) (output entity.Topic, err error) {
+	result := repo.DBWrite.Save(&topic)
+
+	if result.Error != nil {
+		return entity.Topic{}, result.Error
+	}
+
+	return topic, nil
+}
+
+func (repo *TopicAllocationRepo) DeleteTopic(ID string) (err error) {
+	var topic entity.Topic
+
+	result := repo.DBWrite.Where("ID = ?", ID).Delete(&topic)
+
+	if result.Error != nil {
+		return result.Error
+	}
+
+	return nil
+}
diff --git a/src/module/topic_allocation/internal/usecase/repository.go b/src/module/topic_allocation/internal/usecase/repository.go
new file mode 100644
index 0000000000000000000000000000000000000000..98ba932a1d467f344420be9dc05742990b942719
--- /dev/null
+++ b/src/module/topic_allocation/internal/usecase/repository.go
@@ -0,0 +1,11 @@
+package usecase
+
+import "gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity"
+
+type TopicAllocationRepo interface {
+	NewTopic(topic entity.Topic) (output entity.Topic, err error)
+	GetTopic(page int, limit int, search string, id string) (output []entity.Topic, err error)
+	GetTopicByID(ID string) (output entity.Topic, err error)
+	UpdateTopic(topic entity.Topic) (output entity.Topic, err error)
+	DeleteTopic(ID string) (err error)
+}
\ No newline at end of file
diff --git a/src/module/topic_allocation/internal/usecase/topic_allocation.go b/src/module/topic_allocation/internal/usecase/topic_allocation.go
new file mode 100644
index 0000000000000000000000000000000000000000..8aef0b2bf3d77359c646fd0a578df84ac2fda7f4
--- /dev/null
+++ b/src/module/topic_allocation/internal/usecase/topic_allocation.go
@@ -0,0 +1,62 @@
+package usecase
+
+import (
+	"gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/utils"
+)
+
+type TopicUsecase interface {
+	AddTopic(topic entity.Topic) (entity.Topic, error)
+	GetTopic(param utils.PageLimitSearchID) ([]entity.Topic, error)
+	GetTopicByID(param string) (entity.Topic, error)
+	UpdateTopic(topic entity.Topic) (entity.Topic, error)
+	DeleteTopic(param string) (error)
+}
+
+type TopicUc struct {
+	topicAllocationRepo TopicAllocationRepo
+}
+
+func NewTopicUc(topicAllocationRepo TopicAllocationRepo) *TopicUc {
+	return &TopicUc{
+		topicAllocationRepo: topicAllocationRepo,
+	}
+}
+
+func (uc *TopicUc) AddTopic(topic entity.Topic) (entity.Topic, error) {
+	newTopic, err := uc.topicAllocationRepo.NewTopic(topic)
+
+	if err != nil {
+		return entity.Topic{}, err
+	}
+
+	return newTopic, nil
+}
+
+func (uc *TopicUc) GetTopic(param utils.PageLimitSearchID) ([]entity.Topic, error) {
+	return uc.topicAllocationRepo.GetTopic(param.Page, param.Limit, param.Search, param.ID)
+}
+
+func (uc *TopicUc) GetTopicByID(param string) (entity.Topic, error) {
+	return uc.topicAllocationRepo.GetTopicByID(param)
+}
+
+func (uc *TopicUc) UpdateTopic(topic entity.Topic) (entity.Topic, error) {
+	updatedTopic, err := uc.topicAllocationRepo.UpdateTopic(topic)
+
+	if err != nil {
+		return entity.Topic{}, err
+	}
+
+	return updatedTopic, nil
+}
+
+func (uc *TopicUc) DeleteTopic(param string) (error) {
+	err := uc.topicAllocationRepo.DeleteTopic(param)
+
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
\ No newline at end of file
diff --git a/src/module/topic_allocation/transport/admin_handler.go b/src/module/topic_allocation/transport/admin_handler.go
new file mode 100644
index 0000000000000000000000000000000000000000..d46d6993691c40329c90d5b41b4d768686fde199
--- /dev/null
+++ b/src/module/topic_allocation/transport/admin_handler.go
@@ -0,0 +1,115 @@
+package transport
+
+import (
+	"net/http"
+
+	"github.com/labstack/echo"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/entity"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/config"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/internal/repository"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/module/topic_allocation/internal/usecase"
+	"gitlab.informatika.org/k-01-11/graduit-be/src/utils"
+)
+
+type AdminTopicAllocationHandler struct {
+	topicUsecase usecase.TopicUsecase
+}
+
+func NewAdminTopicAllocationHandler(cfg config.TopicAllocationTransportConfig) *AdminTopicAllocationHandler {
+	topicAllocationRepository := repository.NewTopicAllocationRepository(cfg.DBWrite, cfg.DBRead)
+	topicUseCase := usecase.NewTopicUc(topicAllocationRepository)
+
+	return &AdminTopicAllocationHandler{
+		topicUsecase: topicUseCase,
+	}
+}
+
+func (admin *AdminTopicAllocationHandler) MountAdmin(group *echo.Group) {
+	group.GET("/alokasi-topik/:id", admin.GetTopicByID)
+	group.GET("/alokasi-topik", admin.GetTopics)
+	group.POST("/alokasi-topik", admin.AddTopic)
+	group.PUT("/alokasi-topik/:id", admin.UpdateTopic)
+	group.DELETE("/alokasi-topik/:id", admin.DeleteTopic)
+}
+
+func (admin *AdminTopicAllocationHandler) GetTopics(c echo.Context) error {
+	param, err := utils.GetPageLimitSearchID(c.QueryParams())
+	
+	if err != nil {
+		return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, err.Error(), nil))
+	}
+
+	list, err := admin.topicUsecase.GetTopic(param)
+	if err != nil {
+		return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil))
+	}
+
+	return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topics retreived", list))
+}
+
+func (admin *AdminTopicAllocationHandler) GetTopicByID(c echo.Context) error {
+	id := c.Param("id")
+
+	if id != "" {
+		item, err := admin.topicUsecase.GetTopicByID(id)
+
+		if err != nil {
+			return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil))
+		}
+
+		return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topics retreived", item))
+	} else {
+		return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, "Incorrect URL", nil))
+	}
+}
+
+func (admin *AdminTopicAllocationHandler) AddTopic(c echo.Context) error {
+	topic := new(entity.Topic)
+
+	if err := c.Bind(topic); err != nil {
+		return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil))
+	}
+
+	newTopic, err := admin.topicUsecase.AddTopic(*topic)
+	if err != nil {
+		return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, err.Error(), nil))
+	}
+
+	return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topic added successfully", newTopic))
+}
+
+func (admin *AdminTopicAllocationHandler) UpdateTopic(c echo.Context) error {
+	id := c.Param("id")
+
+	if id != "" {
+		topic := new(entity.Topic)
+		c.Bind(topic)
+		topic.ID = id
+
+		newItem, err := admin.topicUsecase.UpdateTopic(*topic)
+
+		if err != nil {
+			return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, "Failed to update topic", nil))
+		}
+
+		return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topic updated", newItem))
+	} else {
+		return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, "Please provide topic id", nil))
+	}
+}
+
+func (admin *AdminTopicAllocationHandler) DeleteTopic(c echo.Context) error {
+	id := c.Param("id")
+
+	if id != "" {
+		err := admin.topicUsecase.DeleteTopic(id)
+
+		if err != nil {
+			return c.JSON(http.StatusInternalServerError, utils.ResponseDetailOutput(false, http.StatusInternalServerError, "Failed to delete topic", nil))
+		}
+
+		return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "Topic deleted successfully", nil))
+	} else {
+		return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, "Please provide topic id", nil))
+	}
+}
\ No newline at end of file
diff --git a/src/utils/helper.go b/src/utils/helper.go
index 74fa2d891fe487d898764f1b2238e7b9ffeecf85..0212d684e82f165fa2f980230697d6736a8fb5f1 100644
--- a/src/utils/helper.go
+++ b/src/utils/helper.go
@@ -17,6 +17,13 @@ type ResponseDetail struct {
 	Data    interface{} `json:"data,omitempty"`
 }
 
+type PageLimitSearchID struct {
+	Page int
+	Limit int
+	Search string
+	ID string
+}
+
 func ResponseDetailOutput(success bool, code int, message string, data interface{}) ResponseDetail {
 	res := ResponseDetail{
 		Success: success,
@@ -53,3 +60,50 @@ func GetLimitOffset(urlValues url.Values) (output LimitOffset, err error) {
 
 	return *param, nil
 }
+
+func GetID(urlValues url.Values) (output string, err error) {
+	id := urlValues.Get("id")
+	if id != "" {
+		return id, nil
+	} else {
+		return "", nil
+	}
+}
+
+func GetPageLimitSearchID(urlValues url.Values) (output PageLimitSearchID, err error) {
+	param := new(PageLimitSearchID)
+	page := urlValues.Get("page")
+	limit := urlValues.Get("limit")
+	search := urlValues.Get("search")
+	id := urlValues.Get("idPembimbing")
+
+	if page != "" {
+		pageInt, err := strconv.Atoi(page)
+
+		if err != nil {
+			return PageLimitSearchID{}, err
+		}
+
+		param.Page = pageInt
+	}
+
+	if limit != "" {
+		limitInt, err := strconv.Atoi(limit)
+
+		if err != nil {
+			return PageLimitSearchID{}, err
+		}
+
+		param.Limit = limitInt
+	}
+
+	if search != "" {
+		param.Search = search
+	}
+
+	if id != "" {
+		param.ID = id
+	}
+
+	return *param, nil
+}
\ No newline at end of file