Skip to content

Commit

Permalink
0.2.0 #53
Browse files Browse the repository at this point in the history
0.2.0
  • Loading branch information
raymondanythings authored Dec 27, 2023
2 parents 3d6f2f1 + ffb4bbb commit 2efbb74
Show file tree
Hide file tree
Showing 17 changed files with 294 additions and 15 deletions.
3 changes: 3 additions & 0 deletions k8s/deployment-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ spec:
envFrom:
- secretRef:
name: catsnewyear-dev
env:
- name: KUBE_ENV
value: development
volumeMounts:
- name: tz-seoul
mountPath: /etc/localtime
Expand Down
5 changes: 4 additions & 1 deletion k8s/deployment-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
env: production
spec:
strategy:
type: "RollingUpdate"
type: 'RollingUpdate'
# rollingUpdate:
# maxUnavailable: 1
# maxSurge: 1
Expand Down Expand Up @@ -41,6 +41,9 @@ spec:
envFrom:
- secretRef:
name: catsnewyear-prod
env:
- name: KUBE_ENV
value: public
volumeMounts:
- name: tz-seoul
mountPath: /etc/localtime
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "shinnyang",
"version": "0.1.9",
"version": "0.2.0",
"description": "",
"author": {
"name": "Medici",
Expand Down
24 changes: 24 additions & 0 deletions src/auth/guards/optinal-access.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { AuthService } from '../auth.service';
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Request } from 'express';
import { Observable } from 'rxjs';

@Injectable()
export class OptinalAccessGuard implements CanActivate {
constructor(private readonly authService: AuthService) {}

canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest() as Request;
const token = request.headers.authorization?.replace('Bearer ', '');
if (token) {
const payload = this.authService.verify(token, {
secret: process.env.SALT,
});
request['user'] = payload;
}

return true;
}
}
47 changes: 45 additions & 2 deletions src/common/common.controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { Controller, Get } from '@nestjs/common';
import { Body, Controller, Get, Patch, UseGuards } from '@nestjs/common';
import { CommonService } from './common.service';
import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger';
import {
ApiBearerAuth,
ApiOkResponse,
ApiOperation,
ApiTags,
} from '@nestjs/swagger';
import { CatDTO } from './dto/cat.dto';
import { AccessoryDTO } from './dto/accessory.dto';
import { UserCatDto } from './dto/user-cat.dto';
import { AccessGuard } from '../auth/guards/acess.guard';
import { AuthUser } from '../auth/decorators/auth-user.decorator';
import { Payload } from '../auth/dtos/jwt.dto';
import { UserCatPatchDto } from './dto/user-cat-patch.dto';

@ApiTags('Common API')
@Controller('common')
Expand Down Expand Up @@ -34,4 +44,37 @@ export class CommonController {
async getAccessoryData() {
return await this.commonService.findAllAccessories();
}

@ApiOperation({
description: '유저의 냥이 정보 조회',
summary: '유저의 냥이 정보를 조회한다.',
})
@ApiOkResponse({
description: '유저냥이 정보 조회 성공',
type: [UserCatDto],
})
@ApiBearerAuth()
@Get('user-cat')
@UseGuards(AccessGuard)
async getUserCatData(@AuthUser() { id }: Payload) {
return await this.commonService.findUserCats(id);
}

@ApiOperation({
description: '유저냥이 악세사리 변경',
summary: '유저의 냥이 악세사리를 변경한다.',
})
@ApiOkResponse({
description: '유저냥이 악세사리 변경 성공',
type: [UserCatDto],
})
@ApiBearerAuth()
@Patch('accessory')
@UseGuards(AccessGuard)
async updateUserCatAccessory(
@AuthUser() { id }: Payload,
@Body() userCatPatchDto: UserCatPatchDto,
) {
return await this.commonService.updateUserCatAccessory(id, userCatPatchDto);
}
}
37 changes: 37 additions & 0 deletions src/common/common.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { Cats } from './entities/cats.entity';
import { CatDTO } from './dto/cat.dto';
import { Accessories } from './entities/accessories.entity';
import { AccessoryDTO } from './dto/accessory.dto';
import { UserCatEntity } from './entities/user-cat.entity';
import { UserCatDto } from './dto/user-cat.dto';
import { UserCatPatchDto } from './dto/user-cat-patch.dto';

