Skip to content

Commit

Permalink
(BE) Add API for Creating a Document in Workspace (#61)
Browse files Browse the repository at this point in the history
* Add base code for workspace documents

* Fix lint & Add service for workspace document

* Add controller for creating a workspace document
  • Loading branch information
devleejb authored Jan 18, 2024
1 parent 7bbeee8 commit 18f6160
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 2 deletions.
2 changes: 2 additions & 0 deletions backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { APP_GUARD } from "@nestjs/core/constants";
import { JwtAuthGuard } from "./auth/jwt.guard";
import { WorkspacesModule } from "./workspaces/workspaces.module";
import { WorkspaceUsersModule } from "./workspace-users/workspace-users.module";
import { WorkspaceDocumentsModule } from "./workspace-documents/workspace-documents.module";

@Module({
imports: [
Expand All @@ -15,6 +16,7 @@ import { WorkspaceUsersModule } from "./workspace-users/workspace-users.module";
AuthModule,
WorkspacesModule,
WorkspaceUsersModule,
WorkspaceDocumentsModule,
],
controllers: [],
providers: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ApiProperty } from "@nestjs/swagger";

export class CreateWorkspaceDocumentDto {
@ApiProperty({ description: "Title of document to create", type: String })
title: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { WorkspaceDocumentDomain } from "./workspace-document-domain.type";

export class CreateWorkspaceDocumentResponse extends WorkspaceDocumentDomain {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ApiProperty } from "@nestjs/swagger";

export class WorkspaceDocumentDomain {
@ApiProperty({ type: String, description: "ID of the document" })
id: string;
@ApiProperty({ type: String, description: "Yorkie Document ID of the document" })
yorkieDocumentId: string;
@ApiProperty({ type: String, description: "Title of the document" })
title: string;
@ApiProperty({ type: String, description: "Content of the document", required: false })
content?: string;
@ApiProperty({ type: Date, description: "Created date of the document" })
createdAt: Date;
@ApiProperty({ type: Date, description: "Updated date of the document" })
updatedAt: Date;
@ApiProperty({ type: String, description: "ID of the workspace that includes the document" })
workspaceId: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from "@nestjs/testing";
import { WorkspaceDocumentsController } from "./workspace-documents.controller";

describe("WorkspaceDocumentsController", () => {
let controller: WorkspaceDocumentsController;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [WorkspaceDocumentsController],
}).compile();

controller = module.get<WorkspaceDocumentsController>(WorkspaceDocumentsController);
});

it("should be defined", () => {
expect(controller).toBeDefined();
});
});
44 changes: 44 additions & 0 deletions backend/src/workspace-documents/workspace-documents.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Body, Controller, Param, Post, Req } from "@nestjs/common";
import { WorkspaceDocumentsService } from "./workspace-documents.service";
import {
ApiBearerAuth,
ApiBody,
ApiCreatedResponse,
ApiNotFoundResponse,
ApiOperation,
ApiTags,
} from "@nestjs/swagger";
import { AuthroizedRequest } from "src/utils/types/req.type";
import { CreateWorkspaceDocumentDto } from "./dto/create-workspace-document.dto";
import { CreateWorkspaceDocumentResponse } from "./types/create-workspace-document-response.type";
import { HttpExceptionResponse } from "src/utils/types/http-exception-response.type";

