syntax = "v1" type ( PlacementTopicData { 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"` } ListPlacementTopicsData { List []PlacementTopicData `json:"list"` } CreatePlacementTopicReq { 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"` } UpdatePlacementTopicReq { 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"` } PlacementTopicPath { ID string `path:"id" validate:"required"` } UpdatePlacementTopicHandlerReq { PlacementTopicPath UpdatePlacementTopicReq } CreatePlacementTopicHandlerReq { CreatePlacementTopicReq } ExpandPlacementTopicGraphHandlerReq { PlacementTopicPath ExpandKnowledgeGraphReq } PatchPlacementTopicGraphNodesHandlerReq { PlacementTopicPath PatchKnowledgeGraphNodesReq } StartPlacementTopicScanJobHandlerReq { PlacementTopicPath StartBrandScanJobReq } ListPlacementTopicScanPostsHandlerReq { PlacementTopicPath ListBrandScanPostsReq } GeneratePlacementTopicOutreachDraftsHandlerReq { PlacementTopicPath GenerateOutreachDraftsReq } PublishPlacementTopicOutreachDraftHandlerReq { PlacementTopicPath PublishOutreachDraftReq } PatchPlacementTopicScanPostOutreachHandlerReq { PlacementTopicPath PostID string `path:"postId"` PatchScanPostOutreachReq } DeletePlacementTopicScanPostHandlerReq { PlacementTopicPath PostID string `path:"postId" validate:"required"` } BatchDeletePlacementTopicScanPostsReq { PostIDs []string `json:"post_ids" validate:"required"` } BatchDeletePlacementTopicScanPostsData { DeletedCount int `json:"deleted_count"` } BatchDeletePlacementTopicScanPostsHandlerReq { PlacementTopicPath BatchDeletePlacementTopicScanPostsReq } GeneratePlacementTopicContentMatrixHandlerReq { PlacementTopicPath GenerateContentMatrixReq } UpsertPlacementTopicScanScheduleHandlerReq { PlacementTopicPath UpsertBrandScanScheduleReq } ) @server( group: placement_topic prefix: /api/v1/placement/topics middleware: AuthJWT tags: "Placement Topic" summary: "找 TA 主題;每個主題關聯一個品牌,一個品牌可有多個主題。Requires Bearer JWT." ) service gateway { @handler listPlacementTopics get / returns (ListPlacementTopicsData) @handler createPlacementTopic post / (CreatePlacementTopicHandlerReq) returns (PlacementTopicData) @handler getPlacementTopic get /:id (PlacementTopicPath) returns (PlacementTopicData) @handler updatePlacementTopic patch /:id (UpdatePlacementTopicHandlerReq) returns (PlacementTopicData) @handler deletePlacementTopic delete /:id (PlacementTopicPath) @handler expandPlacementTopicGraph post /:id/knowledge-graph/expand (ExpandPlacementTopicGraphHandlerReq) returns (ExpandKnowledgeGraphData) @handler getPlacementTopicGraph get /:id/knowledge-graph (PlacementTopicPath) returns (KnowledgeGraphData) @handler patchPlacementTopicGraphNodes patch /:id/knowledge-graph/nodes (PatchPlacementTopicGraphNodesHandlerReq) returns (KnowledgeGraphData) @handler startPlacementTopicScanJob post /:id/scan-jobs (StartPlacementTopicScanJobHandlerReq) returns (StartBrandScanJobData) @handler listPlacementTopicScanPosts get /:id/scan-posts (ListPlacementTopicScanPostsHandlerReq) returns (ListBrandScanPostsData) @handler generatePlacementTopicOutreachDrafts post /:id/outreach-drafts/generate (GeneratePlacementTopicOutreachDraftsHandlerReq) returns (GenerateOutreachDraftsData) @handler publishPlacementTopicOutreachDraft post /:id/outreach-drafts/publish (PublishPlacementTopicOutreachDraftHandlerReq) returns (PublishOutreachDraftData) @handler patchPlacementTopicScanPostOutreach patch /:id/scan-posts/:postId (PatchPlacementTopicScanPostOutreachHandlerReq) returns (ScanPostData) @handler deletePlacementTopicScanPost delete /:id/scan-posts/:postId (DeletePlacementTopicScanPostHandlerReq) @handler batchDeletePlacementTopicScanPosts post /:id/scan-posts/batch-delete (BatchDeletePlacementTopicScanPostsHandlerReq) returns (BatchDeletePlacementTopicScanPostsData) @handler getPlacementTopicContentMatrix get /:id/content-matrix (PlacementTopicPath) returns (ContentMatrixData) @handler generatePlacementTopicContentMatrix post /:id/content-matrix/generate (GeneratePlacementTopicContentMatrixHandlerReq) returns (ContentMatrixData) @handler getPlacementTopicScanSchedule get /:id/scan-schedule (PlacementTopicPath) returns (BrandScanScheduleData) @handler upsertPlacementTopicScanSchedule put /:id/scan-schedule (UpsertPlacementTopicScanScheduleHandlerReq) returns (BrandScanScheduleData) }