Commit e0524c0
fix(bedrock): expose bedrock-models under self-service /api/providers (#534)
* fix(bedrock): expose bedrock-models under self-service /api/providers path
The admin handler registered /api/admin/providers/{id}/bedrock-models,
but the frontend's default axios baseURL is /api, so every page load
from a non-admin deployment hits /api/providers/{id}/bedrock-models —
which the self_service handler did not route, yielding a 404. Reported
against production at maxx.gemini.skr.rocks after #533 merged.
Fix: add the 4-segment "providers/{id}/bedrock-models" case to
self_service.go and extract the shared GET/POST logic into
serveBedrockDiscoveredModels so both handlers call the same code path
instead of diverging. Both /api/admin/… and /api/… now return the
identical payload (verified locally with a real Bedrock provider:
200 OK + 14 discovered models on both endpoints).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bedrock): gate self-service POST force-refresh behind admin role
Both Claude and CodeRabbit round-1 reviewers flagged the same MAJOR on
PR #534: the new /api/providers/{id}/bedrock-models self-service route
accepted POST without an admin check, so any authenticated tenant
member could hammer force-refresh. The POST path bypasses the
in-process TTL and Invalidate() rate-limit and calls
ListInferenceProfiles + ListFoundationModels against the provider's
AWS account — a cheap amplifier for burning the tenant's AWS API
quota.
The admin path was implicitly admin-only via its /api/admin/ URL; the
self-service mirror inherited no such boundary. Gate POST behind
h.requireAdmin so only the admin UI's refresh button reaches it; GET
stays available to any authenticated member (same access posture as
the providers list itself).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bedrock): wire discovery persistence for desktop startup path
Codex round-1 [P2]: bedrock.SetDiscoveryRepository was only called
from cmd/maxx/main.go, but the desktop/Wails launcher initializes
adapters through core.InitializeServerComponents and never invoked
the setter. The persisted Bedrock catalog was a no-op on that path —
every desktop restart paid the full ~1-5s
ListInferenceProfiles + ListFoundationModels cold-start on the first
Bedrock request.
Move the wire-up into core.InitializeServerComponents (alongside
cooldown persistence) so both startup paths get it:
- NewBedrockDiscoveryRepository constructed in InitializeDatabase
- Added to DatabaseRepos.BedrockDiscoveryRepo
- bedrock.SetDiscoveryRepository called in InitializeServerComponents
cmd/maxx/main.go drops the duplicate call and the named bedrock
import (back to `_` side-effect registration).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bedrock): hide Refresh button for non-admin viewers
Codex round-2 [P2]: the admin-gate added to the self-service POST route
gives non-admin tenant members a 403 when they click the Refresh
button — the UI still advertised the action even though the backend
would reject it.
Hide the button when user.role !== 'admin'. Non-admin members can
still see the discovery catalog (GET is unrestricted); only the
force-refresh action is admin-only, consistent with the backend
policy. Admin users see the button unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(bedrock): restore CLI wiring + gate lazy-refresh on non-admin GET
Codex round-4 flagged two P2 issues on the rebased branch:
1. Moving bedrock.SetDiscoveryRepository into
core.InitializeServerComponents dropped it from the CLI startup —
cmd/maxx/main.go doesn't route through core.InitializeServerComponents
(only the desktop launcher does). Result: the server binary stopped
wiring the repo at all, so every restart paid the full AWS
round-trip again. Restore the call in main.go alongside the one in
core/database.go; the setter is idempotent so both paths are safe.
2. DiscoveredModels's lazy TTL refresh meant a non-admin tenant member
could still trigger ListInferenceProfiles just by opening the
provider page after the 30-min window. The POST admin-gate blocked
the hammer path but not this slow-drip one. Added an
allowLazyRefresh parameter and wired self-service GET to
h.isAdmin(r), so non-admin reads return the in-memory snapshot
only. Admin GET and POST retain the refresh path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 11f3cee commit e0524c0
6 files changed
Lines changed: 99 additions & 30 deletions
File tree
- cmd/maxx
- internal
- adapter/provider/bedrock
- core
- handler
- web/src/pages/providers/components
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
128 | 130 | | |
129 | 131 | | |
130 | 132 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
126 | 126 | | |
127 | 127 | | |
128 | 128 | | |
129 | | - | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
130 | 132 | | |
131 | 133 | | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
136 | 144 | | |
137 | 145 | | |
138 | 146 | | |
| |||
142 | 150 | | |
143 | 151 | | |
144 | 152 | | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
150 | 160 | | |
151 | 161 | | |
152 | 162 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
130 | 131 | | |
131 | 132 | | |
132 | 133 | | |
| 134 | + | |
133 | 135 | | |
134 | 136 | | |
135 | 137 | | |
| |||
166 | 168 | | |
167 | 169 | | |
168 | 170 | | |
| 171 | + | |
169 | 172 | | |
170 | 173 | | |
171 | 174 | | |
| |||
205 | 208 | | |
206 | 209 | | |
207 | 210 | | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
208 | 219 | | |
209 | 220 | | |
210 | 221 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
252 | 252 | | |
253 | 253 | | |
254 | 254 | | |
255 | | - | |
256 | | - | |
257 | | - | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
258 | 272 | | |
259 | 273 | | |
260 | 274 | | |
261 | 275 | | |
262 | 276 | | |
263 | | - | |
| 277 | + | |
264 | 278 | | |
265 | 279 | | |
266 | 280 | | |
| |||
269 | 283 | | |
270 | 284 | | |
271 | 285 | | |
272 | | - | |
| 286 | + | |
273 | 287 | | |
274 | 288 | | |
275 | 289 | | |
| |||
297 | 311 | | |
298 | 312 | | |
299 | 313 | | |
300 | | - | |
| 314 | + | |
301 | 315 | | |
302 | 316 | | |
303 | 317 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
77 | 101 | | |
78 | 102 | | |
79 | 103 | | |
| |||
Lines changed: 17 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
34 | 40 | | |
35 | 41 | | |
36 | 42 | | |
| |||
239 | 245 | | |
240 | 246 | | |
241 | 247 | | |
242 | | - | |
243 | | - | |
244 | | - | |
245 | | - | |
246 | | - | |
247 | | - | |
248 | | - | |
249 | | - | |
250 | | - | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
251 | 259 | | |
252 | 260 | | |
253 | 261 | | |
| |||
0 commit comments