@Injectable()
export class CommonService {
Expand Down Expand Up @@ -33,4 +36,38 @@ export class CommonService {
});
return accessories.map((accessory) => new AccessoryDTO(accessory));
}

async findUserCats(id: string): Promise<UserCatDto[]> {
const userCats = await this.dataSource.getRepository(UserCatEntity).find({
where: { userId: id },
relations: {
cat: true,
accessory: true,
},
});
return userCats.map(
(userCat) => new UserCatDto(userCat.cat, userCat.accessory),
);
}

async updateUserCatAccessory(id: string, userCatPatchDto: UserCatPatchDto) {
const userCat = await this.dataSource.getRepository(UserCatEntity).findOne({
where: {
userId: id,
catId: userCatPatchDto.catId,
},
});
userCat.accessoryId = userCatPatchDto.accessoryId;
await this.dataSource.getRepository(UserCatEntity).save(userCat);

const cat = await this.dataSource
.getRepository(Cats)
.findOne({ where: { id: userCatPatchDto.catId } });

const accessory = await this.dataSource
.getRepository(Accessories)
.findOne({ where: { id: userCatPatchDto.accessoryId } });

return new UserCatDto(new CatDTO(cat), new AccessoryDTO(accessory));
}
}
12 changes: 6 additions & 6 deletions src/common/dto/accessory.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ export class AccessoryDTO {
@IsString()
iconImage: string;

constructor(accessory: Accessories) {
this.id = accessory.id;
this.name = accessory.name;
this.code = accessory.code;
this.fullImage = accessory.fullImage;
this.iconImage = accessory.iconImage;
constructor(accessory?: Accessories) {
this.id = accessory?.id || '';
this.name = accessory?.name || '';
this.code = accessory?.code || '';
this.fullImage = accessory?.fullImage || '';
this.iconImage = accessory?.iconImage || '';
}
}
18 changes: 18 additions & 0 deletions src/common/dto/user-cat-patch.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IsUUID } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class UserCatPatchDto {
@ApiProperty({
description: '고양이아이디',
example: 'be17e0ab-6463-4db8-bdfa-bc9011193038',
})
@IsUUID('all')
catId: string;

@ApiProperty({
description: '악세사리아이디',
example: 'be17e0ab-6463-4db8-bdfa-bc9011193038',
})
@IsUUID('all')
accessoryId: string;
}
59 changes: 59 additions & 0 deletions src/common/dto/user-cat.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { CatDTO } from './cat.dto';
import { AccessoryDTO } from './accessory.dto';
import { IsString, IsUUID } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class UserCatDto {
@ApiProperty({
description: '냥이 아이디',
example: 'be17e0ab-6463-4db8-bdfa-bc9011193038',
})
@IsUUID('all')
catId: string;

@ApiProperty({ description: '냥이 이름', example: '우무' })
@IsString()
catName: string;

@ApiProperty({ description: '냥이 객체코드 (영어이름)', example: 'umu' })
@IsString()
catCode: string;

@ApiProperty({
description: '악세사리 아이디',
example: '53227c7f-9dde-4adb-b448-69664fcae813',
nullable: true,
required: false,
})
@IsUUID('all')
accessoryId?: string;

@ApiProperty({
description: '악세사리 이름',
example: '빵 모자',
nullable: true,
required: false,
})
@IsString()
accessoryName?: string;

@ApiProperty({
description: '악세사리 객체코드 ',
example: 'AC-H-1',
nullable: true,
required: false,
})
@IsString()
accessoryCode?: string;

constructor(catDto: CatDTO, accessoryDto: AccessoryDTO) {
if (accessoryDto) {
this.accessoryCode = accessoryDto.code;
this.accessoryId = accessoryDto.id;
this.accessoryName = accessoryDto.name;
}
this.catCode = catDto.code;
this.catId = catDto.id;
this.catName = catDto.name;
}
}
49 changes: 49 additions & 0 deletions src/common/entities/user-cat.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
import { BaseEntity } from './base.entity';
import { User } from 'src/users/entities/user.entity';
import { Cats } from './cats.entity';
import { Accessories } from './accessories.entity';