@ApiTags("Workspace.Documents")
@ApiBearerAuth()
@Controller("workspaces/:workspace_id/documents")
export class WorkspaceDocumentsController {
constructor(private workspaceDocumentsService: WorkspaceDocumentsService) {}

@Post()
@ApiOperation({
summary: "Create a Document in a Workspace",
description: "Create a document with the title in a workspace",
})
@ApiBody({ type: CreateWorkspaceDocumentDto })
@ApiCreatedResponse({ type: CreateWorkspaceDocumentResponse })
@ApiNotFoundResponse({
type: HttpExceptionResponse,
description: "The workspace does not exist, or the user lacks the appropriate permissions.",
})
async create(
@Req() req: AuthroizedRequest,
@Param("workspace_id") workspaceId: string,
@Body() createWorkspaceDocumentDto: CreateWorkspaceDocumentDto
): Promise<CreateWorkspaceDocumentResponse> {
return this.workspaceDocumentsService.create(
req.user.id,
workspaceId,
createWorkspaceDocumentDto.title
);
}
}
10 changes: 10 additions & 0 deletions backend/src/workspace-documents/workspace-documents.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from "@nestjs/common";
import { WorkspaceDocumentsService } from "./workspace-documents.service";
import { WorkspaceDocumentsController } from "./workspace-documents.controller";
import { PrismaService } from "src/db/prisma.service";

@Module({
providers: [WorkspaceDocumentsService, PrismaService],
controllers: [WorkspaceDocumentsController],
})
export class WorkspaceDocumentsModule {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Test, TestingModule } from "@nestjs/testing";
import { WorkspaceDocumentsService } from "./workspace-documents.service";

describe("WorkspaceDocumentsService", () => {
let service: WorkspaceDocumentsService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [WorkspaceDocumentsService],
}).compile();

service = module.get<WorkspaceDocumentsService>(WorkspaceDocumentsService);
});

it("should be defined", () => {
expect(service).toBeDefined();
});
});
28 changes: 28 additions & 0 deletions backend/src/workspace-documents/workspace-documents.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Injectable, NotFoundException } from "@nestjs/common";
import { PrismaService } from "src/db/prisma.service";

@Injectable()
export class WorkspaceDocumentsService {
constructor(private prismaService: PrismaService) {}

async create(userId: string, workspaceId: string, title: string) {
try {
await this.prismaService.userWorkspace.findFirstOrThrow({
where: {
userId,
workspaceId,
},
});
} catch (e) {
throw new NotFoundException();
}

return this.prismaService.document.create({
data: {
title,
workspaceId,
yorkieDocumentId: Math.random().toString(36).substring(7),
},
});
}
}
14 changes: 13 additions & 1 deletion backend/src/workspace-users/workspace-users.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { Controller, DefaultValuePipe, Get, Param, ParseIntPipe, Query, Req } from "@nestjs/common";
import { ApiBearerAuth, ApiFoundResponse, ApiOperation, ApiQuery, ApiTags } from "@nestjs/swagger";
import {
ApiBearerAuth,
ApiFoundResponse,
ApiNotFoundResponse,
ApiOperation,
ApiQuery,
ApiTags,
} from "@nestjs/swagger";
import { FindWorkspaceUsersResponse } from "./types/find-workspace-users-response.type";
import { AuthroizedRequest } from "src/utils/types/req.type";
import { WorkspaceUsersService } from "./workspace-users.service";
import { HttpExceptionResponse } from "src/utils/types/http-exception-response.type";

@ApiTags("Workspace.Users")
@ApiBearerAuth()
Expand All @@ -16,6 +24,10 @@ export class WorkspaceUsersController {
description: "Return the users in the workspace. This API supports KeySet pagination.",
})
@ApiFoundResponse({ type: FindWorkspaceUsersResponse })
@ApiNotFoundResponse({
type: HttpExceptionResponse,
description: "The workspace does not exist, or the user lacks the appropriate permissions.",
})
@ApiQuery({
name: "page_size",
type: Number,
Expand Down
2 changes: 1 addition & 1 deletion backend/src/workspaces/workspaces.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class WorkspacesController {
@ApiFoundResponse({ type: FindWorkspaceResponse })
@ApiNotFoundResponse({
type: HttpExceptionResponse,
description: "The Workspace does not exist, or the user lacks the appropriate permissions.",
description: "The workspace does not exist, or the user lacks the appropriate permissions.",
})
async findOne(
@Req() req: AuthroizedRequest,
Expand Down

0 comments on commit 18f6160

Please sign in to comment.