@things-factory/integration-data-go-kr 10.0.0-beta.62 → 10.0.0-beta.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -16
- package/ROADMAP.md +25 -14
- package/dist-server/engine/connector/data-go-kr-client.d.ts +1 -1
- package/dist-server/engine/connector/data-go-kr-client.js +25 -2
- package/dist-server/engine/connector/data-go-kr-client.js.map +1 -1
- package/dist-server/engine/connector/data-go-kr-connector.d.ts +5 -11
- package/dist-server/engine/connector/data-go-kr-connector.js +3 -9
- package/dist-server/engine/connector/data-go-kr-connector.js.map +1 -1
- package/dist-server/engine/spec/building-ledger/hub.d.ts +12 -0
- package/dist-server/engine/spec/{building-ledger.js → building-ledger/hub.js} +13 -10
- package/dist-server/engine/spec/building-ledger/hub.js.map +1 -0
- package/dist-server/engine/spec/building-ledger/index.d.ts +7 -0
- package/dist-server/engine/spec/building-ledger/index.js +12 -0
- package/dist-server/engine/spec/building-ledger/index.js.map +1 -0
- package/dist-server/engine/spec/index.d.ts +2 -1
- package/dist-server/engine/spec/index.js +22 -5
- package/dist-server/engine/spec/index.js.map +1 -1
- package/dist-server/engine/spec/types.d.ts +3 -3
- package/dist-server/engine/spec/types.js +1 -1
- package/dist-server/engine/spec/types.js.map +1 -1
- package/dist-server/engine/spec/weather/asos.d.ts +2 -0
- package/dist-server/engine/spec/weather/asos.js +33 -0
- package/dist-server/engine/spec/weather/asos.js.map +1 -0
- package/dist-server/engine/spec/weather/aws.d.ts +2 -0
- package/dist-server/engine/spec/weather/aws.js +28 -0
- package/dist-server/engine/spec/weather/aws.js.map +1 -0
- package/dist-server/engine/spec/weather/index.d.ts +14 -0
- package/dist-server/engine/spec/weather/index.js +23 -0
- package/dist-server/engine/spec/weather/index.js.map +1 -0
- package/dist-server/engine/spec/weather/mid-term-forecast.d.ts +2 -0
- package/dist-server/engine/spec/weather/mid-term-forecast.js +56 -0
- package/dist-server/engine/spec/weather/mid-term-forecast.js.map +1 -0
- package/dist-server/engine/spec/weather/short-term-forecast.d.ts +2 -0
- package/dist-server/engine/spec/weather/short-term-forecast.js +71 -0
- package/dist-server/engine/spec/weather/short-term-forecast.js.map +1 -0
- package/dist-server/engine/spec/weather/warning.d.ts +2 -0
- package/dist-server/engine/spec/weather/warning.js +34 -0
- package/dist-server/engine/spec/weather/warning.js.map +1 -0
- package/dist-server/engine/task/building-ledger/general.js +1 -1
- package/dist-server/engine/task/building-ledger/general.js.map +1 -1
- package/dist-server/engine/task/call.d.ts +10 -3
- package/dist-server/engine/task/call.js +20 -4
- package/dist-server/engine/task/call.js.map +1 -1
- package/dist-server/engine/task/index.d.ts +1 -0
- package/dist-server/engine/task/index.js +1 -0
- package/dist-server/engine/task/index.js.map +1 -1
- package/dist-server/engine/task/weather/grid-converter.d.ts +24 -0
- package/dist-server/engine/task/weather/grid-converter.js +69 -0
- package/dist-server/engine/task/weather/grid-converter.js.map +1 -0
- package/dist-server/engine/task/weather/index.d.ts +13 -0
- package/dist-server/engine/task/weather/index.js +18 -0
- package/dist-server/engine/task/weather/index.js.map +1 -0
- package/dist-server/engine/task/weather/short-term-forecast.d.ts +38 -0
- package/dist-server/engine/task/weather/short-term-forecast.js +99 -0
- package/dist-server/engine/task/weather/short-term-forecast.js.map +1 -0
- package/dist-server/index.d.ts +2 -0
- package/dist-server/index.js +4 -1
- package/dist-server/index.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/helps/integration/connector/data-go-kr-connector.md +6 -7
- package/helps/integration/services/building-ledger.md +6 -5
- package/helps/integration/services/weather.md +82 -0
- package/helps/integration/task/building-ledger.md +25 -1
- package/helps/integration/task/data-go-kr-call.md +31 -4
- package/helps/integration/task/weather-short-term-forecast.md +96 -0
- package/logs/.5e5d741d8b7784a2fbad65eedc0fd46946aaf6f2-audit.json +15 -0
- package/logs/connections-2026-04-25-09.log +0 -0
- package/package.json +2 -2
- package/server/engine/connector/data-go-kr-client.ts +26 -2
- package/server/engine/connector/data-go-kr-connector.ts +8 -11
- package/server/engine/spec/{building-ledger.ts → building-ledger/hub.ts} +12 -9
- package/server/engine/spec/building-ledger/index.ts +7 -0
- package/server/engine/spec/index.ts +24 -3
- package/server/engine/spec/types.ts +3 -3
- package/server/engine/spec/weather/asos.ts +32 -0
- package/server/engine/spec/weather/aws.ts +27 -0
- package/server/engine/spec/weather/index.ts +14 -0
- package/server/engine/spec/weather/mid-term-forecast.ts +56 -0
- package/server/engine/spec/weather/short-term-forecast.ts +73 -0
- package/server/engine/spec/weather/warning.ts +33 -0
- package/server/engine/task/building-ledger/general.ts +2 -2
- package/server/engine/task/call.ts +24 -4
- package/server/engine/task/index.ts +1 -0
- package/server/engine/task/weather/grid-converter.ts +79 -0
- package/server/engine/task/weather/index.ts +14 -0
- package/server/engine/task/weather/short-term-forecast.ts +110 -0
- package/server/index.ts +2 -0
- package/translations/en.json +9 -2
- package/translations/ja.json +9 -2
- package/translations/ko.json +9 -2
- package/translations/ms.json +9 -2
- package/translations/zh.json +9 -2
- package/dist-server/engine/spec/building-ledger.d.ts +0 -9
- package/dist-server/engine/spec/building-ledger.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { OperationParamSpec, ServiceSpec } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 기상청_중기예보 조회서비스 (data.go.kr 데이터셋 15059468).
|
|
5
|
+
*
|
|
6
|
+
* 3~10일 전망. 광역 권역(regId) 단위로 06·18시 발표.
|
|
7
|
+
*/
|
|
8
|
+
const sharedParams: OperationParamSpec[] = [
|
|
9
|
+
{
|
|
10
|
+
name: 'regId',
|
|
11
|
+
required: true,
|
|
12
|
+
description:
|
|
13
|
+
'광역 권역 코드. 육상은 `11B00000`(서울/인천/경기) 등, 기온은 `11B10101`(서울) 등 더 세분화. KMA 권역 코드 표 참조.',
|
|
14
|
+
example: '11B00000'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'tmFc',
|
|
18
|
+
required: true,
|
|
19
|
+
length: 12,
|
|
20
|
+
description: '발표시각 YYYYMMDDHHMM. 중기예보는 06·18시 발표.',
|
|
21
|
+
example: '202604250600'
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
export const KmaMidTermForecastService: ServiceSpec = {
|
|
26
|
+
serviceId: '1360000/MidFcstInfoService',
|
|
27
|
+
label: '기상청_중기예보 조회서비스',
|
|
28
|
+
description: '3~10일 중기예보. 육상·기온·해상 별 오퍼레이션.',
|
|
29
|
+
homepage: 'https://www.data.go.kr/data/15059468/openapi.do',
|
|
30
|
+
operations: {
|
|
31
|
+
getMidFcst: {
|
|
32
|
+
operationId: 'getMidFcst',
|
|
33
|
+
label: '중기예보 종합',
|
|
34
|
+
description: '중기 전망 텍스트 (해석본).',
|
|
35
|
+
params: sharedParams
|
|
36
|
+
},
|
|
37
|
+
getMidLandFcst: {
|
|
38
|
+
operationId: 'getMidLandFcst',
|
|
39
|
+
label: '육상 중기예보',
|
|
40
|
+
description: '육상 권역의 강수확률·하늘상태 (3~10일).',
|
|
41
|
+
params: sharedParams
|
|
42
|
+
},
|
|
43
|
+
getMidTa: {
|
|
44
|
+
operationId: 'getMidTa',
|
|
45
|
+
label: '중기 기온예보',
|
|
46
|
+
description: '아침 최저·낮 최고 기온 (3~10일).',
|
|
47
|
+
params: sharedParams
|
|
48
|
+
},
|
|
49
|
+
getMidSeaFcst: {
|
|
50
|
+
operationId: 'getMidSeaFcst',
|
|
51
|
+
label: '해상 중기예보',
|
|
52
|
+
description: '해상 권역의 풍향·풍속·파고.',
|
|
53
|
+
params: sharedParams
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { OperationParamSpec, ServiceSpec } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 기상청_단기예보 조회서비스 v2 (data.go.kr 데이터셋 15084084).
|
|
5
|
+
*
|
|
6
|
+
* 동네예보 + 초단기예보 + 초단기실황. 모두 KMA 5km 격자좌표(nx, ny) 기준.
|
|
7
|
+
*/
|
|
8
|
+
const sharedParams: OperationParamSpec[] = [
|
|
9
|
+
{
|
|
10
|
+
name: 'base_date',
|
|
11
|
+
label: 'label.base-date',
|
|
12
|
+
required: true,
|
|
13
|
+
length: 8,
|
|
14
|
+
description: '발표일자 YYYYMMDD',
|
|
15
|
+
example: '20260425'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'base_time',
|
|
19
|
+
label: 'label.base-time',
|
|
20
|
+
required: true,
|
|
21
|
+
length: 4,
|
|
22
|
+
description:
|
|
23
|
+
'발표시각 HHMM. 단기예보는 0200·0500·0800·1100·1400·1700·2000·2300, 초단기 시리즈는 매시각 정시.',
|
|
24
|
+
example: '1100'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'nx',
|
|
28
|
+
label: 'label.nx',
|
|
29
|
+
required: true,
|
|
30
|
+
description: 'KMA 5km 격자 X좌표 (위경도 → 격자 변환은 task/weather/grid-converter 헬퍼).',
|
|
31
|
+
example: '60'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'ny',
|
|
35
|
+
label: 'label.ny',
|
|
36
|
+
required: true,
|
|
37
|
+
description: 'KMA 5km 격자 Y좌표.',
|
|
38
|
+
example: '127'
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
export const KmaShortTermForecastService: ServiceSpec = {
|
|
43
|
+
serviceId: '1360000/VilageFcstInfoService_2.0',
|
|
44
|
+
label: '기상청_단기예보 조회서비스',
|
|
45
|
+
description: '동네예보(3일치)·초단기예보(6시간)·초단기실황 3개 오퍼레이션. KMA 5km 격자좌표 기준.',
|
|
46
|
+
homepage: 'https://www.data.go.kr/data/15084084/openapi.do',
|
|
47
|
+
operations: {
|
|
48
|
+
getVilageFcst: {
|
|
49
|
+
operationId: 'getVilageFcst',
|
|
50
|
+
label: '단기예보 조회',
|
|
51
|
+
description:
|
|
52
|
+
'동네예보. 02·05·08·11·14·17·20·23시 (각 +10분 후 제공) 발표, 3일치 3시간 간격 카테고리 (POP·PCP·SKY·REH·T1H·UUU·VVV·VEC·WSD·TMN·TMX 등).',
|
|
53
|
+
params: sharedParams,
|
|
54
|
+
responseNotes:
|
|
55
|
+
'items.item 이 (카테고리×시점) 조합으로 매우 많이 반환됨 (3일치 약 800+건). numOfRows 를 충분히 크게 (1000+) 잡거나 페이징.',
|
|
56
|
+
externalDocsUrl: 'https://www.data.go.kr/data/15084084/openapi.do'
|
|
57
|
+
},
|
|
58
|
+
getUltraSrtFcst: {
|
|
59
|
+
operationId: 'getUltraSrtFcst',
|
|
60
|
+
label: '초단기예보 조회',
|
|
61
|
+
description: '발표시각 +45분 후 제공. 매시각 발표. 향후 6시간 예보 (1시간 단위).',
|
|
62
|
+
params: sharedParams,
|
|
63
|
+
externalDocsUrl: 'https://www.data.go.kr/data/15084084/openapi.do'
|
|
64
|
+
},
|
|
65
|
+
getUltraSrtNcst: {
|
|
66
|
+
operationId: 'getUltraSrtNcst',
|
|
67
|
+
label: '초단기실황 조회',
|
|
68
|
+
description: '발표시각 +10분 후 제공. 매시각 발표. 현재 관측값 (T1H·RN1·UUU·VVV·REH·PTY·VEC·WSD).',
|
|
69
|
+
params: sharedParams,
|
|
70
|
+
externalDocsUrl: 'https://www.data.go.kr/data/15084084/openapi.do'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { OperationParamSpec, ServiceSpec } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 기상청_기상특보 조회서비스 (data.go.kr 데이터셋 15059092).
|
|
5
|
+
*
|
|
6
|
+
* 호우·태풍·강풍·풍랑·대설 등 특보의 발효 현황 및 상세 내용.
|
|
7
|
+
*/
|
|
8
|
+
const sharedParams: OperationParamSpec[] = [
|
|
9
|
+
{ name: 'stnId', required: true, description: '발표 관할 지점 ID. 전국=108. KMA 지점 코드 표 참조.', example: '108' },
|
|
10
|
+
{ name: 'fromTmFc', required: true, length: 8, description: '검색시작일 YYYYMMDD', example: '20260425' },
|
|
11
|
+
{ name: 'toTmFc', required: true, length: 8, description: '검색종료일 YYYYMMDD', example: '20260425' }
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
export const KmaWeatherWarningService: ServiceSpec = {
|
|
15
|
+
serviceId: '1360000/WthrWrnInfoService',
|
|
16
|
+
label: '기상청_기상특보 조회서비스',
|
|
17
|
+
description: '기상특보(호우·태풍·강풍·풍랑·대설 등) 발효 현황 및 상세 내용 조회.',
|
|
18
|
+
homepage: 'https://www.data.go.kr/data/15059092/openapi.do',
|
|
19
|
+
operations: {
|
|
20
|
+
getWthrWrnList: {
|
|
21
|
+
operationId: 'getWthrWrnList',
|
|
22
|
+
label: '특보 목록 조회',
|
|
23
|
+
description: '발표 시각 범위 내의 특보 목록.',
|
|
24
|
+
params: sharedParams
|
|
25
|
+
},
|
|
26
|
+
getWthrWrnInfo: {
|
|
27
|
+
operationId: 'getWthrWrnInfo',
|
|
28
|
+
label: '특보 상세 조회',
|
|
29
|
+
description: '발효 중인 특정 특보의 상세 발표문.',
|
|
30
|
+
params: sharedParams
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConnectionManager, Context, TaskRegistry, evaluateTemplate } from '@things-factory/integration-base'
|
|
2
2
|
|
|
3
3
|
import { DataGoKrConnectionInstance } from '../../connector/data-go-kr-connector'
|
|
4
|
-
import {
|
|
4
|
+
import { BldRgstHubService } from '../../spec/building-ledger'
|
|
5
5
|
import { BrTitleItem, BuildingLedgerResult } from '../../types'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -48,7 +48,7 @@ async function BuildingLedgerTask(step, context: Context): Promise<{ data: Build
|
|
|
48
48
|
if (!bjdongCd) throw new Error('data-go-kr-building-ledger: bjdongCd is required')
|
|
49
49
|
if (!bun) throw new Error('data-go-kr-building-ledger: bun is required')
|
|
50
50
|
|
|
51
|
-
const servicePath = `${
|
|
51
|
+
const servicePath = `${BldRgstHubService.serviceId}/getBrTitleInfo`
|
|
52
52
|
|
|
53
53
|
const normalizedParams = {
|
|
54
54
|
sigunguCd,
|
|
@@ -11,7 +11,7 @@ import { OperationSpec, SpecRegistry } from '../spec'
|
|
|
11
11
|
* 수백 개 태스크로 폭발하는 것을 방지하는 핵심 설계.
|
|
12
12
|
*
|
|
13
13
|
* 입력:
|
|
14
|
-
* - `operationRef` : `"<serviceId>.<operationId>"` 형식 (예: `"1613000/
|
|
14
|
+
* - `operationRef` : `"<serviceId>.<operationId>"` 형식 (예: `"1613000/BldRgstHubService.getBrTitleInfo"`)
|
|
15
15
|
* - `params` : 오퍼레이션 파라미터 객체. 스펙 등록된 오퍼레이션이면 자동 검증·기본값·zero-pad 적용
|
|
16
16
|
*
|
|
17
17
|
* 레지스트리에 없는 오퍼레이션도 호출 가능 (스펙 없음 → 검증 스킵). 새 data.go.kr 서비스가
|
|
@@ -136,17 +136,37 @@ function normalizeAndValidateParams(operation: OperationSpec, input: Record<stri
|
|
|
136
136
|
return output
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* SpecRegistry 에 등록된 모든 오퍼레이션을 (operationRef → display) 옵션으로 펼친다.
|
|
141
|
+
* 모듈 로딩 시 한 번 평가되며, 이후 register() 로 추가된 spec 은 반영되지 않음
|
|
142
|
+
* (드문 케이스라 수용 — 향후 동적 parameterSpec 도입 시 해결).
|
|
143
|
+
*/
|
|
144
|
+
function buildOperationRefOptions(): Array<{ value: string; display: string }> {
|
|
145
|
+
return SpecRegistry.listServices()
|
|
146
|
+
.flatMap(svc =>
|
|
147
|
+
Object.values(svc.operations).map(op => ({
|
|
148
|
+
value: `${svc.serviceId}.${op.operationId}`,
|
|
149
|
+
display: `[${svc.label}] ${op.label}`
|
|
150
|
+
}))
|
|
151
|
+
)
|
|
152
|
+
.sort((a, b) => a.display.localeCompare(b.display, 'ko'))
|
|
153
|
+
}
|
|
154
|
+
|
|
139
155
|
DataGoKrCall.parameterSpec = [
|
|
140
156
|
{
|
|
141
|
-
type: '
|
|
157
|
+
type: 'select',
|
|
142
158
|
name: 'operationRef',
|
|
143
159
|
label: 'label.operation-ref',
|
|
144
|
-
|
|
160
|
+
property: {
|
|
161
|
+
options: buildOperationRefOptions()
|
|
162
|
+
}
|
|
145
163
|
},
|
|
146
164
|
{
|
|
147
165
|
type: 'scenario-step-input',
|
|
148
166
|
name: 'params',
|
|
149
|
-
label: 'label.operation-params'
|
|
167
|
+
label: 'label.operation-params',
|
|
168
|
+
placeholder:
|
|
169
|
+
'오퍼레이션 파라미터를 JSON 객체로. 예) 건축물대장: {"sigunguCd":"11680","bjdongCd":"10300","bun":"223"} · 단기예보: {"base_date":"20260425","base_time":"1100","nx":"60","ny":"127"}. 정확한 키는 helps/integration/services/<domain>.md 참고.'
|
|
150
170
|
}
|
|
151
171
|
]
|
|
152
172
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KMA(기상청) 5km 격자좌표 ↔ 위경도 변환.
|
|
3
|
+
*
|
|
4
|
+
* 동네예보·초단기 시리즈는 위경도가 아닌 KMA 자체 격자(nx, ny) 로 호출하므로,
|
|
5
|
+
* 일반적으로 알고 있는 위경도 좌표를 격자로 바꿔주는 헬퍼가 필요하다.
|
|
6
|
+
*
|
|
7
|
+
* 변환식 출처: 기상청 공식 동네예보 격자 변환 문서 (Lambert Conformal Conic).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const RE = 6371.00877 /* 지구 반경 (km) */
|
|
11
|
+
const GRID = 5.0 /* 격자 간격 (km) */
|
|
12
|
+
const SLAT1 = 30.0 /* 표준 위도 1 (degree) */
|
|
13
|
+
const SLAT2 = 60.0 /* 표준 위도 2 (degree) */
|
|
14
|
+
const OLON = 126.0 /* 기준점 경도 (degree) */
|
|
15
|
+
const OLAT = 38.0 /* 기준점 위도 (degree) */
|
|
16
|
+
const XO = 43 /* 기준점 X좌표 (격자 단위) */
|
|
17
|
+
const YO = 136 /* 기준점 Y좌표 (격자 단위) */
|
|
18
|
+
|
|
19
|
+
const DEGRAD = Math.PI / 180.0
|
|
20
|
+
const RADDEG = 180.0 / Math.PI
|
|
21
|
+
|
|
22
|
+
const re = RE / GRID
|
|
23
|
+
const slat1 = SLAT1 * DEGRAD
|
|
24
|
+
const slat2 = SLAT2 * DEGRAD
|
|
25
|
+
const olon = OLON * DEGRAD
|
|
26
|
+
const olat = OLAT * DEGRAD
|
|
27
|
+
|
|
28
|
+
const sn =
|
|
29
|
+
Math.log(Math.cos(slat1) / Math.cos(slat2)) /
|
|
30
|
+
Math.log(Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5))
|
|
31
|
+
const sf = (Math.pow(Math.tan(Math.PI * 0.25 + slat1 * 0.5), sn) * Math.cos(slat1)) / sn
|
|
32
|
+
const ro = (re * sf) / Math.pow(Math.tan(Math.PI * 0.25 + olat * 0.5), sn)
|
|
33
|
+
|
|
34
|
+
export interface LatLon {
|
|
35
|
+
/** 위도 (degree). */
|
|
36
|
+
latitude: number
|
|
37
|
+
/** 경도 (degree). */
|
|
38
|
+
longitude: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface KmaGrid {
|
|
42
|
+
/** 격자 X. */
|
|
43
|
+
nx: number
|
|
44
|
+
/** 격자 Y. */
|
|
45
|
+
ny: number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 위경도 → KMA 5km 격자좌표 (nx, ny). */
|
|
49
|
+
export function latLonToGrid(input: LatLon): KmaGrid {
|
|
50
|
+
const ra = (re * sf) / Math.pow(Math.tan(Math.PI * 0.25 + input.latitude * DEGRAD * 0.5), sn)
|
|
51
|
+
let theta = input.longitude * DEGRAD - olon
|
|
52
|
+
if (theta > Math.PI) theta -= 2.0 * Math.PI
|
|
53
|
+
if (theta < -Math.PI) theta += 2.0 * Math.PI
|
|
54
|
+
theta *= sn
|
|
55
|
+
const x = ra * Math.sin(theta) + XO
|
|
56
|
+
const y = ro - ra * Math.cos(theta) + YO
|
|
57
|
+
return { nx: Math.floor(x + 1.5), ny: Math.floor(y + 1.5) }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** KMA 5km 격자좌표 → 위경도 (격자 중심점). */
|
|
61
|
+
export function gridToLatLon(input: KmaGrid): LatLon {
|
|
62
|
+
const xn = input.nx - XO
|
|
63
|
+
const yn = ro - (input.ny - YO)
|
|
64
|
+
let ra = Math.sqrt(xn * xn + yn * yn)
|
|
65
|
+
if (sn < 0.0) ra = -ra
|
|
66
|
+
let alat = Math.pow((re * sf) / ra, 1.0 / sn)
|
|
67
|
+
alat = 2.0 * Math.atan(alat) - Math.PI * 0.5
|
|
68
|
+
let theta: number
|
|
69
|
+
if (Math.abs(xn) <= 0.0) {
|
|
70
|
+
theta = 0.0
|
|
71
|
+
} else if (Math.abs(yn) <= 0.0) {
|
|
72
|
+
theta = Math.PI * 0.5
|
|
73
|
+
if (xn < 0.0) theta = -theta
|
|
74
|
+
} else {
|
|
75
|
+
theta = Math.atan2(xn, yn)
|
|
76
|
+
}
|
|
77
|
+
const alon = theta / sn + olon
|
|
78
|
+
return { latitude: alat * RADDEG, longitude: alon * RADDEG }
|
|
79
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 기상청(KMA) 도메인 전용 태스크 그룹.
|
|
3
|
+
*
|
|
4
|
+
* 새 KMA 전용 태스크(예: AWS 자동수집, 특보 알림 등) 추가 시:
|
|
5
|
+
* - 본 폴더에 `<variant>.ts` 파일 추가 → TaskRegistry 등록
|
|
6
|
+
* - 본 index 에 `import './<variant>'` 한 줄 추가
|
|
7
|
+
*
|
|
8
|
+
* 단순 조회는 범용 `data-go-kr-call` + 스펙 레지스트리로 충분하므로,
|
|
9
|
+
* 이 폴더에는 입력 폼·헬퍼·도메인 가공이 가치 있는 태스크만 배치.
|
|
10
|
+
*/
|
|
11
|
+
import './short-term-forecast'
|
|
12
|
+
|
|
13
|
+
export { latLonToGrid, gridToLatLon } from './grid-converter'
|
|
14
|
+
export type { LatLon, KmaGrid } from './grid-converter'
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { ConnectionManager, Context, TaskRegistry, evaluateTemplate } from '@things-factory/integration-base'
|
|
2
|
+
|
|
3
|
+
import { DataGoKrConnectionInstance } from '../../connector/data-go-kr-connector'
|
|
4
|
+
import { KmaShortTermForecastService } from '../../spec/weather/short-term-forecast'
|
|
5
|
+
import { latLonToGrid } from './grid-converter'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 기상청 단기예보 (`getVilageFcst`) 조회 태스크.
|
|
9
|
+
*
|
|
10
|
+
* 입력 폼이 명시된 전용 태스크. 위경도 입력 시 KMA 격자로 자동 변환.
|
|
11
|
+
*
|
|
12
|
+
* 입력 (둘 중 하나):
|
|
13
|
+
* - `nx`, `ny` : KMA 5km 격자좌표
|
|
14
|
+
* - `latitude`, `longitude`: 위경도 (자동으로 nx/ny 로 변환)
|
|
15
|
+
*
|
|
16
|
+
* 추가:
|
|
17
|
+
* - `baseDate` : 발표일자 YYYYMMDD (필수)
|
|
18
|
+
* - `baseTime` : 발표시각 HHMM (필수, 0200/0500/0800/1100/1400/1700/2000/2300)
|
|
19
|
+
* - `numOfRows` : 페이지당 결과수 (기본 1000 — 3일치 카테고리×시점 합계 약 800+)
|
|
20
|
+
*
|
|
21
|
+
* 다른 단기예보 오퍼레이션(getUltraSrtFcst, getUltraSrtNcst) 은 동일 서비스 안에 있으므로
|
|
22
|
+
* 범용 `data-go-kr-call` 로 호출 권장.
|
|
23
|
+
*/
|
|
24
|
+
async function ShortTermForecastTask(step, context: Context): Promise<{ data: { items: any[] } }> {
|
|
25
|
+
const { connection: connectionName, params } = step
|
|
26
|
+
const { domain, user, data, variables, lng, logger } = context
|
|
27
|
+
|
|
28
|
+
const instance: DataGoKrConnectionInstance = await ConnectionManager.getConnectionInstanceByName(
|
|
29
|
+
domain,
|
|
30
|
+
connectionName
|
|
31
|
+
)
|
|
32
|
+
if (!instance?.client) {
|
|
33
|
+
throw new Error(`data-go-kr connection '${connectionName}' is not established.`)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const scope = { domain, user, lng, data, variables, console }
|
|
37
|
+
const evalString = (value: string | undefined) => {
|
|
38
|
+
if (value === undefined || value === null || value === '') return undefined
|
|
39
|
+
try {
|
|
40
|
+
return evaluateTemplate(String(value), scope)
|
|
41
|
+
} catch (err) {
|
|
42
|
+
throw new Error(`weather-short-term-forecast: failed to evaluate parameter: ${(err as Error).message}`)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const evalNumber = (value: any): number | undefined => {
|
|
46
|
+
const s = evalString(value as string | undefined)
|
|
47
|
+
if (s === undefined) return undefined
|
|
48
|
+
const n = Number(s)
|
|
49
|
+
return Number.isFinite(n) ? n : undefined
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const baseDate = evalString(params.baseDate)
|
|
53
|
+
const baseTime = evalString(params.baseTime)
|
|
54
|
+
if (!baseDate) throw new Error('weather-short-term-forecast: baseDate is required')
|
|
55
|
+
if (!baseTime) throw new Error('weather-short-term-forecast: baseTime is required')
|
|
56
|
+
|
|
57
|
+
const explicitNx = evalNumber(params.nx)
|
|
58
|
+
const explicitNy = evalNumber(params.ny)
|
|
59
|
+
const lat = evalNumber(params.latitude)
|
|
60
|
+
const lon = evalNumber(params.longitude)
|
|
61
|
+
|
|
62
|
+
let nx: number
|
|
63
|
+
let ny: number
|
|
64
|
+
if (explicitNx !== undefined && explicitNy !== undefined) {
|
|
65
|
+
nx = explicitNx
|
|
66
|
+
ny = explicitNy
|
|
67
|
+
} else if (lat !== undefined && lon !== undefined) {
|
|
68
|
+
const grid = latLonToGrid({ latitude: lat, longitude: lon })
|
|
69
|
+
nx = grid.nx
|
|
70
|
+
ny = grid.ny
|
|
71
|
+
logger?.info?.(`[data-go-kr] latLonToGrid lat=${lat} lon=${lon} → nx=${nx} ny=${ny}`)
|
|
72
|
+
} else {
|
|
73
|
+
throw new Error(
|
|
74
|
+
'weather-short-term-forecast: provide either (nx, ny) or (latitude, longitude). 둘 다 비어있음.'
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const servicePath = `${KmaShortTermForecastService.serviceId}/getVilageFcst`
|
|
79
|
+
const queryParams = {
|
|
80
|
+
base_date: baseDate,
|
|
81
|
+
base_time: baseTime,
|
|
82
|
+
nx,
|
|
83
|
+
ny,
|
|
84
|
+
numOfRows: evalNumber(params.numOfRows) ?? 1000,
|
|
85
|
+
pageNo: evalNumber(params.pageNo) ?? 1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
logger?.info?.(`[data-go-kr] ${servicePath} params=${JSON.stringify(queryParams)}`)
|
|
89
|
+
|
|
90
|
+
const items = await instance.client.getItems<any>(servicePath, queryParams)
|
|
91
|
+
|
|
92
|
+
return { data: { items } }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
ShortTermForecastTask.parameterSpec = [
|
|
96
|
+
{ type: 'string', name: 'baseDate', label: 'label.base-date', placeholder: '예) 20260425' },
|
|
97
|
+
{ type: 'string', name: 'baseTime', label: 'label.base-time', placeholder: '예) 1100' },
|
|
98
|
+
{ type: 'string', name: 'nx', label: 'label.nx', placeholder: '예) 60' },
|
|
99
|
+
{ type: 'string', name: 'ny', label: 'label.ny', placeholder: '예) 127' },
|
|
100
|
+
{ type: 'string', name: 'latitude', label: 'label.latitude', placeholder: '위경도 입력 시 nx/ny 자동 계산' },
|
|
101
|
+
{ type: 'string', name: 'longitude', label: 'label.longitude' },
|
|
102
|
+
{ type: 'string', name: 'numOfRows', label: 'label.num-of-rows', placeholder: '기본 1000' },
|
|
103
|
+
{ type: 'string', name: 'pageNo', label: 'label.page-no', placeholder: '기본 1' }
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
ShortTermForecastTask.help = 'integration/task/weather-short-term-forecast'
|
|
107
|
+
|
|
108
|
+
TaskRegistry.registerTaskHandler('data-go-kr-weather-short-term-forecast', ShortTermForecastTask)
|
|
109
|
+
|
|
110
|
+
export default ShortTermForecastTask
|
package/server/index.ts
CHANGED
|
@@ -3,3 +3,5 @@ import './engine'
|
|
|
3
3
|
export * from './engine/types'
|
|
4
4
|
export * from './engine/spec'
|
|
5
5
|
export { DataGoKrClient } from './engine/connector/data-go-kr-client'
|
|
6
|
+
export { latLonToGrid, gridToLatLon } from './engine/task/weather'
|
|
7
|
+
export type { LatLon, KmaGrid } from './engine/task/weather'
|
package/translations/en.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"label.service-key": "Service Key (data.go.kr)",
|
|
3
|
-
"label.api-origin": "API Origin (optional)",
|
|
4
3
|
"label.operation-ref": "Operation Reference",
|
|
5
4
|
"label.operation-params": "Operation Parameters",
|
|
6
5
|
"label.sigungu-cd": "Sigungu Code",
|
|
7
6
|
"label.bjdong-cd": "Beopjeongdong Code",
|
|
8
7
|
"label.plat-gb-cd": "Plot Type",
|
|
9
8
|
"label.bun": "Parcel Bun (main)",
|
|
10
|
-
"label.ji": "Parcel Ji (sub)"
|
|
9
|
+
"label.ji": "Parcel Ji (sub)",
|
|
10
|
+
"label.base-date": "Base Date (YYYYMMDD)",
|
|
11
|
+
"label.base-time": "Base Time (HHMM)",
|
|
12
|
+
"label.nx": "Grid X (KMA 5km)",
|
|
13
|
+
"label.ny": "Grid Y (KMA 5km)",
|
|
14
|
+
"label.latitude": "Latitude (auto-converts to grid if filled)",
|
|
15
|
+
"label.longitude": "Longitude",
|
|
16
|
+
"label.num-of-rows": "Results per page",
|
|
17
|
+
"label.page-no": "Page number"
|
|
11
18
|
}
|
package/translations/ja.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"label.service-key": "サービスキー (data.go.kr)",
|
|
3
|
-
"label.api-origin": "APIオリジン(任意)",
|
|
4
3
|
"label.operation-ref": "オペレーション参照",
|
|
5
4
|
"label.operation-params": "オペレーションパラメータ",
|
|
6
5
|
"label.sigungu-cd": "市郡区コード",
|
|
7
6
|
"label.bjdong-cd": "法定洞コード",
|
|
8
7
|
"label.plat-gb-cd": "土地区分",
|
|
9
8
|
"label.bun": "本番",
|
|
10
|
-
"label.ji": "副番"
|
|
9
|
+
"label.ji": "副番",
|
|
10
|
+
"label.base-date": "発表日付 (YYYYMMDD)",
|
|
11
|
+
"label.base-time": "発表時刻 (HHMM)",
|
|
12
|
+
"label.nx": "格子 X (KMA 5km)",
|
|
13
|
+
"label.ny": "格子 Y (KMA 5km)",
|
|
14
|
+
"label.latitude": "緯度 (緯経度入力時は自動格子変換)",
|
|
15
|
+
"label.longitude": "経度",
|
|
16
|
+
"label.num-of-rows": "ページあたり件数",
|
|
17
|
+
"label.page-no": "ページ番号"
|
|
11
18
|
}
|
package/translations/ko.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"label.service-key": "서비스키 (data.go.kr)",
|
|
3
|
-
"label.api-origin": "API 오리진 (선택)",
|
|
4
3
|
"label.operation-ref": "오퍼레이션 참조",
|
|
5
4
|
"label.operation-params": "오퍼레이션 파라미터",
|
|
6
5
|
"label.sigungu-cd": "시군구코드",
|
|
7
6
|
"label.bjdong-cd": "법정동코드",
|
|
8
7
|
"label.plat-gb-cd": "대지 구분",
|
|
9
8
|
"label.bun": "본번",
|
|
10
|
-
"label.ji": "부번"
|
|
9
|
+
"label.ji": "부번",
|
|
10
|
+
"label.base-date": "발표일자 (YYYYMMDD)",
|
|
11
|
+
"label.base-time": "발표시각 (HHMM)",
|
|
12
|
+
"label.nx": "격자 X (KMA 5km)",
|
|
13
|
+
"label.ny": "격자 Y (KMA 5km)",
|
|
14
|
+
"label.latitude": "위도 (위경도 입력 시 자동 격자 변환)",
|
|
15
|
+
"label.longitude": "경도",
|
|
16
|
+
"label.num-of-rows": "페이지당 결과수",
|
|
17
|
+
"label.page-no": "페이지 번호"
|
|
11
18
|
}
|
package/translations/ms.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"label.service-key": "Service Key (data.go.kr)",
|
|
3
|
-
"label.api-origin": "Asal API (pilihan)",
|
|
4
3
|
"label.operation-ref": "Rujukan Operasi",
|
|
5
4
|
"label.operation-params": "Parameter Operasi",
|
|
6
5
|
"label.sigungu-cd": "Kod Sigungu",
|
|
7
6
|
"label.bjdong-cd": "Kod Beopjeongdong",
|
|
8
7
|
"label.plat-gb-cd": "Jenis Lot",
|
|
9
8
|
"label.bun": "No. Bun",
|
|
10
|
-
"label.ji": "No. Ji"
|
|
9
|
+
"label.ji": "No. Ji",
|
|
10
|
+
"label.base-date": "Tarikh Asas (YYYYMMDD)",
|
|
11
|
+
"label.base-time": "Masa Asas (HHMM)",
|
|
12
|
+
"label.nx": "Grid X (KMA 5km)",
|
|
13
|
+
"label.ny": "Grid Y (KMA 5km)",
|
|
14
|
+
"label.latitude": "Latitud (auto-tukar ke grid bila diisi)",
|
|
15
|
+
"label.longitude": "Longitud",
|
|
16
|
+
"label.num-of-rows": "Bilangan rekod per muka",
|
|
17
|
+
"label.page-no": "No. muka surat"
|
|
11
18
|
}
|
package/translations/zh.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"label.service-key": "服务密钥 (data.go.kr)",
|
|
3
|
-
"label.api-origin": "API 源(可选)",
|
|
4
3
|
"label.operation-ref": "操作引用",
|
|
5
4
|
"label.operation-params": "操作参数",
|
|
6
5
|
"label.sigungu-cd": "市郡区代码",
|
|
7
6
|
"label.bjdong-cd": "法定洞代码",
|
|
8
7
|
"label.plat-gb-cd": "用地类型",
|
|
9
8
|
"label.bun": "本番",
|
|
10
|
-
"label.ji": "副番"
|
|
9
|
+
"label.ji": "副番",
|
|
10
|
+
"label.base-date": "发布日期 (YYYYMMDD)",
|
|
11
|
+
"label.base-time": "发布时刻 (HHMM)",
|
|
12
|
+
"label.nx": "网格 X (KMA 5km)",
|
|
13
|
+
"label.ny": "网格 Y (KMA 5km)",
|
|
14
|
+
"label.latitude": "纬度 (输入经纬度自动转换为网格)",
|
|
15
|
+
"label.longitude": "经度",
|
|
16
|
+
"label.num-of-rows": "每页条数",
|
|
17
|
+
"label.page-no": "页码"
|
|
11
18
|
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ServiceSpec } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* 국토교통부_건축물대장정보 서비스 v2 (data.go.kr 데이터셋 15044713).
|
|
4
|
-
*
|
|
5
|
-
* 세움터(EAIS) DB 를 원천으로 하는 공공 건축물대장 Open API.
|
|
6
|
-
* 모든 오퍼레이션은 동일한 PNU(필지고유번호) 구성요소로 조회한다:
|
|
7
|
-
* - sigunguCd (5) + bjdongCd (5) + platGbCd (1) + bun (4) + ji (4)
|
|
8
|
-
*/
|
|
9
|
-
export declare const BldRgstServiceV2: ServiceSpec;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"building-ledger.js","sourceRoot":"","sources":["../../../server/engine/spec/building-ledger.ts"],"names":[],"mappings":"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","sourcesContent":["import { OperationParamSpec, ServiceSpec } from './types'\n\n/**\n * PNU 5요소 파라미터 스펙 — BldRgstServiceV2 의 모든 오퍼레이션이 공유.\n * 별도 배열 분리로 작성해두면 타 서비스(예: 건축물대장 허브) 도 재사용 가능.\n */\nconst pnuParams: OperationParamSpec[] = [\n {\n name: 'sigunguCd',\n label: 'label.sigungu-cd',\n required: true,\n length: 5,\n description: '시군구코드 5자리 (법정동코드 10자리의 앞 5자리).',\n example: '11680'\n },\n {\n name: 'bjdongCd',\n label: 'label.bjdong-cd',\n required: true,\n length: 5,\n description: '법정동코드 5자리 (법정동코드 10자리의 뒤 5자리).',\n example: '10300'\n },\n {\n name: 'platGbCd',\n label: 'label.plat-gb-cd',\n default: '0',\n length: 1,\n description: '대지구분 1자리. `0` 대지 / `1` 산 / `2` 블록.',\n example: '0',\n enum: [\n { value: '0', label: '대지' },\n { value: '1', label: '산' },\n { value: '2', label: '블록' }\n ]\n },\n {\n name: 'bun',\n label: 'label.bun',\n required: true,\n pad: 4,\n description: '본번. 자동으로 4자리 zero-pad 됨 (예: `6` → `0006`). 하이픈 포함 지번은 본번/부번을 각각 입력.',\n example: '223'\n },\n {\n name: 'ji',\n label: 'label.ji',\n default: '0',\n pad: 4,\n description: '부번. 없으면 `0`. 자동 4자리 zero-pad.',\n example: '0'\n }\n]\n\n/**\n * 국토교통부_건축물대장정보 서비스 v2 (data.go.kr 데이터셋 15044713).\n *\n * 세움터(EAIS) DB 를 원천으로 하는 공공 건축물대장 Open API.\n * 모든 오퍼레이션은 동일한 PNU(필지고유번호) 구성요소로 조회한다:\n * - sigunguCd (5) + bjdongCd (5) + platGbCd (1) + bun (4) + ji (4)\n */\nexport const BldRgstServiceV2: ServiceSpec = {\n serviceId: '1613000/BldRgstService_v2',\n label: '국토교통부_건축물대장정보 서비스 v2',\n description:\n '세움터(EAIS) 원천의 건축물대장 정보를 조회한다. 표제부·총괄표제부·층별개요·부속지번·전유공용면적·주택가격·소유자현황·기본개요 등 8개 오퍼레이션 제공.',\n homepage: 'https://www.data.go.kr/data/15044713/openapi.do',\n operations: {\n getBrTitleInfo: {\n operationId: 'getBrTitleInfo',\n label: '표제부 조회',\n description:\n '건축물대장 표제부 (건물 본문) 를 조회한다. 연면적·용적률·지상층수·지하층수·주구조·주용도 등 건물 개요를 반환. 한 필지에 동이 여러 개이면 복수 레코드로 내려온다.',\n params: [...pnuParams],\n responseNotes:\n '응답 `response.body.items.item` 이 배열 또는 단일 객체로 올 수 있음. 모든 숫자 필드가 문자열(`\"114000.00\"`)로 내려옴. 집합건축물은 `regstrKindCd=3`, 일반건축물은 `regstrKindCd=2`.',\n externalDocsUrl: 'https://www.data.go.kr/data/15044713/openapi.do',\n examples: [\n {\n label: '서울 강남구 역삼동 823',\n params: { sigunguCd: '11680', bjdongCd: '10300', bun: '823', ji: '0' }\n }\n ]\n },\n getBrRecapTitleInfo: {\n operationId: 'getBrRecapTitleInfo',\n label: '총괄표제부 조회',\n description:\n '집합건축물(아파트 단지 등) 의 총괄표제부를 조회한다. 단지 전체 연면적·대지면적·동 수·세대수 등을 반환. 일반건축물에는 없음.',\n params: [...pnuParams],\n responseNotes: '일반건축물대장(단동) 의 경우 레코드가 없음. 집합건축물일 때만 유효.',\n examples: [\n {\n label: '아파트 단지 (예시)',\n params: { sigunguCd: '11680', bjdongCd: '10300', bun: '823', ji: '0' }\n }\n ]\n },\n getBrFlrOulnInfo: {\n operationId: 'getBrFlrOulnInfo',\n label: '층별개요 조회',\n description:\n '층별로 주용도·구조·면적을 조회. 지하 N층부터 지상 M층까지 각 층의 상세 구성을 반환. `regstrKindCd`, `regstrGbCd` 로 어느 대장의 층인지 구분.',\n params: [...pnuParams],\n responseNotes: '한 필지에 동이 여러 개이면 각 동의 각 층이 모두 나옴 → 결과 건수가 많을 수 있음.'\n },\n getBrExposPubuseAreaInfo: {\n operationId: 'getBrExposPubuseAreaInfo',\n label: '전유공용면적 조회',\n description:\n '집합건축물의 호(세대) 별 전유면적·공용면적을 조회. 아파트 세대별 실제 면적 산출에 사용.',\n params: [...pnuParams],\n responseNotes: '집합건축물일 때만 레코드 존재. 일반건축물에는 해당 없음.'\n },\n getBrAtchJibunInfo: {\n operationId: 'getBrAtchJibunInfo',\n label: '부속지번 조회',\n description: '대장에 연결된 부속지번(인접 필지 등) 목록을 조회.',\n params: [...pnuParams]\n },\n getBrHsprcInfo: {\n operationId: 'getBrHsprcInfo',\n label: '주택가격 조회',\n description: '공동주택/단독주택 공시가격 이력을 조회. 연도별 개별주택가격·공동주택가격 제공.',\n params: [...pnuParams]\n },\n getBrBasisOulnInfo: {\n operationId: 'getBrBasisOulnInfo',\n label: '기본개요 조회',\n description: '대장의 기본개요(대장 구분, 대장 종류, 변동일, 변동원인) 를 조회. 변동 이력 추적 용도.',\n params: [...pnuParams]\n },\n getBrExposInfo: {\n operationId: 'getBrExposInfo',\n label: '전유부 조회',\n description: '집합건축물의 호(세대) 목록과 호별 개요를 조회. 전유공용면적보다 상위 요약 수준.',\n params: [...pnuParams]\n }\n }\n}\n"]}
|