Accept optional sort_order when creating LMS programs.
Preserve append-after-max ordering when omitting sort_order and keep global uniqueness enforced by DB. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
4a681265d7
commit
d28bddace1
|
|
@ -1,13 +1,13 @@
|
||||||
-- name: CreateProgram :one
|
-- name: CreateProgram :one
|
||||||
INSERT INTO programs (name, description, thumbnail, sort_order)
|
INSERT INTO programs (name, description, thumbnail, sort_order)
|
||||||
SELECT
|
SELECT
|
||||||
$1,
|
sqlc.arg('name'),
|
||||||
$2,
|
sqlc.arg('description'),
|
||||||
$3,
|
sqlc.arg('thumbnail'),
|
||||||
coalesce((
|
COALESCE(sqlc.narg('sort_order')::int, COALESCE((
|
||||||
SELECT
|
SELECT
|
||||||
max(p.sort_order)
|
max(p.sort_order)
|
||||||
FROM programs AS p), 0) + 1
|
FROM programs AS p), 0) + 1)
|
||||||
RETURNING
|
RETURNING
|
||||||
*;
|
*;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4150,7 +4150,7 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Create a top-level LMS program",
|
"description": "Create a top-level LMS program. Optional sort_order inserts at that global ordering; omit it to append after the current highest sort_order. Unique constraint applies to sort_order.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
|
@ -10563,6 +10563,11 @@ const docTemplate = `{
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"description": "SortOrder inserts at this global program order when set; omit to append after current max (sort_order uniqueness is enforced).",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
"thumbnail": {
|
"thumbnail": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4142,7 +4142,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"post": {
|
"post": {
|
||||||
"description": "Create a top-level LMS program",
|
"description": "Create a top-level LMS program. Optional sort_order inserts at that global ordering; omit it to append after the current highest sort_order. Unique constraint applies to sort_order.",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
|
@ -10555,6 +10555,11 @@
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"sort_order": {
|
||||||
|
"description": "SortOrder inserts at this global program order when set; omit to append after current max (sort_order uniqueness is enforced).",
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
"thumbnail": {
|
"thumbnail": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -468,6 +468,11 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
|
sort_order:
|
||||||
|
description: SortOrder inserts at this global program order when set; omit
|
||||||
|
to append after current max (sort_order uniqueness is enforced).
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
thumbnail:
|
thumbnail:
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
|
|
@ -5230,7 +5235,9 @@ paths:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: Create a top-level LMS program
|
description: Create a top-level LMS program. Optional sort_order inserts at
|
||||||
|
that global ordering; omit it to append after the current highest sort_order.
|
||||||
|
Unique constraint applies to sort_order.
|
||||||
parameters:
|
parameters:
|
||||||
- description: Program
|
- description: Program
|
||||||
in: body
|
in: body
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ SELECT
|
||||||
$1,
|
$1,
|
||||||
$2,
|
$2,
|
||||||
$3,
|
$3,
|
||||||
coalesce((
|
COALESCE($4::int, COALESCE((
|
||||||
SELECT
|
SELECT
|
||||||
max(p.sort_order)
|
max(p.sort_order)
|
||||||
FROM programs AS p), 0) + 1
|
FROM programs AS p), 0) + 1)
|
||||||
RETURNING
|
RETURNING
|
||||||
id, name, description, thumbnail, created_at, updated_at, sort_order
|
id, name, description, thumbnail, created_at, updated_at, sort_order
|
||||||
`
|
`
|
||||||
|
|
@ -29,10 +29,16 @@ type CreateProgramParams struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description pgtype.Text `json:"description"`
|
Description pgtype.Text `json:"description"`
|
||||||
Thumbnail pgtype.Text `json:"thumbnail"`
|
Thumbnail pgtype.Text `json:"thumbnail"`
|
||||||
|
SortOrder pgtype.Int4 `json:"sort_order"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) CreateProgram(ctx context.Context, arg CreateProgramParams) (Program, error) {
|
func (q *Queries) CreateProgram(ctx context.Context, arg CreateProgramParams) (Program, error) {
|
||||||
row := q.db.QueryRow(ctx, CreateProgram, arg.Name, arg.Description, arg.Thumbnail)
|
row := q.db.QueryRow(ctx, CreateProgram,
|
||||||
|
arg.Name,
|
||||||
|
arg.Description,
|
||||||
|
arg.Thumbnail,
|
||||||
|
arg.SortOrder,
|
||||||
|
)
|
||||||
var i Program
|
var i Program
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ import "time"
|
||||||
|
|
||||||
// Program is the top-level container in the LMS hierarchy (e.g. tracks like Beginner / Intermediate / Advanced).
|
// Program is the top-level container in the LMS hierarchy (e.g. tracks like Beginner / Intermediate / Advanced).
|
||||||
type Program struct {
|
type Program struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Thumbnail *string `json:"thumbnail,omitempty"`
|
Thumbnail *string `json:"thumbnail,omitempty"`
|
||||||
SortOrder int `json:"sort_order"`
|
SortOrder int `json:"sort_order"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
UpdatedAt *time.Time `json:"updated_at,omitempty"`
|
||||||
Access *LMSEntityAccess `json:"access,omitempty"`
|
Access *LMSEntityAccess `json:"access,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18,6 +18,8 @@ type CreateProgramInput struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Thumbnail *string `json:"thumbnail,omitempty"`
|
Thumbnail *string `json:"thumbnail,omitempty"`
|
||||||
|
// SortOrder inserts at this global program order when set; omit to append after current max (sort_order uniqueness is enforced).
|
||||||
|
SortOrder *int `json:"sort_order,omitempty" validate:"omitempty,min=0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateProgramInput struct {
|
type UpdateProgramInput struct {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ func (s *Store) CreateProgram(ctx context.Context, input domain.CreateProgramInp
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Description: toPgText(input.Description),
|
Description: toPgText(input.Description),
|
||||||
Thumbnail: toPgText(input.Thumbnail),
|
Thumbnail: toPgText(input.Thumbnail),
|
||||||
|
SortOrder: optionalInt4Update(input.SortOrder),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return domain.Program{}, err
|
return domain.Program{}, err
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
|
|
||||||
// CreateProgram godoc
|
// CreateProgram godoc
|
||||||
// @Summary Create program
|
// @Summary Create program
|
||||||
// @Description Create a top-level LMS program
|
// @Description Create a top-level LMS program. Optional sort_order inserts at that global ordering; omit it to append after the current highest sort_order. Unique constraint applies to sort_order.
|
||||||
// @Tags programs
|
// @Tags programs
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user