{
  "schema_version": 1,
  "diagram_type": "architecture",
  "meta": {
    "title": "Shelf · Python 서버 아키텍처",
    "quality_profile": "showcase",
    "viewBox": [
      1250,
      680
    ]
  },
  "components": [
    {
      "id": "reader",
      "type": "frontend",
      "label": "모바일 리더",
      "sublabel": "탭 · 스크롤 · 읽기 위치",
      "pos": [
        40,
        300
      ],
      "size": [
        200,
        80
      ]
    },
    {
      "id": "web",
      "type": "backend",
      "label": "Flask · Waitress",
      "sublabel": "인증 · 페이지 API",
      "pos": [
        350,
        300
      ],
      "size": [
        200,
        80
      ]
    },
    {
      "id": "zip",
      "type": "backend",
      "label": "Python ZIP 캐시",
      "sublabel": "3개 ZIP · 10만 항목",
      "pos": [
        680,
        300
      ],
      "size": [
        200,
        80
      ]
    },
    {
      "id": "media",
      "type": "database",
      "label": "NAS 이미지 원본",
      "sublabel": "폴더 · ZIP / CBZ",
      "pos": [
        1010,
        300
      ],
      "size": [
        200,
        80
      ]
    },
    {
      "id": "state",
      "type": "database",
      "label": "SQLite",
      "sublabel": "색인 · 즐겨찾기 · 책갈피",
      "pos": [
        350,
        80
      ],
      "size": [
        200,
        80
      ]
    },
    {
      "id": "pillow",
      "type": "backend",
      "label": "Pillow",
      "sublabel": "썸네일 · 포맷 변환",
      "pos": [
        680,
        520
      ],
      "size": [
        200,
        80
      ]
    },
    {
      "id": "thumbs",
      "type": "database",
      "label": "썸네일 캐시",
      "sublabel": "디스크 256 MiB",
      "pos": [
        1010,
        520
      ],
      "size": [
        200,
        80
      ]
    }
  ],
  "connections": [
    {
      "id": "http",
      "from": "reader",
      "to": "web",
      "label": "HTTP",
      "variant": "emphasis"
    },
    {
      "id": "read",
      "from": "web",
      "to": "zip",
      "label": "페이지 읽기",
      "variant": "emphasis"
    },
    {
      "id": "zip-read",
      "from": "zip",
      "to": "media",
      "label": "파일 I/O",
      "variant": "emphasis"
    },
    {
      "id": "sql",
      "from": "web",
      "to": "state",
      "label": "SQL",
      "variant": "default"
    },
    {
      "id": "convert",
      "from": "zip",
      "to": "pillow",
      "label": "첫 이미지",
      "variant": "default",
      "labelDy": 24
    },
    {
      "id": "thumb-save",
      "from": "pillow",
      "to": "thumbs",
      "label": "WebP 저장",
      "variant": "default"
    }
  ],
  "cards": [
    {
      "dot": "cyan",
      "title": "사용자 경험",
      "items": [
        "폴더별 책 · 첫 이미지 표지",
        "가로/세로 맞춤 · 다음 권 연속 읽기"
      ]
    },
    {
      "dot": "emerald",
      "title": "책임 분리",
      "items": [
        "Flask: 인증과 읽기 상태",
        "ZIP: 필요한 이미지 한 장만 읽기"
      ]
    },
    {
      "dot": "amber",
      "title": "운영 경계",
      "items": [
        "원본은 수정하지 않음",
        "기존 서버를 Blue로 보존"
      ]
    }
  ]
}