diff --git a/src/app.module.ts b/src/app.module.ts
index 472f80ff28d2b1e4824e6f10870c57b7a0ad9f79..954b6366eef3e7b377d9be3b448da7831cac5f35 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -22,10 +22,6 @@ import { DashboardModule } from "./dashboard/dashboard.module";
 import { BimbinganModule } from "./bimbingan/bimbingan.module";
 import { Konfigurasi } from "./entities/konfigurasi.entity";
 import { KonfigurasiModule } from "./konfigurasi/konfigurasi.module";
-import { DosenBimbinganModule } from "./dosen-bimbingan/dosen-bimbingan.module";
-import { ApprovalModule } from "./approval/approval.module";
-import { PendaftaranSidsem } from "./entities/pendaftaranSidsem";
-import { Ketersediaan } from "./entities/ketersediaan.entity";
 import { validate } from "./env.validation";
 import { BerkasBimbingan } from "./entities/berkasBimbingan";
 import { MataKuliah } from "./entities/mataKuliah";
@@ -33,6 +29,7 @@ import { SubmisiTugas } from "./entities/submisiTugas";
 import { KelasModule } from "./kelas/kelas.module";
 import { BerkasSubmisiTugas } from "./entities/berkasSubmisiTugas";
 import { BerkasTugas } from "./entities/berkasTugas";
