Skip to content

Commit f2f0030

Browse files
committed
feat(FR-2451): update spec to reflect schema changes (queryPreset field, QueryPresetCategory, category grouping)
1 parent ff61903 commit f2f0030

2 files changed

Lines changed: 54 additions & 116 deletions

File tree

  • .specs
    • draft-auto-scaling-rule-management
    • draft-auto-scaling-rule-ux

.specs/draft-auto-scaling-rule-management/spec.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@
6060
- [ ] 사용자가 Preset의 메트릭 이름을 선택하면, 해당 Preset에 연결된 쿼리 템플릿과 타임 윈도우가 자동으로 적용됨
6161
- [ ] 기존 수동 입력 방식(KERNEL metric source의 `cpu_util`, `mem` 등)도 함께 유지하여 하위 호환성 보장
6262

63-
#### 서비스 디테일 페이지 - 조건 모드 선택 (단일/범위)
63+
#### 서비스 디테일 페이지 - 조건 모드 선택 (Scale In / Scale Out / Scale In & Out)
6464

65-
- [ ] Auto Scaling Rule 추가/편집 모달에서 조건 설정 영역에 Segmented 컴포넌트를 추가하여 "단일" / "범위 선택" 두 가지 모드를 전환할 수 있도록 함
66-
- [ ] **단일 모드**: 현재 UI와 동일하게 하나의 comparator (`greater_than`, `greater_than_or_equal`, `less_than`, `less_than_or_equal`)와 threshold 값을 입력
67-
- [ ] **범위 선택 모드**: 쿼리 키를 기준으로 상한/하한 범위를 동시에 지정
68-
- UI 구성: `[하한값] [< 또는 ≤] [쿼리 키] [< 또는 ≤] [상한값]`
69-
- 왼쪽 비교 연산자: `greater_than` (`<`) 또는 `greater_than_or_equal` (`<=`) — 쿼리 키가 하한값보다 큼
70-
- 오른쪽 비교 연산자: `less_than` (`<`) 또는 `less_than_or_equal` (`<=`) — 쿼리 키가 상한값보다 작음
71-
- 각 비교 연산자는 드롭다운 또는 토글로 선택
72-
- [ ] 기본 모드는 "단일"로 설정
65+
- [ ] Auto Scaling Rule 추가/편집 모달에서 조건 설정 영역에 Radio.Group (버튼형) 컴포넌트를 추가하여 가지 조건 방향을 선택할 수 있도록 함
66+
- [ ] **Scale In** (`Metric < 하한값`): `minThreshold`만 설정. UI: `Metric < [입력값]`
67+
- [ ] **Scale Out** (`상한값 < Metric`): `maxThreshold`만 설정. UI: `[입력값] < Metric`
68+
- [ ] **Scale In & Out** (범위): `minThreshold` + `maxThreshold` 동시 설정. 두 행으로 표시
69+
- 하한값 >= 상한값이면 validation 에러를 표시
70+
- [ ] 비교 연산자는 항상 `<` (strict less than)만 사용하며, `` 선택 UI는 제공하지 않음
71+
- [ ] Step Size 필드의 prefix 기호가 조건 모드에 따라 ``/`+`/`±`로 자동 변경됨
72+
- [ ] 기본 모드는 "Scale Out"으로 설정
7373

7474
#### 서비스 디테일 페이지 - 쿼리 결과값 미리보기
7575

@@ -119,14 +119,16 @@
119119
- [ ] Preset 메트릭 선택 시 관련 설정(타임 윈도우 등)이 자동으로 반영된다
120120
- [ ] 기존 수동 입력 방식도 여전히 동작한다
121121

122-
### 조건 모드 선택 (단일/범위)
122+
### 조건 모드 선택 (Scale In / Scale Out / Scale In & Out)
123123

