Skip to content

feat: add TablesDB API coverage and Transactions API support#32

Open
Divyansha23 wants to merge 1 commit intomasterfrom
SUC-1877-update-tablesdb-API
Open

feat: add TablesDB API coverage and Transactions API support#32
Divyansha23 wants to merge 1 commit intomasterfrom
SUC-1877-update-tablesdb-API

Conversation

@Divyansha23
Copy link
Contributor

@Divyansha23 Divyansha23 commented Feb 27, 2026

What does this PR do?

Adds full TablesDB and Transactions API coverage to the Node.js playground.

TablesDB API

Added complete CRUD coverage for the TablesDB service — a new Appwrite database type (type: "tablesdb") distinct from the legacy Databases service:

Resource APIs
Database create, list, get, update, delete
Tables createTable, listTables, getTable, updateTable, deleteTable
Columns createStringColumn, createIntegerColumn, createFloatColumn, createBooleanColumn, listColumns, getColumn, deleteColumn
Indexes createIndex, listIndexes, deleteIndex
Rows createRow, listRows (with Query.equal), getRow, updateRow, deleteRow

Transactions API

Implemented the full TablesDB Transactions lifecycle, demonstrating the three-step pattern:

  1. Create a transaction → tablesDB.createTransaction({ ttl: 60 })
  2. Stage operations by passing transactionId to row methods, or batch-stage via createOperations
  3. Commit or rollback via tablesDB.updateTransaction({ transactionId, commit: true }) or { rollback: true }
Function What it demonstrates
createTransaction Create a transaction with a 60-second TTL
getTransaction Retrieve a transaction by ID
listTransactions List all transactions
stageCreateRow Stage a row creation by passing transactionId to createRow
stageUpdateRow Stage a row update by passing transactionId to updateRow
stageOperations Batch-stage multiple operations via createOperations
commitTransaction Commit all staged ops atomically
rollbackTransactionDemo Full rollback demo — create tx, stage a row, roll back (status "failed" = successful rollback, staged data discarded)
deleteTransaction Create and delete a throwaway transaction

Other changes

  • Config now reads from environment variables (APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID, APPWRITE_API_KEY) with fallback placeholders.
  • Updated function runtime from deprecated Runtime.Node200 to Runtime.Node22.
  • All methods use the latest SDK object-based parameter syntax.

Testing

Ran the full playground end-to-end against Appwrite Cloud — all 60+ API calls passed successfully, including TablesDB CRUD and the complete Transactions flow (create → stage → commit, rollback demo, delete).

Summary by CodeRabbit

  • New Features

    • Introduced TablesDB with complete database table management capabilities including table creation, column definitions, indexing, row operations, and transaction support for coordinated changes.
    • Configuration now accepts environment variables for endpoint, project ID, and API key with fallback values.
  • Updates

    • Upgraded Node.js runtime to version 22 for improved performance and compatibility.

@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Walkthrough

This change integrates TablesDB functionality into the application. The import statement is expanded to include the TablesDB client from node-appwrite, and a new TablesDB instance is created. Configuration values (endpoint, project ID, API key) are updated to read from environment variables with fallback values. Over 30 new public API functions are added to support TablesDB operations including databases, tables, columns, indexes, rows, and transactions. The Node.js runtime version is updated from 20 to 22 in both function creation and update calls. The runAllTasks function is extended to execute the new TablesDB API sequences alongside existing API demonstrations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main changes: adding TablesDB API coverage and Transactions API support, which align directly with the substantial additions in the changeset.
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 docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SUC-1877-update-tablesdb-API

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link

@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.

🧹 Nitpick comments (3)
src/app.js (3)

9-11: Fail fast when required Appwrite env vars are missing.

Lines 9-11 silently fall back to placeholders, which delays failure until the first API call and makes setup errors less obvious.

🛠️ Suggested fail-fast config
+const endpoint = process.env.APPWRITE_ENDPOINT;
+const projectId = process.env.APPWRITE_PROJECT_ID;
+const apiKey = process.env.APPWRITE_API_KEY;
+
+if (!endpoint || !projectId || !apiKey) {
+    throw new Error('Missing APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID, or APPWRITE_API_KEY');
+}
+
 const client = new Client()
