feat(migrations): Harden task audit tracking and optimize article templates
- Added migration to harden task audit tracking by modifying audit_logs and related tables. - Introduced operator_id to several tables for better tracking of actions. - Updated article_templates with new prompt templates for various article types, enhancing content generation. - Created prompt_rules and schedule_tasks tables to manage content generation rules and scheduling. - Added foreign key constraints to articles for better data integrity.
This commit is contained in:
@@ -18,6 +18,7 @@ const enUS = {
|
||||
refresh: "Refresh",
|
||||
search: "Search",
|
||||
save: "Save",
|
||||
back: "Back",
|
||||
next: "Next",
|
||||
previous: "Previous",
|
||||
submit: "Submit",
|
||||
@@ -91,11 +92,19 @@ const enUS = {
|
||||
},
|
||||
templates: {
|
||||
title: "Template Creation",
|
||||
description: "Filter existing articles, choose templates, and trigger new generation tasks.",
|
||||
description: "Choose a suitable template or use the batch feature to quickly generate GEO content.",
|
||||
},
|
||||
wizard: {
|
||||
title: "Template Wizard",
|
||||
description: "Follow the template-driven three-step flow to fill inputs, confirm structure, and generate the article.",
|
||||
},
|
||||
articleEditor: {
|
||||
title: "Article Editor",
|
||||
description: "Edit titles, content, and publishing settings in a dedicated workspace.",
|
||||
},
|
||||
custom: {
|
||||
title: "Custom Generation",
|
||||
description: "No matching backend APIs exist in this repository yet.",
|
||||
description: "Generate articles with custom prompt rules, instant or scheduled.",
|
||||
},
|
||||
optimize: {
|
||||
title: "Article Optimization",
|
||||
@@ -206,13 +215,17 @@ const enUS = {
|
||||
publishStatus: "Publish status",
|
||||
generateStatus: "Generation status",
|
||||
keyword: "Search",
|
||||
generationTime: "Generation time",
|
||||
generationTimeStart: "Start time",
|
||||
generationTimeEnd: "End time",
|
||||
keywordPlaceholder: "Search by article title",
|
||||
unsupportedDate: "Date range filtering is not available in the current backend yet.",
|
||||
},
|
||||
list: {
|
||||
count: "{count} articles",
|
||||
empty: "No articles have been created yet.",
|
||||
preview: "Preview",
|
||||
edit: "Edit article",
|
||||
editDisabled: "Only draft, failed, or completed articles can be edited",
|
||||
versions: "Versions",
|
||||
deleteConfirm: "Delete this article?",
|
||||
deleteSuccess: "Article deleted.",
|
||||
@@ -228,20 +241,28 @@ const enUS = {
|
||||
basic: "Basic info",
|
||||
basicDesc: "Language, template fields, and brand context",
|
||||
structure: "Structure",
|
||||
structureDesc: "Title, key points, and outline",
|
||||
structureDesc: "Title and outline",
|
||||
generate: "Generate",
|
||||
generateDesc: "Review and submit the task",
|
||||
generateDesc: "Confirm the outline, add key points, and submit the task",
|
||||
},
|
||||
sections: {
|
||||
templateFields: "Template fields",
|
||||
brandContext: "Brand context",
|
||||
language: "Language",
|
||||
brandInfo: "Brand",
|
||||
brandLibrary: "Brand library",
|
||||
brandName: "Brand name",
|
||||
website: "Official website",
|
||||
brandSummary: "AI brand summary",
|
||||
keywords: "Keywords",
|
||||
competitors: "Competitors",
|
||||
chooseTitle: "Choose a title",
|
||||
customTitle: "Custom title",
|
||||
structure: "Article structure",
|
||||
customOutline: "Custom section",
|
||||
preview: "Article preview",
|
||||
generatedOutline: "Confirm outline",
|
||||
outlinePreview: "Outline preview",
|
||||
keyPoints: "Key points",
|
||||
review: "Review",
|
||||
notes: "Notes",
|
||||
@@ -249,11 +270,35 @@ const enUS = {
|
||||
},
|
||||
hints: {
|
||||
brandContext: "Optional. Selecting a brand pulls in keywords and competitor context.",
|
||||
brandFlow: "You can pick a brand from the library or type one manually. AI analysis will expand keywords, competitors, and title options.",
|
||||
brandSummaryPlaceholder: "After analysis, AI will summarize the brand angle, positioning, and content opportunities here.",
|
||||
keywords: "Type keywords directly or reuse brand-library keywords. AI results will be merged into this list.",
|
||||
competitors: "Competitors stay editable. You can add rows manually and save useful ones back into the competitor library.",
|
||||
competitorEmptyEditable: "No competitors yet. Add one manually or let AI fill the list first.",
|
||||
templateFields: "Keep any extra template-specific fields here to constrain the writing direction.",
|
||||
titleSelection: "AI will return 5 better title options before you move forward. Choose one or rewrite it.",
|
||||
structure: "Keep the default outline or trim sections for this draft.",
|
||||
preview: "The panel on the right updates the article frame in real time.",
|
||||
previewEmpty: "Select one or more sections to preview the article frame here.",
|
||||
generatedOutline: "AI generates the full article outline first. You can edit, add, or delete nodes before creating the final article.",
|
||||
outlinePreview: "The panel on the right updates from the current outline in real time.",
|
||||
outlineEmpty: "Generate the outline first to edit the article structure here.",
|
||||
review: "Check the final setup before creating the generation task.",
|
||||
competitorEmpty: "No competitors are available under this brand yet.",
|
||||
customTitle: "Use this field if you want to override the title manually.",
|
||||
keyPoints: "Add any key messages, angles, or style notes here.",
|
||||
async: "The backend creates the article and task first, then completes content generation asynchronously.",
|
||||
},
|
||||
actions: {
|
||||
analyze: "Analyze",
|
||||
addCompetitor: "Add competitor",
|
||||
addSection: "Add section",
|
||||
addOutlineNode: "Add node",
|
||||
addOutlineChild: "Add child",
|
||||
favorite: "Save",
|
||||
saved: "Saved",
|
||||
submit: "Submit and generate",
|
||||
},
|
||||
review: {
|
||||
templateName: "Template",
|
||||
articleTitle: "Article title",
|
||||
@@ -268,12 +313,65 @@ const enUS = {
|
||||
zh: "Simplified Chinese",
|
||||
en: "English",
|
||||
},
|
||||
table: {
|
||||
website: "Website",
|
||||
name: "Name",
|
||||
description: "Description",
|
||||
actions: "Actions",
|
||||
},
|
||||
placeholders: {
|
||||
brandLibrary: "Choose an existing brand from the library",
|
||||
brandName: "Enter a brand name, or refine the selected library brand",
|
||||
website: "Official website, optional",
|
||||
keywords: "Type keywords and press Enter",
|
||||
customTitle: "Override the AI title here if needed",
|
||||
customOutline: "Add another section, for example “Buying advice”",
|
||||
keyPoints: "Add any extra instructions, key angles, or constraints for the article",
|
||||
competitorWebsite: "Official site or landing page",
|
||||
competitorName: "Competitor name",
|
||||
competitorDescription: "One-line positioning or summary",
|
||||
outlineNode: "Enter a title",
|
||||
},
|
||||
promptVisible: "Prompt visible",
|
||||
promptSealed: "Prompt sealed",
|
||||
assist: {
|
||||
analyzeTitle: "AI is analyzing keywords and competitors. Please wait…",
|
||||
titleTitle: "AI is generating titles. Please wait…",
|
||||
outlineTitle: "AI is generating the article outline. Please wait…",
|
||||
analyzeStages: {
|
||||
brand: "Analyzing the brand context…",
|
||||
keywords: "Extracting keyword opportunities…",
|
||||
competitors: "Mapping competitors and websites…",
|
||||
},
|
||||
titleStages: {
|
||||
context: "Preparing the current brief…",
|
||||
strategy: "Generating title directions from keywords and competitors…",
|
||||
finalize: "Returning 5 title options…",
|
||||
},
|
||||
outlineStages: {
|
||||
context: "Preparing the title, keywords, and competitor context…",
|
||||
structure: "Generating the article outline from the selected structure…",
|
||||
finalize: "Returning the editable outline result…",
|
||||
},
|
||||
},
|
||||
messages: {
|
||||
requiredField: "Please fill in {field} first.",
|
||||
missingBrand: "Choose a brand from the library or enter a brand name first.",
|
||||
missingTitle: "Please choose or enter an article title.",
|
||||
missingOutline: "Please select at least one outline section.",
|
||||
missingGeneratedOutline: "Please generate and confirm the article outline first.",
|
||||
missingCompetitorName: "Enter a competitor name before saving it to the library.",
|
||||
savedCompetitor: "Competitor saved to the brand library.",
|
||||
assistReady: "AI analysis is ready. You can keep refining the draft.",
|
||||
assistFailed: "AI analysis failed. Please try again.",
|
||||
assistTimeout: "AI analysis timed out. Please try again.",
|
||||
titleFailed: "Title generation failed. Please try again.",
|
||||
titleTimeout: "Title generation timed out. Please try again.",
|
||||
outlineFailed: "Outline generation failed. Please try again.",
|
||||
outlineTimeout: "Outline generation timed out. Please try again.",
|
||||
draftSaved: "Draft saved. Returning to the template list.",
|
||||
draftSaveFailed: "Failed to save the draft. Please try again.",
|
||||
queued: "Task submitted. The article is now waiting in the generation queue.",
|
||||
submitted: "Generation task submitted. Refreshing article data.",
|
||||
},
|
||||
},
|
||||
@@ -284,6 +382,31 @@ const enUS = {
|
||||
versionHistory: "Version history",
|
||||
untitled: "Untitled article",
|
||||
noContent: "This article does not have generated content yet.",
|
||||
editor: {
|
||||
publish: "Publish",
|
||||
titlePlaceholder: "Enter article title",
|
||||
leaveConfirm: {
|
||||
title: "Unsaved changes",
|
||||
description: "This article has unsaved edits. Leave now to discard them, or save first before going back.",
|
||||
discard: "Discard changes",
|
||||
saveAndLeave: "Save and leave",
|
||||
},
|
||||
platformsTitle: "Publish platforms",
|
||||
platformsHint: "This uses the shared publish-platform selector. For now it shows placeholder bound platforms on the frontend.",
|
||||
coverTitle: "Cover image",
|
||||
coverHint: "Upload a cover asset before publishing. This is local preview only for now.",
|
||||
coverUpload: "Upload cover image",
|
||||
imagePrompt: "Enter image URL",
|
||||
messages: {
|
||||
saved: "Article saved.",
|
||||
generating: "This article is still generating. Try editing it later.",
|
||||
locked: "Only completed articles can be edited.",
|
||||
publishPending: "Publishing is not wired yet. The current action only saves content.",
|
||||
},
|
||||
platforms: {
|
||||
zhihu: "Zhihu",
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
templateType: "Template",
|
||||
currentVersion: "Current version",
|
||||
@@ -350,6 +473,131 @@ const enUS = {
|
||||
chooseKeyword: "Please choose a keyword first.",
|
||||
},
|
||||
},
|
||||
custom: {
|
||||
eyebrow: "Custom Generation",
|
||||
title: "Custom Generation",
|
||||
description: "Generate articles with custom prompt rules, instant or scheduled.",
|
||||
cards: {
|
||||
instantTitle: "Instant Generation",
|
||||
instantDesc: "Quickly create custom content tasks",
|
||||
scheduleTitle: "Scheduled Generation",
|
||||
scheduleDesc: "Set up automated content generation plans",
|
||||
},
|
||||
tabs: {
|
||||
articles: "Articles",
|
||||
instantTasks: "Instant Tasks",
|
||||
scheduleTasks: "Scheduled Tasks",
|
||||
promptRules: "Prompt Rules",
|
||||
},
|
||||
promptRule: {
|
||||
name: "Rule name",
|
||||
namePlaceholder: "Enter prompt name",
|
||||
content: "Prompt content",
|
||||
scene: "Scene",
|
||||
tone: "Default tone",
|
||||
wordCount: "Default word count",
|
||||
status: "Status",
|
||||
articleCount: "Article count",
|
||||
createTitle: "Create Prompt Rule",
|
||||
editTitle: "Edit Prompt Rule",
|
||||
deleteConfirm: "Delete this rule?",
|
||||
enabled: "Enabled",
|
||||
disabled: "Disabled",
|
||||
ungrouped: "Ungrouped",
|
||||
groupPlaceholder: "Select a prompt group",
|
||||
contentPlaceholder: "Enter prompt content, variables supported",
|
||||
},
|
||||
task: {
|
||||
basicSection: "I Basic Information",
|
||||
advancedSection: "I Advanced Settings",
|
||||
name: "Task name",
|
||||
namePlaceholder: "Use a simple name so the task is easy to identify later.",
|
||||
prompt: "Select Prompt",
|
||||
promptPlaceholder: "Select a prompt",
|
||||
createPrompt: "New Prompt",
|
||||
platforms: "Publish platforms",
|
||||
platformsHint: "Choose one or more publish platforms. Only bound platforms are shown here.",
|
||||
platformConnected: "Connected",
|
||||
platformEmptyTitle: "Publish platforms are coming",
|
||||
platformEmptyHint: "Once the media integration is wired, bound tenant platforms will appear here automatically.",
|
||||
cover: "Cover image",
|
||||
coverHint: "Keep the cover clear, complete, and visually polished.",
|
||||
coverUpload: "Upload cover image",
|
||||
coverUploadHint: "Local preview only for now",
|
||||
scheduleTime: "Schedule article generation",
|
||||
scheduleEveryDay: "Every day",
|
||||
enableWebSearch: "Enable web search for generation",
|
||||
generateCount: "Article count",
|
||||
submit: "Create task",
|
||||
},
|
||||
group: {
|
||||
title: "Rule Groups",
|
||||
createTitle: "Create Group",
|
||||
editTitle: "Edit Group",
|
||||
deleteConfirm: "Deleting this group will move its rules to ungrouped. Continue?",
|
||||
name: "Group name",
|
||||
allRules: "All Rules",
|
||||
},
|
||||
schedule: {
|
||||
name: "Task name",
|
||||
rule: "Prompt rule",
|
||||
cron: "Frequency",
|
||||
platform: "Target platform",
|
||||
nextRun: "Next run",
|
||||
startAt: "Start time",
|
||||
endAt: "End time",
|
||||
brand: "Brand",
|
||||
createTitle: "Create Scheduled Task",
|
||||
editTitle: "Edit Scheduled Task",
|
||||
deleteConfirm: "Delete this scheduled task?",
|
||||
enabled: "Enabled",
|
||||
disabled: "Disabled",
|
||||
cronOptions: {
|
||||
daily: "Once daily",
|
||||
twiceDaily: "Twice daily",
|
||||
weekly: "Once weekly",
|
||||
custom: "Custom Cron",
|
||||
},
|
||||
},
|
||||
instant: {
|
||||
title: "Instant Generate",
|
||||
createTitle: "Create Instant Task",
|
||||
selectRule: "Select prompt rule",
|
||||
selectBrand: "Select brand",
|
||||
selectPlatform: "Target platform",
|
||||
submit: "Generate now",
|
||||
extraParams: "Extra parameters",
|
||||
},
|
||||
filters: {
|
||||
promptRule: "Prompt rule",
|
||||
publishStatus: "Publish status",
|
||||
generateStatus: "Generation status",
|
||||
title: "Title",
|
||||
generateTime: "Generation time",
|
||||
},
|
||||
messages: {
|
||||
ruleCreated: "Rule created.",
|
||||
ruleUpdated: "Rule updated.",
|
||||
ruleDeleted: "Rule deleted.",
|
||||
ruleEnabled: "Rule enabled.",
|
||||
ruleDisabled: "Rule disabled.",
|
||||
groupCreated: "Group created.",
|
||||
groupUpdated: "Group updated.",
|
||||
groupDeleted: "Group deleted.",
|
||||
scheduleCreated: "Scheduled task created.",
|
||||
scheduleUpdated: "Scheduled task updated.",
|
||||
scheduleDeleted: "Scheduled task deleted.",
|
||||
scheduleEnabled: "Scheduled task enabled.",
|
||||
scheduleDisabled: "Scheduled task disabled.",
|
||||
generateSubmitted: "Generation task submitted.",
|
||||
missingTaskName: "Enter a task name first.",
|
||||
missingPromptRule: "Choose a prompt first.",
|
||||
invalidGenerateCount: "Article count must be at least 1.",
|
||||
invalidScheduleTime: "Choose a valid schedule time.",
|
||||
missingPromptName: "Enter a prompt name first.",
|
||||
missingPromptContent: "Enter prompt content first.",
|
||||
},
|
||||
},
|
||||
featureStub: {
|
||||
eyebrow: "Feature Placeholder",
|
||||
currentStatus: "Current status",
|
||||
|
||||
Reference in New Issue
Block a user