124-
- [ ] Segmented 컴포넌트로 "단일" / "범위 선택" 모드를 전환할 수 있다
125-
- [ ] 단일 모드에서는 기존처럼 하나의 comparator와 threshold를 입력한다
126-
- [ ] 범위 선택 모드에서는 `[하한값] [</ ≤] [쿼리 키] [</≤] [상한값]` 형태로 상한/하한 범위를 지정할 수 있다
127-
- [ ] 왼쪽 비교 연산자는 `greater_than`(`<`) 또는 `greater_than_or_equal`(`<=`)이다
128-
- [ ] 오른쪽 비교 연산자는 `less_than`(`<`) 또는 `less_than_or_equal`(`<=`)이다
129-
- [ ] 기본 모드는 "단일"이다
124+
- [ ] Radio.Group (버튼형)으로 "Scale In" / "Scale Out" / "Scale In & Out" 세 가지 모드를 선택할 수 있다
125+
- [ ] Scale In 선택 시 `Metric < [값]` UI가 표시되고 `minThreshold`만 저장된다
126+
- [ ] Scale Out 선택 시 `[값] < Metric` UI가 표시되고 `maxThreshold`만 저장된다
127+
- [ ] Scale In & Out 선택 시 두 행으로 상한/하한을 동시에 입력하며 `minThreshold` + `maxThreshold`가 저장된다
128+
- [ ] Scale In & Out 모드에서 하한값 >= 상한값이면 validation 에러가 표시된다
129+
- [ ] 비교 연산자는 항상 `<`만 사용한다
130+
- [ ] Step Size 필드의 prefix 기호가 ``/`+`/`±`로 자동 변경된다
131+
- [ ] 기본 모드는 "Scale Out"이다
130132

131133
### 쿼리 결과값 미리보기
132134

.specs/draft-auto-scaling-rule-ux/spec.md

Lines changed: 36 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,25 @@
3535

3636
에디터 모달의 비교 연산자 드롭다운은 **Legacy 단일 모드에서만** 표시하며, `<` (LESS_THAN)과 `>` (GREATER_THAN) 두 가지만 제공한다. 스키마에는 `LESS_THAN_OR_EQUAL`, `GREATER_THAN_OR_EQUAL`도 존재하지만, UI에서는 사용하지 않는다.
3737

38-
#### 2. 조건 모드 선택 (단일/범위)
38+
#### 2. 조건 모드 선택 (Scale In / Scale Out / Scale In & Out)
3939

40-
Auto Scaling Rule 에디터 모달에 Ant Design `Segmented` 컴포넌트를 추가하여 "단일" / "범위" 모드를 전환한다.
40+
Auto Scaling Rule 에디터 모달에 Ant Design `Radio.Group` (버튼형) 컴포넌트를 추가하여 세 가지 조건 방향을 선택한다. 비교 연산자는 항상 `<` (strict less than)만 사용하며, `` 선택 UI는 제공하지 않는다.
4141

42-
- **단일 모드** (기본): "상한" 또는 "하한" 방향을 선택하고 threshold 값을 입력
43-
- 상한 (`metric < threshold`): `maxThreshold`만 설정, `minThreshold`는 null
44-
- 하한 (`threshold < metric`): `minThreshold`만 설정, `maxThreshold`는 null
45-
- **범위 모드**: `[하한값]` ~ `[상한값]` 범위를 지정 (`minThreshold` + `maxThreshold` 동시 사용)
42+
- **Scale In** (`metric < threshold`): `minThreshold`만 설정, `maxThreshold`는 null
43+
- UI: `Metric < [입력값]`
44+
- **Scale Out** (`threshold < metric`): `maxThreshold`만 설정, `minThreshold`는 null
45+
- UI: `[입력값] < Metric`
46+
- 기본 선택값
47+
- **Scale In & Out** (범위): `minThreshold` + `maxThreshold` 동시 설정
48+
- UI: `Metric < [하한값]` + `[상한값] < Metric` 두 행으로 표시
4649
- 하한값 >= 상한값이면 validation 에러를 표시
4750

