feat(generation): migrate article generation and template-assist to RabbitMQ queues
Replace in-process generation with queue-based async execution via RabbitMQ. Add generation task runtime for lifecycle management, article generation payload/queue abstractions, and template-assist queue publisher. Refactor prompt generation service to support batch generation with per-item error tracking. Update stream hub to bridge queue events to SSE. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package app
|
||||
|
||||
import "github.com/geo-platform/tenant-api/internal/tenant/repository"
|
||||
|
||||
const (
|
||||
generationPayloadTemplateKey = "__snapshot_template_key"
|
||||
generationPayloadTemplateName = "__snapshot_template_name"
|
||||
generationPayloadTemplatePromptTemplate = "__snapshot_template_prompt_template"
|
||||
generationPayloadPromptRuleID = "__snapshot_prompt_rule_id"
|
||||
generationPayloadPromptRuleName = "__snapshot_prompt_rule_name"
|
||||
generationPayloadPromptRuleContent = "__snapshot_prompt_rule_content"
|
||||
generationPayloadPromptRuleScene = "__snapshot_prompt_rule_scene"
|
||||
generationPayloadPromptRuleTone = "__snapshot_prompt_rule_tone"
|
||||
generationPayloadPromptRuleWordCount = "__snapshot_prompt_rule_word_count"
|
||||
generationPayloadKnowledgePrompt = "__snapshot_knowledge_prompt"
|
||||
)
|
||||
|
||||
func attachTemplateSnapshot(payload map[string]interface{}, record *repository.TemplateRecord) map[string]interface{} {
|
||||
if payload == nil {
|
||||
payload = map[string]interface{}{}
|
||||
}
|
||||
if record == nil {
|
||||
return payload
|
||||
}
|
||||
|
||||
payload[generationPayloadTemplateKey] = record.TemplateKey
|
||||
payload[generationPayloadTemplateName] = record.TemplateName
|
||||
if record.PromptTemplate != nil {
|
||||
payload[generationPayloadTemplatePromptTemplate] = *record.PromptTemplate
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
func extractTemplateSnapshot(payload map[string]interface{}) (string, string, *string) {
|
||||
templateKey := extractString(payload, generationPayloadTemplateKey)
|
||||
templateName := extractString(payload, generationPayloadTemplateName)
|
||||
promptTemplateText := extractString(payload, generationPayloadTemplatePromptTemplate)
|
||||
if templateKey == "" || templateName == "" {
|
||||
return "", "", nil
|
||||
}
|
||||
if promptTemplateText == "" {
|
||||
return templateKey, templateName, nil
|
||||
}
|
||||
return templateKey, templateName, &promptTemplateText
|
||||
}
|
||||
|
||||
func attachPromptRuleSnapshot(payload map[string]interface{}, rule *promptRuleGenerationRecord) map[string]interface{} {
|
||||
if payload == nil {
|
||||
payload = map[string]interface{}{}
|
||||
}
|
||||
if rule == nil {
|
||||
return payload
|
||||
}
|
||||
|
||||
payload[generationPayloadPromptRuleID] = rule.ID
|
||||
payload[generationPayloadPromptRuleName] = rule.Name
|
||||
payload[generationPayloadPromptRuleContent] = rule.PromptContent
|
||||
if rule.Scene != nil {
|
||||
payload[generationPayloadPromptRuleScene] = *rule.Scene
|
||||
}
|
||||
if rule.DefaultTone != nil {
|
||||
payload[generationPayloadPromptRuleTone] = *rule.DefaultTone
|
||||
}
|
||||
if rule.DefaultWordCount != nil {
|
||||
payload[generationPayloadPromptRuleWordCount] = *rule.DefaultWordCount
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
func extractPromptRuleSnapshot(payload map[string]interface{}) *promptRuleGenerationRecord {
|
||||
ruleID := int64(extractInt(payload, generationPayloadPromptRuleID))
|
||||
name := extractString(payload, generationPayloadPromptRuleName)
|
||||
content := extractString(payload, generationPayloadPromptRuleContent)
|
||||
if ruleID <= 0 || content == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
record := &promptRuleGenerationRecord{
|
||||
ID: ruleID,
|
||||
Name: name,
|
||||
PromptContent: content,
|
||||
Status: "enabled",
|
||||
}
|
||||
if scene := extractString(payload, generationPayloadPromptRuleScene); scene != "" {
|
||||
record.Scene = &scene
|
||||
}
|
||||
if tone := extractString(payload, generationPayloadPromptRuleTone); tone != "" {
|
||||
record.DefaultTone = &tone
|
||||
}
|
||||
if wordCount := extractInt(payload, generationPayloadPromptRuleWordCount); wordCount > 0 {
|
||||
value := wordCount
|
||||
record.DefaultWordCount = &value
|
||||
}
|
||||
return record
|
||||
}
|
||||
Reference in New Issue
Block a user