syntax = "v1"

type (
	CopyResearchMapData {
		AudienceSummary string   `json:"audience_summary,omitempty"`
		ContentGoal     string   `json:"content_goal,omitempty"`
		Questions       []string `json:"questions,omitempty"`
		Pillars         []string `json:"pillars,omitempty"`
		Exclusions      []string `json:"exclusions,omitempty"`
		SuggestedTags   []string `json:"suggested_tags,omitempty"`
		BenchmarkNotes  string   `json:"benchmark_notes,omitempty"`
	}

	PersonaData {
		ID              string              `json:"id"`
		DisplayName     string              `json:"display_name,omitempty"`
		Persona         string              `json:"persona,omitempty"`
		Brief           string              `json:"brief,omitempty"`
		StyleProfile    string              `json:"style_profile,omitempty"`
		StyleBenchmark  string              `json:"style_benchmark,omitempty"`
		SeedQuery       string              `json:"seed_query,omitempty"`
		CopyResearchMap CopyResearchMapData `json:"copy_research_map,omitempty"`
		CreateAt        int64               `json:"create_at"`
		UpdateAt        int64               `json:"update_at"`
	}

	ListPersonasData {
		List []PersonaData `json:"list"`
	}

	CreatePersonaReq {
		DisplayName string `json:"display_name,optional"`
	}

	PersonaPath {
		ID string `path:"id" validate:"required"`
	}

	UpdatePersonaReq {
		DisplayName    *string `json:"display_name,optional"`
		Persona        *string `json:"persona,optional"`
		Brief          *string `json:"brief,optional"`
		StyleProfile   *string `json:"style_profile,optional"`
		StyleBenchmark *string `json:"style_benchmark,optional"`
	}

	StartPersonaStyleAnalysisReq {
		BenchmarkUsername string `json:"benchmark_username" validate:"required"`
	}

	StartPersonaStyleAnalysisData {
		JobID   string `json:"job_id"`
		Status  string `json:"status"`
		Message string `json:"message"`
	}

	UpdatePersonaHandlerReq {
		PersonaPath
		UpdatePersonaReq
	}

	StartPersonaStyleAnalysisHandlerReq {
		PersonaPath
		StartPersonaStyleAnalysisReq
	}

	StartPersonaStyleAnalysisFromTextReq {
		ReferenceTexts []string `json:"reference_texts,optional"`
		RawText        string   `json:"raw_text,optional"`
		SourceLabel    string   `json:"source_label,optional"`
	}

	StartPersonaStyleAnalysisFromTextData {
		Persona   PersonaData `json:"persona"`
		PostCount int         `json:"post_count"`
		Message   string      `json:"message"`
	}

	StartPersonaStyleAnalysisFromTextHandlerReq {
		PersonaPath
		StartPersonaStyleAnalysisFromTextReq
	}

	StartPersonaViralScanJobReq {
		Keywords []string `json:"keywords,optional"`
	}

	StartPersonaViralScanJobData {
		JobID   string `json:"job_id"`
		Status  string `json:"status"`
		Message string `json:"message"`
	}

	StartPersonaViralScanJobHandlerReq {
		PersonaPath
		StartPersonaViralScanJobReq
	}

	ListPersonaViralScanPostsReq {
		Limit int `form:"limit,optional"`
	}

	ViralScanPostData {
		ID              string          `json:"id"`
		SearchTag       string          `json:"search_tag"`
		Permalink       string          `json:"permalink"`
		Author          string          `json:"author"`
		AuthorVerified  bool            `json:"author_verified,omitempty"`
		FollowerCount   int             `json:"follower_count,omitempty"`
		Text            string          `json:"text"`
		LikeCount       int             `json:"like_count"`
		ReplyCount      int             `json:"reply_count"`
		EngagementScore int             `json:"engagement_score"`
		Source          string          `json:"source"`
		ScanJobID       string          `json:"scan_job_id"`
		Replies         []ScanReplyData `json:"replies,omitempty"`
		CreateAt        int64           `json:"create_at"`
	}

	ListPersonaViralScanPostsData {
		List  []ViralScanPostData `json:"list"`
		Total int                 `json:"total"`
	}

	ListPersonaViralScanPostsHandlerReq {
		PersonaPath
		ListPersonaViralScanPostsReq
	}

	CopyDraftData {
		ID            string   `json:"id"`
		PersonaID     string   `json:"persona_id"`
		ContentPlanID string   `json:"content_plan_id,omitempty"`
		CopyMissionID string   `json:"copy_mission_id,omitempty"`
		ScanPostID    string   `json:"scan_post_id,omitempty"`
		FormulaID     string   `json:"formula_id,omitempty"`
		DraftType     string   `json:"draft_type"`
		SortOrder     int      `json:"sort_order,omitempty"`
		Text       string   `json:"text"`
		TopicTag   string   `json:"topic_tag,omitempty"`
		Angle      string   `json:"angle,omitempty"`
		Hook           string   `json:"hook,omitempty"`
		Rationale      string   `json:"rationale,omitempty"`
		ReferenceNotes string   `json:"reference_notes,omitempty"`
		Sources        []string `json:"sources,omitempty"`
		AiScore             int    `json:"ai_score,omitempty"`
		FormulaScore        int    `json:"formula_score,omitempty"`
		BrandFitScore       int    `json:"brand_fit_score,omitempty"`
		RiskScore           int    `json:"risk_score,omitempty"`
		SimilarityScore     int    `json:"similarity_score,omitempty"`
		EngagementPotential int    `json:"engagement_potential,omitempty"`
		FreshnessScore      int    `json:"freshness_score,omitempty"`
		ReviewSuggestion    string `json:"review_suggestion,omitempty"`
		Status             string `json:"status,omitempty"`
		PublishQueueID     string `json:"publish_queue_id,omitempty"`
		PublishedMediaID   string `json:"published_media_id,omitempty"`
		PublishedPermalink string `json:"published_permalink,omitempty"`
		PublishedAt        int64  `json:"published_at,omitempty"`
		CreateAt           int64  `json:"create_at"`
	}

	ListPersonaCopyDraftsData {
		List  []CopyDraftData `json:"list"`
		Total int             `json:"total"`
	}

	GeneratePersonaCopyDraftReq {
		ScanPostID string `json:"scan_post_id" validate:"required"`
	}

	GeneratePersonaCopyDraftHandlerReq {
		PersonaPath
		GeneratePersonaCopyDraftReq
	}

	GeneratePersonaCopyDraftData {
		Draft   CopyDraftData `json:"draft"`
		Message string        `json:"message"`
	}

	CopyDraftPath {
		ID      string `path:"id" validate:"required"`
		DraftID string `path:"draftId" validate:"required"`
	}

	UpdateCopyDraftReq {
		Text      *string `json:"text,optional"`
		TopicTag  *string `json:"topic_tag,optional"`
		Hook      *string `json:"hook,optional"`
		Angle     *string `json:"angle,optional"`
		Rationale *string `json:"rationale,optional"`
		Status    *string `json:"status,optional"`
	}

	TopicCandidateData {
		ID                   string   `json:"id"`
		PersonaID            string   `json:"persona_id"`
		Name                 string   `json:"name"`
		Source               string   `json:"source,omitempty"`
		Category             string   `json:"category,omitempty"`
		SeedQuery            string   `json:"seed_query,omitempty"`
		TrendReason          string   `json:"trend_reason,omitempty"`
		TrendKeywords        []string `json:"trend_keywords,omitempty"`
		HeatScore            int      `json:"heat_score,omitempty"`
		FitScore             int      `json:"fit_score,omitempty"`
		InteractionScore     int      `json:"interaction_score,omitempty"`
		ExtendScore          int      `json:"extend_score,omitempty"`
		RiskScore            int      `json:"risk_score,omitempty"`
		FinalScore           float64  `json:"final_score,omitempty"`
		RecommendedMissions  []string `json:"recommended_missions,omitempty"`
		Status               string   `json:"status,omitempty"`
		CreateAt             int64    `json:"create_at"`
		UpdateAt             int64    `json:"update_at"`
	}

	ContentPlanData {
		ID                  string   `json:"id"`
		PersonaID           string   `json:"persona_id"`
		TopicCandidateID    string   `json:"topic_candidate_id,omitempty"`
		Topic               string   `json:"topic"`
		Mission             string   `json:"mission"`
		TargetAudience      string   `json:"target_audience,omitempty"`
		Angle               string   `json:"angle,omitempty"`
		OpeningType         string   `json:"opening_type,omitempty"`
		BodyType            string   `json:"body_type,omitempty"`
		Emotion             string   `json:"emotion,omitempty"`
		EndingType          string   `json:"ending_type,omitempty"`
		CtaType             string   `json:"cta_type,omitempty"`
		RiskLevel           string   `json:"risk_level,omitempty"`
		RequiresHumanReview bool     `json:"requires_human_review,omitempty"`
		Avoid               []string `json:"avoid,omitempty"`
		SelectedKnowledge   []string `json:"selected_knowledge,omitempty"`
		Status              string   `json:"status,omitempty"`
		CreateAt            int64    `json:"create_at"`
		UpdateAt            int64    `json:"update_at"`
	}

	FeedbackEventData {
		ID            string `json:"id"`
		PersonaID     string `json:"persona_id"`
		ContentPlanID string `json:"content_plan_id,omitempty"`
		DraftID       string `json:"draft_id,omitempty"`
		Decision      string `json:"decision"`
		Note          string `json:"note,omitempty"`
		Snapshot      string `json:"snapshot,omitempty"`
		CreateAt      int64  `json:"create_at"`
	}

	KnowledgeSourceData {
		ID string `json:"id"`
		PersonaID string `json:"persona_id"`
		SourceType string `json:"source_type"`
		Title string `json:"title,omitempty"`
		Filename string `json:"filename,omitempty"`
		ParsedStatus string `json:"parsed_status,omitempty"`
		ChunkCount int `json:"chunk_count,omitempty"`
		CreateAt int64 `json:"create_at"`
	}

	KnowledgeChunkData {
		ID string `json:"id"`
		PersonaID string `json:"persona_id"`
		SourceID string `json:"source_id"`
		Content string `json:"content"`
		Topics []string `json:"topics,omitempty"`
		StyleTags []string `json:"style_tags,omitempty"`
		RiskLevel string `json:"risk_level,omitempty"`
		CreateAt int64 `json:"create_at"`
	}

	FormulaPoolData {
		ID string `json:"id"`
		PersonaID string `json:"persona_id"`
		Type string `json:"type"`
		Name string `json:"name"`
		Pattern string `json:"pattern,omitempty"`
		UseCases []string `json:"use_cases,omitempty"`
		Avoid []string `json:"avoid,omitempty"`
		Weight int `json:"weight,omitempty"`
		CreateAt int64 `json:"create_at"`
		UpdateAt int64 `json:"update_at"`
	}

	CreateKnowledgeSourceReq {
		SourceType string `json:"source_type" validate:"required"`
		Title string `json:"title,optional"`
		Filename string `json:"filename,optional"`
		Content string `json:"content,optional"`
		ContentBase64 string `json:"content_base64,optional"`
	}

	CreateKnowledgeSourceHandlerReq {
		PersonaPath
		CreateKnowledgeSourceReq
	}

	ListKnowledgeSourcesData { List []KnowledgeSourceData `json:"list"` }
	ListKnowledgeChunksData { List []KnowledgeChunkData `json:"list"` }
	ListFormulaPoolsData { List []FormulaPoolData `json:"list"` }

	CreateFormulaPoolReq {
		Type string `json:"type" validate:"required"`
		Name string `json:"name" validate:"required"`
		Pattern string `json:"pattern,optional"`
		UseCases []string `json:"use_cases,optional"`
		Avoid []string `json:"avoid,optional"`
		Weight int `json:"weight,optional"`
	}

	CreateFormulaPoolHandlerReq {
		PersonaPath
		CreateFormulaPoolReq
	}

	ListTopicCandidatesData {
		List []TopicCandidateData `json:"list"`
	}

	ListContentPlansData {
		List []ContentPlanData `json:"list"`
	}

	CreateContentPlanReq {
		TopicCandidateID    string   `json:"topic_candidate_id,optional"`
		Topic               string   `json:"topic" validate:"required"`
		Mission             string   `json:"mission" validate:"required"`
		TargetAudience      string   `json:"target_audience,optional"`
		Angle               string   `json:"angle,optional"`
		OpeningType         string   `json:"opening_type,optional"`
		BodyType            string   `json:"body_type,optional"`
		Emotion             string   `json:"emotion,optional"`
		EndingType          string   `json:"ending_type,optional"`
		CtaType             string   `json:"cta_type,optional"`
		RiskLevel           string   `json:"risk_level,optional"`
		RequiresHumanReview bool     `json:"requires_human_review,optional"`
		Avoid               []string `json:"avoid,optional"`
		SelectedKnowledge   []string `json:"selected_knowledge,optional"`
	}

	CreateContentPlanHandlerReq {
		PersonaPath
		CreateContentPlanReq
	}

	ContentPlanPath {
		ID            string `path:"id" validate:"required"`
		ContentPlanID string `path:"contentPlanId" validate:"required"`
	}

	UpdateContentPlanReq {
		Topic               *string  `json:"topic,optional"`
		Mission             *string  `json:"mission,optional"`
		TargetAudience      *string  `json:"target_audience,optional"`
		Angle               *string  `json:"angle,optional"`
		OpeningType         *string  `json:"opening_type,optional"`
		BodyType            *string  `json:"body_type,optional"`
		Emotion             *string  `json:"emotion,optional"`
		EndingType          *string  `json:"ending_type,optional"`
		CtaType             *string  `json:"cta_type,optional"`
		RiskLevel           *string  `json:"risk_level,optional"`
		RequiresHumanReview *bool    `json:"requires_human_review,optional"`
		Avoid               []string `json:"avoid,optional"`
		SelectedKnowledge   []string `json:"selected_knowledge,optional"`
		Status              *string  `json:"status,optional"`
	}

	UpdateContentPlanHandlerReq {
		ContentPlanPath
		UpdateContentPlanReq
	}

	CreateFeedbackEventReq {
		ContentPlanID string `json:"content_plan_id,optional"`
		DraftID       string `json:"draft_id,optional"`
		Decision      string `json:"decision" validate:"required"`
		Note          string `json:"note,optional"`
		Snapshot      string `json:"snapshot,optional"`
	}

	CreateFeedbackEventHandlerReq {
		PersonaPath
		CreateFeedbackEventReq
	}

	UpdateCopyDraftHandlerReq {
		CopyDraftPath
		UpdateCopyDraftReq
	}

	PublishCopyDraftReq {
		Text     string `json:"text,optional"`
		TopicTag string `json:"topic_tag,optional"`
		Confirm  bool   `json:"confirm"`
	}

	PublishCopyDraftHandlerReq {
		CopyDraftPath
		PublishCopyDraftReq
	}

	PublishCopyDraftData {
		DraftID   string `json:"draft_id"`
		MediaID   string `json:"media_id"`
		Permalink string `json:"permalink,omitempty"`
		Status    string `json:"status"`
		Message   string `json:"message"`
	}

	ScheduleCopyDraftsReq {
		AccountID string            `json:"account_id" validate:"required"`
		DraftIDs  []string          `json:"draft_ids" validate:"required,min=1"`
		StartAt   int64             `json:"start_at,optional"`
		Timezone  string            `json:"timezone,optional"`
		Slots     []PublishSlotData `json:"slots,optional"`
		Mode      string            `json:"mode,optional"`
	}

	ScheduleCopyDraftsData {
		Scheduled int                    `json:"scheduled"`
		List      []PublishQueueItemData `json:"list"`
		Message   string                 `json:"message"`
	}

	SchedulePersonaDraftsHandlerReq {
		PersonaPath
		ScheduleCopyDraftsReq
	}

	StylePresetData {
		ID          string   `json:"id"`
		PersonaID   string   `json:"persona_id"`
		Name        string   `json:"name"`
		Tone        string   `json:"tone,omitempty"`
		CTA         []string `json:"cta,omitempty"`
		BannedWords []string `json:"banned_words,omitempty"`
		Notes       string   `json:"notes,omitempty"`
		CreateAt    int64    `json:"create_at"`
		UpdateAt    int64    `json:"update_at"`
	}

	ListStylePresetsData {
		List []StylePresetData `json:"list"`
	}

	UpsertStylePresetReq {
		Name        string   `json:"name" validate:"required"`
		Tone        string   `json:"tone,optional"`
		CTA         []string `json:"cta,optional"`
		BannedWords []string `json:"banned_words,optional"`
		Notes       string   `json:"notes,optional"`
		Apply        bool     `json:"apply,optional"`
	}

	StylePresetPath {
		ID       string `path:"id" validate:"required"`
		PresetID string `path:"presetId" validate:"required"`
	}

	UpsertStylePresetHandlerReq {
		StylePresetPath
		UpsertStylePresetReq
	}

	DeleteCopyDraftData {
		DraftID string `json:"draft_id"`
		Message string `json:"message"`
	}

	PrunePersonaCopyDraftsReq {
		Keep int `json:"keep,optional"`
	}

	PrunePersonaCopyDraftsHandlerReq {
		PersonaPath
		PrunePersonaCopyDraftsReq
	}

	PrunePersonaCopyDraftsData {
		Deleted int64  `json:"deleted"`
		Kept    int    `json:"kept"`
		Message string `json:"message"`
	}

	ListPersonaContentInboxReq {
		Page       int64  `form:"page,optional"`
		PageSize   int64  `form:"pageSize,optional"`
		Status     string `form:"status,optional"`
		RangeStart int64  `form:"rangeStart,optional"`
		RangeEnd   int64  `form:"rangeEnd,optional"`
	}

	ListPersonaContentInboxHandlerReq {
		PersonaPath
		ListPersonaContentInboxReq
	}

	ContentInboxItemData {
		CopyDraftData
		ScheduledAt   int64  `json:"scheduled_at,omitempty"`
		Lifecycle     string `json:"lifecycle"`
		GroupDate     int64  `json:"group_date"`
		FormulaLabel  string `json:"formula_label,omitempty"`
	}

	ListPersonaContentInboxData {
		Pagination PaginationData         `json:"pagination"`
		List       []ContentInboxItemData `json:"list"`
	}

	SchedulePersonaCopyDraftReq {
		AccountID   string `json:"account_id" validate:"required"`
		TopicTag    string `json:"topic_tag,optional"`
		ScheduledAt int64  `json:"scheduled_at,optional"`
	}

	SchedulePersonaCopyDraftHandlerReq {
		CopyDraftPath
		SchedulePersonaCopyDraftReq
	}

	ContentFormulaPath {
		ID        string `path:"id" validate:"required"`
		FormulaID string `path:"formulaId" validate:"required"`
	}

	GenerateFromContentFormulaReq {
		AccountID     string `json:"account_id" validate:"required"`
		Topic         string `json:"topic" validate:"required"`
		Brief         string `json:"brief,optional"`
		UseWebSearch  bool   `json:"use_web_search,optional"`
		DraftCount    int    `json:"draft_count,optional"`
	}

	GenerateFromContentFormulaHandlerReq {
		ContentFormulaPath
		GenerateFromContentFormulaReq
	}

	GenerateFromContentFormulaData {
		List    []CopyDraftData `json:"list"`
		Message string          `json:"message"`
	}

	GeneratePersonaTopicMatrixReq {
		Topic         string `json:"topic" validate:"required"`
		ContentPlanID string `json:"content_plan_id,optional"`
		Brief         string `json:"brief,optional"`
		UseWebSearch  bool   `json:"use_web_search,optional"`
		DraftCount    int    `json:"draft_count,optional"`
	}

	GeneratePersonaTopicMatrixHandlerReq {
		PersonaPath
		GeneratePersonaTopicMatrixReq
	}

	GeneratePersonaTopicMatrixData {
		List    []CopyDraftData `json:"list"`
		Message string          `json:"message"`
	}

	StartPersonaTopicMatrixJobHandlerReq {
		PersonaPath
		GeneratePersonaTopicMatrixReq
	}

	StartPersonaTopicMatrixJobData {
		JobID      string `json:"job_id"`
		Status     string `json:"status"`
		AiProvider string `json:"ai_provider"`
		AiModel    string `json:"ai_model"`
		Message    string `json:"message"`
	}

	StartPersonaFormulaDraftJobReq {
		AccountID    string `json:"account_id" validate:"required"`
		FormulaID    string `json:"formula_id" validate:"required"`
		Topic        string `json:"topic" validate:"required"`
		Brief        string `json:"brief,optional"`
		UseWebSearch bool   `json:"use_web_search,optional"`
		DraftCount   int    `json:"draft_count,optional"`
	}

	StartPersonaFormulaDraftJobHandlerReq {
		PersonaPath
		StartPersonaFormulaDraftJobReq
	}

	StartPersonaFormulaDraftJobData {
		JobID      string `json:"job_id"`
		Status     string `json:"status"`
		AiProvider string `json:"ai_provider"`
		AiModel    string `json:"ai_model"`
		Message    string `json:"message"`
	}

	StartPersonaRewriteDraftJobReq {
		AccountID     string `json:"account_id" validate:"required"`
		ReferenceText string `json:"reference_text" validate:"required"`
		Topic         string `json:"topic" validate:"required"`
		Brief         string `json:"brief,optional"`
		SaveLabel     string `json:"save_label,optional"`
		UseWebSearch  bool   `json:"use_web_search,optional"`
		DraftCount    int    `json:"draft_count,optional"`
	}

	StartPersonaRewriteDraftJobHandlerReq {
		PersonaPath
		StartPersonaRewriteDraftJobReq
	}

	StartPersonaRewriteDraftJobData {
		JobID      string `json:"job_id"`
		Status     string `json:"status"`
		AiProvider string `json:"ai_provider"`
		AiModel    string `json:"ai_model"`
		Message    string `json:"message"`
	}
)

