Make practice title optional on create.
POST /practices and exam-prep practice create accept missing or null title; persist as empty string. Refresh OpenAPI and document the behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
bd1767d2a6
commit
71bc09a638
|
|
@ -415,6 +415,8 @@ This creates the practice record scoped to lesson.
|
|||
|
||||
### Request
|
||||
|
||||
`title` is optional; omit it or use an empty string to create a practice without a display title (stored as empty).
|
||||
|
||||
Include `publish_status`: `DRAFT` to hide the practice from subscribed learners until you set it to `PUBLISHED` (via create or `PUT /practices/:id`). Omit the field or send `PUBLISHED` to go live immediately (backward compatible).
|
||||
|
||||
```json
|
||||
|
|
|
|||
71
docs/docs.go
71
docs/docs.go
|
|
@ -10434,13 +10434,21 @@ const docTemplate = `{
|
|||
"domain.CreateExamPrepPracticeInput": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"question_set_id",
|
||||
"title"
|
||||
"question_set_id"
|
||||
],
|
||||
"properties": {
|
||||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
@ -10485,11 +10493,19 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"publish_status": {
|
||||
"description": "Omit or DRAFT (default) for drafts; PUBLISHED for learner-visible lessons.",
|
||||
"type": "string"
|
||||
"description": "Omit or empty defaults to DRAFT; set PUBLISHED to make visible to learners immediately.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"sort_order": {
|
||||
"type": "integer"
|
||||
"description": "SortOrder within the module when set; omit to append after current max within module_id.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"thumbnail": {
|
||||
"type": "string"
|
||||
|
|
@ -10516,6 +10532,11 @@ const docTemplate = `{
|
|||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"sort_order": {
|
||||
"description": "SortOrder within the course when set; omit to append after current max within course_id (uniqueness is per-course).",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -10524,8 +10545,7 @@ const docTemplate = `{
|
|||
"required": [
|
||||
"parent_id",
|
||||
"parent_kind",
|
||||
"question_set_id",
|
||||
"title"
|
||||
"question_set_id"
|
||||
],
|
||||
"properties": {
|
||||
"parent_id": {
|
||||
|
|
@ -10546,6 +10566,16 @@ const docTemplate = `{
|
|||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"description": "Omit or empty for backward compatibility defaults to PUBLISHED; set DRAFT to save hidden from learners until published.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
@ -11327,6 +11357,15 @@ const docTemplate = `{
|
|||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
@ -11380,8 +11419,13 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
},
|
||||
"publish_status": {
|
||||
"description": "DRAFT or PUBLISHED",
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"sort_order": {
|
||||
"type": "integer"
|
||||
|
|
@ -11420,6 +11464,15 @@ const docTemplate = `{
|
|||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10426,13 +10426,21 @@
|
|||
"domain.CreateExamPrepPracticeInput": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"question_set_id",
|
||||
"title"
|
||||
"question_set_id"
|
||||
],
|
||||
"properties": {
|
||||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
@ -10477,11 +10485,19 @@
|
|||
"type": "string"
|
||||
},
|
||||
"publish_status": {
|
||||
"description": "Omit or DRAFT (default) for drafts; PUBLISHED for learner-visible lessons.",
|
||||
"type": "string"
|
||||
"description": "Omit or empty defaults to DRAFT; set PUBLISHED to make visible to learners immediately.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"sort_order": {
|
||||
"type": "integer"
|
||||
"description": "SortOrder within the module when set; omit to append after current max within module_id.",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"thumbnail": {
|
||||
"type": "string"
|
||||
|
|
@ -10508,6 +10524,11 @@
|
|||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"sort_order": {
|
||||
"description": "SortOrder within the course when set; omit to append after current max within course_id (uniqueness is per-course).",
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -10516,8 +10537,7 @@
|
|||
"required": [
|
||||
"parent_id",
|
||||
"parent_kind",
|
||||
"question_set_id",
|
||||
"title"
|
||||
"question_set_id"
|
||||
],
|
||||
"properties": {
|
||||
"parent_id": {
|
||||
|
|
@ -10538,6 +10558,16 @@
|
|||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"description": "Omit or empty for backward compatibility defaults to PUBLISHED; set DRAFT to save hidden from learners until published.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
@ -11319,6 +11349,15 @@
|
|||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
@ -11372,8 +11411,13 @@
|
|||
"type": "string"
|
||||
},
|
||||
"publish_status": {
|
||||
"description": "DRAFT or PUBLISHED",
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"sort_order": {
|
||||
"type": "integer"
|
||||
|
|
@ -11412,6 +11456,15 @@
|
|||
"persona_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"publish_status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DRAFT",
|
||||
"draft",
|
||||
"PUBLISHED",
|
||||
"published"
|
||||
]
|
||||
},
|
||||
"question_set_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -389,6 +389,13 @@ definitions:
|
|||
properties:
|
||||
persona_id:
|
||||
type: integer
|
||||
publish_status:
|
||||
enum:
|
||||
- DRAFT
|
||||
- draft
|
||||
- PUBLISHED
|
||||
- published
|
||||
type: string
|
||||
question_set_id:
|
||||
type: integer
|
||||
quick_tips:
|
||||
|
|
@ -401,7 +408,6 @@ definitions:
|
|||
type: string
|
||||
required:
|
||||
- question_set_id
|
||||
- title
|
||||
type: object
|
||||
domain.CreateExamPrepUnitInput:
|
||||
properties:
|
||||
|
|
@ -419,9 +425,18 @@ definitions:
|
|||
description:
|
||||
type: string
|
||||
publish_status:
|
||||
description: Omit or DRAFT (default) for drafts; PUBLISHED for learner-visible lessons.
|
||||
description: Omit or empty defaults to DRAFT; set PUBLISHED to make visible
|
||||
to learners immediately.
|
||||
enum:
|
||||
- DRAFT
|
||||
- draft
|
||||
- PUBLISHED
|
||||
- published
|
||||
type: string
|
||||
sort_order:
|
||||
description: SortOrder within the module when set; omit to append after current
|
||||
max within module_id.
|
||||
minimum: 0
|
||||
type: integer
|
||||
thumbnail:
|
||||
type: string
|
||||
|
|
@ -440,6 +455,11 @@ definitions:
|
|||
type: string
|
||||
name:
|
||||
type: string
|
||||
sort_order:
|
||||
description: SortOrder within the course when set; omit to append after current
|
||||
max within course_id (uniqueness is per-course).
|
||||
minimum: 0
|
||||
type: integer
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
|
|
@ -456,6 +476,15 @@ definitions:
|
|||
- LESSON
|
||||
persona_id:
|
||||
type: integer
|
||||
publish_status:
|
||||
description: Omit or empty for backward compatibility defaults to PUBLISHED;
|
||||
set DRAFT to save hidden from learners until published.
|
||||
enum:
|
||||
- DRAFT
|
||||
- draft
|
||||
- PUBLISHED
|
||||
- published
|
||||
type: string
|
||||
question_set_id:
|
||||
type: integer
|
||||
quick_tips:
|
||||
|
|
@ -470,7 +499,6 @@ definitions:
|
|||
- parent_id
|
||||
- parent_kind
|
||||
- question_set_id
|
||||
- title
|
||||
type: object
|
||||
domain.CreateProgramInput:
|
||||
properties:
|
||||
|
|
@ -996,6 +1024,13 @@ definitions:
|
|||
properties:
|
||||
persona_id:
|
||||
type: integer
|
||||
publish_status:
|
||||
enum:
|
||||
- DRAFT
|
||||
- draft
|
||||
- PUBLISHED
|
||||
- published
|
||||
type: string
|
||||
question_set_id:
|
||||
type: integer
|
||||
quick_tips:
|
||||
|
|
@ -1031,7 +1066,11 @@ definitions:
|
|||
description:
|
||||
type: string
|
||||
publish_status:
|
||||
description: DRAFT or PUBLISHED
|
||||
enum:
|
||||
- DRAFT
|
||||
- draft
|
||||
- PUBLISHED
|
||||
- published
|
||||
type: string
|
||||
sort_order:
|
||||
type: integer
|
||||
|
|
@ -1057,6 +1096,13 @@ definitions:
|
|||
properties:
|
||||
persona_id:
|
||||
type: integer
|
||||
publish_status:
|
||||
enum:
|
||||
- DRAFT
|
||||
- draft
|
||||
- PUBLISHED
|
||||
- published
|
||||
type: string
|
||||
question_set_id:
|
||||
type: integer
|
||||
quick_tips:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ func (p ExamPrepPractice) VisibleToLearners() bool {
|
|||
|
||||
// CreateExamPrepPracticeInput is the body for POST .../exam-prep/lessons/{lessonId}/practices (lesson from path).
|
||||
type CreateExamPrepPracticeInput struct {
|
||||
Title string `json:"title" validate:"required"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
StoryDescription *string `json:"story_description,omitempty"`
|
||||
StoryImage *string `json:"story_image,omitempty"`
|
||||
PersonaID *int64 `json:"persona_id,omitempty"`
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (p Practice) VisibleToLearners() bool {
|
|||
type CreatePracticeInput struct {
|
||||
ParentKind ParentKind `json:"parent_kind" validate:"required,oneof=COURSE MODULE LESSON"`
|
||||
ParentID int64 `json:"parent_id" validate:"required,gt=0"`
|
||||
Title string `json:"title" validate:"required"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
StoryDescription *string `json:"story_description,omitempty"`
|
||||
StoryImage *string `json:"story_image,omitempty"`
|
||||
PersonaID *int64 `json:"persona_id,omitempty"`
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func (s *Store) CreateExamPrepLessonPractice(ctx context.Context, lessonID int64
|
|||
ps := domain.ParsePracticePublishStatusInput(in.PublishStatus)
|
||||
p, err := s.queries.ExamPrepCreateLessonPractice(ctx, dbgen.ExamPrepCreateLessonPracticeParams{
|
||||
UnitModuleLessonID: lessonID,
|
||||
Title: in.Title,
|
||||
Title: derefString(in.Title),
|
||||
StoryDescription: toPgText(in.StoryDescription),
|
||||
StoryImage: toPgText(in.StoryImage),
|
||||
PersonaID: int64PtrToPg8(in.PersonaID),
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ func optionalInt8UpdateID(val *int64) pgtype.Int8 {
|
|||
return pgtype.Int8{Int64: *val, Valid: true}
|
||||
}
|
||||
|
||||
func derefString(p *string) string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
return *p
|
||||
}
|
||||
|
||||
func lmsPracticeToDomain(p dbgen.LmsPractice) domain.Practice {
|
||||
out := domain.Practice{
|
||||
ID: p.ID,
|
||||
|
|
@ -98,7 +105,7 @@ func (s *Store) CreateLmsPractice(
|
|||
CourseID: int64PtrToPg8(courseID),
|
||||
ModuleID: int64PtrToPg8(moduleID),
|
||||
LessonID: int64PtrToPg8(lessonID),
|
||||
Title: in.Title,
|
||||
Title: derefString(in.Title),
|
||||
StoryDescription: toPgText(in.StoryDescription),
|
||||
StoryImage: toPgText(in.StoryImage),
|
||||
PersonaID: int64PtrToPg8(in.PersonaID),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user