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:
2026-04-02 00:31:28 +08:00
parent de30497f59
commit b31d8d0096
101 changed files with 16671 additions and 721 deletions
+148 -4
View File
@@ -9,24 +9,48 @@ import type {
BrandRequest,
Competitor,
CompetitorRequest,
GenerateFromRuleRequest,
GenerateFromRuleResponse,
JsonValue,
Keyword,
KeywordRequest,
LoginRequest,
LoginResponse,
PromptRule,
PromptRuleGroup,
PromptRuleGroupRequest,
PromptRuleListParams,
PromptRuleListResponse,
PromptRuleRequest,
PromptRuleSimple,
PromptRuleStatusRequest,
QuotaSummary,
Question,
QuestionRequest,
QuestionVersion,
RecentArticle,
RefreshResponse,
ScheduleTask,
ScheduleTaskListParams,
ScheduleTaskListResponse,
ScheduleTaskRequest,
ScheduleTaskStatusRequest,
TemplateDetail,
TemplateAnalyzeTaskRequest,
TemplateAnalyzeTaskResultResponse,
TemplateAssistTaskCreateResponse,
TemplateOutlineTaskRequest,
TemplateOutlineTaskResultResponse,
TemplateSaveDraftRequest,
TemplateSaveDraftResponse,
TemplateTitleTaskRequest,
TemplateTitleTaskResultResponse,
TemplateGenerateRequest,
TemplateGenerateResponse,
TemplateListItem,
TemplateSchema,
TemplateCard,
UpdateQuestionRequest,
UpdateArticleRequest,
UserInfo,
WorkspaceOverview,
} from "@geo/shared-types";
@@ -98,8 +122,47 @@ export const templatesApi = {
detail(id: number) {
return apiClient.get<TemplateDetail>(`/api/tenant/templates/${id}`);
},
schema(id: number) {
return apiClient.get<TemplateSchema>(`/api/tenant/templates/${id}/schema`);
createAnalyzeTask(id: number, payload: TemplateAnalyzeTaskRequest) {
return apiClient.post<TemplateAssistTaskCreateResponse, TemplateAnalyzeTaskRequest>(
`/api/tenant/templates/${id}/analyze-tasks`,
payload,
);
},
getAnalyzeTaskResult(id: number, taskId: string) {
return apiClient.get<TemplateAnalyzeTaskResultResponse>(
`/api/tenant/templates/${id}/analyze_task_result`,
{ params: { task_id: taskId } },
);
},
createTitleTask(id: number, payload: TemplateTitleTaskRequest) {
return apiClient.post<TemplateAssistTaskCreateResponse, TemplateTitleTaskRequest>(
`/api/tenant/templates/${id}/title-tasks`,
payload,
);
},
getTitleTaskResult(id: number, taskId: string) {
return apiClient.get<TemplateTitleTaskResultResponse>(
`/api/tenant/templates/${id}/gen_title_task_result`,
{ params: { task_id: taskId } },
);
},
createOutlineTask(id: number, payload: TemplateOutlineTaskRequest) {
return apiClient.post<TemplateAssistTaskCreateResponse, TemplateOutlineTaskRequest>(
`/api/tenant/templates/${id}/outline-tasks`,
payload,
);
},
getOutlineTaskResult(id: number, taskId: string) {
return apiClient.get<TemplateOutlineTaskResultResponse>(
`/api/tenant/templates/${id}/gen_outline_task_result`,
{ params: { task_id: taskId } },
);
},
createAssistTask(id: number, payload: TemplateAnalyzeTaskRequest) {
return this.createAnalyzeTask(id, payload);
},
getAssistTask(id: number, taskId: string) {
return this.getAnalyzeTaskResult(id, taskId);
},
generate(id: number, payload: TemplateGenerateRequest) {
return apiClient.post<TemplateGenerateResponse, TemplateGenerateRequest>(
@@ -107,6 +170,12 @@ export const templatesApi = {
payload,
);
},
saveDraft(id: number, payload: TemplateSaveDraftRequest) {
return apiClient.post<TemplateSaveDraftResponse, TemplateSaveDraftRequest>(
`/api/tenant/templates/${id}/drafts`,
payload,
);
},
};
export const articlesApi = {
@@ -116,6 +185,9 @@ export const articlesApi = {
detail(id: number) {
return apiClient.get<ArticleDetail>(`/api/tenant/articles/${id}`);
},
update(id: number, payload: UpdateArticleRequest) {
return apiClient.put<ArticleDetail, UpdateArticleRequest>(`/api/tenant/articles/${id}`, payload);
},
versions(id: number) {
return apiClient.get<ArticleVersion[]>(`/api/tenant/articles/${id}/versions`);
},
@@ -270,10 +342,82 @@ export const brandsApi = {
},
};
export const promptRulesApi = {
list(params?: PromptRuleListParams) {
return apiClient.get<PromptRuleListResponse>("/api/tenant/prompt-rules", { params });
},
listSimple() {
return apiClient.get<PromptRuleSimple[]>("/api/tenant/prompt-rules/simple");
},
detail(id: number) {
return apiClient.get<PromptRule>(`/api/tenant/prompt-rules/${id}`);
},
create(payload: PromptRuleRequest) {
return apiClient.post<PromptRule, PromptRuleRequest>("/api/tenant/prompt-rules", payload);
},
update(id: number, payload: PromptRuleRequest) {
return apiClient.put<null, PromptRuleRequest>(`/api/tenant/prompt-rules/${id}`, payload);
},
remove(id: number) {
return apiClient.remove<null>(`/api/tenant/prompt-rules/${id}`);
},
toggleStatus(id: number, payload: PromptRuleStatusRequest) {
return apiClient.put<null, PromptRuleStatusRequest>(`/api/tenant/prompt-rules/${id}/status`, payload);
},
listGroups() {
return apiClient.get<PromptRuleGroup[]>("/api/tenant/prompt-rules/groups");
},
createGroup(payload: PromptRuleGroupRequest) {
return apiClient.post<PromptRuleGroup, PromptRuleGroupRequest>("/api/tenant/prompt-rules/groups", payload);
},
updateGroup(id: number, payload: PromptRuleGroupRequest) {
return apiClient.put<null, PromptRuleGroupRequest>(`/api/tenant/prompt-rules/groups/${id}`, payload);
},
removeGroup(id: number) {
return apiClient.remove<null>(`/api/tenant/prompt-rules/groups/${id}`);
},
};
export const schedulesApi = {
list(params?: ScheduleTaskListParams) {
return apiClient.get<ScheduleTaskListResponse>("/api/tenant/schedules", { params });
},
detail(id: number) {
return apiClient.get<ScheduleTask>(`/api/tenant/schedules/${id}`);
},
create(payload: ScheduleTaskRequest) {
return apiClient.post<ScheduleTask, ScheduleTaskRequest>("/api/tenant/schedules", payload);
},
update(id: number, payload: ScheduleTaskRequest) {
return apiClient.put<null, ScheduleTaskRequest>(`/api/tenant/schedules/${id}`, payload);
},
remove(id: number) {
return apiClient.remove<null>(`/api/tenant/schedules/${id}`);
},
toggleStatus(id: number, payload: ScheduleTaskStatusRequest) {
return apiClient.put<null, ScheduleTaskStatusRequest>(`/api/tenant/schedules/${id}/status`, payload);
},
};
export const generateApi = {
fromRule(payload: GenerateFromRuleRequest) {
return apiClient.post<GenerateFromRuleResponse, GenerateFromRuleRequest>(
"/api/tenant/articles/generate-from-rule",
payload,
);
},
};
export function normalizeInputParams(
payload: Record<string, JsonValue>,
articleId?: number,
wizardState?: Record<string, JsonValue>,
): TemplateGenerateRequest {
return { input_params: payload };
return {
article_id: articleId,
input_params: payload,
wizard_state: wizardState,
};
}
function consumeSSEBuffer(