feat(api): list an author's published posts at /authors/{author}/posts
- AuthorPosts reuses the /posts published predicate, per_page clamp, sort allow-list and row serializer - Bearer tokens are ignored; drafts and scheduled posts never appear - Both author routes share one resolve-or-respond helper for identical 404/500 paths - Document query keys, envelope and 404 in README
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"git.golem15.com/golem15/sm-journal-plugin/models"
|
||||
"git.golem15.com/golem15/summercms/modules/backpack"
|
||||
"git.golem15.com/golem15/summercms/modules/lagoon"
|
||||
"git.golem15.com/golem15/summercms/modules/wire"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -129,3 +130,37 @@ func AuthorShow(app *backpack.App) http.HandlerFunc {
|
||||
wire.WriteJSON(w, http.StatusOK, map[string]any{"data": authorProfile(row)})
|
||||
}
|
||||
}
|
||||
|
||||
// AuthorPosts is GET /_journal/api/v1/authors/{author}/posts: that author's
|
||||
// published posts, paginated like GET /posts. Bearer tokens are ignored.
|
||||
func AuthorPosts(app *backpack.App) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
db, author, ok := authorOrRespond(app, w, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
perPage := clampPerPage(r.URL.Query().Get("per_page"))
|
||||
page := max(1, atoiDefault(r.URL.Query().Get("page"), 1))
|
||||
|
||||
q := applyPublished(db.Model(&models.Post{}).
|
||||
Preload("User").Preload("Categories").Preload("Tags")).
|
||||
Where("user_id = ?", author.ID)
|
||||
|
||||
var total int64
|
||||
if err := q.Count(&total).Error; err != nil {
|
||||
writeAPIError(w, http.StatusInternalServerError, "Internal server error")
|
||||
return
|
||||
}
|
||||
order := listOrder(strings.TrimSpace(r.URL.Query().Get("sort")), false)
|
||||
var posts []models.Post
|
||||
if err := q.Order(order).Offset((page - 1) * perPage).Limit(perPage).Find(&posts).Error; err != nil {
|
||||
writeAPIError(w, http.StatusInternalServerError, "Internal server error")
|
||||
return
|
||||
}
|
||||
rows := make([]map[string]any, 0, len(posts))
|
||||
for i := range posts {
|
||||
rows = append(rows, serializePost(&posts[i], db))
|
||||
}
|
||||
wire.WriteJSON(w, http.StatusOK, lagoon.Paginate(rows, page, perPage, total))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user