diff --git a/.env.example b/.env.example
index 72f7f62791250d9e59c7aa77dcac87908056c761..636ce5ecb1f6cbdeac73878e12263937afd06f5b 100644
--- a/.env.example
+++ b/.env.example
@@ -6,15 +6,4 @@ POSTGRES_DATABASE=
 AUTH_SERVICE_URL=http://localhost:3001
 FE_URL=http://localhost:5173
 
-KONF_PERIODE_KEY=PERIODE
-KONF_MIN_BIMBINGAN_KEY=MINIMAL_BIMBINGAN
-KONF_AWAL_PENDAFTARAN_KEY=AWAL_PENDAFTARAN
-KONF_AKHIR_PENDAFTARAN_KEY=AKHIR_PENDAFTARAN
-KONF_AWAL_SEMPRO_KEY=AWAL_SEMPRO
-KONF_AKHIR_SEMPRO_KEY=AKHIR_SEMPRO
-KONF_AWAL_SEM_TESIS_KEY=AWAL_SEM_TESIS
-KONF_AKHIR_SEM_TESIS_KEY=AKHIR_SEM_TESIS
-KONF_AWAL_SIDANG_KEY=AWAL_SIDANG
-KONF_AKHIR_SIDANG_KEY=AKHIR_SIDANG
-
 COOKIE_NAME=gradu-it.access-token
diff --git a/package-lock.json b/package-lock.json
index bd68a73e016611adc98632e4bcfadd3d500ebfa3..88b4e7cf5b71bf20a1847997a4f1f8261ae0640b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1944,13 +1944,13 @@
       }
     },
     "node_modules/@nestjs/platform-express": {
-      "version": "10.3.3",
-      "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.3.tgz",
-      "integrity": "sha512-GGKSEU48Os7nYFIsUM0nutuFUGn5AbeP8gzFBiBCAtiuJWrXZXpZ58pMBYxAbMf7IrcOZFInHEukjHGAQU0OZw==",
+      "version": "10.3.7",
+      "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.7.tgz",
+      "integrity": "sha512-noNJ+PyIxQJLCKfuXz0tcQtlVAynfLIuKy62g70lEZ86UrIqSrZFqvWs/rFUgkbT6J8H7Rmv11hASOnX+7M2rA==",
       "dependencies": {
         "body-parser": "1.20.2",
         "cors": "2.8.5",
-        "express": "4.18.2",
+        "express": "4.19.2",
         "multer": "1.4.4-lts.1",
         "tslib": "2.6.2"
       },
@@ -3851,9 +3851,9 @@
       "dev": true
     },
     "node_modules/cookie": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
-      "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+      "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
       "engines": {
         "node": ">= 0.6"
       }
@@ -4593,16 +4593,16 @@
       }
     },
     "node_modules/express": {
-      "version": "4.18.2",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
-      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+      "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
       "dependencies": {
         "accepts": "~1.3.8",
         "array-flatten": "1.1.1",
-        "body-parser": "1.20.1",
+        "body-parser": "1.20.2",
         "content-disposition": "0.5.4",
         "content-type": "~1.0.4",
-        "cookie": "0.5.0",
+        "cookie": "0.6.0",
         "cookie-signature": "1.0.6",
         "debug": "2.6.9",
         "depd": "2.0.0",
@@ -4633,29 +4633,6 @@
         "node": ">= 0.10.0"
       }
     },
-    "node_modules/express/node_modules/body-parser": {
-      "version": "1.20.1",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
-      "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
-      "dependencies": {
-        "bytes": "3.1.2",
-        "content-type": "~1.0.4",
-        "debug": "2.6.9",
-        "depd": "2.0.0",
-        "destroy": "1.2.0",
-        "http-errors": "2.0.0",
-        "iconv-lite": "0.4.24",
-        "on-finished": "2.4.1",
-        "qs": "6.11.0",
-        "raw-body": "2.5.1",
-        "type-is": "~1.6.18",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8",
-        "npm": "1.2.8000 || >= 1.4.16"
-      }
-    },
     "node_modules/express/node_modules/debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -4674,20 +4651,6 @@
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
       "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
     },
