Feat/project onboarding stages#3
Conversation
Add configurable onboarding stages keyed by SDK method, persist completion in project onboarding JSON on successful API responses, and expose listStages and updateStage routes with stages.read/write scopes and stage/stageList models. Made-with: Cursor
Emit console realtime when onboarding stages complete in API shutdown. Add Project/StagesBase + StagesConsoleClientTest following Platforms pattern. Made-with: Cursor
Made-with: Cursor
Policy Check Failed✗ 3/3 policy checks failed: • Need 2 more approval(s) (0/2) — comment LGTM or approve via review To merge this PR:
|
PR SummaryWhat Changed
Key Changes by AreaAPI: New endpoints Data Model: Automation: Hook in Files Changed
Review Focus Areas
ArchitectureDesign Decisions: Automatic completion uses a centralized hook rather than per-endpoint changes. This keeps SDK methods clean but couples completion logic to API controller internals. The Scalability & Extensibility: Stage definitions are config-driven ( Risks: Hook-based auto-completion may miss edge cases (async operations, partial failures). Intentional: JSON field limits queryability of stage status. Unintentional: No cleanup if SDK call succeeds but subsequent operation fails. Merge StatusNOT MERGEABLE — PR Score 55/100, below threshold (50)
|
| 'at' => DateTime::now(), | ||
| 'actorType' => $this->resolveActorType($apiKey, $user, $mode), | ||
| ]; | ||
| $project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('onboarding', $byStageId)); |
There was a problem hiding this comment.
After a stage is skipped, a successful API call that matches that stage (for example PATCH /v1/projects/{id}/stages/create_database with skip=true followed by creating a database) will never mark it completed because the shutdown hook in app/controllers/shared/api.php now treats skipped as terminal.
Change the shared API hook to only preserve COMPLETED as terminal, or add explicit logic here to let real route completion overwrite SKIPPED with COMPLETED when the mapped SDK action later succeeds.
Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert php developer with deep knowledge of security, performance, and best practices.
### Context
File: src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php
Lines: 90-90
Issue Type: functional-medium
Severity: medium
Issue Description:
After a stage is skipped, a successful API call that matches that stage (for example PATCH /v1/projects/{id}/stages/create_database with skip=true followed by creating a database) will never mark it completed because the shutdown hook in app/controllers/shared/api.php now treats skipped as terminal.
Current Code:
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('onboarding', $byStageId));
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow php best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
Security Scan Summary
No critical security issues detected Scan completed in 34.6sSecurity scan powered by Codity.ai |
Greptile SummaryThis PR introduces a project onboarding system with three stages (
Confidence Score: 2/5Not safe to merge — the shutdown hook change corrupts realtime event delivery for all project-API calls that trigger a stage, and the missing migration would break existing deployments on upgrade. Two independent defects affect core infrastructure paths: the
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client
participant API as API Route Handler
participant Shutdown as Shutdown Hook
participant DB as dbForPlatform
participant RT as Realtime Queue
Client->>API: POST /databases (or similar SDK method)
API->>DB: create document
API->>RT: setEvent(databases.[id].create)
API-->>Shutdown: hand off
Shutdown->>Shutdown: check 2xx and not console project
Shutdown->>Shutdown: match sdkLabel to stageId
Shutdown->>DB: updateDocument(projects, onboarding)
Shutdown->>RT: reset()
Shutdown->>RT: setSubscribers(['console']) + setEvent(stage.complete)
Shutdown->>RT: trigger() — stage-complete event fires
Note over Shutdown,RT: subscribers stays ['console']
Shutdown->>RT: from(queueForEvents) — does NOT reset subscribers
Shutdown->>RT: trigger() — main event sent to console only
Client->>API: GET /v1/projects/:id/stages
API->>DB: getDocument(projects, projectId)
DB-->>API: project with onboarding map
API-->>Client: Stage list
Client->>API: PATCH /v1/projects/:id/stages/:stageId
API->>DB: getDocument + updateDocument (SKIPPED)
API-->>Client: Stage object
|
| '$id' => ID::custom('onboarding'), | ||
| 'type' => Database::VAR_STRING, | ||
| 'format' => '', | ||
| 'size' => 65536, | ||
| 'signed' => true, | ||
| 'required' => false, | ||
| 'default' => [], | ||
| 'array' => false, | ||
| 'filters' => ['json'], | ||
| ], |
There was a problem hiding this comment.
No database migration for the new
onboarding attribute
The onboarding attribute is added to the platform.php schema definition, but this PR does not include a corresponding migration class (e.g., V25.php). Existing deployments that upgrade will not have the onboarding column in their projects collection. Any attempt by the shutdown hook or the Update endpoint to call updateDocument('projects', …, new Document(['onboarding' => …])) on an upgraded installation will fail at the database layer. New fresh installs are unaffected because platform.php is consumed at collection-creation time, not on upgrade.
| )) | ||
| ->param('projectId', '', new UID(), 'Project unique ID.') | ||
| ->param('stageId', '', new Text(64), 'Stage ID.') | ||
| ->param('skip', true, new Boolean(), 'Mark the stage as skipped.', true) |
There was a problem hiding this comment.
The
skip parameter defaults to true, meaning a PATCH request sent with no body will silently skip the stage. This is a destructive default; callers who forget to include the body (or who intend a no-op read) will permanently mark stages as skipped. Defaulting to false preserves the current status unless the caller explicitly opts in.
| ->param('skip', true, new Boolean(), 'Mark the stage as skipped.', true) | |
| ->param('skip', false, new Boolean(), 'Mark the stage as skipped.', true) |
Dependency vulnerability scanning
View vulnerability details (9 items)1. phpseclib/phpseclib 3.0.51 CVE: GHSA-3qpq-r242-jqj7
2. webonyx/graphql-php 14.11.10 CVE: GHSA-68jq-c3rv-pcrr
3. webonyx/graphql-php 14.11.10 CVE: GHSA-fc86-6rv6-2jpm
4. webonyx/graphql-php 14.11.10 CVE: GHSA-r7cg-qjjm-xhqq
5. twig/twig 3.14.2 CVE: GHSA-24x9-r6q4-q93w
6. twig/twig 3.14.2 CVE: GHSA-4j38-f5cw-54h7
7. twig/twig 3.14.2 CVE: GHSA-7fxw-r6jv-74c8
8. twig/twig 3.14.2 CVE: GHSA-7p85-w9px-jpjp
9. twig/twig 3.14.2 CVE: GHSA-vcc8-phrv-43wj
Powered by Codity.ai · Docs |
License Compliance Scan
Strong copyleft licenses detected - review before merging Weak copyleft licenses found - verify compatibility Some packages have unknown licenses - manual review required High Risk Licenses - 1 packagesGPL-2.0-or-later (1 packages):
Medium Risk Licenses - 17 packagesApache-2.0 AND LGPL-3.0-or-later (3 packages):
Apache-2.0 AND LGPL-3.0-or-later AND MIT (1 packages):
LGPL-2.1-only (1 packages):
LGPL-2.1-or-later (1 packages):
LGPL-3.0-or-later (11 packages):
Unknown Licenses - 4 packages
Powered by Codity.ai · Docs |
Code Quality Report — test-org-codity/appwrite · PR #3Scanned: 2026-05-23 09:10 UTC | Score: 29/100 | Provider: github Executive Summary
Top Findings[CQ-LLM-001]
|
| File | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
app/config/collections/platform.php |
0 | 0 | 0 | 1 | 1 |
app/controllers/shared/api.php |
0 | 1 | 2 | 43 | 46 |
app/init/configs.php |
0 | 0 | 0 | 1 | 1 |
app/init/constants.php |
0 | 0 | 0 | 1 | 1 |
app/init/models.php |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/list-stages.md |
0 | 0 | 0 | 1 | 2 |
docs/references/projects/update-stage.md |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php |
0 | 0 | 0 | 10 | 10 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/XList.php |
0 | 0 | 0 | 4 | 4 |
src/Appwrite/Utopia/Response/Model/Project.php |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Utopia/Response/Model/Stage.php |
0 | 0 | 0 | 1 | 1 |
tests/e2e/Services/Project/StagesBase.php |
0 | 0 | 0 | 12 | 12 |
Recommendations
- Resolve High severity issues, especially error handling gaps and performance bottlenecks.
- Run automated tests after applying fixes to verify no regressions.
|
@codity review |
Policy Check Failed✗ 3/3 policy checks failed: • Need 2 more approval(s) (0/2) — comment LGTM or approve via review To merge this PR:
|
PR SummaryWhat Changed
Key Changes by AreaAPI: Added Data Model: New Auto-Completion: Hook in Files Changed
Review Focus Areas
ArchitectureDesign Decisions: Chose JSON field over separate collection to avoid join complexity and keep reads fast. Stage-to-SDK mapping is hardcoded in config for simplicity. Intentionally no migration for existing projects: they start with empty onboarding state. Scalability & Extensibility: Adding new stages requires config change only. Out of scope: webhooks on stage change, progress percentages, or per-user (vs per-project) tracking. Risks: Hook runs on every API call. Monitor latency impact. Actor type detection relies on request context which may be incomplete for internal/service calls. Merge StatusNOT MERGEABLE — PR Score 43/100, below threshold (50)
|
| : (! $user->isEmpty() | ||
| ? ($mode === APP_MODE_ADMIN ? ACTIVITY_TYPE_ADMIN : ACTIVITY_TYPE_USER) | ||
| : ACTIVITY_TYPE_GUEST); | ||
| $byStageId[$stageId] = [ |
There was a problem hiding this comment.
After PATCH /v1/projects/{projectId}/stages/create_database with {"skip":true}, a later successful databases.create call still overwrites that skipped stage to completed because this hook updates the stale $project snapshot instead of reloading onboarding state first.
Before computing $done and writing completion, reload the current project document from dbForPlatform (or perform a conditional/merge update) so an already-skipped stage is not reverted by a later request using an older injected $project instance.
Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert php developer with deep knowledge of security, performance, and best practices.
### Context
File: app/controllers/shared/api.php
Lines: 846-846
Issue Type: functional-high
Severity: high
Issue Description:
After PATCH /v1/projects/{projectId}/stages/create_database with {"skip":true}, a later successful databases.create call still overwrites that skipped stage to completed because this hook updates the stale $project snapshot instead of reloading onboarding state first.
Current Code:
$byStageId[$stageId] = [
'status' => ONBOARDING_STATUS_COMPLETED,
'at' => DateTime::now(),
'actorType' => $actorType,
];
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow php best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
| if ($skip) { | ||
| $prev = \is_array($row) ? ($row['status'] ?? '') : ''; | ||
| if ($prev !== ONBOARDING_STATUS_COMPLETED) { | ||
| $byStageId[$stageId] = [ | ||
| 'status' => ONBOARDING_STATUS_SKIPPED, | ||
| 'at' => DateTime::now(), | ||
| 'actorType' => $this->resolveActorType($apiKey, $user, $mode), | ||
| ]; | ||
| $project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('onboarding', $byStageId)); |
There was a problem hiding this comment.
This update reads and writes the project without an atomic compare or transaction, so a concurrent successful stage completion can be overwritten with skipped; re-read under a lock or perform a conditional update that preserves completed.
Suggested fix
if ($skip) {
$project = $dbForPlatform->getDocument('projects', $projectId);
$byStageId = $project->getAttribute('onboarding', []);
if (! \is_array($byStageId)) {
$byStageId = [];
}
$row = \is_array($byStageId[$stageId] ?? null) ? $byStageId[$stageId] : null;
$prev = \is_array($row) ? ($row['status'] ?? '') : '';
if ($prev !== ONBOARDING_STATUS_COMPLETED) {
$byStageId[$stageId] = [
'status' => ONBOARDING_STATUS_SKIPPED,
'at' => DateTime::now(),
'actorType' => $this->resolveActorType($apiKey, $user, $mode),
];
$project = $dbForPlatform->updateDocument('projects', $project->getId(), new Document([
'onboarding' => $byStageId,
]));
}
}Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert php developer with deep knowledge of security, performance, and best practices.
### Context
File: src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php
Lines: 82-90
Issue Type: security-high
Severity: high
Issue Description:
This update reads and writes the project without an atomic compare or transaction, so a concurrent successful stage completion can be overwritten with `skipped`; re-read under a lock or perform a conditional update that preserves `completed`.
Current Code:
if ($skip) {
$prev = \is_array($row) ? ($row['status'] ?? '') : '';
if ($prev !== ONBOARDING_STATUS_COMPLETED) {
$byStageId[$stageId] = [
'status' => ONBOARDING_STATUS_SKIPPED,
'at' => DateTime::now(),
'actorType' => $this->resolveActorType($apiKey, $user, $mode),
];
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project->setAttribute('onboarding', $byStageId));
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow php best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
Security Scan Summary
No critical security issues detected Scan completed in 53.2sSecurity scan powered by Codity.ai |
Dependency vulnerability scanning
View vulnerability details (9 items)1. phpseclib/phpseclib 3.0.51 CVE: GHSA-3qpq-r242-jqj7
2. webonyx/graphql-php 14.11.10 CVE: GHSA-68jq-c3rv-pcrr
3. webonyx/graphql-php 14.11.10 CVE: GHSA-fc86-6rv6-2jpm
4. webonyx/graphql-php 14.11.10 CVE: GHSA-r7cg-qjjm-xhqq
5. twig/twig 3.14.2 CVE: GHSA-24x9-r6q4-q93w
6. twig/twig 3.14.2 CVE: GHSA-4j38-f5cw-54h7
7. twig/twig 3.14.2 CVE: GHSA-7fxw-r6jv-74c8
8. twig/twig 3.14.2 CVE: GHSA-7p85-w9px-jpjp
9. twig/twig 3.14.2 CVE: GHSA-vcc8-phrv-43wj
Powered by Codity.ai · Docs |
License Compliance Scan
Strong copyleft licenses detected - review before merging Weak copyleft licenses found - verify compatibility Some packages have unknown licenses - manual review required High Risk Licenses - 1 packagesGPL-2.0-or-later (1 packages):
Medium Risk Licenses - 17 packagesApache-2.0 AND LGPL-3.0-or-later (3 packages):
Apache-2.0 AND LGPL-3.0-or-later AND MIT (1 packages):
LGPL-2.1-only (1 packages):
LGPL-2.1-or-later (1 packages):
LGPL-3.0-or-later (11 packages):
Unknown Licenses - 4 packages
Powered by Codity.ai · Docs |
Code Quality Report — test-org-codity/appwrite · PR #3Scanned: 2026-05-23 09:32 UTC | Score: 29/100 | Provider: github Executive Summary
Top Findings[CQ-LLM-001]
|
| File | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
app/config/collections/platform.php |
0 | 0 | 0 | 1 | 1 |
app/controllers/shared/api.php |
0 | 1 | 2 | 43 | 46 |
app/init/configs.php |
0 | 0 | 0 | 1 | 1 |
app/init/constants.php |
0 | 0 | 0 | 1 | 1 |
app/init/models.php |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/list-stages.md |
0 | 0 | 0 | 1 | 2 |
docs/references/projects/update-stage.md |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php |
0 | 0 | 0 | 10 | 10 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/XList.php |
0 | 0 | 0 | 4 | 4 |
src/Appwrite/Utopia/Response/Model/Project.php |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Utopia/Response/Model/Stage.php |
0 | 0 | 0 | 1 | 1 |
tests/e2e/Services/Project/StagesBase.php |
0 | 0 | 0 | 12 | 12 |
Recommendations
- Resolve High severity issues, especially error handling gaps and performance bottlenecks.
- Run automated tests after applying fixes to verify no regressions.
|
@codity review |
Policy Check Failed✗ 3/3 policy checks failed: • Need 2 more approval(s) (0/2) — comment LGTM or approve via review To merge this PR:
|
PR SummaryWhat Changed
Key Changes by AreaDatabase: Added API: New endpoints in Permissions: New Models: Added Config: New Files Changed
Review Focus Areas
ArchitectureDesign Decisions: Chose JSON column over normalized table to keep stage definitions flexible and avoid migrations when adding new stages. Auto-completion uses response interception rather than service-level hooks to minimize code changes across multiple services. Risks: JSON column limits queryability of stage history. This is intentional (stages are per-project, not queried across projects). Actor type tracking (user/admin/key) relies on request context availability in shared API hook. Verify this holds for all SDK paths, including server-side and CLI usage. |
| if (! \is_array($byStageId)) { | ||
| $byStageId = []; | ||
| } | ||
| $done = \is_array($byStageId[$stageId] ?? null) ? ($byStageId[$stageId]['status'] ?? '') : ''; |
There was a problem hiding this comment.
After a client skips stage create_database via PATCH /v1/projects/{projectId}/stages/create_database, the next successful POST /v1/databases still overwrites that skipped row to completed, breaking the cross-endpoint contract that skipped stages remain skipped.
Before marking a route-derived stage complete, reload the latest project document from dbForPlatform and honor any existing skipped status, or make the stage update endpoint and shutdown hook use a shared compare-and-swap helper to prevent stale in-memory $project data from overriding prior writes.
Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert php developer with deep knowledge of security, performance, and best practices.
### Context
File: app/controllers/shared/api.php
Lines: 834-834
Issue Type: functional-medium
Severity: medium
Issue Description:
After a client skips stage `create_database` via `PATCH /v1/projects/{projectId}/stages/create_database`, the next successful `POST /v1/databases` still overwrites that skipped row to `completed`, breaking the cross-endpoint contract that skipped stages remain skipped.
Current Code:
$done = \is_array($byStageId[$stageId] ?? null) ? ($byStageId[$stageId]['status'] ?? '') : '';
if ($done !== ONBOARDING_STATUS_COMPLETED && $done !== ONBOARDING_STATUS_SKIPPED) {
$actorType = ($apiKey !== null && $apiKey->getRole() === User::ROLE_APPS)
? match ($apiKey->getType()) {
API_KEY_ACCOUNT => ACTIVITY_TYPE_KEY_ACCOUNT,
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow php best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
Security Scan Summary
No critical security issues detected Scan completed in 38.2sSecurity scan powered by Codity.ai |
Dependency vulnerability scanning
View vulnerability details (9 items)1. phpseclib/phpseclib 3.0.51 CVE: GHSA-3qpq-r242-jqj7
2. webonyx/graphql-php 14.11.10 CVE: GHSA-68jq-c3rv-pcrr
3. webonyx/graphql-php 14.11.10 CVE: GHSA-fc86-6rv6-2jpm
4. webonyx/graphql-php 14.11.10 CVE: GHSA-r7cg-qjjm-xhqq
5. twig/twig 3.14.2 CVE: GHSA-24x9-r6q4-q93w
6. twig/twig 3.14.2 CVE: GHSA-4j38-f5cw-54h7
7. twig/twig 3.14.2 CVE: GHSA-7fxw-r6jv-74c8
8. twig/twig 3.14.2 CVE: GHSA-7p85-w9px-jpjp
9. twig/twig 3.14.2 CVE: GHSA-vcc8-phrv-43wj
Powered by Codity.ai · Docs |
License Compliance Scan
Strong copyleft licenses detected - review before merging Weak copyleft licenses found - verify compatibility Some packages have unknown licenses - manual review required High Risk Licenses - 1 packagesGPL-2.0-or-later (1 packages):
Medium Risk Licenses - 17 packagesApache-2.0 AND LGPL-3.0-or-later (3 packages):
Apache-2.0 AND LGPL-3.0-or-later AND MIT (1 packages):
LGPL-2.1-only (1 packages):
LGPL-2.1-or-later (1 packages):
LGPL-3.0-or-later (11 packages):
Unknown Licenses - 4 packages
Powered by Codity.ai · Docs |
Code Quality Report — test-org-codity/appwrite · PR #3Scanned: 2026-05-23 09:54 UTC | Score: 29/100 | Provider: github Executive Summary
Top Findings[CQ-LLM-001]
|
| File | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
app/config/collections/platform.php |
0 | 0 | 0 | 1 | 1 |
app/controllers/shared/api.php |
0 | 1 | 2 | 43 | 46 |
app/init/configs.php |
0 | 0 | 0 | 1 | 1 |
app/init/constants.php |
0 | 0 | 0 | 1 | 1 |
app/init/models.php |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/list-stages.md |
0 | 0 | 0 | 1 | 2 |
docs/references/projects/update-stage.md |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php |
0 | 0 | 0 | 10 | 10 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/XList.php |
0 | 0 | 0 | 4 | 4 |
src/Appwrite/Utopia/Response/Model/Project.php |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Utopia/Response/Model/Stage.php |
0 | 0 | 0 | 1 | 1 |
tests/e2e/Services/Project/StagesBase.php |
0 | 0 | 0 | 12 | 12 |
Recommendations
- Resolve High severity issues, especially error handling gaps and performance bottlenecks.
- Run automated tests after applying fixes to verify no regressions.
Merge StatusNOT MERGEABLE — PR Score 41/100, below threshold (50)
|
|
@codity review |
Policy Check Failed✗ 3/3 policy checks failed: • Need 2 more approval(s) (0/2) — comment LGTM or approve via review To merge this PR:
|
|
PR review started! Estimated time: 5-10 minutes. Custom Review Instructions Detectedsource: context file (CLAUDE.md / .cursorrules)
@AGENTS.md
Learn MoreAsk Codity questions: Mention Trigger a manual review: Comment Generate unit tests: Comment Run security scan again: Comment |
|
@codity review |
PR SummaryWhat Changed
Key Changes by AreaDatabase: Added Configuration: Created API: New endpoints in Models: Added Authorization: New Files Changed
Review Focus Areas
Architecture
Merge StatusNOT MERGEABLE — PR Score 39/100, below threshold (50)
|
| if ($skip) { | ||
| $prev = \is_array($row) ? ($row['status'] ?? '') : ''; | ||
| if ($prev !== ONBOARDING_STATUS_COMPLETED) { | ||
| $byStageId[$stageId] = [ |
There was a problem hiding this comment.
After a client skips a stage via PATCH /v1/projects/{projectId}/stages/{stageId}, the later successful API call for that stage (for example creating a database) never flips it to completed because the shutdown hook in app/controllers/shared/api.php explicitly refuses to overwrite skipped status.
| $byStageId[$stageId] = [ | |
| Either allow the shutdown hook to transition skipped -> completed when the mapped SDK action succeeds, or persist a distinct "dismissed" state for manual skips that does not block later automatic completion. |
Prompt for AI assistance
Copy the prompt below and paste it into ChatGPT, Claude, or any LLM:
You are an expert php developer with deep knowledge of security, performance, and best practices.
### Context
File: src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php
Lines: 85-85
Issue Type: functional-medium
Severity: medium
Issue Description:
After a client skips a stage via PATCH /v1/projects/{projectId}/stages/{stageId}, the later successful API call for that stage (for example creating a database) never flips it to completed because the shutdown hook in app/controllers/shared/api.php explicitly refuses to overwrite skipped status.
Current Code:
$byStageId[$stageId] = [
'status' => ONBOARDING_STATUS_SKIPPED,
'at' => DateTime::now(),
'actorType' => $this->resolveActorType($apiKey, $user, $mode),
];
---
### Instructions
1. Fix the issue described above
2. Maintain the exact indentation and code style from the original
3. Follow php best practices and language-specific idioms
4. Ensure the fix addresses the root cause, not just the symptoms
5. Add brief inline comments explaining the fix if needed
### Constraints
- Do not change functionality beyond fixing the identified issue
- Preserve existing variable names and function signatures unless they are part of the problem
- Ensure the fix is production-ready
---
Security Scan Summary
No critical security issues detected Scan completed in 33.0sSecurity scan powered by Codity.ai |
Dependency vulnerability scanning
View vulnerability details (9 items)1. phpseclib/phpseclib 3.0.51 CVE: GHSA-3qpq-r242-jqj7
2. webonyx/graphql-php 14.11.10 CVE: GHSA-68jq-c3rv-pcrr
3. webonyx/graphql-php 14.11.10 CVE: GHSA-fc86-6rv6-2jpm
4. webonyx/graphql-php 14.11.10 CVE: GHSA-r7cg-qjjm-xhqq
5. twig/twig 3.14.2 CVE: GHSA-24x9-r6q4-q93w
6. twig/twig 3.14.2 CVE: GHSA-4j38-f5cw-54h7
7. twig/twig 3.14.2 CVE: GHSA-7fxw-r6jv-74c8
8. twig/twig 3.14.2 CVE: GHSA-7p85-w9px-jpjp
9. twig/twig 3.14.2 CVE: GHSA-vcc8-phrv-43wj
Powered by Codity.ai · Docs |
License Compliance Scan
Strong copyleft licenses detected - review before merging Weak copyleft licenses found - verify compatibility Some packages have unknown licenses - manual review required High Risk Licenses - 1 packagesGPL-2.0-or-later (1 packages):
Medium Risk Licenses - 17 packagesApache-2.0 AND LGPL-3.0-or-later (3 packages):
Apache-2.0 AND LGPL-3.0-or-later AND MIT (1 packages):
LGPL-2.1-only (1 packages):
LGPL-2.1-or-later (1 packages):
LGPL-3.0-or-later (11 packages):
Unknown Licenses - 4 packages
Powered by Codity.ai · Docs |
Code Quality Report — test-org-codity/appwrite · PR #3Scanned: 2026-05-23 10:27 UTC | Score: 29/100 | Provider: github Executive Summary
Top Findings[CQ-LLM-001]
|
| File | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
app/config/collections/platform.php |
0 | 0 | 0 | 1 | 1 |
app/controllers/shared/api.php |
0 | 1 | 2 | 43 | 47 |
app/init/configs.php |
0 | 0 | 0 | 1 | 1 |
app/init/constants.php |
0 | 0 | 0 | 1 | 1 |
app/init/models.php |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/list-stages.md |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/update-stage.md |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php |
0 | 0 | 0 | 10 | 10 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/XList.php |
0 | 0 | 0 | 4 | 4 |
src/Appwrite/Utopia/Response/Model/Project.php |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Utopia/Response/Model/Stage.php |
0 | 0 | 0 | 1 | 1 |
tests/e2e/Services/Project/StagesBase.php |
0 | 0 | 0 | 12 | 12 |
Recommendations
- Resolve High severity issues, especially error handling gaps and performance bottlenecks.
- Run automated tests after applying fixes to verify no regressions.
|
@codity review |
Policy Check Failed✗ 3/3 policy checks failed: • Need 2 more approval(s) (0/2) — comment LGTM or approve via review To merge this PR:
|
PR SummaryWhat Changed
Key Changes by AreaAPI: Added Data Model: Added Permissions: New Auto-Completion: Hook in Files Changed
Review Focus Areas
ArchitectureDesign Decisions: Stages are stored as JSON in the project document rather than a separate collection. This keeps reads fast and avoids joins. The tradeoff is limited queryability of stage history. Scalability & Extensibility: Actor type tracking (user/admin/API key/guest) supports future audit requirements. New stages require config changes only, no schema migrations. Risks: The auto-completion hook runs on every SDK method call. This is intentional but adds overhead to hot paths. The Merge StatusNOT MERGEABLE — PR Score 40/100, below threshold (50)
|
Security Scan Summary
No critical security issues detected Scan completed in 33.4sSecurity scan powered by Codity.ai |
Dependency vulnerability scanning
View vulnerability details (9 items)1. phpseclib/phpseclib 3.0.51 CVE: GHSA-3qpq-r242-jqj7
2. webonyx/graphql-php 14.11.10 CVE: GHSA-68jq-c3rv-pcrr
3. webonyx/graphql-php 14.11.10 CVE: GHSA-fc86-6rv6-2jpm
4. webonyx/graphql-php 14.11.10 CVE: GHSA-r7cg-qjjm-xhqq
5. twig/twig 3.14.2 CVE: GHSA-24x9-r6q4-q93w
6. twig/twig 3.14.2 CVE: GHSA-4j38-f5cw-54h7
7. twig/twig 3.14.2 CVE: GHSA-7fxw-r6jv-74c8
8. twig/twig 3.14.2 CVE: GHSA-7p85-w9px-jpjp
9. twig/twig 3.14.2 CVE: GHSA-vcc8-phrv-43wj
Powered by Codity.ai · Docs |
License Compliance Scan
Strong copyleft licenses detected - review before merging Weak copyleft licenses found - verify compatibility Some packages have unknown licenses - manual review required High Risk Licenses - 1 packagesGPL-2.0-or-later (1 packages):
Medium Risk Licenses - 17 packagesApache-2.0 AND LGPL-3.0-or-later (3 packages):
Apache-2.0 AND LGPL-3.0-or-later AND MIT (1 packages):
LGPL-2.1-only (1 packages):
LGPL-2.1-or-later (1 packages):
LGPL-3.0-or-later (11 packages):
Unknown Licenses - 4 packages
Powered by Codity.ai · Docs |
Code Quality Report — test-org-codity/appwrite · PR #3Scanned: 2026-05-23 12:11 UTC | Score: 30/100 | Provider: github Executive Summary
Top Findings[CQ-LLM-001]
|
| File | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
app/config/collections/platform.php |
0 | 0 | 0 | 1 | 1 |
app/controllers/shared/api.php |
0 | 1 | 2 | 44 | 47 |
app/init/configs.php |
0 | 0 | 0 | 1 | 1 |
app/init/models.php |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/list-stages.md |
0 | 0 | 0 | 1 | 1 |
docs/references/projects/update-stage.md |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/Update.php |
0 | 0 | 0 | 10 | 10 |
src/Appwrite/Platform/Modules/Projects/Http/Stages/XList.php |
0 | 0 | 0 | 4 | 4 |
src/Appwrite/Utopia/Response/Model/Project.php |
0 | 0 | 0 | 1 | 1 |
src/Appwrite/Utopia/Response/Model/Stage.php |
0 | 0 | 0 | 1 | 1 |
tests/e2e/Services/Project/StagesBase.php |
0 | 0 | 0 | 12 | 12 |
Recommendations
- Resolve High severity issues, especially error handling gaps and performance bottlenecks.
- Run automated tests after applying fixes to verify no regressions.
What does this PR do?
(Provide a description of what this PR does and why it's needed.)
Test Plan
(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Screenshots may also be helpful.)
Related PRs and Issues
Checklist