# AWC v000 데이터 계약

## 1. Normalized Source
```json
{
  "source_id": "nssb_env",
  "label": "NSSB 환경",
  "kind": "timeseries",
  "time_axis": ["datetime", "crop_day", "das", "week", "stage"],
  "supports_farm": true,
  "field_registry": "legacy_csv:nssb"
}
```
브라우저는 `source_id`만 사용한다. DB명/테이블명은 응답하지 않아도 된다.

## 2. Normalized Field
```json
{
  "field": "AT",
  "title": "온도",
  "multiplier": 1,
  "unit": "℃",
  "decimals": 1,
  "scale": {"mode":"fixed","min":-20,"max":60},
  "sql_expr_id": null,
  "colors": {"light":"#...","dark":"#...","reference":"rgba(...)"},
  "is_monitor": false,
  "alias_available": false
}
```
`is_monitor`는 **title에 `모니터` 포함 여부만**으로 결정한다.

## 3. Monitor Field
```json
{
  "field": "VentState",
  "title": "천창모니터",
  "is_monitor": true,
  "alias_available": true,
  "default_curve": "stepline"
}
```
Alias JSON 예:
```json
{
  "0": "닫힘",
  "1": "시간에 의해 열림",
  "2": "습도에 의해 열림",
  "3": "온도에 의해 열림"
}
```
툴팁은 `3 · 온도에 의해 열림`처럼 원시값을 반드시 함께 남긴다.

## 4. Data Query Request
```json
{
  "source_id": "nssb_env",
  "farms": ["01","07","23"],
  "fields": ["AT","AH"],
  "range": {"from":"2026-08-01 06:00:00","to":"2026-08-08 05:59:59"},
  "time_axis": "datetime",
  "interval": "10m",
  "aggregation": "avg"
}
```
서버는 registry에 없는 source/field/aggregation/interval을 거부한다.

## 5. Data Query Response
```json
{
  "ok": true,
  "meta": {
    "source_id": "nssb_env",
    "fields": [],
    "farms": [],
    "range": {},
    "warnings": []
  },
  "rows": [
    {"time":"2026-08-01 06:00:00","farm":"01","AT":24.1,"AH":80.2}
  ]
}
```
결측값을 0으로 만들지 않는다. `null` 또는 row 부재로 명확히 유지한다.

## 6. Window Config
```json
{
  "window_id": "awc-chart2d-uuid",
  "module_id": "awc.chart2d",
  "title": "온도 농가 비교",
  "query": {},
  "render": {
    "chart_type":"line",
    "field_overrides": {},
    "theme":"auto"
  },
  "links": {"group_id":"g1","sync":["range","farm","cursor"]}
}
```
AIWK rect는 localStorage에 존재할 수 있고 server workspace 저장 시 snapshot으로 포함한다.

## 7. Workspace
```json
{
  "workspace_id": 12,
  "name": "생산량 원인 분석",
  "scope": "shared",
  "min_role": "viewer",
  "windows": [],
  "created_by": "server-user-key",
  "version": 1
}
```
viewer는 shared workspace 원본 저장 금지.

## 8. Correlation Request
```json
{
  "x": {"source_id":"nssb_env","field":"AT","metric":"avg"},
  "y": {"source_id":"production","field":"yield","metric":"sum"},
  "observation_unit": "farm_stage",
  "farms": ["01","02","03"],
  "stage": [1,2,3]
}
```

## 9. Correlation Response
```json
{
  "ok": true,
  "n": 50,
  "pearson_r": -0.62,
  "regression": {"slope": -1.2, "intercept": 44.3},
  "points": [
    {"farm":"01","x":25.1,"y":88.0,"stage":2}
  ],
  "warnings": []
}
```
상관관계는 인과관계라고 표현하지 않는다.

## 10. API 오류
```json
{
  "ok": false,
  "code": "FIELD_NOT_ALLOWED",
  "message": "허용되지 않은 필드입니다.",
  "detail": {"source_id":"...","field":"..."}
}
```
실패 시 HTTP 상태코드와 JSON code를 같이 사용하고, 클라이언트는 이전 성공 상태를 유지한다.