-    "node_modules/express/node_modules/raw-body": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
-      "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
-      "dependencies": {
-        "bytes": "3.1.2",
-        "http-errors": "2.0.0",
-        "iconv-lite": "0.4.24",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/external-editor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
@@ -4937,9 +4900,9 @@
       "dev": true
     },
     "node_modules/follow-redirects": {
-      "version": "1.15.5",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
-      "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
+      "version": "1.15.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
       "funding": [
         {
           "type": "individual",
diff --git a/src/alokasi-ruangan/alokasi-ruangan.controller.ts b/src/alokasi-ruangan/alokasi-ruangan.controller.ts
index 1994fd435d23c13bf931d45fdd02a01344096301..7d8b01d99043b3b6827afdd02095b5903fd0c0d5 100644
--- a/src/alokasi-ruangan/alokasi-ruangan.controller.ts
+++ b/src/alokasi-ruangan/alokasi-ruangan.controller.ts
@@ -13,7 +13,6 @@ import {
   ApiOkResponse,
   ApiTags,
 } from "@nestjs/swagger";
-import { RoleEnum } from "src/entities/pengguna.entity";
 import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
 import { Roles } from "src/middlewares/roles.decorator";
 import { RolesGuard } from "src/middlewares/roles.guard";
@@ -25,12 +24,13 @@ import {
   UpdateAlokasiRuanganRespDto,
 } from "./alokasi-ruangan.dto";
 import { AlokasiRuanganService } from "./alokasi-ruangan.service";
+import { HIGH_AUTHORITY_ROLES } from "src/helper/roles";
 
 @ApiTags("Alokasi Ruangan")
 @ApiBearerAuth()
 @ApiCookieAuth()
 @UseGuards(CustomAuthGuard, RolesGuard)
-@Roles(RoleEnum.ADMIN, RoleEnum.TU)
+@Roles(...HIGH_AUTHORITY_ROLES)
 @Controller("alokasi-ruangan")
 export class AlokasiRuanganController {
   constructor(private readonly alokasiRuanganService: AlokasiRuanganService) {}
diff --git a/src/alokasi-topik/alokasi-topik.controller.ts b/src/alokasi-topik/alokasi-topik.controller.ts
index 6fa4e26ac50478a46780cab0a29e11ccda0d7035..069ae9fb2290d3831476d20cb7068beae81fbed4 100644
--- a/src/alokasi-topik/alokasi-topik.controller.ts
+++ b/src/alokasi-topik/alokasi-topik.controller.ts
@@ -9,22 +9,24 @@ import {
   Post,
   Put,
   Query,
+  Req,
   UseGuards,
 } from "@nestjs/common";
 import {
   ApiBearerAuth,
   ApiCookieAuth,
+  ApiCreatedResponse,
   ApiOkResponse,
+  ApiOperation,
   ApiTags,
 } from "@nestjs/swagger";
 import { RoleEnum } from "src/entities/pengguna.entity";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
 import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
 import { Roles } from "src/middlewares/roles.decorator";
 import { RolesGuard } from "src/middlewares/roles.guard";
 import {
   CreateBulkTopikDto,
-  CreateRespDto,
+  TopikIdRespDto,
   CreateTopikDto,
   GetAllRespDto,
   OmittedTopik,
@@ -34,6 +36,9 @@ import {
   createBulkRespDto,
 } from "./alokasi-topik.dto";
 import { AlokasiTopikService } from "./alokasi-topik.service";
+import { Request } from "express";
+import { AuthDto } from "src/auth/auth.dto";
+import { HIGH_AUTHORITY_ROLES, isHighAuthority } from "src/helper/roles";
 
 @ApiTags("Alokasi Topik")
 @ApiCookieAuth()
@@ -41,82 +46,129 @@ import { AlokasiTopikService } from "./alokasi-topik.service";
 @Controller("alokasi-topik")
 @UseGuards(CustomAuthGuard, RolesGuard)
 export class AlokasiTopikController {
-  constructor(
-    private alokasiTopikService: AlokasiTopikService,
-    private konfService: KonfigurasiService,
-  ) {}
+  constructor(private alokasiTopikService: AlokasiTopikService) {}
 
-  @ApiOkResponse({ type: CreateRespDto })
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
+  @ApiOperation({
+    summary: "Create new topik. Roles: S2_TIM_TESIS, ADMIN, S2_PEMBIMBING",
+  })
+  @ApiCreatedResponse({ type: TopikIdRespDto })
+  @Roles(...HIGH_AUTHORITY_ROLES, RoleEnum.S2_PEMBIMBING)
   @Post()
-  async create(@Body() createDto: CreateTopikDto) {
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) throw new BadRequestException("Periode belum dikonfigurasi.");
+  async create(
+    @Body() createDto: CreateTopikDto,
+    @Req() req: Request,
+  ): Promise<TopikIdRespDto> {
+    const { roles, id } = req.user as AuthDto;
+    // user only has S2_PEMBIMBING role
+    if (!isHighAuthority(roles) && createDto.idPengaju !== id) {
+      throw new BadRequestException("Pengaju ID harus sama dengan user ID");
+    }
 
-    return await this.alokasiTopikService.create({ ...createDto, periode });
+    return await this.alokasiTopikService.create(createDto);
   }
 
+  @ApiOperation({
+    summary: "Create multiple topik. Roles: S2_TIM_TESIS, ADMIN",
+  })
   @ApiOkResponse({ type: createBulkRespDto })
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
+  @Roles(...HIGH_AUTHORITY_ROLES)
   @Post("/bulk")
   async createBulk(@Body() createDto: CreateBulkTopikDto) {
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) throw new BadRequestException("Periode belum dikonfigurasi.");
-
-    return await this.alokasiTopikService.createBulk(createDto, periode);
+    return await this.alokasiTopikService.createBulk(createDto);
   }
 
+  @ApiOperation({
+    summary:
+      "Get topik by ID. Roles: S2_TIM_TESIS, ADMIN, S2_PEMBIMBING, S2_MAHASISWA",
+  })
   @ApiOkResponse({ type: OmittedTopik })
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
+  @Roles(...HIGH_AUTHORITY_ROLES, RoleEnum.S2_PEMBIMBING, RoleEnum.S2_MAHASISWA)
   @Get("/:id")
   async getById(@Param() params: TopikParamDto) {
-    const res = await this.alokasiTopikService.findById(params.id);
+    const res = await this.alokasiTopikService.findActiveTopikById(params.id);
     if (!res) throw new NotFoundException();
     return res as OmittedTopik;
   }
 
+  @ApiOperation({
+    summary:
+      "Get all topik. Roles: S2_TIM_TESIS, ADMIN, S2_MAHASISWA, S2_PEMBIMBING",
+  })
   @ApiOkResponse({ type: GetAllRespDto })
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN, RoleEnum.S2_MAHASISWA)
+  @Roles(...HIGH_AUTHORITY_ROLES, RoleEnum.S2_MAHASISWA, RoleEnum.S2_PEMBIMBING)
   @Get()
   async getAll(
     @Query()
     query: TopikQueryDto,
   ) {
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
+    return await this.alokasiTopikService.findAllActiveTopikCreatedByPembimbing(
+      {
+        ...query,
+        page: query.page || 1,
+      },
     );
-
-    if (!periode) throw new BadRequestException("Periode belum dikonfigurasi.");
-
-    return await this.alokasiTopikService.findAllCreatedByPembimbing({
-      page: query.page || 1,
-      ...query,
-      periode,
-    });
   }
 
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
+  @ApiOperation({
+    summary: "Update topik. Roles: S2_TIM_TESIS, ADMIN, S2_PEMBIMBING",
+  })
+  @ApiOkResponse({ type: TopikIdRespDto })
+  @Roles(...HIGH_AUTHORITY_ROLES, RoleEnum.S2_PEMBIMBING)
   @Put("/:id")
   async update(
     @Param() params: TopikParamDto,
     @Body() updateDto: UpdateTopikDto,
-  ) {
-    const res = await this.alokasiTopikService.update(params.id, updateDto);
-    if (!res.affected) throw new NotFoundException();
-    return res;
+    @Req() req: Request,
+  ): Promise<TopikIdRespDto> {
+    let idPengaju = undefined;
+    const { roles, id } = req.user as AuthDto;
+    // user only has S2_PEMBIMBING role
+    if (!isHighAuthority(roles)) {
+      if (updateDto.idPengaju !== id) {
+        throw new BadRequestException("Pengaju ID harus sama dengan user ID");
+      }
+      idPengaju = id;
+    }
+
+    const res = await this.alokasiTopikService.update(
+      params.id,
+      updateDto,
+      idPengaju,
+    );
+    if (!res.affected)
+      throw new NotFoundException(
+        "Topik tidak ditemukan di antara topik yang dapat Anda akses",
+      );
+
+    const resp: TopikIdRespDto = { id: params.id };
+
+    return resp;
   }
 
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
+  @ApiOperation({
+    summary: "Delete topik. Roles: S2_TIM_TESIS, ADMIN, S2_PEMBIMBING",
+  })
+  @ApiOkResponse({ type: TopikIdRespDto })
+  @Roles(...HIGH_AUTHORITY_ROLES, RoleEnum.S2_PEMBIMBING)
   @Delete("/:id")
-  async delete(@Param() params: TopikParamDto) {
-    const res = await this.alokasiTopikService.remove(params.id);
-    if (!res.affected) throw new NotFoundException();
-    return res;
+  async delete(
+    @Param() params: TopikParamDto,
+    @Req() req: Request,
+  ): Promise<TopikIdRespDto> {
+    let idPengaju = undefined;
+    const { roles, id } = req.user as AuthDto;
+    // user only has S2_PEMBIMBING role
+    if (!isHighAuthority(roles)) {
+      idPengaju = id;
+    }
+
+    const res = await this.alokasiTopikService.remove(params.id, idPengaju);
+    if (!res.affected)
+      throw new NotFoundException(
+        "Topik tidak ditemukan di antara topik yang dapat Anda akses",
+      );
+
+    const resp: TopikIdRespDto = { id: params.id };
+    return resp;
   }
 }
diff --git a/src/alokasi-topik/alokasi-topik.dto.ts b/src/alokasi-topik/alokasi-topik.dto.ts
index 93e7dd82db19970390d4cef921e1a774ed2ffabc..5c41225c23ddf1fbefe996dfc7f961ad5ecebc01 100644
--- a/src/alokasi-topik/alokasi-topik.dto.ts
+++ b/src/alokasi-topik/alokasi-topik.dto.ts
@@ -61,7 +61,7 @@ export class TopikQueryDto {
   idPembimbing?: string;
 }
 
-export class PengajuDto extends OmitType(Pengguna, ["nim"] as const) {}
+export class PengajuDto extends OmitType(Pengguna, ["nim", "aktif"] as const) {}
 
 export class OmittedTopik extends OmitType(Topik, ["idPengaju"] as const) {
   @ApiProperty({ type: PengajuDto })
@@ -81,7 +81,7 @@ export class createBulkRespDto {
   ids: string[];
 }
 
-export class CreateRespDto {
+export class TopikIdRespDto {
   @ApiProperty()
   id: string;
 }
diff --git a/src/alokasi-topik/alokasi-topik.module.ts b/src/alokasi-topik/alokasi-topik.module.ts
index e9769a4998d5a192e5ee21fa17ad23f4449353fb..f7daaff6363cf0e2d4d1bcedeaea2c38023f6a67 100644
--- a/src/alokasi-topik/alokasi-topik.module.ts
+++ b/src/alokasi-topik/alokasi-topik.module.ts
@@ -5,10 +5,9 @@ import { TypeOrmModule } from "@nestjs/typeorm";
 import { Topik } from "src/entities/topik.entity";
 import { CustomStrategy } from "src/middlewares/custom.strategy";
 import { AuthModule } from "src/auth/auth.module";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
 
 @Module({
-  imports: [TypeOrmModule.forFeature([Topik]), AuthModule, KonfigurasiModule],
+  imports: [TypeOrmModule.forFeature([Topik]), AuthModule],
   providers: [AlokasiTopikService, CustomStrategy],
   controllers: [AlokasiTopikController],
 })
diff --git a/src/alokasi-topik/alokasi-topik.service.ts b/src/alokasi-topik/alokasi-topik.service.ts
index b9056ab744f4cb42d6fc970e629cf3f189afcaec..d52534adfd7f8155ba67dbf0ffe4684b689e9773 100644
--- a/src/alokasi-topik/alokasi-topik.service.ts
+++ b/src/alokasi-topik/alokasi-topik.service.ts
@@ -2,10 +2,10 @@ import { Injectable } from "@nestjs/common";
 import { InjectRepository } from "@nestjs/typeorm";
 import { RoleEnum } from "src/entities/pengguna.entity";
 import { Topik } from "src/entities/topik.entity";
-import { ArrayContains, Like, Repository } from "typeorm";
+import { ArrayContains, ILike, Repository } from "typeorm";
 import {
   CreateBulkTopikDto,
-  CreateRespDto,
+  TopikIdRespDto,
   CreateTopikDto,
   GetAllRespDto,
   UpdateTopikDto,
@@ -16,35 +16,26 @@ import {
 export class AlokasiTopikService {
   constructor(@InjectRepository(Topik) private topikRepo: Repository<Topik>) {}
 
-  async create(
-    createDto: CreateTopikDto & { periode: string },
-  ): Promise<CreateRespDto> {
+  async create(createDto: CreateTopikDto): Promise<TopikIdRespDto> {
     const ids = (await this.topikRepo.insert(createDto)).identifiers;
 
     return { id: ids[0].id };
   }
 
-  async createBulk(
-    createDto: CreateBulkTopikDto,
-    periode: string,
-  ): Promise<createBulkRespDto> {
+  async createBulk(createDto: CreateBulkTopikDto): Promise<createBulkRespDto> {
     const ids = (
-      await this.topikRepo.insert(
-        createDto.data.map((dto) => ({ ...dto, periode })),
-      )
+      await this.topikRepo.insert(createDto.data.map((dto) => ({ ...dto })))
     ).identifiers;
 
     return { ids: ids.map(({ id }) => id) };
   }
 
-  async findById(id: string) {
-    // not periode-protected
+  async findActiveTopikById(id: string) {
     return await this.topikRepo.findOne({
       select: {
         id: true,
         judul: true,
         deskripsi: true,
-        periode: true,
         pengaju: {
           id: true,
           nama: true,
@@ -54,6 +45,7 @@ export class AlokasiTopikService {
       },
       where: {
         id,
+        aktif: true,
       },
       relations: {
         pengaju: true,
@@ -61,19 +53,17 @@ export class AlokasiTopikService {
     });
   }
 
-  async findAllCreatedByPembimbing(options: {
+  async findAllActiveTopikCreatedByPembimbing(options: {
     page: number;
     limit?: number;
     search?: string;
     idPembimbing?: string;
-    periode: string;
   }): Promise<GetAllRespDto> {
     const dataQuery = this.topikRepo.find({
       select: {
         id: true,
         judul: true,
         deskripsi: true,
-        periode: true,
         pengaju: {
           id: true,
           nama: true,
@@ -82,12 +72,12 @@ export class AlokasiTopikService {
         },
       },
       where: {
-        periode: options.periode,
+        aktif: true,
         pengaju: {
           id: options.idPembimbing || undefined,
           roles: ArrayContains([RoleEnum.S2_PEMBIMBING]),
         },
-        judul: Like(`%${options.search || ""}%`),
+        judul: ILike(`%${options.search || ""}%`),
       },
       relations: {
         pengaju: true,
@@ -107,8 +97,7 @@ export class AlokasiTopikService {
         .createQueryBuilder("topik")
         .select("topik.id")
         .innerJoinAndSelect("topik.pengaju", "pengaju")
-        .where("topik.periode = :periode", { periode: options.periode })
-        .andWhere("pengaju.roles @> :role", {
+        .where("pengaju.roles @> :role", {
           role: [RoleEnum.S2_PEMBIMBING],
         });
 
@@ -142,13 +131,15 @@ export class AlokasiTopikService {
     }
   }
 
-  async update(id: string, updateDto: UpdateTopikDto) {
-    // not periode-protected
-    return await this.topikRepo.update(id, updateDto);
+  async update(id: string, updateDto: UpdateTopikDto, idPengaju?: string) {
+    const findOpt = idPengaju
+      ? { id, idPengaju, aktif: true }
+      : { id, aktif: true };
+    return await this.topikRepo.update(findOpt, updateDto);
   }
 
-  async remove(id: string) {
-    // not periode-protected
-    return await this.topikRepo.delete({ id }); // TODO: manage relation cascading option
+  async remove(id: string, idPengaju?: string) {
+    const findOpt = idPengaju ? { id, idPengaju } : { id };
+    return await this.topikRepo.update(findOpt, { aktif: false });
   }
 }
diff --git a/src/app.module.ts b/src/app.module.ts
index 0898cf406d426d16670b566e96a8f75eb025710e..1fa72cf33516b968b419451019bbdaa1725db5a9 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -2,39 +2,26 @@ import { Module } from "@nestjs/common";
 import { TypeOrmModule } from "@nestjs/typeorm";
 import { AppController } from "./app.controller";
 import { AppService } from "./app.service";
-import { AuditLog } from "./entities/auditLog.entity";
 import { Bimbingan } from "./entities/bimbingan.entity";
-import { DosenBimbingan } from "./entities/dosenBimbingan.entity";
-import { Kelas } from "./entities/kelas.entity";
-import { MahasiswaKelas } from "./entities/mahasiswaKelas.entity";
-import { PendaftaranTesis } from "./entities/pendaftaranTesis.entity";
-import { PengajarKelas } from "./entities/pengajarKelas.entity";
 import { Pengguna } from "./entities/pengguna.entity";
 import { Topik } from "./entities/topik.entity";
-// import { Ruangan } from "./entities/ruangan.entity";
+import { DosenBimbingan } from "./entities/dosenBimbingan.entity";
+import { PendaftaranTesis } from "./entities/pendaftaranTesis.entity";
+import { PengujiSidsem } from "./entities/pengujiSidsem.entity";
+import { RegistrasiTesisModule } from "./registrasi-tesis/registrasi-tesis.module";
 import { ConfigModule } from "@nestjs/config";
 import { AlokasiRuanganModule } from "./alokasi-ruangan/alokasi-ruangan.module";
 import { AlokasiTopikModule } from "./alokasi-topik/alokasi-topik.module";
 import { AuthModule } from "./auth/auth.module";
 import { BimbinganModule } from "./bimbingan/bimbingan.module";
-import { DashboardModule } from "./dashboard/dashboard.module";
-import { DosenBimbinganModule } from "./dosen-bimbingan/dosen-bimbingan.module";
+import { validate } from "./env.validation";
 import { BerkasBimbingan } from "./entities/berkasBimbingan.entity";
-import { BerkasSubmisiTugas } from "./entities/berkasSubmisiTugas.entity";
-import { BerkasTugas } from "./entities/berkasTugas.entity";
-import { Konfigurasi } from "./entities/konfigurasi.entity";
-import { MataKuliah } from "./entities/mataKuliah.entity";
 import { PendaftaranSidsem } from "./entities/pendaftaranSidsem";
-import { PengujiSidsem } from "./entities/pengujiSidsem.entity";
-import { SubmisiTugas } from "./entities/submisiTugas.entity";
-import { Tugas } from "./entities/tugas.entity";
-import { validate } from "./env.validation";
-import { KelasModule } from "./kelas/kelas.module";
+import { DosenBimbinganModule } from "./dosen-bimbingan/dosen-bimbingan.module";
+import { PenggunaModule } from "./pengguna/pengguna.module";
 import { KonfigurasiModule } from "./konfigurasi/konfigurasi.module";
-import { NilaiModule } from "./nilai/nilai.module";
-import { RegistrasiTesisModule } from "./registrasi-tesis/registrasi-tesis.module";
-import { SubmisiTugasModule } from "./submisi-tugas/submisi-tugas.module";
-import { TugasModule } from "./tugas/tugas.module";
+import { Konfigurasi } from "./entities/konfigurasi.entity";
+import { DashboardModule } from "./dashboard/dashboard.module";
 
 @Module({
   imports: [
@@ -53,20 +40,10 @@ import { TugasModule } from "./tugas/tugas.module";
         Pengguna,
         PendaftaranSidsem,
         Topik,
-        AuditLog,
         DosenBimbingan,
-        Kelas,
-        MahasiswaKelas,
-        PengajarKelas,
+        Konfigurasi,
         PendaftaranTesis,
-        // Ruangan,
-        Tugas,
         PengujiSidsem,
-        Konfigurasi,
-        MataKuliah,
-        SubmisiTugas,
-        BerkasSubmisiTugas,
-        BerkasTugas,
       ],
       synchronize: true,
     }),
@@ -75,13 +52,10 @@ import { TugasModule } from "./tugas/tugas.module";
     AlokasiTopikModule,
     DashboardModule,
     BimbinganModule,
-    KonfigurasiModule,
-    KelasModule,
-    TugasModule,
-    SubmisiTugasModule,
-    NilaiModule,
     DosenBimbinganModule,
     AlokasiRuanganModule,
+    PenggunaModule,
+    KonfigurasiModule,
   ],
   controllers: [AppController],
   providers: [AppService],
diff --git a/src/bimbingan/bimbingan.controller.ts b/src/bimbingan/bimbingan.controller.ts
index 99eab5d006d76622b2d8cf3a7699c41f93e4ead2..4f03874b94e456fe8a890c47cc05661fb890835d 100644
--- a/src/bimbingan/bimbingan.controller.ts
+++ b/src/bimbingan/bimbingan.controller.ts
@@ -45,9 +45,7 @@ export class BimbinganController {
   constructor(private readonly bimbinganService: BimbinganService) {}
 
   @ApiOkResponse({ type: GetByMahasiswaIdResDto })
-  @ApiNotFoundResponse({
-    description: "Tidak ada pendaftaran pada periode sekarang",
-  })
+  @ApiNotFoundResponse({ description: "Tidak ada pendaftaran" })
   @Roles(RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
   @Get("/mahasiswa/:mahasiswaId")
   async getByMahasiswaId(
@@ -61,9 +59,7 @@ export class BimbinganController {
   }
 
   @ApiOkResponse({ type: GetByMahasiswaIdResDto })
-  @ApiNotFoundResponse({
-    description: "Tidak ada pendaftaran pada periode sekarang",
-  })
+  @ApiNotFoundResponse({ description: "Tidak ada pendaftaran" })
   @Roles(RoleEnum.S2_MAHASISWA)
   @Get("/")
   async getOwnBimbingan(
@@ -80,9 +76,7 @@ export class BimbinganController {
     description:
       "Waktu bimbingan lebih dari hari ini atau bimbingan berikutnya sebelum waktu bimbingan yang dimasukkan",
   })
-  @ApiNotFoundResponse({
-    description: "Tidak ada pendaftaran pada periode sekarang",
-  })
+  @ApiNotFoundResponse({ description: "Tidak ada pendaftaran" })
   @Roles(RoleEnum.S2_MAHASISWA)
   @ApiBody({ type: CreateBimbinganReqDto })
   @Post("/")
@@ -94,9 +88,7 @@ export class BimbinganController {
   }
 
   @ApiOkResponse({ type: UpdateStatusResDto })
-  @ApiNotFoundResponse({
-    description: "Bimbingan tidak ditemukan",
-  })
+  @ApiNotFoundResponse({ description: "Bimbingan tidak ditemukan" })
   @ApiForbiddenResponse({
     description: "Anda tidak memiliki akses untuk mengubah status bimbingan",
   })
@@ -111,9 +103,7 @@ export class BimbinganController {
   }
 
   @ApiOkResponse({ type: GetByBimbinganIdResDto })
-  @ApiNotFoundResponse({
-    description: "Bimbingan tidak ditemukan",
-  })
+  @ApiNotFoundResponse({ description: "Bimbingan tidak ditemukan" })
   @Roles(RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN)
   @Get("/:bimbinganId")
   async getByBimbinganId(
diff --git a/src/bimbingan/bimbingan.dto.ts b/src/bimbingan/bimbingan.dto.ts
index f3afcdac8aeeb0380633e5609bc7b35d8c864013..649f9c95366f56738a281689e0520c876ec8cef7 100644
--- a/src/bimbingan/bimbingan.dto.ts
+++ b/src/bimbingan/bimbingan.dto.ts
@@ -33,7 +33,6 @@ class PickedTopikBimbingan extends PickType(Topik, [
   "judul",
   "deskripsi",
   "idPengaju",
-  "periode",
 ] as const) {}
 
 export class GetByMahasiswaIdResDto {
diff --git a/src/bimbingan/bimbingan.module.ts b/src/bimbingan/bimbingan.module.ts
index 30174c69ff5a33b4a5caa742095ef9f830c5eb8d..b77070fda6099172ac83112b4163af9a742f656d 100644
--- a/src/bimbingan/bimbingan.module.ts
+++ b/src/bimbingan/bimbingan.module.ts
@@ -4,22 +4,25 @@ import { BimbinganService } from "./bimbingan.service";
 import { TypeOrmModule } from "@nestjs/typeorm";
 import { Bimbingan } from "src/entities/bimbingan.entity";
 import { PendaftaranTesis } from "src/entities/pendaftaranTesis.entity";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
 import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
 import { BerkasBimbingan } from "src/entities/berkasBimbingan.entity";
+import { PenggunaModule } from "src/pengguna/pengguna.module";
+import { PenggunaService } from "src/pengguna/pengguna.service";
+import { Pengguna } from "src/entities/pengguna.entity";
 
 @Module({
   imports: [
     TypeOrmModule.forFeature([
       Bimbingan,
       PendaftaranTesis,
-      Konfigurasi,
       DosenBimbingan,
       BerkasBimbingan,
+      Pengguna,
     ]),
+    PenggunaModule,
   ],
   controllers: [BimbinganController],
-  providers: [BimbinganService],
+  providers: [BimbinganService, PenggunaService],
   exports: [BimbinganService],
 })
 export class BimbinganModule {}
diff --git a/src/bimbingan/bimbingan.service.ts b/src/bimbingan/bimbingan.service.ts
index 52c1ba28e98f9c71aad2d88e5ebeafb8d1cb1d40..825ce9109b5ac2c4be8f5e68aa0e600b2eda67e0 100644
--- a/src/bimbingan/bimbingan.service.ts
+++ b/src/bimbingan/bimbingan.service.ts
@@ -9,7 +9,6 @@ import * as dayjs from "dayjs";
 import { AuthDto } from "src/auth/auth.dto";
 import { Bimbingan, BimbinganStatus } from "src/entities/bimbingan.entity";
 import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
 import {
   PendaftaranTesis,
   RegStatus,
@@ -25,6 +24,7 @@ import {
   UpdateStatusResDto,
 } from "./bimbingan.dto";
 import { BerkasBimbingan } from "src/entities/berkasBimbingan.entity";
+import { PenggunaService } from "src/pengguna/pengguna.service";
 
 @Injectable()
 export class BimbinganService {
@@ -33,29 +33,23 @@ export class BimbinganService {
     private bimbinganRepository: Repository<Bimbingan>,
     @InjectRepository(PendaftaranTesis)
     private pendaftaranTesisRepository: Repository<PendaftaranTesis>,
-    @InjectRepository(Konfigurasi)
-    private konfigurasiRepository: Repository<Konfigurasi>,
     @InjectRepository(DosenBimbingan)
     private dosenBimbinganRepository: Repository<DosenBimbingan>,
     @InjectRepository(BerkasBimbingan)
     private berkasBimbinganRepository: Repository<BerkasBimbingan>,
+    private penggunaService: PenggunaService,
   ) {}
 
   async getByMahasiswaId(
     mahasiswaId: string,
     user: AuthDto,
   ): Promise<GetByMahasiswaIdResDto> {
-    const currentPeriode = await this.konfigurasiRepository.findOne({
-      where: { key: process.env.KONF_PERIODE_KEY },
-    });
+    await this.penggunaService.isMahasiswaAktifOrFail(mahasiswaId);
 
     const pendaftaran = await this.pendaftaranTesisRepository.findOne({
       where: {
         mahasiswa: { id: mahasiswaId },
         status: RegStatus.APPROVED,
-        topik: {
-          periode: currentPeriode.value,
-        },
       },
       relations: {
         mahasiswa: true,
@@ -65,9 +59,7 @@ export class BimbinganService {
     });
 
     if (!pendaftaran) {
-      throw new NotFoundException(
-        "Tidak ada pendaftaran yang disetujui pada periode ini",
-      );
+      throw new NotFoundException("Tidak ada pendaftaran yang disetujui");
     }
 
     // Validate bimbingan data by its dosbim
@@ -119,17 +111,10 @@ export class BimbinganService {
     createDto: CreateBimbinganReqDto,
   ): Promise<CreateBimbinganResDto> {
     // Check if user registered in bimbingan
-    const currentPeriode = await this.konfigurasiRepository.findOne({
-      where: { key: process.env.KONF_PERIODE_KEY },
-    });
-
     const pendaftaran = await this.pendaftaranTesisRepository.findOne({
       where: {
         mahasiswa: { id: mahasiswaId },
         status: RegStatus.APPROVED,
-        topik: {
-          periode: currentPeriode.value,
-        },
       },
       relations: {
         mahasiswa: true,
@@ -139,9 +124,7 @@ export class BimbinganService {
     });
 
     if (!pendaftaran) {
-      throw new NotFoundException(
-        "Tidak ada pendaftaran yang disetujui pada periode ini",
-      );
+      throw new NotFoundException("Tidak ada pendaftaran yang disetujui");
     }
 
     if (dayjs(createDto.waktuBimbingan).isAfter(dayjs(new Date()).endOf("d")))
@@ -180,7 +163,7 @@ export class BimbinganService {
     user: AuthDto,
     dto: UpdateStatusDto,
   ): Promise<UpdateStatusResDto> {
-    const bimbingan = await this.getByBimbinganId(user, dto.bimbinganId);
+    const bimbingan = await this.getByBimbinganId(user, dto.bimbinganId); // already check if mahasiswa is aktif
 
     await this.bimbinganRepository.update(bimbingan.id, {
       disahkan: dto.status,
@@ -195,19 +178,13 @@ export class BimbinganService {
     user: AuthDto,
     bimbinganId: string,
   ): Promise<GetByBimbinganIdResDto> {
-    const currentPeriode = await this.konfigurasiRepository.findOne({
-      where: { key: process.env.KONF_PERIODE_KEY },
-    });
-
     const bimbinganQuery = this.bimbinganRepository
       .createQueryBuilder("bimbingan")
       .leftJoinAndSelect("bimbingan.pendaftaran", "pendaftaran")
       .leftJoinAndSelect("pendaftaran.dosenBimbingan", "dosenBimbingan")
       .leftJoinAndSelect("dosenBimbingan.dosen", "dosen")
       .leftJoinAndSelect("bimbingan.berkas", "berkas")
-      .leftJoin("pendaftaran.topik", "topik", "topik.periode = :periode", {
-        periode: currentPeriode.value,
-      })
+      .leftJoin("pendaftaran.topik", "topik")
       .leftJoinAndSelect("pendaftaran.mahasiswa", "mahasiswa")
       .where("bimbingan.id = :id", { id: bimbinganId });
     const bimbingan = await bimbinganQuery.getOne();
@@ -216,6 +193,10 @@ export class BimbinganService {
       throw new NotFoundException("Bimbingan tidak ditemukan");
     }
 
+    if (!bimbingan.pendaftaran.mahasiswa.aktif) {
+      throw new BadRequestException("Bimbingan milik mahasiswa tidak aktif");
+    }
+
     if (
       !user.roles.includes(RoleEnum.ADMIN) &&
       !bimbingan.pendaftaran.dosenBimbingan
diff --git a/src/dashboard/dashboard.controller.ts b/src/dashboard/dashboard.controller.ts
index 31a3a4cc1dc88afe12ba4b05e16bc015fd2a41e9..bb16aebd0a8cb044554d293950f8056baa3b6c4b 100644
--- a/src/dashboard/dashboard.controller.ts
+++ b/src/dashboard/dashboard.controller.ts
@@ -8,7 +8,6 @@ import { AuthDto } from "src/auth/auth.dto";
 import { Request } from "express";
 import {
   DashboardDto,
-  DashboardMahasiswaResDto,
   GetDashboardDosbimQueryDto,
   JalurStatisticDto,
 } from "./dashboard.dto";
@@ -48,16 +47,4 @@ export class DashboardController {
       (request.user as AuthDto).id,
     );
   }
-
-  @UseGuards(CustomAuthGuard, RolesGuard)
-  @Roles(RoleEnum.S2_MAHASISWA)
-  @ApiOkResponse({ type: DashboardMahasiswaResDto })
-  @Get("/mahasiswa")
-  async getDashboardMahasiswa(
-    @Req() request: Request,
-  ): Promise<DashboardMahasiswaResDto> {
-    return this.dashboardService.getDashboardMahasiswa(
-      (request.user as AuthDto).id,
-    );
-  }
 }
diff --git a/src/dashboard/dashboard.dto.ts b/src/dashboard/dashboard.dto.ts
index 8d279937d0616eb007400145e622316c5d4b9012..b11d1e6155273b64a4aaf73064f813eada47abd1 100644
--- a/src/dashboard/dashboard.dto.ts
+++ b/src/dashboard/dashboard.dto.ts
@@ -4,14 +4,9 @@ import {
   OmitType,
   PickType,
 } from "@nestjs/swagger";
-import {
-  JalurEnum,
-  PendaftaranTesis,
-} from "../entities/pendaftaranTesis.entity";
+import { JalurEnum } from "../entities/pendaftaranTesis.entity";
 import { Topik } from "src/entities/topik.entity";
 import { Pengguna } from "src/entities/pengguna.entity";
-import { Bimbingan } from "src/entities/bimbingan.entity";
-import { PendaftaranSidsem } from "src/entities/pendaftaranSidsem";
 import { IsOptional } from "class-validator";
 import { BimbinganStatus } from "src/entities/bimbingan.entity";
 
@@ -23,35 +18,10 @@ class PickedMhsDashboard extends PickType(Pengguna, [
   "email",
 ] as const) {}
 
-class OmittedTopikMhsDashboard extends OmitType(Topik, ["pengaju"] as const) {}
-
 class NoEmailUserDashboard extends OmitType(PickedMhsDashboard, [
   "email",
 ] as const) {}
 
-export class NoNIMUserDashboard extends OmitType(PickedMhsDashboard, [
-  "nim",
-] as const) {}
-
-class OmittedPendaftaranTesisMhsDashboard extends OmitType(PendaftaranTesis, [
-  "mahasiswa",
-  "topik",
-  "penerima",
-] as const) {
-  @ApiProperty()
-  topik: OmittedTopikMhsDashboard;
-
-  @ApiProperty()
-  penerima: NoEmailUserDashboard;
-}
-
-class SidsemWithPenguji extends OmitType(PendaftaranSidsem, [
-  "penguji",
-] as const) {
-  @ApiProperty({ type: [NoNIMUserDashboard] })
-  penguji: NoNIMUserDashboard[];
-}
-
 export class DashboardDto {
   @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
   id: string;
@@ -77,38 +47,6 @@ export class JalurStatisticDto {
   count: number;
 }
 
-export class DashboardMahasiswaResDto {
-  @ApiProperty()
-  mahasiswa: PickedMhsDashboard;
-
-  @ApiProperty({ type: OmittedPendaftaranTesisMhsDashboard, nullable: true })
-  pendaftaranTesis: OmittedPendaftaranTesisMhsDashboard;
-
-  @ApiProperty({ type: [NoNIMUserDashboard] })
-  dosenBimbingan: NoNIMUserDashboard[];
-
-  @ApiProperty({ type: [Bimbingan] })
-  bimbingan: Bimbingan[];
-
-  @ApiProperty({
-    type: PendaftaranSidsem,
-    nullable: true,
-  })
-  seminarSatu: PendaftaranSidsem;
-
-  @ApiProperty({
-    type: SidsemWithPenguji,
-    nullable: true,
-  })
-  seminarDua: SidsemWithPenguji;
-
-  @ApiProperty({
-    type: SidsemWithPenguji,
-    nullable: true,
-  })
-  sidang: SidsemWithPenguji;
-}
-
 export class GetDashboardDosbimQueryDto {
   @ApiPropertyOptional({})
   @IsOptional()
diff --git a/src/dashboard/dashboard.module.ts b/src/dashboard/dashboard.module.ts
index 8f8f447d98f6ce5c3d40de228881aa244d364bba..4f310dc17f1ecef4ffba88fe01b46b60cfacddca 100644
--- a/src/dashboard/dashboard.module.ts
+++ b/src/dashboard/dashboard.module.ts
@@ -4,24 +4,11 @@ import { DashboardController } from "./dashboard.controller";
 import { DashboardService } from "./dashboard.service";
 import { PendaftaranTesis } from "../entities/pendaftaranTesis.entity";
 import { Pengguna } from "../entities/pengguna.entity";
-import { Topik } from "../entities/topik.entity";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
-import { Bimbingan } from "src/entities/bimbingan.entity";
-import { PendaftaranSidsem } from "src/entities/pendaftaranSidsem";
-import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
 import { BimbinganModule } from "src/bimbingan/bimbingan.module";
 
 @Module({
   imports: [
-    TypeOrmModule.forFeature([
-      PendaftaranTesis,
-      Pengguna,
-      Topik,
-      Konfigurasi,
-      Bimbingan,
-      PendaftaranSidsem,
-      DosenBimbingan,
-    ]),
+    TypeOrmModule.forFeature([PendaftaranTesis, Pengguna]),
     BimbinganModule,
   ],
   controllers: [DashboardController],
diff --git a/src/dashboard/dashboard.service.ts b/src/dashboard/dashboard.service.ts
index c2bfcb12e4e7c8bbcbfdfacf6b77a224c475a5b1..f168aa396a89aaf5a062d1c061baffa0ad988f45 100644
--- a/src/dashboard/dashboard.service.ts
+++ b/src/dashboard/dashboard.service.ts
@@ -6,19 +6,7 @@ import {
   RegStatus,
 } from "../entities/pendaftaranTesis.entity";
 import { Pengguna } from "../entities/pengguna.entity";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
-import { Bimbingan } from "src/entities/bimbingan.entity";
-import {
-  DashboardDto,
-  DashboardMahasiswaResDto,
-  JalurStatisticDto,
-  NoNIMUserDashboard,
-} from "./dashboard.dto";
-import {
-  PendaftaranSidsem,
-  TipeSidsemEnum,
-} from "src/entities/pendaftaranSidsem";
-import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
+import { DashboardDto, JalurStatisticDto } from "./dashboard.dto";
 import { BimbinganService } from "src/bimbingan/bimbingan.service";
 
 @Injectable()
@@ -28,14 +16,6 @@ export class DashboardService {
     private pendaftaranTesisRepository: Repository<PendaftaranTesis>,
     @InjectRepository(Pengguna)
     private penggunaRepository: Repository<Pengguna>,
-    @InjectRepository(Konfigurasi)
-    private konfigurasiRepository: Repository<Konfigurasi>,
-    @InjectRepository(Bimbingan)
-    private bimbinganRepository: Repository<Bimbingan>,
-    @InjectRepository(PendaftaranSidsem)
-    private pendaftaranSidsemRepository: Repository<PendaftaranSidsem>,
-    @InjectRepository(DosenBimbingan)
-    private dosenBimbinganRepository: Repository<DosenBimbingan>,
     private bimbinganService: BimbinganService,
   ) {}
 
@@ -49,14 +29,6 @@ export class DashboardService {
     dosenId: string,
     search?: string,
   ): Promise<DashboardDto[]> {
-    const currentPeriode = await this.konfigurasiRepository.findOne({
-      where: { key: process.env.KONF_PERIODE_KEY },
-    });
-
-    if (!currentPeriode) {
-      throw new BadRequestException("Periode belum dikonfigurasi");
-    }
-
     let pendaftaranTesisQuery = this.pendaftaranTesisRepository
       .createQueryBuilder("pendaftaranTesis")
       .leftJoinAndSelect("pendaftaranTesis.mahasiswa", "mahasiswa")
@@ -69,10 +41,10 @@ export class DashboardService {
           dosenId,
         },
       )
+      .where("mahasiswa.aktif = true")
       .andWhere("pendaftaranTesis.status = :status", {
         status: RegStatus.APPROVED,
-      })
-      .andWhere("topik.periode = :periode", { periode: currentPeriode.value });
+      });
 
     if (search) {
       pendaftaranTesisQuery = pendaftaranTesisQuery.andWhere(
@@ -112,15 +84,9 @@ export class DashboardService {
   async getStatisticsByJalurPilihan(
     dosenId: string,
   ): Promise<JalurStatisticDto[]> {
-    const [currentPeriode, dosen] = await Promise.all([
-      this.konfigurasiRepository.findOne({
-        where: { key: process.env.KONF_PERIODE_KEY },
-      }),
-      this.penggunaRepository.findOne({
-        where: { id: dosenId },
-      }),
-    ]);
-
+    const dosen = await this.penggunaRepository.findOne({
+      where: { id: dosenId },
+    });
     if (!dosen) {
       throw new BadRequestException("Dosen tidak ditemukan");
     }
@@ -129,9 +95,7 @@ export class DashboardService {
       .createQueryBuilder("pendaftaranTesis")
       .select("pendaftaranTesis.jalurPilihan", "jalurPilihan")
       .addSelect("COUNT(*)", "count")
-      .leftJoin("pendaftaranTesis.topik", "topik", "topik.periode = :periode", {
-        periode: currentPeriode.value,
-      })
+      .leftJoin("pendaftaranTesis.mahasiswa", "mahasiswa")
       .innerJoin(
         "pendaftaranTesis.dosenBimbingan",
         "dosenBimbingan",
@@ -140,6 +104,7 @@ export class DashboardService {
           dosenId,
         },
       )
+      .where("mahasiswa.aktif = true")
       .andWhere("pendaftaranTesis.status = :status", {
         status: RegStatus.APPROVED,
       })
@@ -148,126 +113,4 @@ export class DashboardService {
 
     return statistics as JalurStatisticDto[];
   }
-
-  async getDashboardMahasiswa(
-    mahasiswaId: string,
-  ): Promise<DashboardMahasiswaResDto> {
-    const currentPeriode = await this.konfigurasiRepository.findOne({
-      where: { key: process.env.KONF_PERIODE_KEY },
-    });
-
-    const mahasiswaQuery = this.penggunaRepository
-      .createQueryBuilder("pengguna")
-      .select([
-        "pengguna.id",
-        "pengguna.nama",
-        "pengguna.email",
-        "pengguna.nim",
-      ])
-      .where("pengguna.id = :id", { id: mahasiswaId });
-    const pendaftaranTesisQuery = this.pendaftaranTesisRepository
-      .createQueryBuilder("pendaftaranTesis")
-      .select([
-        "pendaftaranTesis.id",
-        "pendaftaranTesis.jalurPilihan",
-        "pendaftaranTesis.waktuPengiriman",
-        "pendaftaranTesis.jadwalInterview",
-        "pendaftaranTesis.waktuKeputusan",
-        "pendaftaranTesis.status",
-        "penerima.id",
-        "penerima.nama",
-        "penerima.email",
-      ])
-      .leftJoin("pendaftaranTesis.mahasiswa", "mahasiswa")
-      .leftJoinAndSelect("pendaftaranTesis.topik", "topik")
-      .leftJoin("pendaftaranTesis.penerima", "penerima")
-      .where("mahasiswa.id = :id", { id: mahasiswaId })
-      .andWhere("topik.periode = :periode", { periode: currentPeriode.value })
-      .orderBy("pendaftaranTesis.waktuPengiriman", "DESC");
-
-    const [mahasiswa, pendaftaranTesis] = await Promise.all([
-      mahasiswaQuery.getOne(),
-      pendaftaranTesisQuery.getOne(),
-    ]);
-
-    let dosenBimbingan: DosenBimbingan[] = [];
-    let bimbingan: Bimbingan[] = [];
-    let seminarSatu: PendaftaranSidsem | null = null;
-    let seminarDua: PendaftaranSidsem | null = null;
-    let sidang: PendaftaranSidsem | null = null;
-
-    if (pendaftaranTesis) {
-      const dosenBimbinganQuery = this.dosenBimbinganRepository
-        .createQueryBuilder("dosenBimbingan")
-        .select(["dosen.id", "dosen.nama", "dosen.email"])
-        .leftJoin("dosenBimbingan.dosen", "dosen")
-        .where("dosenBimbingan.idPendaftaran = :id", {
-          id: pendaftaranTesis.id,
-        });
-      const bimbinganQuery = this.bimbinganRepository
-        .createQueryBuilder("bimbingan")
-        .leftJoinAndSelect("bimbingan.berkas", "berkas")
-        .where("bimbingan.pendaftaranId = :id", {
-          id: pendaftaranTesis.id,
-        });
-      const [seminarSatuQuery, seminarDuaQuery, sidangQuery] = Object.values(
-        TipeSidsemEnum,
-      ).map((tipe) => {
-        let temp = this.pendaftaranSidsemRepository
-          .createQueryBuilder("pendaftaranSidsem")
-          .leftJoinAndSelect("pendaftaranSidsem.ruangan", "ruangan")
-          .where("pendaftaranSidsem.pendaftaranTesisId = :id", {
-            id: pendaftaranTesis.id,
-          })
-          .andWhere("pendaftaranSidsem.tipe = :tipe", {
-            tipe,
-          })
-          .andWhere("NOT pendaftaranSidsem.ditolak");
-
-        if (tipe !== TipeSidsemEnum.SEMINAR_1) {
-          temp = temp
-            .leftJoinAndSelect("pendaftaranSidsem.penguji", "penguji")
-            .leftJoinAndSelect("penguji.dosen", "dosen");
-        }
-
-        return temp;
-      });
-
-      [dosenBimbingan, bimbingan, seminarSatu, seminarDua, sidang] =
-        await Promise.all([
-          dosenBimbinganQuery.getMany(),
-          bimbinganQuery.getMany(),
-          seminarSatuQuery.getOne(),
-          seminarDuaQuery.getOne(),
-          sidangQuery.getOne(),
-        ]);
-    }
-
-    return {
-      mahasiswa,
-      pendaftaranTesis,
-      dosenBimbingan:
-        dosenBimbingan.length > 0
-          ? (dosenBimbingan as any as NoNIMUserDashboard[])
-          : [pendaftaranTesis.penerima],
-      bimbingan,
-      seminarSatu,
-      seminarDua: {
-        ...seminarDua,
-        penguji: seminarDua?.penguji.map((p) => ({
-          id: p.dosen.id,
-          nama: p.dosen.nama,
-          email: p.dosen.email,
-        })),
-      },
-      sidang: {
-        ...sidang,
-        penguji: sidang?.penguji.map((p) => ({
-          id: p.dosen.id,
-          nama: p.dosen.nama,
-          email: p.dosen.email,
-        })),
-      },
-    };
-  }
 }
diff --git a/src/dosen-bimbingan/dosen-bimbingan.dto.ts b/src/dosen-bimbingan/dosen-bimbingan.dto.ts
index 23c823e7389a759b7d532c02543e736d5bbaf0d4..16e493a95a99c7f62c02cf894b7386b3e5974383 100644
--- a/src/dosen-bimbingan/dosen-bimbingan.dto.ts
+++ b/src/dosen-bimbingan/dosen-bimbingan.dto.ts
@@ -14,4 +14,5 @@ export class GetDosbimResDto extends PickType(Pengguna, [
   "id",
   "email",
   "nama",
+  "keahlian",
 ] as const) {}
diff --git a/src/dosen-bimbingan/dosen-bimbingan.module.ts b/src/dosen-bimbingan/dosen-bimbingan.module.ts
index 1929f62932c353150ab780e6a6fb785c560a9357..1721d9d65412532695c2c187b62f6aec9e248070 100644
--- a/src/dosen-bimbingan/dosen-bimbingan.module.ts
+++ b/src/dosen-bimbingan/dosen-bimbingan.module.ts
@@ -3,18 +3,11 @@ import { DosenBimbinganController } from "./dosen-bimbingan.controller";
 import { DosenBimbinganService } from "./dosen-bimbingan.service";
 import { AuthModule } from "src/auth/auth.module";
 import { TypeOrmModule } from "@nestjs/typeorm";
-import { PendaftaranTesis } from "src/entities/pendaftaranTesis.entity";
-import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
 import { Pengguna } from "src/entities/pengguna.entity";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
 import { CustomStrategy } from "src/middlewares/custom.strategy";
 
 @Module({
-  imports: [
-    TypeOrmModule.forFeature([PendaftaranTesis, DosenBimbingan, Pengguna]),
-    AuthModule,
-    KonfigurasiModule,
-  ],
+  imports: [TypeOrmModule.forFeature([Pengguna]), AuthModule],
   controllers: [DosenBimbinganController],
   providers: [DosenBimbinganService, CustomStrategy],
 })
diff --git a/src/dosen-bimbingan/dosen-bimbingan.service.ts b/src/dosen-bimbingan/dosen-bimbingan.service.ts
index 88f0f9d159f8f0e4949c06a4c5bbcb7ad9a9643a..9d9039a1dbc62780d044cb2fac6f09239e2ebc07 100644
--- a/src/dosen-bimbingan/dosen-bimbingan.service.ts
+++ b/src/dosen-bimbingan/dosen-bimbingan.service.ts
@@ -16,6 +16,7 @@ export class DosenBimbinganService {
         id: true,
         nama: true,
         email: true,
+        keahlian: true,
       },
       where: {
         roles: ArrayContains([RoleEnum.S2_PEMBIMBING]),
diff --git a/src/entities/auditLog.entity.ts b/src/entities/auditLog.entity.ts
deleted file mode 100644
index c95d05a03fb11fb13d835bc1e6c64b22e107bff6..0000000000000000000000000000000000000000
--- a/src/entities/auditLog.entity.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
-import { Pengguna } from "./pengguna.entity";
-
-@Entity()
-export class AuditLog {
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
-  pengguna: Pengguna;
-}
diff --git a/src/entities/berkasSubmisiTugas.entity.ts b/src/entities/berkasSubmisiTugas.entity.ts
deleted file mode 100644
index e48d5e8d88f1449b767d3e88f1f9862e8e0f6560..0000000000000000000000000000000000000000
--- a/src/entities/berkasSubmisiTugas.entity.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
-import { SubmisiTugas } from "./submisiTugas.entity";
-import { ApiProperty } from "@nestjs/swagger";
-import { IsString, IsUUID } from "@nestjs/class-validator";
-import { IsUrl } from "class-validator";
-
-@Entity()
-export class BerkasSubmisiTugas {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => SubmisiTugas, (submisi) => submisi.id, {
-    orphanedRowAction: "delete",
-  })
-  submisiTugas: SubmisiTugas;
-
-  @ApiProperty()
-  @IsString()
-  @Column({ type: "text" })
-  nama: string;
-
-  @ApiProperty({ example: "https://example.com/berkas.pdf" })
-  @IsUrl()
-  @Column({ type: "text" })
-  url: string;
-}
diff --git a/src/entities/berkasTugas.entity.ts b/src/entities/berkasTugas.entity.ts
deleted file mode 100644
index c18bccfa9c839754ca8ed7bb0f5789f8841e3ff1..0000000000000000000000000000000000000000
--- a/src/entities/berkasTugas.entity.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
-import { Tugas } from "./tugas.entity";
-import { ApiProperty } from "@nestjs/swagger";
-import { IsUrl, IsUUID } from "class-validator";
-import { IsString } from "@nestjs/class-validator";
-
-@Entity()
-export class BerkasTugas {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => Tugas, (tugas) => tugas.id, { orphanedRowAction: "delete" })
-  tugas: Tugas;
-
-  @ApiProperty()
-  @IsString()
-  @Column({ type: "text" })
-  nama: string;
-
-  @ApiProperty({ example: "https://example.com/berkas.pdf" })
-  @IsUrl()
-  @Column({ type: "text" })
-  url: string;
-}
diff --git a/src/entities/kelas.entity.ts b/src/entities/kelas.entity.ts
deleted file mode 100644
index deec327ed9a9028f7eb8ddd886826f35a3294c80..0000000000000000000000000000000000000000
--- a/src/entities/kelas.entity.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
-  Column,
-  Entity,
-  JoinColumn,
-  ManyToOne,
-  OneToMany,
-  PrimaryGeneratedColumn,
-} from "typeorm";
-import { MataKuliah } from "./mataKuliah.entity";
-import { ApiProperty } from "@nestjs/swagger";
-import { PengajarKelas } from "./pengajarKelas.entity";
-import { MahasiswaKelas } from "./mahasiswaKelas.entity";
-import {
-  IsPositive,
-  IsString,
-  IsUUID,
-  Length,
-  MaxLength,
-} from "@nestjs/class-validator";
-import { Tugas } from "./tugas.entity";
-
-@Entity()
-export class Kelas {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @Column({ type: "smallint" })
-  @ApiProperty({ example: 1 })
-  @IsPositive()
-  nomor: number;
-
-  @ApiProperty()
-  @IsString()
-  @Column({ type: "text" })
-  periode: string;
-
-  @ApiProperty({ type: MataKuliah })
-  @ManyToOne(() => MataKuliah, (mataKuliah) => mataKuliah.kode)
-  @JoinColumn({ name: "mataKuliahKode" })
-  mataKuliah: MataKuliah;
-
-  @ApiProperty({ minLength: 6, maxLength: 6, example: "IF4031" })
-  @IsString()
-  @Length(6)
-  @Column({ nullable: true })
-  mataKuliahKode: string;
-
-  @ApiProperty({ example: "bg-blue-600/20" })
-  @IsString()
-  @MaxLength(24)
-  @Column({ type: "varchar", length: 24 })
-  warna: string;
-
-  @OneToMany(() => PengajarKelas, (pengajar) => pengajar.kelas)
-  pengajar: PengajarKelas[];
-
-  @OneToMany(() => MahasiswaKelas, (mahasiswa) => mahasiswa.kelas)
-  mahasiswa: MahasiswaKelas[];
-
-  @OneToMany(() => Tugas, (tugas) => tugas.kelas)
-  tugas: Tugas[];
-}
diff --git a/src/entities/konfigurasi.entity.ts b/src/entities/konfigurasi.entity.ts
index 538a9fa944cad11819c8323dafa99decc9801908..26ee3cee556d63ef6ae248c1f957afe0c56254f8 100644
--- a/src/entities/konfigurasi.entity.ts
+++ b/src/entities/konfigurasi.entity.ts
@@ -1,10 +1,27 @@
+import { ApiProperty } from "@nestjs/swagger";
+import { IsEnum, IsString } from "class-validator";
 import { Column, Entity, PrimaryColumn } from "typeorm";
 
+export enum KonfigurasiKeyEnum {
+  AWAL_PENDAFTARAN = "AWAL_PENDAFTARAN",
+  AKHIR_PENDAFTARAN = "AKHIR_PENDAFTARAN",
+  AWAL_SEMPRO = "AWAL_SEMPRO",
+  AKHIR_SEMPRO = "AKHIR_SEMPRO",
+  AWAL_SEM_TESIS = "AWAL_SEM_TESIS",
+  AKHIR_SEM_TESIS = "AKHIR_SEM_TESIS",
+  AWAL_SIDANG = "AWAL_SIDANG",
+  AKHIR_SIDANG = "AKHIR_SIDANG",
+}
+
 @Entity()
 export class Konfigurasi {
-  @PrimaryColumn({ type: "text" })
-  key: string;
+  @ApiProperty({ enum: KonfigurasiKeyEnum })
+  @IsEnum(KonfigurasiKeyEnum)
+  @PrimaryColumn({ type: "enum", enum: KonfigurasiKeyEnum })
+  key: KonfigurasiKeyEnum;
 
+  @ApiProperty()
+  @IsString()
   @Column({ type: "text" })
   value: string;
 }
diff --git a/src/entities/mahasiswaKelas.entity.ts b/src/entities/mahasiswaKelas.entity.ts
deleted file mode 100644
index 0753aa6f75f865913b7e42209248310948dc67c2..0000000000000000000000000000000000000000
--- a/src/entities/mahasiswaKelas.entity.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import {
-  Column,
-  Entity,
-  JoinColumn,
-  ManyToOne,
-  PrimaryGeneratedColumn,
-} from "typeorm";
-import { Kelas } from "./kelas.entity";
-import { Pengguna } from "./pengguna.entity";
-
-@Entity()
-export class MahasiswaKelas {
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => Kelas, (kelas) => kelas.id)
-  @JoinColumn({ name: "kelasId" })
-  kelas: Kelas;
-
-  @Column()
-  kelasId: string;
-
-  @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
-  @JoinColumn({ name: "mahasiswaId" })
-  mahasiswa: Pengguna;
-
-  @Column()
-  mahasiswaId: string;
-
-  @Column({ type: "real", nullable: true })
-  nilaiAkhir?: number;
-}
diff --git a/src/entities/mataKuliah.entity.ts b/src/entities/mataKuliah.entity.ts
deleted file mode 100644
index 9e1fed5d807a176b89288144623ec72575ef5e33..0000000000000000000000000000000000000000
--- a/src/entities/mataKuliah.entity.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { ApiProperty } from "@nestjs/swagger";
-import { IsString, Length, MaxLength } from "class-validator";
-import { Column, Entity, OneToMany, PrimaryColumn } from "typeorm";
-import { Kelas } from "./kelas.entity";
-
-@Entity()
-export class MataKuliah {
-  @ApiProperty({ minLength: 6, maxLength: 6, example: "IF4031" })
-  @IsString()
-  @Length(6)
-  @PrimaryColumn({ type: "varchar", length: 6 })
-  kode: string;
-
-  @ApiProperty({ maxLength: 256 })
-  @IsString()
-  @MaxLength(256)
-  @Column({ type: "varchar", length: 256 })
-  nama: string;
-
-  @OneToMany(() => Kelas, (kelas) => kelas.mataKuliah)
-  kelas: Kelas[];
-}
diff --git a/src/entities/pendaftaranTesis.entity.ts b/src/entities/pendaftaranTesis.entity.ts
index 637a05e71e7be84615568bcaef45f0adc2d14e2c..e9a8fa31c2f525bcc45c5d87cf250d018901ceda 100644
--- a/src/entities/pendaftaranTesis.entity.ts
+++ b/src/entities/pendaftaranTesis.entity.ts
@@ -1,6 +1,7 @@
 import {
   Column,
   Entity,
+  JoinColumn,
   ManyToOne,
   OneToMany,
   PrimaryGeneratedColumn,
@@ -56,13 +57,17 @@ export class PendaftaranTesis {
   status: RegStatus;
 
   @ApiProperty({ type: Topik })
-  @ManyToOne(() => Topik, (topik) => topik.id)
+  @ManyToOne(() => Topik, (topik) => topik.id, { cascade: true })
   topik: Topik;
 
   @ApiProperty()
   @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
+  @JoinColumn({ name: "mahasiswaId" })
   mahasiswa: Pengguna;
 
+  @Column()
+  mahasiswaId: string;
+
   @ApiProperty()
   @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
   penerima: Pengguna;
diff --git a/src/entities/pengajarKelas.entity.ts b/src/entities/pengajarKelas.entity.ts
deleted file mode 100644
index 61a314c4f21548b3b48e9aeb510b2d195d9a3662..0000000000000000000000000000000000000000
--- a/src/entities/pengajarKelas.entity.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import {
-  Column,
-  Entity,
-  JoinColumn,
-  ManyToOne,
-  PrimaryGeneratedColumn,
-} from "typeorm";
-import { Kelas } from "./kelas.entity";
-import { Pengguna } from "./pengguna.entity";
-
-@Entity()
-export class PengajarKelas {
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => Kelas, (kelas) => kelas.id)
-  @JoinColumn({ name: "kelasId" })
-  kelas: Kelas;
-
-  @Column()
-  kelasId: string;
-
-  @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
-  @JoinColumn({ name: "pengajarId" })
-  pengajar: Pengguna;
-
-  @Column()
-  pengajarId: string;
-}
diff --git a/src/entities/pengguna.entity.ts b/src/entities/pengguna.entity.ts
index c28a606ea4031436e36fc7958c0756a78f898cbe..c6011ee1dc0ec6adb74010bc2a21bae668198d23 100644
--- a/src/entities/pengguna.entity.ts
+++ b/src/entities/pengguna.entity.ts
@@ -1,4 +1,3 @@
-import { IsString } from "@nestjs/class-validator";
 import {
   ApiHideProperty,
   ApiProperty,
@@ -6,21 +5,18 @@ import {
 } from "@nestjs/swagger";
 import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
 import { PendaftaranTesis } from "./pendaftaranTesis.entity";
-import { SubmisiTugas } from "./submisiTugas.entity";
+import { DosenBimbingan } from "./dosenBimbingan.entity";
 
 export enum RoleEnum {
   ADMIN = "ADMIN",
-  TU = "TU",
   S2_MAHASISWA = "S2_MAHASISWA",
   S2_PEMBIMBING = "S2_PEMBIMBING",
   S2_PENGUJI = "S2_PENGUJI",
   S2_TIM_TESIS = "S2_TIM_TESIS",
-  S2_KULIAH = "S2_KULIAH",
   S1_MAHASISWA = "S1_MAHASISWA",
   S1_PEMBIMBING = "S1_PEMBIMBING",
   S1_PENGUJI = "S1_PENGUJI",
   S1_TIM_TA = "S1_TIM_TA",
-  S1_KULIAH = "S1_KULIAH",
 }
 
 @Entity()
@@ -55,13 +51,36 @@ export class Pengguna {
   roles: RoleEnum[];
 
   @ApiPropertyOptional()
-  @IsString()
   @Column({ type: "text", nullable: true })
-  kontak: string;
+  kontakWhatsApp: string;
+
+  @ApiPropertyOptional()
+  @Column({ type: "text", nullable: true })
+  kontakMsTeams: string;
+
+  @ApiPropertyOptional()
+  @Column({ type: "text", nullable: true })
+  kontakEmail: string;
+
+  @ApiPropertyOptional()
+  @Column({ type: "text", nullable: true })
+  kontakTelp: string;
+
+  @ApiPropertyOptional()
+  @Column({ type: "text", nullable: true })
+  kontakLainnya: string;
+
+  @ApiPropertyOptional()
+  @Column({ type: "text", nullable: true })
+  keahlian: string;
+
+  @ApiHideProperty()
+  @Column({ type: "boolean", default: true })
+  aktif: boolean;
 
   @OneToMany(() => PendaftaranTesis, (pendaftaran) => pendaftaran.mahasiswa)
   pendaftaranTesis: PendaftaranTesis[];
 
-  @OneToMany(() => SubmisiTugas, (submisiTugas) => submisiTugas.mahasiswa)
-  submisiTugas: SubmisiTugas[];
+  @OneToMany(() => DosenBimbingan, (dosen) => dosen.dosen)
+  dosenBimbingan: DosenBimbingan[];
 }
diff --git a/src/entities/ruangan.entity.ts b/src/entities/ruangan.entity.ts
deleted file mode 100644
index 86dfaf804683751d50f397df3a55f00488dc0bfa..0000000000000000000000000000000000000000
--- a/src/entities/ruangan.entity.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-// import { ApiProperty } from "@nestjs/swagger";
-// import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
-
-// @Entity()
-// export class Ruangan {
-//   @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-//   @PrimaryGeneratedColumn("uuid")
-//   id: string;
-
-//   @ApiProperty()
-//   @Column({ type: "text" })
-//   nama: string;
-// }
diff --git a/src/entities/submisiTugas.entity.ts b/src/entities/submisiTugas.entity.ts
deleted file mode 100644
index be380d37d6c0b4dadf641f794735a343990e13b5..0000000000000000000000000000000000000000
--- a/src/entities/submisiTugas.entity.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import {
-  Column,
-  Entity,
-  JoinColumn,
-  ManyToOne,
-  OneToMany,
-  PrimaryGeneratedColumn,
-} from "typeorm";
-import { Pengguna } from "./pengguna.entity";
-import { Tugas } from "./tugas.entity";
-import { BerkasSubmisiTugas } from "./berkasSubmisiTugas.entity";
-import { ApiProperty } from "@nestjs/swagger";
-import { IsString, IsUUID } from "class-validator";
-import { IsBoolean } from "@nestjs/class-validator";
-
-@Entity()
-export class SubmisiTugas {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
-  @JoinColumn({ name: "mahasiswaId" })
-  mahasiswa: Pengguna;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @Column()
-  mahasiswaId: string;
-
-  @ApiProperty()
-  @IsString()
-  @Column({ type: "text" })
-  jawaban: string;
-
-  @ApiProperty({ description: "true means submitted, false means draft" })
-  @IsBoolean()
-  @Column({ type: "boolean" })
-  isSubmitted: boolean; // false means draft (saved), true means submitted
-
-  @ApiProperty({ type: [BerkasSubmisiTugas] })
-  @OneToMany(
-    () => BerkasSubmisiTugas,
-    (berkasSubmisiTugas) => berkasSubmisiTugas.submisiTugas,
-    { cascade: true },
-  )
-  berkasSubmisiTugas: BerkasSubmisiTugas[];
-
-  @ApiProperty()
-  @Column({
-    type: "timestamptz",
-    default: () => "CURRENT_TIMESTAMP",
-    nullable: true,
-  })
-  submittedAt: Date;
-
-  @ManyToOne(() => Tugas, (tugas) => tugas.id)
-  @JoinColumn({ name: "tugasId" })
-  tugas: Tugas;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @Column()
-  tugasId: string;
-}
diff --git a/src/entities/topik.entity.ts b/src/entities/topik.entity.ts
index 127540cc0619fa7863227bf11029f78160287a84..17eb3bf158b175d37e93a9a0684a16f943bc5ba1 100644
--- a/src/entities/topik.entity.ts
+++ b/src/entities/topik.entity.ts
@@ -1,4 +1,3 @@
-import { ApiProperty } from "@nestjs/swagger";
 import {
   Column,
   Entity,
@@ -7,6 +6,7 @@ import {
   PrimaryGeneratedColumn,
 } from "typeorm";
 import { Pengguna } from "./pengguna.entity";
+import { ApiHideProperty, ApiProperty } from "@nestjs/swagger";
 
 @Entity()
 export class Topik {
@@ -31,7 +31,7 @@ export class Topik {
   @Column({ nullable: true })
   idPengaju: string;
 
-  @ApiProperty()
-  @Column({ type: "text" })
-  periode: string;
+  @ApiHideProperty()
+  @Column({ type: "boolean", default: true })
+  aktif: boolean;
 }
diff --git a/src/entities/tugas.entity.ts b/src/entities/tugas.entity.ts
deleted file mode 100644
index 2424b87973fd01fe854e40ca50079dbc40e0f4ee..0000000000000000000000000000000000000000
--- a/src/entities/tugas.entity.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import {
-  Column,
-  Entity,
-  JoinColumn,
-  ManyToOne,
-  OneToMany,
-  PrimaryGeneratedColumn,
-} from "typeorm";
-import { Kelas } from "./kelas.entity";
-import { Pengguna } from "./pengguna.entity";
-import { BerkasTugas } from "./berkasTugas.entity";
-import { ApiProperty } from "@nestjs/swagger";
-import { IsDateString, IsUUID, MaxLength } from "class-validator";
-import { IsString } from "@nestjs/class-validator";
-import { SubmisiTugas } from "./submisiTugas.entity";
-
-@Entity()
-export class Tugas {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @PrimaryGeneratedColumn("uuid")
-  id: string;
-
-  @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
-  @JoinColumn({ name: "pembuatId" })
-  pembuat: Pengguna;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @Column()
-  pembuatId: string;
-
-  @ManyToOne(() => Pengguna, (pengguna) => pengguna.id)
-  @JoinColumn({ name: "pengubahId" })
-  pengubah: Pengguna;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @Column()
-  pengubahId: string;
-
-  @ApiProperty()
-  @IsString()
-  @MaxLength(256)
-  @Column({ type: "varchar", length: 256 })
-  judul: string;
-
-  @ApiProperty()
-  @IsDateString()
-  @Column({ type: "timestamptz", default: () => "CURRENT_TIMESTAMP" })
-  waktuMulai: Date;
-
-  @ApiProperty()
-  @IsDateString()
-  @Column({ type: "timestamptz" })
-  waktuSelesai: Date;
-
-  @ApiProperty()
-  @IsString()
-  @Column({ type: "text" })
-  deskripsi: string;
-
-  @ApiProperty({ type: [BerkasTugas] })
-  @OneToMany(() => BerkasTugas, (berkasTugas) => berkasTugas.tugas, {
-    cascade: true,
-  })
-  berkasTugas: BerkasTugas[];
-
-  @ApiProperty()
-  @Column({ type: "timestamptz", default: () => "CURRENT_TIMESTAMP" })
-  createdAt: Date;
-
-  @ApiProperty()
-  @Column({ type: "timestamptz", default: () => "CURRENT_TIMESTAMP" })
-  updatedAt: Date;
-
-  @ManyToOne(() => Kelas, (kelas) => kelas.id)
-  @JoinColumn({ name: "kelasId" })
-  kelas: Kelas;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  @Column()
-  kelasId: string;
-
-  @OneToMany(() => SubmisiTugas, (submisiTugas) => submisiTugas.tugas)
-  submisiTugas: SubmisiTugas[];
-}
diff --git a/src/env.validation.ts b/src/env.validation.ts
index e14a7cc35fd80b3e9bd3c0dbb3fbcbee7c31e157..1d5e6d037f02d9f54e2c3c7a0af08adc63785ff6 100644
--- a/src/env.validation.ts
+++ b/src/env.validation.ts
@@ -34,36 +34,6 @@ class EnvironmentVariables {
   @IsUrl({ require_tld: false })
   FE_URL: string;
 
-  @IsString()
-  KONF_PERIODE_KEY: string;
-
-  @IsString()
-  KONF_MIN_BIMBINGAN_KEY: string;
-
-  @IsString()
-  KONF_AWAL_PENDAFTARAN_KEY: string;
-
-  @IsString()
-  KONF_AKHIR_PENDAFTARAN_KEY: string;
-
-  @IsString()
-  KONF_AWAL_SEMPRO_KEY: string;
-
-  @IsString()
-  KONF_AKHIR_SEMPRO_KEY: string;
-
-  @IsString()
-  KONF_AWAL_SEM_TESIS_KEY: string;
-
-  @IsString()
-  KONF_AKHIR_SEM_TESIS_KEY: string;
-
-  @IsString()
-  KONF_AWAL_SIDANG_KEY: string;
-
-  @IsString()
-  KONF_AKHIR_SIDANG_KEY: string;
-
   @IsString()
   COOKIE_NAME: string;
 }
diff --git a/src/helper/roles.ts b/src/helper/roles.ts
new file mode 100644
index 0000000000000000000000000000000000000000..690f29dd520df4c348a4520cfc75aee48540dca5
--- /dev/null
+++ b/src/helper/roles.ts
@@ -0,0 +1,7 @@
+import { RoleEnum } from "src/entities/pengguna.entity";
+
+export const HIGH_AUTHORITY_ROLES = [RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS];
+
+export function isHighAuthority(roles: RoleEnum[]) {
+  return roles.some((role) => HIGH_AUTHORITY_ROLES.includes(role));
+}
diff --git a/src/helper/validation.ts b/src/helper/validation.ts
deleted file mode 100644
index cfc65eb722c4859bd1569749bccb0e8785721b77..0000000000000000000000000000000000000000
--- a/src/helper/validation.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { NotFoundException } from "@nestjs/common";
-import { validate as uuidValidate } from "uuid";
-
-interface ID {
-  id: string;
-  object: string;
-}
-
-export function validateId(items: ID[]) {
-  for (const item of items) {
-    const isValidUUID = uuidValidate(item.id);
-
-    if (!isValidUUID) {
-      throw new NotFoundException(`${item.object} not found.`);
-    }
-  }
-}
diff --git a/src/kelas/kelas.constant.ts b/src/kelas/kelas.constant.ts
deleted file mode 100644
index 050cbbca5914f9eb24c9e646e62e2629d047a51b..0000000000000000000000000000000000000000
--- a/src/kelas/kelas.constant.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export const CARD_COLORS = [
-  "bg-blue-600/20",
-  "bg-yellow-600/20",
-  "bg-green-600/20",
-  "bg-red-600/20",
-  "bg-purple-600/20",
-  "bg-pink-600/20",
-  "bg-indigo-600/20",
-  "bg-cyan-600/20",
-  "bg-amber-600/20",
-  "bg-lime-600/20",
-  "bg-emerald-600/20",
-  "bg-teal-600/20",
-  "bg-cyan-600/20",
-  "bg-violet-600/20",
-  "bg-fuchsia-600/20",
-  "bg-rose-600/20",
-  "bg-sky-600/20",
-  "bg-cyan-600/20",
-];
diff --git a/src/kelas/kelas.controller.ts b/src/kelas/kelas.controller.ts
deleted file mode 100644
index ae942b029bd3415ece79a2d5df0b3b4ad5befd3a..0000000000000000000000000000000000000000
--- a/src/kelas/kelas.controller.ts
+++ /dev/null
@@ -1,231 +0,0 @@
-import {
-  Body,
-  Controller,
-  Delete,
-  ForbiddenException,
-  Get,
-  Param,
-  Post,
-  Put,
-  Query,
-  Req,
-  UseGuards,
-} from "@nestjs/common";
-import {
-  ByIdKelasDto,
-  CreateKelasDto,
-  DeleteKelasDto,
-  GetKelasDetailRespDto,
-  GetKelasQueryDto,
-  GetKelasRespDto,
-  GetNextNomorResDto,
-  IdKelasResDto,
-  KodeRespDto,
-  UpdateKelasDto,
-} from "./kelas.dto";
-import { Request } from "express";
-import { AuthDto } from "src/auth/auth.dto";
-import { RoleEnum } from "src/entities/pengguna.entity";
-import {
-  ApiBadRequestResponse,
-  ApiBearerAuth,
-  ApiCookieAuth,
-  ApiCreatedResponse,
-  ApiInternalServerErrorResponse,
-  ApiNotFoundResponse,
-  ApiOkResponse,
-  ApiOperation,
-  ApiTags,
-} from "@nestjs/swagger";
-import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
-import { RolesGuard } from "src/middlewares/roles.guard";
-import { KelasService } from "./kelas.service";
-import { Roles } from "src/middlewares/roles.decorator";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-import { Kelas } from "src/entities/kelas.entity";
-
-@ApiTags("Kelas")
-@ApiBearerAuth()
-@ApiCookieAuth()
-@Controller("kelas")
-@UseGuards(CustomAuthGuard, RolesGuard)
-export class KelasController {
-  constructor(private readonly kelasServ: KelasService) {}
-
-  @ApiOperation({
-    summary:
-      "Get list of kelas. Roles: S2_KULIAH, S2_MAHASISWA, S2_TIM_TESIS, ADMIN",
-  })
-  @ApiOkResponse({ type: GetKelasRespDto, isArray: true })
-  @Roles(
-    RoleEnum.S2_KULIAH,
-    RoleEnum.S2_MAHASISWA,
-    RoleEnum.S2_TIM_TESIS,
-    RoleEnum.ADMIN,
-  )
-  @Get()
-  async getListKelas(@Query() query: GetKelasQueryDto, @Req() req: Request) {
-    let idMahasiswa = undefined;
-    let idPengajar = undefined;
-
-    const { id, roles } = req.user as AuthDto;
-
-    if (!roles.includes(query.view)) {
-      throw new ForbiddenException();
-    }
-
-    if (query.view === RoleEnum.S2_KULIAH) {
-      idPengajar = id;
-    }
-
-    if (query.view === RoleEnum.S2_MAHASISWA) {
-      idMahasiswa = id;
-    }
-
-    return await this.kelasServ.getListKelas(
-      idMahasiswa,
-      idPengajar,
-      query.kodeMatkul,
-      query.search,
-    );
-  }
-
-  @ApiOkResponse({ type: MataKuliah, isArray: true })
-  @Get("/mata-kuliah")
-  async getAllMatkul() {
-    return await this.kelasServ.getAllMatkul();
-  }
-
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
-  @ApiOkResponse({ type: GetNextNomorResDto })
-  @Get("/next-nomor/:kodeMatkul")
-  async getNextNomor(
-    @Param("kodeMatkul") kodeMatkul: string,
-  ): Promise<GetNextNomorResDto> {
-    const nomor = await this.kelasServ.getNextNomorKelas(kodeMatkul);
-
-    return {
-      nomor,
-    };
-  }
-
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
-  @ApiOkResponse({ type: IdKelasResDto })
-  @ApiBadRequestResponse({
-    description: "Nomor kelas sudah ada",
-  })
-  @ApiInternalServerErrorResponse({
-    description: "Gagal membuat kelas",
-  })
-  @Post()
-  async createKelas(@Body() body: CreateKelasDto): Promise<IdKelasResDto> {
-    return await this.kelasServ.create(body);
-  }
-
-  // TODO: restrict payload
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
-  @ApiOkResponse({ type: IdKelasResDto })
-  @ApiNotFoundResponse({
-    description: "Kelas dengan id (dan nomor) yang terkait tidak ditemukan",
-  })
-  @ApiBadRequestResponse({
-    description:
-      "(Saat pembuatan kelas) nomor kelas sudah ada atau mataKuliahKode tidak ada",
-  })
-  @ApiInternalServerErrorResponse({
-    description: "Gagal memperbarui kelas atau gagal membuat kelas",
-  })
-  @Put()
-  async updateKelas(@Body() body: UpdateKelasDto): Promise<IdKelasResDto> {
-    return await this.kelasServ.updateOrCreate(body);
-  }
-
-  @ApiCreatedResponse({ type: KodeRespDto })
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
-  @Post("mata-kuliah")
-  async createMataKuliah(@Body() body: MataKuliah) {
-    return await this.kelasServ.createMatkul(body);
-  }
-
-  @Roles(RoleEnum.S2_TIM_TESIS, RoleEnum.ADMIN)
-  @ApiOkResponse({ type: Kelas })
-  @ApiNotFoundResponse({ description: "Kelas tidak ditemukan" })
-  @ApiInternalServerErrorResponse({ description: "Gagal menghapus kelas" })
-  @Delete()
-  async delete(@Body() body: DeleteKelasDto): Promise<Kelas> {
-    return await this.kelasServ.delete(body);
-  }
-
-  @Roles(
-    RoleEnum.S2_TIM_TESIS,
-    RoleEnum.ADMIN,
-    RoleEnum.S2_KULIAH,
-    RoleEnum.S2_MAHASISWA,
-  )
-  @ApiOkResponse({ type: GetKelasRespDto })
-  @ApiOperation({
-    summary:
-      "Get kelas general information by kelas id. Roles: S2_KULIAH, S2_MAHASISWA, S2_TIM_TESIS, ADMIN",
-  })
-  @Get("/:id")
-  async getById(
-    @Param() param: ByIdKelasDto,
-    @Req() req: Request,
-  ): Promise<GetKelasRespDto> {
-    let idMahasiswa = undefined;
-    let idPengajar = undefined;
-
-    const { id, roles } = req.user as AuthDto;
-
-    if (
-      !roles.includes(RoleEnum.S2_TIM_TESIS) &&
-      !roles.includes(RoleEnum.ADMIN)
-    ) {
-      if (roles.includes(RoleEnum.S2_KULIAH)) {
-        idPengajar = id;
-      } else {
-        // requester only has S2_MAHASISWA access
-        idMahasiswa = id;
-      }
-    }
-
-    return await this.kelasServ.getById(param.id, idMahasiswa, idPengajar);
-  }
-
-  @Roles(
-    RoleEnum.S2_TIM_TESIS,
-    RoleEnum.ADMIN,
-    RoleEnum.S2_KULIAH,
-    RoleEnum.S2_MAHASISWA,
-  )
-  @ApiOperation({
-    summary:
-      "Get kelas mahasiswa and pengajar list by kelas id. Roles: S2_KULIAH, S2_MAHASISWA, S2_TIM_TESIS, ADMIN",
-  })
-  @ApiOkResponse({ type: GetKelasDetailRespDto })
-  @Get("/:id/detail")
-  async getKelasDetail(@Param() param: ByIdKelasDto, @Req() req: Request) {
-    let idMahasiswa = undefined;
-    let idPengajar = undefined;
-
-    const { id, roles } = req.user as AuthDto;
-
-    if (
-      !roles.includes(RoleEnum.S2_TIM_TESIS) &&
-      !roles.includes(RoleEnum.ADMIN)
-    ) {
-      if (roles.includes(RoleEnum.S2_KULIAH)) {
-        idPengajar = id;
-      } else {
-        // requester only has S2_MAHASISWA access
-        idMahasiswa = id;
-      }
-    }
-
-    return await this.kelasServ.getKelasDetail(
-      param.id,
-      idMahasiswa,
-      idPengajar,
-    );
-  }
-}
diff --git a/src/kelas/kelas.dto.ts b/src/kelas/kelas.dto.ts
deleted file mode 100644
index 352ae36ea1a1d0c0e45ee7e9eb6eb778cd460439..0000000000000000000000000000000000000000
--- a/src/kelas/kelas.dto.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import { IsEnum, IsOptional, IsPositive } from "@nestjs/class-validator";
-import {
-  ApiProperty,
-  PickType,
-  PartialType,
-  ApiPropertyOptional,
-} from "@nestjs/swagger";
-import { Kelas } from "src/entities/kelas.entity";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-import { Pengguna, RoleEnum } from "src/entities/pengguna.entity";
-
-export class CreateKelasDto extends PickType(Kelas, [
-  "mataKuliahKode",
-] as const) {
-  @ApiPropertyOptional({ example: 1 })
-  @IsOptional()
-  @IsPositive()
-  nomor: number;
-}
-
-export class UpdateKelasDto extends PartialType(Kelas) {}
-
-export class IdKelasResDto extends PickType(Kelas, ["id"] as const) {}
-
-export class DeleteKelasDto extends PickType(Kelas, [
-  "mataKuliahKode",
-  "nomor",
-] as const) {}
-
-export class GetKelasQueryDto {
-  @IsEnum([RoleEnum.S2_KULIAH, RoleEnum.S2_MAHASISWA, RoleEnum.S2_TIM_TESIS])
-  @ApiProperty({
-    enum: [RoleEnum.S2_KULIAH, RoleEnum.S2_MAHASISWA, RoleEnum.S2_TIM_TESIS],
-  })
-  view: RoleEnum.S2_KULIAH | RoleEnum.S2_MAHASISWA | RoleEnum.S2_TIM_TESIS;
-
-  @ApiPropertyOptional({ example: "IF3270" })
-  @IsOptional()
-  kodeMatkul: string;
-
-  @ApiPropertyOptional({ example: "Intelegensi Buatan" })
-  @IsOptional()
-  search: string;
-}
-
-export class ByIdKelasDto extends PickType(Kelas, ["id"] as const) {}
-
-export class GetKelasRespDto {
-  @ApiProperty()
-  id: string;
-
-  @ApiProperty({ example: "K02" })
-  nomor: string;
-
-  @ApiProperty({ example: "IF3270" })
-  kode_mata_kuliah: string;
-
-  @ApiProperty({ example: "Pengembangan Aplikasi Terdistribusi" })
-  nama_mata_kuliah: string;
-
-  @ApiProperty()
-  jumlah_mahasiswa: number;
-
-  @ApiProperty({ example: "bg-blue-600/20" })
-  warna: string;
-}
-
-export class KodeRespDto extends PickType(MataKuliah, ["kode"] as const) {}
-
-export class GetNextNomorResDto {
-  @ApiProperty({ example: 2 })
-  nomor: number;
-}
-
-class PickedPengajarKelasDto extends PickType(Pengguna, [
-  "id",
-  "nama",
-] as const) {}
-
-class PickedMahasiswaKelasDto extends PickType(Pengguna, [
-  "id",
-  "nama",
-  "nim",
-] as const) {}
-
-export class GetKelasDetailRespDto extends PickType(Kelas, ["id"] as const) {
-  @ApiProperty({ type: [PickedPengajarKelasDto] })
-  pengajar: PickedPengajarKelasDto[];
-
-  @ApiProperty({ type: [PickedMahasiswaKelasDto] })
-  mahasiswa: PickedMahasiswaKelasDto[];
-}
diff --git a/src/kelas/kelas.module.ts b/src/kelas/kelas.module.ts
deleted file mode 100644
index 38dfa27f8690f2608b1450c134536f7d3d920651..0000000000000000000000000000000000000000
--- a/src/kelas/kelas.module.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Module } from "@nestjs/common";
-import { KelasService } from "./kelas.service";
-import { TypeOrmModule } from "@nestjs/typeorm";
-import { Kelas } from "src/entities/kelas.entity";
-import { AuthModule } from "src/auth/auth.module";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
-import { KelasController } from "./kelas.controller";
-import { CustomStrategy } from "src/middlewares/custom.strategy";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-
-@Module({
-  imports: [
-    TypeOrmModule.forFeature([Kelas, MataKuliah]),
-    AuthModule,
-    KonfigurasiModule,
-  ],
-  controllers: [KelasController],
-  providers: [KelasService, CustomStrategy],
-})
-export class KelasModule {}
diff --git a/src/kelas/kelas.service.ts b/src/kelas/kelas.service.ts
deleted file mode 100644
index fa62a4707fe36efeca92ef76b8074dd392e7a92b..0000000000000000000000000000000000000000
--- a/src/kelas/kelas.service.ts
+++ /dev/null
@@ -1,361 +0,0 @@
-import {
-  BadRequestException,
-  Injectable,
-  InternalServerErrorException,
-  NotFoundException,
-} from "@nestjs/common";
-import { InjectRepository } from "@nestjs/typeorm";
-import { Kelas } from "src/entities/kelas.entity";
-import { Brackets, Repository } from "typeorm";
-import {
-  CreateKelasDto,
-  DeleteKelasDto,
-  GetKelasDetailRespDto,
-  GetKelasRespDto,
-  IdKelasResDto,
-  UpdateKelasDto,
-} from "./kelas.dto";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-import { CARD_COLORS } from "./kelas.constant";
-
-@Injectable()
-export class KelasService {
-  constructor(
-    @InjectRepository(Kelas)
-    private kelasRepo: Repository<Kelas>,
-    @InjectRepository(MataKuliah)
-    private mataKuliahRepo: Repository<MataKuliah>,
-    private konfService: KonfigurasiService,
-  ) {}
-  async getListKelas(
-    idMahasiswa?: string,
-    idPengajar?: string,
-    kodeMatkul?: string,
-    search?: string,
-  ) {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    let baseQuery = this.kelasRepo
-      .createQueryBuilder("kelas")
-      .leftJoinAndSelect("kelas.mahasiswa", "mahasiswa")
-      .leftJoinAndSelect("kelas.mataKuliah", "mataKuliah")
-      .select([
-        "kelas.id AS id",
-        "kelas.nomor AS nomor",
-        "kelas.warna AS warna",
-        "mataKuliah.kode AS kode_mata_kuliah",
-        "mataKuliah.nama AS nama_mata_kuliah",
-        "COUNT(mahasiswa) AS jumlah_mahasiswa",
-      ])
-      .orderBy("mataKuliah.kode", "ASC")
-      .addOrderBy("kelas.nomor", "ASC")
-      .where("kelas.periode = :periode", { periode: currPeriod });
-
-    if (idMahasiswa) {
-      baseQuery = baseQuery
-        .innerJoin("kelas.mahasiswa", "mahasiswa_filter")
-        .andWhere("mahasiswa_filter.mahasiswaId = :idMahasiswa", {
-          idMahasiswa,
-        });
-    }
-
-    if (idPengajar) {
-      baseQuery = baseQuery
-        .innerJoin("kelas.pengajar", "pengajar")
-        .andWhere("pengajar.pengajarId = :idPengajar", {
-          idPengajar,
-        });
-    }
-
-    if (kodeMatkul) {
-      baseQuery = baseQuery.andWhere("mataKuliah.kode = :kodeMatkul", {
-        kodeMatkul,
-      });
-    }
-
-    if (search) {
-      baseQuery = baseQuery.andWhere(
-        new Brackets((qb) => {
-          qb.where("mataKuliah.kode ILIKE :search", {
-            search: `%${search}%`,
-          }).orWhere("mataKuliah.nama ILIKE :search", {
-            search: `%${search}%`,
-          });
-        }),
-      );
-    }
-
-    const result = await baseQuery
-      .groupBy("kelas.id, mataKuliah.kode")
-      .getRawMany();
-
-    const mapped: GetKelasRespDto[] = result.map((r) => ({
-      id: r.id,
-      nomor: "K" + `${r.nomor}`.padStart(2, "0"),
-      kode_mata_kuliah: r.kode_mata_kuliah,
-      nama_mata_kuliah: r.nama_mata_kuliah,
-      jumlah_mahasiswa: parseInt(r.jumlah_mahasiswa),
-      warna: r.warna,
-    }));
-
-    return mapped;
-  }
-
-  async getById(id: string, idMahasiswa?: string, idPengajar?: string) {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    let baseQuery = this.kelasRepo
-      .createQueryBuilder("kelas")
-      .leftJoinAndSelect("kelas.mahasiswa", "mahasiswa")
-      .leftJoinAndSelect("kelas.mataKuliah", "mataKuliah")
-      .select([
-        "kelas.id AS id",
-        "kelas.nomor AS nomor",
-        "kelas.warna AS warna",
-        "mataKuliah.kode AS kode_mata_kuliah",
-        "mataKuliah.nama AS nama_mata_kuliah",
-        "COUNT(mahasiswa) AS jumlah_mahasiswa",
-      ])
-      .where("kelas.id = :id", { id })
-      .andWhere("kelas.periode = :periode", { periode: currPeriod });
-
-    if (idMahasiswa) {
-      baseQuery = baseQuery
-        .innerJoin("kelas.mahasiswa", "mahasiswa_filter")
-        .andWhere("mahasiswa_filter.mahasiswaId = :idMahasiswa", {
-          idMahasiswa,
-        });
-    }
-
-    if (idPengajar) {
-      baseQuery = baseQuery
-        .innerJoin("kelas.pengajar", "pengajar")
-        .andWhere("pengajar.pengajarId = :idPengajar", {
-          idPengajar,
-        });
-    }
-
-    const result = await baseQuery
-      .groupBy("kelas.id, mataKuliah.kode")
-      .getRawOne();
-
-    if (!result) {
-      throw new NotFoundException("Kelas tidak ditemukan");
-    }
-
-    const mapped: GetKelasRespDto = {
-      id: result.id,
-      nomor: "K" + `${result.nomor}`.padStart(2, "0"),
-      kode_mata_kuliah: result.kode_mata_kuliah,
-      nama_mata_kuliah: result.nama_mata_kuliah,
-      jumlah_mahasiswa: parseInt(result.jumlah_mahasiswa),
-      warna: result.warna,
-    };
-
-    return mapped;
-  }
-
-  async getKelasDetail(
-    idKelas: string,
-    idMahasiswa?: string,
-    idPengajar?: string,
-  ) {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    let baseQuery = this.kelasRepo
-      .createQueryBuilder("kelas")
-      .leftJoinAndSelect("kelas.mahasiswa", "mahasiswaKelas")
-      .leftJoinAndSelect("mahasiswaKelas.mahasiswa", "mahasiswa")
-      .leftJoinAndSelect("kelas.pengajar", "pengajarKelas")
-      .leftJoinAndSelect("pengajarKelas.pengajar", "pengajar")
-      .select([
-        "kelas.id",
-        "mahasiswaKelas.id",
-        "mahasiswa.id",
-        "mahasiswa.nim",
-        "mahasiswa.nama",
-        "pengajarKelas.id",
-        "pengajar.id",
-        "pengajar.nama",
-      ])
-      .orderBy("pengajar.nama", "ASC")
-      .addOrderBy("mahasiswa.nim", "ASC")
-      .where("kelas.id = :idKelas", { idKelas })
-      .andWhere("kelas.periode = :periode", { periode: currPeriod });
-
-    if (idMahasiswa) {
-      baseQuery = baseQuery
-        .innerJoin("kelas.mahasiswa", "mahasiswaFilter")
-        .andWhere("mahasiswaFilter.mahasiswaId = :idMahasiswa", {
-          idMahasiswa,
-        });
-    }
-
-    if (idPengajar) {
-      baseQuery = baseQuery
-        .innerJoin("kelas.pengajar", "pengajarFilter")
-        .andWhere("pengajarFilter.pengajarId = :idPengajar", {
-          idPengajar,
-        });
-    }
-
-    const result = await baseQuery.getOne();
-
-    if (!result) {
-      throw new NotFoundException(
-        "Kelas tidak ditemukan di antara kelas yang dapat Anda akses",
-      );
-    }
-
-    const mapped: GetKelasDetailRespDto = {
-      id: result.id,
-      pengajar: result.pengajar.map((p) => ({
-        id: p.pengajar.id,
-        nama: p.pengajar.nama,
-      })),
-      mahasiswa: result.mahasiswa.map((m) => ({
-        id: m.mahasiswa.id,
-        nim: m.mahasiswa.nim,
-        nama: m.mahasiswa.nama,
-      })),
-    };
-
-    return mapped;
-  }
-
-  async create(createDto: CreateKelasDto): Promise<IdKelasResDto> {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    let nomor = createDto.nomor;
-    if (nomor) {
-      const checkClassQueary = this.kelasRepo
-        .createQueryBuilder("kelas")
-        .where("kelas.nomor = :nomor", { nomor })
-        .andWhere("kelas.mataKuliahKode = :mataKuliahKode", {
-          mataKuliahKode: createDto.mataKuliahKode,
-        })
-        .andWhere("kelas.periode = :periode", { periode: currPeriod });
-
-      const checkClass = await checkClassQueary.getOne();
-
-      if (checkClass) {
-        throw new BadRequestException(`Kelas dengan nomor ${nomor} sudah ada`);
-      }
-    } else {
-      nomor = await this.getNextNomorKelas(createDto.mataKuliahKode);
-    }
-
-    const colorIdx = Math.floor(Math.random() * CARD_COLORS.length);
-    const kelas = this.kelasRepo.create({
-      ...createDto,
-      nomor,
-      periode: currPeriod,
-      warna: CARD_COLORS[colorIdx],
-    });
-
-    try {
-      await this.kelasRepo.save(kelas);
-    } catch {
-      throw new InternalServerErrorException("Gagal membuat kelas baru");
-    }
-
-    return {
-      id: kelas.id,
-    };
-  }
-
-  async createMatkul(createDto: MataKuliah) {
-    await this.mataKuliahRepo.insert(createDto);
-
-    return { kode: createDto.kode };
-  }
-
-  async updateOrCreate(dto: UpdateKelasDto): Promise<IdKelasResDto> {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    if (!dto.id) {
-      // Create kelas
-      if (!dto.mataKuliahKode) {
-        throw new BadRequestException("Kode mata kuliah tidak boleh kosong");
-      }
-
-      return await this.create({
-        mataKuliahKode: dto.mataKuliahKode,
-        nomor: dto.nomor,
-      });
-    } else {
-      // Update kelas
-      const kelasQuery = this.kelasRepo
-        .createQueryBuilder("kelas")
-        .where("kelas.id = :id", { id: dto.id })
-        .andWhere("kelas.periode = :periode", { periode: currPeriod });
-
-      if (dto.nomor) {
-        kelasQuery.andWhere("kelas.nomor = :nomor", { nomor: dto.nomor });
-      }
-
-      const kelas = await kelasQuery.getOne();
-
-      if (!kelas) {
-        throw new NotFoundException("Kelas tidak ditemukan");
-      }
-
-      try {
-        await this.kelasRepo.update(kelas.id, dto);
-      } catch {
-        throw new InternalServerErrorException("Gagal memperbarui kelas");
-      }
-
-      return {
-        id: kelas.id,
-      };
-    }
-  }
-
-  async delete(dto: DeleteKelasDto): Promise<Kelas> {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    const kelasQuery = this.kelasRepo
-      .createQueryBuilder("kelas")
-      .where("kelas.nomor = :nomor", { nomor: dto.nomor })
-      .andWhere("kelas.mataKuliahKode = :mataKuliahKode", {
-        mataKuliahKode: dto.mataKuliahKode,
-      })
-      .andWhere("kelas.periode = :periode", { periode: currPeriod });
-
-    const kelas = await kelasQuery.getOne();
-
-    if (!kelas) {
-      throw new BadRequestException("Kelas tidak ditemukan");
-    }
-
-    try {
-      await this.kelasRepo.delete(kelas.id);
-    } catch {
-      throw new InternalServerErrorException("Gagal menghapus kelas");
-    }
-
-    return kelas;
-  }
-
-  async getAllMatkul(): Promise<MataKuliah[]> {
-    return await this.mataKuliahRepo.find();
-  }
-
-  async getNextNomorKelas(kodeMatkul: string): Promise<number> {
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-
-    const maxClass = await this.kelasRepo.findOne({
-      where: {
-        mataKuliahKode: kodeMatkul,
-        periode: currPeriod,
-      },
-      order: {
-        nomor: "DESC",
-      },
-    });
-
-    return maxClass ? maxClass.nomor + 1 : 1;
-  }
-}
diff --git a/src/konfigurasi/konfigurasi.controller.ts b/src/konfigurasi/konfigurasi.controller.ts
index 8f5b99b300caba5f8c9d09d5b032feaa08f613ab..caf6a97a7950a431351f9d130913c7be03783420 100644
--- a/src/konfigurasi/konfigurasi.controller.ts
+++ b/src/konfigurasi/konfigurasi.controller.ts
@@ -26,8 +26,7 @@ export class KonfigurasiController {
   async updateKonfigurasi(
     @Body() data: KonfigurasiArrDto,
   ): Promise<UpdateKonfigurasiResDto> {
-    await this.konfigurasiService.updateKonfigurasi(data);
-    return { message: "success" };
+    return await this.konfigurasiService.updateKonfigurasi(data);
   }
 
   @ApiOkResponse({ type: KonfigurasiArrDto })
diff --git a/src/konfigurasi/konfigurasi.dto.ts b/src/konfigurasi/konfigurasi.dto.ts
index 0de2f06b9f82d10df61c2c475ab1e56a26d3342a..1ebdd10da2f421f1aabdd53afe02b26466269032 100644
--- a/src/konfigurasi/konfigurasi.dto.ts
+++ b/src/konfigurasi/konfigurasi.dto.ts
@@ -1,24 +1,19 @@
 import { ApiProperty } from "@nestjs/swagger";
 import { Type } from "class-transformer";
-import { IsString, ValidateNested } from "class-validator";
+import { ValidateNested } from "class-validator";
+import {
+  Konfigurasi,
+  KonfigurasiKeyEnum,
+} from "src/entities/konfigurasi.entity";
 
-export class KonfigurasiDto {
-  @ApiProperty()
-  @IsString()
-  key: string;
-
-  @ApiProperty()
-  @IsString()
-  value: string;
-}
 export class KonfigurasiArrDto {
-  @ApiProperty({ type: [KonfigurasiDto] })
+  @ApiProperty({ type: [Konfigurasi] })
   @ValidateNested({ each: true })
-  @Type(() => KonfigurasiDto)
-  data: KonfigurasiDto[];
+  @Type(() => Konfigurasi)
+  data: Konfigurasi[];
 }
 
 export class UpdateKonfigurasiResDto {
-  @ApiProperty()
-  message: string;
+  @ApiProperty({ enum: KonfigurasiKeyEnum, isArray: true })
+  keys: KonfigurasiKeyEnum[];
 }
diff --git a/src/konfigurasi/konfigurasi.service.ts b/src/konfigurasi/konfigurasi.service.ts
index a8e7edaccbcafeeab8aa59f9039ce69ae88a21c2..6702c21184cc55ec1124dc165b0abd80abf4ad43 100644
--- a/src/konfigurasi/konfigurasi.service.ts
+++ b/src/konfigurasi/konfigurasi.service.ts
@@ -1,8 +1,11 @@
-import { BadRequestException, Injectable } from "@nestjs/common";
+import { Injectable } from "@nestjs/common";
 import { InjectRepository } from "@nestjs/typeorm";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
+import {
+  Konfigurasi,
+  KonfigurasiKeyEnum,
+} from "src/entities/konfigurasi.entity";
 import { Repository } from "typeorm";
-import { KonfigurasiArrDto } from "./konfigurasi.dto";
+import { KonfigurasiArrDto, UpdateKonfigurasiResDto } from "./konfigurasi.dto";
 
 @Injectable()
 export class KonfigurasiService {
@@ -11,16 +14,25 @@ export class KonfigurasiService {
     private konfigurasiRepository: Repository<Konfigurasi>,
   ) {}
 
-  async updateKonfigurasi({ data }: KonfigurasiArrDto) {
-    return await this.konfigurasiRepository.upsert(data, ["key"]);
+  async updateKonfigurasi({
+    data,
+  }: KonfigurasiArrDto): Promise<UpdateKonfigurasiResDto> {
+    await this.konfigurasiRepository.upsert(data, ["key"]);
+    const res = {
+      keys: data.map((d) => d.key),
+    };
+    return res;
   }
 
   async getKonfigurasi(): Promise<KonfigurasiArrDto> {
     const data = await this.konfigurasiRepository.find();
+
     return { data };
   }
 
-  async getKonfigurasiByKey(key: string): Promise<string | undefined> {
+  async getKonfigurasiByKey(
+    key: KonfigurasiKeyEnum,
+  ): Promise<string | undefined> {
     const data = await this.konfigurasiRepository.findOne({
       where: {
         key,
@@ -29,16 +41,4 @@ export class KonfigurasiService {
 
     return data?.value;
   }
-
-  async getPeriodeOrFail() {
-    const currPeriod = await this.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!currPeriod) {
-      throw new BadRequestException("Periode belum dikonfigurasi");
-    }
-
-    return currPeriod;
-  }
 }
diff --git a/src/main.ts b/src/main.ts
index fdce89e3372e4a1ea2d1a7bf5006ee2054c3f487..8f39d1c33675cd4f871fe6271f9bfbd301979f3a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -25,12 +25,8 @@ async function bootstrap() {
     .addTag("Bimbingan")
     .addTag("Dashboard")
     .addTag("Dosen Bimbingan")
-    .addTag("Kelas")
     .addTag("Konfigurasi")
-    .addTag("Nilai")
     .addTag("Registrasi Tesis")
-    .addTag("Submisi Tugas")
-    .addTag("Tugas")
     .addCookieAuth(process.env.COOKIE_NAME)
     .addBearerAuth()
     .build();
diff --git a/src/nilai/nilai.controller.ts b/src/nilai/nilai.controller.ts
deleted file mode 100644
index 6bb1cb659a4ad0347e37c69df0ad85750da2d1ad..0000000000000000000000000000000000000000
--- a/src/nilai/nilai.controller.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { Body, Controller, Get, Patch, Query, UseGuards } from "@nestjs/common";
-import { NilaiService } from "./nilai.service";
-import {
-  ApiBearerAuth,
-  ApiCookieAuth,
-  ApiOkResponse,
-  ApiTags,
-} from "@nestjs/swagger";
-import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
-import { RolesGuard } from "src/middlewares/roles.guard";
-import { Roles } from "src/middlewares/roles.decorator";
-import { RoleEnum } from "src/entities/pengguna.entity";
-import {
-  GetNilaiByMatkulQueryDto,
-  GetNilaiByMatkulRespDto,
-  UpdateNilaiDto,
-  UpdateNilaiRespDto,
-} from "./nilai.dto";
-
-@ApiBearerAuth()
-@ApiCookieAuth()
-@ApiTags("Nilai")
-@UseGuards(CustomAuthGuard, RolesGuard)
-@Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
-@Controller("nilai")
-export class NilaiController {
-  constructor(private nilaiServ: NilaiService) {}
-
-  @ApiOkResponse({ type: [GetNilaiByMatkulRespDto] })
-  @Get()
-  async getNilaiByMatkul(@Query() query: GetNilaiByMatkulQueryDto) {
-    return this.nilaiServ.getNilaiByMatkul(
-      query.kode,
-      query.page || 1,
-      query.limit || 10,
-      query.search || "",
-    );
-  }
-
-  @ApiOkResponse({ type: UpdateNilaiRespDto })
-  @Patch()
-  async updateNilai(@Body() body: UpdateNilaiDto) {
-    return this.nilaiServ.updateNilai(body.mahasiswaKelasIds, body.nilaiAkhir);
-  }
-}
diff --git a/src/nilai/nilai.dto.ts b/src/nilai/nilai.dto.ts
deleted file mode 100644
index 1b933d07468212dbfacd8fc41d441227b5084418..0000000000000000000000000000000000000000
--- a/src/nilai/nilai.dto.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { IsNumberString } from "@nestjs/class-validator";
-import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
-import {
-  IsNumber,
-  IsOptional,
-  IsPositive,
-  IsString,
-  IsUUID,
-  MaxLength,
-  MinLength,
-} from "class-validator";
-
-export class GetNilaiByMatkulQueryDto {
-  @ApiPropertyOptional({ example: "IF4031" })
-  @IsOptional()
-  @IsString()
-  @MinLength(6)
-  @MaxLength(6)
-  kode?: string;
-
-  @ApiPropertyOptional()
-  @IsOptional()
-  @IsString()
-  search?: string;
-
-  @IsOptional()
-  @IsNumberString()
-  @ApiPropertyOptional({ description: "default: 1" })
-  page?: number;
-
-  @IsOptional()
-  @IsNumberString()
-  @ApiPropertyOptional({ description: "default: 10" })
-  limit?: number;
-}
-
-export class GetNilaiByMatkulRespDto {
-  @ApiProperty({ example: "IF4031" })
-  mata_kuliah_kode: string;
-
-  @ApiProperty({ example: "Pemrograman Berbasis Kerangka Kerja" })
-  mata_kuliah_nama: string;
-
-  @ApiProperty()
-  kelas_nomor: number;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  mahasiswa_kelas_id: string;
-
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  mahasiswa_id: string;
-
-  @ApiProperty()
-  mahasiswa_nama: string;
-
-  @ApiProperty({ example: "13517000" })
-  mahasiswa_nim: string;
-
-  @ApiProperty()
-  nilai_akhir: string | null;
-}
-
-export class UpdateNilaiRespDto {
-  @ApiProperty({
-    type: [String],
-    example: ["550e8400-e29b-41d4-a716-446655440000"],
-  })
-  @IsUUID("all", { each: true })
-  mahasiswaKelasIds: string[];
-}
-
-export class UpdateNilaiDto extends UpdateNilaiRespDto {
-  @ApiPropertyOptional({ description: "undefined: assign nilai to null" })
-  @IsOptional()
-  @IsNumber()
-  @IsPositive()
-  nilaiAkhir?: number;
-}
diff --git a/src/nilai/nilai.module.ts b/src/nilai/nilai.module.ts
deleted file mode 100644
index f9aca923b411670865c235c946b28d698a099a52..0000000000000000000000000000000000000000
--- a/src/nilai/nilai.module.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Module } from "@nestjs/common";
-import { TypeOrmModule } from "@nestjs/typeorm";
-import { AuthModule } from "src/auth/auth.module";
-import { Kelas } from "src/entities/kelas.entity";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
-import { MahasiswaKelas } from "src/entities/mahasiswaKelas.entity";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-import { KelasModule } from "src/kelas/kelas.module";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
-import { NilaiController } from "./nilai.controller";
-import { NilaiService } from "./nilai.service";
-import { CustomStrategy } from "src/middlewares/custom.strategy";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import { KelasService } from "src/kelas/kelas.service";
-
-@Module({
-  imports: [
-    TypeOrmModule.forFeature([MahasiswaKelas, Kelas, MataKuliah, Konfigurasi]),
-    AuthModule,
-    KonfigurasiModule,
-    KelasModule,
-  ],
-  controllers: [NilaiController],
-  providers: [NilaiService, CustomStrategy, KelasService, KonfigurasiService],
-})
-export class NilaiModule {}
diff --git a/src/nilai/nilai.service.ts b/src/nilai/nilai.service.ts
deleted file mode 100644
index 81ebba4d7151fc7b42f495d542af94057fd4f66e..0000000000000000000000000000000000000000
--- a/src/nilai/nilai.service.ts
+++ /dev/null
@@ -1,98 +0,0 @@
-import { Injectable } from "@nestjs/common";
-import { InjectRepository } from "@nestjs/typeorm";
-import { Kelas } from "src/entities/kelas.entity";
-import { MahasiswaKelas } from "src/entities/mahasiswaKelas.entity";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import { Brackets, In, Repository } from "typeorm";
-import { GetNilaiByMatkulRespDto, UpdateNilaiRespDto } from "./nilai.dto";
-
-@Injectable()
-export class NilaiService {
-  constructor(
-    @InjectRepository(MahasiswaKelas)
-    private mhsKelasRepo: Repository<MahasiswaKelas>,
-    @InjectRepository(Kelas)
-    private kelasRepo: Repository<Kelas>,
-    @InjectRepository(MataKuliah)
-    private mataKuliahRepo: Repository<MataKuliah>,
-    private konfServ: KonfigurasiService,
-  ) {}
-
-  private async isMhsKelasOrFail(mhsKelasIds: string[]) {
-    const periode = await this.konfServ.getPeriodeOrFail();
-
-    const mhsKelas = await this.mhsKelasRepo.find({
-      select: { id: true },
-      where: { id: In(mhsKelasIds), kelas: { periode } },
-    });
-
-    for (const mhsKelasId of mhsKelasIds) {
-      if (!mhsKelas.find((mk) => mk.id === mhsKelasId)) {
-        throw new Error(`Mahasiswa kelas ${mhsKelasId} tidak ditemukan`);
-      }
-    }
-  }
-
-  async getNilaiByMatkul(
-    mataKuliahKode: string,
-    page: number,
-    limit: number,
-    search: string,
-  ) {
-    const currPeriode = await this.konfServ.getPeriodeOrFail();
-    console.log(limit);
-
-    const baseQuery = this.mataKuliahRepo
-      .createQueryBuilder("matkul")
-      .select([
-        "matkul.kode AS mata_kuliah_kode",
-        "matkul.nama AS mata_kuliah_nama",
-        "kelas.nomor AS kelas_nomor",
-        "mhsKelas.id AS mahasiswa_kelas_id",
-        "mahasiswa.id AS mahasiswa_id",
-        "mahasiswa.nama AS mahasiswa_nama",
-        "mahasiswa.nim AS mahasiswa_nim",
-        "mhsKelas.nilaiAkhir AS nilai_akhir",
-      ])
-      .innerJoin("matkul.kelas", "kelas")
-      .leftJoin("kelas.mahasiswa", "mhsKelas")
-      .innerJoin("mhsKelas.mahasiswa", "mahasiswa")
-      .where("kelas.periode = :periode", { periode: currPeriode })
-      .andWhere(
-        new Brackets((qb) => {
-          qb.where("mahasiswa.nama ILIKE :search", {
-            search: `%${search}%`,
-          }).orWhere("mahasiswa.nim ILIKE :search", { search: `%${search}%` });
-        }),
-      );
-
-    if (mataKuliahKode) {
-      baseQuery.andWhere("matkul.kode = :kode", { kode: mataKuliahKode });
-    }
-
-    const mhsKelas: GetNilaiByMatkulRespDto[] = await baseQuery
-      .orderBy("matkul.kode")
-      .addOrderBy("kelas.nomor")
-      .addOrderBy("mahasiswa.nim")
-      .skip((page - 1) * limit)
-      .limit(limit)
-      .getRawMany();
-
-    return mhsKelas;
-  }
-
-  async updateNilai(
-    mhsKelasIds: string[],
-    nilaiAkhir?: number,
-  ): Promise<UpdateNilaiRespDto> {
-    await this.isMhsKelasOrFail(mhsKelasIds);
-
-    await this.mhsKelasRepo.update(
-      { id: In(mhsKelasIds) },
-      { nilaiAkhir: nilaiAkhir ?? null },
-    );
-
-    return { mahasiswaKelasIds: mhsKelasIds };
-  }
-}
diff --git a/src/pengguna/pengguna.module.ts b/src/pengguna/pengguna.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3e5276cbb4849fcc7453b7b2618834fcd3a2f3c7
--- /dev/null
+++ b/src/pengguna/pengguna.module.ts
@@ -0,0 +1,11 @@
+import { Module } from "@nestjs/common";
+import { PenggunaService } from "./pengguna.service";
+import { TypeOrmModule } from "@nestjs/typeorm";
+import { Pengguna } from "src/entities/pengguna.entity";
+
+@Module({
+  imports: [TypeOrmModule.forFeature([Pengguna])],
+  providers: [PenggunaService],
+  exports: [PenggunaService],
+})
+export class PenggunaModule {}
diff --git a/src/pengguna/pengguna.service.ts b/src/pengguna/pengguna.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..28281715431f789c616d7213ec8a8cea18b7c80c
--- /dev/null
+++ b/src/pengguna/pengguna.service.ts
@@ -0,0 +1,24 @@
+import { Injectable, NotFoundException } from "@nestjs/common";
+import { InjectRepository } from "@nestjs/typeorm";
+import { Pengguna, RoleEnum } from "src/entities/pengguna.entity";
+import { ArrayContains, Repository } from "typeorm";
+
+@Injectable()
+export class PenggunaService {
+  constructor(
+    @InjectRepository(Pengguna)
+    private penggunaRepo: Repository<Pengguna>,
+  ) {}
+
+  async isMahasiswaAktifOrFail(id: string) {
+    const mhs = await this.penggunaRepo.findOneBy({
+      id,
+      aktif: true,
+      roles: ArrayContains([RoleEnum.S2_MAHASISWA]),
+    });
+
+    if (!mhs) {
+      throw new NotFoundException("Mahasiswa aktif tidak ditemukan");
+    }
+  }
+}
diff --git a/src/registrasi-tesis/registrasi-tesis.controller.ts b/src/registrasi-tesis/registrasi-tesis.controller.ts
index e41920cdafcd7e91a4378bd0224bfdbcb9605ec7..0ac28aece930cb6f6c9ea7ec037540d9ec3d5f1e 100644
--- a/src/registrasi-tesis/registrasi-tesis.controller.ts
+++ b/src/registrasi-tesis/registrasi-tesis.controller.ts
@@ -1,5 +1,4 @@
 import {
-  BadRequestException,
   Body,
   Controller,
   ForbiddenException,
@@ -12,8 +11,11 @@ import {
   UseGuards,
 } from "@nestjs/common";
 import {
+  ApiBadRequestResponse,
   ApiBearerAuth,
   ApiCookieAuth,
+  ApiCreatedResponse,
+  ApiNotFoundResponse,
   ApiOkResponse,
   ApiOperation,
   ApiTags,
@@ -21,7 +23,6 @@ import {
 import { Request } from "express";
 import { AuthDto } from "src/auth/auth.dto";
 import { RoleEnum } from "src/entities/pengguna.entity";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
 import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
 import { Roles } from "src/middlewares/roles.decorator";
 import { RolesGuard } from "src/middlewares/roles.guard";
@@ -48,20 +49,24 @@ import { RegistrasiTesisService } from "./registrasi-tesis.service";
 export class RegistrasiTesisController {
   constructor(
     private readonly registrasiTesisService: RegistrasiTesisService,
-    private readonly konfService: KonfigurasiService,
   ) {}
 
   @ApiOperation({
-    summary:
-      "Create new registration. Roles: S2_MAHASISWA, ADMIN, S2_TIM_TESIS",
+    summary: "Create new registration. Roles: S2_MAHASISWA",
+  })
+  @ApiCreatedResponse({ type: IdDto })
+  @ApiNotFoundResponse({ description: "Penerima atau topik tidak ditemukan" })
+  @ApiBadRequestResponse({
+    description:
+      "Mahasiswa sedang memiliki pendaftaran aktif atau judul dan deskripsi topik baru tidak ada",
   })
   @UseGuards(CustomAuthGuard, RolesGuard)
-  @Roles(RoleEnum.S2_MAHASISWA, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
+  @Roles(RoleEnum.S2_MAHASISWA)
   @Post()
   async createTopicRegistration(
     @Body() topicRegistrationDto: RegDto,
     @Req() req: Request,
-  ) {
+  ): Promise<IdDto> {
     const { id } = req.user as AuthDto;
 
     return this.registrasiTesisService.createTopicRegistration(
@@ -91,17 +96,8 @@ export class RegistrasiTesisController {
       }
     }
 
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) {
-      throw new BadRequestException("Periode belum dikonfigurasi.");
-    }
-
     return this.registrasiTesisService.findByUserId(
       params.mahasiswaId,
-      periode,
       false,
       undefined,
     );
@@ -130,17 +126,8 @@ export class RegistrasiTesisController {
       idPenerima = id;
     }
 
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) {
-      throw new BadRequestException("Periode belum dikonfigurasi.");
-    }
-
     const res = await this.registrasiTesisService.findByUserId(
       params.mahasiswaId,
-      periode,
       true,
       idPenerima,
     );
@@ -163,12 +150,7 @@ export class RegistrasiTesisController {
       throw new ForbiddenException();
     }
 
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
     return this.registrasiTesisService.getRegsStatistics({
-      periode,
       idPenerima: query.view == RoleEnum.S2_PEMBIMBING ? idPenerima : undefined,
     });
   }
@@ -194,20 +176,11 @@ export class RegistrasiTesisController {
       throw new ForbiddenException();
     }
 
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) {
-      throw new BadRequestException("Periode belum dikonfigurasi.");
-    }
-
     return await this.registrasiTesisService.findAllRegs({
       ...query,
       page: query.page || 1,
       idPenerima:
         query.view === RoleEnum.S2_PEMBIMBING ? idPenerima : undefined,
-      periode,
     });
   }
 
@@ -224,14 +197,6 @@ export class RegistrasiTesisController {
     @Body() body: UpdateInterviewBodyDto,
     @Req() req: Request,
   ) {
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) {
-      throw new BadRequestException("Periode belum dikonfigurasi.");
-    }
-
     const { id, roles } = req.user as AuthDto;
     let idPenerima = undefined;
 
@@ -245,7 +210,6 @@ export class RegistrasiTesisController {
 
     return await this.registrasiTesisService.updateInterviewDate(
       params.mhsId,
-      periode,
       body,
       idPenerima,
     );
@@ -264,14 +228,6 @@ export class RegistrasiTesisController {
     @Body() body: UpdateStatusBodyDto,
     @Req() req: Request,
   ) {
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) {
-      throw new BadRequestException("Periode belum dikonfigurasi.");
-    }
-
     const { id, roles } = req.user as AuthDto;
     let idPenerima = undefined;
 
@@ -285,7 +241,6 @@ export class RegistrasiTesisController {
 
     return await this.registrasiTesisService.updateStatus(
       params.mhsId,
-      periode,
       body,
       idPenerima,
     );
@@ -303,17 +258,8 @@ export class RegistrasiTesisController {
     @Param() params: UpdateByMhsParamsDto,
     @Body() body: UpdatePembimbingBodyDto,
   ) {
-    const periode = await this.konfService.getKonfigurasiByKey(
-      process.env.KONF_PERIODE_KEY,
-    );
-
-    if (!periode) {
-      throw new BadRequestException("Periode belum dikonfigurasi.");
-    }
-
     return await this.registrasiTesisService.updatePembimbingList(
       params.mhsId,
-      periode,
       body,
     );
   }
diff --git a/src/registrasi-tesis/registrasi-tesis.dto.ts b/src/registrasi-tesis/registrasi-tesis.dto.ts
index 330f31d2bf8ea6118fa74403d210c1cf87e13921..7d5d1bf284f8957d52f75af71505fad198e74b52 100644
--- a/src/registrasi-tesis/registrasi-tesis.dto.ts
+++ b/src/registrasi-tesis/registrasi-tesis.dto.ts
@@ -16,25 +16,28 @@ import {
 import { Pengguna, RoleEnum } from "src/entities/pengguna.entity";
 
 export class RegDto {
-  @IsUUID()
-  @ApiProperty()
-  idMahasiswa: string;
-
   @IsUUID()
   @ApiProperty()
   idPenerima: string;
 
-  @IsString()
-  @ApiProperty()
-  judulTopik: string;
-
-  @IsString()
-  @ApiProperty()
-  deskripsi: string;
+  @IsUUID()
+  @IsOptional()
+  @ApiPropertyOptional()
+  idTopik?: string;
 
   @IsEnum(JalurEnum)
   @ApiProperty({ enum: JalurEnum })
   jalurPilihan: JalurEnum;
+
+  @IsString()
+  @IsOptional()
+  @ApiPropertyOptional()
+  judulTopik?: string;
+
+  @IsString()
+  @IsOptional()
+  @ApiPropertyOptional()
+  deskripsiTopik?: string;
 }
 
 export class RegByMhsParamDto {
@@ -168,7 +171,11 @@ export class UpdatePembimbingBodyDto {
 class DosenPembimbingDto extends PickType(Pengguna, [
   "id",
   "nama",
-  "kontak",
+  "kontakWhatsApp",
+  "kontakMsTeams",
+  "kontakEmail",
+  "kontakTelp",
+  "kontakLainnya",
 ] as const) {}
 
 export class GetByIdRespDto extends PickType(PendaftaranTesis, [
diff --git a/src/registrasi-tesis/registrasi-tesis.module.ts b/src/registrasi-tesis/registrasi-tesis.module.ts
index 65926b077ae351036dcd06e380b17bec135f42bc..0b64d44cec70b955ad05a008eedd82f63760e1c3 100644
--- a/src/registrasi-tesis/registrasi-tesis.module.ts
+++ b/src/registrasi-tesis/registrasi-tesis.module.ts
@@ -8,7 +8,8 @@ import { RegistrasiTesisService } from "./registrasi-tesis.service";
 import { Topik } from "src/entities/topik.entity";
 import { CustomStrategy } from "src/middlewares/custom.strategy";
 import { AuthModule } from "src/auth/auth.module";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
+import { PenggunaModule } from "src/pengguna/pengguna.module";
+import { PenggunaService } from "src/pengguna/pengguna.service";
 
 @Module({
   imports: [
@@ -19,9 +20,9 @@ import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
       Topik,
     ]),
     AuthModule,
-    KonfigurasiModule,
+    PenggunaModule,
   ],
   controllers: [RegistrasiTesisController],
-  providers: [RegistrasiTesisService, CustomStrategy],
+  providers: [RegistrasiTesisService, CustomStrategy, PenggunaService],
 })
 export class RegistrasiTesisModule {}
diff --git a/src/registrasi-tesis/registrasi-tesis.service.ts b/src/registrasi-tesis/registrasi-tesis.service.ts
index 74afb3e99311335adae3e191090ce7b4902964cb..17e59c6096fcf7f65aff48a21dda444938e8515e 100644
--- a/src/registrasi-tesis/registrasi-tesis.service.ts
+++ b/src/registrasi-tesis/registrasi-tesis.service.ts
@@ -6,6 +6,7 @@ import {
   NotFoundException,
 } from "@nestjs/common";
 import { InjectRepository } from "@nestjs/typeorm";
+import * as dayjs from "dayjs";
 import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
 import {
   PendaftaranTesis,
@@ -14,7 +15,6 @@ import {
 import { Pengguna, RoleEnum } from "src/entities/pengguna.entity";
 import { Topik } from "src/entities/topik.entity";
 import { generateQueryBuilderOrderByObj } from "src/helper/sorting";
-import { validateId } from "src/helper/validation";
 import { ArrayContains, Brackets, DataSource, In, Repository } from "typeorm";
 import {
   FindAllNewestRegRespDto,
@@ -25,7 +25,7 @@ import {
   UpdatePembimbingBodyDto,
   UpdateStatusBodyDto,
 } from "./registrasi-tesis.dto";
-import * as dayjs from "dayjs";
+import { PenggunaService } from "src/pengguna/pengguna.service";
 
 @Injectable()
 export class RegistrasiTesisService {
@@ -39,82 +39,132 @@ export class RegistrasiTesisService {
     @InjectRepository(DosenBimbingan)
     private dosenBimbinganRepository: Repository<DosenBimbingan>,
     private dataSource: DataSource,
+    private penggunaService: PenggunaService,
   ) {}
 
   async createTopicRegistration(
     userId: string,
     topicRegistrationDto: RegDto,
-  ): Promise<PendaftaranTesis> {
-    // TODO: Proper validations
-
-    // Validate id
-    validateId([
-      { id: userId, object: "Pengguna" },
-      { id: topicRegistrationDto.idPenerima, object: "Pembimbing" },
-    ]);
-
-    // Validate user id, supervisor id
-    const [user, supervisor, topic] = await Promise.all([
-      this.penggunaRepository.findOne({
-        where: { id: userId },
+  ): Promise<IdDto> {
+    const queries: (
+      | Promise<void | PendaftaranTesis>
+      | Promise<Pengguna>
+      | Promise<Topik>
+    )[] = [
+      this.getNewestRegByMhsOrFail(userId).catch((ex: BadRequestException) => {
+        if (ex.message === "No mahasiswa user with given id exists") {
+          throw ex;
+        }
+        // else: mahasiswa does not have pending registration -> allowed
       }),
       this.penggunaRepository.findOne({
         where: { id: topicRegistrationDto.idPenerima },
       }),
-      this.topicRepostitory.findOne({
-        where: { judul: topicRegistrationDto.judulTopik },
-      }),
-    ]);
+    ];
+
+    if (topicRegistrationDto.idTopik) {
+      queries.push(
+        this.topicRepostitory.findOne({
+          where: { id: topicRegistrationDto.idTopik },
+        }),
+      );
+    }
+
+    const queryResult = await Promise.all(queries);
+    const lastPendaftaran = queryResult[0] as PendaftaranTesis;
+    const penerima = queryResult[1] as Pengguna;
+    let topik = topicRegistrationDto.idTopik ? (queryResult[2] as Topik) : null;
+
+    if (!penerima) {
+      throw new NotFoundException("Penerima not found.");
+    }
 
-    if (!user) {
-      throw new NotFoundException("User not found.");
-    } else if (!supervisor) {
-      throw new NotFoundException("Supervisor not found.");
-    } else if (!topic) {
-      throw new NotFoundException("Topic not found.");
+    if (topicRegistrationDto.idTopik) {
+      if (!topik) {
+        throw new NotFoundException("Topic not found.");
+      }
+
+      if (!topik.aktif) {
+        throw new BadRequestException("Topic is not active.");
+      }
+    }
+
+    if (lastPendaftaran && lastPendaftaran.status !== RegStatus.REJECTED) {
+      throw new BadRequestException(
+        "Mahasiswa already has pending registration in this period",
+      );
+    }
+
+    if (!topik) {
+      if (
+        !topicRegistrationDto.judulTopik ||
+        !topicRegistrationDto.deskripsiTopik
+      ) {
+        throw new BadRequestException(
+          "Judul dan deskripsi topik tidak boleh kosong.",
+        );
+      }
+
+      topik = this.topicRepostitory.create({
+        judul: topicRegistrationDto.judulTopik,
+        deskripsi: topicRegistrationDto.deskripsiTopik,
+        idPengaju: userId,
+      });
     }
 
     // Create new registration
     const createdRegistration = this.pendaftaranTesisRepository.create({
       ...topicRegistrationDto,
-      mahasiswa: user,
-      penerima: supervisor,
-      topik: topic,
+      mahasiswaId: userId,
+      penerima,
+      topik,
     });
 
     await this.pendaftaranTesisRepository.save(createdRegistration);
 
-    return createdRegistration;
+    return {
+      id: createdRegistration.id,
+    };
   }
 
   async findByUserId(
     mahasiswaId: string,
-    periode: string,
     isNewestOnly: boolean,
     idPenerima?: string,
   ) {
+    await this.penggunaService.isMahasiswaAktifOrFail(mahasiswaId);
+
     const baseQuery = this.pendaftaranTesisRepository
       .createQueryBuilder("pt")
-      .select("pt.id")
-      .addSelect("pt.jadwalInterview")
-      .addSelect("pt.status")
-      .addSelect("pt.jalurPilihan")
-      .addSelect("pt.waktuPengiriman")
-      .addSelect("topik.judul")
-      .addSelect("penerima.id")
-      .addSelect("penerima.nama")
-      .addSelect("dosenBimbingan")
-      .addSelect("dosen.id")
-      .addSelect("dosen.nama")
-      .addSelect("dosen.kontak")
-      .addSelect("topik.judul")
-      .addSelect("topik.deskripsi")
+      .select([
+        "pt.id",
+        "pt.jadwalInterview",
+        "pt.status",
+        "pt.jalurPilihan",
+        "pt.waktuPengiriman",
+        "topik.judul",
+        "topik.deskripsi",
+        "penerima.id",
+        "penerima.nama",
+        "penerima.kontakWhatsApp",
+        "penerima.kontakMsTeams",
+        "penerima.kontakEmail",
+        "penerima.kontakTelp",
+        "penerima.kontakLainnya",
+        "dosenBimbingan",
+        "dosen.id",
+        "dosen.nama",
+        "dosen.kontakWhatsApp",
+        "dosen.kontakMsTeams",
+        "dosen.kontakEmail",
+        "dosen.kontakTelp",
+        "dosen.kontakLainnya",
+      ])
       .leftJoin("pt.topik", "topik")
       .leftJoin("pt.penerima", "penerima")
       .leftJoin("pt.dosenBimbingan", "dosenBimbingan")
       .leftJoin("dosenBimbingan.dosen", "dosen")
       .where("pt.mahasiswaId = :mahasiswaId", { mahasiswaId })
-      .andWhere("topik.periode = :periode", { periode })
       .orderBy("pt.waktuPengiriman", "DESC");
 
     const res = await baseQuery.getMany();
@@ -157,10 +207,9 @@ export class RegistrasiTesisService {
   }
 
   async getRegsStatistics(options: {
-    periode: string;
     idPenerima?: string;
   }): Promise<RegStatisticsRespDto> {
-    const totalMahasiswa = this.penggunaRepository.count({
+    let totalMahasiswa = this.penggunaRepository.count({
       where: { roles: ArrayContains([RoleEnum.S2_MAHASISWA]) },
     });
 
@@ -179,13 +228,15 @@ export class RegistrasiTesisService {
         "latest",
         "latest.latest_mahasiswaId = pt.mahasiswaId AND pt.waktuPengiriman = latest.latestPengiriman",
       )
-      .innerJoinAndSelect("pt.topik", "topik")
-      .where("topik.periode = :periode", { periode: options.periode });
+      .innerJoin("pt.mahasiswa", "mahasiswa")
+      .where("mahasiswa.aktif = true");
 
     if (options.idPenerima) {
       baseQuery.andWhere("pt.penerimaId = :idPenerima", {
         idPenerima: options.idPenerima,
       });
+
+      totalMahasiswa = baseQuery.getCount();
     }
 
     const totalDiterima = baseQuery
@@ -236,7 +287,6 @@ export class RegistrasiTesisService {
     search?: string;
     order_by?: "nim";
     sort?: "ASC" | "DESC";
-    periode: string;
   }) {
     const baseQuery = this.pendaftaranTesisRepository
       .createQueryBuilder("pt")
@@ -258,10 +308,9 @@ export class RegistrasiTesisService {
     );
 
     baseQuery
-      .innerJoinAndSelect("pt.topik", "topik")
       .innerJoinAndSelect("pt.penerima", "penerima")
       .innerJoinAndSelect("pt.mahasiswa", "mahasiswa")
-      .where("topik.periode = :periode", { periode: options.periode });
+      .where("mahasiswa.aktif = true");
 
     if (options.idPenerima) {
       baseQuery.andWhere("pt.penerimaId = :idPenerima", {
@@ -269,7 +318,7 @@ export class RegistrasiTesisService {
       });
     }
 
-    if (options.search)
+    if (options.search) {
       baseQuery.andWhere(
         new Brackets((qb) =>
           qb
@@ -281,11 +330,11 @@ export class RegistrasiTesisService {
             }),
         ),
       );
+    }
 
-    if (options.status)
-      baseQuery.andWhere("pt.status = :status", {
-        status: options.status,
-      });
+    if (options.status) {
+      baseQuery.andWhere("pt.status = :status", { status: options.status });
+    }
 
     if (options.order_by) {
       const orderByMapping = {
@@ -324,7 +373,7 @@ export class RegistrasiTesisService {
     return resData;
   }
 
-  private async getNewestRegByMhs(mahasiswaId: string, periode: string) {
+  private async getNewestRegByMhsOrFail(mahasiswaId: string) {
     const mahasiswa = await this.penggunaRepository.findOne({
       select: {
         id: true,
@@ -348,7 +397,6 @@ export class RegistrasiTesisService {
         topik: {
           judul: true,
           deskripsi: true,
-          periode: true,
         },
         penerima: {
           id: true,
@@ -361,9 +409,6 @@ export class RegistrasiTesisService {
       },
       where: {
         mahasiswa: mahasiswa,
-        topik: {
-          periode,
-        },
       },
       order: {
         waktuPengiriman: "DESC",
@@ -380,10 +425,11 @@ export class RegistrasiTesisService {
 
   async updateInterviewDate(
     mahasiswaId: string,
-    periode: string,
     dto: UpdateInterviewBodyDto,
     idPenerima?: string,
   ) {
+    await this.penggunaService.isMahasiswaAktifOrFail(mahasiswaId);
+
     const minDate = new Date();
     minDate.setDate(minDate.getDate() + 2);
 
@@ -393,7 +439,7 @@ export class RegistrasiTesisService {
       );
     }
 
-    const newestReg = await this.getNewestRegByMhs(mahasiswaId, periode);
+    const newestReg = await this.getNewestRegByMhsOrFail(mahasiswaId);
 
     if (newestReg && idPenerima && newestReg.penerima.id !== idPenerima) {
       throw new ForbiddenException();
@@ -423,11 +469,12 @@ export class RegistrasiTesisService {
 
   async updateStatus(
     mahasiswaId: string,
-    periode: string,
     dto: UpdateStatusBodyDto,
     idPenerima?: string,
   ) {
-    const newestReg = await this.getNewestRegByMhs(mahasiswaId, periode);
+    await this.penggunaService.isMahasiswaAktifOrFail(mahasiswaId);
+
+    const newestReg = await this.getNewestRegByMhsOrFail(mahasiswaId);
 
     if (newestReg && idPenerima && newestReg.penerima.id !== idPenerima) {
       throw new ForbiddenException();
@@ -470,10 +517,11 @@ export class RegistrasiTesisService {
 
   async updatePembimbingList(
     mahasiswaId: string,
-    periode: string,
     { pembimbing_ids: dosen_ids }: UpdatePembimbingBodyDto,
   ) {
-    const newestReg = await this.getNewestRegByMhs(mahasiswaId, periode);
+    await this.penggunaService.isMahasiswaAktifOrFail(mahasiswaId);
+
+    const newestReg = await this.getNewestRegByMhsOrFail(mahasiswaId);
 
     if (newestReg.status !== RegStatus.APPROVED)
       throw new BadRequestException(
diff --git a/src/submisi-tugas/submisi-tugas.controller.ts b/src/submisi-tugas/submisi-tugas.controller.ts
deleted file mode 100644
index cb4f45a1b1cdb0d5535344ac9d8ccee62e4db8b9..0000000000000000000000000000000000000000
--- a/src/submisi-tugas/submisi-tugas.controller.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import {
-  Body,
-  Controller,
-  Get,
-  Param,
-  Post,
-  Query,
-  Req,
-  UseGuards,
-} from "@nestjs/common";
-import { SubmisiTugasService } from "./submisi-tugas.service";
-import {
-  ApiBearerAuth,
-  ApiCookieAuth,
-  ApiOkResponse,
-  ApiOperation,
-  ApiTags,
-} from "@nestjs/swagger";
-import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
-import { RolesGuard } from "src/middlewares/roles.guard";
-import { Roles } from "src/middlewares/roles.decorator";
-import { RoleEnum } from "src/entities/pengguna.entity";
-import {
-  CreateSubmisiTugasDto,
-  GetSubmisiTugasByIdRespDto,
-  GetSubmisiTugasByTugasIdQueryDto,
-  GetSubmisiTugasByTugasIdRespDto,
-  SubmisiTugasIdDto,
-} from "./submisi-tugas.dto";
-import { AuthDto } from "src/auth/auth.dto";
-import { Request } from "express";
-
-@ApiTags("Submisi Tugas")
-@ApiBearerAuth()
-@ApiCookieAuth()
-@UseGuards(CustomAuthGuard, RolesGuard)
-@Controller("submisi-tugas")
-export class SubmisiTugasController {
-  constructor(private submisiTugasServ: SubmisiTugasService) {}
-
-  @Roles(RoleEnum.S2_MAHASISWA)
-  @Post()
-  async createSubmisiTugas(
-    @Body() createDto: CreateSubmisiTugasDto,
-    @Req() req: Request,
-  ) {
-    // TODO: More validation
-    const { id } = req.user as AuthDto;
-
-    return await this.submisiTugasServ.createSubmisiTugas(createDto, id);
-  }
-
-  @ApiOperation({
-    summary:
-      "Get submisi tugas by sumbisi tugas id. Roles: S2_KULIAH, S2_MAHASISWA",
-  })
-  @ApiOkResponse({ type: GetSubmisiTugasByIdRespDto })
-  @Roles(RoleEnum.S2_KULIAH, RoleEnum.S2_MAHASISWA)
-  @Get("/:id")
-  async getSubmisiTugasById(
-    @Req() req: Request,
-    @Param() param: SubmisiTugasIdDto,
-  ) {
-    const { id, roles } = req.user as AuthDto;
-
-    let idMahasiswa = undefined;
-    let idPengajar = undefined;
-
-    if (!roles.includes(RoleEnum.S2_KULIAH)) {
-      idMahasiswa = id;
-    } else {
-      idPengajar = id;
-    }
-
-    return await this.submisiTugasServ.getSubmisiTugasById(
-      param.id,
-      idMahasiswa,
-      idPengajar,
-    );
-  }
-
-  @ApiOperation({
-    summary: "Get list of submisi tugas summary by tugas id. Roles: S2_KULIAH",
-  })
-  @ApiOkResponse({ type: [GetSubmisiTugasByTugasIdRespDto] })
-  @Roles(RoleEnum.S2_KULIAH)
-  @Get()
-  async getSubmisiTugasByTugasId(
-    @Req() req: Request,
-    @Query() query: GetSubmisiTugasByTugasIdQueryDto,
-  ) {
-    const { id } = req.user as AuthDto;
-
-    return await this.submisiTugasServ.getSubmisiTugasByTugasId(
-      query.tugasId,
-      id,
-      query.search || "",
-      query.page || 1,
-      query.limit || 10,
-      query.order || "ASC",
-      query.isSubmitted,
-    );
-  }
-}
diff --git a/src/submisi-tugas/submisi-tugas.dto.ts b/src/submisi-tugas/submisi-tugas.dto.ts
deleted file mode 100644
index daa8486087d0e417d1ef0c72f9b74e8b8cf15900..0000000000000000000000000000000000000000
--- a/src/submisi-tugas/submisi-tugas.dto.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-import { IsString } from "@nestjs/class-validator";
-import {
-  ApiProperty,
-  ApiPropertyOptional,
-  OmitType,
-  PickType,
-} from "@nestjs/swagger";
-import { Transform, Type } from "class-transformer";
-import {
-  IsBoolean,
-  IsEnum,
-  IsNumberString,
-  IsOptional,
-  ValidateNested,
-} from "class-validator";
-import { BerkasSubmisiTugas } from "src/entities/berkasSubmisiTugas.entity";
-import { PendaftaranTesis } from "src/entities/pendaftaranTesis.entity";
-import { Pengguna } from "src/entities/pengguna.entity";
-import { SubmisiTugas } from "src/entities/submisiTugas.entity";
-import { GetTugasByIdRespDto } from "src/tugas/tugas.dto";
-
-class BerkasSubmisiTugasWithoutId extends OmitType(BerkasSubmisiTugas, [
-  "id",
-] as const) {}
-
-export class CreateSubmisiTugasDto extends PickType(SubmisiTugas, [
-  "jawaban",
-  "isSubmitted",
-  "tugasId",
-]) {
-  @ApiProperty({ type: [BerkasSubmisiTugasWithoutId] })
-  @ValidateNested({ each: true })
-  @Type(() => BerkasSubmisiTugasWithoutId)
-  berkasSubmisiTugas: BerkasSubmisiTugasWithoutId[];
-}
-
-export class SubmisiTugasIdDto extends PickType(SubmisiTugas, [
-  "id",
-] as const) {}
-
-export class GetSubmisiTugasByTugasIdQueryDto extends PickType(SubmisiTugas, [
-  "tugasId",
-] as const) {
-  @ApiPropertyOptional()
-  @IsOptional()
-  @IsString()
-  search?: string;
-
-  @IsOptional()
-  @IsNumberString()
-  @ApiPropertyOptional({ description: "default: 1" })
-  page?: number;
-
-  @IsOptional()
-  @IsNumberString()
-  @ApiPropertyOptional({ description: "default: 10" })
-  limit?: number;
-
-  @IsOptional()
-  @IsBoolean()
-  @Transform(({ value }) => value === "true")
-  @ApiPropertyOptional({
-    description: "if not specified, will return all submisi tugas",
-  })
-  isSubmitted?: boolean;
-
-  @ApiPropertyOptional({
-    enum: ["ASC", "DESC"],
-    description: "order by nim. default: ASC",
-  })
-  @IsOptional()
-  @IsEnum(["ASC", "DESC"])
-  order?: "ASC" | "DESC";
-}
-
-class PickedSubmisiTugas extends PickType(SubmisiTugas, [
-  "id",
-  "isSubmitted",
-  "berkasSubmisiTugas",
-] as const) {}
-
-class PickedSubmisiTugasExtended extends PickType(SubmisiTugas, [
-  "id",
-  "isSubmitted",
-  "jawaban",
-  "submittedAt",
-  "berkasSubmisiTugas",
-] as const) {}
-
-class PickedPendaftaranTesis extends PickType(PendaftaranTesis, [
-  "id",
-  "jalurPilihan",
-  "waktuPengiriman",
-  "jadwalInterview",
-  "status",
-  "topik",
-] as const) {}
-
-class PickedPendaftaran extends PickType(Pengguna, [
-  "id",
-  "nama",
-  "email",
-] as const) {
-  @ApiProperty({ type: PickedPendaftaranTesis })
-  pendaftaranTesis: PickedPendaftaranTesis;
-}
-
-export class GetSubmisiTugasByTugasIdRespDto extends PickType(Pengguna, [
-  "id",
-  "nim",
-  "nama",
-] as const) {
-  @ApiPropertyOptional({ type: PickedSubmisiTugas })
-  submisiTugas?: PickedSubmisiTugas;
-}
-
-export class GetSubmisiTugasByIdRespDto {
-  @ApiProperty({ type: GetTugasByIdRespDto })
-  tugas: GetTugasByIdRespDto;
-
-  @ApiPropertyOptional({ type: PickedPendaftaran })
-  pendaftaran?: PickedPendaftaran;
-
-  @ApiProperty({ type: PickedSubmisiTugasExtended })
-  submisiTugas: PickedSubmisiTugasExtended;
-}
diff --git a/src/submisi-tugas/submisi-tugas.module.ts b/src/submisi-tugas/submisi-tugas.module.ts
deleted file mode 100644
index 1fd15428a499fe276ed0aeaef1b8168bd532b105..0000000000000000000000000000000000000000
--- a/src/submisi-tugas/submisi-tugas.module.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Module } from "@nestjs/common";
-import { SubmisiTugasController } from "./submisi-tugas.controller";
-import { SubmisiTugasService } from "./submisi-tugas.service";
-import { CustomStrategy } from "src/middlewares/custom.strategy";
-import { TypeOrmModule } from "@nestjs/typeorm";
-import { AuthModule } from "src/auth/auth.module";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
-import { SubmisiTugas } from "src/entities/submisiTugas.entity";
-import { BerkasSubmisiTugas } from "src/entities/berkasSubmisiTugas.entity";
-import { TugasModule } from "src/tugas/tugas.module";
-import { Pengguna } from "src/entities/pengguna.entity";
-import { Tugas } from "src/entities/tugas.entity";
-import { MahasiswaKelas } from "src/entities/mahasiswaKelas.entity";
-
-@Module({
-  imports: [
-    TypeOrmModule.forFeature([
-      SubmisiTugas,
-      BerkasSubmisiTugas,
-      Pengguna,
-      Tugas,
-      MahasiswaKelas,
-    ]),
-    AuthModule,
-    KonfigurasiModule,
-    TugasModule,
-  ],
-  controllers: [SubmisiTugasController],
-  providers: [SubmisiTugasService, CustomStrategy],
-})
-export class SubmisiTugasModule {}
diff --git a/src/submisi-tugas/submisi-tugas.service.ts b/src/submisi-tugas/submisi-tugas.service.ts
deleted file mode 100644
index d3c1c11a98b638aecbf96c5b67c1b8326073ef93..0000000000000000000000000000000000000000
--- a/src/submisi-tugas/submisi-tugas.service.ts
+++ /dev/null
@@ -1,257 +0,0 @@
-import {
-  ForbiddenException,
-  Injectable,
-  NotFoundException,
-} from "@nestjs/common";
-import { InjectRepository } from "@nestjs/typeorm";
-import { BerkasSubmisiTugas } from "src/entities/berkasSubmisiTugas.entity";
-import { SubmisiTugas } from "src/entities/submisiTugas.entity";
-import { TugasService } from "src/tugas/tugas.service";
-import { Brackets, Repository } from "typeorm";
-import {
-  CreateSubmisiTugasDto,
-  GetSubmisiTugasByIdRespDto,
-  GetSubmisiTugasByTugasIdRespDto,
-} from "./submisi-tugas.dto";
-import { Pengguna } from "src/entities/pengguna.entity";
-import { Tugas } from "src/entities/tugas.entity";
-import { RegStatus } from "src/entities/pendaftaranTesis.entity";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import { MahasiswaKelas } from "src/entities/mahasiswaKelas.entity";
-
-@Injectable()
-export class SubmisiTugasService {
-  constructor(
-    @InjectRepository(SubmisiTugas)
-    private submisiTugasRepo: Repository<SubmisiTugas>,
-    @InjectRepository(BerkasSubmisiTugas)
-    private berkasSubmisiTugasRepo: Repository<BerkasSubmisiTugas>,
-    @InjectRepository(Pengguna)
-    private penggunaRepo: Repository<Pengguna>,
-    @InjectRepository(Tugas)
-    private tugasRepo: Repository<Tugas>,
-    @InjectRepository(MahasiswaKelas)
-    private mahasiswaKelasRepo: Repository<MahasiswaKelas>,
-    private tugasService: TugasService,
-    private konfService: KonfigurasiService,
-  ) {}
-  private async isMahasiswaSubmisiTugasOrFail(
-    submisiTugasId: string,
-    mahasiswaId: string,
-  ) {
-    const submisiTugas = await this.submisiTugasRepo.findOne({
-      where: { id: submisiTugasId },
-    });
-
-    if (!submisiTugas) {
-      throw new NotFoundException("Submisi tugas tidak ditemukan");
-    }
-
-    if (submisiTugas.mahasiswaId !== mahasiswaId) {
-      throw new ForbiddenException("Anda tidak memiliki akses");
-    }
-
-    // validate periode
-    await this.tugasService.isMahasiswaTugasOrFail(
-      mahasiswaId,
-      submisiTugas.tugasId,
-    );
-  }
-
-  private async isPengajarSubmisiTugasOrFail(
-    submisiTugasId: string,
-    pengajarId: string,
-  ) {
-    const submisiTugas = await this.submisiTugasRepo.findOne({
-      where: { id: submisiTugasId },
-      relations: ["tugas"],
-    });
-
-    if (!submisiTugas) {
-      throw new NotFoundException("Submisi tugas tidak ditemukan");
-    }
-
-    await this.tugasService.isPengajarTugasOrFail(
-      pengajarId,
-      submisiTugas.tugas.id,
-    );
-  }
-
-  async createSubmisiTugas(
-    createDto: CreateSubmisiTugasDto,
-    mahasiswaId: string,
-  ) {
-    await this.tugasService.isMahasiswaTugasOrFail(
-      mahasiswaId,
-      createDto.tugasId,
-    );
-
-    const tugas = await this.tugasRepo.findOneBy({ id: createDto.tugasId });
-    const mahasiswa = await this.penggunaRepo.findOneBy({ id: mahasiswaId });
-
-    const berkasSubmisiTugas = createDto.berkasSubmisiTugas.map(
-      (berkasSubmisiTugas) =>
-        this.berkasSubmisiTugasRepo.create(berkasSubmisiTugas),
-    );
-
-    const submisiTugas = this.submisiTugasRepo.create({
-      ...createDto,
-      mahasiswa,
-      submittedAt: createDto.isSubmitted ? new Date() : null,
-      tugas,
-      berkasSubmisiTugas,
-    });
-
-    await this.submisiTugasRepo.save(submisiTugas);
-
-    return submisiTugas;
-  }
-
-  private async getSubmisiTugas(id: string) {
-    const submisiTugas = await this.submisiTugasRepo.findOne({
-      where: { id },
-      relations: ["berkasSubmisiTugas"],
-    });
-
-    if (!submisiTugas) {
-      throw new NotFoundException("Submisi tugas tidak ditemukan");
-    }
-
-    return submisiTugas;
-  }
-
-  async getSubmisiTugasById(
-    id: string,
-    mahasiswaId?: string,
-    pengajarId?: string,
-  ) {
-    if (mahasiswaId) {
-      await this.isMahasiswaSubmisiTugasOrFail(id, mahasiswaId);
-    }
-
-    if (pengajarId) {
-      await this.isPengajarSubmisiTugasOrFail(id, pengajarId);
-    }
-
-    const currPeriod = await this.konfService.getPeriodeOrFail();
-    const submisiTugas = await this.getSubmisiTugas(id);
-
-    const pendaftaranQuery = this.penggunaRepo
-      .createQueryBuilder("pengguna")
-      .select([
-        "pengguna.id",
-        "pengguna.nama",
-        "pengguna.email",
-        "pendaftaranTesis.jalurPilihan",
-        "pendaftaranTesis.waktuPengiriman",
-        "topik.id",
-        "topik.judul",
-        "topik.deskripsi",
-      ])
-      .leftJoinAndSelect("pengguna.pendaftaranTesis", "pendaftaranTesis")
-      .leftJoinAndSelect("pendaftaranTesis.topik", "topik")
-      .where("pengguna.id = :id", { id: submisiTugas.mahasiswaId })
-      .andWhere("pendaftaranTesis.status = :status", {
-        status: RegStatus.APPROVED,
-      })
-      .andWhere("topik.periode = :periode", { periode: currPeriod })
-      .getOne();
-
-    const [tugas, pendaftaran] = await Promise.all([
-      this.tugasService.getTugasById(submisiTugas.tugasId),
-      pendaftaranQuery,
-    ]);
-
-    const result: GetSubmisiTugasByIdRespDto = {
-      tugas,
-      submisiTugas,
-      pendaftaran: {
-        ...pendaftaran,
-        pendaftaranTesis:
-          pendaftaran.pendaftaranTesis.length > 0
-            ? pendaftaran.pendaftaranTesis[0]
-            : undefined,
-      },
-    };
-
-    return result;
-  }
-
-  async getSubmisiTugasByTugasId(
-    tugasId: string,
-    idPenerima: string,
-    search: string,
-    page: number,
-    limit: number,
-    order: "ASC" | "DESC",
-    isSubmitted?: boolean,
-  ) {
-    await this.tugasService.isPengajarTugasOrFail(idPenerima, tugasId);
-
-    const baseQuery = await this.mahasiswaKelasRepo
-      .createQueryBuilder("mk")
-      .innerJoin("mk.kelas", "kelas", "kelas.id = mk.kelasId")
-      .innerJoinAndSelect("mk.mahasiswa", "mahasiswa")
-      .leftJoinAndSelect(
-        "mahasiswa.submisiTugas",
-        "submisiTugas",
-        "submisiTugas.tugasId = :tugasId",
-        { tugasId },
-      )
-      .leftJoinAndSelect(
-        "submisiTugas.berkasSubmisiTugas",
-        "berkasSubmisiTugas",
-      )
-      .select([
-        "mk.id",
-        "mahasiswa.id",
-        "mahasiswa.nim",
-        "mahasiswa.nama",
-        "submisiTugas.id",
-        "submisiTugas.isSubmitted",
-        "berkasSubmisiTugas",
-      ])
-      .distinctOn(["mahasiswa.nim"])
-      .where(
-        new Brackets((qb) => {
-          qb.where("mahasiswa.nama ILIKE :search", {
-            search: `%${search}%`,
-          }).orWhere("mahasiswa.nim ILIKE :search", { search: `%${search}%` });
-        }),
-      )
-      .orderBy("mahasiswa.nim", order);
-
-    if (isSubmitted !== undefined) {
-      if (isSubmitted) {
-        baseQuery.andWhere("submisiTugas.isSubmitted = true");
-      } else {
-        baseQuery.andWhere(
-          new Brackets((qb) =>
-            qb
-              .where("submisiTugas.isSubmitted <> true")
-              .orWhere("submisiTugas.isSubmitted IS NULL"),
-          ),
-        );
-      }
-    }
-
-    const submisiTugas = await baseQuery
-      .limit(limit)
-      .skip((page - 1) * limit)
-      .getMany();
-
-    const mappedResult: GetSubmisiTugasByTugasIdRespDto[] = submisiTugas.map(
-      (submisi) => ({
-        id: submisi.mahasiswa.id,
-        nim: submisi.mahasiswa.nim,
-        nama: submisi.mahasiswa.nama,
-        submisiTugas:
-          submisi.mahasiswa.submisiTugas.length > 0
-            ? submisi.mahasiswa.submisiTugas[0]
-            : undefined,
-      }),
-    );
-
-    return mappedResult;
-  }
-}
diff --git a/src/tugas/tugas.controller.ts b/src/tugas/tugas.controller.ts
deleted file mode 100644
index b66f4efe167c7a14fea84ac9c710f4f559155186..0000000000000000000000000000000000000000
--- a/src/tugas/tugas.controller.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import {
-  Body,
-  Controller,
-  Get,
-  Param,
-  Post,
-  Put,
-  Query,
-  Req,
-  UseGuards,
-} from "@nestjs/common";
-import { TugasService } from "./tugas.service";
-import { Roles } from "src/middlewares/roles.decorator";
-import { RoleEnum } from "src/entities/pengguna.entity";
-import {
-  ApiBearerAuth,
-  ApiCookieAuth,
-  ApiCreatedResponse,
-  ApiOkResponse,
-  ApiOperation,
-  ApiTags,
-} from "@nestjs/swagger";
-import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
-import { RolesGuard } from "src/middlewares/roles.guard";
-import {
-  TugasIdDto,
-  CreateTugasDto,
-  UpdateTugasDto,
-  GetTugasByIdRespDto,
-  GetTugasByKelasIdQueryDto,
-  GetTugasByKelasIdRespDto,
-} from "./tugas.dto";
-import { Request } from "express";
-import { AuthDto } from "src/auth/auth.dto";
-
-@ApiCookieAuth()
-@ApiBearerAuth()
-@ApiTags("Tugas")
-@UseGuards(CustomAuthGuard, RolesGuard)
-@Controller("tugas")
-export class TugasController {
-  constructor(private readonly tugasService: TugasService) {}
-
-  @ApiOperation({ summary: "Create Tugas. Roles: S2_KULIAH" })
-  @ApiCreatedResponse({ type: TugasIdDto })
-  @Roles(RoleEnum.S2_KULIAH)
-  @Post()
-  async createTugas(@Body() createDto: CreateTugasDto, @Req() req: Request) {
-    const { id } = req.user as AuthDto;
-
-    return await this.tugasService.createTugas(createDto, id);
-  }
-
-  @ApiOperation({ summary: "Update Tugas. Roles: S2_KULIAH" })
-  @ApiOkResponse({ type: TugasIdDto })
-  @Roles(RoleEnum.S2_KULIAH)
-  @Put()
-  async updateTugas(@Body() updateDto: UpdateTugasDto, @Req() req: Request) {
-    const { id } = req.user as AuthDto;
-
-    return await this.tugasService.updateTugasById(updateDto, id);
-  }
-
-  @ApiOperation({
-    summary: "Get Tugas by id. Roles: S2_KULIAH, S2_MAHASISWA",
-  })
-  @ApiOkResponse({ type: GetTugasByIdRespDto })
-  @Roles(RoleEnum.S2_KULIAH, RoleEnum.S2_MAHASISWA)
-  @Get("/:id")
-  async getTugasById(@Param() param: TugasIdDto, @Req() req: Request) {
-    let idPengajar = undefined;
-    let idMahasiswa = undefined;
-
-    const { id, roles } = req.user as AuthDto;
-
-    if (!roles.includes(RoleEnum.S2_KULIAH)) {
-      idMahasiswa = id;
-    } else {
-      idPengajar = id;
-    }
-
-    return this.tugasService.getTugasById(param.id, idMahasiswa, idPengajar);
-  }
-
-  @ApiOperation({
-    summary: "Get Tugas list by kelas id. Roles: S2_KULIAH",
-  })
-  @ApiOkResponse({ type: GetTugasByKelasIdRespDto })
-  @Roles(RoleEnum.S2_KULIAH)
-  @Get()
-  async getTugasByKelasId(
-    @Req() req: Request,
-    @Query() query: GetTugasByKelasIdQueryDto,
-  ) {
-    const { id } = req.user as AuthDto;
-
-    return this.tugasService.getTugasByKelasId(
-      query.kelasId,
-      id,
-      query.search || "",
-      query.page || 1,
-      query.limit || 10,
-    );
-  }
-}
diff --git a/src/tugas/tugas.dto.ts b/src/tugas/tugas.dto.ts
deleted file mode 100644
index afbb6eff67825b726e20169db6dee9e73d79f0ce..0000000000000000000000000000000000000000
--- a/src/tugas/tugas.dto.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import {
-  ApiProperty,
-  ApiPropertyOptional,
-  OmitType,
-  PickType,
-} from "@nestjs/swagger";
-import { Type } from "class-transformer";
-import {
-  IsNumberString,
-  IsOptional,
-  IsString,
-  IsUUID,
-  ValidateNested,
-} from "class-validator";
-import { BerkasTugas } from "src/entities/berkasTugas.entity";
-import { Kelas } from "src/entities/kelas.entity";
-import { Pengguna } from "src/entities/pengguna.entity";
-import { Tugas } from "src/entities/tugas.entity";
-import { GetKelasRespDto } from "src/kelas/kelas.dto";
-
-class BerkasTugasWithoutId extends OmitType(BerkasTugas, ["id"] as const) {}
-
-export class CreateTugasDto extends PickType(Tugas, [
-  "judul",
-  "waktuMulai",
-  "waktuSelesai",
-  "deskripsi",
-  "kelasId",
-]) {
-  @ApiProperty({ type: [BerkasTugasWithoutId] })
-  @ValidateNested({ each: true })
-  @Type(() => BerkasTugasWithoutId)
-  berkasTugas: BerkasTugasWithoutId[];
-}
-
-export class UpdateTugasDto extends OmitType(CreateTugasDto, [
-  "kelasId",
-] as const) {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  id: string;
-}
-
-export class TugasIdDto extends PickType(Tugas, ["id"] as const) {}
-
-class PickedPengajarKelas extends PickType(Pengguna, ["id", "nama"] as const) {}
-
-class PickedTugasKelas extends PickType(Kelas, [
-  "id",
-  "nomor",
-  "mataKuliah",
-] as const) {}
-
-export class GetTugasByIdRespDto extends PickType(Tugas, [
-  "id",
-  "judul",
-  "waktuMulai",
-  "waktuSelesai",
-  "deskripsi",
-  "createdAt",
-  "updatedAt",
-  "berkasTugas",
-] as const) {
-  @ApiProperty({ type: PickedPengajarKelas })
-  pembuat: PickedPengajarKelas;
-
-  @ApiProperty({ type: PickedPengajarKelas })
-  pengubah: PickedPengajarKelas;
-
-  @ApiProperty({ type: PickedTugasKelas })
-  kelas: PickedTugasKelas;
-}
-
-export class GetTugasByKelasIdQueryDto extends PickType(Tugas, [
-  "kelasId",
-] as const) {
-  @ApiPropertyOptional()
-  @IsOptional()
-  @IsString()
-  search?: string;
-
-  @IsOptional()
-  @IsNumberString()
-  @ApiPropertyOptional({ description: "default: 1" })
-  page?: number;
-
-  @IsOptional()
-  @IsNumberString()
-  @ApiPropertyOptional({ description: "default: 10" })
-  limit?: number;
-}
-
-export class GetTugasSummaryRespDto extends PickType(Tugas, [
-  "id",
-  "judul",
-  "waktuMulai",
-  "waktuSelesai",
-] as const) {
-  @ApiProperty()
-  totalSubmisi: number;
-}
-
-export class GetTugasByKelasIdRespDto {
-  @ApiProperty({ type: [GetTugasSummaryRespDto] })
-  tugas: GetTugasSummaryRespDto[];
-
-  @ApiProperty({ type: GetKelasRespDto })
-  kelas: GetKelasRespDto;
-}
diff --git a/src/tugas/tugas.module.ts b/src/tugas/tugas.module.ts
deleted file mode 100644
index 3a8d49258c546ffaa9d9d95014f4d10af9190442..0000000000000000000000000000000000000000
--- a/src/tugas/tugas.module.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { Module } from "@nestjs/common";
-import { TugasController } from "./tugas.controller";
-import { TugasService } from "./tugas.service";
-import { TypeOrmModule } from "@nestjs/typeorm";
-import { PengajarKelas } from "src/entities/pengajarKelas.entity";
-import { MahasiswaKelas } from "src/entities/mahasiswaKelas.entity";
-import { Tugas } from "src/entities/tugas.entity";
-import { SubmisiTugas } from "src/entities/submisiTugas.entity";
-import { AuthModule } from "src/auth/auth.module";
-import { KonfigurasiModule } from "src/konfigurasi/konfigurasi.module";
-import { CustomStrategy } from "src/middlewares/custom.strategy";
-import { BerkasTugas } from "src/entities/berkasTugas.entity";
-import { BerkasSubmisiTugas } from "src/entities/berkasSubmisiTugas.entity";
-import { Kelas } from "src/entities/kelas.entity";
-import { Pengguna } from "src/entities/pengguna.entity";
-import { KelasModule } from "src/kelas/kelas.module";
-import { KelasService } from "src/kelas/kelas.service";
-import { MataKuliah } from "src/entities/mataKuliah.entity";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import { Konfigurasi } from "src/entities/konfigurasi.entity";
-
-@Module({
-  imports: [
-    TypeOrmModule.forFeature([
-      PengajarKelas,
-      MahasiswaKelas,
-      Tugas,
-      SubmisiTugas,
-      BerkasTugas,
-      BerkasSubmisiTugas,
-      Kelas,
-      Pengguna,
-      MataKuliah,
-      Konfigurasi,
-    ]),
-    AuthModule,
-    KonfigurasiModule,
-    KelasModule,
-  ],
-  controllers: [TugasController],
-  providers: [TugasService, CustomStrategy, KelasService, KonfigurasiService],
-  exports: [TugasService],
-})
-export class TugasModule {}
diff --git a/src/tugas/tugas.service.ts b/src/tugas/tugas.service.ts
deleted file mode 100644
index 0f99625c045bdc011de895afd60bd01371658ecb..0000000000000000000000000000000000000000
--- a/src/tugas/tugas.service.ts
+++ /dev/null
@@ -1,277 +0,0 @@
-import {
-  BadRequestException,
-  ForbiddenException,
-  Injectable,
-  NotFoundException,
-} from "@nestjs/common";
-import { InjectRepository } from "@nestjs/typeorm";
-import { Tugas } from "src/entities/tugas.entity";
-import { Repository } from "typeorm";
-import {
-  CreateTugasDto,
-  GetTugasByIdRespDto,
-  GetTugasByKelasIdRespDto,
-  GetTugasSummaryRespDto,
-  TugasIdDto,
-  UpdateTugasDto,
-} from "./tugas.dto";
-import { BerkasTugas } from "src/entities/berkasTugas.entity";
-import { SubmisiTugas } from "src/entities/submisiTugas.entity";
-import { PengajarKelas } from "src/entities/pengajarKelas.entity";
-import { MahasiswaKelas } from "src/entities/mahasiswaKelas.entity";
-import { Kelas } from "src/entities/kelas.entity";
-import { Pengguna } from "src/entities/pengguna.entity";
-import { KelasService } from "src/kelas/kelas.service";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import * as dayjs from "dayjs";
-
-@Injectable()
-export class TugasService {
-  constructor(
-    @InjectRepository(Tugas) private tugasRepo: Repository<Tugas>,
-    @InjectRepository(BerkasTugas)
-    private berkasTugasRepo: Repository<BerkasTugas>,
-    @InjectRepository(SubmisiTugas)
-    private submisiTugasRepo: Repository<SubmisiTugas>,
-    @InjectRepository(PengajarKelas)
-    private doskelRepo: Repository<PengajarKelas>,
-    @InjectRepository(MahasiswaKelas)
-    private mahasiswaKelasRepo: Repository<MahasiswaKelas>,
-    @InjectRepository(Kelas)
-    private kelasRepo: Repository<Kelas>,
-    @InjectRepository(Pengguna)
-    private penggunaRepo: Repository<Pengguna>,
-    private kelasService: KelasService,
-    private konfService: KonfigurasiService,
-  ) {}
-
-  private async isPengajarKelasOrFail(pengajarId: string, kelasId: string) {
-    const periode = await this.konfService.getPeriodeOrFail();
-
-    const doskel = await this.doskelRepo.findOne({
-      where: {
-        pengajarId,
-        kelasId,
-        kelas: {
-          periode,
-        },
-      },
-      relations: ["kelas"],
-    });
-
-    if (!doskel) {
-      throw new ForbiddenException("Anda tidak memiliki akses");
-    }
-  }
-
-  private async isMahasiswaKelasOrFail(mahasiswaId: string, kelasId: string) {
-    const periode = await this.konfService.getPeriodeOrFail();
-
-    const mahasiswaKelas = await this.mahasiswaKelasRepo.findOne({
-      where: {
-        mahasiswaId,
-        kelasId,
-        kelas: {
-          periode,
-        },
-      },
-      relations: ["kelas"],
-    });
-
-    if (!mahasiswaKelas) {
-      throw new ForbiddenException("Anda tidak memiliki akses");
-    }
-  }
-
-  async isPengajarTugasOrFail(pengajarId: string, tugasId: string) {
-    const tugas = await this.tugasRepo.findOne({
-      where: { id: tugasId },
-    });
-
-    if (!tugas) {
-      throw new NotFoundException("Tugas tidak ditemukan");
-    }
-
-    await this.isPengajarKelasOrFail(pengajarId, tugas.kelasId);
-  }
-
-  async isMahasiswaTugasOrFail(mahasiswaId: string, tugasId: string) {
-    const tugas = await this.tugasRepo.findOne({
-      where: { id: tugasId },
-    });
-
-    if (!tugas) {
-      throw new NotFoundException("Tugas tidak ditemukan");
-    }
-
-    return await this.isMahasiswaKelasOrFail(mahasiswaId, tugas.kelasId);
-  }
-
-  private async getTugas(tugasId: string): Promise<GetTugasByIdRespDto> {
-    const result: GetTugasByIdRespDto[] = await this.tugasRepo
-      .createQueryBuilder("tugas")
-      .leftJoinAndSelect("tugas.pembuat", "pembuat")
-      .leftJoinAndSelect("tugas.pengubah", "pengubah")
-      .leftJoinAndSelect("tugas.kelas", "kelas")
-      .leftJoinAndSelect("kelas.mataKuliah", "mataKuliah")
-      .leftJoinAndSelect("tugas.berkasTugas", "berkasTugas")
-      .select([
-        "tugas.id",
-        "pembuat.id",
-        "pembuat.nama",
-        "pengubah.id",
-        "pengubah.nama",
-        "tugas.judul",
-        "tugas.waktuMulai",
-        "tugas.waktuSelesai",
-        "tugas.deskripsi",
-        "tugas.createdAt",
-        "tugas.updatedAt",
-        "berkasTugas",
-        "kelas.id",
-        "kelas.nomor",
-        "mataKuliah.kode",
-        "mataKuliah.nama",
-      ])
-      .where("tugas.id = :tugasId", { tugasId })
-      .getMany();
-
-    return result[0];
-  }
-
-  async createTugas(
-    createDto: CreateTugasDto,
-    pembuatId: string,
-  ): Promise<TugasIdDto> {
-    await this.isPengajarKelasOrFail(pembuatId, createDto.kelasId);
-
-    if (dayjs(createDto.waktuMulai).isAfter(dayjs(createDto.waktuSelesai))) {
-      throw new BadRequestException(
-        "Waktu mulai tidak boleh setelah waktu selesai",
-      );
-    }
-
-    const kelas = await this.kelasRepo.findOne({
-      where: { id: createDto.kelasId },
-    });
-
-    const pembuat = await this.penggunaRepo.findOne({
-      where: { id: pembuatId },
-    });
-
-    const berkasTugas = createDto.berkasTugas.map((berkas) =>
-      this.berkasTugasRepo.create(berkas),
-    );
-
-    const tugas = this.tugasRepo.create({
-      ...createDto,
-      kelas,
-      pembuat,
-      pengubah: pembuat,
-      berkasTugas,
-    });
-
-    const result = await this.tugasRepo.save(tugas);
-
-    return { id: result.id };
-  }
-
-  async updateTugasById(
-    updateDto: UpdateTugasDto,
-    pengubahId: string,
-  ): Promise<TugasIdDto> {
-    await this.isPengajarTugasOrFail(pengubahId, updateDto.id);
-
-    if (dayjs(updateDto.waktuMulai).isAfter(dayjs(updateDto.waktuSelesai))) {
-      throw new BadRequestException(
-        "Waktu mulai tidak boleh setelah waktu selesai",
-      );
-    }
-
-    const berkasTugas = updateDto.berkasTugas.map((berkas) =>
-      this.berkasTugasRepo.create(berkas),
-    );
-
-    const pengubah = await this.penggunaRepo.findOne({
-      where: { id: pengubahId },
-    });
-
-    const prevTugas = await this.tugasRepo.findOne({
-      where: { id: updateDto.id },
-      relations: ["kelas", "pembuat"],
-    });
-
-    const data = {
-      ...updateDto,
-      updatedAt: new Date(),
-      pengubah,
-      kelas: prevTugas.kelas,
-      pembuat: prevTugas.pembuat,
-      berkasTugas,
-    };
-
-    await this.tugasRepo.save(data);
-
-    return { id: updateDto.id };
-  }
-
-  async getTugasById(id: string, idMahasiswa?: string, idPengajar?: string) {
-    if (idMahasiswa) {
-      await this.isMahasiswaTugasOrFail(idMahasiswa, id);
-    }
-
-    if (idPengajar) {
-      await this.isPengajarTugasOrFail(idPengajar, id);
-    }
-
-    const result = await this.getTugas(id);
-
-    return result;
-  }
-
-  async getTugasByKelasId(
-    kelasId: string,
-    idPengajar: string,
-    search: string,
-    page: number,
-    limit: number,
-  ): Promise<GetTugasByKelasIdRespDto> {
-    await this.isPengajarKelasOrFail(idPengajar, kelasId);
-
-    const kelasQuery = this.kelasService.getById(kelasId);
-    const tugasQuery = await this.tugasRepo
-      .createQueryBuilder("tugas")
-      .leftJoinAndSelect(
-        "tugas.submisiTugas",
-        "submisi_tugas",
-        "submisi_tugas.isSubmitted = true",
-      )
-      .select([
-        "tugas.id AS id",
-        "tugas.judul AS judul",
-        "tugas.waktuMulai AS waktu_mulai",
-        "tugas.waktuSelesai AS waktu_selesai",
-        "COUNT(submisi_tugas) AS total_submisi",
-      ])
-      .where("tugas.kelasId = :kelasId", {
-        kelasId,
-      })
-      .andWhere("tugas.judul ILIKE :search", { search: `%${search}%` })
-      .groupBy("tugas.id")
-      .orderBy("tugas.createdAt", "DESC")
-      .limit(limit)
-      .skip((page - 1) * limit)
-      .getRawMany();
-
-    const [kelas, tugas] = await Promise.all([kelasQuery, tugasQuery]);
-    const mappedTugas: GetTugasSummaryRespDto[] = tugas.map((tugas) => ({
-      id: tugas.id,
-      judul: tugas.judul,
-      waktuMulai: tugas.waktu_mulai,
-      waktuSelesai: tugas.waktu_selesai,
-      totalSubmisi: parseInt(tugas.total_submisi),
-    }));
-
-    return { kelas, tugas: mappedTugas };
-  }
-}