@server(
	group:      persona
	prefix:     /api/v1/personas
	middleware: AuthJWT
	tags:       "Persona"
	summary:    "Reusable persona profiles with 8D style strategy. Requires Bearer JWT."
)
service gateway {
	@handler listPersonas
	get / returns (ListPersonasData)

	@handler createPersona
	post / (CreatePersonaReq) returns (PersonaData)

	@handler getPersona
	get /:id (PersonaPath) returns (PersonaData)

	@handler updatePersona
	patch /:id (UpdatePersonaHandlerReq) returns (PersonaData)

	@handler deletePersona
	delete /:id (PersonaPath)

	@handler startPersonaStyleAnalysis
	post /:id/style-analysis (StartPersonaStyleAnalysisHandlerReq) returns (StartPersonaStyleAnalysisData)

	@handler startPersonaStyleAnalysisFromText
	post /:id/style-analysis-from-text (StartPersonaStyleAnalysisFromTextHandlerReq) returns (StartPersonaStyleAnalysisFromTextData)

	@handler startPersonaViralScanJob
	post /:id/viral-scan-jobs (StartPersonaViralScanJobHandlerReq) returns (StartPersonaViralScanJobData)

	@handler listPersonaViralScanPosts
	get /:id/viral-scan-posts (ListPersonaViralScanPostsHandlerReq) returns (ListPersonaViralScanPostsData)

	@handler listPersonaCopyDrafts
	get /:id/copy-drafts (PersonaPath) returns (ListPersonaCopyDraftsData)

	@handler listPersonaContentInbox
	get /:id/content-inbox (ListPersonaContentInboxHandlerReq) returns (ListPersonaContentInboxData)

	@handler listTopicCandidates
	get /:id/topic-candidates (PersonaPath) returns (ListTopicCandidatesData)

	@handler listContentPlans
	get /:id/content-plans (PersonaPath) returns (ListContentPlansData)

	@handler createContentPlan
	post /:id/content-plans (CreateContentPlanHandlerReq) returns (ContentPlanData)

	@handler updateContentPlan
	patch /:id/content-plans/:contentPlanId (UpdateContentPlanHandlerReq) returns (ContentPlanData)

	@handler createFeedbackEvent
	post /:id/feedback-events (CreateFeedbackEventHandlerReq) returns (FeedbackEventData)

	@handler createKnowledgeSource
	post /:id/knowledge-sources (CreateKnowledgeSourceHandlerReq) returns (KnowledgeSourceData)

	@handler listKnowledgeSources
	get /:id/knowledge-sources (PersonaPath) returns (ListKnowledgeSourcesData)

	@handler listKnowledgeChunks
	get /:id/knowledge-chunks (PersonaPath) returns (ListKnowledgeChunksData)

	@handler listFormulaPools
	get /:id/formula-pools (PersonaPath) returns (ListFormulaPoolsData)

	@handler createFormulaPool
	post /:id/formula-pools (CreateFormulaPoolHandlerReq) returns (FormulaPoolData)

	@handler generatePersonaCopyDraft
	post /:id/copy-drafts/generate (GeneratePersonaCopyDraftHandlerReq) returns (GeneratePersonaCopyDraftData)

	@handler updatePersonaCopyDraft
	patch /:id/copy-drafts/:draftId (UpdateCopyDraftHandlerReq) returns (CopyDraftData)

	@handler publishPersonaCopyDraft
	post /:id/copy-drafts/:draftId/publish (PublishCopyDraftHandlerReq) returns (PublishCopyDraftData)

	@handler schedulePersonaDrafts
	post /:id/copy-drafts/schedule (SchedulePersonaDraftsHandlerReq) returns (ScheduleCopyDraftsData)

	@handler schedulePersonaCopyDraft
	post /:id/copy-drafts/:draftId/schedule (SchedulePersonaCopyDraftHandlerReq) returns (ScheduleCopyDraftsData)

	@handler generateFromContentFormula
	post /:id/content-formulas/:formulaId/generate (GenerateFromContentFormulaHandlerReq) returns (GenerateFromContentFormulaData)

	@handler generatePersonaTopicMatrix
	post /:id/topic-matrix/generate (GeneratePersonaTopicMatrixHandlerReq) returns (GeneratePersonaTopicMatrixData)

	@handler startPersonaTopicMatrixJob
	post /:id/topic-matrix/jobs (StartPersonaTopicMatrixJobHandlerReq) returns (StartPersonaTopicMatrixJobData)

	@handler startPersonaFormulaDraftJob
	post /:id/formula-draft/jobs (StartPersonaFormulaDraftJobHandlerReq) returns (StartPersonaFormulaDraftJobData)

	@handler startPersonaRewriteDraftJob
	post /:id/rewrite-draft/jobs (StartPersonaRewriteDraftJobHandlerReq) returns (StartPersonaRewriteDraftJobData)

	@handler deletePersonaCopyDraft
	delete /:id/copy-drafts/:draftId (CopyDraftPath) returns (DeleteCopyDraftData)

	@handler prunePersonaCopyDrafts
	post /:id/copy-drafts/prune (PrunePersonaCopyDraftsHandlerReq) returns (PrunePersonaCopyDraftsData)

	@handler listStylePresets
	get /:id/style-presets (PersonaPath) returns (ListStylePresetsData)

	@handler upsertStylePreset
	put /:id/style-presets/:presetId (UpsertStylePresetHandlerReq) returns (StylePresetData)

	@handler deleteStylePreset
	delete /:id/style-presets/:presetId (StylePresetPath)
}