-    .setEndpoint(process.env.APPWRITE_ENDPOINT || 'YOUR_ENDPOINT')   // Replace with your endpoint
-    .setProject(process.env.APPWRITE_PROJECT_ID || 'YOUR_PROJECT_ID')  // Replace with your project ID
-    .setKey(process.env.APPWRITE_API_KEY || 'YOUR_API_KEY');        // Replace with your API Key
+    .setEndpoint(endpoint)
+    .setProject(projectId)
+    .setKey(apiKey);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app.js` around lines 9 - 11, Replace the silent placeholder defaults for
Appwrite configuration with a fail-fast check: before calling setEndpoint,
setProject, and setKey in the client initialization (the code around
setEndpoint(...), setProject(...), setKey(...)), validate that
process.env.APPWRITE_ENDPOINT, process.env.APPWRITE_PROJECT_ID, and
process.env.APPWRITE_API_KEY are present and non-empty and throw an Error or
exit with a clear message listing the missing variables; only call
client.setEndpoint(...).setProject(...).setKey(...) when all required env vars
are provided to ensure immediate, explicit failure on misconfiguration.

1283-1320: Wrap the new TablesDB flow in try/finally so cleanup still runs on failures.

If one TablesDB/transaction call fails, the current sequence skips all subsequent delete calls and leaves test resources behind.

♻️ Suggested cleanup guard
+const safeRun = async (fn) => {
+    try { await fn(); } catch (err) { console.log(chalk.yellow(`Cleanup skipped: ${err.message}`)); }
+};

 const runAllTasks = async () => {
@@
-    await createTablesDatabase();
-    await listTablesDatabases();
-    await getTablesDatabase();
-    await updateTablesDatabase();
-
-    await createTable();
-    await listTables();
-    await getTable();
-    await updateTable();
-
-    await createColumns();
-    await listTableColumns();
-    await getTableColumn();
-
-    await createTableIndex();
-    await listTableIndexes();
-
-    await createTableRow();
-    await listTableRows();
-    await getTableRow();
-    await updateTableRow();
-
-    // Transactions API
-    await createTransaction();
-    await getTransaction();
-    await listTransactions();
-    await stageCreateRow();
-    await stageUpdateRow();
-    await stageOperations();
-    await commitTransaction();
-    await rollbackTransactionDemo();
-    await deleteTransaction();
-
-    await deleteTableRow();
-    await deleteTableIndex();
-    await deleteTableColumn();
-    await deleteTable();
-    await deleteTablesDatabase();
+    await createTablesDatabase();
+    try {
+        await listTablesDatabases();
+        await getTablesDatabase();
+        await updateTablesDatabase();
+        await createTable();
+        await listTables();
+        await getTable();
+        await updateTable();
+        await createColumns();
+        await listTableColumns();
+        await getTableColumn();
+        await createTableIndex();
+        await listTableIndexes();
+        await createTableRow();
+        await listTableRows();
+        await getTableRow();
+        await updateTableRow();
+        await createTransaction();
+        await getTransaction();
+        await listTransactions();
+        await stageCreateRow();
+        await stageUpdateRow();
+        await stageOperations();
+        await commitTransaction();
+        await rollbackTransactionDemo();
+        await deleteTransaction();
+    } finally {
+        await safeRun(deleteTableRow);
+        await safeRun(deleteTableIndex);
+        await safeRun(deleteTableColumn);
+        await safeRun(deleteTable);
+        await safeRun(deleteTablesDatabase);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app.js` around lines 1283 - 1320, The sequence of TablesDB and
transaction calls (e.g., createTablesDatabase, createTable, createColumns,
createTableIndex, createTableRow, createTransaction, stageCreateRow,
commitTransaction, etc.) must be wrapped in a try/finally so cleanup always
runs; move all setup and test operations into the try block and place all
teardown calls (deleteTableRow, deleteTableIndex, deleteTableColumn,
deleteTable, deleteTablesDatabase, plus deleteTransaction/rollback if needed)
into the finally block so that even if any intermediate await throws, the
deleteTablesDatabase and related cleanup functions still execute; ensure awaits
remain and consider guarding deletes with existence checks if necessary.

