From 33072bf925f724abf9d0e5493917d1305ad9bf00 Mon Sep 17 00:00:00 2001 From: Lovel George <36924734+lovelgeorge99@users.noreply.github.com> Date: Wed, 5 Feb 2025 14:36:02 -0500 Subject: [PATCH 1/2] added inital models --- .env.example | 4 ++ package.json | 1 + .../migrations/20250205172850_/migration.sql | 16 +++++ .../20250205180025_user_entity/migration.sql | 10 +++ .../migration.sql | 68 +++++++++++++++++++ prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 53 +++++++++++++++ yarn.lock | 5 ++ 8 files changed, 160 insertions(+) create mode 100644 .env.example create mode 100644 prisma/migrations/20250205172850_/migration.sql create mode 100644 prisma/migrations/20250205180025_user_entity/migration.sql create mode 100644 prisma/migrations/20250205193050_initail_entities/migration.sql create mode 100644 prisma/migrations/migration_lock.toml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1eb1395 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +DATABASE_URL= + +MYSQL_DATABASE= +MYSQL_ROOT_PASSWORD= \ No newline at end of file diff --git a/package.json b/package.json index b104de5..550b75f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@nestjs/common": "^11.0.1", "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", + "@prisma/client": "^6.3.1", "prisma": "^6.3.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1" diff --git a/prisma/migrations/20250205172850_/migration.sql b/prisma/migrations/20250205172850_/migration.sql new file mode 100644 index 0000000..188c572 --- /dev/null +++ b/prisma/migrations/20250205172850_/migration.sql @@ -0,0 +1,16 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "worldId" TEXT NOT NULL, + "username" TEXT NOT NULL, + "name" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_worldId_key" ON "User"("worldId"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_username_key" ON "User"("username"); diff --git a/prisma/migrations/20250205180025_user_entity/migration.sql b/prisma/migrations/20250205180025_user_entity/migration.sql new file mode 100644 index 0000000..7c36730 --- /dev/null +++ b/prisma/migrations/20250205180025_user_entity/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `name` on the `User` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "User" DROP COLUMN "name", +ADD COLUMN "pollsCreatedCount" INTEGER NOT NULL DEFAULT 0, +ADD COLUMN "profilePicture" TEXT; diff --git a/prisma/migrations/20250205193050_initail_entities/migration.sql b/prisma/migrations/20250205193050_initail_entities/migration.sql new file mode 100644 index 0000000..a3a7399 --- /dev/null +++ b/prisma/migrations/20250205193050_initail_entities/migration.sql @@ -0,0 +1,68 @@ +-- CreateTable +CREATE TABLE "Poll" ( + "id" SERIAL NOT NULL, + "userId" INTEGER NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "startDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "endDate" TIMESTAMP(3) NOT NULL, + "isAnonymous" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "Poll_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Option" ( + "id" SERIAL NOT NULL, + "optionText" TEXT NOT NULL, + "pollId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Option_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Tag" ( + "id" SERIAL NOT NULL, + "content" TEXT, + + CONSTRAINT "Tag_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Vote" ( + "id" SERIAL NOT NULL, + "weight" INTEGER NOT NULL, + "optionId" INTEGER NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "proof" TEXT[], + + CONSTRAINT "Vote_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_PollToTag" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL, + + CONSTRAINT "_PollToTag_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE INDEX "_PollToTag_B_index" ON "_PollToTag"("B"); + +-- AddForeignKey +ALTER TABLE "Poll" ADD CONSTRAINT "Poll_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Option" ADD CONSTRAINT "Option_pollId_fkey" FOREIGN KEY ("pollId") REFERENCES "Poll"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Vote" ADD CONSTRAINT "Vote_optionId_fkey" FOREIGN KEY ("optionId") REFERENCES "Option"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PollToTag" ADD CONSTRAINT "_PollToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Poll"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PollToTag" ADD CONSTRAINT "_PollToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..648c57f --- /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 (e.g., Git) +provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ee282c7..0cdae82 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -12,3 +12,56 @@ datasource db { provider = "postgresql" url = env("DATABASE_URL") } + +model User{ + id Int @id @default(autoincrement()) + worldId String @unique() + username String @unique() + profilePicture String? + pollsCreatedCount Int @default(0) + createdAt DateTime @default(now()) + poll Poll[] + +} + + +model Poll{ + id Int @id @default(autoincrement()) + user User @relation(fields: [userId],references: [id]) + userId Int + title String + description String? + options Option[] + tags Tag[] + createdAt DateTime @default(now()) + startDate DateTime @default(now()) + endDate DateTime + isAnonymous Boolean @default(false) + +} + +model Option { + id Int @id @default(autoincrement()) + optionText String + poll Poll @relation(fields: [pollId], references: [id]) + pollId Int + votes Vote[] + createdAt DateTime @default(now()) +} + +model Tag{ + id Int @id @default(autoincrement()) + content String? + poll Poll[] + +} + + +model Vote{ + id Int @id @default(autoincrement()) + weight Int + option Option @relation(fields: [optionId], references: [id]) + optionId Int + createdAt DateTime @default(now()) + proof String[] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e1d15fc..24ccefa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1063,6 +1063,11 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@prisma/client@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.3.1.tgz#4e4b05b27f4541ea541a601c57a8ada10b526848" + integrity sha512-ARAJaPs+eBkemdky/XU3cvGRl+mIPHCN2lCXsl5Vlb0E2gV+R6IN7aCI8CisRGszEZondwIsW9Iz8EJkTdykyA== + "@prisma/debug@6.3.1": version "6.3.1" resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.3.1.tgz#08730461dab4fe147efa70637952b942dc1961b5" From 97f1649ecb05a8e47b51d5e4558906ff19968bf8 Mon Sep 17 00:00:00 2001 From: Lovel George <36924734+lovelgeorge99@users.noreply.github.com> Date: Tue, 11 Feb 2025 17:03:19 -0500 Subject: [PATCH 2/2] added users module --- package.json | 2 ++ prisma/schema.prisma | 1 - src/app.module.ts | 7 +++++-- src/prisma.service.ts | 11 +++++++++++ src/users/dtos/CreateUser.dto.ts | 15 +++++++++++++++ src/users/users.controller.ts | 20 ++++++++++++++++++++ src/users/users.module.ts | 12 ++++++++++++ src/users/users.service.ts | 13 +++++++++++++ yarn.lock | 29 +++++++++++++++++++++++++++++ 9 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/prisma.service.ts create mode 100644 src/users/dtos/CreateUser.dto.ts create mode 100644 src/users/users.controller.ts create mode 100644 src/users/users.module.ts create mode 100644 src/users/users.service.ts diff --git a/package.json b/package.json index 550b75f..71447b0 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ "@nestjs/core": "^11.0.1", "@nestjs/platform-express": "^11.0.1", "@prisma/client": "^6.3.1", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.1", "prisma": "^6.3.1", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0cdae82..e736fb4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -56,7 +56,6 @@ model Tag{ } - model Vote{ id Int @id @default(autoincrement()) weight Int diff --git a/src/app.module.ts b/src/app.module.ts index 8662803..02dfaa6 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,10 +1,13 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { UsersService } from './users/users.service'; +import { UsersController } from './users/users.controller'; +import { UsersModule } from './users/users.module'; @Module({ - imports: [], - controllers: [AppController], + imports: [UsersModule], + controllers: [AppController, UsersController], providers: [AppService], }) export class AppModule {} diff --git a/src/prisma.service.ts b/src/prisma.service.ts new file mode 100644 index 0000000..6b637a4 --- /dev/null +++ b/src/prisma.service.ts @@ -0,0 +1,11 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class PrismaService extends PrismaClient implements OnModuleInit { + async onModuleInit() { + await this.$connect() + .then(() => console.log('Connected to DB')) + .catch((err) => console.log(err)); + } +} diff --git a/src/users/dtos/CreateUser.dto.ts b/src/users/dtos/CreateUser.dto.ts new file mode 100644 index 0000000..7bc55a5 --- /dev/null +++ b/src/users/dtos/CreateUser.dto.ts @@ -0,0 +1,15 @@ +import { IsNotEmpty, IsOptional, IsString } from 'class-validator'; + +export class CreateUserDto { + @IsString() + @IsNotEmpty() + worldId: string; + + @IsString() + @IsNotEmpty() + username: string; + + @IsString() + @IsOptional() + profilePicture?: string; +} diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts new file mode 100644 index 0000000..11a988d --- /dev/null +++ b/src/users/users.controller.ts @@ -0,0 +1,20 @@ +import { + Body, + Controller, + Post, + UsePipes, + ValidationPipe, +} from '@nestjs/common'; +import { UsersService } from './users.service'; +import { CreateUserDto } from './dtos/CreateUser.dto'; + +@Controller('users') +export class UsersController { + constructor(private userService: UsersService) {} + + @Post() + @UsePipes(ValidationPipe) + async createUser(@Body() createUserDto: CreateUserDto) { + return await this.userService.createUser(createUserDto); + } +} diff --git a/src/users/users.module.ts b/src/users/users.module.ts new file mode 100644 index 0000000..9c2f057 --- /dev/null +++ b/src/users/users.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { PrismaService } from 'src/prisma.service'; +import { UsersController } from './users.controller'; +import { UsersService } from './users.service'; + +@Module({ + imports: [], + controllers: [UsersController], + providers: [UsersService, PrismaService], + exports: [UsersService], +}) +export class UsersModule {} diff --git a/src/users/users.service.ts b/src/users/users.service.ts new file mode 100644 index 0000000..b061a62 --- /dev/null +++ b/src/users/users.service.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@nestjs/common'; +import { Prisma } from '@prisma/client'; +import { PrismaService } from 'src/prisma.service'; + +@Injectable() +export class UsersService { + constructor(private prisma: PrismaService) {} + + async createUser(data: Prisma.UserCreateInput) { + console.log(data); + return this.prisma.user.create({ data }); + } +} diff --git a/yarn.lock b/yarn.lock index 24ccefa..ed67ed1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1471,6 +1471,11 @@ "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" +"@types/validator@^13.11.8": + version "13.12.2" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.2.tgz#760329e756e18a4aab82fc502b51ebdfebbe49f5" + integrity sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA== + "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" @@ -2283,6 +2288,20 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + +class-validator@^0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.1.tgz#ff2411ed8134e9d76acfeb14872884448be98110" + integrity sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ== + dependencies: + "@types/validator" "^13.11.8" + libphonenumber-js "^1.10.53" + validator "^13.9.0" + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -4092,6 +4111,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +libphonenumber-js@^1.10.53: + version "1.11.19" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.11.19.tgz#de6437b15d23d9e3b16e5b14c6f2d6d65f58c9b7" + integrity sha512-bW/Yp/9dod6fmyR+XqSUL1N5JE7QRxQ3KrBIbYS1FTv32e5i3SEtQVX+71CYNv8maWNSOgnlCoNp9X78f/cKiA== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -5586,6 +5610,11 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^2.0.0" +validator@^13.9.0: + version "13.12.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.12.0.tgz#7d78e76ba85504da3fee4fd1922b385914d4b35f" + integrity sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"