// Code generated by goctl. DO NOT EDIT.
// goctl 1.10.1

package types

type AIChatData struct {
	Text         string `json:"text"`
	FinishReason string `json:"finish_reason,optional"`
}

type AIChatReq struct {
	Provider    string      `json:"provider" validate:"required,oneof=opencode-go xai"` // AI provider
	Model       string      `json:"model" validate:"required"`                          // 模型 ID
	System      string      `json:"system,optional"`                                    // system prompt
	Messages    []AIMessage `json:"messages" validate:"required,min=1,dive"`            // 對話訊息
	Temperature *float64    `json:"temperature,optional"`                               // 溫度
	MaxTokens   *int        `json:"max_tokens,optional"`                                // 最大輸出 token
}

type AIMessage struct {
	Role    string `json:"role" validate:"required,oneof=system user assistant"` // 訊息角色
	Content string `json:"content" validate:"required"`                          // 訊息內容
}

type AIProviderModelsData struct {
	ID      string   `json:"id"`
	Label   string   `json:"label"`
	Models  []string `json:"models"`
	Streams bool     `json:"streams"`
	Error   string   `json:"error,optional"` // 拉 models 失敗時的摘要
}

type AIProviderOption struct {
	ID      string `json:"id"`
	Label   string `json:"label"`
	Streams bool   `json:"streams"`
}

type AIProviderPath struct {
	Provider string `path:"provider" validate:"required,oneof=opencode-go xai"` // 要查模型的 provider
}

type AIProvidersData struct {
	Providers []AIProviderOption `json:"providers"`
}

type AnalyzeStyle8DData struct {
	PersonaID      string `json:"persona_id"`
	PostCount      int    `json:"post_count"`
	StyleProfile   string `json:"style_profile"`
	StyleBenchmark string `json:"style_benchmark"`
}

type AnalyzeStyle8DPostReq struct {
	Text       string `json:"text"`
	Permalink  string `json:"permalink,optional"`
	LikeCount  int    `json:"like_count,optional"`
	ReplyCount int    `json:"reply_count,optional"`
}

type AnalyzeStyle8DReq struct {
	ID               string                  `path:"id" validate:"required"`
	WorkerID         string                  `json:"worker_id" validate:"required"`
	TenantID         string                  `json:"tenant_id" validate:"required"`
	OwnerUID         string                  `json:"owner_uid" validate:"required"`
	PersonaID        string                  `json:"persona_id" validate:"required"`
	ThreadsAccountID string                  `json:"threads_account_id" validate:"required"`
	Username         string                  `json:"username" validate:"required"`
	Posts            []AnalyzeStyle8DPostReq `json:"posts" validate:"required"`
	Steps            []JobStepProgressData   `json:"steps,optional"`
}

type AuthLoginReq struct {
	TenantID string `json:"tenant_id" validate:"required"`
	Email    string `json:"email" validate:"required,email"`
	Password string `json:"password" validate:"required,min=8,max=128"`
}

type AuthRefreshReq struct {
	RefreshToken string `json:"refresh_token" validate:"required"`
}

type AuthRegisterReq struct {
	TenantID    string `json:"tenant_id" validate:"required"`
	Email       string `json:"email" validate:"required,email"`
	Password    string `json:"password" validate:"required,min=8,max=128"`
	DisplayName string `json:"display_name,optional"`
	Language    string `json:"language,optional"`
}

type AuthTokenData struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpiresIn    int64  `json:"expires_in"`
	UID          string `json:"uid"`
	TokenType    string `json:"token_type"`
}

type BatchDeletePlacementTopicScanPostsData struct {
	DeletedCount int `json:"deleted_count"`
}

type BatchDeletePlacementTopicScanPostsHandlerReq struct {
	PlacementTopicPath
	BatchDeletePlacementTopicScanPostsReq
}

type BatchDeletePlacementTopicScanPostsReq struct {
	PostIDs []string `json:"post_ids" validate:"required"`
}

type BrandData struct {
	ID             string             `json:"id"`
	DisplayName    string             `json:"display_name,omitempty"`
	TopicName      string             `json:"topic_name,omitempty"`
	SeedQuery      string             `json:"seed_query,omitempty"`
	Brief          string             `json:"brief,omitempty"`
	ProductBrief   string             `json:"product_brief,omitempty"`
	ProductContext string             `json:"product_context,omitempty"`
	ProductID      string             `json:"product_id,omitempty"`
	Products       []BrandProductData `json:"products,omitempty"`
	TargetAudience string             `json:"target_audience,omitempty"`
	Goals          string             `json:"goals,omitempty"`
	ResearchMap    ResearchMapData    `json:"research_map,omitempty"`
	CreateAt       int64              `json:"create_at"`
	UpdateAt       int64              `json:"update_at"`
}

type BrandPath struct {
	ID string `path:"id" validate:"required"`
}

type BrandProductData struct {
	ID             string   `json:"id"`
	Label          string   `json:"label"`
	ProductContext string   `json:"product_context"`
	MatchTags      []string `json:"match_tags,omitempty"`
	CreateAt       int64    `json:"create_at"`
	UpdateAt       int64    `json:"update_at"`
}

type BrandProductPath struct {
	ID        string `path:"id" validate:"required"`
	ProductID string `path:"productId" validate:"required"`
}

type BrandScanScheduleData struct {
	ID        string `json:"id,omitempty"`
	BrandID   string `json:"brand_id"`
	Cron      string `json:"cron"`
	Timezone  string `json:"timezone"`
	Enabled   bool   `json:"enabled"`
	NextRunAt int64  `json:"next_run_at,omitempty"`
	LastRunAt int64  `json:"last_run_at,omitempty"`
}

type BraveSourceData struct {
	Query   string `json:"query,omitempty"`
	Title   string `json:"title,omitempty"`
	URL     string `json:"url,omitempty"`
	Snippet string `json:"snippet,omitempty"`
}

type CancelJobReq struct {
	ID     string `path:"id" validate:"required"` // job run id
	Reason string `json:"reason,optional"`        // cancel reason
}

type ClaimWorkerJobReq struct {
	WorkerType string `json:"worker_type" validate:"required"`
	WorkerID   string `json:"worker_id" validate:"required"`
}

