diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..d14eab8de75d9ac7aacc4faed33394ff2ac57689 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +dist +node_modules +.env \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..60937fa941f657b5baedda90beed212a9592da3d --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +POSTGRES_HOST=localhost +POSTGRES_PORT=5432 +POSTGRES_USER= +POSTGRES_PASSWORD= +POSTGRES_DATABASE= \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 259de13c733a7284a352a5cba1e9fd57e97e431d..9ade1ea0f1753fb3cbe1e7c19093a365c3ed88f7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,25 +1,25 @@ module.exports = { - parser: '@typescript-eslint/parser', + parser: "@typescript-eslint/parser", parserOptions: { - project: 'tsconfig.json', + project: "tsconfig.json", tsconfigRootDir: __dirname, - sourceType: 'module', + sourceType: "module", }, - plugins: ['@typescript-eslint/eslint-plugin'], + plugins: ["@typescript-eslint/eslint-plugin"], extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", ], root: true, env: { node: true, jest: true, }, - ignorePatterns: ['.eslintrc.js'], + ignorePatterns: [".eslintrc.js"], rules: { - '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', + "@typescript-eslint/interface-name-prefix": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "off", }, }; diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index a20502b7f06d848452da0d93ce8830c1d86b05dd..0000000000000000000000000000000000000000 --- a/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "all" -} diff --git a/package-lock.json b/package-lock.json index 6800fd80d82b43528e6b44baa4137a56b2ee37bf..ed3799a3fcf1ec45d7e2d40c205a4b94a1abd5c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,9 @@ "version": "0.0.1", "license": "UNLICENSED", "dependencies": { + "@nestjs/axios": "^3.0.2", "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.2.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.2", @@ -1668,6 +1670,16 @@ "node": ">=8" } }, + "node_modules/@nestjs/axios": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-3.0.2.tgz", + "integrity": "sha512-Z6GuOUdNQjP7FX+OuV2Ybyamse+/e0BFdTWBX5JxpBDKA+YkdLynDgG6HTF04zy6e9zPa19UX0WA2VDoehwhXQ==", + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0", + "axios": "^1.3.1", + "rxjs": "^6.0.0 || ^7.0.0" + } + }, "node_modules/@nestjs/cli": { "version": "10.3.2", "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.3.2.tgz", @@ -1813,6 +1825,32 @@ } } }, + "node_modules/@nestjs/config": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.2.0.tgz", + "integrity": "sha512-BpYRn57shg7CH35KGT6h+hT7ZucB6Qn2B3NBNdvhD4ApU8huS5pX/Wc2e/aO5trIha606Bz2a9t9/vbiuTBTww==", + "dependencies": { + "dotenv": "16.4.1", + "dotenv-expand": "10.0.0", + "lodash": "4.17.21", + "uuid": "9.0.1" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "rxjs": "^7.1.0" + } + }, + "node_modules/@nestjs/config/node_modules/dotenv": { + "version": "16.4.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", + "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/@nestjs/core": { "version": "10.3.3", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.3.tgz", @@ -2913,8 +2951,18 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "peer": true, + "dependencies": { + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } }, "node_modules/babel-jest": { "version": "29.7.0", @@ -3588,7 +3636,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3864,7 +3911,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -3958,6 +4004,14 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "engines": { + "node": ">=12" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4739,6 +4793,26 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "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==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "peer": true, + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -4808,7 +4882,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -6370,8 +6443,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -7309,6 +7381,12 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "peer": true + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/package.json b/package.json index 34365517dc196ae8b86a6c59c3bb2584386ef178..1f1c5a9790adf7d2f639a8d849efafa899f05127 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,9 @@ "lint:fix": "prettier --write --list-different . && npm run lint:js --fix" }, "dependencies": { + "@nestjs/axios": "^3.0.2", "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.2.0", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.2", diff --git a/src/app.controller.spec.ts b/src/app.controller.spec.ts deleted file mode 100644 index d22f3890a380cea30641cfecc329b5c794ef5fb2..0000000000000000000000000000000000000000 --- a/src/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; - -describe('AppController', () => { - let appController: AppController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile(); - - appController = app.get<AppController>(AppController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(appController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/src/app.controller.ts b/src/app.controller.ts index cce879ee622146012901c9adb47ef40c0fd3a555..1e7e628309a220eac78eaca27cd54042b48df882 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,5 +1,5 @@ -import { Controller, Get } from '@nestjs/common'; -import { AppService } from './app.service'; +import { Controller, Get } from "@nestjs/common"; +import { AppService } from "./app.service"; @Controller() export class AppController { diff --git a/src/app.module.ts b/src/app.module.ts index f4135c5eed69f38f4cff1222ba62c93a01a7e0c8..171261220ecfc70b89c378e1e99dfedd349b039c 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,36 +1,40 @@ -import { Module } from '@nestjs/common'; -import { AppController } from './app.controller'; -import { AppService } from './app.service'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Bimbingan } from './entities/bimbingan.entity'; -import { Pengguna } from './entities/pengguna.entity'; -import { RangeJadwalSeminar } from './entities/rangeJadwalSeminar.entity'; -import { Seminar } from './entities/seminar.entity'; -import { Topik } from './entities/topik.entity'; -import { AuditLog } from './entities/auditLog.entity'; -import { DosenBimbingan } from './entities/dosenBimbingan.entity'; -import { Kelas } from './entities/kelas.entity'; -import { MahasiswaKelas } from './entities/mahasiswaKelas'; -import { PengajarKelas } from './entities/pengajarKelas.entity'; -import { PengajuanPengambilanTopik } from './entities/pengajuanPengambilanTopik.entity'; -import { PengambilanTopik } from './entities/pengambilanTopik.entity'; -import { RangeJadwalSidang } from './entities/rangeJadwalSidang.entity'; -import { Ruangan } from './entities/ruangan.entity'; -import { Sidang } from './entities/sidang.entity'; -import { Tugas } from './entities/tugas.entity'; -import { PembimbingSeminar } from './entities/pembimbingSeminar.entity'; -import { PembimbingSidang } from './entities/pembimbingSidang.entity'; -import { PengujiSidang } from './entities/pengujiSidang.entity'; +import { Module } from "@nestjs/common"; +import { AppController } from "./app.controller"; +import { AppService } from "./app.service"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { Bimbingan } from "./entities/bimbingan.entity"; +import { Pengguna } from "./entities/pengguna.entity"; +import { RangeJadwalSeminar } from "./entities/rangeJadwalSeminar.entity"; +import { Seminar } from "./entities/seminar.entity"; +import { Topik } from "./entities/topik.entity"; +import { AuditLog } from "./entities/auditLog.entity"; +import { DosenBimbingan } from "./entities/dosenBimbingan.entity"; +import { Kelas } from "./entities/kelas.entity"; +import { MahasiswaKelas } from "./entities/mahasiswaKelas"; +import { PengajarKelas } from "./entities/pengajarKelas.entity"; +import { PengajuanPengambilanTopik } from "./entities/pengajuanPengambilanTopik.entity"; +import { PengambilanTopik } from "./entities/pengambilanTopik.entity"; +import { RangeJadwalSidang } from "./entities/rangeJadwalSidang.entity"; +import { Ruangan } from "./entities/ruangan.entity"; +import { Sidang } from "./entities/sidang.entity"; +import { Tugas } from "./entities/tugas.entity"; +import { PembimbingSeminar } from "./entities/pembimbingSeminar.entity"; +import { PembimbingSidang } from "./entities/pembimbingSidang.entity"; +import { PengujiSidang } from "./entities/pengujiSidang.entity"; +import { RegistrasiTesisModule } from "./registrasi-tesis/registrasi-tesis.module"; +import { ConfigModule } from "@nestjs/config"; @Module({ imports: [ + ConfigModule.forRoot(), TypeOrmModule.forRoot({ - type: 'postgres', - host: 'localhost', - port: 5432, - username: 'ppl', - password: 'ppl', - database: 'ppl', + type: "postgres", + host: process.env.POSTGRES_HOST, + port: +process.env.POSTGRES_PORT || 5432, + username: process.env.POSTGRES_USER, + password: process.env.POSTGRES_PASSWORD, + database: process.env.POSTGRES_DATABASE, + ssl: process.env.POSTGRES_HOST !== "localhost", entities: [ Bimbingan, Pengguna, @@ -55,6 +59,7 @@ import { PengujiSidang } from './entities/pengujiSidang.entity'; // autoLoadEntities: true, synchronize: true, }), + RegistrasiTesisModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/app.service.ts b/src/app.service.ts index 927d7cca0badb13577152bf8753ce3552358f53b..b00a66790d79c0897f821f5d42a7fdfaacf99fca 100644 --- a/src/app.service.ts +++ b/src/app.service.ts @@ -1,8 +1,8 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable } from "@nestjs/common"; @Injectable() export class AppService { getHello(): string { - return 'Hello World!'; + return "Hello World!"; } } diff --git a/src/dto/registrasi-topik.ts b/src/dto/registrasi-topik.ts new file mode 100644 index 0000000000000000000000000000000000000000..3d0021750739795336deb7d08c75ee7d14f36141 --- /dev/null +++ b/src/dto/registrasi-topik.ts @@ -0,0 +1,7 @@ +export class RegistrasiTopikDto { + idMahasiswa: string; + idPembimbing: string; + judulTopik: string; + deskripsi: string; + jalurPilihan: string; +} diff --git a/src/entities/auditLog.entity.ts b/src/entities/auditLog.entity.ts index 8d70fbcadfec8fe2293d717633687b0a7c6dc1e2..c95d05a03fb11fb13d835bc1e6c64b22e107bff6 100644 --- a/src/entities/auditLog.entity.ts +++ b/src/entities/auditLog.entity.ts @@ -1,11 +1,11 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class AuditLog { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - pengguna: string; + pengguna: Pengguna; } diff --git a/src/entities/bimbingan.entity.ts b/src/entities/bimbingan.entity.ts index cfbd07fd2d31976247b16e388fd100306339a1cc..997e08193353a428c388ee21ee96a9c4ca146020 100644 --- a/src/entities/bimbingan.entity.ts +++ b/src/entities/bimbingan.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Topik } from './topik.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Topik } from "./topik.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class Bimbingan { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Topik, (topik) => topik.id) - topik: string; + topik: Topik; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + mahasiswa: Pengguna; } diff --git a/src/entities/dosenBimbingan.entity.ts b/src/entities/dosenBimbingan.entity.ts index 7019c26ebc0ae1249fdc83dcd16861356a6faaf6..50450bf3ad46f912b6b387944240e0d15a93c318 100644 --- a/src/entities/dosenBimbingan.entity.ts +++ b/src/entities/dosenBimbingan.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Bimbingan } from './bimbingan.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Bimbingan } from "./bimbingan.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class DosenBimbingan { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Bimbingan, (bimbingan) => bimbingan.id) - bimbingan: string; + bimbingan: Bimbingan; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - dosen: string; + dosen: Pengguna; } diff --git a/src/entities/kelas.entity.ts b/src/entities/kelas.entity.ts index 12e38eadd4652011b8eeae764d9ad193d06dc133..00fcfc4d8fa30479dd969a1bfeb629b6bb72bc78 100644 --- a/src/entities/kelas.entity.ts +++ b/src/entities/kelas.entity.ts @@ -1,7 +1,7 @@ -import { Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity() export class Kelas { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; } diff --git a/src/entities/mahasiswaKelas.ts b/src/entities/mahasiswaKelas.ts index 8f7b027b886da1918f8dfb25a2c4c23a24a5cb75..2c8422498639304cb86e2cb7f7eefacc3614b38d 100644 --- a/src/entities/mahasiswaKelas.ts +++ b/src/entities/mahasiswaKelas.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Kelas } from './kelas.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Kelas } from "./kelas.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class MahasiswaKelas { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Kelas, (kelas) => kelas.id) - kelas: string; + kelas: Kelas; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + mahasiswa: Pengguna; } diff --git a/src/entities/pembimbingSeminar.entity.ts b/src/entities/pembimbingSeminar.entity.ts index 7fc6c00062e55b8c86d711d9006d7c730032c038..024ebe5b57e6835441faa33d687137fb82565cbb 100644 --- a/src/entities/pembimbingSeminar.entity.ts +++ b/src/entities/pembimbingSeminar.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Seminar } from './seminar.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Seminar } from "./seminar.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class PembimbingSeminar { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Seminar, (seminar) => seminar.id) - seminar: string; + seminar: Seminar; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - dosen: string; + dosen: Pengguna; } diff --git a/src/entities/pembimbingSidang.entity.ts b/src/entities/pembimbingSidang.entity.ts index 495477a2c6172aacfa02a1516541b43edfbb146c..a3d9dbec55b4d3e94d7a1e6d8b14262b10752e3d 100644 --- a/src/entities/pembimbingSidang.entity.ts +++ b/src/entities/pembimbingSidang.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Sidang } from './sidang.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Sidang } from "./sidang.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class PembimbingSidang { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Sidang, (sidang) => sidang.id) - sidang: string; + sidang: Sidang; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - dosen: string; + dosen: Pengguna; } diff --git a/src/entities/pengajarKelas.entity.ts b/src/entities/pengajarKelas.entity.ts index dba4910c31b428953d466ae1cefaffbe5271c0b9..ad5b1351996cf9c2dba15bcd5aff65d270fa1e74 100644 --- a/src/entities/pengajarKelas.entity.ts +++ b/src/entities/pengajarKelas.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Kelas } from './kelas.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Kelas } from "./kelas.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class PengajarKelas { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Kelas, (kelas) => kelas.id) - kelas: string; + kelas: Kelas; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - dosen: string; + dosen: Pengguna; } diff --git a/src/entities/pengajuanPengambilanTopik.entity.ts b/src/entities/pengajuanPengambilanTopik.entity.ts index 0ef3d433c069dc8258e653ac9515b845aa84a673..01a193286188f877065398c2749e17e4937ee797 100644 --- a/src/entities/pengajuanPengambilanTopik.entity.ts +++ b/src/entities/pengajuanPengambilanTopik.entity.ts @@ -1,15 +1,42 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Topik } from './topik.entity'; -import { Pengguna } from './pengguna.entity'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Topik } from "./topik.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class PengajuanPengambilanTopik { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; + @Column({ nullable: true }) + disahkan: boolean; + + @Column({ nullable: true }) + deskripsi: string; + + @Column() + jalurPilihan: string; + + @Column({ type: "timestamptz" }) + waktuPengiriman: Date; + + @Column({ type: "timestamptz", nullable: true }) + waktuPersetujuan: Date; + + @Column({ type: "timestamptz", nullable: true }) + jadwalInterview: Date; + + @Column({ type: "timestamptz", nullable: true }) + waktuPengesahan: Date; + + @Column({ type: "timestamptz", nullable: true }) + waktuPenolakan: Date; + @ManyToOne(() => Topik, (topik) => topik.id) - topik: string; + topik: Topik; + + @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) + mahasiswa: Pengguna; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + pembimbing: Pengguna; } diff --git a/src/entities/pengambilanTopik.entity.ts b/src/entities/pengambilanTopik.entity.ts index 0529504e8c706778b8ecb2af2004bce5e7580955..6e933ed1214f0e1312076963fd7270719c5acb9c 100644 --- a/src/entities/pengambilanTopik.entity.ts +++ b/src/entities/pengambilanTopik.entity.ts @@ -1,15 +1,24 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Topik } from './topik.entity'; -import { Pengguna } from './pengguna.entity'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Topik } from "./topik.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class PengambilanTopik { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; + @Column() + deskripsi: string; + + @Column() + jalurPilihan: string; + @ManyToOne(() => Topik, (topik) => topik.id) - topik: string; + topik: Topik; + + @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) + mahasiswa: Pengguna; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + pembimbing: Pengguna; } diff --git a/src/entities/pengguna.entity.ts b/src/entities/pengguna.entity.ts index 2780da4aa8d5ea25207c0bcca4eaf6ffab7298b6..4ff51c2dcc29e2e6e0a30cf1aafd8e76303f910c 100644 --- a/src/entities/pengguna.entity.ts +++ b/src/entities/pengguna.entity.ts @@ -1,7 +1,19 @@ -import { Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity() export class Pengguna { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; + + @Column() + nama: string; + + @Column() + email: string; + + @Column() + status: string; + + @Column("simple-array") + roles: string[]; } diff --git a/src/entities/pengujiSidang.entity.ts b/src/entities/pengujiSidang.entity.ts index 70724b91d92e04c0de181155aa4537fe598ff0bf..dfcd36b5c2f5e06bebad302b3488aedff86338c7 100644 --- a/src/entities/pengujiSidang.entity.ts +++ b/src/entities/pengujiSidang.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Sidang } from './sidang.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Sidang } from "./sidang.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class PengujiSidang { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Sidang, (sidang) => sidang.id) - sidang: string; + sidang: Sidang; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - dosen: string; + dosen: Pengguna; } diff --git a/src/entities/rangeJadwalSeminar.entity.ts b/src/entities/rangeJadwalSeminar.entity.ts index 414914933524222443b1dbef7203ce46c6179dbf..fa16bf749d40cdfeff7253f61bc098063a7348a3 100644 --- a/src/entities/rangeJadwalSeminar.entity.ts +++ b/src/entities/rangeJadwalSeminar.entity.ts @@ -1,7 +1,7 @@ -import { Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity() export class RangeJadwalSeminar { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; } diff --git a/src/entities/rangeJadwalSidang.entity.ts b/src/entities/rangeJadwalSidang.entity.ts index dc890196f9c62297f4b75b99913de11b1413947e..6479aef875d9d7b23cd9db1c00317af5e60756cd 100644 --- a/src/entities/rangeJadwalSidang.entity.ts +++ b/src/entities/rangeJadwalSidang.entity.ts @@ -1,7 +1,7 @@ -import { Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity() export class RangeJadwalSidang { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; } diff --git a/src/entities/ruangan.entity.ts b/src/entities/ruangan.entity.ts index cb07a65669effdd5c7c1d014f4d85bd8a2fd086f..97df4c092f30bd329d8c3ece86d385bd0e6300c2 100644 --- a/src/entities/ruangan.entity.ts +++ b/src/entities/ruangan.entity.ts @@ -1,7 +1,7 @@ -import { Entity, PrimaryGeneratedColumn } from 'typeorm'; +import { Entity, PrimaryGeneratedColumn } from "typeorm"; @Entity() export class Ruangan { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; } diff --git a/src/entities/seminar.entity.ts b/src/entities/seminar.entity.ts index 9c04dd1b5ab33d53ce3d6f2dc5960a97987b91a8..7b0e30b783be1e1401448e73f5fd078f7d4cdd0c 100644 --- a/src/entities/seminar.entity.ts +++ b/src/entities/seminar.entity.ts @@ -1,22 +1,22 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Pengguna } from './pengguna.entity'; -import { RangeJadwalSeminar } from './rangeJadwalSeminar.entity'; -import { Ruangan } from './ruangan.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Pengguna } from "./pengguna.entity"; +import { RangeJadwalSeminar } from "./rangeJadwalSeminar.entity"; +import { Ruangan } from "./ruangan.entity"; @Entity() export class Seminar { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + mahasiswa: Pengguna; @ManyToOne( () => RangeJadwalSeminar, (rangeJadwalSeminar) => rangeJadwalSeminar.id, ) - rangeJadwal: string; + rangeJadwal: RangeJadwalSeminar; @ManyToOne(() => Ruangan, (ruangan) => ruangan.id) - ruangan: string; + ruangan: Ruangan; } diff --git a/src/entities/sidang.entity.ts b/src/entities/sidang.entity.ts index 2f276598b8f0f40f18fe1efb99127ad669875787..c2dc57ecdca72af17a7496883e74a716f46dbf1c 100644 --- a/src/entities/sidang.entity.ts +++ b/src/entities/sidang.entity.ts @@ -1,22 +1,22 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Pengguna } from './pengguna.entity'; -import { RangeJadwalSidang } from './rangeJadwalSidang.entity'; -import { Ruangan } from './ruangan.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Pengguna } from "./pengguna.entity"; +import { RangeJadwalSidang } from "./rangeJadwalSidang.entity"; +import { Ruangan } from "./ruangan.entity"; @Entity() export class Sidang { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + mahasiswa: Pengguna; @ManyToOne( () => RangeJadwalSidang, (rangeJadwalSidang) => rangeJadwalSidang.id, ) - rangeJadwal: string; + rangeJadwal: RangeJadwalSidang; @ManyToOne(() => Ruangan, (ruangan) => ruangan.id) - ruangan: string; + ruangan: Ruangan; } diff --git a/src/entities/topik.entity.ts b/src/entities/topik.entity.ts index c960bf0dcca418175befbc7ecdf141f684c3f058..e0da355499ef58e1592a7b2b2899d27201c7bb50 100644 --- a/src/entities/topik.entity.ts +++ b/src/entities/topik.entity.ts @@ -1,11 +1,14 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Pengguna } from './pengguna.entity'; +import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class Topik { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; + @Column() + judul: string; + @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - dosen: string; + dosen: Pengguna; } diff --git a/src/entities/tugas.entity.ts b/src/entities/tugas.entity.ts index 8fc9d111435235925916d30e1b54e95910c8669f..c445104cee8dbc1688e474e84031487e8d35f385 100644 --- a/src/entities/tugas.entity.ts +++ b/src/entities/tugas.entity.ts @@ -1,15 +1,15 @@ -import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Kelas } from './kelas.entity'; -import { Pengguna } from './pengguna.entity'; +import { Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; +import { Kelas } from "./kelas.entity"; +import { Pengguna } from "./pengguna.entity"; @Entity() export class Tugas { - @PrimaryGeneratedColumn('uuid') + @PrimaryGeneratedColumn("uuid") id: string; @ManyToOne(() => Kelas, (kelas) => kelas.id) - kelas: string; + kelas: Kelas; @ManyToOne(() => Pengguna, (pengguna) => pengguna.id) - mahasiswa: string; + mahasiswa: Pengguna; } diff --git a/src/helper/validation.ts b/src/helper/validation.ts new file mode 100644 index 0000000000000000000000000000000000000000..cfc65eb722c4859bd1569749bccb0e8785721b77 --- /dev/null +++ b/src/helper/validation.ts @@ -0,0 +1,17 @@ +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/main.ts b/src/main.ts index 13cad38cff92aa3b3d3ef6232306e450cadf5713..2553930747b4e0e2f52ff0a42f7f34ff44f0c407 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,11 @@ -import { NestFactory } from '@nestjs/core'; -import { AppModule } from './app.module'; +import { NestFactory } from "@nestjs/core"; +import { AppModule } from "./app.module"; async function bootstrap() { const app = await NestFactory.create(AppModule); + + app.enableCors(); + await app.listen(3000); } bootstrap(); diff --git a/src/registrasi-tesis/registrasi-tesis.controller.ts b/src/registrasi-tesis/registrasi-tesis.controller.ts new file mode 100644 index 0000000000000000000000000000000000000000..18284cfb10c4eb44e3f38a2adc6b352d90696472 --- /dev/null +++ b/src/registrasi-tesis/registrasi-tesis.controller.ts @@ -0,0 +1,27 @@ +import { Body, Controller, Post, Get, Param } from "@nestjs/common"; +import { RegistrasiTesisService } from "./registrasi-tesis.service"; +import { RegistrasiTopikDto } from "src/dto/registrasi-topik"; + +@Controller("registrasi-tesis") +export class RegistrasiTesisController { + constructor( + private readonly registrasiTesisService: RegistrasiTesisService, + ) {} + + // TODO: Protect using roles and guards + + @Get("/mahasiswa/:mahasiswaId") + findByUserId(@Param() params: { mahasiswaId: string }) { + return this.registrasiTesisService.findByUserId(params.mahasiswaId); + } + + @Post() + async createTopicRegistration( + @Body() topicRegistrationDto: RegistrasiTopikDto, + ) { + return this.registrasiTesisService.createTopicRegistration( + "ae9697b9-590f-4820-826b-948f5e746ca7", // TODO: Get user id from request, for now use generated UUID + topicRegistrationDto, + ); + } +} diff --git a/src/registrasi-tesis/registrasi-tesis.module.ts b/src/registrasi-tesis/registrasi-tesis.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..9b7a365ee001666b6b95db5168708a0b40bc9063 --- /dev/null +++ b/src/registrasi-tesis/registrasi-tesis.module.ts @@ -0,0 +1,22 @@ +import { Module } from "@nestjs/common"; +import { PengajuanPengambilanTopik } from "src/entities/pengajuanPengambilanTopik.entity"; +import { Pengguna } from "src/entities/pengguna.entity"; +import { DosenBimbingan } from "src/entities/dosenBimbingan.entity"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { RegistrasiTesisController } from "./registrasi-tesis.controller"; +import { RegistrasiTesisService } from "./registrasi-tesis.service"; +import { Topik } from "src/entities/topik.entity"; + +@Module({ + imports: [ + TypeOrmModule.forFeature([ + Pengguna, + DosenBimbingan, + PengajuanPengambilanTopik, + Topik, + ]), + ], + controllers: [RegistrasiTesisController], + providers: [RegistrasiTesisService], +}) +export class RegistrasiTesisModule {} diff --git a/src/registrasi-tesis/registrasi-tesis.service.ts b/src/registrasi-tesis/registrasi-tesis.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..39ca645e009b0ff800338d6303308b9234b1c6a1 --- /dev/null +++ b/src/registrasi-tesis/registrasi-tesis.service.ts @@ -0,0 +1,76 @@ +import { Injectable, NotFoundException } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; +import { PengajuanPengambilanTopik } from "src/entities/pengajuanPengambilanTopik.entity"; +import { RegistrasiTopikDto } from "src/dto/registrasi-topik"; +import { Pengguna } from "src/entities/pengguna.entity"; +import { validateId } from "src/helper/validation"; +import { Topik } from "src/entities/topik.entity"; + +@Injectable() +export class RegistrasiTesisService { + constructor( + @InjectRepository(PengajuanPengambilanTopik) + private pengajuanPengambilanTopikRepository: Repository<PengajuanPengambilanTopik>, + @InjectRepository(Pengguna) + private penggunaRepository: Repository<Pengguna>, + @InjectRepository(Topik) + private topicRepostitory: Repository<Topik>, + ) {} + + async createTopicRegistration( + userId: string, + topicRegistrationDto: RegistrasiTopikDto, + ): Promise<PengajuanPengambilanTopik> { + // TODO: Proper validations + + // Validate id + validateId([ + { id: userId, object: "Pengguna" }, + { id: topicRegistrationDto.idPembimbing, object: "Pembimbing" }, + ]); + + // Validate user id, supervisor id + const [user, supervisor, topic] = await Promise.all([ + this.penggunaRepository.findOne({ + where: { id: userId }, + }), + this.penggunaRepository.findOne({ + where: { id: topicRegistrationDto.idPembimbing }, + }), + this.topicRepostitory.findOne({ + where: { judul: topicRegistrationDto.judulTopik }, + }), + ]); + + 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."); + } + + // Create new registration + const createdRegistration = this.pengajuanPengambilanTopikRepository.create( + { + ...topicRegistrationDto, + waktuPengiriman: new Date(), + mahasiswa: user, + pembimbing: supervisor, + topik: topic, + }, + ); + + await this.pengajuanPengambilanTopikRepository.save(createdRegistration); + + return createdRegistration; + } + + async findByUserId(mahasiswaId: string) { + return await this.pengajuanPengambilanTopikRepository.find({ + relations: ["topik", "pembimbing"], + where: { mahasiswa: { id: mahasiswaId } }, + }); + } +} diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts deleted file mode 100644 index 50cda62332e9474925e819ff946358a9c40d1bf2..0000000000000000000000000000000000000000 --- a/test/app.e2e-spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; - -describe('AppController (e2e)', () => { - let app: INestApplication; - - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - }); - - it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); -}); diff --git a/test/jest-e2e.json b/test/jest-e2e.json deleted file mode 100644 index e9d912f3e3cefc18505d3cd19b3a5a9f567f5de0..0000000000000000000000000000000000000000 --- a/test/jest-e2e.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } -}