| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
- 노드간 통신
- ㅉ때
- R2DBC Paging
- Loki 로그
- UnsupportedOperationException
- 애자일 싫타
- jsonMarshaller
- nGinder
- intellij
- reids
- 개발 어렵당.ㅠ
- 핀포인트
- Ingress Controller Fake
- LPOS
- 7879
- Armeria
- fake jwt
- RedirectService
- 논블록킹 성능
- 오블완
- 월급루팡 일지
- 았
- save/update
- pinpoint 2.5.3
- pinpoint
- 티스토리챌린지
- 플루터
- formik
- OIDC
- hbase 저장공간 설정
- Today
- Total
대머리개발자
고랭(goLand) - 게시판/댓글 신고하기 기능 설계 본문
완벽하게 설계를 하고 나서 개발하면 나이스하겠지만
완벽한 설계를 애초에 한다는 것이.. 우리내 평민들 사이에서는 어불성서.
그렇기 때문에.. 계속 고민 또 고민해야 한다.
이것도 계속 설계에 대한 고민만 하는것이 아니라.. 초안을 작성하고 실제 개발을 진행하고.. 개발을 진행하면서.. 설계를 바꿔 나가는..애자일하게 가는것이 훌륭하겠다!!
신고 기능은
게시글 신고와 댓글 신고가 있다.
하나의 테이블로 설계를 진행했다.
신고의 대상이 많지 않을 것으로 판단하고 게시글과 댓글을 하나의 바구니에 담으려고 한 부분이고.
두 친구의 시퀀스(PK)는 auto_increment으로 진행되기 때문에 별도 target_type 필요했다.
create table if not exists Reports
(
id bigint AUTO_INCREMENT PRIMARY KEY comment 'id',
target_id bigint not null comment '신고 대상 Id',
target_Type tinyint default 0 comment '0: board, 1:comment',
user_id varchar(100) not null comment '신고자 Id',
nickname varchar(100) not null comment '신고자 nickname',
reason tinyint default 0 comment 'reason is code',
user_reason varchar(100) comment 'etc - 사용자 별도 내용',
reg_dt timestamp default current_timestamp() not null comment '등록 일시'
)
comment '신고' charset = utf8mb4;
targetType에 대한 처리를 위한....코드가..ㅎㄷㄷ..@.@
DB 값으로는 단순 숫자(int)로 관리하고... 프론트와 주고 받을 때는 사람이 바로 이해할 수 있는 문맥(string)으로 해야 하고..
해당 처리는 아래와 같다....
프론트 <--> 서버 (마셜/언마셜).. ㅋㅋ 이 단어은 ㅎㅂ... ejb할때나 들어봤던 건데.. 추억돋고
type TargetType int8
// 신고 대상 ID 상수 정의
const (
TargetNone TargetType = 0 // none -> 0
TargetBoard TargetType = 1 // board -> 1
TargetComment TargetType = 2 // comment -> 2
)
var (
targetStringToID = map[string]TargetType{
"board": TargetBoard,
"comment": TargetComment,
}
// DB 정수 ID -> 클라이언트 문자열
targetIDToString = map[TargetType]string{
TargetBoard: "board",
TargetComment: "comment",
}
)
func (t TargetType) String() string {
return targetIDToString[t]
}
func (tk *TargetType) Scan(value interface{}) error {
// DB 값이 INT8인지 확인하고 TargetType으로 변환합니다.
if i, ok := value.(int8); ok {
*tk = TargetType(i)
return nil
}
// 다른 타입이 들어온 경우 에러 반환
return fmt.Errorf("TargetType 스캔 실패: 예상치 못한 타입 %T", value)
}
func (tk *TargetType) UnmarshalJSON(b []byte) error {
var s string
// 1. JSON 값을 문자열로 추출 (예: "board")
if err := json.Unmarshal(b, &s); err != nil {
return fmt.Errorf("TargetKind는 문자열이어야 합니다: %v", err)
}
// 2. 매핑 테이블을 사용하여 문자열을 정수 ID로 변환
if id, ok := targetStringToID[s]; ok {
*tk = id
return nil
}
return fmt.Errorf("유효하지 않은 targetType 값입니다: %s", s)
}
func (tk *TargetType) MarshalJSON() ([]byte, error) {
if s, ok := targetIDToString[*tk]; ok {
// 매핑된 문자열을 JSON으로 변환하여 반환 (예: "board")
return json.Marshal(s)
}
// 매핑되지 않은 값이라면 에러 처리 또는 정수 자체를 반환할 수 있음
return nil, errors.New("알 수 없는 TargetKind입니다")
}
지저분하다...그럼 고민해야지.... 안 되면 말고 ㅎ
create table if not exists Reports
(
id bigint AUTO_INCREMENT PRIMARY KEY comment 'id',
boardId bigint default 0 comment '신고 대상 boardId',
commentId bigint default 0 comment '신고 대상 commentId',
user_id varchar(100) not null comment '신고자 Id',
nickname varchar(100) not null comment '신고자 nickname',
reason tinyint default 0 comment 'reason is code',
user_reason varchar(100) comment 'etc - 사용자 별도 내용',
reg_dt timestamp default current_timestamp() not null comment '등록 일시'
)
comment '신고' charset = utf8mb4;
boardId와 commentId를 각각 놓으면 더 깔끔하게 정리할 수 있겠다.
결국 commentId가 0이면.. 게시물 신고가 되는 거고
commentId의 value가 있다면 그건... 댓글에 신고가 되는거고.. 어차피.. 둘 다.. boardId는 필수로 필요한 값이니....targetType을 자동 변환하기 위한 코드들이 필요 없어지게 되었다..
나이스!!
'개발이야기' 카테고리의 다른 글
| 고랭(goLand) - ent 스럽게 (1) | 2025.12.22 |
|---|---|
| 고랭(goLand) - NCP Object Storage(s3) 연동 (0) | 2025.12.19 |
| 고랭(goLand) - 게시판 조회수 조지기 (0) | 2025.12.12 |
| 고랭(goLand) 작업하기 (0) | 2025.12.10 |
| 고랭(goLand) 프로젝트 셋팅 (0) | 2025.12.09 |