type ContentMatrixData struct {
	ID          string                 `json:"id,omitempty"`
	BrandID     string                 `json:"brand_id"`
	Rows        []ContentMatrixRowData `json:"rows"`
	GeneratedAt int64                  `json:"generated_at"`
	CreateAt    int64                  `json:"create_at,omitempty"`
	UpdateAt    int64                  `json:"update_at,omitempty"`
}

type ContentMatrixRowData struct {
	SortOrder        int      `json:"sort_order"`
	SearchTag        string   `json:"search_tag"`
	Angle            string   `json:"angle"`
	Hook             string   `json:"hook"`
	Text             string   `json:"text"`
	ReferenceNotes   string   `json:"reference_notes"`
	SourcePermalinks []string `json:"source_permalinks"`
	Rationale        string   `json:"rationale"`
}

type CopyDraftData struct {
	ID                 string   `json:"id"`
	PersonaID          string   `json:"persona_id"`
	CopyMissionID      string   `json:"copy_mission_id,omitempty"`
	ScanPostID         string   `json:"scan_post_id,omitempty"`
	DraftType          string   `json:"draft_type"`
	SortOrder          int      `json:"sort_order,omitempty"`
	Text               string   `json:"text"`
	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"`
	Status             string   `json:"status,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"`
}

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

type CopyMissionData struct {
	ID            string                     `json:"id"`
	PersonaID     string                     `json:"persona_id"`
	Label         string                     `json:"label,omitempty"`
	SeedQuery     string                     `json:"seed_query,omitempty"`
	Brief         string                     `json:"brief,omitempty"`
	ResearchMap   CopyMissionResearchMapData `json:"research_map,omitempty"`
	SelectedTags  []string                   `json:"selected_tags,omitempty"`
	LastScanJobID string                     `json:"last_scan_job_id,omitempty"`
	Status        string                     `json:"status,omitempty"`
	CreateAt      int64                      `json:"create_at"`
	UpdateAt      int64                      `json:"update_at"`
}

type CopyMissionInspirationData struct {
	Label         string                             `json:"label"`
	SeedQuery     string                             `json:"seed_query"`
	Brief         string                             `json:"brief"`
	TrendReason   string                             `json:"trend_reason,omitempty"`
	TrendKeywords []string                           `json:"trend_keywords,omitempty"`
	Sources       []CopyMissionInspirationSourceData `json:"sources,omitempty"`
	WebSearchUsed bool                               `json:"web_search_used"`
	Message       string                             `json:"message"`
}

type CopyMissionInspirationSourceData struct {
	Query   string `json:"query,omitempty"`
	Title   string `json:"title,omitempty"`
	Snippet string `json:"snippet,omitempty"`
	URL     string `json:"url,omitempty"`
}

type CopyMissionPath struct {
	PersonaID string `path:"personaId" validate:"required"`
	ID        string `path:"id" validate:"required"`
}

type CopyMissionResearchMapData struct {
	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   []CopySuggestedTagData   `json:"suggested_tags,omitempty"`
	SimilarAccounts []CopySimilarAccountData `json:"similar_accounts,omitempty"`
	BenchmarkNotes  string                   `json:"benchmark_notes,omitempty"`
}

type CopyMissionScanScheduleData struct {
	ID        string `json:"id,omitempty"`
	PersonaID string `json:"persona_id"`
	MissionID string `json:"mission_id"`
	Cron      string `json:"cron"`
	Timezone  string `json:"timezone"`
	Enabled   bool   `json:"enabled"`
	NextRunAt int64  `json:"next_run_at,omitempty"`
	LastRunAt int64  `json:"last_run_at,omitempty"`
}

type CopyResearchMapData struct {
	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"`
}

type CopySimilarAccountData struct {
	Username        string `json:"username"`
	Reason          string `json:"reason,omitempty"`
	Source          string `json:"source,omitempty"`
	Confidence      string `json:"confidence,omitempty"`
	ProfileUrl      string `json:"profile_url,omitempty"`
	AuthorVerified  bool   `json:"author_verified,omitempty"`
	FollowerCount   int    `json:"follower_count,omitempty"`
	EngagementScore int    `json:"engagement_score,omitempty"`
	LikeCount       int    `json:"like_count,omitempty"`
	ReplyCount      int    `json:"reply_count,omitempty"`
	PostCount       int    `json:"post_count,omitempty"`
}

type CopySuggestedTagData struct {
	Tag          string `json:"tag"`
	Reason       string `json:"reason,omitempty"`
	SearchIntent string `json:"search_intent,omitempty"`
	SearchType   string `json:"search_type,omitempty"`
}

type CreateBrandProductHandlerReq struct {
	BrandPath
	CreateBrandProductReq
}

type CreateBrandProductReq struct {
	Label          string   `json:"label" validate:"required"`
	ProductContext string   `json:"product_context" validate:"required"`
	MatchTags      []string `json:"match_tags,optional"`
}

type CreateBrandReq struct {
	DisplayName string `json:"display_name,optional"`
}

type CreateCopyMissionHandlerReq struct {
	PersonaCopyMissionsPath
	CreateCopyMissionReq
}

type CreateCopyMissionReq struct {
	Label     string `json:"label" validate:"required"`
	SeedQuery string `json:"seed_query" validate:"required"`
	Brief     string `json:"brief" validate:"required"`
}

type CreateJobReq struct {
	TemplateType string                 `json:"template_type" validate:"required"`                                 // job template type
	Scope        string                 `json:"scope" validate:"required,oneof=user account system persona brand"` // job scope
	ScopeID      string                 `json:"scope_id" validate:"required"`                                      // scope id
	Payload      map[string]interface{} `json:"payload,optional"`                                                  // job payload
}

type CreateJobScheduleReq struct {
	TemplateType    string                 `json:"template_type" validate:"required"`                                 // template type
	Scope           string                 `json:"scope" validate:"required,oneof=user account system persona brand"` // scope
	ScopeID         string                 `json:"scope_id" validate:"required"`                                      // scope id
	Cron            string                 `json:"cron" validate:"required"`                                          // cron expression
	Timezone        string                 `json:"timezone,optional"`                                                 // timezone
	PayloadTemplate map[string]interface{} `json:"payload_template,optional"`                                         // payload template
	Enabled         bool                   `json:"enabled"`                                                           // enabled flag
}

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

type CreatePlacementTopicHandlerReq struct {
	CreatePlacementTopicReq
}

