Files
life-echo/api/app/features/memoir/models.py

221 lines
7.7 KiB
Python
Raw Normal View History

from sqlalchemy import (
JSON,
Boolean,
Column,
DateTime,
ForeignKey,
Integer,
String,
Text,
)
from sqlalchemy.orm import relationship
from app.core.db import Base, utc_now
class Chapter(Base):
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
"""章节阅读与导出视图canonical_markdown 为正文真源。"""
__tablename__ = "chapters"
id = Column(String, primary_key=True)
user_id = Column(String, ForeignKey("users.id"), nullable=False)
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
book_id = Column(String, ForeignKey("books.id", ondelete="SET NULL"), nullable=True)
title = Column(String, nullable=False)
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
category = Column(String, nullable=True)
order_index = Column(Integer, nullable=False)
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
summary = Column(Text, nullable=True)
canonical_markdown = Column(Text, nullable=True) # 当前生效正文markdown-first
status = Column(String, default="draft") # active / draft / archived
cover_asset_id = Column(String, nullable=True)
current_version_id = Column(String, nullable=True) # FK 在 migration 中分步添加
created_at = Column(DateTime(timezone=True), default=utc_now)
updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
is_new = Column(Boolean, default=True)
is_active = Column(Boolean, default=True)
source_segments = Column(JSON, nullable=True)
2026-03-20 15:15:35 +08:00
# story-backed 章节story 变更后标 True由 Celery 重组 canonical_markdown
markdown_compose_dirty = Column(Boolean, default=False, nullable=False)
markdown_composed_at = Column(DateTime(timezone=True), nullable=True)
# 与 canonical 同一生成时机物化;无签名 URL读时 hydrate
reading_segments_json = Column(JSON, nullable=True)
user = relationship("User", back_populates="chapters")
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
book = relationship("Book", back_populates="chapters")
images = relationship(
"MemoirImage",
back_populates="chapter",
foreign_keys="MemoirImage.chapter_id",
cascade="all, delete-orphan",
)
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
versions = relationship(
"ChapterVersion",
back_populates="chapter",
foreign_keys="ChapterVersion.chapter_id",
cascade="all, delete-orphan",
)
current_version = relationship(
"ChapterVersion",
primaryjoin="Chapter.current_version_id == ChapterVersion.id",
foreign_keys="ChapterVersion.id",
)
story_links = relationship(
"ChapterStoryLink",
back_populates="chapter",
cascade="all, delete-orphan",
)
cover_intents = relationship(
"ChapterCoverIntent",
back_populates="chapter",
cascade="all, delete-orphan",
)
class MemoirImage(Base):
__tablename__ = "memoir_images"
id = Column(String, primary_key=True)
chapter_id = Column(
String, ForeignKey("chapters.id", ondelete="CASCADE"), nullable=False
)
order_index = Column(Integer, nullable=False, default=0)
placeholder = Column(Text, nullable=True)
description = Column(Text, nullable=True)
status = Column(String, nullable=False, default="pending")
prompt = Column(Text, nullable=True)
url = Column(Text, nullable=True)
storage_key = Column(Text, nullable=True)
provider = Column(String, nullable=True)
style = Column(String, nullable=True)
size = Column(String, nullable=True)
error = Column(Text, nullable=True)
retryable = Column(Boolean, nullable=True)
created_at = Column(DateTime(timezone=True), nullable=True)
updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
chapter = relationship("Chapter", back_populates="images")
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
class ChapterVersion(Base):
"""Chapter 版本快照,记录正文变更与来源。"""
__tablename__ = "chapter_versions"
id = Column(String, primary_key=True)
chapter_id = Column(
String,
ForeignKey("chapters.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
version_no = Column(Integer, nullable=False)
markdown_snapshot = Column(Text, nullable=False)
change_summary = Column(Text, nullable=True)
actor_type = Column(String, nullable=True) # ai / user / editor / system
source_type = Column(
String, nullable=True
) # generate / rewrite / merge / manual / migration
parent_version_id = Column(
String, ForeignKey("chapter_versions.id", ondelete="SET NULL"), nullable=True
)
prompt_meta = Column(JSON, nullable=True)
created_at = Column(DateTime(timezone=True), default=utc_now)
chapter = relationship(
"Chapter", back_populates="versions", foreign_keys=[chapter_id]
)
parent_version = relationship(
"ChapterVersion",
remote_side="ChapterVersion.id",
foreign_keys=[parent_version_id],
)
class ChapterCoverIntent(Base):
"""Chapter 封面意图(结构化)。"""
__tablename__ = "chapter_cover_intents"
id = Column(String, primary_key=True)
chapter_id = Column(
String,
ForeignKey("chapters.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
chapter_version_id = Column(
String,
ForeignKey("chapter_versions.id", ondelete="SET NULL"),
nullable=True,
)
story_ids = Column(JSON, nullable=True)
prompt_brief = Column(Text, nullable=True)
status = Column(String, nullable=False)
claim_token = Column(String, nullable=True)
claimed_at = Column(DateTime(timezone=True), nullable=True)
attempt_count = Column(Integer, nullable=False, default=0)
asset_id = Column(String, nullable=True)
error = Column(Text, nullable=True)
created_at = Column(DateTime(timezone=True), default=utc_now)
updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
chapter = relationship("Chapter", back_populates="cover_intents")
class ChapterStoryLink(Base):
"""Chapter 与 Story 的编排关联。"""
__tablename__ = "chapter_story_links"
id = Column(String, primary_key=True)
chapter_id = Column(
String,
ForeignKey("chapters.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
story_id = Column(
String, ForeignKey("stories.id", ondelete="CASCADE"), nullable=False, index=True
)
order_index = Column(Integer, nullable=False)
role = Column(String, nullable=True) # core / bridge / appendix
created_at = Column(DateTime(timezone=True), default=utc_now)
chapter = relationship("Chapter", back_populates="story_links")
story = relationship("Story", back_populates="chapter_links")
class Book(Base):
__tablename__ = "books"
id = Column(String, primary_key=True)
user_id = Column(String, ForeignKey("users.id"), nullable=False)
title = Column(String, nullable=False)
total_pages = Column(Integer, default=0)
total_words = Column(Integer, default=0)
cover_image_url = Column(String, nullable=True)
updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
has_update = Column(Boolean, default=False)
last_update_chapter_id = Column(String, nullable=True)
user = relationship("User", back_populates="books")
重构回忆录为 story-first / markdown-first 架构并整合图片意图与前端 UI 修复 本次 squash merge 将 codex-story-first-image-intent 的整体改动合入 development,核心内容包括: 1. 后端数据与迁移:新增 stories、story_versions、story_image_intents、chapter_cover_intents、assets 等模型与 Alembic 迁移,建立 story-first、markdown-first、asset-first 的主数据链路。 2. 生成与任务链:引入 StoryBuilderOrchestrator、ChapterComposerOrchestrator、story_image_tasks、chapter_cover_tasks,图片生成从正文占位符改为结构化 intent -> asset -> markdown 回填。 3. 并发与一致性:为 story/chapter intent 增加 claim_token、claimed_at、attempt_count,采用数据库原子 claim 为主、Redis 锁为辅,避免重复生成、锁误删和 processing 卡死。 4. Memoir 读写路径:章节 canonical_markdown 成为正文真源,列表/详情接口补齐 markdown、cover_asset、word_count 等字段,PDF 与 asset 解析链路同步升级。 5. Memory / Retrieval:扩展 transcript ingest、chunking、evidence 检索与 story 聚合基础设施,为后续 story-first RAG 与多 agent 编排提供底座。 6. App 端体验:章节页继续走 MarkdownRenderer 阅读链,同时吸收 fix3-19 的跨平台 UI glitch 修复;更新对话页、首页、文案资源与章节列表映射逻辑。 7. 测试与文档:补充 asset resolver、story image task、章节封面派发、markdown 映射等回归测试,并加入图片占位符退役设计文档。
2026-03-20 10:30:07 +08:00
chapters = relationship(
"Chapter",
back_populates="book",
foreign_keys="Chapter.book_id",
)
class MemoirState(Base):
__tablename__ = "memoir_states"
id = Column(String, primary_key=True)
user_id = Column(String, ForeignKey("users.id"), unique=True, nullable=False)
stage_order = Column(JSON, default=list)
current_stage = Column(String, default="childhood")
covered_stages = Column(JSON, default=list)
slots = Column(JSON, nullable=False)
updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now)
user = relationship("User", back_populates="memoir_state")