Skip to content

add and changes to quickstart prompts#2662

Merged
atharvadeosthale merged 10 commits intoai-docsfrom
quickstart-prompts
Mar 10, 2026
Merged

add and changes to quickstart prompts#2662
atharvadeosthale merged 10 commits intoai-docsfrom
quickstart-prompts

Conversation

@atharvadeosthale
Copy link
Member

@atharvadeosthale atharvadeosthale commented Dec 12, 2025

Summary by CodeRabbit

  • Documentation
    • Added/expanded quick-start authentication guides across 20+ platforms (Android Java, Android Kotlin/Compose, Angular, iOS/Apple, Dart, Deno, .NET, Flutter, Go, Kotlin, Node.js, Nuxt, PHP, Python, React, React Native, Ruby, Solid, SvelteKit, Swift, TanStack Start, Vue, Web).
    • Android (Java & Kotlin) guides include a full auth scaffold with sample UI flows (register/login/logout) and OAuth callback guidance.
    • Minor snippet and parameter fixes across several quickstarts for consistency.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

Adds or updates a large collection of quick-start documentation and prompt files across many platforms and languages (Android Java, Android Kotlin/Compose, Flutter, Apple/iOS, React, React Native, Next.js, Nuxt, Vue, Angular, SvelteKit, Solid, TanStack Start, Refine, Node, Deno, Go, .NET, Dart, Kotlin server, Python, Ruby, PHP, Swift, and Web). Introduces concrete Android Java artifacts (AppwriteHelper.java, MainActivity.java, activity_main.xml, manifest snippet) and Android/Kotlin singleton examples. Multiple markdoc snippets adjust API parameter names, casing, callback handling, and import/package names. Changes are primarily documentation with embedded code samples and run/test guidance.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'add and changes to quickstart prompts' is vague and generic. It uses non-descriptive language ('add and changes') that doesn't clearly communicate the specific nature or scope of the modifications across 28 quickstart documentation files. Revise the title to be more specific, such as 'Add comprehensive quickstart documentation prompts for 28 SDK/framework integrations' or 'Update quickstart guides with standardized prompt documentation and code examples'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch quickstart-prompts

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.

@atharvadeosthale atharvadeosthale marked this pull request as ready for review January 14, 2026 11:57
Copy link
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: 17

🤖 Fix all issues with AI agents
In `@src/routes/docs/quick-starts/android/prompt.md`:
- Around line 140-211: The login form Column is always rendered even when a user
is authenticated; change the UI so only one state shows by converting the
current separate if (user.isNotEmpty()) { /* logged-in Column */ } and the
subsequent standalone Column (login form) into an if/else or otherwise render
the login form only when user.isEmpty(); locate the first Column guarded by
user.isNotEmpty() and wrap the second Column (the TextField/Row with Buttons and
the coroutineScope.launch calls to Appwrite.onLogin/Appwrite.onRegister) inside
the else branch so the logged-in message and the login form cannot appear
simultaneously.

In `@src/routes/docs/quick-starts/angular/prompt.md`:
- Around line 99-107: The register method calls the async login(email, password)
without awaiting it, risking race conditions; update register (the async
register method) to await the login call (await this.login(email, password)) so
the registration flow completes only after login finishes and UI/state updates
reliably; ensure any returned value from login is handled or returned if callers
expect it.

In `@src/routes/docs/quick-starts/dart/prompt.md`:
- Around line 44-49: The file declares an unused variable "databases" while
later assigning to an undeclared "tablesDB", causing a runtime error; remove the
unused "databases" declaration and declare "tablesDB" before use (e.g., var
tablesDB; or TablesDB tablesDB;) so that the existing assignment tablesDB =
TablesDB(client); refers to a defined variable; keep the existing todoDatabase
and todoTable declarations as needed.

In `@src/routes/docs/quick-starts/dotnet/prompt.md`:
- Around line 115-134: The calls to tablesDB.createRow use camelCase but C#
methods should be PascalCase; update each invocation (tablesDB.createRow) to use
tablesDB.CreateRow and ensure any other occurrences (e.g., CreateRow overloads
or references) are updated consistently so the method resolves correctly at
compile time.

In `@src/routes/docs/quick-starts/flutter/prompt.md`:
- Around line 114-117: The call to widget.account.createEmailPasswordSession
incorrectly uses curly braces around parameters (JavaScript/JSON style); change
it to a normal Dart method call by removing the { } so the named parameters are
passed directly inside the parentheses to createEmailPasswordSession (reference:
widget.account.createEmailPasswordSession).
- Around line 125-130: The Flutter Appwrite calls are using a JS-style object
literal; update both widget.account.create and
widget.account.createEmailPasswordSession to use Dart named parameters instead
of wrapping them in {}—call widget.account.create(userId: ID.unique(), email:
email, password: password, name: name) and
widget.account.createEmailPasswordSession(email: email, password: password) by
removing the surrounding braces and passing parameters as named arguments.

In `@src/routes/docs/quick-starts/go/prompt.md`:
- Around line 42-51: The declaration uses the wrong variable name: you declared
appwriteDatabases *tablesDB.TablesDB but the code later references tablesDB;
rename the declared variable to tablesDB (e.g., change appwriteDatabases to
tablesDB inside the var block) so the symbol tablesDB (used in subsequent calls)
matches the actual variable type *tablesDB.TablesDB and resolves the compilation
errors.
- Around line 128-147: Replace the unexported method calls to createRow with the
exported SDK method CreateRow on the tablesDB client in all three places where
you call it (the calls passing todoDatabase.Id, todoTable.Id, id.Unique(),
testTodo1/testTodo2/testTodo3); update each tablesDB.createRow(...) to
tablesDB.CreateRow(...) so it matches the Appwrite Go SDK exported method name.

In `@src/routes/docs/quick-starts/php/prompt.md`:
- Line 210: The run command incorrectly points to "php src/index.php" while the
example creates the file as "index.php" (see creation at line 33); update the
run instruction to execute the correct path "php index.php" so the command
matches the created file and avoids a file-not-found error.

In `@src/routes/docs/quick-starts/python/prompt.md`:
- Around line 91-98: The quick-start Python snippet uses the wrong parameter
name for the Appwrite SDK: change the create_string_column call so that the
parameter currently named default is renamed to xdefault; update the invocation
of tablesDB.create_string_column (the call that references todoDatabase['$id']
and todoTable['$id'] with key='description', size=255, required=False) to pass
xdefault='This is a test description.' instead of default='This is a test
description.' so it matches the SDK signature used in the Deno and .NET
examples.

In `@src/routes/docs/quick-starts/ruby/prompt.md`:
- Around line 153-160: The script calls run_all_tasks(databases) but never
defines databases, causing a NameError; after the client is initialized create
the Databases service instance (e.g., instantiate Appwrite::Databases with the
existing client) and assign it to databases, then pass that variable into
run_all_tasks(databases); update the call site where run_all_tasks is invoked
and ensure helper methods prepare_database, seed_database, and get_todos receive
that databases instance.
- Around line 28-91: The prepare_database method currently takes an unused
parameter (databases) and relies on the outer tablesDB variable, causing unclear
scope; fix by changing prepare_database to accept the TablesDB instance (e.g.,
def prepare_database(tables_db)) and use that local parameter (tables_db.create,
tables_db.create_table, tables_db.create_string_column, etc.), and when
referencing created resources use their returned id fields (e.g.,
todo_database['$id'] and todo_table['$id'] for database_id/table_id) rather than
relying on .id so the function is self-contained and does not depend on global
state.

In `@src/routes/docs/quick-starts/swift/prompt.md`:
- Around line 137-138: The getTodos function contains unnecessary forced casts
(databaseId: todoDatabase!.id as! String, tableId: todoTable!.id as! String);
remove the forced as! String casts and mirror the prepareDatabase fix by passing
the id values directly (or safely unwrapping them first) e.g. use
todoDatabase!.id and todoTable!.id or guard-let unwrap todoDatabase and
todoTable and then use their .id properties without casting.
- Around line 70-79: Remove the unnecessary forced casts and unsafe
force-unwrapping around todoDatabase!.id and todoTable!.id: stop using "as!
String" and avoid force-unwrapping; instead use the id property directly (if
it’s already a String) or safely unwrap with guard/if let before calling
tablesDB.createTextColumn / tablesDB.createBooleanColumn (and any other
create*Column calls shown), and apply the same change to the later occurrences
referenced at lines 137-138 so all calls use safe/unwrapped ids (refer to
todoDatabase, todoTable, createTextColumn, createBooleanColumn).