891-893: Prefer readiness polling over fixed sleeps for schema/index creation.

The hardcoded 2-second waits can be flaky on slower instances. Poll for available status with timeout instead of sleeping blindly.

♻️ Suggested refactor sketch
+const waitUntil = async (check, label, timeoutMs = 30000, intervalMs = 1000) => {
+    const start = Date.now();
+    while (Date.now() - start < timeoutMs) {
+        if (await check()) return;
+        await new Promise((resolve) => setTimeout(resolve, intervalMs));
+    }
+    throw new Error(`${label} did not become ready in time`);
+};

-    console.log("Waiting a little to ensure columns are created ...");
-    await new Promise((resolve) => setTimeout(resolve, 2000));
+    await waitUntil(async () => {
+        const cols = await tablesDB.listColumns({ databaseId: tablesDatabaseId, tableId });
+        return cols.columns?.every((c) => c.status === 'available');
+    }, 'TablesDB columns');

-    console.log("Waiting a little to ensure index is created ...");
-    await new Promise((resolve) => setTimeout(resolve, 2000));
+    await waitUntil(async () => {
+        const idx = await tablesDB.listIndexes({ databaseId: tablesDatabaseId, tableId });
+        return idx.indexes?.some((i) => i.key === 'idx_year' && i.status === 'available');
+    }, 'TablesDB index idx_year');

Also applies to: 930-932

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

In `@src/app.js` around lines 891 - 893, Replace the hardcoded 2s sleep used after
the console.log("Waiting a little to ensure columns are created ...") and the
similar sleep at the later occurrence with a readiness polling approach:
implement a small helper (e.g., waitForAvailability(checkerFn, timeoutMs =
30000, intervalMs = 500)) that repeatedly calls a checker function (a function
that queries the schema/index status — e.g., describeTable(), getIndexStatus()
or the existing API you already use) until it returns an "available" truthy
result or the timeout elapses, and use this helper in place of the await new
Promise(...) calls so both the original sleep and the second instance (the one
at 930-932) poll for availability with a reasonable timeout and interval rather
than sleeping a fixed duration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/app.js`:
- Around line 9-11: Replace the silent placeholder defaults for Appwrite
configuration with a fail-fast check: before calling setEndpoint, setProject,
and setKey in the client initialization (the code around setEndpoint(...),
setProject(...), setKey(...)), validate that process.env.APPWRITE_ENDPOINT,
process.env.APPWRITE_PROJECT_ID, and process.env.APPWRITE_API_KEY are present
and non-empty and throw an Error or exit with a clear message listing the
missing variables; only call client.setEndpoint(...).setProject(...).setKey(...)
when all required env vars are provided to ensure immediate, explicit failure on
misconfiguration.
- Around line 1283-1320: The sequence of TablesDB and transaction calls (e.g.,
createTablesDatabase, createTable, createColumns, createTableIndex,
createTableRow, createTransaction, stageCreateRow, commitTransaction, etc.) must
be wrapped in a try/finally so cleanup always runs; move all setup and test
operations into the try block and place all teardown calls (deleteTableRow,
deleteTableIndex, deleteTableColumn, deleteTable, deleteTablesDatabase, plus
deleteTransaction/rollback if needed) into the finally block so that even if any
intermediate await throws, the deleteTablesDatabase and related cleanup
functions still execute; ensure awaits remain and consider guarding deletes with
existence checks if necessary.
- Around line 891-893: Replace the hardcoded 2s sleep used after the
console.log("Waiting a little to ensure columns are created ...") and the
similar sleep at the later occurrence with a readiness polling approach:
implement a small helper (e.g., waitForAvailability(checkerFn, timeoutMs =
30000, intervalMs = 500)) that repeatedly calls a checker function (a function
that queries the schema/index status — e.g., describeTable(), getIndexStatus()
or the existing API you already use) until it returns an "available" truthy
result or the timeout elapses, and use this helper in place of the await new
Promise(...) calls so both the original sleep and the second instance (the one
at 930-932) poll for availability with a reasonable timeout and interval rather
than sleeping a fixed duration.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac03d5f and f52636c.

📒 Files selected for processing (1)
  • src/app.js

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