"""金标准输入 fixtures(灵感 F2)——3 个不同题材的最小 spec+world+outline。 每个 fixture 是一份**自造、不依赖 DB** 的最小设定:书级蓝本(含 genre)+ 世界观硬规则 + 定型主角 + 本章大纲节拍。评估脚本据此组装 craft-on / craft-off 两版写章请求。 新增题材只需追加一个 `FixtureCase`(genre 必须命中 `ww_config.GENRE_CRAFT` 才有片段可注)。 """ from __future__ import annotations from dataclasses import dataclass, field from typing import Any from ww_core.domain.repositories import CharacterView, ProjectSpecView, WorldEntityView @dataclass(frozen=True) class FixtureCase: """一份金标准写章输入(题材 / 章号 / 书级蓝本 / 世界观 / 主角 / 本章节拍)。""" slug: str genre: str chapter_no: int spec: ProjectSpecView world: tuple[WorldEntityView, ...] characters: tuple[CharacterView, ...] beats: dict[str, Any] = field(default_factory=dict) _XIANXIA = FixtureCase( slug="xianxia", genre="仙侠", chapter_no=3, # 开篇章(≤3)——覆盖黄金三章 marker 注入 spec=ProjectSpecView( title="逆脉证道", genre="仙侠", logline="废脉少年叶尘为救绝症妹妹寻回春灵药,滴血觉醒上古逆天功法,逆修九境搅动仙门风云。", premise="天地灵气稀薄,修行看灵脉品阶;废脉者纳灵极慢,被视作修行绝路。", theme="卑微者的不屈与救赎——修的是道,护的是人。", tone="热血隐忍", narrative_pov="第三人称限知", ending_type="正剧", ), world=( WorldEntityView( type="设定", name="九境修为", rules={ "境界": ["淬体", "开脉", "灵动", "纳灵", "凝魂", "化虚", "通玄", "渡劫", "证道"], "每境": "分前中后三重", }, ), WorldEntityView( type="设定", name="灵脉", rules={"作用": "决定纳灵速度", "废脉": "纳灵极慢,被视作修行绝路"}, ), ), characters=( CharacterView( name="叶尘", role="主角", motive="为身患寒髓之症、命不久矣的妹妹叶暖寻回春灵药", backstory="青云宗外门弟子,天生废脉、常年受人轻慢,性子沉静隐忍。", speech_tics={"风格": "话少、点到为止,逼到绝境时语气反而更冷更稳"}, ), ), beats={ "summary": "叶尘被同门构陷逐出青云宗,独行荒山避雨于古洞," "滴血觉醒《逆脉真解》,一招震退追杀者。", "entities": ["叶尘"], "text": "叶尘 古洞 滴血 觉醒 逆脉真解 震退 追杀者", }, ) _URBAN = FixtureCase( slug="urban", genre="都市", chapter_no=1, # 开篇第一章 spec=ProjectSpecView( title="重启我的黄金时代", genre="都市", logline="落魄程序员林川一夜重生回到二十年前,凭前世记忆在时代风口逆天改命。", premise="重生回到世纪初互联网草莽年代,机会遍地、格局未定。", theme="不甘平庸者抓住的第二次机会。", tone="爽快励志", narrative_pov="第一人称", ending_type="HE", ), world=( WorldEntityView( type="设定", name="重生规则", rules={ "回溯": "重生回到 2003 年的大学时代", "记忆": "完整保留前世记忆与二十年行业趋势", }, ), ), characters=( CharacterView( name="林川", role="主角", motive="改写前世潦倒猝死的结局,护住家人、抓住时代机遇翻身", backstory="前世三十五岁猝死于出租屋的落魄外包程序员。", speech_tics={"风格": "表面随和、心里门儿清,说话带点自嘲"}, ), ), beats={ "summary": "林川在出租屋猝死后睁眼回到 2003 年的大学宿舍," "认出这是重来一次的机会,立下第一个目标。", "entities": ["林川"], "text": "林川 重生 2003 大学宿舍 认清机会", }, ) _SUSPENSE = FixtureCase( slug="suspense", genre="悬疑", chapter_no=2, # 开篇第二章 spec=ProjectSpecView( title="雾隐镇失踪案", genre="悬疑", logline="刑警周砚回到多雾的故乡小镇调查连环失踪案,线索却一步步指向自己尘封的童年。", premise="常年浓雾笼罩的封闭小镇,二十年前也发生过同样的失踪,无人被起诉。", theme="逼近真相与自我和解的代价。", tone="冷峻压抑", narrative_pov="第三人称限知", ending_type="开放", ), world=( WorldEntityView( type="设定", name="雾隐镇", rules={ "环境": "常年浓雾、信号时断时续", "旧案": "二十年前发生过同类失踪,卷宗离奇缺页", }, ), ), characters=( CharacterView( name="周砚", role="主角", motive="查清连环失踪真相,也为解开自己童年缺失的那段记忆", backstory="市局刑警,幼年从雾隐镇被送走,对故乡的记忆断片。", speech_tics={"风格": "话短、爱用反问,审讯时不动声色"}, ), ), beats={ "summary": "周砚勘查第二名失踪者的住所," "在墙缝里发现一张与二十年前旧案笔迹相同的纸条,心头一凛。", "entities": ["周砚"], "text": "周砚 现场勘查 墙缝 纸条 二十年前 旧案", }, ) # 金标准题材集:仙侠 / 都市 / 悬疑(各含开篇章,覆盖黄金三章 marker)。 FIXTURES: tuple[FixtureCase, ...] = (_XIANXIA, _URBAN, _SUSPENSE)