Skip to content

Add API key migration support#183

Open
premtsd-code wants to merge 13 commits into
mainfrom
add-api-key-migration
Open

Add API key migration support#183
premtsd-code wants to merge 13 commits into
mainfrom
add-api-key-migration

Conversation

@premtsd-code
Copy link
Copy Markdown
Contributor

Summary

  • Adds API key migration support for the Appwrite source/destination (new ApiKey resource, source export via console headers, destination import).
  • Adds platform migration support (new Platform resource).
  • Pulls in feat-platform-db-access (PR Add platform migration support #154), which switches platform listing/export from console-key HTTP calls to the Project SDK service with buildQueries.

Notes

  • Platforms no longer require console headers — they go through projectService->listPlatforms / exportPlatforms($batchSize).
  • API keys still require console headers and continue to use the exportWithConsoleHeaders wrapper.
  • Stacks on top of the platform-db-access work; if PR Add platform migration support #154 lands first, this diff will shrink accordingly.

Test plan

  • composer install && composer test (vendor not present in worktree — please run locally)
  • composer lint && composer format
  • E2E: migrate a project with API keys + platforms from one Appwrite instance to another, verify both arrive
  • Verify report totals for apiKey and platform resource types

…d-api-key-migration

# Conflicts:
#	src/Migration/Destinations/Appwrite.php
#	src/Migration/Sources/Appwrite.php
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR adds ApiKey and Platform resource support to the Appwrite migration adapters, wiring up export (source), import (destination), reporting, and registration in Transfer and Resource. Platform export is refactored to use the Project SDK service instead of console-key HTTP calls.

  • ApiKey resource class (Resources/Integrations/ApiKey.php): new model with cursor-paginated export via Project::listKeys, deduplication by name in the destination, and a freshly-generated secret on import (original secret is intentionally not preserved).
  • Source export (Sources/Appwrite.php): exportApiKeys implements the same cursor-based pagination loop as exportPlatforms; reportIntegrations is extended to count keys via listKeys(...)->total.
  • Destination import (Destinations/Appwrite.php): createApiKey writes directly to the platform DB, follows the createPlatform pattern for permissions, timestamps, and cache invalidation, and catches DuplicateException for graceful skipping.

Confidence Score: 3/5

Not safe to merge until the known unresolved null-safety bugs are fixed; every real-world key without an expiry date or that has never been accessed will throw a TypeError and fail export entirely.

The export loop in Sources/Appwrite.php passes $key->expire and $key->accessedAt directly from the Appwrite SDK response into the ApiKey constructor, which declares both parameters as non-nullable string. The SDK returns null for both fields on keys with no expiry and keys that have never been used — both are extremely common in production projects. A TypeError thrown inside the pagination loop halts the entire export of API keys. This was identified in a previous review round but the constructor types and the construction site were not updated to apply the same ?? '' guard that fromArray already uses.

src/Migration/Sources/Appwrite.php (exportApiKeys construction site) and src/Migration/Resources/Integrations/ApiKey.php (constructor parameter types for expire and accessedAt)

Important Files Changed

Filename Overview
src/Migration/Resources/Integrations/ApiKey.php New ApiKey resource class; constructor declares expire and accessedAt as non-nullable strings but SDK can return null for both fields, causing TypeError at runtime for most real-world keys
src/Migration/Sources/Appwrite.php Adds exportApiKeys with correct cursor-based pagination; passes nullable SDK fields directly to a non-nullable constructor which throws TypeError for keys with no expiry or that have never been used
src/Migration/Destinations/Appwrite.php Adds createApiKey writing to the platform DB; uses correct string $this->project for resourceId, generates a fresh secret, and follows the same deduplication and cache-purge pattern as createPlatform
src/Migration/Resource.php Adds TYPE_API_KEY constant ('api-key') and registers it in ALL_RESOURCES; consistent with existing hyphenated type names
src/Migration/Transfer.php Registers TYPE_API_KEY in GROUP_INTEGRATIONS_RESOURCES and the resource ordering/whitelist arrays; changes are additive and consistent
tests/Migration/Unit/Adapters/MockDestination.php Adds TYPE_API_KEY to mock's supported resources list; correct and minimal change
tests/Migration/Unit/Adapters/MockSource.php Adds TYPE_API_KEY to mock source's supported resources list; correct and minimal change

Reviews (8): Last reviewed commit: "Pass through resource permissions to cre..." | Re-trigger Greptile

Comment thread src/Migration/Sources/Appwrite.php Outdated
Comment thread src/Migration/Sources/Appwrite.php Outdated
Comment thread src/Migration/Sources/Appwrite.php Outdated
Comment thread src/Migration/Destinations/Appwrite.php Outdated
Source uses Project SDK (listKeys with cursor pagination); destination
writes keys directly via dbForPlatform, matching the platform pattern.
Comment thread src/Migration/Destinations/Appwrite.php Outdated
$this->headers/endpoint/key were only read by the inherited call() method
which the destination no longer invokes. STATUS_ERROR is never set inside
createPlatform/createApiKey (they throw), so the guard only needs SKIPPED.
Reverting the wider cleanup — those properties are part of the
inherited Target surface, not the headers issue under review.
Matches the existing platform pattern. Source-side SDK Key model doesn't
expose $permissions today so this is [] in practice (same as platforms),
but the hook is in place for when source can populate it.
SDK strips $permissions from Key responses so we can't copy from source;
match the upstream createKey controller default since dbForPlatform.keys
is gated by endpoint scope, not document perms.
Comment thread src/Migration/Sources/Appwrite.php
Drop the endpoint-scope tangent — the comment is about why we picked
this value, not about whether doc perms get enforced.
projectInternalId is a written-but-not-queryable legacy column on the
keys collection (upstream filter uses resourceInternalId + resourceType).
Mirror that here so the duplicate-check find() doesn't error out.
Drop the removed projectInternalId/projectId legacy fields and use
empty permissions, matching the current server-ce Project/Keys/Create
action exactly.
Mirror createPlatform's pattern. Resolves to [] today since the SDK
doesn't expose $permissions on Key responses, matching the upstream
createKey endpoint default. Hook is in place if/when the SDK starts
emitting permissions.
@premtsd-code premtsd-code changed the title Add API key and platform migration support Add API key migration support May 14, 2026
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.

1 participant