+import { PendaftaranSidsem } from "./entities/pendaftaranSidsem";
 
 @Module({
   imports: [
@@ -61,7 +58,6 @@ import { BerkasTugas } from "./entities/berkasTugas";
         Tugas,
         PengujiSidang,
         Konfigurasi,
-        Ketersediaan,
         MataKuliah,
         SubmisiTugas,
         BerkasSubmisiTugas,
@@ -75,8 +71,6 @@ import { BerkasTugas } from "./entities/berkasTugas";
     DashboardModule,
     BimbinganModule,
     KonfigurasiModule,
-    DosenBimbinganModule,
-    ApprovalModule,
     KelasModule,
   ],
   controllers: [AppController],
diff --git a/src/approval/approval.controller.ts b/src/approval/approval.controller.ts
deleted file mode 100644
index 866410794f5f767cd84ad5489fdcdc5817c9024b..0000000000000000000000000000000000000000
--- a/src/approval/approval.controller.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { Controller, Patch, Param, UseGuards } from "@nestjs/common";
-import { ApprovalService } from "./approval.service";
-import {
-  PendaftaranTesis,
-  RegStatus,
-} from "src/entities/pendaftaranTesis.entity";
-import { CustomAuthGuard } from "src/middlewares/custom-auth.guard";
-import { RolesGuard } from "src/middlewares/roles.guard";
-import { RoleEnum } from "src/entities/pengguna.entity";
-import { Roles } from "src/middlewares/roles.decorator";
-import {
-  ApiBearerAuth,
-  ApiCookieAuth,
-  ApiOkResponse,
-  ApiTags,
-} from "@nestjs/swagger";
-import { ByIdParamDto } from "./approval.dto";
-
-@ApiTags("Approval")
-@ApiCookieAuth()
-@ApiBearerAuth()
-@Controller("approval")
-@UseGuards(CustomAuthGuard, RolesGuard)
-@Roles(RoleEnum.S2_PEMBIMBING)
-export class ApprovalController {
-  constructor(private readonly approvalService: ApprovalService) {}
-
-  @ApiOkResponse({ type: PendaftaranTesis })
-  @Patch(":id/approve")
-  async approvePendaftaran(
-    @Param() param: ByIdParamDto,
-  ): Promise<PendaftaranTesis> {
-    return this.approvalService.approvePendaftaran(
-      param.id,
-      RegStatus.APPROVED,
-    );
-  }
-
-  @ApiOkResponse({ type: PendaftaranTesis })
-  @Patch(":id/reject")
-  async declinePendaftaran(
-    @Param() param: ByIdParamDto,
-  ): Promise<PendaftaranTesis> {
-    return this.approvalService.approvePendaftaran(
-      param.id,
-      RegStatus.REJECTED,
-    );
-  }
-
-  @ApiOkResponse({ type: PendaftaranTesis })
-  @Patch(":id/interview")
-  async interviewPendaftaran(
-    @Param() param: ByIdParamDto,
-  ): Promise<PendaftaranTesis> {
-    return this.approvalService.approvePendaftaran(
-      param.id,
-      RegStatus.INTERVIEW,
-    );
-  }
-}
diff --git a/src/approval/approval.dto.ts b/src/approval/approval.dto.ts
deleted file mode 100644
index b9fea475cfd34a9705b8b8fcd66f0a69ca1995d2..0000000000000000000000000000000000000000
--- a/src/approval/approval.dto.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { IsUUID } from "@nestjs/class-validator";
-import { ApiProperty } from "@nestjs/swagger";
-
-export class ByIdParamDto {
-  @IsUUID()
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  id: string;
-}
diff --git a/src/approval/approval.module.ts b/src/approval/approval.module.ts
deleted file mode 100644
index c28790252c59277b51e473a33ab7d8b38ae32065..0000000000000000000000000000000000000000
--- a/src/approval/approval.module.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Module } from "@nestjs/common";
-import { TypeOrmModule } from "@nestjs/typeorm";
-import { PendaftaranTesis } from "src/entities/pendaftaranTesis.entity";
-import { ApprovalController } from "./approval.controller";
-import { ApprovalService } from "./approval.service";
-
-@Module({
-  imports: [TypeOrmModule.forFeature([PendaftaranTesis])],
-  controllers: [ApprovalController],
-  providers: [ApprovalService],
-})
-export class ApprovalModule {}
diff --git a/src/approval/approval.service.ts b/src/approval/approval.service.ts
deleted file mode 100644
index 8163efeda7b43052e82b6a5441b5590f384f1b6a..0000000000000000000000000000000000000000
--- a/src/approval/approval.service.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { Injectable } from "@nestjs/common";
-import { InjectRepository } from "@nestjs/typeorm";
-import { FindOneOptions, Repository } from "typeorm";
-import {
-  PendaftaranTesis,
-  RegStatus,
-} from "src/entities/pendaftaranTesis.entity";
-
-@Injectable()
-export class ApprovalService {
-  constructor(
-    @InjectRepository(PendaftaranTesis)
-    private readonly pendaftaranRepository: Repository<PendaftaranTesis>,
-  ) {}
-
-  async approvePendaftaran(
-    id: string,
-    status: RegStatus,
-  ): Promise<PendaftaranTesis> {
-    try {
-      const findOneOptions: FindOneOptions<PendaftaranTesis> = {
-        where: { id },
-      };
-      const pendaftaran =
-        await this.pendaftaranRepository.findOneOrFail(findOneOptions);
-      pendaftaran.status = status;
-
-      return await this.pendaftaranRepository.save(pendaftaran);
-    } catch (error) {
-      throw new Error("Pendaftaran not found");
-    }
-  }
-}
diff --git a/src/dosen-bimbingan/dosen-bimbingan.controller.ts b/src/dosen-bimbingan/dosen-bimbingan.controller.ts
deleted file mode 100644
index ef0b6acae18dc2d24c5e25dbdf88eaa8158a46df..0000000000000000000000000000000000000000
--- a/src/dosen-bimbingan/dosen-bimbingan.controller.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import {
-  Body,
-  Controller,
-  Delete,
-  Get,
-  NotFoundException,
-  Put,
-  Query,
-  UseGuards,
-} from "@nestjs/common";
-import {
-  ApiBearerAuth,
-  ApiCookieAuth,
-  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";
-import {
-  DosbimOptQueryDto,
-  DosbimQueryDto,
-  GetDosbimResDto,
-  SuccessResDto,
-  UpdateDosbimDto,
-} from "./dosen-bimbingan.dto";
-import { DosenBimbinganService } from "./dosen-bimbingan.service";
-
-@ApiTags("Dosen Bimbingan")
-@ApiCookieAuth()
-@ApiBearerAuth()
-@Controller("dosen-bimbingan")
-@UseGuards(CustomAuthGuard, RolesGuard)
-export class DosenBimbinganController {
-  constructor(private readonly dosbimService: DosenBimbinganService) {}
-
-  @ApiOkResponse({ type: [GetDosbimResDto] })
-  @Roles(
-    RoleEnum.ADMIN,
-    RoleEnum.S2_TIM_TESIS,
-    RoleEnum.S2_MAHASISWA,
-    RoleEnum.S2_TIM_TESIS,
-  )
-  @Get()
-  async get(@Query() query: DosbimOptQueryDto) {
-    if (!query.regId) return await this.dosbimService.getAll();
-
-    const res = await this.dosbimService.findByRegId(query.regId);
-    const mappedRes: GetDosbimResDto[] = res.map((r) => r.dosen);
-    return mappedRes;
-  }
-
-  @ApiOkResponse({ type: SuccessResDto })
-  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
-  @Put()
-  async updateByRegId(
-    @Query() query: DosbimQueryDto,
-    @Body() body: UpdateDosbimDto,
-  ): Promise<SuccessResDto> {
-    await this.dosbimService.updateByRegId(query.regId, body.dosbimIds);
-
-    return {
-      status: "ok",
-    };
-  }
-
-  @ApiOkResponse({ type: SuccessResDto })
-  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
-  @Delete()
-  async deleteByRegId(@Query() query: DosbimQueryDto): Promise<SuccessResDto> {
-    const res = await this.dosbimService.removeByRegId(query.regId);
-
-    if (!res.affected) throw new NotFoundException();
-
-    return {
-      status: "ok",
-    };
-  }
-}
diff --git a/src/dosen-bimbingan/dosen-bimbingan.dto.ts b/src/dosen-bimbingan/dosen-bimbingan.dto.ts
deleted file mode 100644
index 11d56b1135d145102b6ac69a56474ae66975dac5..0000000000000000000000000000000000000000
--- a/src/dosen-bimbingan/dosen-bimbingan.dto.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import {
-  ArrayMaxSize,
-  IsArray,
-  IsUUID,
-  ArrayMinSize,
-  ArrayUnique,
-  IsOptional,
-} from "@nestjs/class-validator";
-import { ApiProperty, ApiPropertyOptional, PickType } from "@nestjs/swagger";
-import { Pengguna } from "src/entities/pengguna.entity";
-
-export class DosbimOptQueryDto {
-  @ApiPropertyOptional({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsOptional()
-  @IsUUID()
-  regId?: string;
-}
-
-export class DosbimQueryDto {
-  @ApiProperty({ example: "550e8400-e29b-41d4-a716-446655440000" })
-  @IsUUID()
-  regId: string;
-}
-
-export class UpdateDosbimDto {
-  @ApiProperty({
-    type: [String],
-    example: ["550e8400-e29b-41d4-a716-446655440000"],
-  })
-  @IsArray()
-  @IsUUID("all", { each: true })
-  @ArrayMinSize(1)
-  @ArrayMaxSize(3)
-  @ArrayUnique()
-  dosbimIds: string[];
-}
-
-export class SuccessResDto {
-  @ApiProperty()
-  status: string;
-}
-
-export class GetDosbimResDto extends PickType(Pengguna, [
-  "id",
-  "email",
-  "nama",
-] as const) {}
diff --git a/src/dosen-bimbingan/dosen-bimbingan.module.ts b/src/dosen-bimbingan/dosen-bimbingan.module.ts
deleted file mode 100644
index 1929f62932c353150ab780e6a6fb785c560a9357..0000000000000000000000000000000000000000
--- a/src/dosen-bimbingan/dosen-bimbingan.module.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Module } from "@nestjs/common";
-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,
-  ],
-  controllers: [DosenBimbinganController],
-  providers: [DosenBimbinganService, CustomStrategy],
-})
-export class DosenBimbinganModule {}
diff --git a/src/dosen-bimbingan/dosen-bimbingan.service.ts b/src/dosen-bimbingan/dosen-bimbingan.service.ts
deleted file mode 100644
index 456364ee4bc51946474c2cd5e54e92fc26909fe8..0000000000000000000000000000000000000000
--- a/src/dosen-bimbingan/dosen-bimbingan.service.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import {
-  BadRequestException,
-  Injectable,
-  InternalServerErrorException,
-} from "@nestjs/common";
-import { InjectRepository } from "@nestjs/typeorm";
-import { DosenBimbingan } from "src/entities/dosenBimbingan.entity";
-import {
-  PendaftaranTesis,
-  RegStatus,
-} from "src/entities/pendaftaranTesis.entity";
-import { Pengguna, RoleEnum } from "src/entities/pengguna.entity";
-import { KonfigurasiService } from "src/konfigurasi/konfigurasi.service";
-import { ArrayContains, DataSource, Repository } from "typeorm";
-
-@Injectable()
-export class DosenBimbinganService {
-  constructor(
-    @InjectRepository(DosenBimbingan)
-    private dosbimRepo: Repository<DosenBimbingan>,
-    @InjectRepository(Pengguna)
-    private penggunaRepo: Repository<Pengguna>,
-    @InjectRepository(PendaftaranTesis)
-    private pendaftaranRepo: Repository<PendaftaranTesis>,
-    private konfService: KonfigurasiService,
-    private dataSource: DataSource,
-  ) {}
-
-  async getAll() {
-    return await this.penggunaRepo.find({
-      select: {
-        id: true,
-        nama: true,
-        email: true,
-      },
-      where: {
-        roles: ArrayContains([RoleEnum.S2_PEMBIMBING]),
-      },
-    });
-  }
-
-  async findByRegId(regId: string) {
-    return await this.dosbimRepo.find({
-      select: {
-        id: true,
-        dosen: {
-          id: true,
-          nama: true,
-          email: true,
-        },
-      },
-      relations: {
-        dosen: true,
-      },
-      where: {
-        pendaftaran: {
-          id: regId,
-        },
-      },
-    });
-  }
-
-  async updateByRegId(regId: string, dosbimIds: string[]) {
-    const [reg, currPeriod] = await Promise.all([
-      this.pendaftaranRepo.findOne({
-        select: { id: true, status: true },
-        where: { id: regId },
-        relations: { topik: true },
-      }),
-      this.konfService.getKonfigurasiByKey(process.env.KONF_PERIODE_KEY),
-    ]);
-
-    if (!reg || reg.status !== RegStatus.APPROVED) {
-      throw new BadRequestException(
-        "Registrasi tidak ditemukan atau tidak disetujui.",
-      );
-    }
-
-    if (!currPeriod || currPeriod !== reg.topik.periode) {
-      throw new BadRequestException(
-        "Periode belum dikonfigurasi atau tidak sesuai dengan periode sekarang.",
-      );
-    }
-
-    for (const dosbimId of dosbimIds) {
-      const res = await this.penggunaRepo.findOne({
-        select: {
-          id: true,
-        },
-        where: {
-          id: dosbimId,
-          roles: ArrayContains([RoleEnum.S2_PEMBIMBING]),
-        },
-      });
-
-      if (!res) {
-        throw new BadRequestException("Invalid pembimbing id");
-      }
-    }
-
-    const queryRunner = this.dataSource.createQueryRunner();
-
-    await queryRunner.connect();
-    await queryRunner.startTransaction();
-    try {
-      await this.removeByRegId(regId);
-
-      for (const dosbimId of dosbimIds) {
-        await queryRunner.manager.getRepository(DosenBimbingan).insert({
-          idPendaftaran: regId,
-          idDosen: dosbimId,
-        });
-      }
-
-      await queryRunner.commitTransaction();
-    } catch (err) {
-      await queryRunner.rollbackTransaction();
-
-      throw new InternalServerErrorException();
-    } finally {
-      await queryRunner.release();
-    }
-  }
-
-  async removeByRegId(regId: string) {
-    return await this.dosbimRepo
-      .createQueryBuilder()
-      .delete()
-      .where("idPendaftaran = :idPendaftaran", {
-        idPendaftaran: regId,
-      })
-      .execute();
-  }
-}
diff --git a/src/main.ts b/src/main.ts
index 11cb941afa48d31dc673e827398bac25ee2df6c0..bb2da38e1a57d5422546e9ae52909898e1d51176 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -22,7 +22,6 @@ async function bootstrap() {
     .setDescription("GraduIT API Documentation for S2 services")
     .setVersion("1.0")
     .addTag("Alokasi Topik")
-    .addTag("Approval")
     .addTag("Bimbingan")
     .addTag("Dashboard")
     .addTag("Dosen Bimbingan")
diff --git a/src/registrasi-tesis/registrasi-tesis.controller.ts b/src/registrasi-tesis/registrasi-tesis.controller.ts
index 4b0904fe472ce0dba0b8363e62f53291e5988af4..e41920cdafcd7e91a4378bd0224bfdbcb9605ec7 100644
--- a/src/registrasi-tesis/registrasi-tesis.controller.ts
+++ b/src/registrasi-tesis/registrasi-tesis.controller.ts
@@ -4,7 +4,6 @@ import {
   Controller,
   ForbiddenException,
   Get,
-  NotFoundException,
   Param,
   Patch,
   Post,
@@ -16,6 +15,7 @@ import {
   ApiBearerAuth,
   ApiCookieAuth,
   ApiOkResponse,
+  ApiOperation,
   ApiTags,
 } from "@nestjs/swagger";
 import { Request } from "express";
@@ -27,9 +27,10 @@ import { Roles } from "src/middlewares/roles.decorator";
 import { RolesGuard } from "src/middlewares/roles.guard";
 import {
   FindAllNewestRegRespDto,
+  GetByIdRespDto,
+  IdDto,
   RegByMhsParamDto,
   RegDto,
-  RegParamDto,
   RegQueryDto,
   RegStatisticsRespDto,
   UpdateByMhsParamsDto,
@@ -50,13 +51,10 @@ export class RegistrasiTesisController {
     private readonly konfService: KonfigurasiService,
   ) {}
 
-  @UseGuards(CustomAuthGuard, RolesGuard)
-  @Roles(RoleEnum.S2_MAHASISWA, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
-  @Get("/mahasiswa/:mahasiswaId")
-  findByUserId(@Param() params: RegByMhsParamDto) {
-    return this.registrasiTesisService.findByUserId(params.mahasiswaId);
-  }
-
+  @ApiOperation({
+    summary:
+      "Create new registration. Roles: S2_MAHASISWA, ADMIN, S2_TIM_TESIS",
+  })
   @UseGuards(CustomAuthGuard, RolesGuard)
   @Roles(RoleEnum.S2_MAHASISWA, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
   @Post()
@@ -72,7 +70,88 @@ export class RegistrasiTesisController {
     );
   }
 
-  // Right now only admin & timtesis view is handled (apakah dosen perlu summary juga?)
+  @ApiOperation({
+    summary:
+      "Find registrations (historical) by Mahasiswa ID. Roles: S2_MAHASISWA, ADMIN, S2_TIM_TESIS",
+  })
+  @ApiOkResponse({ type: [GetByIdRespDto] })
+  @UseGuards(CustomAuthGuard, RolesGuard)
+  @Roles(RoleEnum.S2_MAHASISWA, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
+  @Get("/mahasiswa/:mahasiswaId")
+  async findByUserId(@Param() params: RegByMhsParamDto, @Req() req: Request) {
+    const { id, roles } = req.user as AuthDto;
+
+    if (
+      !roles.includes(RoleEnum.ADMIN) &&
+      !roles.includes(RoleEnum.S2_TIM_TESIS)
+    ) {
+      // roles only include RoleEnum.S2_MAHASISWA
+      if (id !== params.mahasiswaId) {
+        throw new ForbiddenException();
+      }
+    }
+
+    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,
+    );
+  }
+
+  @ApiOperation({
+    summary:
+      "Find newest registration by Mahasiswa ID. Roles: ADMIN, S2_TIM_TESIS, S2_PEMBIMBING",
+  })
+  @ApiOkResponse({ type: GetByIdRespDto })
+  @UseGuards(CustomAuthGuard, RolesGuard)
+  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS, RoleEnum.S2_PEMBIMBING)
+  @Get("/mahasiswa/:mahasiswaId/newest")
+  async findNewestByUserId(
+    @Param() params: RegByMhsParamDto,
+    @Req() req: Request,
+  ) {
+    const { id, roles } = req.user as AuthDto;
+
+    let idPenerima = undefined;
+    if (
+      !roles.includes(RoleEnum.ADMIN) &&
+      !roles.includes(RoleEnum.S2_TIM_TESIS)
+    ) {
+      // roles only include RoleEnum.S2_PEMBIMBING
+      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,
+    );
+
+    return res[0];
+  }
+
+  @ApiOperation({
+    summary:
+      "Get statistics of registrations. Roles: S2_PEMBIMBING, ADMIN, S2_TIM_TESIS",
+  })
   @ApiOkResponse({ type: RegStatisticsRespDto })
   @UseGuards(CustomAuthGuard, RolesGuard)
   @Roles(RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
@@ -96,6 +175,10 @@ export class RegistrasiTesisController {
 
   // Admin & TimTesis view will show newst reg records per Mahasiswa
   // Pembimbing view will show all regs towards them
+  @ApiOperation({
+    summary:
+      "Find all newest registration for each Mahasiswa. Roles: S2_PEMBIMBING, ADMIN, S2_TIM_TESIS",
+  })
   @ApiOkResponse({ type: FindAllNewestRegRespDto, isArray: true })
   @UseGuards(CustomAuthGuard, RolesGuard)
   @Roles(RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
@@ -128,42 +211,18 @@ export class RegistrasiTesisController {
     });
   }
 
+  @ApiOperation({
+    summary:
+      "Update interview date of newest in process registration by Mahasiswa ID. Roles: S2_PEMBIMBING, ADMIN, S2_TIM_TESIS",
+  })
+  @ApiOkResponse({ type: IdDto })
   @UseGuards(CustomAuthGuard, RolesGuard)
-  @Roles(RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
-  @Get("/:id")
-  async findById(
-    @Req() req: Request,
-    @Param() params: RegParamDto,
-    @Query()
-    query: ViewQueryDto,
-  ) {
-    const { id: idPenerima, roles } = req.user as AuthDto;
-
-    if (!roles.includes(query.view)) {
-      throw new ForbiddenException();
-    }
-
-    const res = await this.registrasiTesisService.findRegById(params.id);
-    if (!res) {
-      throw new NotFoundException();
-    }
-
-    if (
-      query.view === RoleEnum.S2_PEMBIMBING &&
-      res.penerima.id !== idPenerima
-    ) {
-      throw new ForbiddenException();
-    }
-
-    return res;
-  }
-
-  @UseGuards(CustomAuthGuard, RolesGuard)
-  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
+  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS, RoleEnum.S2_PEMBIMBING)
   @Patch("/:mhsId/interview")
   async updateInterviewDateByMhsId(
     @Param() params: UpdateByMhsParamsDto,
     @Body() body: UpdateInterviewBodyDto,
+    @Req() req: Request,
   ) {
     const periode = await this.konfService.getKonfigurasiByKey(
       process.env.KONF_PERIODE_KEY,
@@ -173,19 +232,37 @@ export class RegistrasiTesisController {
       throw new BadRequestException("Periode belum dikonfigurasi.");
     }
 
+    const { id, roles } = req.user as AuthDto;
+    let idPenerima = undefined;
+
+    if (
+      !roles.includes(RoleEnum.ADMIN) &&
+      !roles.includes(RoleEnum.S2_TIM_TESIS)
+    ) {
+      // roles only include RoleEnum.S2_PEMBIMBING
+      idPenerima = id;
+    }
+
     return await this.registrasiTesisService.updateInterviewDate(
       params.mhsId,
       periode,
       body,
+      idPenerima,
     );
   }
 
+  @ApiOperation({
+    summary:
+      "Update status of newest registration by Mahasiswa ID. Roles: S2_PEMBIMBING, ADMIN, S2_TIM_TESIS",
+  })
+  @ApiOkResponse({ type: IdDto })
   @UseGuards(CustomAuthGuard, RolesGuard)
-  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
+  @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS, RoleEnum.S2_PEMBIMBING)
   @Patch("/:mhsId/status")
   async updateStatusByMhsId(
     @Param() params: UpdateByMhsParamsDto,
     @Body() body: UpdateStatusBodyDto,
+    @Req() req: Request,
   ) {
     const periode = await this.konfService.getKonfigurasiByKey(
       process.env.KONF_PERIODE_KEY,
@@ -195,17 +272,34 @@ export class RegistrasiTesisController {
       throw new BadRequestException("Periode belum dikonfigurasi.");
     }
 
+    const { id, roles } = req.user as AuthDto;
+    let idPenerima = undefined;
+
+    if (
+      !roles.includes(RoleEnum.ADMIN) &&
+      !roles.includes(RoleEnum.S2_TIM_TESIS)
+    ) {
+      // roles only include RoleEnum.S2_PEMBIMBING
+      idPenerima = id;
+    }
+
     return await this.registrasiTesisService.updateStatus(
       params.mhsId,
       periode,
       body,
+      idPenerima,
     );
   }
 
+  @ApiOperation({
+    summary:
+      "Update pembimbing list of approved registration by Mahasiswa ID. Roles: ADMIN, S2_TIM_TESIS",
+  })
+  @ApiOkResponse({ type: IdDto })
   @UseGuards(CustomAuthGuard, RolesGuard)
   @Roles(RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS)
   @Patch("/:mhsId/pembimbing")
-  async udpatePembimbingListByMhsId(
+  async updatePembimbingListByMhsId(
     @Param() params: UpdateByMhsParamsDto,
     @Body() body: UpdatePembimbingBodyDto,
   ) {
diff --git a/src/registrasi-tesis/registrasi-tesis.dto.ts b/src/registrasi-tesis/registrasi-tesis.dto.ts
index f18cca53a0f91f6503197d1318f7ca283cb85015..330f31d2bf8ea6118fa74403d210c1cf87e13921 100644
--- a/src/registrasi-tesis/registrasi-tesis.dto.ts
+++ b/src/registrasi-tesis/registrasi-tesis.dto.ts
@@ -6,10 +6,14 @@ import {
   IsString,
   IsUUID,
 } from "@nestjs/class-validator";
-import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
+import { ApiProperty, ApiPropertyOptional, PickType } from "@nestjs/swagger";
 import { ArrayMinSize, ArrayUnique, IsArray } from "class-validator";
-import { JalurEnum, RegStatus } from "src/entities/pendaftaranTesis.entity";
-import { RoleEnum } from "src/entities/pengguna.entity";
+import {
+  JalurEnum,
+  PendaftaranTesis,
+  RegStatus,
+} from "src/entities/pendaftaranTesis.entity";
+import { Pengguna, RoleEnum } from "src/entities/pengguna.entity";
 
 export class RegDto {
   @IsUUID()
@@ -39,13 +43,21 @@ export class RegByMhsParamDto {
   mahasiswaId: string;
 }
 
-export class RegParamDto {
+export class IdDto {
   @IsUUID()
   @ApiProperty()
   id: string;
 }
 
-export class RegQueryDto {
+export class ViewQueryDto {
+  @IsEnum([RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS])
+  @ApiProperty({
+    enum: [RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS],
+  })
+  view: RoleEnum.S2_PEMBIMBING | RoleEnum.ADMIN | RoleEnum.S2_TIM_TESIS;
+}
+
+export class RegQueryDto extends ViewQueryDto {
   @IsOptional()
   @IsNumberString()
   @ApiPropertyOptional()
@@ -75,35 +87,29 @@ export class RegQueryDto {
   @IsEnum(["ASC", "DESC"])
   @ApiPropertyOptional({ enum: ["ASC", "DESC"] })
   sort?: "ASC" | "DESC";
-
-  @IsEnum([RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS])
-  @ApiProperty({
-    enum: [RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS],
-  })
-  view: RoleEnum.S2_PEMBIMBING | RoleEnum.ADMIN | RoleEnum.S2_TIM_TESIS;
-}
-
-export class ViewQueryDto {
-  @IsEnum([RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS])
-  @ApiProperty({
-    enum: [RoleEnum.S2_PEMBIMBING, RoleEnum.ADMIN, RoleEnum.S2_TIM_TESIS],
-  })
-  view: RoleEnum.S2_PEMBIMBING | RoleEnum.ADMIN | RoleEnum.S2_TIM_TESIS;
 }
 
 export class FindAllNewestRegRespDataDto {
   @ApiProperty()
   pendaftaran_id: string;
+
   @ApiProperty()
   nim: string;
+
   @ApiProperty()
   mahasiswa_nama: string;
+
   @ApiProperty()
   mahasiswa_id: string;
+
   @ApiProperty()
   pembimbing_nama: string;
+
   @ApiProperty()
   status: string;
+
+  @ApiProperty()
+  jadwal_interview: Date;
 }
 
 export class FindAllNewestRegRespDto {
@@ -158,3 +164,26 @@ export class UpdatePembimbingBodyDto {
   @ArrayUnique()
   pembimbing_ids: string[];
 }
+
+class DosenPembimbingDto extends PickType(Pengguna, [
+  "id",
+  "nama",
+  "kontak",
+] as const) {}
+
+export class GetByIdRespDto extends PickType(PendaftaranTesis, [
+  "id",
+  "jadwalInterview",
+  "status",
+  "jalurPilihan",
+  "waktuPengiriman",
+] as const) {
+  @ApiProperty()
+  judulTopik: string;
+
+  @ApiProperty()
+  deskripsiTopik: string;
+
+  @ApiProperty({ type: [DosenPembimbingDto] })
+  dosenPembimbing: DosenPembimbingDto[];
+}
diff --git a/src/registrasi-tesis/registrasi-tesis.service.ts b/src/registrasi-tesis/registrasi-tesis.service.ts
index 1513caa4c7d7cae5ada90e6c5857f93349c6b533..74afb3e99311335adae3e191090ce7b4902964cb 100644
--- a/src/registrasi-tesis/registrasi-tesis.service.ts
+++ b/src/registrasi-tesis/registrasi-tesis.service.ts
@@ -1,5 +1,6 @@
 import {
   BadRequestException,
+  ForbiddenException,
   Injectable,
   InternalServerErrorException,
   NotFoundException,
@@ -14,15 +15,17 @@ 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, DataSource, In, Repository } from "typeorm";
+import { ArrayContains, Brackets, DataSource, In, Repository } from "typeorm";
 import {
   FindAllNewestRegRespDto,
+  IdDto,
   RegDto,
   RegStatisticsRespDto,
   UpdateInterviewBodyDto,
   UpdatePembimbingBodyDto,
   UpdateStatusBodyDto,
 } from "./registrasi-tesis.dto";
+import * as dayjs from "dayjs";
 
 @Injectable()
 export class RegistrasiTesisService {
@@ -84,21 +87,73 @@ export class RegistrasiTesisService {
     return createdRegistration;
   }
 
-  async findByUserId(mahasiswaId: string) {
-    const res = await this.pendaftaranTesisRepository.find({
-      relations: ["topik", "penerima"],
-      where: { mahasiswa: { id: mahasiswaId } },
-    });
+  async findByUserId(
+    mahasiswaId: string,
+    periode: string,
+    isNewestOnly: boolean,
+    idPenerima?: string,
+  ) {
+    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")
+      .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();
+
+    if (res.length === 0) {
+      throw new NotFoundException("Tidak ada registrasi tesis yang ditemukan.");
+    }
 
-    return res.map((r) => ({
-      ...r,
-      penerima: {
-        ...r.penerima,
-        password: undefined,
-        roles: undefined,
-        nim: undefined,
-      },
+    if (idPenerima) {
+      // requester only has S2_PEMBIMBING access
+      const reg = res[0];
+
+      if (reg.penerima.id !== idPenerima) {
+        throw new ForbiddenException();
+      }
+    }
+
+    const mappedRes = res.map((r) => ({
+      id: r.id,
+      jadwalInterview: r.jadwalInterview,
+      jalurPilihan: r.jalurPilihan,
+      status: r.status,
+      waktuPengiriman: r.waktuPengiriman,
+      judulTopik: r.topik.judul,
+      deskripsiTopik: r.topik.deskripsi,
+      dosenPembimbing:
+        r.status === RegStatus.APPROVED
+          ? r.dosenBimbingan.map((db) => db.dosen)
+          : [r.penerima],
     }));
+
+    if (isNewestOnly) {
+      // only get last registration
+      // slow performance because get all records first then only returns the first one
+      // need to change to use subquery
+      mappedRes.splice(1);
+    }
+
+    return mappedRes;
   }
 
   async getRegsStatistics(options: {
@@ -109,69 +164,70 @@ export class RegistrasiTesisService {
       where: { roles: ArrayContains([RoleEnum.S2_MAHASISWA]) },
     });
 
-    // Show newest regs per Mhs if POV TimTesis or Admin
-    if (!options.idPenerima) {
-      const baseQuery = this.pendaftaranTesisRepository
-        .createQueryBuilder("pt")
-        .innerJoinAndSelect(
-          (qb) =>
-            qb
-              .select([
-                "pt.mahasiswaId AS latest_mahasiswaId",
-                "MAX(pt.waktuPengiriman) AS latestPengiriman",
-              ])
-              .from(PendaftaranTesis, "pt")
-              .groupBy("pt.mahasiswaId"),
-          "latest",
-          "latest.latest_mahasiswaId = pt.mahasiswaId AND pt.waktuPengiriman = latest.latestPengiriman",
-        )
-        .innerJoinAndSelect("pt.topik", "topik")
-        .where("topik.periode = :periode", { periode: options.periode });
-
-      const totalDiterima = baseQuery
-        .clone()
-        .andWhere("pt.status = :status", { status: RegStatus.APPROVED })
-        .getCount();
-
-      const totalProses = baseQuery
-        .clone()
-        .where("pt.status IN (:...status)", {
-          status: [RegStatus.NOT_ASSIGNED, RegStatus.INTERVIEW],
-        })
-        .getCount();
-
-      const totalDitolak = baseQuery
-        .clone()
-        .where("pt.status = :status", { status: RegStatus.REJECTED })
-        .getCount();
-
-      const [total, diterima, proses, ditolak] = await Promise.all([
-        totalMahasiswa,
-        totalDiterima,
-        totalProses,
-        totalDitolak,
-      ]);
-
-      return {
-        diterima: {
-          amount: diterima,
-          percentage: Math.round((diterima / total) * 100),
-        },
-        sedang_proses: {
-          amount: proses,
-          percentage: Math.round((proses / total) * 100),
-        },
-        ditolak: {
-          amount: ditolak,
-          percentage: Math.round((ditolak / total) * 100),
-        },
-      };
-    } else {
-      throw new InternalServerErrorException("Not implemented");
+    // Show newest regs per Mhs
+    const baseQuery = this.pendaftaranTesisRepository
+      .createQueryBuilder("pt")
+      .innerJoinAndSelect(
+        (qb) =>
+          qb
+            .select([
+              "pt.mahasiswaId AS latest_mahasiswaId",
+              "MAX(pt.waktuPengiriman) AS latestPengiriman",
+            ])
+            .from(PendaftaranTesis, "pt")
+            .groupBy("pt.mahasiswaId"),
+        "latest",
+        "latest.latest_mahasiswaId = pt.mahasiswaId AND pt.waktuPengiriman = latest.latestPengiriman",
+      )
+      .innerJoinAndSelect("pt.topik", "topik")
+      .where("topik.periode = :periode", { periode: options.periode });
+
+    if (options.idPenerima) {
+      baseQuery.andWhere("pt.penerimaId = :idPenerima", {
+        idPenerima: options.idPenerima,
+      });
     }
+
+    const totalDiterima = baseQuery
+      .clone()
+      .andWhere("pt.status = :status", { status: RegStatus.APPROVED })
+      .getCount();
+
+    const totalProses = baseQuery
+      .clone()
+      .andWhere("pt.status IN (:...status)", {
+        status: [RegStatus.NOT_ASSIGNED, RegStatus.INTERVIEW],
+      })
+      .getCount();
+
+    const totalDitolak = baseQuery
+      .clone()
+      .andWhere("pt.status = :status", { status: RegStatus.REJECTED })
+      .getCount();
+
+    const [total, diterima, proses, ditolak] = await Promise.all([
+      totalMahasiswa,
+      totalDiterima,
+      totalProses,
+      totalDitolak,
+    ]);
+
+    return {
+      diterima: {
+        amount: diterima,
+        percentage: Math.round((diterima / total) * 100),
+      },
+      sedang_proses: {
+        amount: proses,
+        percentage: Math.round((proses / total) * 100),
+      },
+      ditolak: {
+        amount: ditolak,
+        percentage: Math.round((ditolak / total) * 100),
+      },
+    };
   }
 
-  // TODO sort
   async findAllRegs(options: {
     status?: RegStatus;
     page: number;
@@ -186,22 +242,20 @@ export class RegistrasiTesisService {
       .createQueryBuilder("pt")
       .select("pt");
 
-    // Show newest regs per Mhs if POV TimTesis or Admin
+    // Show newest regs per Mhs
     // May need to make materialized view to improve performance
-    if (!options.idPenerima) {
-      baseQuery.innerJoinAndSelect(
-        (qb) =>
-          qb
-            .select([
-              "pt.mahasiswaId AS latest_mahasiswaId",
-              "MAX(pt.waktuPengiriman) AS latestPengiriman",
-            ])
-            .from(PendaftaranTesis, "pt")
-            .groupBy("pt.mahasiswaId"),
-        "latest",
-        "latest.latest_mahasiswaId = pt.mahasiswaId AND pt.waktuPengiriman = latest.latestPengiriman",
-      );
-    }
+    baseQuery.innerJoinAndSelect(
+      (qb) =>
+        qb
+          .select([
+            "pt.mahasiswaId AS latest_mahasiswaId",
+            "MAX(pt.waktuPengiriman) AS latestPengiriman",
+          ])
+          .from(PendaftaranTesis, "pt")
+          .groupBy("pt.mahasiswaId"),
+      "latest",
+      "latest.latest_mahasiswaId = pt.mahasiswaId AND pt.waktuPengiriman = latest.latestPengiriman",
+    );
 
     baseQuery
       .innerJoinAndSelect("pt.topik", "topik")
@@ -209,19 +263,25 @@ export class RegistrasiTesisService {
       .innerJoinAndSelect("pt.mahasiswa", "mahasiswa")
       .where("topik.periode = :periode", { periode: options.periode });
 
+    if (options.idPenerima) {
+      baseQuery.andWhere("pt.penerimaId = :idPenerima", {
+        idPenerima: options.idPenerima,
+      });
+    }
+
     if (options.search)
       baseQuery.andWhere(
-        "mahasiswa.nama LIKE '%' || :search || '%' OR mahasiswa.nim LIKE '%' || :search || '%'",
-        {
-          search: options.search,
-        },
+        new Brackets((qb) =>
+          qb
+            .where("mahasiswa.nama ILIKE :search", {
+              search: `%${options.search}%`,
+            })
+            .orWhere("mahasiswa.nim ILIKE :search", {
+              search: `%${options.search}%`,
+            }),
+        ),
       );
 
-    if (options.idPenerima)
-      baseQuery.andWhere("penerima.id = :idPenerima", {
-        idPenerima: options.idPenerima,
-      });
-
     if (options.status)
       baseQuery.andWhere("pt.status = :status", {
         status: options.status,
@@ -256,6 +316,7 @@ export class RegistrasiTesisService {
         mahasiswa_nama: reg.mahasiswa.nama,
         pembimbing_nama: reg.penerima.nama,
         status: reg.status,
+        jadwal_interview: reg.jadwalInterview,
       })),
       count,
     };
@@ -263,40 +324,7 @@ export class RegistrasiTesisService {
     return resData;
   }
 
-  async findRegById(id: string) {
-    // not periode-protected
-    return await this.pendaftaranTesisRepository.findOne({
-      select: {
-        id: true,
-        waktuPengiriman: true,
-        jadwalInterview: true,
-        waktuKeputusan: true,
-        status: true,
-        jalurPilihan: true,
-        penerima: {
-          id: true,
-          nama: true,
-          email: true,
-        },
-        mahasiswa: {
-          id: true,
-          nama: true,
-          email: true,
-          nim: true,
-        },
-      },
-      where: {
-        id,
-      },
-      relations: {
-        penerima: true,
-        topik: true,
-        mahasiswa: true,
-      },
-    });
-  }
-
-  async getNewestRegByMhs(mahasiswaId: string, periode: string) {
+  private async getNewestRegByMhs(mahasiswaId: string, periode: string) {
     const mahasiswa = await this.penggunaRepository.findOne({
       select: {
         id: true,
@@ -313,14 +341,23 @@ export class RegistrasiTesisService {
     const newestReg = await this.pendaftaranTesisRepository.findOne({
       select: {
         id: true,
+        jadwalInterview: true,
         status: true,
         waktuPengiriman: true,
+        jalurPilihan: true,
         topik: {
+          judul: true,
+          deskripsi: true,
           periode: true,
         },
+        penerima: {
+          id: true,
+        },
       },
       relations: {
         topik: true,
+        penerima: true,
+        mahasiswa: true,
       },
       where: {
         mahasiswa: mahasiswa,
@@ -345,9 +382,23 @@ export class RegistrasiTesisService {
     mahasiswaId: string,
     periode: string,
     dto: UpdateInterviewBodyDto,
+    idPenerima?: string,
   ) {
+    const minDate = new Date();
+    minDate.setDate(minDate.getDate() + 2);
+
+    if (dayjs(dto.date).isBefore(dayjs(minDate).endOf("d"))) {
+      throw new BadRequestException(
+        "Interview date must be at least 2 days from now",
+      );
+    }
+
     const newestReg = await this.getNewestRegByMhs(mahasiswaId, periode);
 
+    if (newestReg && idPenerima && newestReg.penerima.id !== idPenerima) {
+      throw new ForbiddenException();
+    }
+
     const restrictedStatus: RegStatus[] = [
       RegStatus.APPROVED,
       RegStatus.REJECTED,
@@ -367,22 +418,54 @@ export class RegistrasiTesisService {
       { jadwalInterview: newDate, status: RegStatus.INTERVIEW },
     );
 
-    return { status: "ok" };
+    return { id: newestReg.id } as IdDto;
   }
 
   async updateStatus(
     mahasiswaId: string,
     periode: string,
     dto: UpdateStatusBodyDto,
+    idPenerima?: string,
   ) {
     const newestReg = await this.getNewestRegByMhs(mahasiswaId, periode);
 
-    await this.pendaftaranTesisRepository.update(
-      { id: newestReg.id },
-      { status: dto.status },
-    );
+    if (newestReg && idPenerima && newestReg.penerima.id !== idPenerima) {
+      throw new ForbiddenException();
+    }
+
+    const queryRunner = this.dataSource.createQueryRunner();
+    await queryRunner.connect();
+    await queryRunner.startTransaction();
+
+    try {
+      await queryRunner.manager.update(
+        PendaftaranTesis,
+        { id: newestReg.id },
+        { status: dto.status, waktuKeputusan: new Date() },
+      );
+
+      if (dto.status === RegStatus.APPROVED) {
+        await queryRunner.manager.insert(DosenBimbingan, {
+          idPendaftaran: newestReg.id,
+          idDosen: newestReg.penerima.id,
+        });
+      } else {
+        // dto.status === RegStatus.REJECTED
+        await queryRunner.manager.delete(DosenBimbingan, {
+          idPendaftaran: newestReg.id,
+        });
+      }
 
-    return { status: "ok" };
+      await queryRunner.commitTransaction();
+    } catch (err) {
+      await queryRunner.rollbackTransaction();
+
+      throw new InternalServerErrorException();
+    } finally {
+      await queryRunner.release();
+    }
+
+    return { id: newestReg.id } as IdDto;
   }
 
   async updatePembimbingList(
@@ -392,7 +475,6 @@ export class RegistrasiTesisService {
   ) {
     const newestReg = await this.getNewestRegByMhs(mahasiswaId, periode);
 
-    // TODO decide to allow unapproved Registrations to have their Penerima changed or not
     if (newestReg.status !== RegStatus.APPROVED)
       throw new BadRequestException(
         "Cannot update pembimbing on non-approved registration",
@@ -427,7 +509,7 @@ export class RegistrasiTesisService {
       (newId) => !newPembimbingIds.includes(newId),
     );
 
-    const queryRunner = await this.dataSource.createQueryRunner();
+    const queryRunner = this.dataSource.createQueryRunner();
     await queryRunner.connect();
     await queryRunner.startTransaction();
 
@@ -443,10 +525,12 @@ export class RegistrasiTesisService {
       await queryRunner.commitTransaction();
     } catch (err) {
       await queryRunner.rollbackTransaction();
+
+      throw new InternalServerErrorException();
     } finally {
       await queryRunner.release();
     }
 
-    return { status: "ok" };
+    return { id: newestReg.id } as IdDto;
   }
 }