feat: expose optimizer workflow api

This commit is contained in:
Codex
2026-06-21 23:42:37 +08:00
parent 75bcab33c6
commit dd6480a8be
7 changed files with 346 additions and 18 deletions
+30
View File
@@ -245,6 +245,36 @@ export function getArticleJob(dbPath: string | undefined, id: string) {
});
}
export function updateArticleJob(
dbPath: string | undefined,
id: string,
changes: Partial<Pick<ArticleJob, "brand_template_id" | "status" | "export_paths">>,
) {
return withDb(dbPath, (db) => {
const existing = getArticleJob(dbPath, id);
if (!existing) return null;
const updated = {
brand_template_id: changes.brand_template_id ?? existing.brand_template_id,
status: changes.status ?? existing.status,
export_paths: changes.export_paths ?? existing.export_paths,
updated_at: nowIso(),
};
db.prepare(
`update article_jobs set
brand_template_id = @brand_template_id,
status = @status,
export_paths = @export_paths,
updated_at = @updated_at
where id = @id`,
).run({
id,
...updated,
export_paths: serialize(updated.export_paths),
});
return getArticleJob(dbPath, id);
});
}
export function saveFactCard(
dbPath: string | undefined,
jobId: string,
+11 -18
View File
@@ -75,24 +75,17 @@ export const candidateFactCardSchema = factCardBaseSchema
is_ready_for_optimization: card.uncertain_items.length === 0,
})) satisfies z.ZodType<CandidateFactCard>;
export const confirmedFactCardSchema = candidateFactCardSchema
.pipe(
z.object({
company_full_name: z.string().trim().min(1),
company_short_names: z.array(z.string().trim().min(1)).default([]),
brand_names: z.array(z.string().trim().min(1)).default([]),
product_names: z.array(z.string().trim().min(1)).default([]),
target_industry: z.string().trim().min(1),
target_audience: z.string().trim().min(1),
experience_years: z.number().int().nonnegative().nullable().default(null),
core_claims: z.array(z.string().trim().min(1)).default([]),
forbidden_claims: z.array(z.string().trim().min(1)).default([]),
image_topics: z.array(z.string().trim().min(1)).default([]),
uncertain_items: z.array(z.never()).length(0),
is_ready_for_optimization: z.literal(true),
}),
)
.and(z.object({ confirmed_by_user: z.literal(true) })) satisfies z.ZodType<ConfirmedFactCard>;
export const confirmedFactCardSchema = factCardBaseSchema
.extend({
company_full_name: z.string().trim().min(1),
uncertain_items: z.array(z.never()).length(0),
confirmed_by_user: z.literal(true),
is_ready_for_optimization: z.boolean().optional(),
})
.transform((card) => ({
...card,
is_ready_for_optimization: true as const,
})) satisfies z.ZodType<ConfirmedFactCard>;
export const imageSuggestionSchema = z.object({
source: z.string().trim().min(1),