446 lines
14 KiB
Plaintext
446 lines
14 KiB
Plaintext
syntax = "v1"
|
|
|
|
type (
|
|
ResearchItemData {
|
|
Title string `json:"title,omitempty"`
|
|
URL string `json:"url,omitempty"`
|
|
Snippet string `json:"snippet,omitempty"`
|
|
Query string `json:"query,omitempty"`
|
|
}
|
|
|
|
ResearchMapData {
|
|
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"`
|
|
}
|
|
|
|
KnowledgeGraphEvidenceData {
|
|
URL string `json:"url,omitempty"`
|
|
Snippet string `json:"snippet,omitempty"`
|
|
Query string `json:"query,omitempty"`
|
|
}
|
|
|
|
BraveSourceData {
|
|
Query string `json:"query,omitempty"`
|
|
Title string `json:"title,omitempty"`
|
|
URL string `json:"url,omitempty"`
|
|
Snippet string `json:"snippet,omitempty"`
|
|
}
|
|
|
|
BrandProductData {
|
|
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"`
|
|
}
|
|
|
|
BrandData {
|
|
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"`
|
|
}
|
|
|
|
ListBrandProductsData {
|
|
List []BrandProductData `json:"list"`
|
|
}
|
|
|
|
CreateBrandProductReq {
|
|
Label string `json:"label" validate:"required"`
|
|
ProductContext string `json:"product_context" validate:"required"`
|
|
MatchTags []string `json:"match_tags,optional"`
|
|
}
|
|
|
|
UpdateBrandProductReq {
|
|
Label *string `json:"label,optional"`
|
|
ProductContext *string `json:"product_context,optional"`
|
|
MatchTags []string `json:"match_tags,optional"`
|
|
}
|
|
|
|
BrandProductPath {
|
|
ID string `path:"id" validate:"required"`
|
|
ProductID string `path:"productId" validate:"required"`
|
|
}
|
|
|
|
CreateBrandProductHandlerReq {
|
|
BrandPath
|
|
CreateBrandProductReq
|
|
}
|
|
|
|
UpdateBrandProductHandlerReq {
|
|
BrandProductPath
|
|
UpdateBrandProductReq
|
|
}
|
|
|
|
ListBrandsData {
|
|
List []BrandData `json:"list"`
|
|
}
|
|
|
|
CreateBrandReq {
|
|
DisplayName string `json:"display_name,optional"`
|
|
}
|
|
|
|
BrandPath {
|
|
ID string `path:"id" validate:"required"`
|
|
}
|
|
|
|
UpdateBrandReq {
|
|
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"`
|
|
}
|
|
|
|
KnowledgeGraphNodeData {
|
|
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"`
|
|
}
|
|
|
|
KnowledgeGraphEdgeData {
|
|
From string `json:"from"`
|
|
To string `json:"to"`
|
|
Relation string `json:"relation"`
|
|
}
|
|
|
|
KnowledgeGraphData {
|
|
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"`
|
|
}
|
|
|
|
ExpandKnowledgeGraphReq {
|
|
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
|
|
}
|
|
|
|
ExpandKnowledgeGraphData {
|
|
JobID string `json:"job_id"`
|
|
Status string `json:"status"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
KnowledgeGraphNodeUpdate {
|
|
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"`
|
|
}
|
|
|
|
PatchKnowledgeGraphNodesReq {
|
|
Updates []KnowledgeGraphNodeUpdate `json:"updates" validate:"required"`
|
|
}
|
|
|
|
StartBrandScanJobReq {
|
|
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"`
|
|
}
|
|
|
|
StartBrandScanJobData {
|
|
JobID string `json:"job_id"`
|
|
Status string `json:"status"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
ListBrandScanPostsReq {
|
|
Priority string `form:"priority,optional"`
|
|
Recent7d bool `form:"recent_7d,optional"`
|
|
ProductFitMin int `form:"product_fit_min,optional"`
|
|
Limit int `form:"limit,optional"`
|
|
}
|
|
|
|
ScanPostData {
|
|
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"`
|
|
}
|
|
|
|
ListBrandScanPostsData {
|
|
List []ScanPostData `json:"list"`
|
|
Total int `json:"total"`
|
|
}
|
|
|
|
GenerateOutreachDraftsReq {
|
|
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"`
|
|
}
|
|
|
|
OutreachDraftItemData {
|
|
Text string `json:"text"`
|
|
Angle string `json:"angle"`
|
|
Rationale string `json:"rationale"`
|
|
}
|
|
|
|
GenerateOutreachDraftsData {
|
|
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"`
|
|
}
|
|
|
|
PublishOutreachDraftReq {
|
|
ScanPostID string `json:"scan_post_id" validate:"required"`
|
|
Text string `json:"text" validate:"required"`
|
|
Confirm bool `json:"confirm"`
|
|
}
|
|
|
|
PublishOutreachDraftData {
|
|
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"`
|
|
}
|
|
|
|
PatchScanPostOutreachReq {
|
|
OutreachStatus *string `json:"outreach_status,optional"`
|
|
}
|
|
|
|
ContentMatrixRowData {
|
|
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"`
|
|
}
|
|
|
|
ContentMatrixData {
|
|
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"`
|
|
}
|
|
|
|
GenerateContentMatrixReq {
|
|
Count int `json:"count,optional"`
|
|
}
|
|
|
|
ScanReplyData {
|
|
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"`
|
|
}
|
|
|
|
BrandScanScheduleData {
|
|
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"`
|
|
}
|
|
|
|
UpsertBrandScanScheduleReq {
|
|
Cron string `json:"cron,optional"`
|
|
Timezone string `json:"timezone,optional"`
|
|
Enabled bool `json:"enabled"`
|
|
}
|
|
|
|
UpdateBrandHandlerReq {
|
|
BrandPath
|
|
UpdateBrandReq
|
|
}
|
|
|
|
ExpandKnowledgeGraphHandlerReq {
|
|
BrandPath
|
|
ExpandKnowledgeGraphReq
|
|
}
|
|
|
|
PatchKnowledgeGraphNodesHandlerReq {
|
|
BrandPath
|
|
PatchKnowledgeGraphNodesReq
|
|
}
|
|
|
|
StartBrandScanJobHandlerReq {
|
|
BrandPath
|
|
StartBrandScanJobReq
|
|
}
|
|
|
|
ListBrandScanPostsHandlerReq {
|
|
BrandPath
|
|
ListBrandScanPostsReq
|
|
}
|
|
|
|
GenerateOutreachDraftsHandlerReq {
|
|
BrandPath
|
|
GenerateOutreachDraftsReq
|
|
}
|
|
|
|
PublishOutreachDraftHandlerReq {
|
|
BrandPath
|
|
PublishOutreachDraftReq
|
|
}
|
|
|
|
PatchScanPostOutreachHandlerReq {
|
|
BrandPath
|
|
PostID string `path:"postId"`
|
|
PatchScanPostOutreachReq
|
|
}
|
|
|
|
GenerateContentMatrixHandlerReq {
|
|
BrandPath
|
|
GenerateContentMatrixReq
|
|
}
|
|
|
|
UpsertBrandScanScheduleHandlerReq {
|
|
BrandPath
|
|
UpsertBrandScanScheduleReq
|
|
}
|
|
)
|
|
|
|
@server(
|
|
group: brand
|
|
prefix: /api/v1/brands
|
|
middleware: AuthJWT
|
|
tags: "Brand"
|
|
summary: "Brand profiles for placement workflow. Requires Bearer JWT."
|
|
)
|
|
service gateway {
|
|
@handler listBrands
|
|
get / returns (ListBrandsData)
|
|
|
|
@handler createBrand
|
|
post / (CreateBrandReq) returns (BrandData)
|
|
|
|
@handler getBrand
|
|
get /:id (BrandPath) returns (BrandData)
|
|
|
|
@handler updateBrand
|
|
patch /:id (UpdateBrandHandlerReq) returns (BrandData)
|
|
|
|
@handler deleteBrand
|
|
delete /:id (BrandPath)
|
|
|
|
@handler listBrandProducts
|
|
get /:id/products (BrandPath) returns (ListBrandProductsData)
|
|
|
|
@handler createBrandProduct
|
|
post /:id/products (CreateBrandProductHandlerReq) returns (BrandProductData)
|
|
|
|
@handler updateBrandProduct
|
|
patch /:id/products/:productId (UpdateBrandProductHandlerReq) returns (BrandProductData)
|
|
|
|
@handler deleteBrandProduct
|
|
delete /:id/products/:productId (BrandProductPath)
|
|
|
|
@handler expandKnowledgeGraph
|
|
post /:id/knowledge-graph/expand (ExpandKnowledgeGraphHandlerReq) returns (ExpandKnowledgeGraphData)
|
|
|
|
@handler getKnowledgeGraph
|
|
get /:id/knowledge-graph (BrandPath) returns (KnowledgeGraphData)
|
|
|
|
@handler patchKnowledgeGraphNodes
|
|
patch /:id/knowledge-graph/nodes (PatchKnowledgeGraphNodesHandlerReq) returns (KnowledgeGraphData)
|
|
|
|
@handler startBrandScanJob
|
|
post /:id/scan-jobs (StartBrandScanJobHandlerReq) returns (StartBrandScanJobData)
|
|
|
|
@handler listBrandScanPosts
|
|
get /:id/scan-posts (ListBrandScanPostsHandlerReq) returns (ListBrandScanPostsData)
|
|
|
|
@handler generateOutreachDrafts
|
|
post /:id/outreach-drafts/generate (GenerateOutreachDraftsHandlerReq) returns (GenerateOutreachDraftsData)
|
|
|
|
@handler publishOutreachDraft
|
|
post /:id/outreach-drafts/publish (PublishOutreachDraftHandlerReq) returns (PublishOutreachDraftData)
|
|
|
|
@handler patchScanPostOutreach
|
|
patch /:id/scan-posts/:postId (PatchScanPostOutreachHandlerReq) returns (ScanPostData)
|
|
|
|
@handler getBrandContentMatrix
|
|
get /:id/content-matrix (BrandPath) returns (ContentMatrixData)
|
|
|
|
@handler generateBrandContentMatrix
|
|
post /:id/content-matrix/generate (GenerateContentMatrixHandlerReq) returns (ContentMatrixData)
|
|
|
|
@handler getBrandScanSchedule
|
|
get /:id/scan-schedule (BrandPath) returns (BrandScanScheduleData)
|
|
|
|
@handler upsertBrandScanSchedule
|
|
put /:id/scan-schedule (UpsertBrandScanScheduleHandlerReq) returns (BrandScanScheduleData)
|
|
}
|