メインコンテンツへスキップ

ドメインデータクラス設計(YAML → ドメイン)

1. 設計方針

  • 入力1ファイル=1 Bookbook_id を必須)
  • 記載順は意味を持つため、list の順序は保持する
  • 既存更新・削除はしない(SKIP 判定は後段のユースケースで行う)
  • データクラスは YAML スキーマの写像に徹し、BookStack API 概念(id 等)は持たない
  • None を持ち込まず、後段ロジックの分岐を減らすため 空リストに正規化する
  • 文字列は前後 trim(strip)してから保持する(本仕様で固定)

2. データクラス一覧

2.1 BookInput(入力全体)

フィールド 型(設計) 必須 由来 意味
book_id int YAML book_id 対象 Book の ID
wip_markdown str YAML wip_markdown 新規作成ページ本文(Markdown)
pages list[str] ✓(空可) YAML pages Book直下ページ名(順序保持)
chapters list[ChapterInput] ✓(空可) YAML chapters 章定義(順序保持)

正規化:

  • YAML 上で pages / chapters が省略された場合、ドメインでは [] とする。

2.2 ChapterInput(章 + 章配下ページ)

フィールド 型(設計) 必須 由来 意味
name str YAML chapters[].name 章名(同一性判定キー)
pages list[str] ✓(空可) YAML chapters[].pages 章配下ページ名(順序保持)

正規化:

  • YAML 上で chapters[].pages が省略された場合、ドメインでは [] とする。

3. 正規化ルール(YAML → ドメイン変換時)

3.1 欠損の正規化

  1. pages が未指定なら []
  2. chapters が未指定なら []
  3. chapters[].pages が未指定なら []

3.2 文字列の正規化(trim)

以下の文字列は **前後の空白を trim(strip() 相当)**して格納する。

  • wip_markdown
  • pages[] の各要素
  • chapters[].name
  • chapters[].pages[] の各要素

4. ドメインレベル・バリデーション仕様(入力エラー条件)

4.1 必須チェック

  • book_id:存在し、int
  • wip_markdown:存在し、str かつ trim 後に空文字列を禁止strip() 後に "" は入力エラー)

4.2 型チェック

  • pageslist[str]

  • chapterslist[object]

    • namestr(必須)
    • pageslist[str](任意だが指定時は要素が全て str

name / pages[] の要素は、trim 後に空文字列は禁止strip() 後に "" は入力エラー)

4.3 重複チェック(入力エラー)

重複判定は trim 後の値で行う。

  • BookInput.pages 内で同名が重複 → 入力エラー
  • BookInput.chapters 内で ChapterInput.name が重複 → 入力エラー
  • 同一 ChapterInput.pages 内で同名が重複 → 入力エラー
  • Book直下 pages と章配下 pages の同名は 許容(別スコープ)

4.4 トップレベルキーの重複(仕様違反)

  • YAML のトップレベルキー book_id / wip_markdown / pages / chapters の重複定義は仕様違反
  • ただし、重複キー検出のための特別な処理は行わず、パーサが正常にロードできた入力のみを前提とする (仕様として禁止し、可読性と予測可能性を担保する)

5. このデータクラスで担保できること / できないこと

担保できること

  • YAML が期待する形(型・必須性・trim・重複禁止)であること
  • 後段処理が None を気にせず、順序通りに処理できること

担保しないこと(後段責務)

  • book_id が BookStack 上に実在するか
  • 同名章・同名ページが既に存在するか(SKIP 判定はユースケース側)
  • API リトライや通信例外の扱い

次は、この仕様をそのまま **Python の dataclass 定義(型注釈・docstring)**に落とし込み、同時に validate()(または from_yaml() 内)でどこまで検証するか(例外型・メッセージ方針)を固定すれば、実装に直結します。