@Entity({ name: 'user_cat' })
export class UserCatEntity extends BaseEntity {
@Column({
name: 'user_id',
comment: '유저아이디',
unique: false,
nullable: false,
})
userId: string;

@ManyToOne(() => User, (user) => user.id, {
createForeignKeyConstraints: false,
})
@JoinColumn({ name: 'user_id' })
user: User;

@Column({
name: 'cat_id',
comment: '고양이아이디',
unique: false,
nullable: false,
})
catId: string;

@ManyToOne(() => Cats, (cats) => cats.id, {
createForeignKeyConstraints: false,
})
@JoinColumn({ name: 'cat_id' })
cat: Cats;

@Column({
name: 'accessory_id',
comment: '악세사리아이디',
unique: false,
nullable: true,
})
accessoryId: string;
@ManyToOne(() => Accessories, (accessories) => accessories.id, {
createForeignKeyConstraints: false,
})
@JoinColumn({ name: 'accessory_id' })
accessory: Accessories;
}
9 changes: 9 additions & 0 deletions src/common/user-cat.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { DataSource, Repository } from 'typeorm';
import { UserCatEntity } from './entities/user-cat.entity';
import { InjectDataSource } from '@nestjs/typeorm';

export class UserCatRepository extends Repository<UserCatEntity> {
constructor(@InjectDataSource() dataSource: DataSource) {
super(UserCatEntity, dataSource.createEntityManager());
}
}
4 changes: 3 additions & 1 deletion src/database/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { TypeOrmModule } from '@nestjs/typeorm';
database: process.env.DB_NAME, //process.env.DB_NAME, // process.env.DB_NAME,
synchronize: process.env.NODE_ENV !== 'production',
schema:
process.env.NODE_ENV !== 'production' ? 'development' : 'public',
process.env.NODE_ENV !== 'production'
? 'development'
: process.env.KUBE_ENV ?? 'development',
logging: process.env.NODE_ENV !== 'production',
entities: [__dirname + './../**/**.entity{.ts,.js}'],
};
Expand Down
8 changes: 8 additions & 0 deletions src/letters/dtos/letter.request.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ export class CreateLetterDto {
@IsString()
receiverNickname: string;

@ApiProperty({
description: '받는 사용자 아이디 (있을경우 답장으로 간주)',
default: '{uuid}',
})
@IsOptional()
@IsUUID()
receiverId: string;

@ApiProperty({
description: '보낼 편지의 내용',
default: '이 편지는 영국에서부터 시작되어...',
Expand Down
7 changes: 4 additions & 3 deletions src/letters/letter.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import {
import { LetterDetailDto } from './dtos/letter.response.dto';
import { Response } from 'src/common/interface';
import { CreateLetterDto } from './dtos/letter.request.dto';
import { AccessGuard } from 'src/auth/guards/acess.guard';
import { AuthUser } from '../auth/decorators/auth-user.decorator';
import { OptinalAccessGuard } from 'src/auth/guards/optinal-access.guard';
import { Payload } from 'src/auth/dtos/jwt.dto';

@Controller('letters')
@ApiTags('Letters API')
Expand All @@ -41,9 +42,9 @@ export class LetterController {
})
@ApiBearerAuth()
@Post()
@UseGuards(AccessGuard)
@UseGuards(OptinalAccessGuard)
async postLetter(
@AuthUser() { id },
@AuthUser() { id }: Partial<Payload>,
@Body() createLetterDto: CreateLetterDto,
) {
return this.lettersService.createLetter(id, createLetterDto);
Expand Down
7 changes: 7 additions & 0 deletions src/letters/letter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ export class LetterService {
): Promise<Response<LetterDetailDto>> {
const letter = toEntity(userId, createLetterDto);
const newLetter = await this.lettersRepository.createLetter(letter);

if (createLetterDto.receiverId) {
await this.mailsService.saveMails(createLetterDto.receiverId, {
letterId: newLetter.id,
});
}

if (createLetterDto.replyMailId) {
// 편지를 보내는사람이 회원 / 비회원
// 편지를 받는 사람이 회원 / 비회원
Expand Down
Loading

0 comments on commit 2efbb74

Please sign in to comment.