type CreatePlacementTopicReq struct {
	BrandID   string `json:"brand_id" validate:"required"`
	TopicName string `json:"topic_name" validate:"required"`
	SeedQuery string `json:"seed_query" validate:"required"`
	Brief     string `json:"brief" validate:"required"`
	ProductID string `json:"product_id,optional"`
}

type CreateThreadsAccountReq struct {
	DisplayName string `json:"display_name,optional"`
	Activate    *bool  `json:"activate,optional"`
}

type DeletePlacementTopicScanPostHandlerReq struct {
	PlacementTopicPath
	PostID string `path:"postId" validate:"required"`
}

type ErrorDetail struct {
	BizCode  string `json:"biz_code,optional"`
	Scope    int64  `json:"scope,optional"`
	Category int64  `json:"category,optional"`
	Detail   int64  `json:"detail,optional"`
}

type ExpandKnowledgeGraphData struct {
	JobID   string `json:"job_id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

type ExpandKnowledgeGraphHandlerReq struct {
	BrandPath
	ExpandKnowledgeGraphReq
}

type ExpandKnowledgeGraphReq struct {
	SeedQuery      string `json:"seed_query" validate:"required"`
	Supplemental   bool   `json:"supplemental,optional"`
	RegenerateMap  bool   `json:"regenerate_map,optional"`
	ExpandStrategy string `json:"expand_strategy,optional"` // brave | llm | hybrid
}

type ExpandPlacementTopicGraphHandlerReq struct {
	PlacementTopicPath
	ExpandKnowledgeGraphReq
}

type GenerateContentMatrixHandlerReq struct {
	BrandPath
	GenerateContentMatrixReq
}

type GenerateContentMatrixReq struct {
	Count int `json:"count,optional"`
}

type GenerateCopyMissionMatrixData struct {
	Drafts  []CopyDraftData `json:"drafts"`
	Message string          `json:"message"`
}

type GenerateCopyMissionMatrixHandlerReq struct {
	CopyMissionPath
	GenerateCopyMissionMatrixReq
}

type GenerateCopyMissionMatrixReq struct {
	Count int `json:"count,optional"`
}

type GenerateOutreachDraftsData struct {
	ID         string                  `json:"id"`
	ScanPostID string                  `json:"scan_post_id"`
	Relevance  float64                 `json:"relevance"`
	Reason     string                  `json:"reason"`
	Drafts     []OutreachDraftItemData `json:"drafts"`
	CreateAt   int64                   `json:"create_at"`
}

type GenerateOutreachDraftsHandlerReq struct {
	BrandPath
	GenerateOutreachDraftsReq
}

type GenerateOutreachDraftsReq struct {
	ScanPostID     string `json:"scan_post_id" validate:"required"`
	TopicID        string `json:"topic_id,optional"`
	Count          int    `json:"count,optional"`
	VoicePersonaID string `json:"voice_persona_id,optional"`
	ProductID      string `json:"product_id,optional"`
}

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

type GeneratePersonaCopyDraftHandlerReq struct {
	PersonaPath
	GeneratePersonaCopyDraftReq
}

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

type GeneratePlacementTopicContentMatrixHandlerReq struct {
	PlacementTopicPath
	GenerateContentMatrixReq
}

type GeneratePlacementTopicOutreachDraftsHandlerReq struct {
	PlacementTopicPath
	GenerateOutreachDraftsReq
}

type HealthData struct {
	Pong string `json:"pong"`
}

type ImportThreadsAccountSessionData struct {
	Success   bool   `json:"success"`
	Valid     bool   `json:"valid"`
	Synced    bool   `json:"synced"`
	AccountID string `json:"account_id"`
	Username  string `json:"username,omitempty"`
	Message   string `json:"message"`
	UpdateAt  int64  `json:"update_at"`
}

type ImportThreadsAccountSessionHandlerReq struct {
	ThreadsAccountPath
	ImportThreadsAccountSessionReq
}

type ImportThreadsAccountSessionReq struct {
	StorageState string `json:"storageState" validate:"required"`
}

type IslanderChatReq struct {
	Messages []AIMessage `json:"messages" validate:"required,min=1,dive"` // 對話訊息
	Context  string      `json:"context,optional"`                        // 目前頁面與站內導覽快照
}

type JobCancelPolicyData struct {
	Supported    bool   `json:"supported"`
	Mode         string `json:"mode"`
	GraceSeconds int    `json:"grace_seconds"`
}

type JobData struct {
	ID                string                 `json:"id"`
	TemplateType      string                 `json:"template_type"`
	TemplateVersion   int                    `json:"template_version"`
	Scope             string                 `json:"scope"`
	ScopeID           string                 `json:"scope_id"`
	Status            string                 `json:"status"`
	Phase             string                 `json:"phase"`
	WorkerType        string                 `json:"worker_type"`
	Payload           map[string]interface{} `json:"payload"`
	Progress          JobProgressData        `json:"progress"`
	Result            map[string]interface{} `json:"result,optional"`
	Error             string                 `json:"error,optional"`
	Attempt           int                    `json:"attempt"`
	MaxAttempts       int                    `json:"max_attempts"`
	CancelRequestedAt *int64                 `json:"cancel_requested_at,optional"`
	CancelReason      string                 `json:"cancel_reason,optional"`
	StartedAt         *int64                 `json:"started_at,optional"`
	CompletedAt       *int64                 `json:"completed_at,optional"`
	CreateAt          int64                  `json:"create_at"`
	UpdateAt          int64                  `json:"update_at"`
}

type JobEventData struct {
	ID       string                 `json:"id"`
	JobID    string                 `json:"job_id"`
	Type     string                 `json:"type"`
	From     string                 `json:"from,optional"`
	To       string                 `json:"to,optional"`
	Message  string                 `json:"message"`
	Metadata map[string]interface{} `json:"metadata,optional"`
	CreateAt int64                  `json:"create_at"`
}

type JobEventListData struct {
	List []JobEventData `json:"list"`
}

type JobIDPath struct {
	ID string `path:"id" validate:"required"` // job run id
}

type JobListData struct {
	Pagination PaginationData `json:"pagination"`
	List       []JobData      `json:"list"`
}

type JobProgressData struct {
	Summary    string                `json:"summary"`
	Percentage int                   `json:"percentage"`
	Steps      []JobStepProgressData `json:"steps"`
}

type JobRetryPolicyData struct {
	MaxAttempts    int   `json:"max_attempts"`
	BackoffSeconds []int `json:"backoff_seconds"`
}

type JobScheduleData struct {
	ID              string                 `json:"id"`
	TemplateType    string                 `json:"template_type"`
	Scope           string                 `json:"scope"`
	ScopeID         string                 `json:"scope_id"`
	Enabled         bool                   `json:"enabled"`
	Cron            string                 `json:"cron"`
	Timezone        string                 `json:"timezone"`
	PayloadTemplate map[string]interface{} `json:"payload_template"`
	LastRunAt       *int64                 `json:"last_run_at,optional"`
	NextRunAt       int64                  `json:"next_run_at"`
	CreateAt        int64                  `json:"create_at"`
	UpdateAt        int64                  `json:"update_at"`
}

type JobScheduleIDPath struct {
	ID string `path:"id" validate:"required"` // schedule id
}

type JobScheduleListData struct {
	Pagination PaginationData    `json:"pagination"`
	List       []JobScheduleData `json:"list"`
}

type JobStepProgressData struct {
	ID        string `json:"id"`
	Status    string `json:"status"`
	StartedAt *int64 `json:"started_at,optional"`
	EndedAt   *int64 `json:"ended_at,optional"`
	Message   string `json:"message,optional"`
}

type JobTemplateData struct {
	Type              string                `json:"type"`
	Version           int                   `json:"version"`
	Name              string                `json:"name"`
	Description       string                `json:"description"`
	Enabled           bool                  `json:"enabled"`
	Repeatable        bool                  `json:"repeatable"`
	ConcurrencyPolicy string                `json:"concurrency_policy"`
	DedupeKeys        []string              `json:"dedupe_keys"`
	TimeoutSeconds    int                   `json:"timeout_seconds"`
	CancelPolicy      JobCancelPolicyData   `json:"cancel_policy"`
	RetryPolicy       JobRetryPolicyData    `json:"retry_policy"`
	Steps             []JobTemplateStepData `json:"steps"`
}

type JobTemplateListData struct {
	List []JobTemplateData `json:"list"`
}

type JobTemplatePath struct {
	Type string `path:"type" validate:"required"` // template type
}

type JobTemplateStepData struct {
	ID             string `json:"id"`
	Name           string `json:"name"`
	WorkerType     string `json:"worker_type"`
	TimeoutSeconds int    `json:"timeout_seconds"`
	Cancelable     bool   `json:"cancelable"`
}

type KnowledgeGraphData struct {
	ID             string                   `json:"id"`
	BrandID        string                   `json:"brand_id"`
	Seed           string                   `json:"seed"`
	Nodes          []KnowledgeGraphNodeData `json:"nodes"`
	Edges          []KnowledgeGraphEdgeData `json:"edges"`
	BraveSources   []BraveSourceData        `json:"brave_sources,omitempty"`
	ExpandStrategy string                   `json:"expand_strategy,omitempty"`
	PainTagCount   int                      `json:"pain_tag_count"`
	GeneratedAt    int64                    `json:"generated_at"`
	CreateAt       int64                    `json:"create_at"`
	UpdateAt       int64                    `json:"update_at"`
}

type KnowledgeGraphEdgeData struct {
	From     string `json:"from"`
	To       string `json:"to"`
	Relation string `json:"relation"`
}

type KnowledgeGraphEvidenceData struct {
	URL     string `json:"url,omitempty"`
	Snippet string `json:"snippet,omitempty"`
	Query   string `json:"query,omitempty"`
}

type KnowledgeGraphNodeData struct {
	ID              string                       `json:"id"`
	Label           string                       `json:"label"`
	NodeKind        string                       `json:"node_kind"`
	Type            string                       `json:"type"`
	Layer           int                          `json:"layer"`
	Relation        string                       `json:"relation,omitempty"`
	PlacementValue  string                       `json:"placement_value,omitempty"`
	ProductFitScore int                          `json:"product_fit_score"`
	SelectedForScan bool                         `json:"selected_for_scan"`
	RelevanceTags   []string                     `json:"relevance_tags"`
	RecencyTags     []string                     `json:"recency_tags"`
	Evidence        []KnowledgeGraphEvidenceData `json:"evidence,omitempty"`
}

type KnowledgeGraphNodeUpdate struct {
	NodeID          string   `json:"node_id" validate:"required"`
	SelectedForScan *bool    `json:"selected_for_scan,optional"`
	RelevanceTags   []string `json:"relevance_tags,optional"`
	RecencyTags     []string `json:"recency_tags,optional"`
}

type ListBrandProductsData struct {
	List []BrandProductData `json:"list"`
}

type ListBrandScanPostsData struct {
	List  []ScanPostData `json:"list"`
	Total int            `json:"total"`
}

type ListBrandScanPostsHandlerReq struct {
	BrandPath
	ListBrandScanPostsReq
}

type ListBrandScanPostsReq struct {
	Priority      string `form:"priority,optional"`
	Recent7d      bool   `form:"recent_7d,optional"`
	ProductFitMin int    `form:"product_fit_min,optional"`
	Limit         int    `form:"limit,optional"`
}

type ListBrandsData struct {
	List []BrandData `json:"list"`
}

type ListCopyMissionCopyDraftsData struct {
	List  []CopyDraftData `json:"list"`
	Total int             `json:"total"`
}

type ListCopyMissionScanPostsHandlerReq struct {
	CopyMissionPath
	ListCopyMissionScanPostsReq
}

type ListCopyMissionScanPostsReq struct {
	Limit int `form:"limit,optional"`
}

type ListCopyMissionsData struct {
	List []CopyMissionData `json:"list"`
}

type ListJobEventsReq struct {
	ID    string `path:"id" validate:"required"` // job run id
	Limit int64  `form:"limit,optional"`         // max events
}

type ListJobSchedulesReq struct {
	Scope    string `form:"scope,optional"`    // filter by scope
	ScopeID  string `form:"scope_id,optional"` // filter by scope id
	Page     int64  `form:"page,optional"`     // page number starting at 1
	PageSize int64  `form:"pageSize,optional"` // page size
}

type ListJobsReq struct {
	Scope    string `form:"scope,optional"`    // filter by scope
	ScopeID  string `form:"scope_id,optional"` // filter by scope id
	Page     int64  `form:"page,optional"`     // page number starting at 1
	PageSize int64  `form:"pageSize,optional"` // page size
}

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

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

type ListPersonaViralScanPostsHandlerReq struct {
	PersonaPath
	ListPersonaViralScanPostsReq
}

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

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

type ListPlacementTopicScanPostsHandlerReq struct {
	PlacementTopicPath
	ListBrandScanPostsReq
}

type ListPlacementTopicsData struct {
	List []PlacementTopicData `json:"list"`
}

type ListThreadsAccountsData struct {
	List            []ThreadsAccountData `json:"list"`
	ActiveAccountID string               `json:"active_account_id"`
}

type LogoutData struct {
	OK bool `json:"ok"`
}

type MePermissionsData struct {
	UID         string            `json:"uid"`
	TenantID    string            `json:"tenant_id"`
	Roles       []string          `json:"roles"`
	Permissions map[string]string `json:"permissions"`
	Tree        []PermissionNode  `json:"tree,omitempty"`
}

type MePermissionsQuery struct {
	IncludeTree bool `form:"include_tree,optional"`
}

type MemberMeData struct {
	TenantID              string   `json:"tenant_id"`
	UID                   string   `json:"uid"`
	Email                 string   `json:"email"`
	DisplayName           string   `json:"display_name,omitempty"`
	Avatar                string   `json:"avatar,omitempty"`
	Phone                 string   `json:"phone,omitempty"`
	Language              string   `json:"language,omitempty"`
	Currency              string   `json:"currency,omitempty"`
	Status                string   `json:"status"`
	Origin                string   `json:"origin"`
	Roles                 []string `json:"roles,omitempty"`
	BusinessEmail         string   `json:"business_email,omitempty"`
	BusinessEmailVerified bool     `json:"business_email_verified"`
	BusinessPhone         string   `json:"business_phone,omitempty"`
	BusinessPhoneVerified bool     `json:"business_phone_verified"`
	CreateAt              int64    `json:"create_at"`
	UpdateAt              int64    `json:"update_at"`
}

type MemberPlacementSettingsData struct {
	WebSearchProvider     string `json:"web_search_provider"` // brave | exa
	BraveAPIKey           string `json:"brave_api_key,omitempty"`
	BraveAPIKeyConfigured bool   `json:"brave_api_key_configured"`
	ExaAPIKey             string `json:"exa_api_key,omitempty"`
	ExaAPIKeyConfigured   bool   `json:"exa_api_key_configured"`
	BraveCountry          string `json:"brave_country"`
	BraveSearchLang       string `json:"brave_search_lang"`
	ExaUserLocation       string `json:"exa_user_location"`
	ExpandStrategy        string `json:"expand_strategy"` // brave | llm | hybrid
}

type OutreachDraftItemData struct {
	Text      string `json:"text"`
	Angle     string `json:"angle"`
	Rationale string `json:"rationale"`
}

type PaginationData struct {
	Total      int64 `json:"total"`
	Page       int64 `json:"page"`
	PageSize   int64 `json:"pageSize"`
	TotalPages int64 `json:"totalPages"`
}

type PatchKnowledgeGraphNodesHandlerReq struct {
	BrandPath
	PatchKnowledgeGraphNodesReq
}

type PatchKnowledgeGraphNodesReq struct {
	Updates []KnowledgeGraphNodeUpdate `json:"updates" validate:"required"`
}

type PatchPlacementTopicGraphNodesHandlerReq struct {
	PlacementTopicPath
	PatchKnowledgeGraphNodesReq
}

type PatchPlacementTopicScanPostOutreachHandlerReq struct {
	PlacementTopicPath
	PostID string `path:"postId"`
	PatchScanPostOutreachReq
}

type PatchScanPostOutreachHandlerReq struct {
	BrandPath
	PostID string `path:"postId"`
	PatchScanPostOutreachReq
}

type PatchScanPostOutreachReq struct {
	OutreachStatus *string `json:"outreach_status,optional"`
}

type PermissionCatalogData struct {
	Tree []PermissionNode `json:"tree,omitempty"`
	List []PermissionNode `json:"list,omitempty"`
}

type PermissionCatalogQuery struct {
	Status string `form:"status,optional" validate:"omitempty,oneof=open close"`
	Type   string `form:"type,optional" validate:"omitempty,oneof=backend_user frontend_user"`
	Tree   bool   `form:"tree,optional"`
}

type PermissionNode struct {
	ID          string           `json:"id"`
	Parent      string           `json:"parent,omitempty"`
	Name        string           `json:"name"`
	HTTPMethods string           `json:"http_methods,omitempty"`
	HTTPPath    string           `json:"http_path,omitempty"`
	Status      string           `json:"status"`
	Type        string           `json:"type"`
	Children    []PermissionNode `json:"children,omitempty"`
}

type PersonaCopyMissionsPath struct {
	PersonaID string `path:"personaId" validate:"required"`
}

type PersonaData struct {
	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"`
}

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

