feat: auto-assign and return display_order for question set items

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Yared Yemane 2026-06-12 01:38:27 -07:00
parent 8409f69d56
commit c9f4a9c428
4 changed files with 48 additions and 15 deletions

View File

@ -4,7 +4,18 @@ INSERT INTO question_set_items (
question_id,
display_order
)
VALUES ($1, $2, COALESCE($3, 0))
VALUES (
sqlc.arg('set_id'),
sqlc.arg('question_id'),
COALESCE(
sqlc.narg('display_order')::int,
COALESCE((
SELECT max(qsi.display_order)
FROM question_set_items AS qsi
WHERE qsi.set_id = sqlc.arg('set_id')
), 0) + 1
)
)
ON CONFLICT (set_id, question_id) DO UPDATE SET display_order = EXCLUDED.display_order
RETURNING *;

View File

@ -17,19 +17,30 @@ INSERT INTO question_set_items (
question_id,
display_order
)
VALUES ($1, $2, COALESCE($3, 0))
VALUES (
$1,
$2,
COALESCE(
$3::int,
COALESCE((
SELECT max(qsi.display_order)
FROM question_set_items AS qsi
WHERE qsi.set_id = $1
), 0) + 1
)
)
ON CONFLICT (set_id, question_id) DO UPDATE SET display_order = EXCLUDED.display_order
RETURNING id, set_id, question_id, display_order, created_at
`
type AddQuestionToSetParams struct {
SetID int64 `json:"set_id"`
QuestionID int64 `json:"question_id"`
Column3 interface{} `json:"column_3"`
SetID int64 `json:"set_id"`
QuestionID int64 `json:"question_id"`
DisplayOrder pgtype.Int4 `json:"display_order"`
}
func (q *Queries) AddQuestionToSet(ctx context.Context, arg AddQuestionToSetParams) (QuestionSetItem, error) {
row := q.db.QueryRow(ctx, AddQuestionToSet, arg.SetID, arg.QuestionID, arg.Column3)
row := q.db.QueryRow(ctx, AddQuestionToSet, arg.SetID, arg.QuestionID, arg.DisplayOrder)
var i QuestionSetItem
err := row.Scan(
&i.ID,

View File

@ -1096,15 +1096,15 @@ func (s *Store) DeleteQuestionSet(ctx context.Context, id int64) error {
}
func (s *Store) AddQuestionToSet(ctx context.Context, setID, questionID int64, displayOrder *int32) (domain.QuestionSetItem, error) {
var order interface{}
orderParam := pgtype.Int4{Valid: false}
if displayOrder != nil {
order = *displayOrder
orderParam = pgtype.Int4{Int32: *displayOrder, Valid: true}
}
item, err := s.queries.AddQuestionToSet(ctx, dbgen.AddQuestionToSetParams{
SetID: setID,
QuestionID: questionID,
Column3: order,
SetID: setID,
QuestionID: questionID,
DisplayOrder: orderParam,
})
if err != nil {
return domain.QuestionSetItem{}, err

View File

@ -58,6 +58,7 @@ type shortAnswerRes struct {
type questionRes struct {
ID int64 `json:"id"`
DisplayOrder *int32 `json:"display_order,omitempty"`
QuestionText *string `json:"question_text,omitempty"`
QuestionType string `json:"question_type"`
QuestionTypeDefinitionID *int64 `json:"question_type_definition_id,omitempty"`
@ -1264,8 +1265,9 @@ func (h *Handler) DeleteQuestionSet(c *fiber.Ctx) error {
// Question Set Items
type addQuestionToSetReq struct {
QuestionID int64 `json:"question_id" validate:"required"`
DisplayOrder *int32 `json:"display_order"`
QuestionID int64 `json:"question_id" validate:"required"`
// Omit to append after the current highest display_order in the set; set explicitly to insert at a position.
DisplayOrder *int32 `json:"display_order,omitempty" validate:"omitempty,min=0"`
}
type questionSetItemRes struct {
@ -1321,7 +1323,7 @@ func questionSetItemsToRes(items []domain.QuestionSetItemWithQuestion) []questio
// AddQuestionToSet godoc
// @Summary Add question to set
// @Description Links a question to a question set
// @Description Links a question to a question set. Omit display_order to append after the current max; the assigned value is returned in the response.
// @Tags question-set-items
// @Accept json
// @Produce json
@ -1348,6 +1350,12 @@ func (h *Handler) AddQuestionToSet(c *fiber.Ctx) error {
Error: err.Error(),
})
}
if valErrs, ok := h.validator.Validate(c, req); !ok {
return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
Message: "Validation failed",
Error: firstValidationError(valErrs),
})
}
item, err := h.questionsSvc.AddQuestionToSet(c.Context(), setID, req.QuestionID, req.DisplayOrder)
if err != nil {
@ -1487,7 +1495,10 @@ func (h *Handler) GetQuestionsInSet(c *fiber.Ctx) error {
})
}
questionResponses = append(questionResponses, buildQuestionRes(question, catalog))
res := buildQuestionRes(question, catalog)
order := item.DisplayOrder
res.DisplayOrder = &order
questionResponses = append(questionResponses, res)
}
return c.JSON(domain.Response{