48-
> **참고**: Strawberry API (>=26.4.0) 전용. Legacy (<26.4.0)에서는 `comparator` + 단일 `threshold`를 그대로 사용하며, 범위 모드는 지원하지 않는다.
51+
스텝 사이즈 필드의 prefix 기호는 조건 모드에 따라 자동으로 변경된다:
52+
- Scale In: `` (minus)
53+
- Scale Out: `+` (plus)
54+
- Scale In & Out: `±`
55+
56+
> **참고**: Strawberry API (>=26.4.0) 전용. Legacy (<26.4.0)에서는 `comparator` + 단일 `threshold`를 그대로 사용하며, Scale In & Out(범위) 모드는 지원하지 않는다.
4957
5058
#### 3. Prometheus Preset 기반 메트릭 선택
5159

@@ -57,21 +65,22 @@ Auto Scaling Rule 에디터 모달에 Ant Design `Segmented` 컴포넌트를 추
5765

5866
`<26.4.0`에서는 `KERNEL`/`INFERENCE_FRAMEWORK`만 표시되며, `PROMETHEUS`는 노출하지 않는다.
5967

68+
`>=26.4.0`에서는 `INFERENCE_FRAMEWORK`가 드롭다운에서 제거되고 `KERNEL``PROMETHEUS`만 표시된다. (`isSupportPrometheusAutoScalingRule`가 true이면 `INFERENCE_FRAMEWORK` 옵션을 숨긴다.)
69+
6070
| metricSource | Preset 선택 UI | prometheusQueryPresetId | metric name |
6171
|---|---|---|---|
6272
| `KERNEL` | 숨김 | `null` | AutoComplete (자동완성 목록: `cpu_util`, `mem`, `net_rx`, `net_tx` + 자유 입력 가능) |
63-
| `INFERENCE_FRAMEWORK` | 숨김 | `null` | AutoComplete (자동완성 목록 없음, 자유 입력) |
64-
| `PROMETHEUS` | 표시 (필수) | 필수 | preset의 `metricName`에서 자동 채움 (입력 불필요) |
73+
| `INFERENCE_FRAMEWORK` | 숨김 | `null` | AutoComplete (자동완성 목록 없음, 자유 입력) `<26.4.0`에서만 표시 |
74+
| `PROMETHEUS` | 표시 (필수) | 필수 | preset 선택 시 자동 채움 (입력 불필요, 숨김 필드로 폼에 포함) |
6575

6676
##### Preset 선택 UI 동작
6777

6878
1. metric source 드롭다운에서 `PROMETHEUS` 선택 시 Prometheus Query Preset Select가 추가로 노출
6979
2. Preset 목록은 `prometheusQueryPresets` query로 로드하여 카테고리별로 그룹핑(`category.name`)하고 `name`을 드롭다운에 표시
7080
3. Preset 선택 시:
7181
- `prometheusQueryPresetId`에 선택된 preset의 UUID 저장 (Relay global ID를 디코딩한 raw UUID)
72-
- `metricName`은 preset의 `metricName`에서 자동으로 채움 (사용자 입력 불필요)
73-
- `queryTemplate`을 읽기 전용으로 표시하여 사용자가 쿼리 내용 확인 가능
74-
- `timeWindow`가 자동 적용 (preset의 `timeWindow`가 null이면 사용자 입력)
82+
- `metricName`은 preset의 `metricName`에서 자동으로 채움 (사용자 입력 불필요, 숨김 필드)
83+
- `timeWindow`가 자동 적용 (preset의 `timeWindow`가 유효한 숫자값이면 적용, null이면 기존값 유지)
7584

7685
##### Rule 목록에서 Prometheus preset 표시
7786

@@ -107,24 +116,29 @@ Prometheus Preset 모드(>=26.4.0)에서 메트릭 설정 form item의 `extra`
107116
- [ ] 기존 KERNEL/INFERENCE_FRAMEWORK metric source 수동 입력이 동작한다
108117