type PlacementTopicData struct {
	ID               string          `json:"id"`
	BrandID          string          `json:"brand_id"`
	BrandDisplayName string          `json:"brand_display_name,omitempty"`
	TopicName        string          `json:"topic_name,omitempty"`
	SeedQuery        string          `json:"seed_query,omitempty"`
	Brief            string          `json:"brief,omitempty"`
	ProductID        string          `json:"product_id,omitempty"`
	ResearchMap      ResearchMapData `json:"research_map,omitempty"`
	CreateAt         int64           `json:"create_at"`
	UpdateAt         int64           `json:"update_at"`
}

type PlacementTopicPath struct {
	ID string `path:"id" validate:"required"`
}

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

type PublishCopyDraftHandlerReq struct {
	CopyDraftPath
	PublishCopyDraftReq
}

type PublishCopyDraftReq struct {
	Text    string `json:"text,optional"`
	Confirm bool   `json:"confirm"`
}

type PublishOutreachDraftData struct {
	ScanPostID         string `json:"scan_post_id"`
	ReplyID            string `json:"reply_id"`
	Permalink          string `json:"permalink"`
	OutreachStatus     string `json:"outreach_status"`
	PublishedPermalink string `json:"published_permalink"`
	Message            string `json:"message"`
}

type PublishOutreachDraftHandlerReq struct {
	BrandPath
	PublishOutreachDraftReq
}