In `@src/routes/docs/quick-starts/vue/prompt.md`:
- Line 110: The phrase "auto login" in the markdown sentence should be a
hyphenated compound adjective; change "auto login works" to "auto-login works"
in the sentence (look for the line containing "Register a new user and auto
login works" in src/routes/docs/quick-starts/vue/prompt.md) so the compound
adjective is correctly hyphenated.

In `@src/routes/docs/quick-starts/web/prompt.md`:
- Around line 29-40: The npm example is missing a TablesDB export which later
examples expect; update the module that creates the Appwrite client (the code
that defines client and account) to also import TablesDB from 'appwrite' and
instantiate/export it as tablesDB (e.g., add import of TablesDB, create tablesDB
= new TablesDB(client), and export tablesDB) while keeping the existing client,
account, and ID exports so later uses of tablesDB succeed.
- Around line 42-51: The CDN example hardcodes the endpoint URL without the
Cloud Region placeholder; update the client.setEndpoint call used with
Appwrite.Client (the CDN snippet creating client, then calling
client.setEndpoint(...).setProject(...)) to use
'https://<REGION>.cloud.appwrite.io/v1' instead of
'https://cloud.appwrite.io/v1' so it matches the npm example and Step 3
instructions about choosing a Cloud Region.
🧹 Nitpick comments (21)
src/routes/docs/quick-starts/php/prompt.md (3)

6-6: Consider wrapping the URL in angle brackets.

The bare URL can be improved for better markdown rendering in some parsers.

📝 Proposed fix
-    - Guide the user to the Appwrite Console (https://cloud.appwrite.io/console).
+    - Guide the user to the Appwrite Console (<https://cloud.appwrite.io/console>).

9-15: Add blank lines around the table.

Markdown tables should be surrounded by blank lines for better compatibility with various markdown parsers.

📝 Proposed fix
     - Under "Integrate with your server", add an API Key with the following scopes:
+
       | Category | Required scopes | Purpose |
       |----------|-----------------|---------|
       | Database | `databases.write` | Allows API key to create, update, and delete databases. |
       | | `tables.write` | Allows API key to create, update, and delete tables. |
       | | `columns.write` | Allows API key to create, update, and delete columns. |
       | | `rows.read` | Allows API key to read rows. |
       | | `rows.write` | Allows API key to create, update, and delete rows. |
+

77-83: Add missing default value for the description column.

The Dart prompt (lines 70-77) includes a default value for the description column (xdefault: 'This is a test description'), but this PHP example omits it. For consistency across quick-start guides and to match the seed data behavior (where testTodo2 omits the description field), consider adding a default value.

♻️ Proposed fix for consistency
         $tablesDB->createStringColumn(
             databaseId: $todoDatabase['$id'],
             tableId: $todoTable['$id'],
             key: 'description',
             size: 255,
             required: false,
+            xdefault: 'This is a test description'
         );
src/routes/docs/quick-starts/tanstack-start/prompt.md (1)

120-120: Fix hyphenation for compound modifier.

The phrase "auto login" should be hyphenated as "auto-login" when used as a compound modifier before a noun.

📝 Proposed fix
-        - Register a new user and auto login works
+        - Register a new user and auto-login works
src/routes/docs/quick-starts/kotlin/prompt.md (2)

8-8: Consider wrapping the URL in angle brackets.

Similar to the PHP guide, the bare URL can be improved for better markdown rendering.

📝 Proposed fix
-    - Guide the user to the Appwrite Console (https://cloud.appwrite.io/console)
+    - Guide the user to the Appwrite Console (<https://cloud.appwrite.io/console>)

10-18: Add blank lines around the table.

Markdown tables should be surrounded by blank lines for better compatibility.

📝 Proposed fix
     - Under "Integrate with your server", add an API Key with the following scopes:
+
       | Category | Required scopes | Purpose |
       |-----------|---------------------|---------|
       | Database | databases.write | Allows API key to create, update, and delete databases |
       | | tables.write | Allows API key to create, update, and delete tables |
       | | columns.write | Allows API key to create, update, and delete columns |
       | | rows.read | Allows API key to read rows |
       | | rows.write | Allows API key to create, update, and delete rows |
+
     - Other scopes are optional
src/routes/docs/quick-starts/apple/prompt.md (1)

24-24: Use markdown link syntax for URLs.

The bare URL should be wrapped in angle brackets or converted to a markdown link for better formatting.

📝 Proposed fix
-    - In the **Package URL** search box, enter: https://github.com/appwrite/sdk-for-apple
+    - In the **Package URL** search box, enter: <https://github.com/appwrite/sdk-for-apple>
src/routes/docs/quick-starts/dotnet/prompt.md (1)

6-16: Improve markdown formatting for better rendering.

The documentation has minor markdown formatting issues: bare URL at line 6 and tables that should be surrounded by blank lines.

📝 Proposed fixes
     - Head to the Appwrite Console (https://cloud.appwrite.io/console).
+    - Head to the Appwrite Console (<https://cloud.appwrite.io/console>).
     - If this is the user's first time, guide them to create an account and create their first project.
     - Under **Integrate with your server**, add an **API Key** with the following scopes:
+
       | Category | Required scopes | Purpose |
       |-----------|-----------------------|---------|
       | Database | `databases.write` | Allows API key to create, update, and delete databases. |
       | | `tables.write` | Allows API key to create, update, and delete tables. |
       | | `columns.write` | Allows API key to create, update, and delete columns. |
       | | `rows.read` | Allows API key to read rows. |
       | | `rows.write` | Allows API key to create, update, and delete rows. |
+
     - Other scopes are optional.
src/routes/docs/quick-starts/react/prompt.md (2)

22-31: Clarify TypeScript support or remove .ts references.

The documentation mentions creating src/lib/appwrite.js (or .ts) but the code snippet only shows JavaScript syntax. If TypeScript is supported, consider adding a TypeScript code example or notes about type imports. Otherwise, remove the (or .ts) references to avoid confusion.


52-52: Wrap URL in code formatting.

The bare URL should be formatted for consistency with markdown best practices.

📝 Suggested fix
-    - Open: http://localhost:3000
+    - Open: `http://localhost:3000`
src/routes/docs/quick-starts/solid/prompt.md (4)

7-10: Consider consistency with other quick-start guides.

This guide begins with Appwrite Console setup, while the React guide (and potentially others) defers this to step 3 where it asks for region/project ID. For a consistent user experience across all framework quick-starts, consider aligning the structure.


8-8: Wrap URL in code formatting.

📝 Suggested fix
-    - Guide the user to head to the Appwrite Console (https://cloud.appwrite.io/console).
+    - Guide the user to head to the Appwrite Console (`https://cloud.appwrite.io/console`).

133-133: Wrap URL in code formatting.

📝 Suggested fix
-    - Open: http://localhost:3000
+    - Open: `http://localhost:3000`

135-135: Use hyphenated compound modifier.

The phrase "auto login" should be hyphenated when used as a compound modifier.

📝 Suggested fix
-        - Register a new user and auto login works
+        - Register a new user and auto-login works
src/routes/docs/quick-starts/sveltekit/prompt.md (2)

109-109: Wrap URL in code formatting.

📝 Suggested fix
-    - Open: http://localhost:5173
+    - Open: `http://localhost:5173`

111-111: Use hyphenated compound modifier.

📝 Suggested fix
-        - Register a new user and auto login works
+        - Register a new user and auto-login works
src/routes/docs/quick-starts/ruby/prompt.md (1)

6-6: Wrap URL in code formatting.

📝 Suggested fix
-    - Guide the user to the Appwrite Console (https://cloud.appwrite.io/console)
+    - Guide the user to the Appwrite Console (`https://cloud.appwrite.io/console`)
src/routes/docs/quick-starts/nuxt/prompt.md (3)

20-32: Consider consistent file paths across framework guides.

This guide uses utils/appwrite.js while other framework guides (React, Solid, SvelteKit) use src/lib/appwrite.js. While Nuxt conventions may differ, consider whether alignment would improve cross-framework consistency for users learning multiple platforms.


105-105: Wrap URL in code formatting.

📝 Suggested fix
-    - Open: http://localhost:3000
+    - Open: `http://localhost:3000`

107-107: Use hyphenated compound modifier.

📝 Suggested fix
-        - Register a new user and auto login works
+        - Register a new user and auto-login works
src/routes/docs/quick-starts/android/prompt.md (1)

199-209: Consider auto-login after successful registration.

After successful registration, the user must manually log in. For better user experience, consider automatically logging in the user after registration, similar to the Angular example (angular/prompt.md line 106).

✨ Proposed enhancement
                                     Button(onClick = {
                                         coroutineScope.launch {
                                             try {
                                                 Appwrite.onRegister(email, password)
+                                                Appwrite.onLogin(email, password)
+                                                user = email
                                             } catch (e: Exception) {
                                                 e.printStackTrace()
                                             }
                                         }
                                     }) {
                                         Text("Register")
                                     }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73bdc62 and 897ce74.

📒 Files selected for processing (25)
  • src/routes/docs/quick-starts/android-java/prompt.md
  • src/routes/docs/quick-starts/android/prompt.md
  • src/routes/docs/quick-starts/angular/prompt.md
  • src/routes/docs/quick-starts/apple/prompt.md
  • src/routes/docs/quick-starts/dart/prompt.md
  • src/routes/docs/quick-starts/deno/prompt.md
  • src/routes/docs/quick-starts/dotnet/prompt.md
  • src/routes/docs/quick-starts/flutter/prompt.md
  • src/routes/docs/quick-starts/go/prompt.md
  • src/routes/docs/quick-starts/kotlin/prompt.md
  • src/routes/docs/quick-starts/nextjs/prompt.md
  • src/routes/docs/quick-starts/node/prompt.md
  • src/routes/docs/quick-starts/nuxt/prompt.md
  • src/routes/docs/quick-starts/php/prompt.md
  • src/routes/docs/quick-starts/python/prompt.md
  • src/routes/docs/quick-starts/react-native/prompt.md
  • src/routes/docs/quick-starts/react/prompt.md
  • src/routes/docs/quick-starts/refine/prompt.md
  • src/routes/docs/quick-starts/ruby/prompt.md
  • src/routes/docs/quick-starts/solid/prompt.md
  • src/routes/docs/quick-starts/sveltekit/prompt.md
  • src/routes/docs/quick-starts/swift/prompt.md
  • src/routes/docs/quick-starts/tanstack-start/prompt.md
  • src/routes/docs/quick-starts/vue/prompt.md
  • src/routes/docs/quick-starts/web/prompt.md
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: atharvadeosthale
Repo: appwrite/website PR: 2614
File: src/routes/docs/products/sites/one-click-deployment/+page.markdoc:74-122
Timestamp: 2025-11-18T21:53:20.905Z
Learning: Appwrite Sites one-click deployment supports the following framework presets: Analog (analog), Angular (angular), Next.js (nextjs), React (react), Nuxt (nuxt), Vue (vue), SvelteKit (sveltekit), Astro (astro), TanStack Start (tanstack-start), Remix (remix), Lynx (lynx), Flutter (flutter), React Native (react-native), Vite (vite), and Other (other).
📚 Learning: 2025-09-05T19:35:04.162Z
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/nuxt/step-6/+page.markdoc:79-83
Timestamp: 2025-09-05T19:35:04.162Z
Learning: In Nuxt tutorial files, the correct Appwrite database instance to use is `tablesDB` (imported from "~/appwrite"), not `database`. All tablesDB method calls should use the object parameter format: listRows({ databaseId, tableId, queries }), createRow({ databaseId, tableId, rowId, data }), and deleteRow({ databaseId, tableId, rowId }).

Applied to files:

  • src/routes/docs/quick-starts/node/prompt.md
📚 Learning: 2025-09-05T19:35:59.449Z
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/react-native/step-6/+page.markdoc:67-73
Timestamp: 2025-09-05T19:35:59.449Z
Learning: In React Native tutorials, the lib/appwrite.js file exports `tablesDB` (not `databases`), so imports should use `import { tablesDB } from "../lib/appwrite"` to match the export pattern established in step-3.

Applied to files:

  • src/routes/docs/quick-starts/node/prompt.md
📚 Learning: 2025-09-05T19:35:53.943Z
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/react/step-6/+page.markdoc:70-75
Timestamp: 2025-09-05T19:35:53.943Z
Learning: In React tutorial files, the correct Appwrite database instance to import is `tablesDB` from "../appwrite", not `databases`. The import statement should be `import { tablesDB } from "../appwrite"` to match the usage throughout the React tutorial code.

Applied to files:

  • src/routes/docs/quick-starts/node/prompt.md
  • src/routes/docs/quick-starts/web/prompt.md
📚 Learning: 2025-11-18T21:53:20.905Z
Learnt from: atharvadeosthale
Repo: appwrite/website PR: 2614
File: src/routes/docs/products/sites/one-click-deployment/+page.markdoc:74-122
Timestamp: 2025-11-18T21:53:20.905Z
Learning: Appwrite Sites one-click deployment supports the following framework presets: Analog (analog), Angular (angular), Next.js (nextjs), React (react), Nuxt (nuxt), Vue (vue), SvelteKit (sveltekit), Astro (astro), TanStack Start (tanstack-start), Remix (remix), Lynx (lynx), Flutter (flutter), React Native (react-native), Vite (vite), and Other (other).

Applied to files:

  • src/routes/docs/quick-starts/react/prompt.md
  • src/routes/docs/quick-starts/refine/prompt.md
🪛 LanguageTool
src/routes/docs/quick-starts/android/prompt.md

[grammar] ~234-~234: Ensure spelling is correct
Context: ... - Login with the registered user - Logout - Surface any Appwrite errors and fix by g...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

src/routes/docs/quick-starts/nuxt/prompt.md

[grammar] ~107-~107: Use a hyphen to join words.
Context: ...: - Register a new user and auto login works - Logout then login ...

(QB_NEW_EN_HYPHEN)

src/routes/docs/quick-starts/sveltekit/prompt.md

[grammar] ~111-~111: Use a hyphen to join words.
Context: ...: - Register a new user and auto login works - Logout then login ...

(QB_NEW_EN_HYPHEN)

src/routes/docs/quick-starts/vue/prompt.md

[grammar] ~110-~110: Use a hyphen to join words.
Context: ...: - Register a new user and auto login works - Logout then login ...

(QB_NEW_EN_HYPHEN)

src/routes/docs/quick-starts/solid/prompt.md

[grammar] ~135-~135: Use a hyphen to join words.
Context: ...: - Register a new user and auto login works - Logout then login ...

(QB_NEW_EN_HYPHEN)

src/routes/docs/quick-starts/tanstack-start/prompt.md

[grammar] ~120-~120: Use a hyphen to join words.
Context: ...: - Register a new user and auto login works - Logout then login ...

(QB_NEW_EN_HYPHEN)

🪛 markdownlint-cli2 (0.18.1)
src/routes/docs/quick-starts/angular/prompt.md

124-124: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/flutter/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)


9-9: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

src/routes/docs/quick-starts/dotnet/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)


9-9: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


15-15: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

src/routes/docs/quick-starts/nuxt/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)


8-8: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


14-14: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

src/routes/docs/quick-starts/apple/prompt.md

24-24: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/node/prompt.md

14-14: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/web/prompt.md

8-8: Bare URL used

(MD034, no-bare-urls)


108-108: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/react/prompt.md

52-52: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/kotlin/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)


9-9: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


15-15: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

src/routes/docs/quick-starts/sveltekit/prompt.md

109-109: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/refine/prompt.md

8-8: Bare URL used

(MD034, no-bare-urls)


23-23: Bare URL used

(MD034, no-bare-urls)


27-27: Bare URL used

(MD034, no-bare-urls)


140-140: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/go/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)


9-9: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


15-15: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

src/routes/docs/quick-starts/swift/prompt.md

8-8: Bare URL used

(MD034, no-bare-urls)


133-133: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/solid/prompt.md

118-118: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/php/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)


9-9: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

src/routes/docs/quick-starts/ruby/prompt.md

6-6: Bare URL used

(MD034, no-bare-urls)

src/routes/docs/quick-starts/nextjs/prompt.md

8-8: Bare URL used

(MD034, no-bare-urls)

⏰ 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). (3)
  • GitHub Check: tests
  • GitHub Check: assets
  • GitHub Check: build
🔇 Additional comments (16)
src/routes/docs/quick-starts/dart/prompt.md (1)

167-167: Verify the command path matches the project structure.

The run command uses dart run bin/my_app.dart, but based on the Dart project structure created in step 1, this should work correctly. However, since step 1 instructs to remove the lib/ and test/ directories, ensure this is intentional and that the user understands they're building a minimal console application.

src/routes/docs/quick-starts/react-native/prompt.md (2)

9-11: Excellent improvement for flexible project integration.

The updated step now handles both new and existing projects gracefully, reducing friction for developers who want to add Appwrite to an existing app.


37-39: Good conditional guidance for UI wiring.

The added guidance helps developers choose the appropriate approach based on their project state, preventing accidental override of important routes in existing projects.

src/routes/docs/quick-starts/tanstack-start/prompt.md (1)

7-11: Excellent directory safety checks.

The logic to detect non-development files in the working directory helps prevent accidental scaffolding in inappropriate locations (e.g., user's Downloads or Documents folder). This is a thoughtful UX improvement.

src/routes/docs/quick-starts/kotlin/prompt.md (2)

5-5: Helpful clarification for SDK selection.

The note distinguishing between the Kotlin Server SDK and Android client SDK helps prevent confusion and guides users to the appropriate quick-start.


78-85: No action needed—the parameter name is correct.

default is not a reserved keyword in Kotlin and is the correct parameter name for the Appwrite Kotlin SDK's createStringColumn method. The code example is accurate.

Likely an incorrect or invalid review comment.

src/routes/docs/quick-starts/dotnet/prompt.md (2)

141-144: Fix method naming to follow C# PascalCase conventions.

The method call uses camelCase (listRows) but C# methods follow PascalCase naming conventions. The correct method name should be ListRows.

🔧 Proposed fix
-        var todos = await tablesDB.listRows(
+        var todos = await tablesDB.ListRows(
             databaseId: todoDatabase.Id,
             tableId: todoTable.Id
         );
⛔ Skipped due to learnings
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/nuxt/step-6/+page.markdoc:79-83
Timestamp: 2025-09-05T19:35:04.162Z
Learning: In Nuxt tutorial files, the correct Appwrite database instance to use is `tablesDB` (imported from "~/appwrite"), not `database`. All tablesDB method calls should use the object parameter format: listRows({ databaseId, tableId, queries }), createRow({ databaseId, tableId, rowId, data }), and deleteRow({ databaseId, tableId, rowId }).

23-23: Version 0.13.0 of the Appwrite .NET SDK is valid, publicly available on NuGet, and has no known security advisories.

src/routes/docs/quick-starts/python/prompt.md (1)

39-39: Upgrade Appwrite Python SDK to version 14.1.0 — version 13.6.1 has known security vulnerabilities.

Version 13.6.1 is flagged by SafetyDB with documented vulnerabilities (including CVE-2024-1063 and CVE-2023-50974). Update the pin to pip install appwrite==14.1.0 (released December 2025, latest stable).

src/routes/docs/quick-starts/apple/prompt.md (1)

25-25: Update SDK version to latest release in quick-start guide.

Version 10.1.0 is outdated; the latest Appwrite Apple SDK is v13.4.0 (released 2025). Update the quick-start instructions to use a current version to prevent users from starting with obsolete dependencies and missing critical features or improvements across 3+ major versions.

⛔ Skipped due to learnings
Learnt from: stnguyen90
Repo: appwrite/website PR: 2520
File: src/routes/docs/advanced/self-hosting/production/updates/+page.markdoc:13-15
Timestamp: 2025-10-24T22:17:14.669Z
Learning: In Appwrite versioning, RC (Release Candidate) versions like `1.6.2-RC1` come before the stable release `1.6.2`. Documentation should recommend upgrading to stable versions, not RC versions.
src/routes/docs/quick-starts/nextjs/prompt.md (2)

7-12: Excellent improvement to project setup flow.

The added logic to check for non-development files and ask the user before proceeding is a thoughtful UX improvement. This prevents accidentally creating projects in inappropriate directories while still allowing flexibility.


36-37: Good distinction between fresh and existing projects.

The conditional routing logic (replace app/page.js for fresh projects vs. create app/auth/page.js for existing) properly respects the user's existing codebase.

src/routes/docs/quick-starts/android-java/prompt.md (2)

64-126: Well-structured singleton pattern with proper callbacks.

The AppwriteHelper class demonstrates good practices:

  • Singleton pattern with thread-safe initialization
  • Clean callback interface for async operations
  • Proper error propagation

256-282: Good UI thread handling and error management.

The login method properly handles:

  • Input validation
  • UI thread updates with runOnUiThread
  • User feedback via Toast messages
  • Error logging
src/routes/docs/quick-starts/go/prompt.md (1)

42-42: Fix the import casing: use lowercase tablesdb.

The import path should be github.com/appwrite/sdk-for-go/tablesdb (lowercase), not tablesDB. Go package names follow lowercase conventions.

⛔ Skipped due to learnings
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/react/step-6/+page.markdoc:70-75
Timestamp: 2025-09-05T19:35:53.943Z
Learning: In React tutorial files, the correct Appwrite database instance to import is `tablesDB` from "../appwrite", not `databases`. The import statement should be `import { tablesDB } from "../appwrite"` to match the usage throughout the React tutorial code.
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/react-native/step-6/+page.markdoc:67-73
Timestamp: 2025-09-05T19:35:59.449Z
Learning: In React Native tutorials, the lib/appwrite.js file exports `tablesDB` (not `databases`), so imports should use `import { tablesDB } from "../lib/appwrite"` to match the export pattern established in step-3.
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/react-native/step-6/+page.markdoc:67-73
Timestamp: 2025-09-05T19:35:59.449Z
Learning: In React Native tutorials, the lib/appwrite.js file exports `tablesDB` (not `databases`), so imports should use `import { tablesDB } from "../lib/appwrite"` to match the export pattern established in step-3.
Learnt from: ebenezerdon
Repo: appwrite/website PR: 2372
File: src/routes/docs/tutorials/nuxt/step-6/+page.markdoc:79-83
Timestamp: 2025-09-05T19:35:04.162Z
Learning: In Nuxt tutorial files, the correct Appwrite database instance to use is `tablesDB` (imported from "~/appwrite"), not `database`. All tablesDB method calls should use the object parameter format: listRows({ databaseId, tableId, queries }), createRow({ databaseId, tableId, rowId, data }), and deleteRow({ databaseId, tableId, rowId }).
src/routes/docs/quick-starts/flutter/prompt.md (1)

68-68: Update the Flutter SDK version to the latest stable release.

Line 68 specifies appwrite:17.0.0, but the latest stable version is 20.3.3 (released January 14, 2026). Update the version reference to ensure users install the current SDK.

⛔ Skipped due to learnings
Learnt from: stnguyen90
Repo: appwrite/website PR: 2520
File: src/routes/docs/advanced/self-hosting/production/updates/+page.markdoc:13-15
Timestamp: 2025-10-24T22:17:14.669Z
Learning: In Appwrite versioning, RC (Release Candidate) versions like `1.6.2-RC1` come before the stable release `1.6.2`. Documentation should recommend upgrading to stable versions, not RC versions.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +140 to +211
if (user.isNotEmpty()) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Logged in as $user")
Button(onClick = {
coroutineScope.launch {
Appwrite.onLogout()
}
}) {
Text("Logout")
}
}
}

Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
TextField(
value = email,
onValueChange = { email = it },
label = { Text("Username") },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(onClick = {
coroutineScope.launch {
try {
Appwrite.onLogin(email, password)

user = email
} catch (e: Exception) {
e.printStackTrace()
}
}
}) {
Text("Login")
}
Button(onClick = {
coroutineScope.launch {
try {
Appwrite.onRegister(email, password)
} catch (e: Exception) {
e.printStackTrace()
}
}
}) {
Text("Register")
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Login form always visible, causing UI overlap.

The logged-in UI (lines 140-155) displays when user.isNotEmpty(), but the login form (lines 157-211) is always rendered. This results in both the "Logged in as..." message and the login form appearing simultaneously when a user is authenticated.

🎨 Proposed fix to show only one UI state
                             var email by remember { mutableStateOf("") }
                             var password by remember { mutableStateOf("") }

                             if (user.isNotEmpty()) {
                                 Column(
                                     modifier = Modifier.fillMaxSize(),
                                     horizontalAlignment = Alignment.CenterHorizontally,
                                     verticalArrangement = Arrangement.Center
                                 ) {
                                     Text(text = "Logged in as $user")
                                     Button(onClick = {
                                         coroutineScope.launch {
                                             Appwrite.onLogout()
+                                            user = ""
                                         }
                                     }) {
                                         Text("Logout")
                                     }
                                 }
-                            }
-
-                            Column(
+                            } else {
+                                Column(
                                 modifier = Modifier.fillMaxSize(),
                                 horizontalAlignment = Alignment.CenterHorizontally,
                                 verticalArrangement = Arrangement.Center
                             ) {
                                 TextField(
                                     value = email,
                                     onValueChange = { email = it },
                                     label = { Text("Username") },
                                     modifier = Modifier
                                         .fillMaxWidth()
                                         .padding(16.dp)
                                 )
                                 TextField(
                                     value = password,
                                     onValueChange = { password = it },
                                     label = { Text("Password") },
                                     modifier = Modifier
                                         .fillMaxWidth()
                                         .padding(16.dp),
                                     visualTransformation = PasswordVisualTransformation(),
                                     keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
                                 )
                                 Row(
                                     modifier = Modifier
                                         .fillMaxWidth()
                                         .padding(16.dp),
                                     horizontalArrangement = Arrangement.SpaceBetween
                                 ) {
                                     Button(onClick = {
                                         coroutineScope.launch {
                                             try {
                                                 Appwrite.onLogin(email, password)

                                                 user = email
                                             } catch (e: Exception) {
                                                 e.printStackTrace()
                                             }
                                         }
                                     }) {
                                         Text("Login")
                                     }
                                     Button(onClick = {
                                         coroutineScope.launch {
                                             try {
                                                 Appwrite.onRegister(email, password)
                                             } catch (e: Exception) {
                                                 e.printStackTrace()
                                             }
                                         }
                                     }) {
                                         Text("Register")
                                     }
                                 }
+                                }
                             }
                         }
                     }
                 }
             }
         }
📝 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.

Suggested change
if (user.isNotEmpty()) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Logged in as $user")
Button(onClick = {
coroutineScope.launch {
Appwrite.onLogout()
}
}) {
Text("Logout")
}
}
}
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
TextField(
value = email,
onValueChange = { email = it },
label = { Text("Username") },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(onClick = {
coroutineScope.launch {
try {
Appwrite.onLogin(email, password)
user = email
} catch (e: Exception) {
e.printStackTrace()
}
}
}) {
Text("Login")
}
Button(onClick = {
coroutineScope.launch {
try {
Appwrite.onRegister(email, password)
} catch (e: Exception) {
e.printStackTrace()
}
}
}) {
Text("Register")
}
}
}
if (user.isNotEmpty()) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = "Logged in as $user")
Button(onClick = {
coroutineScope.launch {
Appwrite.onLogout()
user = ""
}
}) {
Text("Logout")
}
}
} else {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
TextField(
value = email,
onValueChange = { email = it },
label = { Text("Username") },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
)
TextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Button(onClick = {
coroutineScope.launch {
try {
Appwrite.onLogin(email, password)
user = email
} catch (e: Exception) {
e.printStackTrace()
}
}
}) {
Text("Login")
}
Button(onClick = {
coroutineScope.launch {
try {
Appwrite.onRegister(email, password)
} catch (e: Exception) {
e.printStackTrace()
}
}
}) {
Text("Register")
}
}
}
}
🤖 Prompt for AI Agents
In `@src/routes/docs/quick-starts/android/prompt.md` around lines 140 - 211, The
login form Column is always rendered even when a user is authenticated; change
the UI so only one state shows by converting the current separate if
(user.isNotEmpty()) { /* logged-in Column */ } and the subsequent standalone
Column (login form) into an if/else or otherwise render the login form only when
user.isEmpty(); locate the first Column guarded by user.isNotEmpty() and wrap
the second Column (the TextField/Row with Buttons and the coroutineScope.launch
calls to Appwrite.onLogin/Appwrite.onRegister) inside the else branch so the
logged-in message and the login form cannot appear simultaneously.

Comment on lines +99 to +107
async register(email: string, password: string, name: string) {
await account.create({
userId: ID.unique(),
email,
password,
name
});
this.login(email, password);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing await on login call in register method.

Line 106 calls this.login(email, password) without awaiting it. Since login is an async function, this could lead to race conditions or the user interface not updating correctly after registration.

⚡ Proposed fix
             async register(email: string, password: string, name: string) {
                 await account.create({
                     userId: ID.unique(),
                     email,
                     password,
                     name
                 });
-                this.login(email, password);
+                await this.login(email, password);
             }
📝 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.

Suggested change
async register(email: string, password: string, name: string) {
await account.create({
userId: ID.unique(),
email,
password,
name
});
this.login(email, password);
}
async register(email: string, password: string, name: string) {
await account.create({
userId: ID.unique(),
email,
password,
name
});
await this.login(email, password);
}
🤖 Prompt for AI Agents
In `@src/routes/docs/quick-starts/angular/prompt.md` around lines 99 - 107, The
register method calls the async login(email, password) without awaiting it,
risking race conditions; update register (the async register method) to await
the login call (await this.login(email, password)) so the registration flow
completes only after login finishes and UI/state updates reliably; ensure any
returned value from login is handled or returned if callers expect it.

Comment on lines +70 to +79
databaseId: todoDatabase!.id as! String,
tableId: todoTable!.id as! String,
key: "description",
size: 255,
xrequired: false,
xdefault: "This is a test description."
)
try? await tablesDB.createBooleanColumn(
databaseId: todoDatabase!.id as! String,
tableId: todoTable!.id as! String,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Remove unnecessary and potentially unsafe type casts.

Lines 70-71 and 78-79 use forced type casting (as! String) on todoDatabase!.id and todoTable!.id. If these properties are already of type String, the cast is redundant. If they're not, forced casting can cause runtime crashes.

♻️ Proposed fix
     try? await tablesDB.createStringColumn(
-        databaseId: todoDatabase!.id as! String,
-        tableId: todoTable!.id as! String,
+        databaseId: todoDatabase!.id,
+        tableId: todoTable!.id,
         key: "description",
         size: 255,
         xrequired: false,
         xdefault: "This is a test description."
     )
     try? await tablesDB.createBooleanColumn(
-        databaseId: todoDatabase!.id as! String,
-        tableId: todoTable!.id as! String,
+        databaseId: todoDatabase!.id,
+        tableId: todoTable!.id,
         key: "isComplete",
         xrequired: true
     )

Apply the same fix to lines 137-138.

What is the type of the id property on Database and Table models in Appwrite Swift SDK version 10.0.0?
🤖 Prompt for AI Agents
In `@src/routes/docs/quick-starts/swift/prompt.md` around lines 70 - 79, Remove
the unnecessary forced casts and unsafe force-unwrapping around todoDatabase!.id
and todoTable!.id: stop using "as! String" and avoid force-unwrapping; instead
use the id property directly (if it’s already a String) or safely unwrap with
guard/if let before calling tablesDB.createTextColumn /
tablesDB.createBooleanColumn (and any other create*Column calls shown), and
apply the same change to the later occurrences referenced at lines 137-138 so
all calls use safe/unwrapped ids (refer to todoDatabase, todoTable,
createTextColumn, createBooleanColumn).

Comment on lines +137 to +138
databaseId: todoDatabase!.id as! String,
tableId: todoTable!.id as! String
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Same type casting issue in getTodos function.

The same unnecessary type casting appears here. Should be consistent with the fix applied to the prepareDatabase function.

♻️ Proposed fix
     let todos = try? await tablesDB.listRows(
-        databaseId: todoDatabase!.id as! String,
-        tableId: todoTable!.id as! String
+        databaseId: todoDatabase!.id,
+        tableId: todoTable!.id
     )
📝 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.

Suggested change
databaseId: todoDatabase!.id as! String,
tableId: todoTable!.id as! String
databaseId: todoDatabase!.id,
tableId: todoTable!.id
🤖 Prompt for AI Agents
In `@src/routes/docs/quick-starts/swift/prompt.md` around lines 137 - 138, The
getTodos function contains unnecessary forced casts (databaseId:
todoDatabase!.id as! String, tableId: todoTable!.id as! String); remove the
forced as! String casts and mirror the prepareDatabase fix by passing the id
values directly (or safely unwrapping them first) e.g. use todoDatabase!.id and
todoTable!.id or guard-let unwrap todoDatabase and todoTable and then use their
.id properties without casting.

- Run: npm run dev -- --open --port 3000
- Open: http://localhost:3000
- Test flows:
- Register a new user and auto login works
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use hyphenated compound adjective.

The phrase "auto login" should be hyphenated when used as a compound adjective.

📝 Proposed fix
-        - Register a new user and auto login works
+        - Register a new user and auto-login works
📝 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.

Suggested change
- Register a new user and auto login works
- Register a new user and auto-login works
🧰 Tools
🪛 LanguageTool

[grammar] ~110-~110: Use a hyphen to join words.
Context: ...: - Register a new user and auto login works - Logout then login ...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In `@src/routes/docs/quick-starts/vue/prompt.md` at line 110, The phrase "auto
login" in the markdown sentence should be a hyphenated compound adjective;
change "auto login works" to "auto-login works" in the sentence (look for the
line containing "Register a new user and auto login works" in
src/routes/docs/quick-starts/vue/prompt.md) so the compound adjective is
correctly hyphenated.

Comment on lines +42 to +51
- If using CDN, use the global Appwrite object:

```js
const client = new Appwrite.Client();

client.setEndpoint('https://cloud.appwrite.io/v1').setProject('<PROJECT_ID>'); // Replace with your project ID

const account = new Appwrite.Account(client);
const tablesDB = new Appwrite.TablesDB(client);
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

CDN endpoint missing region placeholder.

Line 47 uses https://cloud.appwrite.io/v1 without a region placeholder, while the npm example (line 36) correctly uses https://<REGION>.cloud.appwrite.io/v1. Step 3 asks users for their Cloud Region, so the CDN example should also include the region placeholder for consistency.

🔧 Proposed fix
     - If using CDN, use the global Appwrite object:

         ```js
         const client = new Appwrite.Client();

-        client.setEndpoint('https://cloud.appwrite.io/v1').setProject('<PROJECT_ID>'); // Replace with your project ID
+        client.setEndpoint('https://<REGION>.cloud.appwrite.io/v1').setProject('<PROJECT_ID>'); // Replace with your project ID

         const account = new Appwrite.Account(client);
         const tablesDB = new Appwrite.TablesDB(client);
         ```
📝 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.

Suggested change
- If using CDN, use the global Appwrite object:
```js
const client = new Appwrite.Client();
client.setEndpoint('https://cloud.appwrite.io/v1').setProject('<PROJECT_ID>'); // Replace with your project ID
const account = new Appwrite.Account(client);
const tablesDB = new Appwrite.TablesDB(client);
```
const client = new Appwrite.Client();
client.setEndpoint('https://<REGION>.cloud.appwrite.io/v1').setProject('<PROJECT_ID>'); // Replace with your project ID
const account = new Appwrite.Account(client);
const tablesDB = new Appwrite.TablesDB(client);
🤖 Prompt for AI Agents
In `@src/routes/docs/quick-starts/web/prompt.md` around lines 42 - 51, The CDN
example hardcodes the endpoint URL without the Cloud Region placeholder; update
the client.setEndpoint call used with Appwrite.Client (the CDN snippet creating
client, then calling client.setEndpoint(...).setProject(...)) to use
'https://<REGION>.cloud.appwrite.io/v1' instead of
'https://cloud.appwrite.io/v1' so it matches the npm example and Step 3
instructions about choosing a Cloud Region.

Comment on lines +115 to +150
await tablesDB.createRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo1
);

await tablesDB.createRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo2
);

await tablesDB.createRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo3
);
```

7. Retrieve rows
- Add code to retrieve and display the todo data:

```csharp
var todos = await tablesDB.listRows(
databaseId: todoDatabase.Id,
tableId: todoTable.Id
);

foreach (var todo in todos.Documents)
{
Console.WriteLine($"Title: {todo.Data["title"]}\nDescription: {todo.Data["description"]}\nIs Todo Complete: {todo.Data["isComplete"]}\n\n");
}
```
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
await tablesDB.createRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo1
);
await tablesDB.createRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo2
);
await tablesDB.createRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo3
);
```
7. Retrieve rows
- Add code to retrieve and display the todo data:
```csharp
var todos = await tablesDB.listRows(
databaseId: todoDatabase.Id,
tableId: todoTable.Id
);
foreach (var todo in todos.Documents)
{
Console.WriteLine($"Title: {todo.Data["title"]}\nDescription: {todo.Data["description"]}\nIs Todo Complete: {todo.Data["isComplete"]}\n\n");
}
```
await tablesDB.CreateRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo1
);
await tablesDB.CreateRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo2
);
await tablesDB.CreateRow(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
rowId: ID.Unique(),
data: testTodo3
);
```
7. Retrieve rows
- Add code to retrieve and display the todo data:
```csharp
var todos = await tablesDB.ListRows(
databaseId: todoDatabase.Id,
tableId: todoTable.Id
);
foreach (var todo in todos.Rows)
{
Console.WriteLine($"Title: {todo.Data["title"]}\nDescription: {todo.Data["description"]}\nIs Todo Complete: {todo.Data["isComplete"]}\n\n");
}
```

