diff --git a/apps/backend/apps/backend/src/api/auth/auth.controller.ts b/apps/backend/apps/backend/src/api/auth/auth.controller.ts index dcfc0e8..38d4faf 100644 --- a/apps/backend/apps/backend/src/api/auth/auth.controller.ts +++ b/apps/backend/apps/backend/src/api/auth/auth.controller.ts @@ -10,10 +10,9 @@ import { } from '@nestjs/common'; import { AuthService } from './auth.service'; import { AuthGuard } from '@nestjs/passport'; -import { SignUpDto } from './dto/signup.dto'; -import { SignInDto } from './dto/signin.dto'; import { Public } from 'libs/custom.decorator/custom.decorator'; import RetrieveInfoFromRequest from 'libs/handlers/retriveInfoFromRequest.global'; +import { SignUpDto, SignInDto } from 'libs/types'; @Controller('auth') export class AuthController { diff --git a/apps/backend/apps/backend/src/api/auth/auth.service.ts b/apps/backend/apps/backend/src/api/auth/auth.service.ts index 8d19848..8c76643 100644 --- a/apps/backend/apps/backend/src/api/auth/auth.service.ts +++ b/apps/backend/apps/backend/src/api/auth/auth.service.ts @@ -10,12 +10,11 @@ import { JwtService } from '@nestjs/jwt'; import Redis from 'ioredis'; import * as bcrypt from 'bcrypt'; import { randomBytes } from 'crypto'; -import { SignUpDto } from './dto/signup.dto'; -import { SignInDto } from './dto/signin.dto'; import sendEmail from 'libs/handlers/email.global'; import handleErrors from 'libs/handlers/handleErrors.global'; import RetrieveInfoFromRequest from 'libs/handlers/retriveInfoFromRequest.global'; import { PrismaService } from 'libs/prisma/prisma.service'; +import { SignUpDto, SignInDto } from 'libs/types'; @Injectable() export class AuthService { diff --git a/apps/backend/apps/backend/src/api/user/book.controller.ts b/apps/backend/apps/backend/src/api/user/book.controller.ts index 402bc5d..2825f89 100644 --- a/apps/backend/apps/backend/src/api/user/book.controller.ts +++ b/apps/backend/apps/backend/src/api/user/book.controller.ts @@ -11,10 +11,8 @@ import { } from '@nestjs/common'; import { UserService } from './book.service'; import { AuthGuard } from '@nestjs/passport'; -import { BookDto } from './dto/book.dto'; -import { SectionDto } from './dto/section.dto'; -import { NoteDto } from './dto/note.dto'; import { Public } from 'libs/custom.decorator/custom.decorator'; +import { BookDto, SectionDto, NoteDto } from 'libs/types'; @Controller('user') export class UserController { diff --git a/apps/backend/apps/backend/src/api/user/book.service.ts b/apps/backend/apps/backend/src/api/user/book.service.ts index c87970a..d665466 100644 --- a/apps/backend/apps/backend/src/api/user/book.service.ts +++ b/apps/backend/apps/backend/src/api/user/book.service.ts @@ -1,9 +1,7 @@ import { Injectable } from '@nestjs/common'; -import { BookDto } from './dto/book.dto'; -import { SectionDto } from './dto/section.dto'; -import { NoteDto } from './dto/note.dto'; import RetrieveInfoFromRequest from 'libs/handlers/retriveInfoFromRequest.global'; import { PrismaService } from 'libs/prisma/prisma.service'; +import { BookDto, SectionDto, NoteDto } from 'libs/types'; @Injectable() export class UserService { @@ -90,17 +88,18 @@ export class UserService { throw new Error('Section not found'); } - return await this.prisma.note.create({ - data: { - // TODO save content - // content: note.content, - section: { - connect: { - id: sectionId, - }, - }, - }, - }); + // return await this.prisma.note.create({ + // data: { + // // TODO save content + // // content: note.content, + // section: { + // connect: { + // id: sectionId, + // }, + // }, + // }, + // }); + return 'TODO'; } async getBooks(request: any) { diff --git a/apps/backend/apps/backend/src/api/user/dto/note.dto.ts b/apps/backend/apps/backend/src/api/user/dto/note.dto.ts deleted file mode 100644 index 10383b8..0000000 --- a/apps/backend/apps/backend/src/api/user/dto/note.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IsString, IsNotEmpty } from 'class-validator'; - -export class NoteDto { - @IsString() - @IsNotEmpty() - content: string; -} diff --git a/apps/backend/apps/content_mgmt/src/content_mgmt.module.ts b/apps/backend/apps/content_mgmt/src/content_mgmt.module.ts index 7f45151..3b420ef 100644 --- a/apps/backend/apps/content_mgmt/src/content_mgmt.module.ts +++ b/apps/backend/apps/content_mgmt/src/content_mgmt.module.ts @@ -1,10 +1,13 @@ import { Module } from '@nestjs/common'; import { ContentMgmtController } from './content_mgmt.controller'; import { ContentMgmtService } from './content_mgmt.service'; +import { PrismaModule } from 'libs/prisma/prisma.module'; +import { EditorModule } from './editor/editor.module'; +import { EditorService } from './editor/editor.service'; @Module({ - imports: [], - controllers: [ContentMgmtController], - providers: [ContentMgmtService], + imports: [PrismaModule], + controllers: [ContentMgmtController, EditorModule], + providers: [ContentMgmtService, EditorService], }) export class ContentMgmtModule {} diff --git a/apps/backend/apps/content_mgmt/src/editor/editor.controller.ts b/apps/backend/apps/content_mgmt/src/editor/editor.controller.ts new file mode 100644 index 0000000..e4d2133 --- /dev/null +++ b/apps/backend/apps/content_mgmt/src/editor/editor.controller.ts @@ -0,0 +1,70 @@ +import { + Controller, + Get, + Post, + Body, + Param, + Patch, + Delete, +} from '@nestjs/common'; +import { EditorService } from './editor.service'; +import { + CreateBlockDto, + CreateNoteDto, + UpdateBlockDto, + UpdateNoteDto, +} from 'libs/types'; + +@Controller('editor') +export class EditorController { + constructor(private readonly editorService: EditorService) {} + + // POST /api/documents - Create a new document + @Post('note/new') + createDocument(@Body() createDocumentDto: CreateNoteDto) { + return this.editorService.createDocument(createDocumentDto); + } + + // GET /api/documents/:id - Retrieve a document + @Get('note/:id') + getDocument(@Param('id') id: string) { + return this.editorService.getDocument(id); + } + + // PATCH /api/documents/:id - Update a document + @Patch('note/:id') + updateDocument( + @Param('id') id: string, + @Body() updateDocumentDto: UpdateNoteDto, + ) { + return this.editorService.updateDocument(id, updateDocumentDto); + } + + // DELETE /api/documents/:id - Delete a document + @Delete('note/:id') + deleteDocument(@Param('id') id: string) { + return this.editorService.deleteDocument(id); + } + + // POST /api/documents/:id/blocks - Add a new block to a document + @Post('note/:id/block/new') + addBlock(@Param('id') id: string, @Body() createBlockDto: CreateBlockDto) { + return this.editorService.addBlock(id, createBlockDto); + } + + // PATCH /api/documents/:id/blocks/:blockId - Update a block + @Patch('note/:id/block/:blockId') + updateBlock( + @Param('id') id: string, + @Param('blockId') blockId: string, + @Body() updateBlockDto: UpdateBlockDto, + ) { + return this.editorService.updateBlock(id, blockId, updateBlockDto); + } + + // DELETE /api/documents/:id/blocks/:blockId - Delete a block + @Delete('note/:id/block/:blockId') + deleteBlock(@Param('id') id: string, @Param('blockId') blockId: string) { + return this.editorService.deleteBlock(id, blockId); + } +} diff --git a/apps/backend/apps/content_mgmt/src/editor/editor.module.ts b/apps/backend/apps/content_mgmt/src/editor/editor.module.ts new file mode 100644 index 0000000..381e49a --- /dev/null +++ b/apps/backend/apps/content_mgmt/src/editor/editor.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { EditorController } from './editor.controller'; +import { PrismaService } from 'libs/prisma/prisma.service'; +import { EditorService } from './editor.service'; + +@Module({ + controllers: [EditorController], + providers: [EditorService, PrismaService], +}) +export class EditorModule {} diff --git a/apps/backend/apps/content_mgmt/src/editor/editor.service.ts b/apps/backend/apps/content_mgmt/src/editor/editor.service.ts new file mode 100644 index 0000000..19be563 --- /dev/null +++ b/apps/backend/apps/content_mgmt/src/editor/editor.service.ts @@ -0,0 +1,99 @@ +import { Injectable, NotFoundException } from '@nestjs/common'; +import { PrismaService } from 'libs/prisma/prisma.service'; +import { + CreateBlockDto, + CreateNoteDto, + UpdateBlockDto, + UpdateNoteDto, +} from 'libs/types'; + +@Injectable() +export class EditorService { + constructor(private readonly prisma: PrismaService) {} + + async createDocument(createDocumentDto: CreateNoteDto) { + return `TODO ${createDocumentDto}`; + // return this.prisma.note.create({ + // data: { + // title: createDocumentDto.title, + // blocks: { + // create: createDocumentDto.blocks, + // }, + // }, + // }); + } + + async getDocument(id: string) { + const document = await this.prisma.note.findUnique({ + where: { id }, + include: { blocks: true }, + }); + if (!document) { + throw new NotFoundException(`Document with ID "${id}" not found`); + } + return document; + } + + async updateDocument(id: string, DocumentDto: UpdateNoteDto) { + const document = await this.getDocument(id); + return `TODO ${document} ${DocumentDto}`; + // return this.prisma.note.update({ + // where: { id }, + // data: { + // title: DocumentDto.title ?? document.title, + // blocks: { + // update: DocumentDto.blocks, + // }, + // }, + // }); + } + + async deleteDocument(id: string) { + const result = await this.prisma.note.delete({ + where: { id }, + }); + if (!result) { + throw new NotFoundException(`Document with ID "${id}" not found`); + } + } + + async addBlock(id: string, createBlockDto: CreateBlockDto) { + return `TODO ${id} ${createBlockDto}`; + // return this.prisma.block.create({ + // data: { + // ...createBlockDto, + // id: id, + // }, + // }); + } + + async updateBlock( + id: string, + blockId: string, + updateBlockDto: UpdateBlockDto, + ) { + const document = await this.getDocument(id); + const block = document.blocks.find((b) => b.id === blockId); + if (!block) { + throw new NotFoundException( + `Block with ID "${blockId}" not found in document "${id}"`, + ); + } + // return this.prisma.block.update({ + // where: { id: blockId }, + // data: updateBlockDto, + // }); + return `TODO ${updateBlockDto}`; + } + + async deleteBlock(id: string, blockId: string) { + const document = await this.getDocument(id); + const block = document.blocks.find((b) => b.id === blockId); + if (!block) { + throw new NotFoundException( + `Block with ID "${blockId}" not found in document "${id}"`, + ); + } + await this.prisma.block.delete({ where: { id: blockId } }); + } +} diff --git a/apps/backend/apps/backend/src/api/auth/dto/signin.dto.ts b/apps/backend/libs/types/auth/login.user.dto.ts similarity index 100% rename from apps/backend/apps/backend/src/api/auth/dto/signin.dto.ts rename to apps/backend/libs/types/auth/login.user.dto.ts diff --git a/apps/backend/apps/backend/src/api/auth/dto/signup.dto.ts b/apps/backend/libs/types/auth/signup.user.dto.ts similarity index 100% rename from apps/backend/apps/backend/src/api/auth/dto/signup.dto.ts rename to apps/backend/libs/types/auth/signup.user.dto.ts diff --git a/apps/backend/libs/types/editor/block-type.enum.ts b/apps/backend/libs/types/editor/block-type.enum.ts new file mode 100644 index 0000000..18c09f3 --- /dev/null +++ b/apps/backend/libs/types/editor/block-type.enum.ts @@ -0,0 +1,6 @@ +export enum BlockTypeEnum { + TEXT = 'TEXT', + IMAGE = 'IMAGE', + LINK = 'LINK', + INTERNAL_LINK = 'INTERNAL_LINK', +} diff --git a/apps/backend/libs/types/editor/block.dto.ts b/apps/backend/libs/types/editor/block.dto.ts new file mode 100644 index 0000000..2eff7ac --- /dev/null +++ b/apps/backend/libs/types/editor/block.dto.ts @@ -0,0 +1,26 @@ +import { IsDate, IsEnum, IsNotEmpty, IsString } from 'class-validator'; +import { BlockTypeEnum } from './block-type.enum'; + +export class BlockDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + noteId: string; + + @IsEnum(BlockTypeEnum) + @IsNotEmpty() + type: BlockTypeEnum; + + @IsString() + @IsNotEmpty() + content: string; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/libs/types/editor/book.dto.ts b/apps/backend/libs/types/editor/book.dto.ts new file mode 100644 index 0000000..61467af --- /dev/null +++ b/apps/backend/libs/types/editor/book.dto.ts @@ -0,0 +1,27 @@ +import { IsDate, IsNotEmpty, IsString, ValidateNested } from 'class-validator'; +import { Type } from 'class-transformer'; +import { SectionDto } from './section.dto'; + +export class BookDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + title: string; + + @IsString() + @IsNotEmpty() + userId: string; + + @ValidateNested({ each: true }) + @Type(() => SectionDto) + sections: SectionDto[]; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/libs/types/editor/create.block.ts b/apps/backend/libs/types/editor/create.block.ts new file mode 100644 index 0000000..86663df --- /dev/null +++ b/apps/backend/libs/types/editor/create.block.ts @@ -0,0 +1,16 @@ +import { IsEnum, IsNotEmpty, IsString } from 'class-validator'; +import { BlockTypeEnum } from './block-type.enum'; + +export class CreateBlockDto { + @IsString() + @IsNotEmpty() + noteId: string; + + @IsEnum(BlockTypeEnum) + @IsNotEmpty() + type: BlockTypeEnum; + + @IsString() + @IsNotEmpty() + content: string; +} diff --git a/apps/backend/apps/backend/src/api/user/dto/book.dto.ts b/apps/backend/libs/types/editor/create.book.dto.ts similarity index 57% rename from apps/backend/apps/backend/src/api/user/dto/book.dto.ts rename to apps/backend/libs/types/editor/create.book.dto.ts index af0f4fa..84ca6e6 100644 --- a/apps/backend/apps/backend/src/api/user/dto/book.dto.ts +++ b/apps/backend/libs/types/editor/create.book.dto.ts @@ -1,7 +1,11 @@ import { IsNotEmpty, IsString } from 'class-validator'; -export class BookDto { +export class CreateBookDto { @IsString() @IsNotEmpty() title: string; + + @IsString() + @IsNotEmpty() + userId: string; } diff --git a/apps/backend/libs/types/editor/create.note.dto.ts b/apps/backend/libs/types/editor/create.note.dto.ts new file mode 100644 index 0000000..a422884 --- /dev/null +++ b/apps/backend/libs/types/editor/create.note.dto.ts @@ -0,0 +1,17 @@ +import { IsNotEmpty, IsString, ValidateNested } from 'class-validator'; +import { Type } from 'class-transformer'; +import { CreateBlockDto } from './create.block'; + +export class CreateNoteDto { + @IsString() + @IsNotEmpty() + title: string; + + @IsString() + @IsNotEmpty() + sectionId: string; + + @ValidateNested({ each: true }) + @Type(() => CreateBlockDto) + blocks: CreateBlockDto[]; +} diff --git a/apps/backend/apps/backend/src/api/user/dto/section.dto.ts b/apps/backend/libs/types/editor/create.section.dto.ts similarity index 56% rename from apps/backend/apps/backend/src/api/user/dto/section.dto.ts rename to apps/backend/libs/types/editor/create.section.dto.ts index 803b0be..7331e71 100644 --- a/apps/backend/apps/backend/src/api/user/dto/section.dto.ts +++ b/apps/backend/libs/types/editor/create.section.dto.ts @@ -1,7 +1,11 @@ import { IsNotEmpty, IsString } from 'class-validator'; -export class SectionDto { +export class CreateSectionDto { @IsString() @IsNotEmpty() title: string; + + @IsString() + @IsNotEmpty() + bookId: string; } diff --git a/apps/backend/libs/types/editor/note.dto.ts b/apps/backend/libs/types/editor/note.dto.ts new file mode 100644 index 0000000..50d1621 --- /dev/null +++ b/apps/backend/libs/types/editor/note.dto.ts @@ -0,0 +1,27 @@ +import { IsDate, IsNotEmpty, IsString, ValidateNested } from 'class-validator'; +import { Type } from 'class-transformer'; +import { BlockDto } from './block.dto'; + +export class NoteDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + title: string; + + @IsString() + @IsNotEmpty() + sectionId: string; + + @ValidateNested({ each: true }) + @Type(() => BlockDto) + blocks: BlockDto[]; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/libs/types/editor/section.dto.ts b/apps/backend/libs/types/editor/section.dto.ts new file mode 100644 index 0000000..cfb6fdb --- /dev/null +++ b/apps/backend/libs/types/editor/section.dto.ts @@ -0,0 +1,27 @@ +import { IsDate, IsNotEmpty, IsString, ValidateNested } from 'class-validator'; +import { Type } from 'class-transformer'; +import { NoteDto } from './note.dto'; + +export class SectionDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + title: string; + + @IsString() + @IsNotEmpty() + bookId: string; + + @ValidateNested({ each: true }) + @Type(() => NoteDto) + notes: NoteDto[]; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/libs/types/editor/update.block.dto.ts b/apps/backend/libs/types/editor/update.block.dto.ts new file mode 100644 index 0000000..b82e145 --- /dev/null +++ b/apps/backend/libs/types/editor/update.block.dto.ts @@ -0,0 +1,20 @@ +import { IsEnum, IsNotEmpty, IsString } from 'class-validator'; +import { BlockTypeEnum } from './block-type.enum'; + +export class UpdateBlockDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + noteId: string; + + @IsEnum(BlockTypeEnum) + @IsNotEmpty() + type: BlockTypeEnum; + + @IsString() + @IsNotEmpty() + content: string; +} diff --git a/apps/backend/libs/types/editor/update.note.dto.ts b/apps/backend/libs/types/editor/update.note.dto.ts new file mode 100644 index 0000000..c7e611f --- /dev/null +++ b/apps/backend/libs/types/editor/update.note.dto.ts @@ -0,0 +1,21 @@ +import { IsDate, IsNotEmpty, IsString, ValidateNested } from 'class-validator'; +import { Type } from 'class-transformer'; +import { BlockDto } from './block.dto'; + +export class UpdateNoteDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + title: string; + + @IsString() + @IsNotEmpty() + sectionId: string; + + @ValidateNested({ each: true }) + @Type(() => BlockDto) + blocks: BlockDto[]; +} diff --git a/apps/backend/libs/types/index.ts b/apps/backend/libs/types/index.ts new file mode 100644 index 0000000..c6657aa --- /dev/null +++ b/apps/backend/libs/types/index.ts @@ -0,0 +1,22 @@ +// Auth +export * from './auth/login.user.dto'; +export * from './auth/signup.user.dto'; + +// Editor +export * from './editor/block-type.enum'; +export * from './editor/block.dto'; +export * from './editor/book.dto'; +export * from './editor/create.block'; +export * from './editor/create.book.dto'; +export * from './editor/create.note.dto'; +export * from './editor/create.section.dto'; +export * from './editor/note.dto'; +export * from './editor/section.dto'; +export * from './editor/update.note.dto'; +export * from './editor/update.block.dto'; + +// User +export * from './user/emailSubscription.dto'; +export * from './user/setting.user.dto'; +export * from './user/update.user.dto'; +export * from './user/user.dto'; diff --git a/apps/backend/libs/types/user/emailSubscription.dto.ts b/apps/backend/libs/types/user/emailSubscription.dto.ts new file mode 100644 index 0000000..d92ffee --- /dev/null +++ b/apps/backend/libs/types/user/emailSubscription.dto.ts @@ -0,0 +1,25 @@ +import { IsBoolean, IsDate, IsNotEmpty, IsString } from 'class-validator'; + +export class EmailsSubscriptionDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsBoolean() + @IsNotEmpty() + announcements: boolean; + + @IsBoolean() + @IsNotEmpty() + securityFeatures: boolean; + + @IsBoolean() + @IsNotEmpty() + productUpgrades: boolean; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/libs/types/user/setting.user.dto.ts b/apps/backend/libs/types/user/setting.user.dto.ts new file mode 100644 index 0000000..84a0baa --- /dev/null +++ b/apps/backend/libs/types/user/setting.user.dto.ts @@ -0,0 +1,23 @@ +import { IsDate, IsNotEmpty, IsString, ValidateNested } from 'class-validator'; +import { Type } from 'class-transformer'; +import { EmailsSubscriptionDto } from './emailSubscription.dto'; + +export class UserSettingsDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + emailsSubscriptionId: string; + + @ValidateNested() + @Type(() => EmailsSubscriptionDto) + emailSubscription: EmailsSubscriptionDto; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/libs/types/user/update.user.dto.ts b/apps/backend/libs/types/user/update.user.dto.ts new file mode 100644 index 0000000..21ff308 --- /dev/null +++ b/apps/backend/libs/types/user/update.user.dto.ts @@ -0,0 +1,27 @@ +import { IsBoolean, IsEmail, IsOptional, IsString } from 'class-validator'; + +export class UpdateUserDto { + @IsString() + @IsOptional() + name?: string; + + @IsString() + @IsOptional() + userName?: string; + + @IsEmail() + @IsOptional() + email?: string; + + @IsString() + @IsOptional() + password?: string; + + @IsString() + @IsOptional() + token?: string; + + @IsBoolean() + @IsOptional() + isVerified?: boolean; +} diff --git a/apps/backend/libs/types/user/user.dto.ts b/apps/backend/libs/types/user/user.dto.ts new file mode 100644 index 0000000..04d5d58 --- /dev/null +++ b/apps/backend/libs/types/user/user.dto.ts @@ -0,0 +1,57 @@ +import { + IsBoolean, + IsDate, + IsEmail, + IsNotEmpty, + IsOptional, + IsString, + ValidateNested, +} from 'class-validator'; +import { Type } from 'class-transformer'; +import { BookDto } from '../editor/book.dto'; +import { UserSettingsDto } from './setting.user.dto'; + +export class UserDto { + @IsString() + @IsNotEmpty() + id: string; + + @IsString() + @IsNotEmpty() + name: string; + + @IsString() + @IsNotEmpty() + userName: string; + + @IsEmail() + @IsNotEmpty() + email: string; + + @IsString() + @IsNotEmpty() + password: string; + + @IsString() + @IsOptional() + token?: string; + + @IsBoolean() + @IsNotEmpty() + isVerified: boolean; + + @ValidateNested({ each: true }) + @Type(() => BookDto) + books: BookDto[]; + + @ValidateNested() + @Type(() => UserSettingsDto) + @IsOptional() + settings?: UserSettingsDto; + + @IsDate() + createdAt: Date; + + @IsDate() + updatedAt: Date; +} diff --git a/apps/backend/package.json b/apps/backend/package.json index 8fbbd8e..fb1817a 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -51,6 +51,7 @@ "@nestjs/swagger": "^7.4.0", "@prisma/client": "^5.17.0", "bcrypt": "^5.1.1", + "class-transformer": "^0.5.1", "class-validator": "^0.14.1", "cookie-parser": "^1.4.6", "ioredis": "^5.4.1", diff --git a/apps/backend/prisma/schema.prisma b/apps/backend/prisma/schema.prisma index e745047..5699c6a 100644 --- a/apps/backend/prisma/schema.prisma +++ b/apps/backend/prisma/schema.prisma @@ -1,3 +1,4 @@ +// prisma/schema.prisma generator client { provider = "prisma-client-js" } @@ -7,47 +8,59 @@ datasource db { url = env("DATABASE_URL") } +// User config model User { id String @id @default(cuid()) name String userName String @unique email String @unique password String - token String + token String? isVerified Boolean @default(false) - books Book[] - settings UserSettings @relation(fields: [userSettingsId], references: [id]) + // Relationships + books Book[] + settings UserSettings? @relation(fields: [userSettingsId], references: [id]) + userSettingsId String? @unique - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - userSettingsId String + // Timestamps + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt } +// User settings model UserSettings { id String @id @default(cuid()) - User User[] - emailsSubscriptionId String + // Relationships + user User? @relation - emailSubscription EmailsSubscription @relation(fields: [emailsSubscriptionId], references: [id]) + emailsSubscriptionId String + emailSubscription EmailsSubscription @relation(fields: [emailsSubscriptionId], references: [id]) + // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } +// User email subscription model EmailsSubscription { - id String @id @default(uuid()) - UserSettings UserSettings[] + id String @id @default(uuid()) + // Relationships + userSettings UserSettings[] + + // Subscription types announcements Boolean @default(true) - SecurityFeatures Boolean @default(true) - ProductUpgrades Boolean @default(true) + securityFeatures Boolean @default(true) + productUpgrades Boolean @default(true) + // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } +// Book config model Book { id String @id @default(uuid()) title String @@ -55,36 +68,66 @@ model Book { userId String sections Section[] + // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } +// Section config model Section { id String @id @default(uuid()) title String book Book @relation(fields: [bookId], references: [id]) bookId String - notes Note[] + notes Note[] // Linking notes to sections + // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } +// Merged Note and Document model model Note { id String @id @default(uuid()) + title String // Title of the note section Section @relation(fields: [sectionId], references: [id]) sectionId String - // versions NoteVersion[] + // Content of the note + blocks Block[] + + // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } -//? Implemented in future version +// Block config, which represents individual content pieces in a document +model Block { + id String @id @default(uuid()) + Note Note @relation(fields: [noteId], references: [id]) + noteId String + + // Content of the block (e.g., text, image, etc.) + type typeEnum + content String + + // Timestamps + createdAt DateTime @default(now()) +} + +enum typeEnum { + TEXT + IMAGE + LINKS + INTERNAL_LINK // Link to another note + // other types can be added here +} + +// Uncomment this if you plan to implement versioning in the future // model NoteVersion { // id Int @id @default(autoincrement()) // note Note @relation(fields: [noteId], references: [id]) -// noteId Int +// noteId String // content String // version Int // createdAt DateTime @default(now()) diff --git a/package.json b/package.json index 1a885ce..07f2786 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,11 @@ "name": "@noterai/monorepo", "version": "0.0.1", "description": "Alternative of Notion, with cool features and AI functionality", + "author": { + "name": "Himanshu", + "email": "hyattherate2005@gmail.com", + "url": "https://github.com/Himasnhu-AT" + }, "main": "index.js", "scripts": { "pre-commit": "pnpm format && pnpm lint && pnpm build", @@ -34,7 +39,6 @@ "notes" ], "packageManager": "pnpm@9.11.0", - "author": "Himanshu ", "license": "ISC", "bugs": { "url": "https://github.com/Himasnhu-AT/noterAI/issues"