109118
**Strawberry (>=26.4.0)**
110-
- [ ] 에디터 모달에서 Segmented로 "단일"/"범위" 모드를 전환할 수 있다
111-
- [ ] 단일 모드에서 "상한"(`maxThreshold`만) 또는 "하한"(`minThreshold`만) 방향을 선택할 수 있다
112-
- [ ] 범위 모드에서 `minThreshold` + `maxThreshold`를 동시에 입력하고, `[min] < [metric] < [max]`로 표시된다
113-
- [ ] 범위 모드에서 하한값 >= 상한값이면 validation 에러가 표시된다
114-
- [ ] metric source에 `PROMETHEUS` 옵션이 추가되고, 선택 시 Prometheus Preset Select가 표시된다
115-
- [ ] Prometheus preset 선택 시 `metricName`이 자동으로 채워지고, `queryTemplate`이 읽기 전용으로 표시된다
119+
- [ ] 에디터 모달에서 Radio.Group 버튼으로 "Scale In" / "Scale Out" / "Scale In & Out" 세 가지 조건 방향을 선택할 수 있다
120+
- [ ] Scale In 선택 시 `minThreshold`만 설정되고, `Metric < [값]` UI가 표시된다
121+
- [ ] Scale Out 선택 시 `maxThreshold`만 설정되고, `[값] < Metric` UI가 표시된다 (기본값)
122+
- [ ] Scale In & Out 선택 시 `minThreshold` + `maxThreshold`를 동시에 입력하고, 두 행으로 표시된다
123+
- [ ] Scale In & Out 모드에서 하한값 >= 상한값이면 validation 에러가 표시된다
124+
- [ ] Step Size 필드의 prefix가 조건 모드에 따라 ``/`+`/`±`로 자동 변경된다
125+
- [ ] metric source 드롭다운에 `KERNEL``PROMETHEUS`만 표시된다 (`INFERENCE_FRAMEWORK` 숨김)
126+
- [ ] metric source에 `PROMETHEUS` 선택 시 Prometheus Preset Select가 표시된다
127+
- [ ] Prometheus preset 선택 시 `metricName`이 자동으로 채워진다 (숨김 필드)
116128
- [ ] Prometheus preset 선택 시 `prometheusQueryPresetId` (raw UUID)가 Rule에 저장된다
117-
- [ ] `KERNEL`/`INFERENCE_FRAMEWORK` 선택 시 preset 선택 UI가 숨겨진다
129+
- [ ] `KERNEL` 선택 시 preset 선택 UI가 숨겨진다
118130
- [ ] Rule 목록에서 `PROMETHEUS` source인 rule은 preset 이름이 표시된다
119131
- [ ] Rule 목록은 `ModelDeployment.autoScalingRules` nested connection으로 조회된다
120132

121133
## 버전 게이팅 전략
122134

123135
| 기능 | <26.4.0 (Legacy) | >=26.4.0 (Strawberry) | >=26.4.3 |
124136
|---|---|---|---|
125-
| 비교 연산자 표시 정규화 | 적용 (LESS_THAN/GREATER_THAN 반전) | 적용 (min/maxThreshold 기반) | 동일 |
126-
| 조건 모드 (단일/범위) | 단일만 지원 (Legacy에 범위 필드 없음) | 단일 + 범위 모두 지원 | 동일 |
127-
| Metric Source: PROMETHEUS | 미표시 (KERNEL/INFERENCE_FRAMEWORK만) | PROMETHEUS 추가, Preset 기반 Select | 동일 |
137+
| 비교 연산자 표시 정규화 | 적용 (LESS_THAN/GREATER_THAN 반전) | 적용 (min/maxThreshold 기반, 항상 `<`) | 동일 |
138+
| 조건 모드 UI | 단일만 지원 (Legacy에 범위 필드 없음) | Radio.Group 3-way: Scale In / Scale Out / Scale In & Out | 동일 |
139+
| Metric Source: INFERENCE_FRAMEWORK | 표시 | 숨김 (`isSupportPrometheusAutoScalingRule`) | 동일 |
140+
| Metric Source: PROMETHEUS | 미표시 | 추가, Preset 기반 Select (카테고리별 그룹핑) | 동일 |
141+
| Step Size prefix | 없음 | ``/`+`/`±` (조건 모드 연동) | 동일 |
128142
| Rule 목록 preset 이름 표시 | 미표시 | `prometheusQueryPresetId` 기반 (별도 query) | `queryPreset` 필드 직접 사용 |
129143
| 쿼리 결과값 미리보기 | 미표시 | 표시 (Nice to Have) | 동일 |
130144

