Skip to content

Feat: queries param on list api keys#11278

Merged
Meldiron merged 8 commits into1.8.xfrom
feat-list-api-keys-queries
Feb 10, 2026
Merged

Feat: queries param on list api keys#11278
Meldiron merged 8 commits into1.8.xfrom
feat-list-api-keys-queries

Conversation

@Meldiron
Copy link
Copy Markdown
Contributor

@Meldiron Meldiron commented Feb 9, 2026

What does this PR do?

Allows queries, as all other endpoints, for api keys

Test Plan

New tests

Related PRs and Issues

x

Checklist

  • Have you read the Contributing Guidelines on issues?
  • If the PR includes a change to an API's metadata (desc, label, params, etc.), does it also include updated API specs and example docs?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 9, 2026

📝 Walkthrough

Walkthrough

Adds query-based retrieval and cursor support to the project keys listing endpoint: the controller now accepts an array of query strings, parses and validates them via a new Keys query validator (allowed attributes: expire, accessedAt, name, scopes), and handles limit/default limit, cursor resolution to key documents, grouped filters for total counting, and query error mapping. Adds duplicate-key creation handling that maps duplicate exceptions to a new KEY_ALREADY_EXISTS error code and config entry. End-to-end tests expanded and timing adjusted to exercise query filtering, cursors, ordering, pagination, scopes/name/expiry filters, and related error cases.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding queries parameter support to the list API keys endpoint.
Description check ✅ Passed The description directly relates to the changeset, explaining the motivation (allowing queries on API keys endpoint like other endpoints) and noting new tests were added.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-list-api-keys-queries

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
tests/e2e/Services/Projects/ProjectsConsoleClientTest.php (1)

3146-3172: Assert the duplicate-key error type to cover the new mapping.

Right now only the 409 is checked; asserting the error type would confirm the new KEY_ALREADY_EXISTS mapping is exercised.

✅ Suggested assertion
         $this->assertEquals(409, $response['headers']['status-code']);
+        $this->assertEquals(Exception::KEY_ALREADY_EXISTS, $response['body']['type']);

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 9, 2026

Security Scan Results for PR

Docker Image Scan Results

Package Version Vulnerability Severity
libcrypto3 3.5.4-r0 CVE-2025-15467 CRITICAL
libcrypto3 3.5.4-r0 CVE-2025-69419 HIGH
libcrypto3 3.5.4-r0 CVE-2025-69421 HIGH
libpng 1.6.51-r0 CVE-2025-66293 HIGH
libpng 1.6.51-r0 CVE-2026-22695 HIGH
libpng 1.6.51-r0 CVE-2026-22801 HIGH
libpng-dev 1.6.51-r0 CVE-2025-66293 HIGH
libpng-dev 1.6.51-r0 CVE-2026-22695 HIGH
libpng-dev 1.6.51-r0 CVE-2026-22801 HIGH
libssl3 3.5.4-r0 CVE-2025-15467 CRITICAL
libssl3 3.5.4-r0 CVE-2025-69419 HIGH
libssl3 3.5.4-r0 CVE-2025-69421 HIGH
libxml2 2.13.8-r0 CVE-2025-49794 CRITICAL
libxml2 2.13.8-r0 CVE-2025-49796 CRITICAL
libxml2 2.13.8-r0 CVE-2025-49795 HIGH
libxml2 2.13.8-r0 CVE-2025-6021 HIGH
openssl 3.5.4-r0 CVE-2025-15467 CRITICAL
openssl 3.5.4-r0 CVE-2025-69419 HIGH
openssl 3.5.4-r0 CVE-2025-69421 HIGH
openssl-dev 3.5.4-r0 CVE-2025-15467 CRITICAL
openssl-dev 3.5.4-r0 CVE-2025-69419 HIGH
openssl-dev 3.5.4-r0 CVE-2025-69421 HIGH
py3-urllib3 1.26.20-r0 CVE-2026-21441 HIGH
py3-urllib3-pyc 1.26.20-r0 CVE-2026-21441 HIGH
github.com/containerd/containerd/v2 v2.0.2 CVE-2024-25621 HIGH
golang.org/x/crypto v0.31.0 CVE-2025-22869 HIGH
golang.org/x/oauth2 v0.24.0 CVE-2025-22868 HIGH
stdlib 1.22.10 CVE-2025-47907 HIGH
stdlib 1.22.10 CVE-2025-58183 HIGH
stdlib 1.22.10 CVE-2025-61726 HIGH
stdlib 1.22.10 CVE-2025-61728 HIGH
stdlib 1.22.10 CVE-2025-61729 HIGH
stdlib 1.22.10 CVE-2025-61730 HIGH
stdlib 1.22.10 CVE-2025-68121 HIGH