type PublishOutreachDraftReq struct {
	ScanPostID string `json:"scan_post_id" validate:"required"`
	Text       string `json:"text" validate:"required"`
	Confirm    bool   `json:"confirm"`
}

type PublishPlacementTopicOutreachDraftHandlerReq struct {
	PlacementTopicPath
	PublishOutreachDraftReq
}

type ResearchItemData struct {
	Title   string `json:"title,omitempty"`
	URL     string `json:"url,omitempty"`
	Snippet string `json:"snippet,omitempty"`
	Query   string `json:"query,omitempty"`
}

type ResearchMapData struct {
	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"`
	ResearchItems   []ResearchItemData `json:"research_items,omitempty"`
	ExpandStrategy  string             `json:"expand_strategy,omitempty"`
	PatrolKeywords  []string           `json:"patrol_keywords,omitempty"`
}

type ScanPostData struct {
	ID                 string                      `json:"id"`
	GraphNodeID        string                      `json:"graph_node_id"`
	SearchTag          string                      `json:"search_tag"`
	QueryDimension     string                      `json:"query_dimension"`
	ExternalID         string                      `json:"external_id"`
	Permalink          string                      `json:"permalink"`
	Author             string                      `json:"author"`
	Text               string                      `json:"text"`
	Priority           string                      `json:"priority"`
	PlacementScore     int                         `json:"placement_score"`
	ProductFitScore    int                         `json:"product_fit_score"`
	SolvedByProduct    bool                        `json:"solved_by_product"`
	Source             string                      `json:"source"`
	ScanJobID          string                      `json:"scan_job_id"`
	OutreachStatus     string                      `json:"outreach_status,omitempty"`
	PublishedReplyID   string                      `json:"published_reply_id,omitempty"`
	PublishedPermalink string                      `json:"published_permalink,omitempty"`
	OutreachUpdateAt   int64                       `json:"outreach_update_at,omitempty"`
	PostedAt           string                      `json:"posted_at,omitempty"`
	Replies            []ScanReplyData             `json:"replies,omitempty"`
	LatestDraft        *GenerateOutreachDraftsData `json:"latest_draft,omitempty"`
	CreateAt           int64                       `json:"create_at"`
}

