feat(studio): reflect account-voice / series-scope field split
Robot-author edit form and detail drop positioning/target_readers (now series-level); persona + styles stay (routed to the account profile via the admin API). Series detail shows positioning/target_readers. Types updated; admin API types regenerated.
This commit is contained in:
@@ -690,7 +690,7 @@ export interface paths {
|
|||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
/**
|
/**
|
||||||
* @example ios
|
* @example android
|
||||||
* @enum {string|null}
|
* @enum {string|null}
|
||||||
*/
|
*/
|
||||||
platform?: "ios" | "android" | "web" | "desktop" | null;
|
platform?: "ios" | "android" | "web" | "desktop" | null;
|
||||||
@@ -1155,7 +1155,7 @@ export interface paths {
|
|||||||
content: {
|
content: {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
/**
|
/**
|
||||||
* @example dismissed
|
* @example resolved
|
||||||
* @enum {string|null}
|
* @enum {string|null}
|
||||||
*/
|
*/
|
||||||
status?: "open" | "resolved" | "dismissed" | null;
|
status?: "open" | "resolved" | "dismissed" | null;
|
||||||
|
|||||||
+4
-2
@@ -152,9 +152,8 @@ export interface StudioRobotAuthor {
|
|||||||
avatar?: string | null
|
avatar?: string | null
|
||||||
category_id: string
|
category_id: string
|
||||||
subtopic_id: string | null
|
subtopic_id: string | null
|
||||||
|
/** Account-level voice — stored on the shared profile, flattened into the author. */
|
||||||
persona: string | null
|
persona: string | null
|
||||||
positioning: string | null
|
|
||||||
target_readers: string | null
|
|
||||||
article_style: Record<string, unknown> | null
|
article_style: Record<string, unknown> | null
|
||||||
image_style: Record<string, unknown> | null
|
image_style: Record<string, unknown> | null
|
||||||
publishing_rules: Record<string, unknown> | null
|
publishing_rules: Record<string, unknown> | null
|
||||||
@@ -173,6 +172,9 @@ export interface StudioSeries {
|
|||||||
subtopic_id: string | null
|
subtopic_id: string | null
|
||||||
robot_author_id: string
|
robot_author_id: string
|
||||||
goal: string | null
|
goal: string | null
|
||||||
|
/** Series-level angle/audience (moved off the author). */
|
||||||
|
positioning: string | null
|
||||||
|
target_readers: string | null
|
||||||
reader_journey: string | null
|
reader_journey: string | null
|
||||||
target_article_count: number | null
|
target_article_count: number | null
|
||||||
planned_articles: unknown[] | null
|
planned_articles: unknown[] | null
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ const jsonObject = z.string().refine(
|
|||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
persona: z.string(),
|
persona: z.string(),
|
||||||
positioning: z.string(),
|
|
||||||
target_readers: z.string(),
|
|
||||||
status: z.enum(STATUSES),
|
status: z.enum(STATUSES),
|
||||||
article_style: jsonObject,
|
article_style: jsonObject,
|
||||||
image_style: jsonObject,
|
image_style: jsonObject,
|
||||||
@@ -75,8 +73,6 @@ export function RobotAuthorEditSheet({ author, onOpenChange }: RobotAuthorEditSh
|
|||||||
resolver: zodResolver(schema),
|
resolver: zodResolver(schema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
persona: '',
|
persona: '',
|
||||||
positioning: '',
|
|
||||||
target_readers: '',
|
|
||||||
status: 'pending',
|
status: 'pending',
|
||||||
article_style: '',
|
article_style: '',
|
||||||
image_style: '',
|
image_style: '',
|
||||||
@@ -88,8 +84,6 @@ export function RobotAuthorEditSheet({ author, onOpenChange }: RobotAuthorEditSh
|
|||||||
if (!author) return
|
if (!author) return
|
||||||
form.reset({
|
form.reset({
|
||||||
persona: author.persona ?? '',
|
persona: author.persona ?? '',
|
||||||
positioning: author.positioning ?? '',
|
|
||||||
target_readers: author.target_readers ?? '',
|
|
||||||
status: author.status,
|
status: author.status,
|
||||||
article_style: asText(author.article_style),
|
article_style: asText(author.article_style),
|
||||||
image_style: asText(author.image_style),
|
image_style: asText(author.image_style),
|
||||||
@@ -102,8 +96,6 @@ export function RobotAuthorEditSheet({ author, onOpenChange }: RobotAuthorEditSh
|
|||||||
if (!author) throw new Error('no author')
|
if (!author) throw new Error('no author')
|
||||||
return updateRobotAuthor(author.id, {
|
return updateRobotAuthor(author.id, {
|
||||||
persona: values.persona.trim() || null,
|
persona: values.persona.trim() || null,
|
||||||
positioning: values.positioning.trim() || null,
|
|
||||||
target_readers: values.target_readers.trim() || null,
|
|
||||||
status: values.status,
|
status: values.status,
|
||||||
article_style: parseObject(values.article_style),
|
article_style: parseObject(values.article_style),
|
||||||
image_style: parseObject(values.image_style),
|
image_style: parseObject(values.image_style),
|
||||||
@@ -153,12 +145,9 @@ export function RobotAuthorEditSheet({ author, onOpenChange }: RobotAuthorEditSh
|
|||||||
<Field label="人设" error={form.formState.errors.persona?.message}>
|
<Field label="人设" error={form.formState.errors.persona?.message}>
|
||||||
<Textarea rows={3} {...form.register('persona')} placeholder="务实的家电维修师傅…" />
|
<Textarea rows={3} {...form.register('persona')} placeholder="务实的家电维修师傅…" />
|
||||||
</Field>
|
</Field>
|
||||||
<Field label="内容定位" error={form.formState.errors.positioning?.message}>
|
<p className="-mt-1 text-xs text-muted-foreground">
|
||||||
<Textarea rows={2} {...form.register('positioning')} />
|
人设与写作/配图风格为账号级,对该账号全部系列/文章生效。内容定位、目标读者已移至系列级(在系列上编辑)。
|
||||||
</Field>
|
</p>
|
||||||
<Field label="目标读者" error={form.formState.errors.target_readers?.message}>
|
|
||||||
<Textarea rows={2} {...form.register('target_readers')} />
|
|
||||||
</Field>
|
|
||||||
|
|
||||||
<Field
|
<Field
|
||||||
label="写作风格 (JSON)"
|
label="写作风格 (JSON)"
|
||||||
|
|||||||
@@ -184,8 +184,6 @@ function RobotAuthorsPage() {
|
|||||||
{ label: '用户 UID', value: <code className="font-mono text-xs">{detail?.user_uid}</code> },
|
{ label: '用户 UID', value: <code className="font-mono text-xs">{detail?.user_uid}</code> },
|
||||||
{ label: '分类', value: detail && nameOf(detail.category_id) },
|
{ label: '分类', value: detail && nameOf(detail.category_id) },
|
||||||
{ label: '状态', value: detail && <StatusPill status={detail.status} /> },
|
{ label: '状态', value: detail && <StatusPill status={detail.status} /> },
|
||||||
{ label: '定位', value: detail?.positioning },
|
|
||||||
{ label: '目标读者', value: detail?.target_readers },
|
|
||||||
{ label: '人设', value: detail?.persona },
|
{ label: '人设', value: detail?.persona },
|
||||||
]}
|
]}
|
||||||
jsonBlocks={[
|
jsonBlocks={[
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ function SeriesPage() {
|
|||||||
{ label: 'ID', value: <code className="font-mono text-xs">{detail?.id}</code> },
|
{ label: 'ID', value: <code className="font-mono text-xs">{detail?.id}</code> },
|
||||||
{ label: '状态', value: detail && <StatusPill status={detail.status} /> },
|
{ label: '状态', value: detail && <StatusPill status={detail.status} /> },
|
||||||
{ label: '计划篇数', value: detail?.target_article_count },
|
{ label: '计划篇数', value: detail?.target_article_count },
|
||||||
|
{ label: '内容定位', value: detail?.positioning },
|
||||||
|
{ label: '目标读者', value: detail?.target_readers },
|
||||||
{ label: '读者旅程', value: detail?.reader_journey },
|
{ label: '读者旅程', value: detail?.reader_journey },
|
||||||
{
|
{
|
||||||
label: '作者',
|
label: '作者',
|
||||||
|
|||||||
Reference in New Issue
Block a user