feat(character): appearance/motive 全栈穿线 + motive/traits 口径重切
打通 appearance/motive 从生成→schema→契约→落库→前端整条穿线 (DB 列早在初始迁移、此前一直 NULL,无新迁移),并原子重切人物 内驱口径。 - @llm: CharacterCard/character-gen.md 加 appearance/motive(给默认值守 解析韧性),重切——动机唯一落 motive、traits 只留核心/表层/阴影三层、 arc 引用 motive;regen prompt_hashes.json 金标准。 - @backend: CharacterCardView + CharacterWriteRepo/SqlCharacterWriteRepo (create + update backfill 分支)+ CharacterWriteFields + 路由双向形变 与 _existing_characters 带上两字段。 - @frontend: pnpm gen:api 重生成 TS 客户端;CharacterCardItem 展示/编辑 两字段。 - 测试: schema 默认值/解析、动机不双写重切回归、card_to_view 双向、 ingest 透传、list 暴露、SqlCharacterWriteRepo create/backfill 真 pg 集成。
This commit is contained in:
@@ -55,6 +55,40 @@ export function CharacterCardItem({
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{onEdit || card.appearance ? (
|
||||
<div className="mb-1 flex items-start gap-1 text-ink-soft">
|
||||
<span className="shrink-0 text-ink">外貌:</span>
|
||||
{onEdit ? (
|
||||
<TextInput
|
||||
value={card.appearance ?? ""}
|
||||
onChange={(e) => onEdit({ appearance: e.target.value })}
|
||||
aria-label="外貌形象"
|
||||
controlSize="sm"
|
||||
className="min-w-0 flex-1"
|
||||
/>
|
||||
) : (
|
||||
<span>{card.appearance}</span>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{onEdit || card.motive ? (
|
||||
<div className="mb-1 flex items-start gap-1 text-ink-soft">
|
||||
<span className="shrink-0 text-ink">动机:</span>
|
||||
{onEdit ? (
|
||||
<TextInput
|
||||
value={card.motive ?? ""}
|
||||
onChange={(e) => onEdit({ motive: e.target.value })}
|
||||
aria-label="核心动机"
|
||||
controlSize="sm"
|
||||
className="min-w-0 flex-1"
|
||||
/>
|
||||
) : (
|
||||
<span>{card.motive}</span>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<p className="mb-1 text-ink-soft">
|
||||
<span className="text-ink">背景:</span>
|
||||
{card.backstory}
|
||||
|
||||
Reference in New Issue
Block a user