{
 "openapi": "3.1.0",
 "info": {
  "title": "다운 KITE API",
  "version": "1.0.0",
  "description": "다운 KITE 농장 데이터 REST API (앱·농장 PC 용). MCP(`/mcp`) 와 같은 권한·검증·감사 기록을 쓴다.\n\n- 인증: `Authorization: Bearer dwm_...` 또는 `X-API-Key: dwm_...` — 키는 관리자에게 발급받는다.\n- 응답: 성공 `{ \"data\": ... }`, 실패 `{ \"error\": { \"status\": n, \"message\": \"...\" } }`.\n- 제한: 키당 분당 120회(키마다 다를 수 있음), 동시 2건. 넘으면 429.\n- 변경은 업무 API(목장·사용자·개체·환경)로만 한다. 삭제는 flagYN='N' 표시이며 PATCH 에 active=true 로 되돌린다."
 },
 "servers": [
  {
   "url": "https://mcp.dawoon.link/api/v1"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  },
  {
   "apiKeyHeader": []
  }
 ],
 "tags": [
  {
   "name": "목장",
   "description": "목장(거래처) 조회·등록·수정·사용 중지"
  },
  {
   "name": "사용자",
   "description": "로그인 사용자 조회·등록·수정·정지"
  },
  {
   "name": "개체",
   "description": "가축 개체 조회·수정 (신규 등록은 농장 PC 동기화)"
  },
  {
   "name": "환경",
   "description": "농장 환경 측정값 — 농장 PC 가 기록"
  },
  {
   "name": "조회",
   "description": "범용 조회와 사용 안내"
  }
 ],
 "paths": {
  "/farms": {
   "get": {
    "tags": [
     "목장"
    ],
    "summary": "목장 목록·검색",
    "operationId": "get_farms",
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "required": false,
      "description": "목장명 일부 또는 목장 코드(숫자)",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "flagYN",
      "in": "query",
      "required": false,
      "description": "Y=사용 중, N=삭제(중지) 표시. 생략하면 전체",
      "schema": {
       "type": "string",
       "pattern": "^[YN]$"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "최대 행 수 (1~1000, 기본 100)",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "offset",
      "in": "query",
      "required": false,
      "description": "건너뛸 행 수 (기본 0)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "post": {
    "tags": [
     "목장"
    ],
    "summary": "목장 등록 → 새 compCd",
    "operationId": "post_farms",
    "parameters": [],
    "responses": {
     "201": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "compNm": {
          "type": "string",
          "minLength": 1,
          "description": "목장명 (필수)"
         },
         "part": {
          "default": "00300",
          "description": "구분 코드: 00300 농장(기본) · 00100 사료회사 · 00200 사료 대리점 · 00400 TMR · 00900 기타 · 00500 API 연결사",
          "type": "string"
         },
         "owner": {
          "description": "대표자 (최대 한글 5자)",
          "type": "string"
         },
         "phone": {
          "description": "전화",
          "type": "string"
         },
         "fax": {
          "description": "팩스",
          "type": "string"
         },
         "major": {
          "description": "담당자 (최대 한글 5자)",
          "type": "string"
         },
         "majorPhone": {
          "description": "담당자 연락처",
          "type": "string"
         },
         "address": {
          "description": "주소",
          "type": "string"
         },
         "compNo": {
          "description": "사업자등록번호",
          "type": "string"
         },
         "memo": {
          "description": "메모",
          "type": "string"
         },
         "testTerms": {
          "description": "체험(사용) 기한 YYYY-MM-DD — 등록 시 생략하면 오늘+14일",
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
         },
         "apiKey": {
          "description": "API 연결사(part=00500) 키 — 00500 인데 비우면 자동 생성",
          "type": "string"
         },
         "allowDuplicateName": {
          "default": false,
          "type": "boolean"
         }
        },
        "required": [
         "compNm"
        ]
       },
       "example": {
        "compNm": "행복목장",
        "part": "00300",
        "owner": "홍길동",
        "phone": "010-xxxx-xxxx"
       }
      }
     }
    }
   }
  },
  "/farms/{compCd}": {
   "get": {
    "tags": [
     "목장"
    ],
    "summary": "목장 1건",
    "operationId": "get_farms_compCd",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "patch": {
    "tags": [
     "목장"
    ],
    "summary": "목장 수정 (준 항목만)",
    "operationId": "patch_farms_compCd",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "compNm": {
          "type": "string",
          "minLength": 1
         },
         "part": {
          "type": "string"
         },
         "owner": {
          "description": "대표자 (최대 한글 5자)",
          "type": "string"
         },
         "phone": {
          "description": "전화",
          "type": "string"
         },
         "fax": {
          "description": "팩스",
          "type": "string"
         },
         "major": {
          "description": "담당자 (최대 한글 5자)",
          "type": "string"
         },
         "majorPhone": {
          "description": "담당자 연락처",
          "type": "string"
         },
         "address": {
          "description": "주소",
          "type": "string"
         },
         "compNo": {
          "description": "사업자등록번호",
          "type": "string"
         },
         "memo": {
          "description": "메모",
          "type": "string"
         },
         "testTerms": {
          "description": "체험(사용) 기한 YYYY-MM-DD — 등록 시 생략하면 오늘+14일",
          "type": "string",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
         },
         "apiKey": {
          "description": "API 연결사(part=00500) 키 — 00500 인데 비우면 자동 생성",
          "type": "string"
         },
         "active": {
          "description": "true 면 사용 재개(flagYN='Y'), false 면 사용 중지",
          "type": "boolean"
         }
        }
       },
       "example": {
        "memo": "담당자 변경",
        "majorPhone": "010-xxxx-xxxx"
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "목장"
    ],
    "summary": "목장 사용 중지 (flagYN='N')",
    "operationId": "delete_farms_compCd",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/users": {
   "get": {
    "tags": [
     "사용자"
    ],
    "summary": "사용자 목록",
    "operationId": "get_users",
    "parameters": [
     {
      "name": "compCd",
      "in": "query",
      "required": false,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "q",
      "in": "query",
      "required": false,
      "description": "이름 일부",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "flagYN",
      "in": "query",
      "required": false,
      "description": "Y=사용 중, N=삭제(중지) 표시. 생략하면 전체",
      "schema": {
       "type": "string",
       "pattern": "^[YN]$"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "최대 행 수 (1~1000, 기본 100)",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "offset",
      "in": "query",
      "required": false,
      "description": "건너뛸 행 수 (기본 0)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "post": {
    "tags": [
     "사용자"
    ],
    "summary": "사용자 등록",
    "operationId": "post_users",
    "parameters": [],
    "responses": {
     "201": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "userID": {
          "type": "string",
          "description": "아이디 (영문·숫자·._@- 2~20자)"
         },
         "compCd": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991,
          "description": "소속 목장 compCd (사용 중이어야 함)"
         },
         "password": {
          "type": "string",
          "description": "비밀번호 평문 4~50자 — 서버에서 암호화 저장"
         },
         "userNm": {
          "type": "string",
          "minLength": 1,
          "description": "이름 (필수, 최대 한글 10자)"
         },
         "phone": {
          "description": "전화 (예: 010-xxxx-xxxx)",
          "type": "string"
         },
         "email": {
          "type": "string"
         },
         "level": {
          "description": "등급: 00100 일반(기본) · 00050 열람전용 · 00900 관리자",
          "type": "string"
         },
         "perms": {
          "description": "웹 메뉴 권한 코드 목록 (예: [\"A07\",\"A01\"]). 생략 시 사이트 기본 권한",
          "anyOf": [
           {
            "type": "array",
            "items": {
             "type": "string"
            }
           },
           {
            "type": "string"
           }
          ]
         },
         "mPerms": {
          "description": "모바일 메뉴 권한 코드 목록. 생략 시 사이트 기본 권한",
          "anyOf": [
           {
            "type": "array",
            "items": {
             "type": "string"
            }
           },
           {
            "type": "string"
           }
          ]
         },
         "startPage": {
          "description": "로그인 후 첫 화면 pageUrl (예: dash.html). 그 메뉴가 perms 에 있어야 함",
          "type": "string"
         },
         "phoneGroup": {
          "type": "string"
         },
         "phoneCd": {
          "description": "휴대폰(푸시) 코드",
          "type": "string"
         },
         "smsYN": {
          "description": "문자 수신 여부 (기본 Y)",
          "type": "string",
          "enum": [
           "Y",
           "N"
          ]
         }
        },
        "required": [
         "userID",
         "compCd",
         "password",
         "userNm"
        ]
       },
       "example": {
        "userID": "farm3321_kim",
        "compCd": 3321,
        "password": "<4~50자 평문>",
        "userNm": "김농부",
        "phone": "010-xxxx-xxxx"
       }
      }
     }
    }
   }
  },
  "/users/{userID}": {
   "get": {
    "tags": [
     "사용자"
    ],
    "summary": "사용자 1명",
    "operationId": "get_users_userID",
    "parameters": [
     {
      "name": "userID",
      "in": "path",
      "required": true,
      "description": "사용자 아이디",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "patch": {
    "tags": [
     "사용자"
    ],
    "summary": "사용자 수정 (비밀번호 생략 시 유지)",
    "operationId": "patch_users_userID",
    "parameters": [
     {
      "name": "userID",
      "in": "path",
      "required": true,
      "description": "사용자 아이디",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "compCd": {
          "description": "소속 목장 변경",
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991
         },
         "password": {
          "description": "새 비밀번호 (생략하면 유지)",
          "type": "string"
         },
         "userNm": {
          "description": "이름 (최대 한글 10자)",
          "type": "string",
          "minLength": 1
         },
         "phone": {
          "description": "전화 (예: 010-xxxx-xxxx)",
          "type": "string"
         },
         "email": {
          "type": "string"
         },
         "level": {
          "description": "등급: 00100 일반(기본) · 00050 열람전용 · 00900 관리자",
          "type": "string"
         },
         "perms": {
          "description": "웹 메뉴 권한 코드 목록 (예: [\"A07\",\"A01\"]). 생략 시 사이트 기본 권한",
          "anyOf": [
           {
            "type": "array",
            "items": {
             "type": "string"
            }
           },
           {
            "type": "string"
           }
          ]
         },
         "mPerms": {
          "description": "모바일 메뉴 권한 코드 목록. 생략 시 사이트 기본 권한",
          "anyOf": [
           {
            "type": "array",
            "items": {
             "type": "string"
            }
           },
           {
            "type": "string"
           }
          ]
         },
         "startPage": {
          "description": "로그인 후 첫 화면 pageUrl (예: dash.html). 그 메뉴가 perms 에 있어야 함",
          "type": "string"
         },
         "phoneGroup": {
          "type": "string"
         },
         "phoneCd": {
          "description": "휴대폰(푸시) 코드",
          "type": "string"
         },
         "smsYN": {
          "description": "문자 수신 여부 (기본 Y)",
          "type": "string",
          "enum": [
           "Y",
           "N"
          ]
         },
         "active": {
          "description": "true 면 사용 재개, false 면 정지",
          "type": "boolean"
         }
        }
       },
       "example": {
        "email": "farmer@example.com",
        "smsYN": "N"
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "사용자"
    ],
    "summary": "사용자 정지 (flagYN='N')",
    "operationId": "delete_users_userID",
    "parameters": [
     {
      "name": "userID",
      "in": "path",
      "required": true,
      "description": "사용자 아이디",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/farms/{compCd}/animals": {
   "get": {
    "tags": [
     "개체"
    ],
    "summary": "목장의 개체 목록",
    "operationId": "get_farms_compCd_animals",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     },
     {
      "name": "flagYN",
      "in": "query",
      "required": false,
      "description": "Y=사용 중, N=삭제(중지) 표시. 생략하면 전체",
      "schema": {
       "type": "string",
       "pattern": "^[YN]$"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "최대 행 수 (1~1000, 기본 100)",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "offset",
      "in": "query",
      "required": false,
      "description": "건너뛸 행 수 (기본 0)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/farms/{compCd}/animals/{aniSeq}": {
   "get": {
    "tags": [
     "개체"
    ],
    "summary": "개체 1마리",
    "operationId": "get_farms_compCd_animals_aniSeq",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     },
     {
      "name": "aniSeq",
      "in": "path",
      "required": true,
      "description": "개체 번호 (목장 안에서 고유)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "patch": {
    "tags": [
     "개체"
    ],
    "summary": "개체 수정 (준 항목만)",
    "operationId": "patch_farms_compCd_animals_aniSeq",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     },
     {
      "name": "aniSeq",
      "in": "path",
      "required": true,
      "description": "개체 번호 (목장 안에서 고유)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "changes": {
          "type": "object",
          "propertyNames": {
           "type": "string"
          },
          "additionalProperties": {
           "type": [
            "string",
            "number",
            "boolean",
            "null"
           ]
          },
          "description": "바꿀 컬럼명: 값"
         },
         "active": {
          "description": "true 면 사용, false 면 삭제 표시",
          "type": "boolean"
         }
        },
        "required": [
         "changes"
        ]
       },
       "example": {
        "changes": {
         "aniNick": "누렁이",
         "aniMemo": "건강 양호"
        }
       }
      }
     }
    }
   },
   "delete": {
    "tags": [
     "개체"
    ],
    "summary": "개체 삭제 표시",
    "operationId": "delete_farms_compCd_animals_aniSeq",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     },
     {
      "name": "aniSeq",
      "in": "path",
      "required": true,
      "description": "개체 번호 (목장 안에서 고유)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/farms/{compCd}/env": {
   "get": {
    "tags": [
     "환경"
    ],
    "summary": "환경 측정값 조회 (기간 최대 31일)",
    "operationId": "get_farms_compCd_env",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     },
     {
      "name": "from",
      "in": "query",
      "required": true,
      "description": "시작일 YYYY-MM-DD (필수)",
      "schema": {
       "type": "string",
       "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
      }
     },
     {
      "name": "to",
      "in": "query",
      "required": true,
      "description": "종료일 YYYY-MM-DD (필수)",
      "schema": {
       "type": "string",
       "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
      }
     },
     {
      "name": "envCd",
      "in": "query",
      "required": false,
      "description": "환경 요소 코드 (예: T 온도, H 습도)",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "envPosit",
      "in": "query",
      "required": false,
      "description": "측정 장소 코드",
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "limit",
      "in": "query",
      "required": false,
      "description": "최대 행 수 (1~1000, 기본 100)",
      "schema": {
       "type": "integer"
      }
     },
     {
      "name": "offset",
      "in": "query",
      "required": false,
      "description": "건너뛸 행 수 (기본 0)",
      "schema": {
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   },
   "post": {
    "tags": [
     "환경"
    ],
    "summary": "환경 측정값 기록 (1건 또는 records 최대 50건)",
    "operationId": "post_farms_compCd_env",
    "description": "기록 시각은 서버 현재 시각(시 단위)입니다. 같은 시간대에 다시 보내면 덮어씁니다. 일부가 실패하면 400 과 함께 건별 결과를 돌려줍니다(성공한 건은 이미 기록됨).",
    "parameters": [
     {
      "name": "compCd",
      "in": "path",
      "required": true,
      "description": "목장 코드",
      "schema": {
       "type": "integer"
      },
      "example": 3321
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "oneOf": [
         {
          "type": "object",
          "properties": {
           "envPosit": {
            "type": "string",
            "minLength": 1,
            "maxLength": 5,
            "description": "측정 장소 코드 (예: 1)"
           },
           "envCd": {
            "type": "string",
            "minLength": 1,
            "maxLength": 5,
            "description": "환경 요소 코드 (예: T 온도, H 습도)"
           },
           "envVal": {
            "description": "측정값 (최대 10자)",
            "type": [
             "string",
             "number"
            ]
           },
           "groupCd": {
            "default": "C003",
            "type": "string",
            "maxLength": 4
           }
          },
          "required": [
           "envPosit",
           "envCd",
           "envVal"
          ]
         },
         {
          "type": "object",
          "required": [
           "records"
          ],
          "properties": {
           "records": {
            "type": "array",
            "maxItems": 50,
            "items": {
             "type": "object",
             "properties": {
              "envPosit": {
               "type": "string",
               "minLength": 1,
               "maxLength": 5,
               "description": "측정 장소 코드 (예: 1)"
              },
              "envCd": {
               "type": "string",
               "minLength": 1,
               "maxLength": 5,
               "description": "환경 요소 코드 (예: T 온도, H 습도)"
              },
              "envVal": {
               "description": "측정값 (최대 10자)",
               "type": [
                "string",
                "number"
               ]
              },
              "groupCd": {
               "default": "C003",
               "type": "string",
               "maxLength": 4
              }
             },
             "required": [
              "envPosit",
              "envCd",
              "envVal"
             ]
            }
           }
          }
         }
        ]
       },
       "example": {
        "records": [
         {
          "envPosit": "1",
          "envCd": "T",
          "envVal": "23.5"
         },
         {
          "envPosit": "1",
          "envCd": "H",
          "envVal": "61"
         }
        ]
       }
      }
     }
    }
   }
  },
  "/tables": {
   "get": {
    "tags": [
     "조회"
    ],
    "summary": "조회 가능한 테이블 목록",
    "operationId": "get_tables",
    "parameters": [
     {
      "name": "search",
      "in": "query",
      "required": false,
      "description": "이름 일부",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/tables/{table}": {
   "get": {
    "tags": [
     "조회"
    ],
    "summary": "테이블 구조",
    "operationId": "get_tables_table",
    "parameters": [
     {
      "name": "table",
      "in": "path",
      "required": true,
      "description": "테이블 이름",
      "schema": {
       "type": "string",
       "enum": [
        "tblCompany",
        "tblUser",
        "tblAnimals",
        "tblFarmEnv"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/tables/{table}/query": {
   "post": {
    "tags": [
     "조회"
    ],
    "summary": "조건 조회",
    "operationId": "post_tables_table_query",
    "parameters": [
     {
      "name": "table",
      "in": "path",
      "required": true,
      "description": "테이블 이름",
      "schema": {
       "type": "string",
       "enum": [
        "tblCompany",
        "tblUser",
        "tblAnimals",
        "tblFarmEnv"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "columns": {
          "description": "생략하면 전체 컬럼",
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "where": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "column": {
             "type": "string",
             "description": "컬럼명 (대소문자 무시)"
            },
            "op": {
             "default": "eq",
             "type": "string",
             "enum": [
              "eq",
              "ne",
              "lt",
              "lte",
              "gt",
              "gte",
              "like",
              "in",
              "between",
              "isnull",
              "notnull"
             ]
            },
            "value": {
             "description": "eq/ne/lt/lte/gt/gte/like 의 값",
             "type": [
              "string",
              "number",
              "boolean",
              "null"
             ]
            },
            "values": {
             "description": "in: 값 목록, between: [시작, 끝]",
             "type": "array",
             "items": {
              "type": [
               "string",
               "number"
              ]
             }
            }
           },
           "required": [
            "column"
           ]
          },
          "description": "AND 로 묶이는 조건 목록"
         },
         "orderBy": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "column": {
             "type": "string"
            },
            "desc": {
             "type": "boolean"
            }
           },
           "required": [
            "column"
           ]
          }
         },
         "limit": {
          "default": 100,
          "type": "integer",
          "minimum": 1,
          "maximum": 1000
         },
         "offset": {
          "default": 0,
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
         }
        }
       },
       "example": {
        "where": [
         {
          "column": "compCd",
          "op": "eq",
          "value": 3321
         }
        ],
        "limit": 20
       }
      }
     }
    }
   }
  },
  "/tables/{table}/count": {
   "post": {
    "tags": [
     "조회"
    ],
    "summary": "조건에 맞는 행 수",
    "operationId": "post_tables_table_count",
    "parameters": [
     {
      "name": "table",
      "in": "path",
      "required": true,
      "description": "테이블 이름",
      "schema": {
       "type": "string",
       "enum": [
        "tblCompany",
        "tblUser",
        "tblAnimals",
        "tblFarmEnv"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "where": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "column": {
             "type": "string",
             "description": "컬럼명 (대소문자 무시)"
            },
            "op": {
             "default": "eq",
             "type": "string",
             "enum": [
              "eq",
              "ne",
              "lt",
              "lte",
              "gt",
              "gte",
              "like",
              "in",
              "between",
              "isnull",
              "notnull"
             ]
            },
            "value": {
             "description": "eq/ne/lt/lte/gt/gte/like 의 값",
             "type": [
              "string",
              "number",
              "boolean",
              "null"
             ]
            },
            "values": {
             "description": "in: 값 목록, between: [시작, 끝]",
             "type": "array",
             "items": {
              "type": [
               "string",
               "number"
              ]
             }
            }
           },
           "required": [
            "column"
           ]
          },
          "description": "AND 로 묶이는 조건 목록"
         }
        }
       },
       "example": {
        "where": [
         {
          "column": "compCd",
          "op": "eq",
          "value": 3321
         }
        ]
       }
      }
     }
    }
   }
  },
  "/procedures": {
   "get": {
    "tags": [
     "조회"
    ],
    "summary": "프로시저 목록 (참고용)",
    "operationId": "get_procedures",
    "parameters": [
     {
      "name": "search",
      "in": "query",
      "required": false,
      "description": "이름 일부",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/procedures/{name}": {
   "get": {
    "tags": [
     "조회"
    ],
    "summary": "프로시저 용도·파라미터",
    "operationId": "get_procedures_name",
    "parameters": [
     {
      "name": "name",
      "in": "path",
      "required": true,
      "description": "프로시저 이름",
      "schema": {
       "type": "string",
       "enum": [
        "sp_Company",
        "sp_CompUser",
        "sp_User",
        "sp_Animals",
        "sp_AnimalsWeb",
        "sp_FarmEnv"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "성공",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Success"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/guide": {
   "get": {
    "tags": [
     "조회"
    ],
    "summary": "이 키로 쓸 수 있는 범위의 사용 안내 (markdown)",
    "operationId": "get_guide",
    "parameters": [],
    "responses": {
     "200": {
      "description": "마크다운 문서",
      "content": {
       "text/markdown": {
        "schema": {
         "type": "string"
        }
       }
      }
     },
     "400": {
      "description": "입력값 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "API 키 없음·잘못됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "이 키로는 쓸 수 없는 기능·농장",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "대상 없음",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "중복·이미 처리됨",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "요청 제한 초과",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "500": {
      "description": "서버 오류",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "description": "dwm_<8자>_<40자> 형식의 API 키"
   },
   "apiKeyHeader": {
    "type": "apiKey",
    "in": "header",
    "name": "X-API-Key"
   }
  },
  "schemas": {
   "Success": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "description": "결과 (경로마다 다름)"
     }
    }
   },
   "Error": {
    "type": "object",
    "required": [
     "error"
    ],
    "properties": {
     "error": {
      "type": "object",
      "required": [
       "status",
       "message"
      ],
      "properties": {
       "status": {
        "type": "integer"
       },
       "message": {
        "type": "string"
       },
       "details": {}
      }
     }
    }
   }
  }
 }
}