Source Code Scan Results

🎉 No vulnerabilities found!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@app/controllers/api/projects.php`:
- Around line 32-33: Import ordering in app/controllers/api/projects.php
violates PSR-12: move the two new imports so they alphabetically precede their
peers. Specifically, place Utopia\Database\Exception\Query before
Utopia\Database\Helpers\ID, and place Utopia\Database\Validator\Query\Cursor
before Utopia\Database\Validator\UID; update the use statement order accordingly
so all Utopia\Database imports are alphabetized.
🧹 Nitpick comments (1)
tests/e2e/Services/Projects/ProjectsConsoleClientTest.php (1)

3264-3278: Consider using an explicit order attribute for clarity, but note that Query::orderDesc('') works correctly and isn't flaky.

Query::orderDesc('') automatically resolves to $sequence (an internal system attribute available for all collections) via the Query constructor, so it passes validation. However, for code clarity and maintainability, prefer an explicit attribute like name so the intent is obvious to readers.

🔧 Suggested fix
-                Query::orderDesc('')->toString(),
+                Query::orderDesc('name')->toString(),

@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 9, 2026

✨ Benchmark results

  • Requests per second: 2,806
  • Requests with 200 status code: 505,162
  • P99 latency: 0.056870832

⚡ Benchmark Comparison

Metric This PR Latest version
RPS 2,806 1,391
200 505,162 250,456
P99 0.056870832 0.147055774

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a 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

🤖 Fix all issues with AI agents
In `@app/controllers/api/projects.php`:
- Around line 1188-1195: The cursor key lookup uses
$dbForPlatform->getDocument('keys', $keyId) without verifying the key's project,
which leaks existence of keys across projects; change the lookup to scope by
project (same filters used later: resourceType and resourceInternalId) — either
replace the direct getDocument call with a find/query on the 'keys' collection
filtering by _id = $keyId AND resourceType = 'project' AND resourceInternalId =
$projectInternalId (or validate the returned document's
resourceType/resourceInternalId after getDocument), and only treat it as found
if it belongs to the current project before calling
$cursor->setValue($cursorDocument).

In `@tests/e2e/Services/Projects/ProjectsConsoleClientTest.php`:
- Around line 3367-3375: The test calls Query::orderDesc('') which relies on
undocumented fallback; change the empty string to the explicit allowed attribute
'name' so use Query::orderDesc('name') when building the 'queries' array in the
ProjectsConsoleClientTest (the call that builds $response), ensuring the Keys
validator accepts the attribute and the test intent is clear.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: review in progress by coderabbit.ai -->\n\n> [!NOTE]\n> Currently processing new changes in this PR. This may take a few minutes, please wait...\n> \n> \n> \n> ```ascii\n>  _____________________________________\n> < Please step away from the keyboard! >\n>  -------------------------------------\n>   \\\n>    \\   \\\n>         \\ /\\\n>         ( )\n>       .( o ).\n> ```\n> \n> <sub>✏️ Tip: You can disable in-progress messages and the fortune message in your review settings.</sub>\n\n<!-- end of auto-generated comment: review in progress by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nAdds query-based retrieval and cursor support to the project keys listing endpoint. Introduces a new Keys query validator (allowed attributes: expire, accessedAt, name, scopes). Controller action signature updated to accept an array of queries; queries are parsed and validated, invalid queries or cursors yield query errors, and a valid cursor resolves to a key document for pagination. Filtering now groups parsed queries and uses a filtered count for totals. Public imports updated for QueryException and Cursor. End-to-end tests extended to cover query filtering, cursor pagination, ordering, limits/offsets, and error cases.\n\n## Estimated code review effort\n\n🎯 3 (Moderate) | ⏱️ ~25 minutes\n\n</details>\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n<details>\n<summary>❌ Failed checks (1 warning)</summary>\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n</details>\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                                                            |\n| :---------------: | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|    Title check    | ✅ Passed | The title 'Feat: queries param on list api keys' accurately describes the main change—adding a queries parameter to the API keys list endpoint.                        |\n| Description check | ✅ Passed | The description is directly related to the changeset, explaining the motivation to add queries support to the API keys endpoint and noting that tests have been added. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> 📝 Generate docstrings\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `feat-list-api-keys-queries`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=appwrite/appwrite&utm_content=11278)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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= -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}},"response":{"url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","status":500,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-length":"0","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Mon, 09 Feb 2026 16:13:36 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"5868:881D1:F9D93C:4358932:698A07AE","x-ratelimit-limit":"12500","x-ratelimit-remaining":"12426","x-ratelimit-reset":"1770657093","x-ratelimit-resource":"core","x-ratelimit-used":"74","x-xss-protection":"0"},"data":""}}

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nAdds query-based retrieval and cursor support to the project keys listing endpoint. Introduces a new Keys query validator (allowed attributes: expire, accessedAt, name, scopes). Controller action signature updated to accept an array of queries; queries are parsed and validated, invalid queries or cursors produce query errors, and a valid cursor resolves to a key document for pagination. Filtering groups parsed queries and uses a filtered count for totals. Public imports updated for QueryException and Cursor. End-to-end tests expanded to exercise query filtering, cursor pagination, ordering, limits/offsets, and error cases.\n\n## Estimated code review effort\n\n🎯 4 (Complex) | ⏱️ ~45 minutes\n\n</details>\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n<details>\n<summary>❌ Failed checks (1 warning)</summary>\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n</details>\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                                                |\n| :---------------: | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|    Title check    | ✅ Passed | The title clearly describes the main change: adding a queries parameter to the list API keys endpoint.                                                     |\n| Description check | ✅ Passed | The description relates to the changeset by explaining that the PR adds queries parameter support to the API keys list endpoint, matching other endpoints. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> 📝 Generate docstrings\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `feat-list-api-keys-queries`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n\n---\n\nNo actionable comments were generated in the recent review. 🎉\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=appwrite/appwrite&utm_content=11278)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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= -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}},"response":{"url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","status":500,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-length":"0","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Mon, 09 Feb 2026 16:19:44 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"281F:3847D6:151A1A9:5B274E0:698A091E","x-ratelimit-limit":"12500","x-ratelimit-remaining":"12376","x-ratelimit-reset":"1770657093","x-ratelimit-resource":"core","x-ratelimit-used":"124","x-xss-protection":"0"},"data":""}}

1 similar comment
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nAdds query-based retrieval and cursor support to the project keys listing endpoint. Introduces a new Keys query validator (allowed attributes: expire, accessedAt, name, scopes). Controller action signature updated to accept an array of queries; queries are parsed and validated, invalid queries or cursors produce query errors, and a valid cursor resolves to a key document for pagination. Filtering groups parsed queries and uses a filtered count for totals. Public imports updated for QueryException and Cursor. End-to-end tests expanded to exercise query filtering, cursor pagination, ordering, limits/offsets, and error cases.\n\n## Estimated code review effort\n\n🎯 4 (Complex) | ⏱️ ~45 minutes\n\n</details>\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n<details>\n<summary>❌ Failed checks (1 warning)</summary>\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n</details>\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                                                |\n| :---------------: | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|    Title check    | ✅ Passed | The title clearly describes the main change: adding a queries parameter to the list API keys endpoint.                                                     |\n| Description check | ✅ Passed | The description relates to the changeset by explaining that the PR adds queries parameter support to the API keys list endpoint, matching other endpoints. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> 📝 Generate docstrings\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `feat-list-api-keys-queries`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n\n---\n\nNo actionable comments were generated in the recent review. 🎉\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=appwrite/appwrite&utm_content=11278)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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= -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}},"response":{"url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","status":500,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-length":"0","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Mon, 09 Feb 2026 16:19:44 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"281F:3847D6:151A1A9:5B274E0:698A091E","x-ratelimit-limit":"12500","x-ratelimit-remaining":"12376","x-ratelimit-reset":"1770657093","x-ratelimit-resource":"core","x-ratelimit-used":"124","x-xss-protection":"0"},"data":""}}

@Meldiron Meldiron requested a review from Copilot February 10, 2026 10:45
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 10, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/appwrite/appwrite/issues/comments/3871894430","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nAdds query-based retrieval and cursor support to the project keys listing endpoint. Introduces a new Keys query validator (allowed attributes: expire, accessedAt, name, scopes). The controller action signature now accepts an array of queries; queries and cursor values are parsed and validated (invalid ones produce query errors), a valid cursor resolves to a key document for pagination, and grouped queries produce filters used for retrieval and filtered total counts. Adds QueryException and Cursor imports, a new error constant and mapping for key collisions, and expands end-to-end tests for queries, pagination, ordering, and error cases.\n\n## Estimated code review effort\n\n🎯 4 (Complex) | ⏱️ ~45 minutes\n\n</details>\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n<details>\n<summary>❌ Failed checks (1 warning)</summary>\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n</details>\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                                                                       |\n| :---------------: | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n|    Title check    | ✅ Passed | The title 'Feat: queries param on list api keys' directly and specifically describes the main change: adding queries parameter support to the API keys list endpoint.             |\n| Description check | ✅ Passed | The description clearly explains the PR purpose: adding queries parameter support to the API keys endpoint to align with other endpoints. It mentions tests and provides context. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> 📝 Generate docstrings\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `feat-list-api-keys-queries`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=appwrite/appwrite&utm_content=11278)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}}}

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tests/e2e/Services/Projects/ProjectsConsoleClientTest.php`:
- Around line 1233-1244: The placeholder comment "Ensure.. Something?" should be
replaced with a concrete assertion or removed: either assert the change
persisted by calling the project GET endpoint and checking the saved value (use
the same project id and verify returned ['body']['authDuration'] equals 600) or,
if persistence is already covered elsewhere, delete the comment; reference the
existing $response from the PATCH, the 'authDuration' field, and the client call
that modifies '/projects/' . $id . '/auth/duration'.
🧹 Nitpick comments (2)
tests/e2e/Services/Projects/ProjectsConsoleClientTest.php (2)

