{
 "openapi": "3.1.0",
 "info": {
  "title": "투표함 Open API — 법령별 전자투표 요건",
  "version": "2026-10-29",
  "description": "총회·선거 전자투표에 적용되는 한국 법령 조문, 안건 유형별 의결정족수와 전자투표 근거, 정족수 판정 계산. 인용 조건: CC BY 4.0(출처 표기). 법령 원문은 공공저작물.",
  "contact": {
   "name": "투표함 · 케이코인(KCOIN)",
   "url": "https://vote.easykmarket.com/developers",
   "email": "wmask@naver.com"
  },
  "license": {
   "name": "CC BY 4.0",
   "url": "https://creativecommons.org/licenses/by/4.0/deed.ko"
  }
 },
 "servers": [
  {
   "url": "https://vote.easykmarket.com"
  }
 ],
 "paths": {
  "/open/index.json": {
   "get": {
    "summary": "자료 목록·라이선스·인용 형식",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/open/laws.json": {
   "get": {
    "summary": "추적 법령 목록 (시행일·공포일·수집일·예정 개정)",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/LawSummary"
         }
        }
       }
      }
     }
    }
   }
  },
  "/open/laws/{slug}.json": {
   "get": {
    "summary": "법령 하나의 추적 조문 원문·개정 꼬리표·투표함 적용 내용",
    "parameters": [
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "example": "condominium"
     }
    ],
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Law"
        }
       }
      }
     }
    }
   }
  },
  "/open/resolution-types.json": {
   "get": {
    "summary": "안건 유형별 의결정족수·근거 조문·전자투표 근거·소집통지·본인확인 등급",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ResolutionType"
         }
        }
       }
      }
     }
    }
   }
  },
  "/open/obligations.json": {
   "get": {
    "summary": "조문 전수 대장 — 문장마다 투표함의 대응(done/organizer/context/gap)",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Obligation"
         }
        }
       }
      }
     }
    }
   }
  },
  "/open/changelog.json": {
   "get": {
    "summary": "법령 갱신 이력 — 시행일·공포일·대조일·예정 개정",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/open/resolution-types": {
   "get": {
    "summary": "안건 유형 목록 (서버 엔진에서 직접)",
    "responses": {
     "200": {
      "description": "OK",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     }
    }
   }
  },
  "/api/open/resolution-types/{key}": {
   "get": {
    "summary": "안건 유형 하나",
    "parameters": [
     {
      "name": "key",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "example": "bldg_general"
     }
    ],
    "responses": {
     "200": {
      "description": "OK"
     },
     "404": {
      "description": "없는 유형"
     }
    }
   }
  },
  "/api/open/judge": {
   "post": {
    "summary": "정족수 판정 — 투표함이 개표에 쓰는 엔진 그대로",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/JudgeRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "판정",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Judgment"
        }
       }
      }
     },
     "400": {
      "description": "입력 오류"
     }
    }
   }
  },
  "/api/mcp": {
   "post": {
    "summary": "MCP(Model Context Protocol) Streamable HTTP 엔드포인트 — JSON-RPC 2.0 (initialize, tools/list, tools/call)",
    "responses": {
     "200": {
      "description": "JSON-RPC 응답"
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "LawSummary": {
    "type": "object",
    "properties": {
     "law": {
      "type": "string"
     },
     "slug": {
      "type": "string"
     },
     "effectiveDate": {
      "type": "string",
      "format": "date"
     },
     "promulgatedDate": {
      "type": "string",
      "format": "date"
     },
     "fetchedAt": {
      "type": "string",
      "format": "date"
     },
     "articles": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "upcoming": {
      "type": [
       "object",
       "null"
      ]
     },
     "url": {
      "type": "string"
     }
    }
   },
   "Law": {
    "type": "object",
    "properties": {
     "law": {
      "type": "string"
     },
     "effectiveDate": {
      "type": "string"
     },
     "articles": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "article": {
         "type": "string"
        },
        "title": {
         "type": "string"
        },
        "text": {
         "type": "string"
        },
        "paragraphs": {
         "type": "array"
        },
        "amendments": {
         "type": "array"
        },
        "applied": {
         "type": "array"
        },
        "resolutionTypes": {
         "type": "array"
        }
       }
      }
     }
    }
   },
   "ResolutionType": {
    "type": "object",
    "properties": {
     "key": {
      "type": "string"
     },
     "label": {
      "type": "string"
     },
     "summary": {
      "type": "string"
     },
     "basisLaw": {
      "type": "string"
     },
     "effective": {
      "type": [
       "string",
       "null"
      ]
     },
     "conditions": {
      "type": "array"
     },
     "electronic": {
      "type": "object"
     },
     "notice": {
      "type": "object"
     },
     "auth": {
      "type": "string"
     },
     "url": {
      "type": "string"
     }
    }
   },
   "Obligation": {
    "type": "object",
    "properties": {
     "key": {
      "type": "string"
     },
     "law": {
      "type": "string"
     },
     "article": {
      "type": "string"
     },
     "quote": {
      "type": "string"
     },
     "gist": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "enum": [
       "done",
       "organizer",
       "context",
       "gap"
      ]
     },
     "how": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "JudgeRequest": {
    "type": "object",
    "required": [
     "preset"
    ],
    "properties": {
     "preset": {
      "type": "string",
      "description": "안건 유형 키 (resolution-types 의 key)",
      "example": "bldg_general"
     },
     "eligibleCount": {
      "type": "integer",
      "description": "재적 인원"
     },
     "attendeeCount": {
      "type": "integer",
      "description": "출석(투표) 인원"
     },
     "approveCount": {
      "type": "integer",
      "description": "찬성 인원"
     },
     "eligibleWeight": {
      "type": "number",
      "description": "재적 의결권 합(면적·지분)"
     },
     "castWeight": {
      "type": "number"
     },
     "approveWeight": {
      "type": "number"
     },
     "directAttendanceCount": {
      "type": [
       "integer",
       "null"
      ],
      "description": "직접 출석 인원 (정비사업)"
     }
    },
    "example": {
     "preset": "bldg_general",
     "eligibleCount": 400,
     "attendeeCount": 380,
     "approveCount": 323,
     "eligibleWeight": 32431.2,
     "castWeight": 30800.5,
     "approveWeight": 24279.3
    }
   },
   "Judgment": {
    "type": "object",
    "properties": {
     "outcome": {
      "type": "string",
      "enum": [
       "passed",
       "rejected",
       "pending",
       "runoff"
      ]
     },
     "headline": {
      "type": "string"
     },
     "conditions": {
      "type": "array"
     },
     "basisLaw": {
      "type": "string"
     }
    }
   }
  }
 }
}