feat(backend): add create user report endpoint
This commit is contained in:
parent
799d27b58c
commit
3bb97b8274
3 changed files with 88 additions and 9 deletions
|
@ -10,16 +10,16 @@ import (
|
|||
)
|
||||
|
||||
type Report struct {
|
||||
ID int64
|
||||
UserID xid.ID
|
||||
MemberID *xid.ID
|
||||
Reason string
|
||||
ReporterID xid.ID
|
||||
ID int64 `json:"id"`
|
||||
UserID xid.ID `json:"user_id"`
|
||||
MemberID *xid.ID `json:"member_id"`
|
||||
Reason string `json:"reason"`
|
||||
ReporterID xid.ID `json:"reporter_id"`
|
||||
|
||||
CreatedAt time.Time
|
||||
ResolvedAt *time.Time
|
||||
AdminID *xid.ID
|
||||
AdminComment *string
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
ResolvedAt *time.Time `json:"resolved_at"`
|
||||
AdminID *xid.ID `json:"admin_id"`
|
||||
AdminComment *string `json:"admin_comment"`
|
||||
}
|
||||
|
||||
const ReportPageSize = 100
|
||||
|
@ -88,3 +88,21 @@ func (db *DB) ReportsByReporter(ctx context.Context, reporterID xid.ID, before i
|
|||
}
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func (db *DB) CreateReport(ctx context.Context, reporterID, userID xid.ID, memberID *xid.ID, reason string) (r Report, err error) {
|
||||
sql, args, err := sq.Insert("reports").SetMap(map[string]any{
|
||||
"user_id": userID,
|
||||
"reporter_id": reporterID,
|
||||
"member_id": memberID,
|
||||
"reason": reason,
|
||||
}).Suffix("RETURNING *").ToSql()
|
||||
if err != nil {
|
||||
return r, errors.Wrap(err, "building sql")
|
||||
}
|
||||
|
||||
err = pgxscan.Get(ctx, db, &r, sql, args...)
|
||||
if err != nil {
|
||||
return r, errors.Wrap(err, "executing query")
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
|
58
backend/routes/mod/create_report.go
Normal file
58
backend/routes/mod/create_report.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
package mod
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/db"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/log"
|
||||
"codeberg.org/u1f320/pronouns.cc/backend/server"
|
||||
"emperror.dev/errors"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/rs/xid"
|
||||
)
|
||||
|
||||
const MaxReasonLength = 2000
|
||||
|
||||
type CreateReportRequest struct {
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
func (s *Server) createUserReport(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := r.Context()
|
||||
claims, _ := server.ClaimsFromContext(ctx)
|
||||
|
||||
userID, err := xid.FromString(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
return server.APIError{Code: server.ErrBadRequest, Details: "Invalid user ID"}
|
||||
}
|
||||
|
||||
u, err := s.DB.User(ctx, userID)
|
||||
if err != nil {
|
||||
if err == db.ErrUserNotFound {
|
||||
return server.APIError{Code: server.ErrUserNotFound}
|
||||
}
|
||||
|
||||
log.Errorf("getting user %v: %v", userID, err)
|
||||
return errors.Wrap(err, "getting user")
|
||||
}
|
||||
|
||||
var req CreateReportRequest
|
||||
err = render.Decode(r, &req)
|
||||
if err != nil {
|
||||
return server.APIError{Code: server.ErrBadRequest}
|
||||
}
|
||||
|
||||
if len(req.Reason) > MaxReasonLength {
|
||||
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
|
||||
}
|
||||
|
||||
report, err := s.DB.CreateReport(ctx, claims.UserID, u.ID, nil, req.Reason)
|
||||
if err != nil {
|
||||
log.Errorf("creating report for %v: %v", u.ID, err)
|
||||
return errors.Wrap(err, "creating report")
|
||||
}
|
||||
|
||||
render.JSON(w, r, map[string]any{"created": true, "created_at": report.CreatedAt})
|
||||
return nil
|
||||
}
|
|
@ -22,6 +22,9 @@ func Mount(srv *server.Server, r chi.Router) {
|
|||
|
||||
r.Patch("/reports/{id}", nil)
|
||||
})
|
||||
|
||||
r.With(server.MustAuth).Post("/users/{id}/reports", server.WrapHandler(s.createUserReport))
|
||||
r.With(server.MustAuth).Post("/members/{id}/reports", nil)
|
||||
}
|
||||
|
||||
func MustAdmin(next http.Handler) http.Handler {
|
||||
|
|
Loading…
Reference in a new issue