3146-3172: Assert the error type for duplicate custom key IDs.

You already check the 409; adding the error type/code will lock in the new mapping.

✅ Suggested assertion
         $this->assertEquals(409, $response['headers']['status-code']);
+        $this->assertEquals(409, $response['body']['code']);
+        $this->assertEquals(Exception::KEY_ALREADY_EXISTS, $response['body']['type']);

3233-3285: Make cursor pagination deterministic by adding explicit ordering.

The cursor-after expectation depends on the default order, which could change. Consider specifying an order in the query.

🔧 Example (adjust attribute if needed by validator)
         $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id . '/keys', array_merge([
             'content-type' => 'application/json',
             'x-appwrite-project' => $this->getProject()['$id'],
         ], $this->getHeaders()), [
             'queries' => [
+                Query::orderAsc('$createdAt')->toString(),
                 Query::cursorAfter(new Document(['$id' => $data['keyId']]))->toString(),
             ]
         ]);

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds SDK-style queries support to the Projects “List API Keys” endpoint (bringing it in line with other list endpoints), plus introduces a dedicated query validator and improves duplicate-key error handling. The PR also expands E2E coverage around project keys listing and custom key IDs.

Changes:

  • Add queries parameter support (filter/order/cursor/limit/offset) for GET /v1/projects/:projectId/keys and adjust total counting logic.
  • Introduce KEY_ALREADY_EXISTS error for duplicate key creation attempts.
  • Expand E2E tests for project keys querying and update session-duration test timing/behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/e2e/Services/Projects/ProjectsConsoleClientTest.php Adds E2E coverage for key list querying and duplicate key ID behavior; modifies auth duration test flow.
