Merge pull request #34 from rede5/codex/fix-ticket-not-found-error

Allow admins to view and post on any support ticket
This commit is contained in:
Tiago Yamamoto 2026-01-03 19:41:57 -03:00 committed by GitHub
commit 10d75e87ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 11 deletions

View file

@ -695,7 +695,7 @@ func (h *CoreHandlers) CreateTicket(w http.ResponseWriter, r *http.Request) {
// Create initial message if provided
if req.Message != "" {
_, _ = h.ticketService.AddMessage(r.Context(), ticket.ID, userID, req.Message)
_, _ = h.ticketService.AddMessage(r.Context(), ticket.ID, userID, req.Message, false)
}
w.WriteHeader(http.StatusCreated)
@ -759,7 +759,11 @@ func (h *CoreHandlers) GetTicket(w http.ResponseWriter, r *http.Request) {
}
}
ticket, messages, err := h.ticketService.GetTicket(r.Context(), id, userID)
roleVal := r.Context().Value(middleware.ContextRoles)
roles := middleware.ExtractRoles(roleVal)
isAdmin := hasAdminRole(roles)
ticket, messages, err := h.ticketService.GetTicket(r.Context(), id, userID, isAdmin)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
@ -810,7 +814,11 @@ func (h *CoreHandlers) AddMessage(w http.ResponseWriter, r *http.Request) {
return
}
msg, err := h.ticketService.AddMessage(r.Context(), id, userID, req.Message)
roleVal := r.Context().Value(middleware.ContextRoles)
roles := middleware.ExtractRoles(roleVal)
isAdmin := hasAdminRole(roles)
msg, err := h.ticketService.AddMessage(r.Context(), id, userID, req.Message, isAdmin)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return

View file

@ -61,15 +61,21 @@ func (s *TicketService) ListTickets(ctx context.Context, userID string) ([]model
return tickets, nil
}
func (s *TicketService) GetTicket(ctx context.Context, ticketID string, userID string) (*models.Ticket, []models.TicketMessage, error) {
func (s *TicketService) GetTicket(ctx context.Context, ticketID string, userID string, isAdmin bool) (*models.Ticket, []models.TicketMessage, error) {
// 1. Get Ticket
queryTicket := `
SELECT id, user_id, subject, status, priority, created_at, updated_at
FROM tickets
WHERE id = $1 AND user_id = $2
WHERE id = $1
`
args := []any{ticketID}
if !isAdmin {
queryTicket += " AND user_id = $2"
args = append(args, userID)
}
var t models.Ticket
err := s.DB.QueryRowContext(ctx, queryTicket, ticketID, userID).Scan(
err := s.DB.QueryRowContext(ctx, queryTicket, args...).Scan(
&t.ID, &t.UserID, &t.Subject, &t.Status, &t.Priority, &t.CreatedAt, &t.UpdatedAt,
)
if err != nil {
@ -106,10 +112,16 @@ func (s *TicketService) GetTicket(ctx context.Context, ticketID string, userID s
return &t, messages, nil
}
func (s *TicketService) AddMessage(ctx context.Context, ticketID string, userID string, message string) (*models.TicketMessage, error) {
// Verify ticket ownership first (or admin access, but keeping simple for now)
func (s *TicketService) AddMessage(ctx context.Context, ticketID string, userID string, message string, isAdmin bool) (*models.TicketMessage, error) {
// Verify ticket ownership first (or admin access)
var count int
err := s.DB.QueryRowContext(ctx, "SELECT COUNT(*) FROM tickets WHERE id = $1 AND user_id = $2", ticketID, userID).Scan(&count)
query := "SELECT COUNT(*) FROM tickets WHERE id = $1 AND user_id = $2"
args := []any{ticketID, userID}
if isAdmin {
query = "SELECT COUNT(*) FROM tickets WHERE id = $1"
args = []any{ticketID}
}
err := s.DB.QueryRowContext(ctx, query, args...).Scan(&count)
if err != nil {
return nil, err
}

View file

@ -53,7 +53,7 @@ func TestTicketService_CRUD(t *testing.T) {
WithArgs("ticket-id").
WillReturnResult(sqlmock.NewResult(1, 1))
msg, err := service.AddMessage(ctx, "ticket-id", "user-id", "reply")
msg, err := service.AddMessage(ctx, "ticket-id", "user-id", "reply", false)
assert.NoError(t, err)
assert.NotNil(t, msg)
@ -89,7 +89,7 @@ func TestTicketService_Extended(t *testing.T) {
WillReturnRows(sqlmock.NewRows([]string{"id", "ticket_id", "user_id", "message", "created_at"}).
AddRow("msg-1", "ticket-id", "user-id", "msg body", time.Now()))
tTicket, tMsgs, err := service.GetTicket(ctx, "ticket-id", "user-id")
tTicket, tMsgs, err := service.GetTicket(ctx, "ticket-id", "user-id", false)
assert.NoError(t, err)
assert.Equal(t, "ticket-id", tTicket.ID)
assert.Len(t, tMsgs, 1)