Преглед на файлове

fix: make story-system writes atomic

lingfengQAQ преди 1 месец
родител
ревизия
43a856eca6
променени са 2 файла, в които са добавени 8 реда и са изтрити 4 реда
  1. 2 2
      webnovel-writer/scripts/data_modules/chapter_commit_service.py
  2. 6 2
      webnovel-writer/scripts/data_modules/story_contracts.py

+ 2 - 2
webnovel-writer/scripts/data_modules/chapter_commit_service.py

@@ -2,7 +2,6 @@
 # -*- coding: utf-8 -*-
 from __future__ import annotations
 
-import json
 from pathlib import Path
 from typing import Any, Dict
 
@@ -11,6 +10,7 @@ from chapter_outline_loader import volume_num_for_chapter_from_state
 from .config import DataModulesConfig
 from .event_log_store import EventLogStore
 from .event_projection_router import EventProjectionRouter
+from .story_contracts import write_json
 from .index_manager import IndexManager
 from .override_ledger_service import (
     AmendProposalTrigger,
@@ -79,7 +79,7 @@ class ChapterCommitService:
         target = self.project_root / ".story-system" / "commits"
         target.mkdir(parents=True, exist_ok=True)
         path = target / f"chapter_{int(payload['meta']['chapter']):03d}.commit.json"
-        path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
+        write_json(path, payload)
         return path
 
     def apply_projections(self, payload: Dict[str, Any]) -> Dict[str, Any]:

+ 6 - 2
webnovel-writer/scripts/data_modules/story_contracts.py

@@ -9,6 +9,11 @@ from typing import Any, Dict, Iterable, List
 
 from chapter_outline_loader import volume_num_for_chapter_from_state
 
+try:
+    from security_utils import atomic_write_json
+except ImportError:  # pragma: no cover
+    from scripts.security_utils import atomic_write_json
+
 
 MARKER_BEGIN = "<!-- STORY-SYSTEM:BEGIN -->"
 MARKER_END = "<!-- STORY-SYSTEM:END -->"
@@ -120,8 +125,7 @@ def read_json_if_exists(path: Path) -> Any | None:
 
 
 def write_json(path: Path, payload: Any) -> None:
-    path.parent.mkdir(parents=True, exist_ok=True)
-    path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
+    atomic_write_json(path, payload, backup=True)
 
 
 def write_marked_markdown(path: Path, generated_block: str) -> None: