diff --git a/.env b/.env new file mode 100644 index 0000000..09d3c10 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +DATABASE_URL="mysql://root:ysxgdil0@35.195.248.72:3306/manager" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 064867a..8a83fc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,10 @@ "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", + "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^10.0.0", + "@prisma/client": "^5.8.0", + "dotenv": "^16.3.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1" }, @@ -30,6 +33,7 @@ "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "3.2.2", + "prisma": "^5.8.0", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", @@ -1784,6 +1788,25 @@ } } }, + "node_modules/@nestjs/mapped-types": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.4.tgz", + "integrity": "sha512-xl+gUSp0B+ln1VSNoUftlglk8dfpUes3DHGxKZ5knuBxS5g2H/8p9/DSBOYWUfO5f4u9s6ffBPZ71WO+tbe5SA==", + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/platform-express": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.3.0.tgz", @@ -1921,6 +1944,68 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@prisma/client": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.8.0.tgz", + "integrity": "sha512-QxO6C4MaA/ysTIbC+EcAH1aX/YkpymhXtO6zPdk+FvA7+59tNibIYpd+7koPdViLg2iKES4ojsxWNUGNJaEcbA==", + "hasInstallScript": true, + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.8.0.tgz", + "integrity": "sha512-ZqPpkvbovu/kQJ1bvy57NO4dw97fpQGcbQSCtsqlwSE1UNKJP75R3BKxdznk8ZPMY+GJdMRetWNv4oAvSbWn8Q==", + "devOptional": true + }, + "node_modules/@prisma/engines": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.8.0.tgz", + "integrity": "sha512-Qhqm9WWLujNEC13AuZlUO14SQ15tNLe5puaz+tOk7UqINqJ3PtqMmuSuzomiw2diGVqZ+HYiSQzlR3+pPucVHA==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/debug": "5.8.0", + "@prisma/engines-version": "5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848", + "@prisma/fetch-engine": "5.8.0", + "@prisma/get-platform": "5.8.0" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848.tgz", + "integrity": "sha512-cXcoVweYbnv8xRfkWq9oj8BECOdzHUazrSpYCa0ehp5TNz4l5Spa8jbq/VROCTzj3ZncH5D9Q2TmySYTOUeKlw==", + "devOptional": true + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.8.0.tgz", + "integrity": "sha512-1CAuE+JoYsPNggMEn6qk0zos06Uc9bYZBJ0VBPHD6R7REL05614koAbOCmn52IaYz3nobb7f25hqW6AY7rLkIw==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.8.0", + "@prisma/engines-version": "5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848", + "@prisma/get-platform": "5.8.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.8.0.tgz", + "integrity": "sha512-Nk3rhTFZ1LYkFZJnpSvQcLPCaBWgJQfteHII6UEENOOkYlmP0k3FuswND54tzzEr4qs39wOdV9pbXKX9U2lv7A==", + "devOptional": true, + "dependencies": { + "@prisma/debug": "5.8.0" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -3762,6 +3847,17 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -6902,6 +6998,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/prisma": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.8.0.tgz", + "integrity": "sha512-hDKoEqPt2qEUTH5yGO3l27CBnPtwvte0CGMKrpCr9+/A919JghfqJ3qgCGgMbOwdkXUOzdho0RH9tyUF3UhpMw==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "5.8.0" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", diff --git a/package.json b/package.json index 9584fed..8dbe3cb 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,10 @@ "dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/core": "^10.0.0", + "@nestjs/mapped-types": "*", "@nestjs/platform-express": "^10.0.0", + "@prisma/client": "^5.8.0", + "dotenv": "^16.3.1", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1" }, @@ -41,6 +44,7 @@ "eslint-plugin-prettier": "^5.0.0", "jest": "^29.5.0", "prettier": "3.2.2", + "prisma": "^5.8.0", "source-map-support": "^0.5.21", "supertest": "^6.3.3", "ts-jest": "^29.1.0", diff --git a/prisma/migrations/20240114145643_init/migration.sql b/prisma/migrations/20240114145643_init/migration.sql new file mode 100644 index 0000000..0025a34 --- /dev/null +++ b/prisma/migrations/20240114145643_init/migration.sql @@ -0,0 +1,23 @@ +-- CreateTable +CREATE TABLE `User` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `email` VARCHAR(191) NOT NULL, + `name` VARCHAR(191) NULL, + + UNIQUE INDEX `User_email_key`(`email`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Post` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `title` VARCHAR(191) NOT NULL, + `content` VARCHAR(191) NULL, + `published` BOOLEAN NOT NULL DEFAULT false, + `authorId` INTEGER NOT NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `Post` ADD CONSTRAINT `Post_authorId_fkey` FOREIGN KEY (`authorId`) REFERENCES `User`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/20240114164022_task/migration.sql b/prisma/migrations/20240114164022_task/migration.sql new file mode 100644 index 0000000..cf9f9f6 --- /dev/null +++ b/prisma/migrations/20240114164022_task/migration.sql @@ -0,0 +1,84 @@ +/* + Warnings: + + - You are about to drop the `Post` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `User` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropForeignKey +ALTER TABLE `Post` DROP FOREIGN KEY `Post_authorId_fkey`; + +-- DropTable +DROP TABLE `Post`; + +-- DropTable +DROP TABLE `User`; + +-- CreateTable +CREATE TABLE `Employee` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `username` VARCHAR(191) NOT NULL, + `email` VARCHAR(191) NOT NULL, + + UNIQUE INDEX `Employee_email_key`(`email`), + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Team` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `name` VARCHAR(191) NOT NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `EmployeeOnTeams` ( + `teamId` INTEGER NOT NULL, + `employeeId` INTEGER NOT NULL, + + PRIMARY KEY (`teamId`, `employeeId`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Project` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `name` VARCHAR(191) NOT NULL, + `description` VARCHAR(191) NULL, + `teamId` INTEGER NOT NULL, + `employeeId` INTEGER NOT NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- CreateTable +CREATE TABLE `Task` ( + `id` INTEGER NOT NULL AUTO_INCREMENT, + `title` VARCHAR(191) NOT NULL, + `description` VARCHAR(191) NULL, + `completed` BOOLEAN NOT NULL DEFAULT false, + `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), + `updatedAt` DATETIME(3) NOT NULL, + `userId` INTEGER NOT NULL, + `projectId` INTEGER NULL, + + PRIMARY KEY (`id`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- AddForeignKey +ALTER TABLE `EmployeeOnTeams` ADD CONSTRAINT `EmployeeOnTeams_teamId_fkey` FOREIGN KEY (`teamId`) REFERENCES `Team`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `EmployeeOnTeams` ADD CONSTRAINT `EmployeeOnTeams_employeeId_fkey` FOREIGN KEY (`employeeId`) REFERENCES `Employee`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Project` ADD CONSTRAINT `Project_teamId_fkey` FOREIGN KEY (`teamId`) REFERENCES `Team`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Project` ADD CONSTRAINT `Project_employeeId_fkey` FOREIGN KEY (`employeeId`) REFERENCES `Employee`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Task` ADD CONSTRAINT `Task_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `Employee`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE `Task` ADD CONSTRAINT `Task_projectId_fkey` FOREIGN KEY (`projectId`) REFERENCES `Project`(`id`) ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..e5a788a --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "mysql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..5860ae4 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,62 @@ + +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "mysql" + url = env("DATABASE_URL") +} + + +model Employee { + id Int @id @default(autoincrement()) + username String + email String @unique + teams EmployeeOnTeams[] + tasks Task[] + projects Project[] +} + +model Team { + id Int @id @default(autoincrement()) + name String + members EmployeeOnTeams[] + projects Project[] +} + +model EmployeeOnTeams { + teamId Int + employeeId Int + team Team @relation(fields: [teamId], references: [id]) + employee Employee @relation(fields: [employeeId], references: [id]) + + @@id([teamId, employeeId]) +} + +model Project { + id Int @id @default(autoincrement()) + name String + description String? + tasks Task[] + teamId Int + employeeId Int + team Team @relation(fields: [teamId], references: [id]) + employee Employee @relation(fields: [employeeId], references: [id]) +} + +model Task { + id Int @id @default(autoincrement()) + title String + description String? + completed Boolean @default(false) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + userId Int + employee Employee @relation(fields: [userId], references: [id]) + projectId Int? + project Project? @relation(fields: [projectId], references: [id]) +} + + + diff --git a/src/app.module.ts b/src/app.module.ts index 8662803..da7ef1f 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,9 +1,12 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { DatabaseModule } from './database/database.module'; +import { EmployeeModule } from './employee/employee.module'; + @Module({ - imports: [], + imports: [DatabaseModule, EmployeeModule], controllers: [AppController], providers: [AppService], }) diff --git a/src/app.service.ts b/src/app.service.ts index c1f8be1..483cbd0 100644 --- a/src/app.service.ts +++ b/src/app.service.ts @@ -1,8 +1,10 @@ import { Injectable } from '@nestjs/common'; + @Injectable() export class AppService { getHello(): string { - return 'This text should be changed on push!'; + return 'Code must be resfsf'; + } } diff --git a/src/database/database.module.ts b/src/database/database.module.ts new file mode 100644 index 0000000..7d713b0 --- /dev/null +++ b/src/database/database.module.ts @@ -0,0 +1,9 @@ +import { Global, Module } from '@nestjs/common'; +import { DatabaseService } from './database.service'; + +@Global() +@Module({ + providers: [DatabaseService], + exports:[DatabaseService] +}) +export class DatabaseModule {} diff --git a/src/database/database.service.spec.ts b/src/database/database.service.spec.ts new file mode 100644 index 0000000..b806f31 --- /dev/null +++ b/src/database/database.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { DatabaseService } from './database.service'; + +describe('DatabaseService', () => { + let service: DatabaseService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [DatabaseService], + }).compile(); + + service = module.get(DatabaseService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/database/database.service.ts b/src/database/database.service.ts new file mode 100644 index 0000000..7d07e8b --- /dev/null +++ b/src/database/database.service.ts @@ -0,0 +1,9 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class DatabaseService extends PrismaClient implements OnModuleInit { + async onModuleInit() { + this.$connect() + } +} diff --git a/src/employee/employee.controller.ts b/src/employee/employee.controller.ts new file mode 100644 index 0000000..c155d2a --- /dev/null +++ b/src/employee/employee.controller.ts @@ -0,0 +1,33 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { EmployeeService } from './employee.service'; +import { Prisma } from '@prisma/client'; + +@Controller('employee') +export class EmployeeController { + constructor(private readonly employeeService: EmployeeService) {} + + @Post() + create(@Body() createEmployeeDto: Prisma.EmployeeCreateInput) { + return this.employeeService.create(createEmployeeDto); + } + + @Get() + findAll() { + return this.employeeService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.employeeService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateEmployeeDto: Prisma.EmployeeUpdateInput) { + return this.employeeService.update(+id, updateEmployeeDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.employeeService.remove(+id); + } +} diff --git a/src/employee/employee.module.ts b/src/employee/employee.module.ts new file mode 100644 index 0000000..6c5b6be --- /dev/null +++ b/src/employee/employee.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { EmployeeService } from './employee.service'; +import { EmployeeController } from './employee.controller'; + +@Module({ + controllers: [EmployeeController], + providers: [EmployeeService], +}) +export class EmployeeModule {} diff --git a/src/employee/employee.service.ts b/src/employee/employee.service.ts new file mode 100644 index 0000000..250062c --- /dev/null +++ b/src/employee/employee.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@nestjs/common' +import { Prisma } from '@prisma/client' +import { DatabaseService } from 'src/database/database.service' + +@Injectable() +export class EmployeeService { + constructor(private readonly databaseService: DatabaseService) {} + + async create(createEmployeeDto: Prisma.EmployeeCreateInput) { + return this.databaseService.employee.create({ data: createEmployeeDto }) + } + + findAll() { + return this.databaseService.employee.findMany() + } + + findOne(id: number) { + return this.databaseService.employee.findUnique({ where: { id } }) + } + + update(id: number, updateEmployeeDto: Prisma.EmployeeUpdateInput) { + return `This action updates a #${id} employee` + } + + remove(id: number) { + return `This action removes a #${id} employee` + } +} diff --git a/src/main.ts b/src/main.ts index cb6efb7..0731216 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,7 +3,7 @@ import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); - console.log(`--- app is listening on ${process.env.PORT}`) - await app.listen(process.env.PORT); + console.log(`--- app is listening oooon ${process.env.PORT}`) + await app.listen(process.env.PORT ?? 3000); } bootstrap();