{
  "id": "viewer-public-demo",
  "name": "Simple Blog System",
  "description": "複数ユーザーが記事を書いて公開できるブログシステム",
  "sourceRequirement": "複数ユーザーが記事を書いて公開できるブログシステム",
  "version": 1,
  "actors": [
    {
      "id": "visitor",
      "name": "匿名訪問者",
      "description": "ログインしていない読者",
      "levels": ["anonymous"]
    },
    {
      "id": "reader",
      "name": "ログイン読者",
      "description": "アカウントを持つ読者",
      "levels": ["authenticated"]
    },
    {
      "id": "author",
      "name": "記事執筆者",
      "description": "記事を書いて公開できるユーザー",
      "levels": ["authenticated", "author"]
    },
    {
      "id": "admin",
      "name": "管理者",
      "description": "システム全体を管理",
      "levels": ["authenticated", "author", "owner", "admin"]
    }
  ],
  "entities": [
    {
      "id": "user",
      "name": "User",
      "description": "アカウント",
      "attributes": [
        { "name": "name", "type": "string", "required": true },
        { "name": "email", "type": "string", "required": true },
        { "name": "passwordHash", "type": "string", "required": true, "description": "平文パスワードは保持しない" }
      ]
    },
    {
      "id": "article",
      "name": "Article",
      "description": "記事。下書きから公開までのライフサイクルを持つ",
      "attributes": [
        { "name": "title", "type": "string", "required": true },
        { "name": "body", "type": "text", "required": true },
        { "name": "authorUserId", "type": "user.id", "required": true },
        { "name": "publishedAt", "type": "datetime" }
      ],
      "stateMachineId": "sm-article"
    },
    {
      "id": "comment",
      "name": "Comment",
      "description": "記事へのコメント",
      "attributes": [
        { "name": "body", "type": "text", "required": true },
        { "name": "articleId", "type": "article.id", "required": true }
      ]
    }
  ],
  "stateMachines": [
    {
      "id": "sm-article",
      "entityId": "article",
      "initial": "draft",
      "states": [
        { "name": "draft", "description": "下書き。読者からは見えない" },
        { "name": "published", "description": "公開済み。読者から閲覧可能" }
      ],
      "transitions": [
        { "id": "t-create", "name": "create", "from": "(new)", "to": "draft", "actorId": "author", "description": "author が新規記事を作成" },
        { "id": "t-publish", "name": "publish", "from": "draft", "to": "published", "actorId": "author", "description": "下書きを公開" },
        { "id": "t-unpublish", "name": "unpublish", "from": "published", "to": "draft", "actorId": "author", "description": "公開を取りやめて下書きへ戻す" }
      ]
    }
  ],
  "flows": [
    {
      "id": "f-author-publish",
      "name": "author creates and publishes article",
      "description": "執筆者が記事を作成し、編集して公開する",
      "actorId": "author",
      "primaryEntityId": "article",
      "preconditions": [],
      "steps": [
        { "kind": "transition", "name": "create article", "transitionId": "t-create" },
        { "kind": "action", "name": "edit draft", "actorId": "author", "action": "update", "description": "下書きを編集する" },
        { "kind": "transition", "name": "publish", "transitionId": "t-publish" },
        { "kind": "check", "name": "published article is visible to reader", "ruleIds": ["r-visible"] }
      ]
    },
    {
      "id": "f-reader-reads",
      "name": "reader views article",
      "description": "読者が公開済み記事を読む。権限はDecision d1で決まる",
      "actorId": "visitor",
      "primaryEntityId": "article",
      "preconditions": [{ "entity": "article", "state": "published" }],
      "steps": [
        { "kind": "action", "name": "read article", "actorId": "visitor", "action": "read" },
        { "kind": "check", "name": "article is published", "ruleIds": ["r-visible"] }
      ]
    }
  ],
  "rules": [
    {
      "id": "perm-article-create",
      "kind": "permission",
      "statement": "article.create はauthor以上に許可",
      "subject": "article",
      "action": "create",
      "requiredLevel": "author"
    },
    {
      "id": "perm-article-publish",
      "kind": "permission",
      "statement": "article.publish はauthor以上に許可",
      "subject": "article",
      "action": "publish",
      "requiredLevel": "author"
    },
    {
      "id": "r-visible",
      "kind": "invariant",
      "statement": "公開済み記事のみ読者に見える（draftは不可）",
      "exprs": [{ "type": "state_is", "entity": "article", "state": "published" }]
    }
  ],
  "decisions": [
    {
      "id": "d1",
      "question": "このシステムは匿名閲覧を許可しますか？（記事を読むのにログインが必要？）",
      "status": "open",
      "recommendation": "yes",
      "reason": "公開ブログとして定義されているため、記事の匿名閲覧が標準",
      "impactIfNo": "全ページの閲覧にログインが必要になり、公開性・検索流入が下がる",
      "effect": { "type": "set_permission", "subject": "article", "action": "read", "ifYes": "anonymous", "ifNo": "authenticated" }
    },
    {
      "id": "d2",
      "question": "コメント投稿はログイン必須にしますか？",
      "status": "open",
      "recommendation": "yes",
      "reason": "匿名コメントはスパム・荒らしの典型リスク",
      "impactIfNo": "スパム対策（CAPTCHA等）を別途実装する必要がある",
      "effect": { "type": "set_permission", "subject": "comment", "action": "create", "ifYes": "authenticated", "ifNo": "anonymous" }
    },
    {
      "id": "d3",
      "question": "Userデータの所有者は各ユーザー自身（本人）でよいですか？",
      "status": "open",
      "recommendation": "yes",
      "reason": "アカウント情報は通常そのユーザー本人の所有データ",
      "impactIfNo": "管理者所有となるため、本人による自己情報の管理・削除権が弱まる",
      "effect": { "type": "set_owner", "entityId": "user", "actorId": "reader" }
    }
  ]
}
