Add API keys & environments CRUD UI/API - #1
Conversation
Implements full CRUD UX + API support for API keys and Environments. Backend: ApiKeyService adds ALLOWED_PERMISSIONS, normalizePermissions and update(); ApiKeyController adds PATCH, centralized payload rules, active-first listing (includes revoked), and validation/audit; ApiKeyPolicy update and route registration. Frontend: new/updated ApiKeysPage (create/edit/revoke, one-time plaintext), Environment and EndpointProfile CRUD pages, updated types, i18n (en/pt-BR), router routes and chunk-load recovery, tenant store activeEnvironments logic, auth CSRF resets. Also: SPA catch-all regex fix, push-frontend deploy script, docs/specs/plans and feature tests for API keys.
There was a problem hiding this comment.
Code Review
This pull request implements full CRUD functionality for API keys and environments, and adds creation, editing, archiving, and testing capabilities for endpoint profiles. On the backend, API key updates, validation rules, and policies have been introduced, supported by new feature tests. On the frontend, Vue pages, localization files, and tenant stores have been updated to support these inline CRUD workflows. A review comment points out that the chunk load error recovery mechanism in the router could trigger an infinite reload loop if a chunk is genuinely missing, and suggests implementing a retry guard using sessionStorage to limit reload attempts.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| router.onError((error, to) => { | ||
| const message = String(error?.message ?? error ?? '') | ||
| const isChunkLoadError = | ||
| message.includes('Failed to fetch dynamically imported module') || | ||
| message.includes('error loading dynamically imported module') || | ||
| message.includes('Importing a module script failed') || | ||
| message.includes('Unable to preload CSS') | ||
|
|
||
| if (isChunkLoadError) { | ||
| const target = to?.fullPath || window.location.pathname | ||
| window.location.assign(target) | ||
| } | ||
| }) |
There was a problem hiding this comment.
The chunk load error recovery mechanism forces a full page reload when a chunk fails to load. However, if a chunk is genuinely missing (e.g., due to a failed deployment or deleted asset), this can trigger an infinite reload loop, crashing the user's browser and spamming the server. Consider implementing a retry guard using sessionStorage to limit the reload to a single attempt per path.
router.onError((error, to) => {\n const message = String(error?.message ?? error ?? '')\n const isChunkLoadError =\n message.includes('Failed to fetch dynamically imported module') ||\n message.includes('error loading dynamically imported module') ||\n message.includes('Importing a module script failed') ||\n message.includes('Unable to preload CSS')\n\n if (isChunkLoadError) {\n const target = to?.fullPath || window.location.pathname\n const retryKey = 'chunk-load-retry:' + target\n if (!sessionStorage.getItem(retryKey)) {\n sessionStorage.setItem(retryKey, 'true')\n window.location.assign(target)\n }\n }\n})
Implements full CRUD UX + API support for API keys and Environments. Backend: ApiKeyService adds ALLOWED_PERMISSIONS, normalizePermissions and update(); ApiKeyController adds PATCH, centralized payload rules, active-first listing (includes revoked), and validation/audit; ApiKeyPolicy update and route registration. Frontend: new/updated ApiKeysPage (create/edit/revoke, one-time plaintext), Environment and EndpointProfile CRUD pages, updated types, i18n (en/pt-BR), router routes and chunk-load recovery, tenant store activeEnvironments logic, auth CSRF resets. Also: SPA catch-all regex fix, push-frontend deploy script, docs/specs/plans and feature tests for API keys.