Skip to content

Commit 3d819c1

Browse files
HyeockJinKimclaude
andcommitted
refactor(BA-7297): name operations after their shape, not their gate
An action is global or public; that only super-admins pass the global gate is a separate fact the gate decides. Seventeen action names introduced on this branch said admin, and none of them exist on main, so no audit history splits here. Processor fields wired from the global_* and public_* factories now carry the same prefix, which is what the new Naming section in services/AGENTS.md states. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 48ad6eb commit 3d819c1

51 files changed

Lines changed: 343 additions & 318 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ Applies to every generated artifact — docs, code comments, BEPs, PR descriptio
1919
- Prefer tables and lists over prose.
2020
- Code examples show the interface/contract only, not internal implementation.
2121
- State a rule once at its highest scope (see above); link instead of repeating.
22+
- No asides. Write the rule and the fact, nothing around them.
23+
- Never restate the previous sentence in different words.
24+
- Leave out how an individual value is composed and why a choice reads as natural.
2225

2326
## Document index
2427

src/ai/backend/manager/api/adapters/app_config_allow_list/adapter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ async def admin_create(
9797
scope_type=AppConfigScopeType(input.scope_type.value),
9898
rank=input.rank,
9999
)
100-
action_result = await self._processors.app_config_allow_list.create.run(
100+
action_result = await self._processors.app_config_allow_list.global_create.run(
101101
CreateAppConfigAllowListAction(creator=creator)
102102
)
103103
return CreateAppConfigAllowListPayload(
@@ -128,7 +128,7 @@ async def batch_load_by_ids(
128128
orders=[],
129129
limit=len(ids),
130130
)
131-
action_result = await self._processors.app_config_allow_list.admin_search.run(
131+
action_result = await self._processors.app_config_allow_list.global_search.run(
132132
AdminSearchAppConfigAllowListAction(searcher=searcher)
133133
)
134134
node_map = {node.id: node for node in map(self._data_to_node, action_result.items)}
@@ -151,7 +151,7 @@ async def admin_search(
151151
limit=input.limit,
152152
offset=input.offset,
153153
)
154-
action_result = await self._processors.app_config_allow_list.admin_search.run(
154+
action_result = await self._processors.app_config_allow_list.global_search.run(
155155
AdminSearchAppConfigAllowListAction(searcher=searcher)
156156
)
157157
return SearchAppConfigAllowListPayload(
@@ -181,7 +181,7 @@ async def admin_purge(
181181
self, input: PurgeAppConfigAllowListInput
182182
) -> PurgeAppConfigAllowListPayload:
183183
purger = AppConfigAllowListPurger(allow_list_id=AppConfigAllowListID(input.id))
184-
action_result = await self._processors.app_config_allow_list.purge.run(
184+
action_result = await self._processors.app_config_allow_list.global_purge.run(
185185
PurgeAppConfigAllowListAction(purger=purger)
186186
)
187187
return PurgeAppConfigAllowListPayload(id=action_result.data.id)

src/ai/backend/manager/api/adapters/app_config_definition/adapter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async def admin_create(
7373
self, input: CreateAppConfigDefinitionInput
7474
) -> CreateAppConfigDefinitionPayload:
7575
creator = AppConfigDefinitionCreator(config_name=input.config_name)
76-
action_result = await self._processors.app_config_definition.create.run(
76+
action_result = await self._processors.app_config_definition.global_create.run(
7777
CreateAppConfigDefinitionAction(creator=creator)
7878
)
7979
return CreateAppConfigDefinitionPayload(
@@ -102,7 +102,7 @@ async def batch_load_by_ids(
102102
pagination_spec=_get_app_config_definition_pagination_spec(),
103103
limit=len(ids),
104104
)
105-
action_result = await self._processors.app_config_definition.admin_search.run(
105+
action_result = await self._processors.app_config_definition.global_search.run(
106106
AdminSearchAppConfigDefinitionsAction(searcher=searcher)
107107
)
108108
node_map = {node.id: node for node in map(self._data_to_node, action_result.items)}
@@ -125,7 +125,7 @@ async def admin_search(
125125
limit=input.limit,
126126
offset=input.offset,
127127
)
128-
action_result = await self._processors.app_config_definition.admin_search.run(
128+
action_result = await self._processors.app_config_definition.global_search.run(
129129
AdminSearchAppConfigDefinitionsAction(searcher=searcher)
130130
)
131131
return SearchAppConfigDefinitionsPayload(
@@ -138,7 +138,7 @@ async def admin_search(
138138
async def admin_purge(
139139
self, input: PurgeAppConfigDefinitionInput
140140
) -> PurgeAppConfigDefinitionPayload:
141-
action_result = await self._processors.app_config_definition.purge.run(
141+
action_result = await self._processors.app_config_definition.global_purge.run(
142142
PurgeAppConfigDefinitionAction(definition_id=AppConfigDefinitionID(input.id))
143143
)
144144
return PurgeAppConfigDefinitionPayload(id=action_result.data.id)

src/ai/backend/manager/api/adapters/audit_log/adapter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async def batch_load_by_ids(self, ids: Sequence[uuid.UUID]) -> list[AuditLogNode
6666
pagination=OffsetPagination(limit=len(ids)),
6767
conditions=[AuditLogConditions.by_ids(ids)],
6868
)
69-
action_result = await self._processors.audit_log.search.run(
69+
action_result = await self._processors.audit_log.global_search.run(
7070
SearchAuditLogsAction(searcher=searcher)
7171
)
7272
audit_log_map = {item.id: self._data_to_node(item) for item in action_result.items}
@@ -88,7 +88,7 @@ async def admin_search(self, input: AdminSearchAuditLogsInput) -> SearchAuditLog
8888
limit=input.limit,
8989
offset=input.offset,
9090
)
91-
action_result = await self._processors.audit_log.search.run(
91+
action_result = await self._processors.audit_log.global_search.run(
9292
SearchAuditLogsAction(searcher=searcher)
9393
)
9494
return SearchAuditLogsPayload(

src/ai/backend/manager/api/adapters/login_client_type/adapter.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def _convert_orders(orders: list[LoginClientTypeOrder]) -> list[QueryOrder]:
8888
# --- Non-admin methods ---
8989

9090
async def get(self, type_id: UUID) -> LoginClientTypeNode:
91-
action_result = await self._processors.login_client_type.get.run(
91+
action_result = await self._processors.login_client_type.public_get.run(
9292
GetLoginClientTypeAction(id=type_id)
9393
)
9494
return self._data_to_node(action_result.data)
@@ -97,7 +97,7 @@ async def search(self, input: SearchLoginClientTypesInput) -> SearchLoginClientT
9797
"""Search login client types with filter/order/pagination."""
9898
searcher = self._build_search_searcher(input)
9999

100-
action_result = await self._processors.login_client_type.search.run(
100+
action_result = await self._processors.login_client_type.public_search.run(
101101
SearchLoginClientTypesAction(searcher=searcher)
102102
)
103103

@@ -115,7 +115,7 @@ async def admin_create(self, input: CreateLoginClientTypeInput) -> CreateLoginCl
115115
name=input.name,
116116
description=input.description,
117117
)
118-
action_result = await self._processors.login_client_type.create.run(
118+
action_result = await self._processors.login_client_type.global_create.run(
119119
CreateLoginClientTypeAction(creator=creator)
120120
)
121121
return CreateLoginClientTypePayload(
@@ -138,15 +138,15 @@ async def admin_update(
138138
else TriState.update(input.description)
139139
),
140140
)
141-
action_result = await self._processors.login_client_type.update.run(
141+
action_result = await self._processors.login_client_type.global_update.run(
142142
UpdateLoginClientTypeAction(updater=updater)
143143
)
144144
return UpdateLoginClientTypePayload(
145145
login_client_type=self._data_to_node(action_result.data),
146146
)
147147

148148
async def admin_delete(self, type_id: UUID) -> DeleteLoginClientTypePayload:
149-
action_result = await self._processors.login_client_type.purge.run(
149+
action_result = await self._processors.login_client_type.global_purge.run(
150150
PurgeLoginClientTypeAction(id=type_id)
151151
)
152152
return DeleteLoginClientTypePayload(id=action_result.data.id)

src/ai/backend/manager/api/adapters/object_storage/adapter.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ async def admin_search(
6666
"""
6767
searcher = self.build_searcher(input)
6868

69-
action_result = await self._processors.object_storage.search_object_storages.run(
69+
action_result = await self._processors.object_storage.global_search_object_storages.run(
7070
SearchObjectStoragesAction(searcher=searcher)
7171
)
7272

@@ -146,22 +146,22 @@ async def batch_load_by_ids(self, ids: Sequence[UUID]) -> list[ObjectStorageNode
146146
pagination=OffsetPagination(limit=len(ids)),
147147
conditions=[ObjectStorageConditions.by_ids(ids)],
148148
)
149-
action_result = await self._processors.object_storage.search_object_storages.run(
149+
action_result = await self._processors.object_storage.global_search_object_storages.run(
150150
SearchObjectStoragesAction(searcher=searcher)
151151
)
152152
storage_map = {item.id: self._data_to_dto(item) for item in action_result.items}
153153
return [storage_map.get(storage_id) for storage_id in ids]
154154

155155
async def get(self, storage_id: UUID) -> ObjectStorageNode:
156156
"""Retrieve a single object storage by ID."""
157-
action_result = await self._processors.object_storage.get.run(
157+
action_result = await self._processors.object_storage.global_get.run(
158158
GetObjectStorageAction(storage_id=storage_id)
159159
)
160160
return self._data_to_dto(action_result.data)
161161

162162
async def create(self, input: CreateObjectStorageInput) -> CreateObjectStoragePayload:
163163
"""Create a new object storage."""
164-
action_result = await self._processors.object_storage.create.run(
164+
action_result = await self._processors.object_storage.global_create.run(
165165
CreateObjectStorageAction(
166166
creator=ObjectStorageCreator(
167167
name=input.name,
@@ -202,14 +202,14 @@ async def update(self, input: UpdateObjectStorageInput) -> UpdateObjectStoragePa
202202
else TriState.update(input.region)
203203
),
204204
)
205-
action_result = await self._processors.object_storage.update.run(
205+
action_result = await self._processors.object_storage.global_update.run(
206206
UpdateObjectStorageAction(updater=updater)
207207
)
208208
return UpdateObjectStoragePayload(object_storage=self._data_to_dto(action_result.data))
209209

210210
async def delete(self, input: DeleteObjectStorageInput) -> DeleteObjectStoragePayload:
211211
"""Delete an object storage."""
212-
action_result = await self._processors.object_storage.purge.run(
212+
action_result = await self._processors.object_storage.global_purge.run(
213213
PurgeObjectStorageAction(storage_id=input.id)
214214
)
215215
return DeleteObjectStoragePayload(id=action_result.data.id)
@@ -221,7 +221,7 @@ async def get_presigned_download_url(
221221
expiration: int | None = None,
222222
) -> PresignedDownloadURLPayload:
223223
"""Generate a presigned download URL for an artifact revision."""
224-
action_result = await self._processors.object_storage.get_presigned_download_url.run(
224+
action_result = await self._processors.object_storage.global_get_presigned_download_url.run(
225225
GetDownloadPresignedURLAction(
226226
artifact_revision_id=artifact_revision_id,
227227
key=key,
@@ -236,7 +236,7 @@ async def get_presigned_upload_url(
236236
key: str,
237237
) -> PresignedUploadURLPayload:
238238
"""Generate a presigned upload URL for an artifact revision."""
239-
action_result = await self._processors.object_storage.get_presigned_upload_url.run(
239+
action_result = await self._processors.object_storage.global_get_presigned_upload_url.run(
240240
GetUploadPresignedURLAction(
241241
artifact_revision_id=artifact_revision_id,
242242
key=key,

src/ai/backend/manager/api/adapters/prometheus_query_preset/adapter.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ async def batch_load_by_ids(self, ids: Sequence[UUID]) -> list[QueryDefinitionNo
9090
pagination=OffsetPagination(limit=len(ids)),
9191
conditions=[PrometheusQueryPresetConditions.by_ids(ids)],
9292
)
93-
action_result = await self._processors.prometheus_query_preset.search_presets.run(
93+
action_result = await self._processors.prometheus_query_preset.global_search_presets.run(
9494
SearchPresetsAction(searcher=searcher)
9595
)
9696
preset_map = {item.id: self._data_to_dto(item) for item in action_result.items}
@@ -114,7 +114,7 @@ async def create(self, input: CreateQueryDefinitionInput) -> CreateQueryDefiniti
114114
group_labels=input.options.group_labels,
115115
)
116116

117-
action_result = await self._processors.prometheus_query_preset.create_preset.run(
117+
action_result = await self._processors.prometheus_query_preset.global_create_preset.run(
118118
CreatePresetAction(creator=creator)
119119
)
120120

@@ -128,7 +128,7 @@ async def search(self, input: SearchQueryDefinitionsInput) -> SearchQueryDefinit
128128
"""
129129
searcher = self.build_searcher(input)
130130

131-
action_result = await self._processors.prometheus_query_preset.search_presets.run(
131+
action_result = await self._processors.prometheus_query_preset.global_search_presets.run(
132132
SearchPresetsAction(searcher=searcher)
133133
)
134134

@@ -141,7 +141,7 @@ async def search(self, input: SearchQueryDefinitionsInput) -> SearchQueryDefinit
141141

142142
async def get(self, preset_id: UUID) -> GetQueryDefinitionPayload:
143143
"""Get a single query definition by ID."""
144-
action_result = await self._processors.prometheus_query_preset.get_preset.run(
144+
action_result = await self._processors.prometheus_query_preset.global_get_preset.run(
145145
GetPresetAction(preset_id=PrometheusQueryPresetID(preset_id))
146146
)
147147

@@ -156,15 +156,15 @@ async def update(
156156
pk_value=preset_id,
157157
)
158158

159-
action_result = await self._processors.prometheus_query_preset.update_preset.run(
159+
action_result = await self._processors.prometheus_query_preset.global_update_preset.run(
160160
UpdatePresetAction(preset_id=PrometheusQueryPresetID(preset_id), updater=updater)
161161
)
162162

163163
return ModifyQueryDefinitionPayload(item=self._data_to_dto(action_result.preset))
164164

165165
async def admin_preview(self, input: PreviewQueryDefinitionInput) -> QueryDefinitionResultInfo:
166166
"""Preview a prometheus query template (admin only)."""
167-
action_result = await self._processors.prometheus_query_preset.preview_preset.run(
167+
action_result = await self._processors.prometheus_query_preset.global_preview_preset.run(
168168
PreviewPresetAction(query_template=input.query_template)
169169
)
170170
return self._prometheus_response_to_result_info(action_result.response)
@@ -192,7 +192,7 @@ async def execute_preset(
192192
if time_range is not None
193193
else None
194194
)
195-
action_result = await self._processors.prometheus_query_preset.execute_preset.run(
195+
action_result = await self._processors.prometheus_query_preset.global_execute_preset.run(
196196
ExecutePresetAction(
197197
preset_id=preset_id,
198198
options=execute_options,
@@ -224,7 +224,7 @@ def _prometheus_response_to_result_info(
224224

225225
async def delete(self, input: DeleteQueryDefinitionInput) -> DeleteQueryDefinitionPayload:
226226
"""Delete a query definition by ID."""
227-
action_result = await self._processors.prometheus_query_preset.purge_preset.run(
227+
action_result = await self._processors.prometheus_query_preset.global_purge_preset.run(
228228
PurgePresetAction(preset_id=PrometheusQueryPresetID(input.id))
229229
)
230230

src/ai/backend/manager/api/adapters/prometheus_query_preset_category/adapter.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async def batch_load_by_ids(self, ids: Sequence[UUID]) -> list[CategoryNode | No
7070
conditions=[PrometheusQueryPresetCategoryConditions.by_ids(ids)],
7171
)
7272
action_result = (
73-
await self._processors.prometheus_query_preset_category.search_categories.run(
73+
await self._processors.prometheus_query_preset_category.global_search_categories.run(
7474
SearchCategoriesAction(searcher=searcher)
7575
)
7676
)
@@ -86,8 +86,10 @@ async def create(self, input: CreateCategoryInput) -> CreateCategoryPayload:
8686
description=input.description,
8787
)
8888

89-
action_result = await self._processors.prometheus_query_preset_category.create_category.run(
90-
CreateCategoryAction(creator=creator)
89+
action_result = (
90+
await self._processors.prometheus_query_preset_category.global_create_category.run(
91+
CreateCategoryAction(creator=creator)
92+
)
9193
)
9294

9395
return CreateCategoryPayload(item=self._data_to_dto(action_result.data))
@@ -101,7 +103,7 @@ async def search(self, input: SearchCategoriesInput) -> SearchCategoriesPayload:
101103
searcher = self.build_searcher(input)
102104

103105
action_result = (
104-
await self._processors.prometheus_query_preset_category.search_categories.run(
106+
await self._processors.prometheus_query_preset_category.global_search_categories.run(
105107
SearchCategoriesAction(searcher=searcher)
106108
)
107109
)
@@ -115,16 +117,20 @@ async def search(self, input: SearchCategoriesInput) -> SearchCategoriesPayload:
115117

116118
async def get(self, category_id: UUID) -> GetCategoryPayload:
117119
"""Get a single category by ID."""
118-
action_result = await self._processors.prometheus_query_preset_category.get_category.run(
119-
GetCategoryAction(category_id=PrometheusQueryPresetCategoryID(category_id))
120+
action_result = (
121+
await self._processors.prometheus_query_preset_category.global_get_category.run(
122+
GetCategoryAction(category_id=PrometheusQueryPresetCategoryID(category_id))
123+
)
120124
)
121125

122126
return GetCategoryPayload(item=self._data_to_dto(action_result.data))
123127

124128
async def delete(self, input: DeleteCategoryInput) -> DeleteCategoryPayload:
125129
"""Remove a category by ID."""
126-
action_result = await self._processors.prometheus_query_preset_category.purge_category.run(
127-
PurgeCategoryAction(category_id=PrometheusQueryPresetCategoryID(input.id))
130+
action_result = (
131+
await self._processors.prometheus_query_preset_category.global_purge_category.run(
132+
PurgeCategoryAction(category_id=PrometheusQueryPresetCategoryID(input.id))
133+
)
128134
)
129135

130136
return DeleteCategoryPayload(id=action_result.data.id)

0 commit comments

Comments
 (0)