src/Appwrite/Utopia/Database/Validator/Queries/Keys.php New queries validator defining allowed filter attributes for keys listing.
src/Appwrite/Extend/Exception.php Adds new KEY_ALREADY_EXISTS exception constant.
app/controllers/api/projects.php Adds queries param and cursor handling to list keys endpoint; maps duplicate key creation to a new exception.
app/config/errors.php Registers KEY_ALREADY_EXISTS as a 409 error with message/description.
Comments suppressed due to low confidence (1)

tests/e2e/Services/Projects/ProjectsConsoleClientTest.php:1249

  • The // Ensure.. Something? comment reads like a placeholder and the following assertion only checks the expired session remains invalid after increasing authDuration. If the goal is to validate the new 10-minute duration, create a new session after updating the project setting and assert it stays valid after a short wait (and/or does not expire within a reasonable window).
        // Ensure.. Something?
        $response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
            'content-type' => 'application/json',
            'x-appwrite-project' => $projectId,
            'Cookie' => $sessionCookie,
        ]));

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1207 to 1214
$filterQueries = Query::groupByType($queries)['filters'];

$keys = $dbForPlatform->find('keys', $queries);

$response->dynamic(new Document([
'keys' => $keys,
'total' => $includeTotal ? count($keys) : 0,
'total' => $includeTotal ? $dbForPlatform->count('keys', $filterQueries, APP_LIMIT_COUNT) : 0,
]), Response::MODEL_KEY_LIST);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find('keys', $queries) can throw an OrderException when a client uses cursor pagination with an order attribute that has null values (e.g. ordering by expire/accessedAt). Other list endpoints catch this and return DATABASE_QUERY_ORDER_NULL, but this handler currently lets the exception bubble. Wrap the find/count calls in a try/catch and map OrderException to a consistent Appwrite exception (and add the corresponding import).

Copilot uses AI. Check for mistakes.
Comment on lines +1185 to +1187
$queries[] = Query::equal('resourceType', ['projects']);
$queries[] = Query::equal('resourceInternalId', [$project->getSequence()]);

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint previously forced Query::limit(5000) (returning up to 5000 keys). After switching to SDK-style queries, no default limit is applied, so the number of returned keys now depends on the database default limit and may be a behavioral/breaking change for callers. If backward compatibility is desired, consider appending a default limit when the client does not supply one.

Copilot uses AI. Check for mistakes.
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cursor pagination assertion is brittle: using cursorAfter without an explicit order* query relies on the API's implicit sort order, and this test creates a mix of custom IDs and generated IDs that may not sort consistently. Add an explicit order (e.g. $sequence) alongside the cursor query, and base expectations on that deterministic ordering.

Suggested change
'queries' => [
'queries' => [
Query::orderAsc('$sequence')->toString(),

Copilot uses AI. Check for mistakes.
@Meldiron Meldiron merged commit 51f0364 into 1.8.x Feb 10, 2026
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants