Code Canvas Database

Add a real Postgres database to any Code Canvas project. Theo writes code against live tables, auto-seeds sample rows, and can repair runtime errors with a click. Built on Neon Serverless Postgres.

Enable the database

Open a Code Canvas project, switch to the Data tab, and click Enable Database. Provisioning takes a few seconds and drops a green indicator next to the project name.

Behind the scenes we create a new Neon project, wire a restrictedapp_reader role for the public share proxy, and store the connection strings encrypted in Appwrite.

What you get

Live Postgres database

Every Code Canvas project can provision its own Neon Postgres instance. Theo and the preview talk to it through window.__db.

End-user authentication

One-click enable creates `_auth_users` + `_auth_sessions`. Your generated app calls `window.__auth.signup()`, `.login()`, `.currentUser()` just like a real SaaS.

Seed data after each table

When Theo creates a table it auto-generates 3–5 realistic rows so the preview isn't empty. Call `db_seed_table` later for more.

Per-user scoping

Theo can call `scope_table_to_user` to add a `user_id UUID` + index (or RLS policy) so each signed-in user only sees their own rows.

Schema history + revert

Every DDL applied to your database is logged. Open the History tab to see the full ledger and revert non-destructive migrations in one click.

CSV import / export

Export up to 10,000 rows from any table. Import rows client-side — we parse and insert them in chunks, showing per-row errors inline.

The window.__db SDK

The preview iframe exposes window.__db. Generated code reads and writes like any other Postgres client:

const { rows } = await window.__db.query('SELECT * FROM todos ORDER BY created_at DESC');

await window.__db.query(
  'INSERT INTO todos (title, completed) VALUES ($1, $2)',
  [title, false]
);
  • Always parameterized — never string-concatenate user input.
  • Always awaited.
  • Wrap in try/catch — Theo reads Postgres errors via the Try-to-fix button (see below).

Authentication

Click Auth → Enabledin the Data tab, or ask Theo "add signup and login". Your app then uses:

await window.__auth.signup(email, password, displayName?);
await window.__auth.login(email, password);
const user = await window.__auth.currentUser();
window.__auth.onAuthChange((user) => { /* react to state */ });

Ask Theo to call scope_table_to_userto add a user_id UUID column + index (and optional Postgres RLS policy) so each user only sees their own rows.

Try-to-fix

Free, one-click repair

When the preview throws a runtime error (including Postgres errors from window.__db), a red Try to fix chip appears above the composer. Clicking it sends the recent errors to Theo and routes the fix through a fastpatch_code repair.

We pair Postgres error codes with one-line hints so Theo knows, for example, that42P01means "table doesn't exist — create it before querying". Throttled to 3 attempts per project per minute.

Seed data

Never start with an empty preview

Theo now passes realistic seed_rows with everydb_create_table call, and can calldb_seed_tablelater with a hint like "three fitness customers" or "urgent support tickets". Internal_auth_* tables are never seeded.

CSV import / export

Open any table in the Data tab. Use Export to download up to 10,000 rows as a CSV, or Import to upload a CSV whose headers match existing columns. Rows insert one-by-one with parameterized SQL and per-row error reporting.

Schema history + revert

The History sub-view lists every schema-changing SQL statement Theo or you applied — with source, tool, and timestamp. Each row shows a best-effort revert button; clicking it runs a compensating DDL (e.g.DROP TABLE,DROP COLUMN) and marks the entry as reverted. Destructive reverts prompt for confirmation.

Publishing a code project keeps the database behind a signed public query proxy. Enable auth + call scope_table_to_userbefore launch so each visitor only sees their own rows.
Was this article helpful?

Related Articles