feat(post): add idempotency support for post creation with client request ID
All checks were successful
Build Backend / build (push) Successful in 3m42s
Build Backend / build-docker (push) Successful in 1m7s

Add client_request_id field to post creation endpoints (CreateVotePost and CreatePostWithSegments).
When provided, the server uses Redis SetNX-based idempotency to prevent duplicate posts
from double-clicks or network retries within a 24-hour TTL. Duplicate requests return
the originally created post; concurrent in-flight requests return 429 "正在发布中,请稍候".
This commit is contained in:
lafay
2026-06-26 17:00:38 +08:00
parent 28cfcbf9a8
commit d8e56e60dc
8 changed files with 231 additions and 19 deletions

View File

@@ -54,20 +54,26 @@ type PostResponse struct {
// CreateVotePostRequest 创建投票帖子请求
type CreateVotePostRequest struct {
Title string `json:"title" binding:"required,max=200"`
Content string `json:"content" binding:"max=2000"`
ChannelID *string `json:"channel_id,omitempty"`
Images []string `json:"images"`
VoteOptions []string `json:"vote_options" binding:"required,min=2,max=10"`
Title string `json:"title" binding:"required,max=200"`
Content string `json:"content" binding:"max=2000"`
ChannelID *string `json:"channel_id,omitempty"`
Images []string `json:"images"`
VoteOptions []string `json:"vote_options" binding:"required,min=2,max=10"`
// ClientRequestID 客户端为本次发帖生成的幂等键UUID
// 同一 userID + ClientRequestID 在 TTL 内重复提交时,后端直接返回首次创建的帖子,避免重复发帖。
ClientRequestID string `json:"client_request_id,omitempty"`
}
// CreatePostWithSegmentsRequest 创建帖子请求(含 segments
type CreatePostWithSegmentsRequest struct {
Title string `json:"title" binding:"required,max=200"`
Content string `json:"content"`
Segments model.MessageSegments `json:"segments"`
Images []string `json:"images"`
ChannelID *string `json:"channel_id,omitempty"`
Title string `json:"title" binding:"required,max=200"`
Content string `json:"content"`
Segments model.MessageSegments `json:"segments"`
Images []string `json:"images"`
ChannelID *string `json:"channel_id,omitempty"`
// ClientRequestID 客户端为本次发帖生成的幂等键UUID
// 同一 userID + ClientRequestID 在 TTL 内重复提交时,后端直接返回首次创建的帖子,避免重复发帖。
ClientRequestID string `json:"client_request_id,omitempty"`
}
// VoteOptionDTO 投票选项DTO