@@ -153,81 +167,3 @@ Strawberry API 마이그레이션과 UX 개선을 동시에 진행하므로, 기
153167
- Query: `endpoint_auto_scaling_rule_nodes(endpoint)``ModelDeployment.autoScalingRules` (nested connection)
154168
- Mutation: `create_endpoint_auto_scaling_rule_node``createAutoScalingRule`, `modify_endpoint_auto_scaling_rule_node``updateAutoScalingRule`, `delete_endpoint_auto_scaling_rule_node``deleteAutoScalingRule`
155169
- 필드: snake_case → camelCase, `threshold`+`comparator``minThreshold`/`maxThreshold`, `cooldown_seconds``timeWindow`, `endpoint``modelDeploymentId`
156-
157-
## 참조
158-
159-
### 현재 코드
160-
161-
| 파일 | 설명 |
162-
|---|---|
163-
| `react/src/components/AutoScalingRuleEditorModal.tsx` | 기존 Rule 추가/편집 모달 (Legacy). rename → `AutoScalingRuleEditorModalLegacy.tsx` |
164-
| `react/src/pages/EndpointDetailPage.tsx` | Rules 목록 테이블 (line 697-926), `baiClient.supports('auto-scaling-rule')` (line 170) |
165-
166-
### GraphQL API
167-
168-
#### Auto Scaling Rule (Strawberry, >=26.4.0)
169-
170-
| 쿼리/뮤테이션 | 설명 |
171-
|---|---|
172-
| `ModelDeployment.autoScalingRules(filter, orderBy, ...)` | Rule 목록 조회 — `ModelDeployment` type의 nested connection |
173-
| `createAutoScalingRule(input: CreateAutoScalingRuleInput!)` | Rule 생성 (`modelDeploymentId` 필수) |
174-
| `updateAutoScalingRule(input: UpdateAutoScalingRuleInput!)` | Rule 수정 (partial update) |
175-
| `deleteAutoScalingRule(input: DeleteAutoScalingRuleInput!)` | Rule 삭제 |
176-
177-
#### Prometheus Query Preset (Read only, 모든 인증된 사용자)
178-
179-
| 쿼리 | 설명 |
180-
|---|---|
181-
| `prometheusQueryPresets(filter, orderBy, limit, offset)` | Preset 목록 조회 (`QueryDefinition.category` 필드로 카테고리 정보 함께 조회 가능) |
182-
| `prometheusQueryPreset(id: ID!)` | Preset 단건 조회 |
183-
| `prometheusQueryPresetResult(id, timeRange, options, timeWindow)` | Preset 기반 쿼리 실행 결과 (Nice to Have) |
184-
| `prometheusQueryPresetCategories(filter, orderBy, ...)` | Preset 카테고리 목록 조회 |
185-
| `prometheusQueryPresetCategory(id: ID!)` | Preset 카테고리 단건 조회 |
186-
187-
### ID 변환 주의사항
188-
189-
- Preset 목록 조회 (`prometheusQueryPresets`) 응답의 `id`는 Relay global ID (base64 인코딩)
190-
- Rule 생성/수정 시 `prometheusQueryPresetId`에는 `toLocalId(globalId)`로 디코딩한 raw UUID를 전달
191-
- Rule 조회 응답의 `prometheusQueryPresetId`는 raw UUID로 반환됨
192-
- `AutoScalingRule.queryPreset` 필드(>=26.4.3)를 사용하면 ID 변환 없이 preset 이름/카테고리 등 정보를 직접 조회 가능
193-
- Rule 수정 시 preset select 초기값 복원은 `prometheusQueryPresetId`와 preset 목록 Relay global ID를 `toLocalId()`로 변환하여 매칭
194-
195-
### 주요 타입 (스키마 기준)
196-
197-
#### AutoScalingMetricComparator (enum)
198-
`LESS_THAN`, `LESS_THAN_OR_EQUAL`, `GREATER_THAN`, `GREATER_THAN_OR_EQUAL`
199-
200-
#### AutoScalingMetricSource (enum)
201-
`KERNEL`, `INFERENCE_FRAMEWORK`, `PROMETHEUS` (PROMETHEUS는 >=26.4.0)
202-
203-
#### AutoScalingRule (type, added 25.19.0)
204-
`id`, `metricSource`, `metricName`, `minThreshold: Decimal`, `maxThreshold: Decimal`, `stepSize`, `timeWindow`, `minReplicas`, `maxReplicas`, `prometheusQueryPresetId: ID` (added 26.4.2), `createdAt`, `lastTriggeredAt`, `queryPreset: QueryDefinition` (added 26.4.3 — preset 객체 직접 resolve)
205-
206-
#### CreateAutoScalingRuleInput
207-
`modelDeploymentId: ID!`, `metricSource: AutoScalingMetricSource!`, `metricName: String!`, `minThreshold: Decimal`, `maxThreshold: Decimal`, `stepSize: Int!`, `timeWindow: Int!`, `minReplicas: Int`, `maxReplicas: Int`, `prometheusQueryPresetId: ID`
208-
209-
#### UpdateAutoScalingRuleInput
210-
`id: ID!`, `metricSource`, `metricName`, `minThreshold`, `maxThreshold`, `stepSize`, `timeWindow`, `minReplicas`, `maxReplicas`, `prometheusQueryPresetId: ID`
211-
212-
#### QueryDefinition (type, added 26.3.0)
213-
`id`, `name`, `description: String`, `rank: Int!`, `categoryId: UUID`, `metricName`, `queryTemplate`, `timeWindow: String`, `options: QueryDefinitionOptions!` (`filterLabels: [String!]!`, `groupLabels: [String!]!`), `createdAt`, `updatedAt`, `category: QueryPresetCategory` (added 26.4.3 — 카테고리 엔티티 직접 resolve)
214-
215-
#### QueryPresetCategory (type, added 26.3.0)
216-
`id: UUID!`, `name: String!`, `description: String`, `createdAt: DateTime!`, `updatedAt: DateTime!`
217-
218-
#### QueryDefinitionExecuteResult (type, added 26.3.0)
219-
`status: String!`, `resultType: String!`, `result: [QueryDefinitionMetricResult!]!`
220-
- **QueryDefinitionMetricResult**: `metric: [MetricLabelEntry!]!`, `values: [QueryDefinitionMetricResultValue!]!`
221-
- **QueryDefinitionMetricResultValue**: `timestamp: Float!`, `value: String!`
222-
223-
#### ExecuteQueryDefinitionOptionsInput
224-
`filterLabels: [MetricLabelEntryInput!]`, `groupLabels: [String!]`
225-
226-
#### QueryTimeRangeInput (added 26.3.0)
227-
`start: DateTime!`, `end: DateTime!`, `step: String!`
228-
229-
## 범위 외 (Out of Scope)
230-
231-
- Admin Prometheus Query Preset CUD (`adminCreatePrometheusQueryPreset`, `adminModifyPrometheusQueryPreset`, `adminDeletePrometheusQueryPreset`) — 별도 Spec
232-
- Auto Scaling Rule CRUD 자체 (이미 구현됨, 이 spec에서는 Strawberry API로 마이그레이션)
233-
- Legacy 코드 완전 제거 (백엔드 최소 버전 올린 후 별도 진행)

0 commit comments

Comments
 (0)