Copy link
Member

Choose a reason for hiding this comment

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

@atharvadeosthale you'll need to check case of SDK methods and basic correctness across all SDKs

Copy link
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: 17

🧹 Nitpick comments (4)
src/routes/docs/quick-starts/go/prompt.md (2)

9-15: Add blank lines around the table for proper markdown formatting.

The table should be surrounded by blank lines to ensure correct rendering across different markdown parsers.

📝 Proposed fix for table formatting
       | | `rows.write` | Allows API key to create, update, and delete rows. |
+
     - Other scopes are optional.

Also add a blank line before line 9:

     - Under "Integrate with your server", add an API Key with the following scopes:
+
       | Category | Required scopes | Purpose |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/go/prompt.md` around lines 9 - 15, Add blank
lines immediately before and after the markdown table block so the table is
separated from surrounding content for correct rendering; specifically, insert
an empty line above the line beginning with "| Category | Required scopes |
Purpose |" and an empty line after the last table row ("| | `rows.write` |
Allows API key to create, update, and delete rows. |") in
src/routes/docs/quick-starts/go/prompt.md.

39-45: Consider noting that imports will be added incrementally.

The initial import block doesn't include id (added in step 5, line 63) or fmt (added in step 8, line 250). Adding a note here about additional imports being introduced later would improve clarity.

💡 Optional improvement

Add a note after the import block:

         "github.com/appwrite/sdk-for-go/query"
     )
+
+    // Note: Additional imports (id, fmt) will be added in subsequent steps
 
     var (
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/go/prompt.md` around lines 39 - 45, Add a short
explanatory note immediately after the initial import block in prompt.md
explaining that additional imports (e.g., the "id" package added later in step 5
and "fmt" added in step 8) will be introduced incrementally as the tutorial
progresses; reference the existing import block (the lines importing
github.com/appwrite/... packages) so readers know to expect later additions
rather than a complete import list up front.
src/routes/docs/quick-starts/swift/+page.markdoc (1)

99-133: Force-unwrapping optionals from try? will crash on any SDK error.

Since try? returns nil on failure, every todoDatabase!.id and todoTable!.id is a potential crash site. For a quick-start guide, this could confuse beginners who hit a misconfiguration. Consider using guard let to exit gracefully with a message. Also, the as! String casts on Lines 119–120, 126–127, 187–188 appear unnecessary since .id is already a String.

