-
Notifications
You must be signed in to change notification settings - Fork 203
Feat: Organization & account keys #2728
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Console (appwrite/console)Project ID: Tip Global CDN and DDoS protection come free with every Sites deployment |
WalkthroughThis PR extends the application to support organizational and account-level API keys alongside existing API keys. Changes include: updating the scopes data structure with a new Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
src/routes/(console)/account/integrations/create-token/+page.svelte (1)
1-5: Use$routesalias instead of deep relative path.The import uses a fragile 3-level relative path. As per coding guidelines, prefer
$routesalias for route module imports.Suggested fix
<script lang="ts"> - import CreateKey from '../../../project-[region]-[project]/overview/(components)/create.svelte'; + import CreateKey from '$routes/(console)/project-[region]-[project]/overview/(components)/create.svelte'; </script>src/routes/(console)/account/integrations/+page.svelte (1)
1-11: Consider migrating to Svelte 5 runes syntax.The component uses Svelte 4's
export let datapattern. Other files in this PR (e.g.,header.svelte) use Svelte 5's$derivedrune. Consider using Svelte 5 syntax for consistency.Svelte 5 runes syntax
<script lang="ts"> import { Container } from '$lib/layout'; import type { PageData } from './$types'; import Keys from './keys.svelte'; - export let data: PageData; + let { data }: { data: PageData } = $props(); </script>src/routes/(console)/organization-[organization]/integrations/create-key/+page.svelte (1)
2-2: Consider moving shared CreateKey component to $lib for better maintainability.The relative import path traverses multiple directory levels to access a component from a different route section. This creates tight coupling and violates the coding guideline to use $lib alias instead of relative paths.
🔎 Recommended approach
Move the shared
CreateKeycomponent to$lib/componentsor a similar shared location, then import it using the$libalias:- import CreateKey from '../../../project-[region]-[project]/overview/(components)/create.svelte'; + import CreateKey from '$lib/components/createKey.svelte';This improves maintainability and follows the project's convention of using path aliases.
Based on coding guidelines: Use $lib, $routes, and $themes aliases instead of relative paths for module imports.
src/routes/(console)/organization-[organization]/integrations/keys.svelte (1)
5-5: Consider moving shared Table component to $lib.Similar to the CreateKey component, the Table component is imported using a relative path from a different route section. For consistency and maintainability, shared components should be placed in
$liband imported using the$libalias.Based on coding guidelines: Use $lib, $routes, and $themes aliases instead of relative paths for module imports.
src/routes/(console)/account/integrations/keys.svelte (1)
5-5: Consider moving shared Table component to $lib.The Table component is imported using a relative path from a different route section. For consistency and maintainability, shared components should be placed in
$liband imported using the$libalias.Based on coding guidelines: Use $lib, $routes, and $themes aliases instead of relative paths for module imports.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (20)
package.jsonsrc/lib/constants.tssrc/routes/(console)/account/header.sveltesrc/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/account/integrations/+page.tssrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/account/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/+layout.sveltesrc/routes/(console)/organization-[organization]/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/create.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.sveltesrc/routes/(console)/project-[region]-[project]/overview/store.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx,js,jsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx,svelte}: Import reusable modules from the src/lib directory using the $lib alias
Use minimal comments in code; reserve comments for TODOs or complex logic explanations
Use $lib, $routes, and $themes aliases instead of relative paths for module imports
Files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/account/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/create.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/store.tssrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/organization-[organization]/+layout.sveltesrc/routes/(console)/organization-[organization]/header.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/account/integrations/keys.sveltesrc/lib/constants.ts
src/routes/**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]
Files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/create.sveltesrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/organization-[organization]/+layout.sveltesrc/routes/(console)/organization-[organization]/header.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/account/integrations/keys.svelte
**/*.{ts,tsx,js,jsx,svelte,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use 4 spaces for indentation, single quotes, 100 character line width, and no trailing commas per Prettier configuration
Files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/account/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/create.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/store.tssrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltepackage.jsonsrc/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/organization-[organization]/+layout.sveltesrc/routes/(console)/organization-[organization]/header.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/account/integrations/keys.sveltesrc/lib/constants.ts
**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development
Files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/create.sveltesrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/organization-[organization]/+layout.sveltesrc/routes/(console)/organization-[organization]/header.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/account/integrations/keys.svelte
src/routes/**
📄 CodeRabbit inference engine (AGENTS.md)
Configure dynamic routes using SvelteKit convention with [param] syntax in route directory names
Files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/account/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/create.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/store.tssrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/organization-[organization]/+layout.sveltesrc/routes/(console)/organization-[organization]/header.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/account/integrations/keys.svelte
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
**/*.ts: Define types inline or in .d.ts files, avoid creating separate .types.ts files
Use TypeScript in non-strict mode; any type is tolerated in this project
Files:
src/routes/(console)/account/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/+page.tssrc/routes/(console)/project-[region]-[project]/overview/store.tssrc/lib/constants.ts
🧠 Learnings (10)
📚 Learning: 2025-11-25T03:15:27.539Z
Learnt from: CR
Repo: appwrite/console PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:15:27.539Z
Learning: Applies to src/routes/**/*.svelte : Use SvelteKit file conventions: +page.svelte for components, +page.ts for data loaders, +layout.svelte for wrappers, +error.svelte for error handling, and dynamic route params in square brackets like [param]
Applied to files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/account/integrations/+page.tssrc/routes/(console)/organization-[organization]/integrations/keys.sveltesrc/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/table.sveltesrc/routes/(console)/account/integrations/create-token/+page.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.sveltesrc/routes/(console)/account/integrations/keys.svelte
📚 Learning: 2025-11-25T03:15:27.539Z
Learnt from: CR
Repo: appwrite/console PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:15:27.539Z
Learning: Applies to **/*.svelte : Use Svelte 5 + SvelteKit 2 syntax with TypeScript for component development
Applied to files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.sveltesrc/routes/(console)/organization-[organization]/integrations/create-key/+page.sveltesrc/routes/(console)/account/integrations/create-token/+page.svelte
📚 Learning: 2025-10-05T09:41:40.439Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2398
File: src/routes/(console)/verify-email/+page.svelte:48-51
Timestamp: 2025-10-05T09:41:40.439Z
Learning: In SvelteKit 5, `page` imported from `$app/state` is a reactive state object (using runes), not a store. It should be accessed as `page.data` without the `$` prefix, unlike the store-based `$page` from `$app/stores` in earlier versions.
Applied to files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.svelte
📚 Learning: 2025-10-13T05:13:54.542Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/table.svelte:33-39
Timestamp: 2025-10-13T05:13:54.542Z
Learning: In Svelte 5, `import { page } from '$app/state'` provides a reactive state proxy that can be accessed directly (e.g., `page.params`), unlike the older `import { page } from '$app/stores'` which returns a readable store requiring the `$page` syntax for auto-subscription in components.
Applied to files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.svelte
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
Applied to files:
src/routes/(console)/account/integrations/+page.sveltesrc/routes/(console)/account/header.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.svelte
📚 Learning: 2025-11-19T11:22:42.553Z
Learnt from: atharvadeosthale
Repo: appwrite/console PR: 2512
File: src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte:51-83
Timestamp: 2025-11-19T11:22:42.553Z
Learning: In src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte, the Lovable integration URL format `https://lovable.dev/` with `autosubmit` and `prompt` as query parameters (set via searchParams) is correct and functional.
Applied to files:
src/routes/(console)/organization-[organization]/integrations/installations.sveltesrc/routes/(console)/account/integrations/create-token/+page.svelte
📚 Learning: 2025-11-25T03:15:27.539Z
Learnt from: CR
Repo: appwrite/console PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T03:15:27.539Z
Learning: Applies to src/lib/components/**/*.svelte : Use PascalCase for component file names and place them in src/lib/components/[feature]/ directory structure
Applied to files:
src/routes/(console)/organization-[organization]/integrations/apps.sveltesrc/routes/(console)/organization-[organization]/integrations/+page.svelte
📚 Learning: 2025-09-26T06:48:57.938Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2373
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:629-631
Timestamp: 2025-09-26T06:48:57.938Z
Learning: In the Appwrite console codebase using appwrite.io/pink-svelte, the Icon component automatically handles CSS variable names passed to its color prop by internally wrapping them with var(). Therefore, passing '--some-css-variable' as a string to the Icon color prop works correctly without needing to manually wrap it with var().
Applied to files:
package.json
📚 Learning: 2025-09-30T07:41:06.679Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2425
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte:454-468
Timestamp: 2025-09-30T07:41:06.679Z
Learning: In `src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte`, the column suggestions API (console.suggestColumns) has a maximum limit of 7 columns returned, which aligns with the initial placeholder count of 7 in customColumns.
Applied to files:
src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte
📚 Learning: 2025-11-19T11:22:42.553Z
Learnt from: atharvadeosthale
Repo: appwrite/console PR: 2512
File: src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte:51-83
Timestamp: 2025-11-19T11:22:42.553Z
Learning: In src/routes/(console)/project-[region]-[project]/overview/platforms/llmBanner.svelte, the Cursor integration URL format `https://cursor.com/link/prompt` with the `text` query parameter is correct and functional.
Applied to files:
src/routes/(console)/account/integrations/create-token/+page.svelte
🧬 Code graph analysis (3)
src/routes/(console)/account/integrations/+page.ts (2)
src/routes/(console)/organization-[organization]/integrations/+page.ts (1)
load(5-16)src/lib/stores/sdk.ts (1)
sdk(173-196)
src/routes/(console)/organization-[organization]/integrations/+page.ts (2)
src/routes/(console)/account/integrations/+page.ts (1)
load(5-15)src/lib/stores/sdk.ts (1)
sdk(173-196)
src/routes/(console)/project-[region]-[project]/overview/store.ts (1)
src/lib/helpers/types.ts (1)
Column(44-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: e2e
🔇 Additional comments (22)
package.json (1)
25-25: LGTM - SDK dependency update.The updated
@appwrite.io/consoleartifact is required for the newaccount.listKeys()andorganizations.listKeys()SDK methods used by this feature.Ensure the new SDK artifact (
b369c68) includes theaccount.listKeysandorganizations.listKeysmethods referenced in the new integration pages.src/routes/(console)/account/integrations/+page.ts (1)
1-15: LGTM - Data loader follows established patterns.The loader correctly mirrors the organization integrations loader structure, uses appropriate dependency tracking, and properly returns the keys data.
src/routes/(console)/organization-[organization]/integrations/installations.svelte (1)
1-23: LGTM - Clean placeholder component.The installations component follows the established CardGrid pattern and appropriately indicates the feature is coming soon.
src/routes/(console)/account/header.svelte (1)
14-53: Good refactoring to unified tabs pattern.The declarative approach with a filtered array is cleaner than conditional array composition. The new Integrations tab is correctly configured as cloud-only with
hasChildren: truefor sub-routes.src/lib/constants.ts (2)
159-165: Well-structured type extension for scopes.The addition of the
typediscriminator field enables proper filtering of scopes based on key context (API, organization, or account). This is a clean approach to extending the data model.
599-613: No action required. Scope filtering by type is already correctly implemented in the Scopes component (scopes.svelte) with the explicit filter.filter((scope) => scope.type === type), preventing duplicate scope names from appearing in the UI.src/routes/(console)/organization-[organization]/header.svelte (1)
87-92: LGTM! Integrations tab follows established patterns.The new Integrations tab is properly configured with appropriate access controls (owner-only and cloud-only), consistent with the existing tab structure.
src/routes/(console)/organization-[organization]/+layout.svelte (1)
39-47: LGTM! Navigation command properly configured.The new "Go to integrations" command follows the established pattern with appropriate keyboard shortcuts and access controls.
src/routes/(console)/organization-[organization]/integrations/apps.svelte (1)
14-21: Verify placeholder content is intentional.The "Coming soon" message indicates this feature is in testing. Confirm this placeholder is appropriate for the current release and whether tracking exists for when this will be implemented.
src/routes/(console)/organization-[organization]/integrations/+page.svelte (1)
1-15: LGTM! Clean component composition.The page follows SvelteKit conventions and cleanly composes the integrations UI sections. The data flow from the load function to child components is straightforward and type-safe.
src/routes/(console)/organization-[organization]/integrations/+page.ts (1)
8-11: No issues found. The SDK methodsdk.forConsole.organizations.listKeysis correctly called with the appropriate parametersorganizationIdandtotal. The route parameterparams.organizationcorrectly contains the organization ID from the[organization]dynamic route segment per SvelteKit convention.src/routes/(console)/project-[region]-[project]/overview/store.ts (1)
41-43: LGTM!The new column presets for organization and account keys are correctly defined and follow the established pattern of cloning
keyColumns. The implementation is consistent with howdevKeyColumnsis structured.src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte (2)
37-37: LGTM!The new
typeprop correctly enables filtering scopes by resource type (api/organization/account), supporting the multi-scope key management feature.
51-59: LGTM!The type-based filtering logic correctly narrows scopes to match the specified key type, ensuring users only see relevant permissions for API, organization, or account keys.
src/routes/(console)/project-[region]-[project]/overview/(components)/deleteBatch.svelte (1)
20-111: Well-structured refactor with consistent helper functions.The helper functions (
getLabel,getSlug,getEvent,getDependency,deleteKey,postDeleteRedirect) effectively centralize key-type-specific logic, making the code maintainable and reducing duplication.However, verify the following:
- Event tracking:
getEvent()returnsSubmit.KeyDeletefor api, organization, and account keys. Confirm whether separate analytics events are needed to distinguish between these key types.- Post-deletion navigation:
postDeleteRedirect()only navigates for API keys (lines 98-101), while other types remain on the same page. Verify this is the intended UX.src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte (3)
21-21: LGTM!The
typeprop correctly enables the component to handle creation of API keys, organization keys, and account tokens with a single unified interface.
33-79: Clean separation of key creation logic.The three specialized creation functions (
createProjectKey,createOrganizationKey,createAccountKey) properly handle:
- Type-specific SDK calls
- Appropriate dependency invalidation
- Correct navigation to the resource-specific path
The implementation is well-organized and maintainable.
98-122: Dynamic notification with smart copy actions.The notification logic correctly:
- Generates a resource-specific title (line 98-99)
- Always includes a copy button for the key/token (lines 100-107)
- Conditionally adds "Copy endpoint" only for API keys (lines 109-116)
This provides a better UX by tailoring the notification to each key type.
src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte (4)
38-49: Correct permission checks per key type.The
canWrite()function appropriately maps each key type to its corresponding permission:
- API keys →
$canWriteKeys- Dev keys →
$canWriteProjects- Organization keys →
$canWriteTeams- Account tokens →
true(user always has permission for their own account)This ensures proper access control for each resource type.
51-156: Well-designed helper functions for multi-type support.The helper functions (
getLabel,getSlug,getColumns,getExpiredColor,getDescription,hasScopes) effectively centralize type-specific behavior, making the component:
- Maintainable: All type-specific logic is in one place
- Extensible: Adding new key types requires updating helpers in a predictable way
- DRY: Eliminates repeated conditionals throughout the template
The implementation correctly handles nuances like:
- Dev keys don't have scopes (line 147-156)
- Different expiration colors for dev keys vs. others (line 90-99)
- Appropriate column presets for each type (line 77-88)
158-177: Smart navigation logic per key type.The
onKeyCreate()function correctly:
- Routes to project-specific creation for API keys (lines 161-163)
- Routes to organization integration for organization keys (lines 166-168)
- Routes to account integration for account tokens (lines 170-171)
- Opens a modal for dev keys instead of navigation (line 174)
This aligns with the different UX flows for each key type.
249-256: Conditional create button with correct visibility logic.The create button:
- Only renders when
showCreateButtonis true AND keys exist (line 249)- Uses the appropriate label for the key type (line 253)
- Triggers the correct creation flow via
onKeyCreate()(line 251)This provides flexible control over when the create action is shown.
| { | ||
| scope: 'account', | ||
| description: "Access to manage account, it's organizations, sessions, tokens, and billing.", | ||
| category: 'Other', | ||
| icon: 'globe', | ||
| type: 'account' | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: Grammar fix needed in description.
"it's" is a contraction of "it is". Use "its" (possessive) instead.
Suggested fix
{
scope: 'account',
- description: "Access to manage account, it's organizations, sessions, tokens, and billing.",
+ description: "Access to manage account, its organizations, sessions, tokens, and billing.",
category: 'Other',
icon: 'globe',
type: 'account'
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { | |
| scope: 'account', | |
| description: "Access to manage account, it's organizations, sessions, tokens, and billing.", | |
| category: 'Other', | |
| icon: 'globe', | |
| type: 'account' | |
| }, | |
| { | |
| scope: 'account', | |
| description: "Access to manage account, its organizations, sessions, tokens, and billing.", | |
| category: 'Other', | |
| icon: 'globe', | |
| type: 'account' | |
| }, |
🤖 Prompt for AI Agents
In src/lib/constants.ts around lines 592 to 598, the description text uses the
contraction "it's" incorrectly; change "it's organizations, sessions, tokens,
and billing." to the possessive form "its organizations, sessions, tokens, and
billing." so the description reads: "Access to manage account, its
organizations, sessions, tokens, and billing."
| return !legacyPrefixes.some((prefix) => val.startsWith(prefix)); | ||
| }); | ||
| console.log(baseFilteredScopes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove debug logging.
This console.log statement appears to be leftover debug code and should be removed before merging.
🔎 Proposed fix
- console.log(baseFilteredScopes);
-
// insert cloud-only scopes right after databases.write📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| console.log(baseFilteredScopes); | |
| // insert cloud-only scopes right after databases.write |
🤖 Prompt for AI Agents
In
src/routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte
around line 47 there is a leftover debug statement
`console.log(baseFilteredScopes);`; remove this console.log call (and any other
stray debug logging if present) so no debugging output remains in production
code, and run lint/format to ensure the file compiles cleanly after removal.

What does this PR do?
Implements UI to manage more types of keys
Test Plan
Manual QA
Related PRs and Issues
appwrite/appwrite#10988
Have you read the Contributing Guidelines on issues?
Yes
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.