## DTO 유효성 검사
- cardId는 카드 엔티티, content 댓글 엔티티
- 엔티티가 서로 다른 요청 필드에 대해 어떻게 유효성 검사를 하는지?
- 어떻게 validateIf를 사용하여야 groups와 같은 효과를 낼 수 있는지?
```javascript=
router.post('/:cardId/comment', async (req, res) => {
const commentService = CommentService.getInstance();
const userId = req.user.id;
const { cardId } = req.params;
const { content } = req.body;
if (cardId === undefined || !isNumberString(cardId)) {
throw new BadRequestError('Wrong params');
}
if (content === undefined) {
throw new BadRequestError('Empty content');
}
const responseBody = await commentService.addComment({ userId, cardId, content });
res.status(201).json(responseBody);
});
```
```javascript=
export class CardDto {
id;
@ValidateIf((o) => o.title !== undefined)
@IsString()
@IsNotEmpty()
title;
@ValidateIf((o) => o.content !== undefined)
@IsString()
content;
@ValidateIf((o) => o.position !== undefined)
@IsNumber()
position;
@ValidateIf((o) => o.dueDate !== undefined)
@IsISO8601()
dueDate;
@ValidateIf((o) => o.listId !== undefined)
@IsNumber()
listId;
}
```
## After Insert 이벤트를 통한 활동 기록 관리
- 활동기록을 저장하는 로직은 각 보드, 리스트, 카드 서비스와 분리되어야 하는가?
```javascript=
@Transactional()
async deleteCard({ userId, cardId }) {
const card = await this.cardRepository
.createQueryBuilder('card')
.select('card.list')
.innerJoinAndSelect('card.list', 'list')
.where('card.id = :cardId', { cardId })
.getRawOne();
if (!card) throw new EntityNotFoundError();
const namespace = getNamespace('localstorage');
namespace?.set('userId', userId);
namespace?.set('boardId', card.list_board_id);
const boardService = BoardService.getInstance();
await boardService.checkForbidden(userId, card.list_board_id);
await this.cardRepository.remove(await this.cardRepository.findOne(cardId));
}
```
```javascript=
async afterRemove(event) {
const activityService = ActivityService.getInstance();
const userService = UserService.getInstance();
const namespace = getNamespace('localstorage');
const user = await userService.getUserById(namespace.get('userId'));
await activityService.createActivity(
namespace.get('boardId'),
`${user.name}님이 카드 ${event.databaseEntity.title}을 삭제하였습니다.`,
);
}
```
## Frontend 피드백
- 리스트나 카드의 위치를 숫자를 통해서 옮기는 것은 직관적이지 않음
- 보드 화면에서 메인으로 돌아갈 때 진입점을 확실하게
- 보드 화면 왼쪽 상단에 보드 이름이 있는데, 보드 이름처럼 안 보임
- 오른쪽 사이드바 이름을 활동 기록이라는 직관적인 이름으로 변경
- 확장앱 자체의 기능이 없어서 아쉬움
- 강렬한 배경색을 톤다운하는 것이 좋아 보임
- 확장앱에서 카드 배열을 1열로
- 카드 댓글이 없는 경우 개수를 표시하지 말것
- 콜드 스타터를 위한 UI 진입장벽 개선
- "컬러와 여백"