Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 프로젝트 생성 API 구현 #55

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/server/config/typeorm.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
import { Task } from '@/task/domain/task.entity';
import { Section } from '@/task/domain/section.entity';
import { Account } from '@/account/entity/account.entity';
import { Project } from '@/project/entity/project.entity';
import { Contributor } from '@/project/entity/contributor.entity';

@Injectable()
export class TypeormConfig implements TypeOrmOptionsFactory {
Expand All @@ -17,7 +19,7 @@ export class TypeormConfig implements TypeOrmOptionsFactory {
username: this.configService.get<string>('DATABASE_USER'),
password: this.configService.get<string>('DATABASE_PASSWORD'),
database: this.configService.get<string>('DATABASE_NAME'),
entities: [Task, Section, Account],
entities: [Task, Section, Account, Project, Contributor],
synchronize: true,
ssl: {
rejectUnauthorized: false,
Expand Down
4 changes: 3 additions & 1 deletion apps/server/src/account/dto/create-user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { IsEmail, IsString, Length } from 'class-validator';
import { IsEmail, IsNotEmpty, IsString, Length } from 'class-validator';

export class CreateUserDto {
@IsNotEmpty()
@IsEmail()
username: string;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴
username 과 email 이 명확하게 분리되었으면 좋겠습니다.
검증은 @isEmail() 이라 이메일을 요구하는 것 같지만, 이름이 username 이라 조금 당황했습니다...

Copy link
Collaborator Author

@jjeonghak jjeonghak Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버에서 사용하는 username은 아이디로 사용되고 있고, 회원가입 때부터 아이디는 이메일 형식으로 받고 있었습니다. 그냥 이메일 형식을 사용하지 않도록 수정해두겠습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사실 username 과, email 중 선택하면 되는 부분인 것 같아요!
저희가 email 을 사용할 필요가 없다면, username 으로도 충분하다고 생각됩니다.

@IsNotEmpty()
@IsString()
@Length(8, 15)
password: string;
Expand Down
3 changes: 2 additions & 1 deletion apps/server/src/account/entity/account.entity.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { EntityTimestamp } from '@/common/entity-timestamp.entity';

@Entity()
export class Account {
export class Account extends EntityTimestamp {
@PrimaryGeneratedColumn()
id: number;

Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { AppController } from './app.controller';
import { HttpLoggingInterceptor } from './common/httpLog.Interceptor';
import { AllExceptionsFilter } from './common/allException.filter';
import { AccountModule } from './account/account.module';
import { ProjectModule } from './project/project.module';

@Module({
imports: [
Expand All @@ -24,6 +25,7 @@ import { AccountModule } from './account/account.module';
}),
TaskModule,
AccountModule,
ProjectModule,
],
controllers: [AppController],
providers: [
Expand Down
9 changes: 9 additions & 0 deletions apps/server/src/common/entity-timestamp.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CreateDateColumn, UpdateDateColumn } from 'typeorm';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


다른 엔티티에서 이 친구를 확장해서 사용하기 위해 common 에 위치한 걸까요?

Copy link
Collaborator Author

@jjeonghak jjeonghak Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모든 엔티티에 필요하다고 생각합니다. 그래서 common에 위치시켰습니다. 딱히 적절한 위치가 생각나지 않더군요..

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다. 저는 저렇게 타임스탬프를 분리해본 경험조차 없습니다 ㅎㅎ


export class EntityTimestamp {
@CreateDateColumn()
createdAt: Date;

@UpdateDateColumn()
updatedAt: Date;
}
17 changes: 17 additions & 0 deletions apps/server/src/project/controller/project.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Body, Controller, Post, UseGuards } from '@nestjs/common';
import { ProjectService } from '../service/project.service';
import { AccessTokenGuard } from '@/account/guard/accessToken.guard';
import { CreateProjectRequest } from '../dto/create-project-request.dto';
import { AuthUser } from '@/account/decorator/authUser.decorator';
import { Account } from '@/account/entity/account.entity';

@UseGuards(AccessTokenGuard)
@Controller('projects')
export class ProjectController {
constructor(private projectService: ProjectService) {}

@Post()
create(@AuthUser() user: Account, @Body() body: CreateProjectRequest) {
return this.projectService.create(user.id, body.title);
}
}
8 changes: 8 additions & 0 deletions apps/server/src/project/dto/create-project-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IsNotEmpty, IsString, Length } from 'class-validator';

export class CreateProjectRequest {
@IsNotEmpty()
@IsString()
@Length(1, 20)
title: string;
}
12 changes: 12 additions & 0 deletions apps/server/src/project/dto/create-project-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Project } from '../entity/project.entity';

export class CreateProjectResponse {
id: number;

title: string;

constructor(project: Project) {
this.id = project.id;
this.title = project.title;
}
}
22 changes: 22 additions & 0 deletions apps/server/src/project/entity/contributor.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { ContributorStatus } from '../enum/contributor-status.enum';
import { ProjectRole } from '../enum/project-role.enum';
import { EntityTimestamp } from '@/common/entity-timestamp.entity';

@Entity()
export class Contributor extends EntityTimestamp {
@PrimaryGeneratedColumn()
id: number;

@Column()
userId: number;

@Column()
projectId: number;

@Column({ type: 'enum', enum: ContributorStatus })
status: ContributorStatus;

@Column({ type: 'enum', enum: ProjectRole })
role: ProjectRole;
}
11 changes: 11 additions & 0 deletions apps/server/src/project/entity/project.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { EntityTimestamp } from '@/common/entity-timestamp.entity';

@Entity()
export class Project extends EntityTimestamp {
@PrimaryGeneratedColumn()
id: number;

@Column()
title: string;
}
5 changes: 5 additions & 0 deletions apps/server/src/project/enum/contributor-status.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ContributorStatus {
PENDING = 'PENDING',
ACCEPTED = 'ACCEPTED',
REJECTED = 'REJECTED',
}
4 changes: 4 additions & 0 deletions apps/server/src/project/enum/project-role.enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum ProjectRole {
ADMIN = 'ADMIN',
GUEST = 'GUEST',
}
13 changes: 13 additions & 0 deletions apps/server/src/project/project.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProjectService } from './service/project.service';
import { ProjectController } from './controller/project.controller';
import { Project } from './entity/project.entity';
import { Contributor } from './entity/contributor.entity';

@Module({
imports: [TypeOrmModule.forFeature([Project, Contributor])],
controllers: [ProjectController],
providers: [ProjectService],
})
export class ProjectModule {}
27 changes: 27 additions & 0 deletions apps/server/src/project/service/project.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Project } from '../entity/project.entity';
import { Contributor } from '../entity/contributor.entity';
import { ContributorStatus } from '../enum/contributor-status.enum';
import { ProjectRole } from '../enum/project-role.enum';
import { CreateProjectResponse } from '../dto/create-project-response.dto';

@Injectable()
export class ProjectService {
constructor(
@InjectRepository(Project) private projectRepository: Repository<Project>,
@InjectRepository(Contributor) private contributorRepository: Repository<Contributor>
) {}

async create(userId: number, title: string) {
const project = await this.projectRepository.save({ title });
await this.contributorRepository.save({
userId,
projectId: project.id,
status: ContributorStatus.ACCEPTED,
role: ProjectRole.ADMIN,
});
return new CreateProjectResponse(project);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔꼼하군요
역시 정한님 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나중에 트랜잭션 처리도 해야겠군요...

}
Loading