type ScanReplyData struct {
	ExternalID string `json:"external_id,omitempty"`
	Author     string `json:"author,omitempty"`
	Text       string `json:"text"`
	Permalink  string `json:"permalink,omitempty"`
	LikeCount  int    `json:"like_count,omitempty"`
	PostedAt   string `json:"posted_at,omitempty"`
}

type SettingData struct {
	ID       string                 `json:"id"`
	Scope    string                 `json:"scope"`
	ScopeID  string                 `json:"scope_id"`
	Key      string                 `json:"key"`
	Value    map[string]interface{} `json:"value"`
	Version  int                    `json:"version"`
	CreateAt int64                  `json:"create_at"`
	UpdateAt int64                  `json:"update_at"`
}

type SettingKeyPath struct {
	Scope   string `path:"scope" validate:"required,oneof=user account system"` // 設定範圍，可選 user / account / system
	ScopeID string `path:"scope_id" validate:"required"`                        // 範圍 ID，例如 user_id、account_id 或 global
	Key     string `path:"key" validate:"required"`                             // 設定 key，例如 ai.default
}

type SettingListData struct {
	Pagination PaginationData `json:"pagination"`
	List       []SettingData  `json:"list"`
}

type SettingPath struct {
	Scope    string `path:"scope" validate:"required,oneof=user account system"` // 設定範圍，可選 user / account / system
	ScopeID  string `path:"scope_id" validate:"required"`                        // 範圍 ID，例如 user_id、account_id 或 global
	Page     int64  `form:"page,optional"`                                       // 頁碼，從 1 開始
	PageSize int64  `form:"pageSize,optional"`                                   // 每頁筆數，server 會限制最大值
}

type SettingUpsertReq struct {
	Scope   string                 `path:"scope" validate:"required,oneof=user account system"` // 設定範圍，可選 user / account / system
	ScopeID string                 `path:"scope_id" validate:"required"`                        // 範圍 ID，例如 user_id、account_id 或 global
	Key     string                 `path:"key" validate:"required"`                             // 設定 key，例如 ai.default
	Value   map[string]interface{} `json:"value" validate:"required"`                           // 設定內容 JSON object
	Version int                    `json:"version,optional"`                                    // schema version，未帶入時預設 1
}