Example: safer unwrap with guard
-func prepareDatabase() async -> (Database?, Table?) {
-    let todoDatabase = try? await tablesDB.create(
+func prepareDatabase() async -> (Database, Table)? {
+    guard let todoDatabase = try? await tablesDB.create(
         databaseId: ID.unique(),
         name: "TodosDB"
-    )
-    let todoTable = try? await tablesDB.createTable(
-        databaseId: todoDatabase!.id,
+    ) else {
+        print("Failed to create database")
+        return nil
+    }
+    guard let todoTable = try? await tablesDB.createTable(
+        databaseId: todoDatabase.id,
         tableId: ID.unique(),
         name: "Todos"
-    )
+    ) else {
+        print("Failed to create table")
+        return nil
+    }
     try? await tablesDB.createVarcharColumn(
-        databaseId: todoDatabase!.id,
-        tableId: todoTable!.id,
+        databaseId: todoDatabase.id,
+        tableId: todoTable.id,
         key: "title",
         size: 255,
         required: true
     )
     try? await tablesDB.createTextColumn(
-        databaseId: todoDatabase!.id as! String,
-        tableId: todoTable!.id as! String,
+        databaseId: todoDatabase.id,
+        tableId: todoTable.id,
         key: "description",
         required: false,
         default: "This is a test description."
     )
     try? await tablesDB.createBooleanColumn(
-        databaseId: todoDatabase!.id as! String,
-        tableId: todoTable!.id as! String,
+        databaseId: todoDatabase.id,
+        tableId: todoTable.id,
         key: "isComplete",
         required: true
     )
     
     return (todoDatabase, todoTable)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/swift/`+page.markdoc around lines 99 - 133, The
code in prepareDatabase uses try? and then force-unwraps todoDatabase!.id and
todoTable!.id (and uses unnecessary as! String casts), which will crash on SDK
errors; change to do/catch or use guard let to safely unwrap the results from
tablesDB.create and tablesDB.createTable into todoDatabase and todoTable, handle
failures by logging/returning (nil, nil) or throwing, and then pass the
unwrapped todoDatabase.id and todoTable.id (without as! casts) into
createVarcharColumn/createTextColumn/createBooleanColumn; ensure each await call
either throws up to caller or is checked so no force-unwrapping remains.
src/routes/docs/quick-starts/dart/prompt.md (1)

159-159: Consider if the delay is necessary.

The 1-second delay between database preparation and seeding might be a workaround for async timing. If possible, verify whether this delay is actually required or if the SDK operations are properly awaited and synchronized.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dart/prompt.md` at line 159, The explicit await
Future.delayed(const Duration(seconds: 1)) is likely a timing workaround between
database preparation and seeding; remove this hardcoded delay and instead ensure
the preparation API is fully awaited/completes before calling the seeding
function (e.g., await db.prepare() or await prepareDatabase() before
seedDatabase()), or add proper completion/future chaining or callbacks so
seeding runs only after the preparation future resolves rather than relying on
Future.delayed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/routes/docs/quick-starts/android-java/`+page.markdoc:
- Around line 137-144: The CoroutineCallback lambdas for the login, register,
and logout flows pass a Throwable `error` into AuthCallback.onError(), causing a
type mismatch; update each lambda (the three new CoroutineCallback<> instances)
to wrap the throwable into an Exception (e.g., new Exception(error)) before
calling callback.onError(...) so the parameter type matches
AuthCallback.onError().

In `@src/routes/docs/quick-starts/dart/prompt.md`:
- Around line 44-85: Update the SDK version used in the quick-start so the
TablesDB API calls work: change the dependency line in Step 2 to require
dart_appwrite 17.0.0 or later (for example `dart pub add dart_appwrite:^17.0.0`)
so that the code using TablesDB and its methods (TablesDB, createTable,
createVarcharColumn, createTextColumn, createBooleanColumn) is compatible;
alternatively remove the explicit version constraint to allow the latest SDK.

In `@src/routes/docs/quick-starts/deno/prompt.md`:
- Around line 173-175: The "Run and test" step uses the invalid command `deno
mod.ts`; update the instruction in prompt.md under the "Run and test" section to
use the correct Deno invocation and required permission flags by replacing `deno
mod.ts` with `deno run --allow-net mod.ts` (Appwrite needs network access) and
mention that the response will print to the console when the script runs.
- Around line 42-50: The snippet currently shows users calling
Client().setEndpoint(...).setProject(...).setKey(...) with a literal API key in
mod.ts; update the docs to demonstrate reading the project ID and API key from
environment variables (e.g., process.env or Deno.env.get) instead of hardcoding,
show how to load those values before calling Client.setProject and
Client.setKey, and add a short note telling users not to commit credentials to
source control and to store them in a secure secrets manager or .env ignored by
VCS.

In `@src/routes/docs/quick-starts/dotnet/prompt.md`:
- Around line 8-16: The markdown table in prompt.md (the block under "Integrate
with your server") lacks blank lines surrounding it causing MD058; edit the file
to add an empty line immediately before the table starts and an empty line
immediately after the table ends so the table is separated from surrounding
text, then save the changes to remove the lint warning.
- Around line 22-23: Update the pinned Appwrite .NET SDK version string "dotnet
add package Appwrite --version 0.13.0" to "dotnet add package Appwrite --version
0.25.0" in both occurrences (the prompt.md snippet and the +page.markdoc file)
so the docs reference the current stable release 0.25.0.

In `@src/routes/docs/quick-starts/kotlin/prompt.md`:
- Around line 27-32: The code block in prompt.md is labeled with the wrong fence
language; change the fenced code block marker from ```groovy to ```kotlin so the
Kotlin DSL snippet for build.gradle.kts (the dependencies { ...
implementation("io.appwrite:sdk-for-kotlin:9.0.0") } block) is correctly
highlighted and matches the Kotlin DSL syntax.
- Around line 66-92: The code in prepareDatabase() uses the unsafe pattern
todoDatabase?.id!! and todoTable?.id!! (combining safe-call and non-null
assertion); replace these with non-nullable locals or plain non-null accesses
after creation: assign val database = tablesDB.create(...) and todoDatabase =
database, val table = tablesDB.createTable(database.id, ... ) and todoTable =
table, then pass database.id and table.id to
createVarcharColumn/createTextColumn/createBooleanColumn to eliminate ?.!! usage
and ensure safe, readable null handling.
- Around line 117-136: The three createRow calls in seedDatabase use the
redundant and unsafe todoDatabase?.id!! and todoTable?.id!! pattern; replace
this by asserting or unwrapping the database/table once before the calls (e.g.,
compute val databaseId = requireNotNull(todoDatabase) { "..." }.id and val
tableId = requireNotNull(todoTable) { "..." }.id or assert todoDatabase!! and
todoTable!! once) and then pass databaseId and tableId into tablesDB.createRow
to remove the ?.!! repetition and ensure clear null-safety; see seedDatabase,
createRow, todoDatabase, todoTable and prepareDatabase for the same pattern.
- Around line 144-155: getTodos uses the unsafe pattern todoDatabase?.id!! and
todoTable?.id!! which can throw; update getTodos to first null-check
todoDatabase and todoTable (e.g., if either is null return or throw a clear
exception) and then call tablesDB.listRows with the non-null ids, or use let to
scope non-null values before calling tablesDB.listRows, referencing the getTodos
function and the todoDatabase/todoTable variables and the tablesDB.listRows
call.

In `@src/routes/docs/quick-starts/node/prompt.md`:
- Around line 20-26: The quick-start step currently hard-codes npm in the
project creation snippet; change the wording and example block in the "Create
Node.js project" step so it tells users to "use your package manager" and show
parallel examples for npm, yarn, and pnpm (e.g., npm init / yarn init / pnpm
init) instead of only "npm init"; update the same pattern in the later snippet
at lines referenced in the comment so all package-manager invocations are
non-prescriptive and include example variants.
- Around line 11-17: The markdown table in prompt.md (the pipe-delimited block
starting with "| Category | Required scopes | Purpose |") needs blank lines
before and after it to satisfy MD058; edit the prompt.md content to insert a
single empty line immediately above the table and another empty line immediately
below the table so the table is separated from surrounding paragraphs.
- Around line 78-84: The createTextColumn call is using the wrong option name
`xdefault`, which prevents the column default from being set; update the object
passed to tablesDB.createTextColumn (the call that includes databaseId:
todoDatabase.$id, tableId: todoTable.$id, key: 'description') to use `default`
instead of `xdefault` so the Appwrite Node SDK receives the correct parameter
name and the column default is applied.

In `@src/routes/docs/quick-starts/python/prompt.md`:
- Around line 7-14: The markdown table under the "Integrate with your server"
section in prompt.md violates MD058 (no blank lines around tables); fix it by
inserting a blank line immediately before the table header row and another blank
line immediately after the final table row so there is an empty line above the
header and below the table content, ensuring the table is separated from
surrounding paragraphs.

In `@src/routes/docs/quick-starts/swift/prompt.md`:
- Around line 20-22: The two occurrences of the product name "XCode" in the
Swift quick-start step should be corrected to the proper branding "Xcode";
update the sentence "Create a Swift CLI application by opening XCode > Create a
new XCode project > macOS > Command Line Tool." to use "Xcode" for both
instances so the step reads "...opening Xcode > Create a new Xcode project...".
- Around line 10-18: In the "Integrate with your server" section update the
Markdown by adding a blank line immediately before the table header row starting
with "| Category | Required scopes | Purpose |" and a blank line immediately
after the final table row ("| | `rows.write` | Allows API key to create, update,
and delete rows. |") so the table is separated by blank lines to satisfy MD058.
- Around line 52-81: The prepareDatabase function currently uses try? and
force-unwraps todoDatabase/todoTable which can silently fail; change
prepareDatabase to async throws and propagate errors instead of swallowing them,
replace try? with try for calls to tablesDB.create, tablesDB.createTable,
createVarcharColumn, createTextColumn, createBooleanColumn, and use safe
unwrapping (guard let todoDatabase = todoDatabase, guard let todoTable =
todoTable) or directly assign the results to non-optional Database/Table values
so the function returns concrete (Database, Table) and surfaces any errors to
the caller (update call sites to handle thrown errors).

---

Duplicate comments:
In `@src/routes/docs/quick-starts/php/prompt.md`:
- Line 212: The run command currently references "php src/index.php" but the
example creates "index.php"; update the run instruction by replacing the
incorrect path "php src/index.php" with "php index.php" so the command matches
the created file (locate the line containing the literal "Run: php
src/index.php" in prompt.md and change it to "Run: php index.php").

In `@src/routes/docs/quick-starts/python/prompt.md`:
- Around line 91-97: The call to tablesDB.create_text_column is using the wrong
parameter name for the column default; replace the default=... argument with
xdefault=... so the create_text_column (or create_string_column) call uses
xdefault='This is a test description.' while keeping database_id, table_id, key,
and required unchanged.

In `@src/routes/docs/quick-starts/swift/prompt.md`:
- Around line 70-79: Remove the forced as! String casts on IDs when calling
createTextColumn/createBooleanColumn: use todoDatabase!.id and todoTable!.id
directly or safely unwrap them before calling (e.g., guard let dbId =
todoDatabase?.id, let tableId = todoTable?.id else { ... }) and then pass
dbId/tableId to the methods instead of forcing as! String; update the calls to
createTextColumn and createBooleanColumn accordingly to avoid runtime crashes
from incorrect casts.
- Around line 136-137: In getTodos replace the forced casts on IDs by removing
"as! String" for databaseId and tableId (i.e., use the existing todoDatabase!.id
and todoTable!.id or perform safe optional binding/casting if needed) so you no
longer force-cast todoDatabase!.id and todoTable!.id; update the databaseId and
tableId assignments in the getTodos block to match the earlier fix (use the
native id values or guard-let cast to String) to avoid runtime force-casts.

---

Nitpick comments:
In `@src/routes/docs/quick-starts/dart/prompt.md`:
- Line 159: The explicit await Future.delayed(const Duration(seconds: 1)) is
likely a timing workaround between database preparation and seeding; remove this
hardcoded delay and instead ensure the preparation API is fully
awaited/completes before calling the seeding function (e.g., await db.prepare()
or await prepareDatabase() before seedDatabase()), or add proper
completion/future chaining or callbacks so seeding runs only after the
preparation future resolves rather than relying on Future.delayed.

In `@src/routes/docs/quick-starts/go/prompt.md`:
- Around line 9-15: Add blank lines immediately before and after the markdown
table block so the table is separated from surrounding content for correct
rendering; specifically, insert an empty line above the line beginning with "|
Category | Required scopes | Purpose |" and an empty line after the last table
row ("| | `rows.write` | Allows API key to create, update, and delete rows. |")
in src/routes/docs/quick-starts/go/prompt.md.
- Around line 39-45: Add a short explanatory note immediately after the initial
import block in prompt.md explaining that additional imports (e.g., the "id"
package added later in step 5 and "fmt" added in step 8) will be introduced
incrementally as the tutorial progresses; reference the existing import block
(the lines importing github.com/appwrite/... packages) so readers know to expect
later additions rather than a complete import list up front.

In `@src/routes/docs/quick-starts/swift/`+page.markdoc:
- Around line 99-133: The code in prepareDatabase uses try? and then
force-unwraps todoDatabase!.id and todoTable!.id (and uses unnecessary as!
String casts), which will crash on SDK errors; change to do/catch or use guard
let to safely unwrap the results from tablesDB.create and tablesDB.createTable
into todoDatabase and todoTable, handle failures by logging/returning (nil, nil)
or throwing, and then pass the unwrapped todoDatabase.id and todoTable.id
(without as! casts) into
createVarcharColumn/createTextColumn/createBooleanColumn; ensure each await call
either throws up to caller or is checked so no force-unwrapping remains.

Comment on lines +44 to +85
var tablesDB;
var todoDatabase;
var todoTable;

Future<void> prepareDatabase() async {
tablesDB = TablesDB(client);

todoDatabase = await tablesDB.create(
databaseId: ID.unique(),
name: 'TodosDB'
);

todoTable = await tablesDB.createTable(
databaseId: todoDatabase.$id,
tableId: ID.unique(),
name: 'Todos'
);

await tablesDB.createVarcharColumn(
databaseId: todoDatabase.$id,
tableId: todoTable.$id,
key: 'title',
size: 255,
xrequired: true
);

await tablesDB.createTextColumn(
databaseId: todoDatabase.$id,
tableId: todoTable.$id,
key: 'description',
xrequired: false,
xdefault: 'This is a test description'
);

await tablesDB.createBooleanColumn(
databaseId: todoDatabase.$id,
tableId: todoTable.$id,
key: 'isComplete',
xrequired: true
);
}
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

dart_appwrite 16.0.0 TablesDB API documentation class methods

💡 Result:

TablesDB does not exist in dart_appwrite 16.0.0, so there is no TablesDB class/method API documentation for that version. The TablesDB service was added in dart_appwrite 17.0.0. [1]

What to do instead:

  • If you must stay on 16.0.0, use the older Databases service API (collections/documents/attributes). [2]
  • If you want TablesDB, upgrade to dart_appwrite >= 17.0.0 and use the TablesDB methods documented here (Dart server SDK): list/create/update/delete tables, columns, indexes, and rows. [3]

Sources:
[1] dart_appwrite changelog (TablesDB added in 17.0.0) (pub.dev)
[2] Databases class API docs (Dart) (pub.dev)
[3] Appwrite TablesDB API reference (Server / Dart) (appwrite.io)

Citations:


🏁 Script executed:

# Search for TablesDB usage in codebase to verify if this is an established pattern
rg "TablesDB" -A 3 -B 1

# Search for other Dart quick-start or tutorial files
fd -e md "dart" | head -20

Repository: appwrite/website

Length of output: 50375


🏁 Script executed:

# Find and examine the Dart quick-start file
fd "dart" -t f | grep -E "(quick-start|prompt)" | head -20

# Get the full content of the Dart quick-start file to see version and imports
cat "src/routes/docs/quick-starts/dart/prompt.md" | head -100

Repository: appwrite/website

Length of output: 3382


Update dart_appwrite SDK version to 17.0.0 or later to match the TablesDB API usage.

The quick-start specifies dart pub add dart_appwrite:16.0.0 in Step 2, but Step 5 uses TablesDB with methods like createTable() and createVarcharColumn(), which are only available in dart_appwrite 17.0.0 and later. Change Step 2 to use version 17.0.0 or remove the version constraint to allow the latest version:

dart pub add dart_appwrite:^17.0.0
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dart/prompt.md` around lines 44 - 85, Update the
SDK version used in the quick-start so the TablesDB API calls work: change the
dependency line in Step 2 to require dart_appwrite 17.0.0 or later (for example
`dart pub add dart_appwrite:^17.0.0`) so that the code using TablesDB and its
methods (TablesDB, createTable, createVarcharColumn, createTextColumn,
createBooleanColumn) is compatible; alternatively remove the explicit version
constraint to allow the latest SDK.

Comment on lines +42 to +50
```ts
import { Client, ID, TablesDB, Models } from 'npm:node-appwrite';

const client: Client = new Client();

client
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('<PROJECT_ID>')
.setKey('<YOUR_API_KEY>');
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid hardcoding API keys in mod.ts.
This instructs users to paste a secret directly into source code, which is easy to commit accidentally. Prefer env vars and mention not to commit them.

Suggested doc tweak
-        client
-            .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
-            .setProject('<PROJECT_ID>')
-            .setKey('<YOUR_API_KEY>');
+        client
+            .setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
+            .setProject('<PROJECT_ID>')
+            .setKey(Deno.env.get('APPWRITE_API_KEY')!);
+
+        // Note: set APPWRITE_API_KEY in your environment and don't commit it.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/deno/prompt.md` around lines 42 - 50, The
snippet currently shows users calling
Client().setEndpoint(...).setProject(...).setKey(...) with a literal API key in
mod.ts; update the docs to demonstrate reading the project ID and API key from
environment variables (e.g., process.env or Deno.env.get) instead of hardcoding,
show how to load those values before calling Client.setProject and
Client.setKey, and add a short note telling users not to commit credentials to
source control and to store them in a secure secrets manager or .env ignored by
VCS.

Comment on lines +173 to +175
8. Run and test
- Run the project: `deno mod.ts`
- View the response in your console
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix the Deno run command and required permissions.
deno mod.ts isn’t a valid command. This should be deno run (and Appwrite requires network access).

Suggested doc tweak
-    - Run the project: `deno mod.ts`
+    - Run the project: `deno run --allow-net --allow-env mod.ts`
📝 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.

Suggested change
8. Run and test
- Run the project: `deno mod.ts`
- View the response in your console
8. Run and test
- Run the project: `deno run --allow-net --allow-env mod.ts`
- View the response in your console
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/deno/prompt.md` around lines 173 - 175, The "Run
and test" step uses the invalid command `deno mod.ts`; update the instruction in
prompt.md under the "Run and test" section to use the correct Deno invocation
and required permission flags by replacing `deno mod.ts` with `deno run
--allow-net mod.ts` (Appwrite needs network access) and mention that the
response will print to the console when the script runs.

Comment on lines +8 to +16
- Under **Integrate with your server**, add an **API Key** with the following scopes:
| Category | Required scopes | Purpose |
|-----------|-----------------------|---------|
| Database | `databases.write` | Allows API key to create, update, and delete databases. |
| | `tables.write` | Allows API key to create, update, and delete tables. |
| | `columns.write` | Allows API key to create, update, and delete columns. |
| | `rows.read` | Allows API key to read rows. |
| | `rows.write` | Allows API key to create, update, and delete rows. |
- Other scopes are optional.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add blank lines around the table to fix markdown lint warning.

The markdown linter flags MD058 (tables should be surrounded by blank lines) at lines 9 and 15.

Proposed fix
     - Under **Integrate with your server**, add an **API Key** with the following scopes:
+
       | Category | Required scopes | Purpose |
       |-----------|-----------------------|---------|
       | Database | `databases.write` | Allows API key to create, update, and delete databases. |
       | | `tables.write` | Allows API key to create, update, and delete tables. |
       | | `columns.write` | Allows API key to create, update, and delete columns. |
       | | `rows.read` | Allows API key to read rows. |
       | | `rows.write` | Allows API key to create, update, and delete rows. |
+
     - Other scopes are optional.
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 9-9: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 15-15: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dotnet/prompt.md` around lines 8 - 16, The
markdown table in prompt.md (the block under "Integrate with your server") lacks
blank lines surrounding it causing MD058; edit the file to add an empty line
immediately before the table starts and an empty line immediately after the
table ends so the table is separated from surrounding text, then save the
changes to remove the lint warning.

Comment on lines +78 to +84
await tablesDB.createTextColumn({
databaseId: todoDatabase.$id,
tableId: todoTable.$id,
key: 'description',
required: false,
xdefault: 'This is a test description'
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Appwrite Node.js SDK createTextColumn default value parameter

💡 Result:

In the Appwrite Node.js SDK (TablesDB service), createTextColumn takes an options object where the default value is passed via the default property:

await tablesDB.createTextColumn({
  databaseId,
  tableId,
  key,
  required: false,
  default: 'My default text', // optional
  array: false               // optional
});

Notes:

  • default is a string default used when the value isn’t provided.
  • You can’t set default when required: true. [1]

Source: Appwrite TablesDB “Create text column” (Node.js) reference. [1]

[1] https://appwrite.io/docs/references/cloud/server-nodejs/tablesDB


Change xdefault to default.

The Appwrite Node.js SDK's createTextColumn method expects the parameter name default, not xdefault. Using the incorrect key will silently fail to set the column's default value.

Corrected code
            await tablesDB.createTextColumn({
                databaseId: todoDatabase.$id,
                tableId: todoTable.$id,
                key: 'description',
                required: false,
                default: 'This is a test description'
            });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/node/prompt.md` around lines 78 - 84, The
createTextColumn call is using the wrong option name `xdefault`, which prevents
the column default from being set; update the object passed to
tablesDB.createTextColumn (the call that includes databaseId: todoDatabase.$id,
tableId: todoTable.$id, key: 'description') to use `default` instead of
`xdefault` so the Appwrite Node SDK receives the correct parameter name and the
column default is applied.

Comment on lines +20 to +22
2. Create Swift project
- Create a Swift CLI application by opening XCode > Create a new XCode project > macOS > Command Line Tool.
- Follow the wizard and open the new project.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use the correct product name “Xcode”.

“XCode” is a typo; Apple’s IDE is branded “Xcode”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/swift/prompt.md` around lines 20 - 22, The two
occurrences of the product name "XCode" in the Swift quick-start step should be
corrected to the proper branding "Xcode"; update the sentence "Create a Swift
CLI application by opening XCode > Create a new XCode project > macOS > Command
Line Tool." to use "Xcode" for both instances so the step reads "...opening
Xcode > Create a new Xcode project...".

Comment on lines +52 to +81
func prepareDatabase() async -> (Database?, Table?) {
let todoDatabase = try? await tablesDB.create(
databaseId: ID.unique(),
name: "TodosDB"
)
let todoTable = try? await tablesDB.createTable(
databaseId: todoDatabase!.id,
tableId: ID.unique(),
name: "Todos"
)
try? await tablesDB.createVarcharColumn(
databaseId: todoDatabase!.id,
tableId: todoTable!.id,
key: "title",
size: 255,
required: true
)
try? await tablesDB.createTextColumn(
databaseId: todoDatabase!.id as! String,
tableId: todoTable!.id as! String,
key: "description",
required: false,
default: "This is a test description."
)
try? await tablesDB.createBooleanColumn(
databaseId: todoDatabase!.id as! String,
tableId: todoTable!.id as! String,
key: "isComplete",
required: true
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t ignore errors or force-unwrap in a “confirm each step succeeds” flow.

Line 53–81 use try? and todoDatabase! / todoTable!, which can silently fail and then crash. This contradicts the instruction to confirm each step succeeds and surface errors. Prefer throwing on failure and safe unwrapping.

✅ Suggested fix (propagate errors and guard unwraps)
-        func prepareDatabase() async -> (Database?, Table?) {
-            let todoDatabase = try? await tablesDB.create(
+        func prepareDatabase() async throws -> (Database, Table) {
+            let todoDatabase = try await tablesDB.create(
                 databaseId: ID.unique(),
                 name: "TodosDB"
             )
-            let todoTable = try? await tablesDB.createTable(
-                databaseId: todoDatabase!.id,
+            let todoTable = try await tablesDB.createTable(
+                databaseId: todoDatabase.id,
                 tableId: ID.unique(),
                 name: "Todos"
             )
-            try? await tablesDB.createVarcharColumn(
-                databaseId: todoDatabase!.id,
-                tableId: todoTable!.id,
+            try await tablesDB.createVarcharColumn(
+                databaseId: todoDatabase.id,
+                tableId: todoTable.id,
                 key: "title",
                 size: 255,
                 required: true
             )
-            try? await tablesDB.createTextColumn(
-                databaseId: todoDatabase!.id as! String,
-                tableId: todoTable!.id as! String,
+            try await tablesDB.createTextColumn(
+                databaseId: todoDatabase.id,
+                tableId: todoTable.id,
                 key: "description",
                 required: false,
                 default: "This is a test description."
             )
-            try? await tablesDB.createBooleanColumn(
-                databaseId: todoDatabase!.id as! String,
-                tableId: todoTable!.id as! String,
+            try await tablesDB.createBooleanColumn(
+                databaseId: todoDatabase.id,
+                tableId: todoTable.id,
                 key: "isComplete",
                 required: true
             )
-
-            return (todoDatabase, todoTable)
+            return (todoDatabase, todoTable)
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/swift/prompt.md` around lines 52 - 81, The
prepareDatabase function currently uses try? and force-unwraps
todoDatabase/todoTable which can silently fail; change prepareDatabase to async
throws and propagate errors instead of swallowing them, replace try? with try
for calls to tablesDB.create, tablesDB.createTable, createVarcharColumn,
createTextColumn, createBooleanColumn, and use safe unwrapping (guard let
todoDatabase = todoDatabase, guard let todoTable = todoTable) or directly assign
the results to non-optional Database/Table values so the function returns
concrete (Database, Table) and surfaces any errors to the caller (update call
sites to handle thrown errors).

Copy link
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: 19

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

♻️ Duplicate comments (8)
src/routes/docs/quick-starts/python/prompt.md (1)

10-20: ⚠️ Potential issue | 🟡 Minor

Add blank lines around the scopes table.

The table still needs an empty line before and after it to satisfy MD058.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/python/prompt.md` around lines 10 - 20, The
markdown table under the "Integrate with your server" section (the API Key
scopes table listing Database rows.write/rows.write etc.) needs an empty line
added immediately before and immediately after the table to satisfy MD058;
update prompt.md by inserting a blank line above the table start and another
blank line after the table end so the table is separated from surrounding
paragraphs.
src/routes/docs/quick-starts/angular/prompt.md (1)

109-117: ⚠️ Potential issue | 🟠 Major

Await the login inside register().

This is the same async sequencing issue flagged earlier: this.login(email, password) should be awaited so the registration flow does not complete before the session/user state is updated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/angular/prompt.md` around lines 109 - 117, In
register() the call to this.login(email, password) is not awaited, so
registration may finish before the session/state updates; change register() to
await the login call (await this.login(email, password)) and propagate/return
the resulting promise as appropriate so the registration flow waits for login in
the register method defined in the same class (register and login).
src/routes/docs/quick-starts/node/prompt.md (3)

86-92: ⚠️ Potential issue | 🟠 Major

Use default, not xdefault, in the Node snippet.

The current Node TablesDB reference shows createTextColumn taking default for the fallback value, so this sample will not set the column default as written. (appwrite.io)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/node/prompt.md` around lines 86 - 92, The
snippet uses the wrong property name "xdefault" when calling
tablesDB.createTextColumn; change it to "default" so the column default value is
set correctly (locate the call to tablesDB.createTextColumn that uses
todoDatabase.$id, todoTable.$id and key 'description' and replace xdefault:
'This is a test description' with default: 'This is a test description').

23-35: ⚠️ Potential issue | 🟡 Minor

Don’t hard-code npm after promising package-manager neutrality.

The prompt says to respect the user’s package manager, but these setup/install steps still force npm.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/node/prompt.md` around lines 23 - 35, The docs
hard-code npm in "Step 2: Create Node.js project" and "Step 3: Install Appwrite
SDK" (lines showing `npm init` and `npm install node-appwrite`); update the text
to be package-manager neutral by either showing a generic placeholder like
"<your-package-manager> init" and "<your-package-manager> add node-appwrite" or
listing common equivalents (npm/yarn/pnpm) and explain the reader should use
their preferred manager so the guide no longer forces npm usage.

11-20: ⚠️ Potential issue | 🟡 Minor

Add blank lines around the scopes table.

This table still violates MD058 because it is flush with the surrounding list text.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/node/prompt.md` around lines 11 - 20, The
markdown table under the "Integrate with your server" section is flush with
surrounding list text and violates MD058; fix it by adding a blank line before
the table and a blank line after the table in
src/routes/docs/quick-starts/node/prompt.md (i.e., insert an empty line between
the preceding list paragraph and the table start, and another empty line after
the table end) so the table is separated from surrounding list text.
src/routes/docs/quick-starts/android/prompt.md (1)

143-214: ⚠️ Potential issue | 🟠 Major

Render a single auth state, and clear it on logout.

The form Column is still always rendered after the logged-in branch, so both UIs appear together once user is set. Also, the logout handler never resets user, so the screen will stay in the authenticated state even after deleteSession() succeeds.

Suggested fix
-                    if (user.isNotEmpty()) {
+                    if (user.isNotEmpty()) {
                         Column(
                             modifier = Modifier.fillMaxSize(),
                             horizontalAlignment = Alignment.CenterHorizontally,
                             verticalArrangement = Arrangement.Center
                         ) {
                             Text(text = "Logged in as $user")
                             Button(onClick = {
                                 coroutineScope.launch {
                                     Appwrite.onLogout()
+                                    user = ""
                                 }
                             }) {
                                 Text("Logout")
                             }
                         }
-                    }
-
-                    Column(
+                    } else {
+                    Column(
                         modifier = Modifier.fillMaxSize(),
                         horizontalAlignment = Alignment.CenterHorizontally,
                         verticalArrangement = Arrangement.Center
                     ) {
                         TextField(
@@
                         }
                     }
+                    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/android/prompt.md` around lines 143 - 214, The
UI currently renders both the logged-in block and the login/register form
because the form Column is not in the else branch, and the logout handler
(Appwrite.onLogout()) never clears the user state; change the top-level
conditional to if (user.isNotEmpty()) { ... } else { /* move the login/register
Column here */ } so only one auth state renders, and in the logout coroutine
(where Appwrite.onLogout() is called) set user = "" after the logout call
(inside the same coroutine and try/catch) to reset state; no other UI changes
needed, keep onLogin/onRegister logic as-is.
src/routes/docs/quick-starts/dart/prompt.md (1)

15-15: ⚠️ Potential issue | 🟠 Major

Bump dart_appwrite here or the later TablesDB sample won't compile.

This still installs dart_appwrite 16.0.0, but TablesDB was added in 17.0.0. As written, readers will install an SDK that does not contain the service used throughout Steps 5-8. (pub.dev)

Suggested fix
-- Run: `dart pub add dart_appwrite:16.0.0`
+- Run: `dart pub add dart_appwrite:^17.0.0`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dart/prompt.md` at line 15, Update the package
install command so readers get the release that contains TablesDB; change the
`dart pub add dart_appwrite:16.0.0` instruction to target 17.0.0 (or a
compatible range like ^17.0.0) so the `TablesDB` service used in Steps 5-8 is
available; edit the line in prompt.md that invokes `dart pub add
dart_appwrite:16.0.0` to use `17.0.0` (or `^17.0.0`) instead.
src/routes/docs/quick-starts/dotnet/prompt.md (1)

26-29: ⚠️ Potential issue | 🟡 Minor

Update the pinned Appwrite SDK version.

0.13.0 is stale here: the current official .NET SDK install instructions use Appwrite 1.0.0 and the latest release is dated March 3, 2026. Keeping the prompt on 0.13.0 teaches an outdated setup path and points readers at the older 1.7.x-compatible package instead of the current 1.8.x line. (github.com)

📦 Suggested update
-- Run: `dotnet add package Appwrite --version 0.13.0`
+- Run: `dotnet add package Appwrite --version 1.0.0`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dotnet/prompt.md` around lines 26 - 29, Update
the pinned Appwrite .NET SDK version in the "Step 3: Install Appwrite SDK"
prompt: replace the current install command string "dotnet add package Appwrite
--version 0.13.0" with the current official package version (e.g., "dotnet add
package Appwrite --version 1.0.0" or the latest released version) so the docs
point to the modern .NET SDK release.
🟡 Minor comments (10)
src/routes/docs/quick-starts/refine/prompt.md-5-5 (1)

5-5: ⚠️ Potential issue | 🟡 Minor

Don’t hardcode npm after promising package-manager neutrality.

The prompt says to respect the user’s package manager, but the concrete commands in Steps 2, 3, and 6 are npm-only. Agents following this literally will switch package managers and churn lockfiles. Parameterize these commands from the user’s chosen tool instead of hardcoding npm.

Also applies to: 18-18, 25-25, 137-137

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/refine/prompt.md` at line 5, The docs hardcode
"npm" in CLI examples even though the prompt promises package-manager
neutrality; update the commands in the prompt.md (Steps 2, 3, 6 and the other
occurrences noted) to use a parameterized package manager token (e.g., a
placeholder like {packageManager} or a helper substitution such as
getPackageManagerCmd()) instead of literal "npm" so agents and users can
substitute yarn/pnpm/etc.; ensure every npm-only command (install, run, add) is
replaced consistently and document the placeholder at the top of the file so
tooling can replace it.
src/routes/docs/quick-starts/nextjs/prompt.md-29-29 (1)

29-29: ⚠️ Potential issue | 🟡 Minor

Inconsistent error handling for missing credentials.

Line 29 instructs to "leave a placeholder and ask the user to provide them" if credentials aren't provided, but lines 34-36 show code that immediately throws an error when endpoint or projectId are empty strings. This creates a conflict: the placeholder approach suggests runtime configuration, while the error prevents the app from initializing.

💡 Suggested approach for better UX

Option 1 - Remove the error and provide clearer placeholder comments:

 const endpoint = '';
 const projectId = '';
-if (!endpoint || !projectId) throw new Error('Missing Appwrite endpoint and project ID');
+// TODO: Replace the above empty strings with your Appwrite endpoint and project ID

Option 2 - Use environment variables for runtime configuration:

-const endpoint = '';
-const projectId = '';
-if (!endpoint || !projectId) throw new Error('Missing Appwrite endpoint and project ID');
+const endpoint = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || '';
+const projectId = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '';
+if (!endpoint || !projectId) throw new Error('Missing Appwrite credentials. Set NEXT_PUBLIC_APPWRITE_ENDPOINT and NEXT_PUBLIC_APPWRITE_PROJECT_ID.');

Also applies to: 34-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/nextjs/prompt.md` at line 29, The docs and code
conflict: the docs tell users to leave placeholders in app/appwrite.js (or
app/appwrite.ts) for endpoint/projectId, but the file contains a check that
throws when endpoint or projectId are empty strings; update the file to match
the placeholder UX by removing the immediate throw and instead read from
environment variables (e.g. APPWRITE_ENDPOINT and APPWRITE_PROJECT_ID) with
clear placeholder comments and a non-fatal warning if values are missing, or
alternatively make the check only throw in production; locate the empty-string
check in app/appwrite.js / app/appwrite.ts and replace the throw with a warning
and env-based fallback so runtime configuration via placeholders works.
src/routes/docs/quick-starts/tanstack-start/prompt.md-28-30 (1)

28-30: ⚠️ Potential issue | 🟡 Minor

Fail fast on placeholders, not just empty strings.

'<REGION>' and '<PROJECT_ID>' are both truthy, so the guard on Line 30 never throws when the sample is left unconfigured. That pushes the first real error into the auth calls instead of catching config mistakes where they happen.

♻️ Suggested doc fix
 const endpoint = 'https://<REGION>.cloud.appwrite.io/v1';
 const projectId = '<PROJECT_ID>';
-if (!endpoint || !projectId) throw new Error('Missing Appwrite endpoint and project ID');
+if (
+    !endpoint ||
+    !projectId ||
+    endpoint.includes('<REGION>') ||
+    projectId.includes('<PROJECT_ID>')
+) {
+    throw new Error('Missing Appwrite endpoint and project ID');
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/tanstack-start/prompt.md` around lines 28 - 30,
The guard currently only checks for falsy endpoint/projectId, so placeholders
like '<REGION>' and '<PROJECT_ID>' bypass it; update the validation around the
endpoint and projectId variables to also detect placeholder tokens (e.g., values
equal to '<REGION>' or '<PROJECT_ID>' or matching a generic placeholder pattern
like /^<.*>$/) and throw a clear Error if detected so the sample fails fast when
left unconfigured (locate and modify the endpoint and projectId
initialization/validation).
src/routes/docs/quick-starts/python/prompt.md-33-42 (1)

33-42: ⚠️ Potential issue | 🟡 Minor

Fix the virtualenv activation copy.

“Active the venv” should be “Activate the venv”, and “Powershell” should be “PowerShell”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/python/prompt.md` around lines 33 - 42, Fix the
typos in the code block: change the line "Active the venv in Unix shell" to
"Activate the venv in Unix shell" and change "Powershell" to "PowerShell" (i.e.,
update the two strings in the prompt.md snippet so they read "Activate the venv
in Unix shell" and "Or in PowerShell" respectively).
src/routes/docs/quick-starts/angular/prompt.md-7-21 (1)

7-21: ⚠️ Potential issue | 🟡 Minor

The prompt still hard-codes npm despite the package-manager requirement.

That inconsistency shows up in both the install steps and the run command.

Also applies to: 137-138

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/angular/prompt.md` around lines 7 - 21, The
prompt hard-codes npm commands (`npm install -g `@angular/cli`` and `npm install
appwrite`) and run commands — update the text to respect the user's package
manager by replacing explicit `npm` invocations with a package-manager
placeholder or detection guidance (e.g., use the user's chosen package manager
variable or instructions to run the equivalent command with yarn/pnpm) and
adjust any run instructions referenced at lines 137-138 to use the same
package-manager-aware form; ensure `ng new . --directory .` and the guidance
about not using cd remain unchanged while swapping only the hard-coded package
manager strings.
src/routes/docs/quick-starts/nuxt/prompt.md-7-18 (1)

7-18: ⚠️ Potential issue | 🟡 Minor

Don’t force npm after telling the agent to honor the user’s package manager.

The install/run instructions are still npm-specific.

Also applies to: 112-113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/nuxt/prompt.md` around lines 7 - 18, The doc
currently hardcodes npm commands (the "npx nuxi@latest init ." and "npm install
appwrite" lines) which contradicts the requirement to honor the user's package
manager; update the instructions under "Step 1: Create or Use Existing Nuxt App"
and "Step 2: Install Appwrite SDK" to be package-manager-aware by offering
equivalent commands or a detection note (e.g., npx / yarn dlx / pnpm dlx for the
nuxi init step and npm install / yarn add / pnpm add for installing appwrite)
and state to run the appropriate command for the user's chosen package manager
rather than forcing npm.
src/routes/docs/quick-starts/react/prompt.md-31-34 (1)

31-34: ⚠️ Potential issue | 🟡 Minor

This “missing config” guard never fires with the provided placeholders.

'<REGION>' and '<PROJECT_ID>' are both truthy, so the error path will not catch an unconfigured sample. Either remove the guard or validate against placeholder values explicitly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/react/prompt.md` around lines 31 - 34, The
current guard using endpoint and projectId is ineffective because the
placeholder strings ('<REGION>' and '<PROJECT_ID>') are truthy; update the check
around endpoint and projectId (used to instantiate Client) to explicitly detect
placeholders (e.g. compare against '<REGION>' / '<PROJECT_ID>' or detect
angle-bracketed values) and throw the error when placeholders are present, or
remove the guard entirely if you prefer not to validate in this sample.
src/routes/docs/quick-starts/react-native/prompt.md-23-24 (1)

23-24: ⚠️ Potential issue | 🟡 Minor

The sample import path only matches one of the documented screen locations.

../lib/appwrite works from app/(tabs)/index.tsx, but not from app/auth.tsx, where the relative path would be ./lib/appwrite. Either split this into two snippets or explicitly tell readers to adjust the import based on where they place the screen.

Also applies to: 40-47

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/react-native/prompt.md` around lines 23 - 24,
The import path shown (../lib/appwrite) only works from certain screens (e.g.,
app/(tabs)/index.tsx) but fails from others (e.g., app/auth.tsx) where the
correct relative path is ./lib/appwrite; update the prompt in
src/routes/docs/quick-starts/react-native/prompt.md to either provide two
example import lines (one for screens under app/(tabs) and one for files like
app/auth.tsx) or add a short note telling readers to adjust the import path
based on their screen location (and apply the same change to the repeated
snippet at lines 40–47).
src/routes/docs/quick-starts/react/prompt.md-7-20 (1)

7-20: ⚠️ Potential issue | 🟡 Minor

Package-manager-neutral wording and commands are out of sync.

The prompt promises package-manager neutrality, but the create/install/run steps are still npm-specific.

Also applies to: 58-61

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/react/prompt.md` around lines 7 - 20, Update the
Step 1 and Step 2 instructions so they are package-manager-neutral: replace the
hardcoded commands ("npm create vite@latest . -- --template react" and "npm
install appwrite") with guidance to use the user's chosen package manager (e.g.,
use <package-manager> create vite... and <package-manager> install appwrite)
and/or detect the user's package manager before running commands; reference the
exact lines/phrases "Step 1: Check Current Directory and Set Up React App", the
create command string, and "Step 2: Install Appwrite" to ensure all occurrences
are updated (also apply same changes to the other occurrence mentioned at lines
58-61).
src/routes/docs/quick-starts/dart/prompt.md-3-3 (1)

3-3: ⚠️ Potential issue | 🟡 Minor

The prompt promises CRUD, but only create/read are implemented.

Steps 6-7 seed rows and list rows, but there is no update or delete example anywhere in the flow. If the prompt is meant to demonstrate CRUD, it should either add those steps or tone the intro down to create/read.

Also applies to: 96-181

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dart/prompt.md` at line 3, The intro claims full
CRUD but the document only shows create and read (notably Steps 6-7 that seed
rows and list rows); either add explicit update and delete examples (e.g., show
an updateRow function and a deleteRow function with sample usage after
seeding/listing) and integrate them into the flow or change the opening sentence
to say "create/read" only; update the examples and any references in the
subsequent sections (Steps 6-7 and the block covering lines 96-181) to reflect
whichever option you choose.
🧹 Nitpick comments (7)
src/routes/docs/quick-starts/apple/prompt.md (1)

63-85: The sample is not actually a singleton.

This section says “Create Appwrite Singleton”, but the code exposes a normal initializer and the view later creates a fresh instance with Appwrite(). Either implement shared with a private init, or rename the section to avoid misleading readers.

Proposed fix
 class Appwrite {
+    static let shared = Appwrite()
+
     var client: Client
     var account: Account
 
-    public init() {
+    private init() {
         self.client = Client()
             .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
             .setProject("<PROJECT_ID>")
 
         self.account = Account(client)
     }
 struct ContentView: View {
     `@StateObject` private var viewModel = ViewModel()
-    let appwrite = Appwrite()
+    let appwrite = Appwrite.shared
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/apple/prompt.md` around lines 63 - 85, The
Appwrite sample is not a singleton: the class Appwrite exposes a public init and
code later constructs Appwrite(), so either implement a true singleton or change
the doc heading; to fix, modify the Appwrite class (Appwrite.swift) to add a
static shared instance (e.g., static let shared = Appwrite()) and make the
initializer private (change public init to private init) so callers must use
Appwrite.shared, and update any example usage in the docs/view to instantiate
via Appwrite.shared instead of Appwrite(); alternatively, if you prefer not to
enforce a singleton, rename the section heading and examples to avoid calling it
a "Singleton".
src/routes/docs/quick-starts/nextjs/prompt.md (1)

80-80: Incomplete deliverables list.

The deliverables list mentions app/page.js, but Step 4 (line 45) indicates that for existing projects, a new route app/auth/page.js should be created instead of overriding the default route. The deliverables should reflect this conditional file creation.

📝 Proposed clarification
-- Files created/updated: `package.json` (deps), `app/appwrite.js`, `app/page.js`
+- Files created/updated: `package.json` (deps), `app/appwrite.js`, `app/page.js` (for new projects) or `app/auth/page.js` (for existing projects)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/nextjs/prompt.md` at line 80, Update the
deliverables list to reflect the conditional file creation: instead of always
listing `app/page.js`, state that the guide creates `app/page.js` for a new app
but for existing projects the instruction creates a new route at
`app/auth/page.js` (and still creates `app/appwrite.js` and updates
`package.json` dependencies); modify the text mentioning `app/page.js` to
mention "either `app/page.js` (new apps) or `app/auth/page.js` (existing
projects)" so it matches Step 4's guidance.
src/routes/docs/quick-starts/android-java/prompt.md (3)

304-310: Consider auto-login after successful registration.

Currently, users must manually log in after registering. Consider automatically logging in the user after successful registration for a smoother user experience.

✨ Auto-login after registration
         appwrite.register(email, password, new AppwriteHelper.AuthCallback<User<Map<String, Object>>>() {
             `@Override`
             public void onSuccess(User<Map<String, Object>> result) {
                 runOnUiThread(() -> {
-                    Toast.makeText(MainActivity.this, "Registration successful. You can now login.", Toast.LENGTH_SHORT).show();
+                    Toast.makeText(MainActivity.this, "Registration successful. Logging in...", Toast.LENGTH_SHORT).show();
+                    // Auto-login after successful registration
+                    login();
                 });
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/android-java/prompt.md` around lines 304 - 310,
After registration in appwrite.register(...) inside the AuthCallback.onSuccess
in MainActivity, automatically sign the user in by invoking the existing login
routine (e.g., call the method that performs authentication such as
appwrite.login(...) or reuse the MainActivity.login(...) helper) from inside
onSuccess, handle success/failure on the UI thread (Toast/navigation), and
ensure you preserve existing error handling and session state management so
registration flows directly to an authenticated state without requiring manual
login.

98-100: Potential loss of error information when wrapping exceptions.

Wrapping the error in new Exception(error) may lose the original exception type and stack trace. If error is already an Exception or Throwable, consider passing it directly or using new Exception(error.getMessage(), error) to preserve the cause chain.

This same pattern appears in the register method (line 115) and logout method (line 128).

♻️ Preserve exception information
             new CoroutineCallback<>((result, error) -> {
                 if (error != null) {
-                    callback.onError(new Exception(error));
+                    callback.onError(error instanceof Exception ? (Exception) error : new Exception(error));
                     return;
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/android-java/prompt.md` around lines 98 - 100,
The callback error handling wraps the incoming error in new Exception(error)
which can drop the original type and stack trace; update the CoroutineCallback
handlers (the anonymous handlers that call callback.onError(...)) to preserve
the cause by either passing the Throwable/Exception directly to callback.onError
if its signature accepts Throwable, or construct a new Exception using new
Exception(error.getMessage(), error) so the original error is set as the cause;
apply the same change in the register and logout handlers where callback.onError
is invoked to ensure the original exception chain and stacktrace are preserved.

267-274: Consider adding email format validation.

For a production app, you might want to validate the email format and password strength requirements before making the API call. However, for a quickstart guide, the current validation is acceptable.

📧 Optional email validation enhancement
     private void login() {
         String email = editTextEmail.getText().toString().trim();
         String password = editTextPassword.getText().toString().trim();
 
         if (email.isEmpty() || password.isEmpty()) {
             Toast.makeText(this, "Please enter email and password", Toast.LENGTH_SHORT).show();
             return;
         }
+        
+        if (!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
+            Toast.makeText(this, "Please enter a valid email address", Toast.LENGTH_SHORT).show();
+            return;
+        }
 
         appwrite.login(email, password, new AppwriteHelper.AuthCallback<Session>() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/android-java/prompt.md` around lines 267 - 274,
The login() method currently only checks for empty email/password; add an email
format validation step (and optionally a password-strength check) before
proceeding with the API call: after retrieving editTextEmail and
editTextPassword values in login(), validate the email using Android's
Patterns.EMAIL_ADDRESS.matcher(email).matches() (or a suitable regex) and show a
Toast indicating invalid email if it fails, and similarly enforce any
password-strength rules you want (length/character checks) before returning;
ensure these checks occur before the existing empty-field check returns control
so invalid input prevents the API call.
src/routes/docs/quick-starts/solid/prompt.md (2)

72-93: Consider adding error handling for authentication operations.

The async functions (login, register, logout) don't include try-catch blocks. While this keeps the quickstart simple, unhandled promise rejections could crash the application or leave it in an inconsistent state. Consider adding basic error handling or at least noting this limitation in the documentation.

🛡️ Example error handling pattern
async function login(email, password) {
    try {
        await account.createEmailPasswordSession({
            email,
            password
        });
        setLoggedInUser(await account.get());
    } catch (error) {
        console.error('Login failed:', error);
        // Optionally set error state to display to user
    }
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/solid/prompt.md` around lines 72 - 93, Wrap the
async auth helpers login, register, and logout in try/catch blocks to prevent
unhandled rejections: in login (function login) catch errors from
account.createEmailPasswordSession and account.get, log or surface the error
(e.g., console.error or an error state) and avoid calling setLoggedInUser on
failure; in register (function register) wrap account.create and the subsequent
login call in try/catch and await login so its errors propagate into the same
handler; in logout (function logout) catch errors from account.deleteSession and
handle/log them and ensure setLoggedInUser(null) only runs when logout succeeds
or is intentionally forced.

11-11: Consider clarifying hostname configuration.

The instruction mentions localhost as the hostname, but the dev server runs on port 3000 (per line 142). Depending on Appwrite's CORS configuration, users might need to specify localhost:3000 as the hostname. Consider adding a note about this to prevent potential CORS issues during testing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/solid/prompt.md` at line 11, Update the
instruction that currently says "Under **Add a platform**, add a **Web app**
with **Hostname** = `localhost` to clarify hostname + port for the dev server:
mention that if running the dev server on port 3000 users should specify
`localhost:3000` (or include both `localhost` and `http://localhost:3000` in
Appwrite's allowed origins/CORS) to avoid CORS issues; adjust the sentence in
the prompt.md content that contains the Hostname guidance accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/routes/docs/quick-starts/angular/prompt.md`:
- Around line 46-63: The docs currently reference app.module.ts and FormsModule
which won't exist for default standalone Angular apps; update the prompt to
either show the standalone approach (mention app.config.ts and adding
FormsModule to the bootstrap or component-level imports for a standalone
AppComponent) or explicitly instruct users to create a module-based project with
ng new my-app --no-standalone so they can edit app.module.ts and add FormsModule
to imports; reference app.module.ts, AppComponent, FormsModule, app.config.ts
and the ng new --no-standalone flag so readers know which path to follow.

In `@src/routes/docs/quick-starts/apple/prompt.md`:
- Around line 143-160: The Task closures for the Register and Login buttons call
appwrite.onRegister and appwrite.onLogin but do not catch errors or surface them
to the user; wrap each await call in a do/catch inside the Button Task, capture
the thrown error from onRegister/onLogin, and update the UI state (e.g., set a
viewModel.errorMessage or toggle a showErrorAlert boolean) so the view can
present an Alert or inline error; ensure you reference the Task closures around
the Button actions, the appwrite.onRegister and appwrite.onLogin calls, and the
viewModel properties you add/use to display the error.
- Around line 124-131: The view model is being recreated on updates because
ContentView declares its owned ViewModel with `@ObservedObject`; change the
property declaration in ContentView from "@ObservedObject var viewModel =
ViewModel()" to use "@StateObject var viewModel = ViewModel()" so the ViewModel
instance is created once and retained for the view's lifecycle (identify
symbols: ViewModel, ContentView, viewModel).

In `@src/routes/docs/quick-starts/dart/prompt.md`:
- Around line 170-171: Replace the fixed Future.delayed with an active readiness
poll: after await prepareDatabase() call a helper (e.g.,
waitForTableAndColumnsReady or pollColumnStatus) that repeatedly fetches the
table/column attributes returned by the Appwrite Dart SDK column/table APIs and
checks the attribute.status field until it equals 'available' (use exponential
backoff, an overall timeout, and surface errors if timeout is reached), then
call seedDatabase(); ensure you reference the same column/table IDs returned
during creation so the poll targets the exact resources.

In `@src/routes/docs/quick-starts/dotnet/prompt.md`:
- Around line 73-95: The column creation calls (CreateVarcharColumn,
CreateTextColumn, CreateBooleanColumn) return 202 and may not be available
immediately before CreateRow runs; add a readiness check: after each Create*
call poll the column status via the tables API (or a GetColumn/GetTable status
endpoint) in a short retry loop until status == "available" (with a
timeout/retry limit), or instead avoid the async gap by passing column
definitions directly into CreateTable so the schema is created atomically before
inserting rows; apply this check before the first CreateRow call.

In `@src/routes/docs/quick-starts/flutter/prompt.md`:
- Around line 130-145: MyAppState never loads the persisted session on startup
so loggedInUser remains null until login/register; add logic in
MyAppState.initState (or an async helper called from initState) to call
widget.account.get() (and/or verify the current session) and setState
loggedInUser if a user is returned, handling errors/empty responses gracefully
so the UI shows "Logged in as <name>" when a session already exists; ensure this
mirrors the existing post-login behavior in login() and register() and uses the
same models.User type.
- Around line 136-162: The auth methods login, register, and logout currently
let Appwrite exceptions bubble up, so update each (login ->
widget.account.createEmailPasswordSession, register -> widget.account.create,
logout -> widget.account.deleteSession) to catch AppwriteException (and generic
Exception) and set a UI-facing state variable (e.g., authError or lastAuthError)
via setState with the error message, then return/fail gracefully so the button
handlers can display it; ensure the register/login handlers still call login on
success and clear authError on success; apply the same catch-and-set-state
pattern to the other auth method blocks in this file referenced by the reviewer.

In `@src/routes/docs/quick-starts/go/prompt.md`:
- Around line 38-65: The quick-start is missing the Cloud region endpoint setup:
update the prompt and the client initialization by asking the user for a Cloud
Region (e.g., "fra", "nyc") and add
appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1") to the
appwrite.NewClient call (alongside appwrite.WithProject and appwrite.WithKey) so
the appwriteClient is configured for Appwrite Cloud.

In `@src/routes/docs/quick-starts/nextjs/prompt.md`:
- Line 6: Step 1 violates the doc's own rule by forcing npm via the
create-next-app flag; remove the `--use-npm` flag from the `create-next-app`
command in the prompt so the CLI can auto-detect the user's package manager
(i.e., update the Step 1 command that includes `create-next-app` to omit
`--use-npm`).
- Line 19: The docs hard-code npm in the installation step ("Run: `npm install
appwrite`") which conflicts with the earlier instruction to respect the user's
package manager; update that line in
src/routes/docs/quick-starts/nextjs/prompt.md to be package-manager agnostic by
replacing the hardcoded command with either a generic placeholder (e.g.,
"<package-manager> install appwrite") or by offering conditional commands for
common managers (npm, yarn, pnpm) so users can follow the correct install
command for their environment.
- Line 65: The README hardcodes "Run: `npm run dev`" which breaks the earlier
instruction to respect the user's package manager; update the text so it uses
the chosen package manager placeholder or variable used elsewhere (e.g.,
`{pkgManager}` or the same placeholder referenced on line 6) instead of
"npm"—replace the literal "npm run dev" with a generic command like
"`{pkgManager} run dev`" or a small conditional note that shows the equivalent
commands for npm/yarn/pnpm to keep consistency with the project's package
manager detection.

In `@src/routes/docs/quick-starts/node/prompt.md`:
- Around line 222-235: The Client initialization is missing the server API key;
update the Client chain (the Client instance created with setEndpoint and
setProject) to include .setKey('<YOUR_API_KEY>') after setProject so server-side
TablesDB calls work; locate the Client instantiation (symbols: Client,
setEndpoint, setProject, TablesDB) and add the setKey call in the same fluent
chain used before creating the TablesDB instance.

In `@src/routes/docs/quick-starts/nuxt/prompt.md`:
- Around line 73-81: The register function currently calls login(email.value,
password.value) without awaiting it, allowing register() to return before login
completes; update the register implementation (the async function register that
calls account.create and login) to await the login call (i.e., await
login(email.value, password.value)) so session creation and UI updates complete
before register resolves.

In `@src/routes/docs/quick-starts/refine/prompt.md`:
- Around line 17-18: Update the quick-start doc to explicitly split new-app vs
existing-app flows: change the bullet that currently reads "If the directory is
empty OR contains an existing project..." into two distinct bullets—one that
says when the directory is empty, scaffold the app with the command `npm create
refine-app@latest . -- --preset refine-appwrite`, and a second that says when an
existing Refine project (detects package.json, src/, config files) is present,
DO NOT run the scaffold command and instead proceed to the
integration/installation steps (install dependencies, run config scripts, and
update files) described later; apply the same split and wording adjustments to
the later block referenced (lines 22–26) so existing apps are routed to
install/configuration only.
- Around line 78-109: The Refine configuration uses NavigateToResource
(NavigateToResource) but no resources are provided to Refine (Refine), so
post-login redirection breaks; either add a resources entry to Refine that maps
the Appwrite collection (use the same <APPWRITE_TABLE_ID> value) so
NavigateToResource can resolve the target resource, or remove NavigateToResource
and replace it with a concrete navigation element (e.g., Navigate
to="/dashboard") in the authenticated route; update the resources prop on the
Refine component accordingly or swap the redirect to a fixed route to restore
correct post-login behavior.

In `@src/routes/docs/quick-starts/solid/prompt.md`:
- Around line 62-138: Add an initial session check on component mount: import
onMount from 'solid-js' and after the createSignal declarations add an
onMount(async () => { try { setLoggedInUser(await account.get()); } catch { /*
no active session */ } }); so the App uses account.get to populate loggedInUser
on load (references: onMount, createSignal, loggedInUser, setLoggedInUser,
account.get).
- Line 87: The login call is missing an await which creates a race with the
preceding account creation; update the call to await login(email, password) so
the code waits for the authentication to complete before proceeding. Locate the
call to login(email, password) and prefix it with await (ensuring the enclosing
function is async), and keep the surrounding account-creation call (e.g.,
createAccount / signUp) ordering intact so the account creation promise resolves
before the login attempt.

In `@src/routes/docs/quick-starts/tanstack-start/prompt.md`:
- Around line 5-6: Update the hardcoded npm commands in the quick-start prompt
so they respect the user's package manager: replace the scaffold/install/dev
commands that currently use npm with package-manager-aware variants (e.g.,
prefer `pnpm create `@tanstack/start`@latest` as the primary scaffold example
and/or show equivalents for pnpm/yarn/bun), or use a placeholder like
`<package-manager> create `@tanstack/start`@latest`, `<package-manager> install`
and `<package-manager> run dev` so the scaffold, install and dev commands (the
lines referencing the scaffold command, the install command, and the dev
command) no longer assume npm.
- Around line 39-40: The example route path in the sample is inconsistent with
the written instructions: if the file to scaffold is src/routes/auth.tsx you
must use createFileRoute('/auth') (whereas src/routes/index.tsx uses
createFileRoute('/')). Update the code sample that uses createFileRoute('/') to
use createFileRoute('/auth') when demonstrating creating src/routes/auth.tsx, or
provide two parallel examples (one using src/routes/index.tsx with
createFileRoute('/') and one using src/routes/auth.tsx with
createFileRoute('/auth')) so the file path and createFileRoute() argument match.

---

Minor comments:
In `@src/routes/docs/quick-starts/angular/prompt.md`:
- Around line 7-21: The prompt hard-codes npm commands (`npm install -g
`@angular/cli`` and `npm install appwrite`) and run commands — update the text to
respect the user's package manager by replacing explicit `npm` invocations with
a package-manager placeholder or detection guidance (e.g., use the user's chosen
package manager variable or instructions to run the equivalent command with
yarn/pnpm) and adjust any run instructions referenced at lines 137-138 to use
the same package-manager-aware form; ensure `ng new . --directory .` and the
guidance about not using cd remain unchanged while swapping only the hard-coded
package manager strings.

In `@src/routes/docs/quick-starts/dart/prompt.md`:
- Line 3: The intro claims full CRUD but the document only shows create and read
(notably Steps 6-7 that seed rows and list rows); either add explicit update and
delete examples (e.g., show an updateRow function and a deleteRow function with
sample usage after seeding/listing) and integrate them into the flow or change
the opening sentence to say "create/read" only; update the examples and any
references in the subsequent sections (Steps 6-7 and the block covering lines
96-181) to reflect whichever option you choose.

In `@src/routes/docs/quick-starts/nextjs/prompt.md`:
- Line 29: The docs and code conflict: the docs tell users to leave placeholders
in app/appwrite.js (or app/appwrite.ts) for endpoint/projectId, but the file
contains a check that throws when endpoint or projectId are empty strings;
update the file to match the placeholder UX by removing the immediate throw and
instead read from environment variables (e.g. APPWRITE_ENDPOINT and
APPWRITE_PROJECT_ID) with clear placeholder comments and a non-fatal warning if
values are missing, or alternatively make the check only throw in production;
locate the empty-string check in app/appwrite.js / app/appwrite.ts and replace
the throw with a warning and env-based fallback so runtime configuration via
placeholders works.

In `@src/routes/docs/quick-starts/nuxt/prompt.md`:
- Around line 7-18: The doc currently hardcodes npm commands (the "npx
nuxi@latest init ." and "npm install appwrite" lines) which contradicts the
requirement to honor the user's package manager; update the instructions under
"Step 1: Create or Use Existing Nuxt App" and "Step 2: Install Appwrite SDK" to
be package-manager-aware by offering equivalent commands or a detection note
(e.g., npx / yarn dlx / pnpm dlx for the nuxi init step and npm install / yarn
add / pnpm add for installing appwrite) and state to run the appropriate command
for the user's chosen package manager rather than forcing npm.

In `@src/routes/docs/quick-starts/python/prompt.md`:
- Around line 33-42: Fix the typos in the code block: change the line "Active
the venv in Unix shell" to "Activate the venv in Unix shell" and change
"Powershell" to "PowerShell" (i.e., update the two strings in the prompt.md
snippet so they read "Activate the venv in Unix shell" and "Or in PowerShell"
respectively).

In `@src/routes/docs/quick-starts/react-native/prompt.md`:
- Around line 23-24: The import path shown (../lib/appwrite) only works from
certain screens (e.g., app/(tabs)/index.tsx) but fails from others (e.g.,
app/auth.tsx) where the correct relative path is ./lib/appwrite; update the
prompt in src/routes/docs/quick-starts/react-native/prompt.md to either provide
two example import lines (one for screens under app/(tabs) and one for files
like app/auth.tsx) or add a short note telling readers to adjust the import path
based on their screen location (and apply the same change to the repeated
snippet at lines 40–47).

In `@src/routes/docs/quick-starts/react/prompt.md`:
- Around line 31-34: The current guard using endpoint and projectId is
ineffective because the placeholder strings ('<REGION>' and '<PROJECT_ID>') are
truthy; update the check around endpoint and projectId (used to instantiate
Client) to explicitly detect placeholders (e.g. compare against '<REGION>' /
'<PROJECT_ID>' or detect angle-bracketed values) and throw the error when
placeholders are present, or remove the guard entirely if you prefer not to
validate in this sample.
- Around line 7-20: Update the Step 1 and Step 2 instructions so they are
package-manager-neutral: replace the hardcoded commands ("npm create vite@latest
. -- --template react" and "npm install appwrite") with guidance to use the
user's chosen package manager (e.g., use <package-manager> create vite... and
<package-manager> install appwrite) and/or detect the user's package manager
before running commands; reference the exact lines/phrases "Step 1: Check
Current Directory and Set Up React App", the create command string, and "Step 2:
Install Appwrite" to ensure all occurrences are updated (also apply same changes
to the other occurrence mentioned at lines 58-61).

In `@src/routes/docs/quick-starts/refine/prompt.md`:
- Line 5: The docs hardcode "npm" in CLI examples even though the prompt
promises package-manager neutrality; update the commands in the prompt.md (Steps
2, 3, 6 and the other occurrences noted) to use a parameterized package manager
token (e.g., a placeholder like {packageManager} or a helper substitution such
as getPackageManagerCmd()) instead of literal "npm" so agents and users can
substitute yarn/pnpm/etc.; ensure every npm-only command (install, run, add) is
replaced consistently and document the placeholder at the top of the file so
tooling can replace it.

In `@src/routes/docs/quick-starts/tanstack-start/prompt.md`:
- Around line 28-30: The guard currently only checks for falsy
endpoint/projectId, so placeholders like '<REGION>' and '<PROJECT_ID>' bypass
it; update the validation around the endpoint and projectId variables to also
detect placeholder tokens (e.g., values equal to '<REGION>' or '<PROJECT_ID>' or
matching a generic placeholder pattern like /^<.*>$/) and throw a clear Error if
detected so the sample fails fast when left unconfigured (locate and modify the
endpoint and projectId initialization/validation).

---

Duplicate comments:
In `@src/routes/docs/quick-starts/android/prompt.md`:
- Around line 143-214: The UI currently renders both the logged-in block and the
login/register form because the form Column is not in the else branch, and the
logout handler (Appwrite.onLogout()) never clears the user state; change the
top-level conditional to if (user.isNotEmpty()) { ... } else { /* move the
login/register Column here */ } so only one auth state renders, and in the
logout coroutine (where Appwrite.onLogout() is called) set user = "" after the
logout call (inside the same coroutine and try/catch) to reset state; no other
UI changes needed, keep onLogin/onRegister logic as-is.

In `@src/routes/docs/quick-starts/angular/prompt.md`:
- Around line 109-117: In register() the call to this.login(email, password) is
not awaited, so registration may finish before the session/state updates; change
register() to await the login call (await this.login(email, password)) and
propagate/return the resulting promise as appropriate so the registration flow
waits for login in the register method defined in the same class (register and
login).

In `@src/routes/docs/quick-starts/dart/prompt.md`:
- Line 15: Update the package install command so readers get the release that
contains TablesDB; change the `dart pub add dart_appwrite:16.0.0` instruction to
target 17.0.0 (or a compatible range like ^17.0.0) so the `TablesDB` service
used in Steps 5-8 is available; edit the line in prompt.md that invokes `dart
pub add dart_appwrite:16.0.0` to use `17.0.0` (or `^17.0.0`) instead.

In `@src/routes/docs/quick-starts/dotnet/prompt.md`:
- Around line 26-29: Update the pinned Appwrite .NET SDK version in the "Step 3:
Install Appwrite SDK" prompt: replace the current install command string "dotnet
add package Appwrite --version 0.13.0" with the current official package version
(e.g., "dotnet add package Appwrite --version 1.0.0" or the latest released
version) so the docs point to the modern .NET SDK release.

In `@src/routes/docs/quick-starts/node/prompt.md`:
- Around line 86-92: The snippet uses the wrong property name "xdefault" when
calling tablesDB.createTextColumn; change it to "default" so the column default
value is set correctly (locate the call to tablesDB.createTextColumn that uses
todoDatabase.$id, todoTable.$id and key 'description' and replace xdefault:
'This is a test description' with default: 'This is a test description').
- Around line 23-35: The docs hard-code npm in "Step 2: Create Node.js project"
and "Step 3: Install Appwrite SDK" (lines showing `npm init` and `npm install
node-appwrite`); update the text to be package-manager neutral by either showing
a generic placeholder like "<your-package-manager> init" and
"<your-package-manager> add node-appwrite" or listing common equivalents
(npm/yarn/pnpm) and explain the reader should use their preferred manager so the
guide no longer forces npm usage.
- Around line 11-20: The markdown table under the "Integrate with your server"
section is flush with surrounding list text and violates MD058; fix it by adding
a blank line before the table and a blank line after the table in
src/routes/docs/quick-starts/node/prompt.md (i.e., insert an empty line between
the preceding list paragraph and the table start, and another empty line after
the table end) so the table is separated from surrounding list text.

In `@src/routes/docs/quick-starts/python/prompt.md`:
- Around line 10-20: The markdown table under the "Integrate with your server"
section (the API Key scopes table listing Database rows.write/rows.write etc.)
needs an empty line added immediately before and immediately after the table to
satisfy MD058; update prompt.md by inserting a blank line above the table start
and another blank line after the table end so the table is separated from
surrounding paragraphs.

---

Nitpick comments:
In `@src/routes/docs/quick-starts/android-java/prompt.md`:
- Around line 304-310: After registration in appwrite.register(...) inside the
AuthCallback.onSuccess in MainActivity, automatically sign the user in by
invoking the existing login routine (e.g., call the method that performs
authentication such as appwrite.login(...) or reuse the MainActivity.login(...)
helper) from inside onSuccess, handle success/failure on the UI thread
(Toast/navigation), and ensure you preserve existing error handling and session
state management so registration flows directly to an authenticated state
without requiring manual login.
- Around line 98-100: The callback error handling wraps the incoming error in
new Exception(error) which can drop the original type and stack trace; update
the CoroutineCallback handlers (the anonymous handlers that call
callback.onError(...)) to preserve the cause by either passing the
Throwable/Exception directly to callback.onError if its signature accepts
Throwable, or construct a new Exception using new Exception(error.getMessage(),
error) so the original error is set as the cause; apply the same change in the
register and logout handlers where callback.onError is invoked to ensure the
original exception chain and stacktrace are preserved.
- Around line 267-274: The login() method currently only checks for empty
email/password; add an email format validation step (and optionally a
password-strength check) before proceeding with the API call: after retrieving
editTextEmail and editTextPassword values in login(), validate the email using
Android's Patterns.EMAIL_ADDRESS.matcher(email).matches() (or a suitable regex)
and show a Toast indicating invalid email if it fails, and similarly enforce any
password-strength rules you want (length/character checks) before returning;
ensure these checks occur before the existing empty-field check returns control
so invalid input prevents the API call.

In `@src/routes/docs/quick-starts/apple/prompt.md`:
- Around line 63-85: The Appwrite sample is not a singleton: the class Appwrite
exposes a public init and code later constructs Appwrite(), so either implement
a true singleton or change the doc heading; to fix, modify the Appwrite class
(Appwrite.swift) to add a static shared instance (e.g., static let shared =
Appwrite()) and make the initializer private (change public init to private
init) so callers must use Appwrite.shared, and update any example usage in the
docs/view to instantiate via Appwrite.shared instead of Appwrite();
alternatively, if you prefer not to enforce a singleton, rename the section
heading and examples to avoid calling it a "Singleton".

In `@src/routes/docs/quick-starts/nextjs/prompt.md`:
- Line 80: Update the deliverables list to reflect the conditional file
creation: instead of always listing `app/page.js`, state that the guide creates
`app/page.js` for a new app but for existing projects the instruction creates a
new route at `app/auth/page.js` (and still creates `app/appwrite.js` and updates
`package.json` dependencies); modify the text mentioning `app/page.js` to
mention "either `app/page.js` (new apps) or `app/auth/page.js` (existing
projects)" so it matches Step 4's guidance.

In `@src/routes/docs/quick-starts/solid/prompt.md`:
- Around line 72-93: Wrap the async auth helpers login, register, and logout in
try/catch blocks to prevent unhandled rejections: in login (function login)
catch errors from account.createEmailPasswordSession and account.get, log or
surface the error (e.g., console.error or an error state) and avoid calling
setLoggedInUser on failure; in register (function register) wrap account.create
and the subsequent login call in try/catch and await login so its errors
propagate into the same handler; in logout (function logout) catch errors from
account.deleteSession and handle/log them and ensure setLoggedInUser(null) only
runs when logout succeeds or is intentionally forced.
- Line 11: Update the instruction that currently says "Under **Add a platform**,
add a **Web app** with **Hostname** = `localhost` to clarify hostname + port for
the dev server: mention that if running the dev server on port 3000 users should
specify `localhost:3000` (or include both `localhost` and
`http://localhost:3000` in Appwrite's allowed origins/CORS) to avoid CORS
issues; adjust the sentence in the prompt.md content that contains the Hostname
guidance accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8fee58e4-a5b1-4f98-85a7-2b0a1028d5be

📥 Commits

Reviewing files that changed from the base of the PR and between c168663 and 2ce5efe.

📒 Files selected for processing (25)
  • src/routes/docs/quick-starts/android-java/prompt.md
  • src/routes/docs/quick-starts/android/prompt.md
  • src/routes/docs/quick-starts/angular/prompt.md
  • src/routes/docs/quick-starts/apple/prompt.md
  • src/routes/docs/quick-starts/dart/prompt.md
  • src/routes/docs/quick-starts/deno/prompt.md
  • src/routes/docs/quick-starts/dotnet/prompt.md
  • src/routes/docs/quick-starts/flutter/prompt.md
  • src/routes/docs/quick-starts/go/prompt.md
  • src/routes/docs/quick-starts/kotlin/prompt.md
  • src/routes/docs/quick-starts/nextjs/prompt.md
  • src/routes/docs/quick-starts/node/prompt.md
  • src/routes/docs/quick-starts/nuxt/prompt.md
  • src/routes/docs/quick-starts/php/prompt.md
  • src/routes/docs/quick-starts/python/prompt.md
  • src/routes/docs/quick-starts/react-native/prompt.md
  • src/routes/docs/quick-starts/react/prompt.md
  • src/routes/docs/quick-starts/refine/prompt.md
  • src/routes/docs/quick-starts/ruby/prompt.md
  • src/routes/docs/quick-starts/solid/prompt.md
  • src/routes/docs/quick-starts/sveltekit/prompt.md
  • src/routes/docs/quick-starts/swift/prompt.md
  • src/routes/docs/quick-starts/tanstack-start/prompt.md
  • src/routes/docs/quick-starts/vue/prompt.md
  • src/routes/docs/quick-starts/web/prompt.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/routes/docs/quick-starts/php/prompt.md
  • src/routes/docs/quick-starts/vue/prompt.md
  • src/routes/docs/quick-starts/ruby/prompt.md
  • src/routes/docs/quick-starts/deno/prompt.md
  • src/routes/docs/quick-starts/web/prompt.md
  • src/routes/docs/quick-starts/kotlin/prompt.md
  • src/routes/docs/quick-starts/sveltekit/prompt.md
  • src/routes/docs/quick-starts/swift/prompt.md

Comment on lines +46 to +63
- First, add `FormsModule` import to handle the login form. Update `app.module.ts`:

```ts
import { FormsModule } from '@angular/forms';
...
@NgModule({
declarations: [
// ...
],
imports: [
// ...
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Angular CLI ng new default 2026 standalone app

💡 Result:

As of Angular v21 (March 2026), ng new creates a standalone-based app by default (--standalone defaults to true). [1]

  • Default (standalone):
    ng new my-app
  • Force NgModule-based project:
    ng new my-app --no-standalone

If your goal is to change defaults for generators (e.g., ng generate component), you can set schematics defaults in angular.json (example shown in Angular workspace config docs). [2]

Sources: [1] [2]


🌐 Web query:

Angular CLI documentation current version default project structure

💡 Result:

Current Angular CLI version (stable)

  • Angular’s docs note that Angular core and Angular CLI major versions are aligned. [1]
  • As of March 9, 2026, the latest stable Angular line is v21, with a latest patch commonly listed as @angular/cli 21.1.4. [2][3]

Default ng new project structure (current defaults)

ng new my-app creates a workspace (root config files) and puts the initial app in src/ by default. [4][5]

Workspace root (typical)

  • angular.json (workspace/project build/test/serve config) [5]
  • package.json, package-lock.json [5]
  • tsconfig.json (base TS config) [5]
  • src/ (root application source) [5]
  • public/ (static assets copied/served as-is) [5]
  • node_modules/ [5]

Inside src/ (typical)

  • app/ (application code) [5]
  • index.html, main.ts, global styles.*, etc. [5]

Standalone is the default

  • ng new defaults to standalone = true, so you typically get src/app/app.config.ts (standalone app config). [4][5]
  • src/app/app.module.ts is only generated when --standalone false. [5]

Multi-project note

  • Additional generated apps/libraries go under projects/. [4][5]
  • If you want everything (including the first app) under projects/, create an empty workspace with --no-create-application and then generate apps. [4][5]

Sources
[1] Angular “Versioning and releases” https://angular.dev/reference/releases (angular.dev)
[2] eosl.date Angular release table (shows latest in v21 line) https://eosl.date/eol/product/angular/ (eosl.date)
[3] Aikido Intel package page (lists @angular/cli latest) https://intel.aikido.dev/packages/npm/%40angular/cli (intel.aikido.dev)
[4] ng new reference https://angular.dev/cli/new (angular.dev)
[5] Angular “File structure” reference https://angular.dev/reference/configs/file-structure (angular.dev)

Citations:


The app.module.ts file does not exist in default Angular CLI apps.

As of Angular v21, ng new creates a standalone app by default. The app.module.ts file is only present when explicitly using the --no-standalone flag. Users following this prompt with the default ng new command will not find the file to edit, causing this instruction to fail.

Update the snippet to either:

  1. Show the standalone setup using app.config.ts instead, or
  2. Explicitly instruct users to create the project with ng new my-app --no-standalone if module-based setup is required
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/angular/prompt.md` around lines 46 - 63, The
docs currently reference app.module.ts and FormsModule which won't exist for
default standalone Angular apps; update the prompt to either show the standalone
approach (mention app.config.ts and adding FormsModule to the bootstrap or
component-level imports for a standalone AppComponent) or explicitly instruct
users to create a module-based project with ng new my-app --no-standalone so
they can edit app.module.ts and add FormsModule to imports; reference
app.module.ts, AppComponent, FormsModule, app.config.ts and the ng new
--no-standalone flag so readers know which path to follow.

Comment on lines +143 to +160
Button(
action: { Task {
try await appwrite.onRegister(
viewModel.email,
viewModel.password
)
}},
label: {
Text("Register")
}
)
Button(
action: { Task {
try await appwrite.onLogin(
viewModel.email,
viewModel.password
)
}},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In SwiftUI, does Task { try await someAsyncThrowingCall() } compile without handling the thrown error, or must the error be caught inside the task closure?

💡 Result:

Yes—Task { try await someAsyncThrowingCall() } compiles even if you don’t catch the error inside the closure.

That’s because the unstructured Task { … } initializer has an overload whose operation is async throws; any thrown error is captured in the returned Task (e.g. Task<Void, Error>) and won’t be reported unless you later try await task.value (or inspect await task.result). (forums.swift.org)

However, SwiftUI’s .task { … } view modifier does not accept a throwing closure (() async -> Void), so inside .task you must handle errors (e.g. do/catch, or try?). (stackoverflow.com)

Citations:


🏁 Script executed:

# First, find and read the file in question
fd "prompt.md" src/routes/docs/quick-starts/apple/ -x cat -n {}

Repository: appwrite/website

Length of output: 6680


Handle errors inside each Task to provide user feedback.

These button handlers capture errors in the Task object but never display them to the user, so authentication failures will silently fail. Add error handling to surface Appwrite errors to the UI.

Proposed fix
             Button(
                 action: { Task {
-                    try await appwrite.onRegister(
-                        viewModel.email,
-                        viewModel.password
-                    )
+                    do {
+                        try await appwrite.onRegister(
+                            viewModel.email,
+                            viewModel.password
+                        )
+                    } catch {
+                        // Surface the Appwrite error in the UI
+                    }
                 }},
                 label: {
                     Text("Register")
                 }
             )
             Button(
                 action: { Task {
-                    try await appwrite.onLogin(
-                        viewModel.email,
-                        viewModel.password
-                    )
+                    do {
+                        try await appwrite.onLogin(
+                            viewModel.email,
+                            viewModel.password
+                        )
+                    } catch {
+                        // Surface the Appwrite error in the UI
+                    }
                 }},
                 label: {
                     Text("Login")
                 }
             )
📝 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.

Suggested change
Button(
action: { Task {
try await appwrite.onRegister(
viewModel.email,
viewModel.password
)
}},
label: {
Text("Register")
}
)
Button(
action: { Task {
try await appwrite.onLogin(
viewModel.email,
viewModel.password
)
}},
Button(
action: { Task {
do {
try await appwrite.onRegister(
viewModel.email,
viewModel.password
)
} catch {
// Surface the Appwrite error in the UI
}
}},
label: {
Text("Register")
}
)
Button(
action: { Task {
do {
try await appwrite.onLogin(
viewModel.email,
viewModel.password
)
} catch {
// Surface the Appwrite error in the UI
}
}},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/apple/prompt.md` around lines 143 - 160, The
Task closures for the Register and Login buttons call appwrite.onRegister and
appwrite.onLogin but do not catch errors or surface them to the user; wrap each
await call in a do/catch inside the Button Task, capture the thrown error from
onRegister/onLogin, and update the UI state (e.g., set a viewModel.errorMessage
or toggle a showErrorAlert boolean) so the view can present an Alert or inline
error; ensure you reference the Task closures around the Button actions, the
appwrite.onRegister and appwrite.onLogin calls, and the viewModel properties you
add/use to display the error.

Comment on lines +170 to +171
await prepareDatabase();
await Future.delayed(const Duration(seconds: 1));
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's confirm the file exists and check the relevant section
cat -n src/routes/docs/quick-starts/dart/prompt.md | sed -n '160,180p'

Repository: appwrite/website

Length of output: 692


🏁 Script executed:

# Also check the surrounding context to understand the full flow
cat -n src/routes/docs/quick-starts/dart/prompt.md | sed -n '1,200p' | tail -100

Repository: appwrite/website

Length of output: 2984


🌐 Web query:

Appwrite createBooleanColumn API response 202 Accepted asynchronous

💡 Result:

createBooleanColumn (Databases → Create boolean attribute: POST /databases/{databaseId}/collections/{collectionId}/attributes/boolean) returns HTTP 202 Accepted because schema/attribute creation is handled asynchronously—the request is accepted and queued, not necessarily finished when the response is returned. [1]

The JSON you get back is an AttributeBoolean object that includes a status field. While the job runs, status can be processing; once done it becomes available. If something goes wrong you may see failed or stuck, with details in error. [2]

To wait for completion, poll Get attribute (or List attributes) until the attribute’s status is available. [2]

Sources:
[1] Appwrite Databases REST API Reference – Create boolean attribute (202 response) (appwrite.io)
[2] Appwrite Model – AttributeBoolean (status values, error) (appwrite.io)

Citations:


🏁 Script executed:

# Search for other quickstart files to see if this pattern appears elsewhere
find . -path "*/quick-starts/*" -name "*.md" -type f | head -20

Repository: appwrite/website

Length of output: 1014


🏁 Script executed:

# Check if there are similar patterns in other language quickstarts
grep -r "Future.delayed\|await.*delay\|sleep\|readiness" src/routes/docs/quick-starts/ --include="*.md" | head -20

Repository: appwrite/website

Length of output: 157


🏁 Script executed:

# Check a few other quickstart files to see how they handle the schema creation delay
cat -n src/routes/docs/quick-starts/node/prompt.md | sed -n '150,180p'

Repository: appwrite/website

Length of output: 1273


🏁 Script executed:

# Check Python quickstart
cat -n src/routes/docs/quick-starts/python/prompt.md | sed -n '150,180p'

Repository: appwrite/website

Length of output: 999


🏁 Script executed:

# Check Go quickstart
cat -n src/routes/docs/quick-starts/go/prompt.md | sed -n '150,180p'

Repository: appwrite/website

Length of output: 825


🏁 Script executed:

# Check if there's documentation about proper polling patterns in Dart quickstart or elsewhere
grep -r "status.*available\|polling\|waitFor\|readiness" src/routes/docs/quick-starts/ --include="*.md" | head -10

Repository: appwrite/website

Length of output: 42


🏁 Script executed:

# Let's check the main function in other quickstarts to see if they also have delays
grep -A 10 "main()" src/routes/docs/quick-starts/node/prompt.md | head -20

Repository: appwrite/website

Length of output: 42


🏁 Script executed:

# Check Python's main execution
grep -B 2 -A 10 "__main__\|if __name__" src/routes/docs/quick-starts/python/prompt.md | head -30

Repository: appwrite/website

Length of output: 674


🏁 Script executed:

# Check Go's main function
grep -B 2 -A 10 "func main()" src/routes/docs/quick-starts/go/prompt.md | head -30

Repository: appwrite/website

Length of output: 572


🏁 Script executed:

# Let's also verify the specific Appwrite Dart SDK behavior documentation
web_search

Repository: appwrite/website

Length of output: 110


🏁 Script executed:

# Let me check if the Node and Python quickstarts might also have timing issues or delays somewhere else
grep -C 5 "prepareDatabase\|prepare_database" src/routes/docs/quick-starts/node/prompt.md | head -30

Repository: appwrite/website

Length of output: 483


🏁 Script executed:

# Check Python's prepare_database more completely
grep -C 10 "def prepare_database" src/routes/docs/quick-starts/python/prompt.md | head -40

Repository: appwrite/website

Length of output: 441


🏁 Script executed:

# Let's verify if other quickstarts might have the same timing issue by checking
# if they also use column creation without proper readiness checks
cat -n src/routes/docs/quick-starts/node/prompt.md | sed -n '60,100p'

Repository: appwrite/website

Length of output: 1300


🏁 Script executed:

# Check if there's any documentation about this pattern in the repository
grep -r "202\|Accepted\|asynchronous\|readiness\|polling.*attribute\|status.*available" src/routes/docs/ --include="*.md" | grep -i "column\|attribute\|schema" | head -10

Repository: appwrite/website

Length of output: 42


Replace the hard-coded delay with a polling readiness check.

The column-creation APIs in Step 5 return HTTP 202 Accepted, meaning schema creation is asynchronous. A one-second delay doesn't guarantee completion and makes this quickstart flaky—seedDatabase() can race the column creation on slower environments or under load. The Appwrite Dart SDK's column methods return an attribute object with a status field that progresses from processing to available. Polling this status before calling seedDatabase() is more reliable than a fixed delay.

Suggested fix
-    await Future.delayed(const Duration(seconds: 1));
+    await waitForSchemaReady();
     await seedDatabase();
     await getTodos();

A helper that polls table and column readiness (checking status == 'available') would eliminate the race condition entirely.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dart/prompt.md` around lines 170 - 171, Replace
the fixed Future.delayed with an active readiness poll: after await
prepareDatabase() call a helper (e.g., waitForTableAndColumnsReady or
pollColumnStatus) that repeatedly fetches the table/column attributes returned
by the Appwrite Dart SDK column/table APIs and checks the attribute.status field
until it equals 'available' (use exponential backoff, an overall timeout, and
surface errors if timeout is reached), then call seedDatabase(); ensure you
reference the same column/table IDs returned during creation so the poll targets
the exact resources.

Comment on lines +73 to +95
await tablesDB.CreateVarcharColumn(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
key: "title",
size: 255,
required: true
);

await tablesDB.CreateTextColumn(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
key: "description",
required: false,
xdefault: "This is a test description"
);

await tablesDB.CreateBooleanColumn(
databaseId: todoDatabase.Id,
tableId: todoTable.Id,
key: "isComplete",
required: true
);
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/routes/docs/quick-starts/dotnet/prompt.md | head -100

Repository: appwrite/website

Length of output: 3719


🏁 Script executed:

cat -n src/routes/docs/quick-starts/dotnet/prompt.md | sed -n '97,130p'

Repository: appwrite/website

Length of output: 995


🌐 Web query:

Appwrite .NET API CreateVarcharColumn CreateTextColumn HTTP status code 202

💡 Result:

In Appwrite, getting HTTP 202 Accepted from the .NET SDK when calling CreateTextColumn / CreateVarcharColumn (i.e., CreateTextAttribute / CreateVarcharAttribute) is expected.

  • Appwrite uses 202 Accepted to mean “accepted for processing but not completed yet” (schema changes like attribute/column creation are asynchronous). [1]
  • In the Appwrite .NET Databases API reference, the Create text attribute and Create varchar attribute endpoints explicitly list 202 application/json as the success response. [2]

What to do: after creating the column, poll GetAttribute(...) (or list attributes) until the returned attribute status becomes available before creating/updating documents that use that column—otherwise you can hit “unknown attribute”/invalid structure errors while it’s still processing. [2]

Sources:
[1] Appwrite “Response codes” (202 Accepted) (appwrite.io)
[2] Appwrite .NET Databases reference (CreateTextAttribute/CreateVarcharAttribute return 202; GetAttribute available) (appwrite.io)

Citations:


🌐 Web query:

Appwrite .NET TablesDB CreateVarcharColumn CreateTextColumn CreateBooleanColumn async 202

💡 Result:

In the Appwrite .NET Server SDK (TablesDB), these column-creation calls are async and you typically await them, but the HTTP response is 202 Accepted because column creation is processed asynchronously on the server side (the returned column can have status: processing and later becomes available). [1], [2]

Examples from the .NET TablesDB API reference: [1]

// Boolean
ColumnBoolean b = await tablesDB.CreateBooleanColumn(
  databaseId: "<DATABASE_ID>",
  tableId: "<TABLE_ID>",
  key: "isActive",
  required: false,
  default: false,   // optional
  array: false      // optional
);

// Text
ColumnText t = await tablesDB.CreateTextColumn(
  databaseId: "<DATABASE_ID>",
  tableId: "<TABLE_ID>",
  key: "description",
  required: false,
  default: "N/A",   // optional
  array: false,     // optional
  encrypt: false    // optional
);

// Varchar
ColumnVarchar v = await tablesDB.CreateVarcharColumn(
  databaseId: "<DATABASE_ID>",
  tableId: "<TABLE_ID>",
  key: "title",
  size: 128,
  required: false,
  default: "Untitled", // optional
  array: false,        // optional
  encrypt: false       // optional
);

To know when it’s ready, poll GetColumn / ListColumns until status becomes available (possible values include available, processing, failed, etc.). [2]

Sources: Appwrite TablesDB .NET API reference [1]; Appwrite column model status semantics [2].


🌐 Web query:

Appwrite .NET TablesDB CreateTable HTTP status code response normal create

💡 Result:

For Appwrite TablesDB (.NET) “Create table” (POST /tablesdb/{databaseId}/tables), a normal successful create returns HTTP 201 Created and the response body is the created Table JSON object (table metadata). [1]

(As a contrast, several TablesDB “create column” operations return 202 Accepted because they’re processed asynchronously.) [1]

Sources: [1]


🌐 Web query:

Appwrite .NET TablesDB CreateRow HTTP status code 201

💡 Result:

TablesDB.CreateRow (POST /tablesdb/{databaseId}/tables/{tableId}/rows) is expected to return HTTP 201 (Created) on success, along with the created Row in the JSON response body. [1]


🌐 Web query:

Appwrite .NET TablesDB CreateTable with columns parameter fields

💡 Result:

In Appwrite’s .NET TablesDB SDK, CreateTable(..., columns: new List<object>(), indexes: new List<object>()) expects each item in columns to be a “column definition object” with (at minimum) these fields:

  • key (string)
  • type (string: string, integer, float, boolean, datetime, relationship)
  • size (int, required when type == "string")
  • optional: required (bool), default (any), array (bool), plus type-specific options (for example relationship options) [1].

Example (C#)

var columns = new List<object>
{
    new Dictionary<string, object>
    {
        ["key"] = "title",
        ["type"] = "string",
        ["size"] = 256,
        ["required"] = true,
        ["array"] = false
        // e.g. ["default"] = "Untitled",
        // e.g. ["encrypt"] = false (supported for some string-like types)
    },
    new Dictionary<string, object>
    {
        ["key"] = "views",
        ["type"] = "integer",
        ["required"] = false,
        ["default"] = 0
    },

    // Relationship column (type-specific options)
    new Dictionary<string, object>
    {
        ["key"] = "author",
        ["type"] = "relationship",
        ["relatedTableId"] = "users",
        ["relationType"] = "oneToOne",   // naming may vary by API version
        ["twoWay"] = false,
        ["onDelete"] = "cascade"
    }
};

var table = await tablesDB.CreateTable(
    databaseId: "<DATABASE_ID>",
    tableId: "<TABLE_ID>",
    name: "Posts",
    columns: columns
);

For relationship columns, the related-table and constraint fields correspond to the relationship-column API: relatedTableId, relation type, optional twoWay, twoWayKey, and onDelete [2].

Sources: Appwrite TablesDB .NET reference (Create table + columns/indexes schema) [1], relationship column options [2].

[1] (appwrite.io)
[2] (appwrite.io)

Citations:


Add a readiness check before inserting rows.

The column creation calls (CreateVarcharColumn, CreateTextColumn, CreateBooleanColumn) return HTTP 202 Accepted—the server accepts the request but processes the schema change asynchronously. Although the code uses await, the await completes when the HTTP response is received, not when the columns finish processing on the server. Step 6 immediately calls CreateRow, which may fail if the columns haven't transitioned to status: available yet.

Add a polling loop to check each column's status before the first CreateRow, or pass the column definitions directly to CreateTable(...) to create the schema atomically.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/dotnet/prompt.md` around lines 73 - 95, The
column creation calls (CreateVarcharColumn, CreateTextColumn,
CreateBooleanColumn) return 202 and may not be available immediately before
CreateRow runs; add a readiness check: after each Create* call poll the column
status via the tables API (or a GetColumn/GetTable status endpoint) in a short
retry loop until status == "available" (with a timeout/retry limit), or instead
avoid the async gap by passing column definitions directly into CreateTable so
the schema is created atomically before inserting rows; apply this check before
the first CreateRow call.

Comment on lines +62 to +138
```jsx
import { createSignal } from 'solid-js';
import { account, ID } from './lib/appwrite';

const App = () => {
const [loggedInUser, setLoggedInUser] = createSignal(null);
const [email, setEmail] = createSignal('');
const [password, setPassword] = createSignal('');
const [name, setName] = createSignal('');

async function login(email, password) {
await account.createEmailPasswordSession({
email,
password
});
setLoggedInUser(await account.get());
}

async function register(email, password, name) {
await account.create({
userId: ID.unique(),
email,
password,
name
});
login(email, password);
}

async function logout() {
await account.deleteSession({ sessionId: 'current' });
setLoggedInUser(null);
}

if (loggedInUser()) {
return (
<div>
<p>Logged in as {loggedInUser().name}</p>
<button onClick={logout}>Logout</button>
</div>
);
}

return (
<div>
<p>Not logged in</p>
<form>
<input
type="email"
placeholder="Email"
value={email()}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={password()}
onChange={(e) => setPassword(e.target.value)}
/>
<input
type="text"
placeholder="Name"
value={name()}
onChange={(e) => setName(e.target.value)}
/>
<button type="button" onClick={() => login(email(), password())}>
Login
</button>
<button type="button" onClick={() => register(email(), password(), name())}>
Register
</button>
</form>
</div>
);
};

export default App;
```
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Missing initial session check on component mount.

The component doesn't check for an existing session when it first loads. Users who are already authenticated (e.g., page refresh, returning users) will see the logged-out state until they manually trigger an action. This degrades the user experience.

⚡ Proposed enhancement to check session on mount

Add this code after the signal declarations:

import { createSignal, onMount } from 'solid-js';
import { account, ID } from './lib/appwrite';

const App = () => {
    const [loggedInUser, setLoggedInUser] = createSignal(null);
    const [email, setEmail] = createSignal('');
    const [password, setPassword] = createSignal('');
    const [name, setName] = createSignal('');

    onMount(async () => {
        try {
            setLoggedInUser(await account.get());
        } catch {
            // No active session
        }
    });

    // ... rest of component
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/solid/prompt.md` around lines 62 - 138, Add an
initial session check on component mount: import onMount from 'solid-js' and
after the createSignal declarations add an onMount(async () => { try {
setLoggedInUser(await account.get()); } catch { /* no active session */ } }); so
the App uses account.get to populate loggedInUser on load (references: onMount,
createSignal, loggedInUser, setLoggedInUser, account.get).

Comment on lines +5 to +6
Respect the user's package manager at all times. Don't use NPM if the user uses something else.

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat src/routes/docs/quick-starts/tanstack-start/prompt.md

Repository: appwrite/website

Length of output: 5513


🌐 Web query:

TanStack Start quick-start documentation package manager commands

💡 Result:

From the TanStack Start (React) Quick Start docs, the scaffold command is:

  • pnpm create @tanstack/start@latest  [1]
  • or (works from any environment that can run npx): npx @tanstack/cli create  [1]

If you use the TanStack CLI, you can explicitly choose a package manager via:

  • tanstack create my-app --package-manager <pm> where <pm> is one of npm | pnpm | yarn | bun | deno  [2]

Sources: [1] TanStack Start React Docs – Quick Start, [2] TanStack CLI Docs – CLI Reference


Make commands respect the user's chosen package manager.

Line 5 states not to use npm unless the user chose it, but lines 12, 16, and 124 hardcode npm for scaffold, install, and dev commands. This contradiction undermines the stated principle and breaks the workflow for pnpm, yarn, and bun users from the first step. TanStack Start's own quick-start uses pnpm create @tanstack/start@latest as the primary command and supports explicit package-manager selection.

♻️ Suggested doc fix
-- To scaffold a new TanStack Start project, run: `npm create `@tanstack/start`@latest .` (use `.` to create in the current directory - do NOT use `cd` to switch directories)
+- To scaffold a new TanStack Start project, run the equivalent command for the detected package manager in the current directory (for example, `npm create `@tanstack/start`@latest .` or `pnpm create `@tanstack/start`@latest .`). Do NOT use `cd` to switch directories.

-- Run: `npm install appwrite`
+- Run the detected package manager's install command for `appwrite`.

-- Run: `npm run dev`
+- Run the detected package manager's dev command.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/tanstack-start/prompt.md` around lines 5 - 6,
Update the hardcoded npm commands in the quick-start prompt so they respect the
user's package manager: replace the scaffold/install/dev commands that currently
use npm with package-manager-aware variants (e.g., prefer `pnpm create
`@tanstack/start`@latest` as the primary scaffold example and/or show equivalents
for pnpm/yarn/bun), or use a placeholder like `<package-manager> create
`@tanstack/start`@latest`, `<package-manager> install` and `<package-manager> run
dev` so the scaffold, install and dev commands (the lines referencing the
scaffold command, the install command, and the dev command) no longer assume
npm.

Comment on lines +39 to +40
- If this is a fresh project, you may replace `src/routes/index.tsx` with an auth UI route.
- If you are working in an existing project, create a new route (e.g., `src/routes/auth.tsx`) instead of overriding the default route.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n src/routes/docs/quick-starts/tanstack-start/prompt.md | head -60

Repository: appwrite/website

Length of output: 3477


🏁 Script executed:

cat -n src/routes/docs/quick-starts/tanstack-start/prompt.md | sed -n '45,70p'

Repository: appwrite/website

Length of output: 1119


🌐 Web query:

TanStack Start React Router file-based routing path string convention

💡 Result:

In TanStack Start, file-based routes use TanStack Router’s conventions, and the string you pass to createFileRoute('...') should match the URL path implied by the file name/directory structure. (tanstack.dev)

Path string conventions (how filenames map to createFileRoute('/...'))

  • __root.tsx → root route (no URL segment). (tanstack.com)
  • Folders or . in filenames create nested URL segments (you can mix both):
    • routes/users/$id/posts.ts or routes/users.$id.posts.tscreateFileRoute('/users/$id/posts') (tanstack.dev)
  • Dynamic params use $:
    • posts.$postId.tsxcreateFileRoute('/posts/$postId') (tanstack.com)
  • Index routes: segment ending in .index matches the parent exactly:
    • routes/users.index.tscreateFileRoute('/users') (tanstack.dev)
  • Pathless layout routes: _ prefix adds layout/nesting without adding a URL segment:
    • routes/_app.a.tsxcreateFileRoute('/a') (but nested under the _app layout) (tanstack.com)
  • Escaping special chars with [...]:
    • my-script[.]js.tscreateFileRoute('/my-script.js') (tanstack.dev)

Sources

  • [1] TanStack Router — File Naming Conventions (tanstack.com)
  • [2] TanStack Start — Server Routes (file route conventions examples) (tanstack.dev)

Citations:


Ensure route scaffold example matches the file path instructions.

Lines 39–40 instruct creating src/routes/auth.tsx for existing projects, but the code sample at lines 48–55 uses createFileRoute('/'). In TanStack's file-based routing, the createFileRoute() path must correspond to the file location; a file at src/routes/auth.tsx requires createFileRoute('/auth'), not createFileRoute('/').

Either update the path string to /auth or provide separate examples for both scenarios (index route vs. auth route).

Suggested fix
-export const Route = createFileRoute('/')({
+export const Route = createFileRoute('/auth')({
     component: Index
 });

Also applies to: 48–55

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/tanstack-start/prompt.md` around lines 39 - 40,
The example route path in the sample is inconsistent with the written
instructions: if the file to scaffold is src/routes/auth.tsx you must use
createFileRoute('/auth') (whereas src/routes/index.tsx uses
createFileRoute('/')). Update the code sample that uses createFileRoute('/') to
use createFileRoute('/auth') when demonstrating creating src/routes/auth.tsx, or
provide two parallel examples (one using src/routes/index.tsx with
createFileRoute('/') and one using src/routes/auth.tsx with
createFileRoute('/auth')) so the file path and createFileRoute() argument match.

@atharvadeosthale atharvadeosthale changed the base branch from main to ai-docs March 10, 2026 07:03
Copy link
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

♻️ Duplicate comments (3)
src/routes/docs/quick-starts/refine/prompt.md (2)

89-121: ⚠️ Potential issue | 🟠 Major

Redirect auth success to a real route.

The sample sends authenticated users to /, but this route tree never defines a concrete page for /; the only concrete child shown here is the wildcard ErrorComponent. That means the “working login/register page” flow can still land on an empty/error state right after sign-in.

Suggested fix
                             <Route
                                 element={
                                     <Authenticated fallback={<Outlet />}>
-                                        <Navigate to="/" />
+                                        <Navigate to="/dashboard" />
                                     </Authenticated>
                                 }
                             >
                                 <Route path="/login" element={<AuthPage />} />
                                 <Route path="/register" element={<AuthPage type="register" />} />
                             </Route>

                             <Route
                                 element={
                                     <Authenticated>
                                         <ThemedLayoutV2>
                                             <Outlet />
                                         </ThemedLayoutV2>
                                     </Authenticated>
                                 }
                             >
+                                <Route path="/dashboard" element={<div>Dashboard</div>} />
                                 <Route path="*" element={<ErrorComponent />} />
                             </Route>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/refine/prompt.md` around lines 89 - 121, The
current authenticated redirect uses Navigate to="/" but no concrete Route for
"/" exists, so after sign-in users hit the wildcard ErrorComponent; update the
route tree by either adding a concrete Route for path="/" (e.g., Route path="/"
element={<HomePage/>} or <Dashboard/> placed under the same Authenticated +
ThemedLayoutV2 wrapper) or change the Navigate target to an existing concrete
route (e.g., "/dashboard") and ensure that Route is defined; update the Route
entries that reference Authenticated, Navigate to="/", ThemedLayoutV2, Outlet,
and ErrorComponent accordingly so the post-login redirect lands on a real page.

16-18: ⚠️ Potential issue | 🟠 Major

Split scaffold and integration into separate paths.

Line 17 says existing projects can proceed, but Line 18 still scaffolds refine-app into .. That can overwrite or collide with an existing app, and Step 3 never becomes the real existing-app branch.

Suggested wording
-- If the directory is empty OR contains an existing project (e.g., `package.json`, `src` folder, config files), proceed with integration without asking.
-- Run: `npm create refine-app@latest . -- --preset refine-appwrite`
+- If the directory is empty, scaffold a new app in the current directory with the Refine-Appwrite preset.
+- If the directory already contains an existing Refine project, do not run the scaffold command. Skip directly to the integration steps below.

 ## Step 3: Install Appwrite (for existing projects only)

 - Using the `refine-appwrite` preset eliminates the need for extra dependencies for a quick start.
 - If integrating into an existing Refine app, run: `npm install `@refinedev/appwrite``

Also applies to: 22-26

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/refine/prompt.md` around lines 16 - 18, The doc
currently always runs the scaffold command `npm create refine-app@latest . --
--preset refine-appwrite` which can overwrite an existing project; change the
flow so "scaffold" and "integration" are explicit separate paths: when the
directory appears to contain an existing project ("existing project" branch),
remove or replace the scaffold command and instruct users to run integration
steps against their existing app (or to opt into a safe integration checklist),
and when the user elects to scaffold, prompt to create a new subdirectory or
confirm intentional overwrite before running the `npm create refine-app@latest .
-- --preset refine-appwrite` command; apply this wording change to both
occurrences of the problematic paragraph blocks so the doc no longer suggests
scaffolding into `.` for existing projects.
src/routes/docs/quick-starts/solid/prompt.md (1)

62-138: ⚠️ Potential issue | 🟠 Major

Missing initial session check on component mount.

The component doesn't check for an existing session when it first loads. Users who are already authenticated (e.g., after page refresh or returning to the app) will see the logged-out state until they manually trigger an action. This degrades the user experience.

Note: The previous issue with the missing await on line 87 has been resolved ✅ - the login call is now properly awaited.

⚡ Proposed enhancement to check session on mount

Add this code after the signal declarations:

-import { createSignal } from 'solid-js';
+import { createSignal, onMount } from 'solid-js';
 import { account, ID } from './lib/appwrite';

 const App = () => {
     const [loggedInUser, setLoggedInUser] = createSignal(null);
     const [email, setEmail] = createSignal('');
     const [password, setPassword] = createSignal('');
     const [name, setName] = createSignal('');

+    onMount(async () => {
+        try {
+            setLoggedInUser(await account.get());
+        } catch {
+            // No active session
+        }
+    });
+
     async function login(email, password) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/solid/prompt.md` around lines 62 - 138, The
component never checks existing sessions on mount, so add an on-mount session
check that calls account.get() and sets the loggedInUser signal if a user is
returned; specifically import onMount from 'solid-js', then in the component
after the createSignal declarations call onMount(async () => { try { const user
= await account.get(); if (user) setLoggedInUser(user); } catch (e) { /*
ignore/not-authenticated */ } }); this ensures loggedInUser is populated on page
load and works with the existing login(), register(), and logout() flows.
🧹 Nitpick comments (2)
src/routes/docs/quick-starts/flutter/prompt.md (1)

89-89: Update the Appwrite Flutter SDK version to the latest.

The installation command pins to version 17.0.0, but 22.0.0 is the current latest version. For a quick-start guide, use the latest SDK version to ensure users have access to the newest features and fixes.

If pinning to 17.0.0 is intentional (e.g., for compatibility with specific constraints), document the reason.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/flutter/prompt.md` at line 89, Update the pinned
Appwrite Flutter SDK version in the quick-start prompt line that currently reads
"Run: `flutter pub add appwrite:17.0.0`" to use the latest release (change to
`22.0.0`) or, if pinning to 17.0.0 is intentional, add a short note explaining
the compatibility reason; locate the string "flutter pub add appwrite:17.0.0" in
the prompt.md and replace the version or insert the explanatory sentence
directly after that line.
src/routes/docs/quick-starts/solid/prompt.md (1)

72-93: Consider adding error handling to authentication functions.

The login, register, and logout functions don't include try-catch blocks. When authentication fails (invalid credentials, network issues, CORS problems), the error won't be caught and the UI state won't update appropriately. Step 6 mentions "Surface any Appwrite errors," but the code doesn't implement error handling.

🛡️ Proposed enhancement to add error handling
 async function login(email, password) {
+    try {
         await account.createEmailPasswordSession({
             email,
             password
         });
         setLoggedInUser(await account.get());
+    } catch (error) {
+        console.error('Login failed:', error);
+        alert('Login failed: ' + error.message);
+    }
 }

 async function register(email, password, name) {
+    try {
         await account.create({
             userId: ID.unique(),
             email,
             password,
             name
         });
         await login(email, password);
+    } catch (error) {
+        console.error('Registration failed:', error);
+        alert('Registration failed: ' + error.message);
+    }
 }

 async function logout() {
+    try {
         await account.deleteSession({ sessionId: 'current' });
         setLoggedInUser(null);
+    } catch (error) {
+        console.error('Logout failed:', error);
+        alert('Logout failed: ' + error.message);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/solid/prompt.md` around lines 72 - 93, The auth
functions (login, register, logout) lack error handling; wrap the calls to
account.createEmailPasswordSession, account.create, account.get and
account.deleteSession in try/catch blocks inside login, register and logout
respectively, call setLoggedInUser(await account.get()) only on successful
login/registration, set or clear an error state (or return/throw the caught
error) in the catch handler so the UI can surface Appwrite errors, and ensure
register awaits login inside a try/catch so failures are handled and do not
leave inconsistent state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/routes/docs/quick-starts/flutter/prompt.md`:
- Around line 146-172: Add error handling and an error state to surface Appwrite
failures: introduce a String? errorMessage field in MyAppState and update login,
register, and logout to catch AppwriteException (or general exceptions) around
calls in createEmailPasswordSession, create, and deleteSession respectively; on
success clear errorMessage in setState and on catch set errorMessage = e.message
?? '<action> failed' (use "Login failed", "Registration failed", "Logout failed"
as appropriate). Also update the button handlers to await these methods (they
already do) and ensure the UI renders errorMessage (e.g., a red Text widget
under the login status) so users see the error. Use the existing function names
login, register, and logout to locate the changes.

In `@src/routes/docs/quick-starts/refine/prompt.md`:
- Line 5: Replace hardcoded npm commands in the quick-start prompt examples (the
scaffold, install and dev command snippets and other occurrences) with
package-manager‑aware wording so the agent honors the user's choice; update the
three command examples to either use a placeholder like "<package-manager>
install" / "<package-manager> run dev" or a phrase such as "using your package
manager (npm, yarn, or pnpm) run …" and apply the same change to the other
listed occurrences in the document so no commands are hardcoded to npm.

---

Duplicate comments:
In `@src/routes/docs/quick-starts/refine/prompt.md`:
- Around line 89-121: The current authenticated redirect uses Navigate to="/"
but no concrete Route for "/" exists, so after sign-in users hit the wildcard
ErrorComponent; update the route tree by either adding a concrete Route for
path="/" (e.g., Route path="/" element={<HomePage/>} or <Dashboard/> placed
under the same Authenticated + ThemedLayoutV2 wrapper) or change the Navigate
target to an existing concrete route (e.g., "/dashboard") and ensure that Route
is defined; update the Route entries that reference Authenticated, Navigate
to="/", ThemedLayoutV2, Outlet, and ErrorComponent accordingly so the post-login
redirect lands on a real page.
- Around line 16-18: The doc currently always runs the scaffold command `npm
create refine-app@latest . -- --preset refine-appwrite` which can overwrite an
existing project; change the flow so "scaffold" and "integration" are explicit
separate paths: when the directory appears to contain an existing project
("existing project" branch), remove or replace the scaffold command and instruct
users to run integration steps against their existing app (or to opt into a safe
integration checklist), and when the user elects to scaffold, prompt to create a
new subdirectory or confirm intentional overwrite before running the `npm create
refine-app@latest . -- --preset refine-appwrite` command; apply this wording
change to both occurrences of the problematic paragraph blocks so the doc no
longer suggests scaffolding into `.` for existing projects.

In `@src/routes/docs/quick-starts/solid/prompt.md`:
- Around line 62-138: The component never checks existing sessions on mount, so
add an on-mount session check that calls account.get() and sets the loggedInUser
signal if a user is returned; specifically import onMount from 'solid-js', then
in the component after the createSignal declarations call onMount(async () => {
try { const user = await account.get(); if (user) setLoggedInUser(user); } catch
(e) { /* ignore/not-authenticated */ } }); this ensures loggedInUser is
populated on page load and works with the existing login(), register(), and
logout() flows.

---

Nitpick comments:
In `@src/routes/docs/quick-starts/flutter/prompt.md`:
- Line 89: Update the pinned Appwrite Flutter SDK version in the quick-start
prompt line that currently reads "Run: `flutter pub add appwrite:17.0.0`" to use
the latest release (change to `22.0.0`) or, if pinning to 17.0.0 is intentional,
add a short note explaining the compatibility reason; locate the string "flutter
pub add appwrite:17.0.0" in the prompt.md and replace the version or insert the
explanatory sentence directly after that line.

In `@src/routes/docs/quick-starts/solid/prompt.md`:
- Around line 72-93: The auth functions (login, register, logout) lack error
handling; wrap the calls to account.createEmailPasswordSession, account.create,
account.get and account.deleteSession in try/catch blocks inside login, register
and logout respectively, call setLoggedInUser(await account.get()) only on
successful login/registration, set or clear an error state (or return/throw the
caught error) in the catch handler so the UI can surface Appwrite errors, and
ensure register awaits login inside a try/catch so failures are handled and do
not leave inconsistent state.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3b2817e8-9b36-47cd-8b33-7212552338dc

📥 Commits

Reviewing files that changed from the base of the PR and between 2ce5efe and cd9d0cc.

📒 Files selected for processing (6)
  • src/routes/docs/quick-starts/apple/prompt.md
  • src/routes/docs/quick-starts/flutter/prompt.md
  • src/routes/docs/quick-starts/nextjs/prompt.md
  • src/routes/docs/quick-starts/nuxt/prompt.md
  • src/routes/docs/quick-starts/refine/prompt.md
  • src/routes/docs/quick-starts/solid/prompt.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/routes/docs/quick-starts/nuxt/prompt.md
  • src/routes/docs/quick-starts/nextjs/prompt.md
  • src/routes/docs/quick-starts/apple/prompt.md

Comment on lines +146 to +172
Future<void> login(String email, String password) async {
await widget.account.createEmailPasswordSession(
email: email,
password: password,
);
final user = await widget.account.get();
setState(() {
loggedInUser = user;
});
}

Future<void> register(String email, String password, String name) async {
await widget.account.create(
userId: ID.unique(),
email: email,
password: password,
name: name,
);
await login(email, password);
}

Future<void> logout() async {
await widget.account.deleteSession(sessionId: 'current');
setState(() {
loggedInUser = null;
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling to surface auth failures.

The login(), register(), and logout() methods don't catch AppwriteException, and the button handlers (lines 206, 212-214, 220-221) don't wrap the calls in try-catch blocks. This means common failures (invalid credentials, duplicate email, network errors) will crash the app or fail silently, violating the Step 6 requirement to "Surface any Appwrite errors."

🛡️ Suggested approach

Add error state and exception handling:

class MyAppState extends State<MyApp> {
  models.User? loggedInUser;
  String? errorMessage;
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();
  final TextEditingController nameController = TextEditingController();

  Future<void> login(String email, String password) async {
    try {
      await widget.account.createEmailPasswordSession(
        email: email,
        password: password,
      );
      final user = await widget.account.get();
      setState(() {
        loggedInUser = user;
        errorMessage = null;
      });
    } on AppwriteException catch (e) {
      setState(() {
        errorMessage = e.message ?? 'Login failed';
      });
    }
  }

  Future<void> register(String email, String password, String name) async {
    try {
      await widget.account.create(
        userId: ID.unique(),
        email: email,
        password: password,
        name: name,
      );
      await login(email, password);
    } on AppwriteException catch (e) {
      setState(() {
        errorMessage = e.message ?? 'Registration failed';
      });
    }
  }

  Future<void> logout() async {
    try {
      await widget.account.deleteSession(sessionId: 'current');
      setState(() {
        loggedInUser = null;
        errorMessage = null;
      });
    } on AppwriteException catch (e) {
      setState(() {
        errorMessage = e.message ?? 'Logout failed';
      });
    }
  }

Then display errorMessage in the UI below the login status:

Text(loggedInUser != null
    ? 'Logged in as ${loggedInUser!.name}'
    : 'Not logged in'),
if (errorMessage != null) ...[
  SizedBox(height: 8.0),
  Text(
    errorMessage!,
    style: TextStyle(color: Colors.red),
  ),
],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/flutter/prompt.md` around lines 146 - 172, Add
error handling and an error state to surface Appwrite failures: introduce a
String? errorMessage field in MyAppState and update login, register, and logout
to catch AppwriteException (or general exceptions) around calls in
createEmailPasswordSession, create, and deleteSession respectively; on success
clear errorMessage in setState and on catch set errorMessage = e.message ??
'<action> failed' (use "Login failed", "Registration failed", "Logout failed" as
appropriate). Also update the button handlers to await these methods (they
already do) and ensure the UI renders errorMessage (e.g., a red Text widget
under the login status) so users see the error. Use the existing function names
login, register, and logout to locate the changes.


Do exactly these steps in order. Confirm each step succeeds before continuing. If any command fails, show the error and fix it automatically.

Respect user's package manager at all time. Don't use NPM if the user uses something else.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don’t hardcode npm after telling the agent to honor the user’s package manager.

The prompt currently says “Don’t use NPM if the user uses something else,” then gives only npm commands for scaffold, install, and dev. Please switch these to package-manager-aware wording so the generated instructions stay consistent.

Suggested wording
-- Run: `npm create refine-app@latest . -- --preset refine-appwrite`
+- Run the equivalent `create refine-app` command for the user's package manager in the current directory with the `refine-appwrite` preset.

-- If integrating into an existing Refine app, run: `npm install `@refinedev/appwrite``
+- If integrating into an existing Refine app, install `@refinedev/appwrite` using the user's package manager.

-- Run: `npm run dev -- --open --port 3000`
+- Start the dev server with the user's package manager, passing `--open --port 3000`.

Also applies to: 18-18, 25-25, 137-137

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/docs/quick-starts/refine/prompt.md` at line 5, Replace hardcoded
npm commands in the quick-start prompt examples (the scaffold, install and dev
command snippets and other occurrences) with package-manager‑aware wording so
the agent honors the user's choice; update the three command examples to either
use a placeholder like "<package-manager> install" / "<package-manager> run dev"
or a phrase such as "using your package manager (npm, yarn, or pnpm) run …" and
apply the same change to the other listed occurrences in the document so no
commands are hardcoded to npm.

@atharvadeosthale atharvadeosthale merged commit d4dfdac into ai-docs Mar 10, 2026
6 checks passed
@atharvadeosthale atharvadeosthale deleted the quickstart-prompts branch March 10, 2026 07:08
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.

2 participants