type StartBrandScanJobData struct {
	JobID   string `json:"job_id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

type StartBrandScanJobHandlerReq struct {
	BrandPath
	StartBrandScanJobReq
}

type StartBrandScanJobReq struct {
	GraphID        string   `json:"graph_id,optional"`
	NodeIDs        []string `json:"node_ids,optional"`
	DualTrack      bool     `json:"dual_track,optional"`
	PatrolMode     bool     `json:"patrol_mode,optional"`
	PatrolKeywords []string `json:"patrol_keywords,optional"`
}

type StartCopyMissionAnalyzeJobData struct {
	JobID   string `json:"job_id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

type StartCopyMissionCopyDraftJobData struct {
	JobID   string `json:"job_id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

type StartCopyMissionCopyDraftJobHandlerReq struct {
	CopyMissionPath
	StartCopyMissionCopyDraftJobReq
}

type StartCopyMissionCopyDraftJobReq struct {
	ScanPostID string `json:"scan_post_id" validate:"required"`
}

type StartCopyMissionMatrixJobData struct {
	JobID   string `json:"job_id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

type StartCopyMissionMatrixJobHandlerReq struct {
	CopyMissionPath
	StartCopyMissionMatrixJobReq
}

type StartCopyMissionMatrixJobReq struct {
	Count int `json:"count,optional"`
}

type StartCopyMissionScanJobData struct {
	JobID   string `json:"job_id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

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

type StartPersonaStyleAnalysisHandlerReq struct {
	PersonaPath
	StartPersonaStyleAnalysisReq
}

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

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

type StartPersonaViralScanJobHandlerReq struct {
	PersonaPath
	StartPersonaViralScanJobReq
}

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

type StartPlacementTopicScanJobHandlerReq struct {
	PlacementTopicPath
	StartBrandScanJobReq
}

type Status struct {
	Code    int64       `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data,optional"`
	Error   ErrorDetail `json:"error,optional"`
}

type StorePersonaStyleProfileData struct {
	ID       string `json:"id"`
	UpdateAt int64  `json:"update_at"`
}

type StorePersonaStyleProfileReq struct {
	ID             string `path:"id" validate:"required"`
	TenantID       string `json:"tenant_id" validate:"required"`
	OwnerUID       string `json:"owner_uid" validate:"required"`
	StyleProfile   string `json:"style_profile" validate:"required"`
	StyleBenchmark string `json:"style_benchmark,optional"`
}

type ThreadsAccountAiSettingsData struct {
	AccountID         string                 `json:"account_id"`
	Provider          string                 `json:"provider"`
	Model             string                 `json:"model"`
	ResearchProvider  string                 `json:"research_provider,omitempty"`
	ResearchModel     string                 `json:"research_model,omitempty"`
	ApiKeys           map[string]string      `json:"api_keys"`
	ApiKeysConfigured map[string]interface{} `json:"api_keys_configured"`
}

type ThreadsAccountConnectionData struct {
	AccountID        string                        `json:"account_id"`
	AccountName      string                        `json:"account_name"`
	Username         string                        `json:"username,omitempty"`
	BrowserConnected bool                          `json:"browser_connected"`
	ApiConnected     bool                          `json:"api_connected"`
	Prefs            ThreadsAccountConnectionPrefs `json:"prefs"`
}

type ThreadsAccountConnectionPrefs struct {
	SearchViaApi     bool   `json:"search_via_api"`
	SearchSourceMode string `json:"search_source_mode"`
	PublishViaApi    bool   `json:"publish_via_api"`
	DevMode          bool   `json:"dev_mode"`
	ScrapeReplies    bool   `json:"scrape_replies"`
	RepliesPerPost   int    `json:"replies_per_post"`
	PublishHeaded    bool   `json:"publish_headed"`
	PlaywrightDebug  bool   `json:"playwright_debug"`
}

type ThreadsAccountData struct {
	ID               string `json:"id"`
	DisplayName      string `json:"display_name,omitempty"`
	Username         string `json:"username,omitempty"`
	ThreadsUserID    string `json:"threads_user_id,omitempty"`
	PersonaID        string `json:"persona_id,omitempty"` // deprecated: persona is chosen per publish, not bound to account
	BrowserConnected bool   `json:"browser_connected"`
	ApiConnected     bool   `json:"api_connected"`
	Status           string `json:"status"`
	CreateAt         int64  `json:"create_at"`
	UpdateAt         int64  `json:"update_at"`
}

type ThreadsAccountPath struct {
	ID string `path:"id" validate:"required"`
}

type UpdateBrandHandlerReq struct {
	BrandPath
	UpdateBrandReq
}

type UpdateBrandProductHandlerReq struct {
	BrandProductPath
	UpdateBrandProductReq
}

type UpdateBrandProductReq struct {
	Label          *string  `json:"label,optional"`
	ProductContext *string  `json:"product_context,optional"`
	MatchTags      []string `json:"match_tags,optional"`
}

type UpdateBrandReq struct {
	DisplayName     *string  `json:"display_name,optional"`
	TopicName       *string  `json:"topic_name,optional"`
	SeedQuery       *string  `json:"seed_query,optional"`
	Brief           *string  `json:"brief,optional"`
	ProductBrief    *string  `json:"product_brief,optional"`
	ProductContext  *string  `json:"product_context,optional"`
	ProductID       *string  `json:"product_id,optional"`
	TargetAudience  *string  `json:"target_audience,optional"`
	Goals           *string  `json:"goals,optional"`
	AudienceSummary *string  `json:"audience_summary,optional"`
	ContentGoal     *string  `json:"content_goal,optional"`
	Questions       []string `json:"questions,optional"`
	Pillars         []string `json:"pillars,optional"`
	Exclusions      []string `json:"exclusions,optional"`
	PatrolKeywords  []string `json:"patrol_keywords,optional"`
}

type UpdateCopyDraftHandlerReq struct {
	CopyDraftPath
	UpdateCopyDraftReq
}

type UpdateCopyDraftReq struct {
	Text   *string `json:"text,optional"`
	Hook   *string `json:"hook,optional"`
	Angle  *string `json:"angle,optional"`
	Status *string `json:"status,optional"`
}

type UpdateCopyMissionHandlerReq struct {
	CopyMissionPath
	UpdateCopyMissionReq
}

type UpdateCopyMissionReq struct {
	Label           *string  `json:"label,optional"`
	SeedQuery       *string  `json:"seed_query,optional"`
	Brief           *string  `json:"brief,optional"`
	AudienceSummary *string  `json:"audience_summary,optional"`
	ContentGoal     *string  `json:"content_goal,optional"`
	Questions       []string `json:"questions,optional"`
	Pillars         []string `json:"pillars,optional"`
	Exclusions      []string `json:"exclusions,optional"`
	BenchmarkNotes  *string  `json:"benchmark_notes,optional"`
	SelectedTags    []string `json:"selected_tags,optional"`
	Status          *string  `json:"status,optional"`
}

type UpdateJobScheduleReq struct {
	ID              string                 `path:"id" validate:"required"`    // schedule id
	Cron            string                 `json:"cron,optional"`             // cron expression
	Timezone        string                 `json:"timezone,optional"`         // timezone
	PayloadTemplate map[string]interface{} `json:"payload_template,optional"` // payload template
	Enabled         *bool                  `json:"enabled,optional"`          // enabled flag
}

type UpdateMemberMeReq struct {
	DisplayName string `json:"display_name,optional"`
	Avatar      string `json:"avatar,optional"`
	Language    string `json:"language,optional"`
	Currency    string `json:"currency,optional"`
	Phone       string `json:"phone,optional"`
}

type UpdateMemberPlacementSettingsReq struct {
	WebSearchProvider *string `json:"web_search_provider,optional"`
	BraveAPIKey       *string `json:"brave_api_key,optional"`
	ExaAPIKey         *string `json:"exa_api_key,optional"`
	BraveCountry      *string `json:"brave_country,optional"`
	BraveSearchLang   *string `json:"brave_search_lang,optional"`
	ExaUserLocation   *string `json:"exa_user_location,optional"`
	ExpandStrategy    *string `json:"expand_strategy,optional"`
}

type UpdatePersonaHandlerReq struct {
	PersonaPath
	UpdatePersonaReq
}

type UpdatePersonaReq struct {
	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"`
}

type UpdatePlacementTopicHandlerReq struct {
	PlacementTopicPath
	UpdatePlacementTopicReq
}

type UpdatePlacementTopicReq struct {
	BrandID         *string  `json:"brand_id,optional"`
	TopicName       *string  `json:"topic_name,optional"`
	SeedQuery       *string  `json:"seed_query,optional"`
	Brief           *string  `json:"brief,optional"`
	ProductID       *string  `json:"product_id,optional"`
	AudienceSummary *string  `json:"audience_summary,optional"`
	ContentGoal     *string  `json:"content_goal,optional"`
	Questions       []string `json:"questions,optional"`
	Pillars         []string `json:"pillars,optional"`
	Exclusions      []string `json:"exclusions,optional"`
	PatrolKeywords  []string `json:"patrol_keywords,optional"`
}

type UpdateThreadsAccountAiSettingsHandlerReq struct {
	ThreadsAccountPath
	UpdateThreadsAccountAiSettingsReq
}

type UpdateThreadsAccountAiSettingsReq struct {
	Provider         *string           `json:"provider,optional"`
	Model            *string           `json:"model,optional"`
	ResearchProvider *string           `json:"research_provider,optional"`
	ResearchModel    *string           `json:"research_model,optional"`
	ApiKeys          map[string]string `json:"api_keys,optional"`
}

type UpdateThreadsAccountConnectionHandlerReq struct {
	ThreadsAccountPath
	UpdateThreadsAccountConnectionReq
}

type UpdateThreadsAccountConnectionReq struct {
	SearchViaApi     *bool   `json:"search_via_api,optional"`
	SearchSourceMode *string `json:"search_source_mode,optional"`
	PublishViaApi    *bool   `json:"publish_via_api,optional"`
	DevMode          *bool   `json:"dev_mode,optional"`
	ScrapeReplies    *bool   `json:"scrape_replies,optional"`
	RepliesPerPost   *int    `json:"replies_per_post,optional"`
	PublishHeaded    *bool   `json:"publish_headed,optional"`
	PlaywrightDebug  *bool   `json:"playwright_debug,optional"`
}

type UpdateThreadsAccountHandlerReq struct {
	ThreadsAccountPath
	UpdateThreadsAccountReq
}

type UpdateThreadsAccountReq struct {
	DisplayName *string `json:"display_name,optional"`
	PersonaID   *string `json:"persona_id,optional"` // deprecated: use persona_id in publish payload instead
}

type UpsertBrandScanScheduleHandlerReq struct {
	BrandPath
	UpsertBrandScanScheduleReq
}

type UpsertBrandScanScheduleReq struct {
	Cron     string `json:"cron,optional"`
	Timezone string `json:"timezone,optional"`
	Enabled  bool   `json:"enabled"`
}

type UpsertCopyMissionScanScheduleHandlerReq struct {
	CopyMissionPath
	UpsertCopyMissionScanScheduleReq
}

type UpsertCopyMissionScanScheduleReq struct {
	Cron     string `json:"cron,optional"`
	Timezone string `json:"timezone,optional"`
	Enabled  bool   `json:"enabled"`
}

type UpsertJobTemplateReq struct {
	Type              string                `path:"type" validate:"required"`             // template type
	Version           int                   `json:"version,optional"`                     // template version
	Name              string                `json:"name" validate:"required"`             // display name
	Description       string                `json:"description,optional"`                 // description
	Enabled           bool                  `json:"enabled"`                              // enabled flag
	Repeatable        bool                  `json:"repeatable"`                           // repeatable flag
	ConcurrencyPolicy string                `json:"concurrency_policy,optional"`          // concurrency policy
	DedupeKeys        []string              `json:"dedupe_keys,optional"`                 // dedupe keys
	TimeoutSeconds    int                   `json:"timeout_seconds,optional"`             // timeout seconds
	CancelPolicy      JobCancelPolicyData   `json:"cancel_policy,optional"`               // cancel policy
	RetryPolicy       JobRetryPolicyData    `json:"retry_policy,optional"`                // retry policy
	Steps             []JobTemplateStepData `json:"steps" validate:"required,min=1,dive"` // steps
}

type UpsertPlacementTopicScanScheduleHandlerReq struct {
	PlacementTopicPath
	UpsertBrandScanScheduleReq
}

type ViralScanPostData struct {
	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"`
}

type WorkerCancelCheckData struct {
	Cancelled bool `json:"cancelled"`
}

type WorkerCompleteReq struct {
	WorkerJobPath
	WorkerID string                 `json:"worker_id" validate:"required"`
	Result   map[string]interface{} `json:"result,optional"`
}

type WorkerFailReq struct {
	WorkerJobPath
	WorkerID string `json:"worker_id" validate:"required"`
	Error    string `json:"error" validate:"required"`
	Phase    string `json:"phase,optional"`
}

type WorkerHeartbeatReq struct {
	WorkerJobPath
	WorkerID   string `json:"worker_id" validate:"required"`
	TTLSeconds int    `json:"ttl_seconds,optional"`
}

type WorkerJobPath struct {
	ID string `path:"id" validate:"required"`
}

type WorkerJobReq struct {
	WorkerJobPath
	WorkerID string `json:"worker_id" validate:"required"`
}

type WorkerOKData struct {
	OK bool `json:"ok"`
}

type WorkerProgressReq struct {
	WorkerJobPath
	WorkerID   string                `json:"worker_id" validate:"required"`
	Phase      string                `json:"phase,optional"`
	Summary    string                `json:"summary,optional"`
	Percentage int                   `json:"percentage,optional"`
	Steps      []JobStepProgressData `json:"steps,optional"`
}

type WorkerThreadsAccountSessionData struct {
	AccountID    string `json:"account_id"`
	StorageState string `json:"storage_state"`
	UpdateAt     int64  `json:"update_at"`
}

type WorkerThreadsAccountSessionReq struct {
	ID       string `path:"id" validate:"required"`
	TenantID string `json:"tenant_id" validate:"required"`
	OwnerUID string `json:"owner_uid" validate:"required"`
}
