Bolt prompt to set up a Postgres database schema
Schema work in Bolt lands as SQL files in supabase/migrations, readable in the editor before anything executes against your database. This prompt orders that work, tables first, then triggers and indexes, then row level security, and closes with a smoke test proving the policies actually reject a cross-owner write.
Last updated
Design and apply a Postgres schema through Bolt's Supabase connection. Deliver it as ordered SQL files in supabase/migrations, one concern per file, so I can read each in the editor before it runs.
Migration 1, core tables for a {{resource}} tracker:
- profiles: id uuid referencing auth.users, display_name, created_at.
- {{resource}}s: id uuid default gen_random_uuid(), owner_id referencing profiles, title text not null with a length check between 1 and 200, status as a proper enum type (draft, active, archived), created_at and updated_at timestamptz defaulting to now().
- comments: id, {{resource}}_id with on delete cascade, author_id, body.
Migration 2, integrity and speed:
- A trigger function touch_updated_at applied to every table carrying updated_at.
- Indexes on owner_id, on comments by parent and created_at descending, and a partial index on status where status is active.
- A unique constraint on (owner_id, title), with a SQL comment explaining the choice.
Migration 3, row level security:
- Enable RLS on all three tables.
- Owners get full access to their rows, authenticated users can select active {{resource}}s, and comments are readable wherever the parent is readable. Each policy carries a one-line comment stating what it permits.
Rules: no serial columns, uuid keys everywhere, no nullable booleans, every timestamp timestamptz, and never store money or quantities as float.
Finish with a smoke check I can paste into the Supabase SQL editor: insert a profile and a record, update it to verify updated_at moves, then attempt a cross-owner update and confirm RLS rejects it.Customize it
Runs in your browser. Nothing you type here is sent anywhere.
Design and apply a Postgres schema through Bolt's Supabase connection. Deliver it as ordered SQL files in supabase/migrations, one concern per file, so I can read each in the editor before it runs. Migration 1, core tables for a users tracker: - profiles: id uuid referencing auth.users, display_name, created_at. - userss: id uuid default gen_random_uuid(), owner_id referencing profiles, title text not null with a length check between 1 and 200, status as a proper enum type (draft, active, archived), created_at and updated_at timestamptz defaulting to now(). - comments: id, users_id with on delete cascade, author_id, body. Migration 2, integrity and speed: - A trigger function touch_updated_at applied to every table carrying updated_at. - Indexes on owner_id, on comments by parent and created_at descending, and a partial index on status where status is active. - A unique constraint on (owner_id, title), with a SQL comment explaining the choice. Migration 3, row level security: - Enable RLS on all three tables. - Owners get full access to their rows, authenticated users can select active userss, and comments are readable wherever the parent is readable. Each policy carries a one-line comment stating what it permits. Rules: no serial columns, uuid keys everywhere, no nullable booleans, every timestamp timestamptz, and never store money or quantities as float. Finish with a smoke check I can paste into the Supabase SQL editor: insert a profile and a record, update it to verify updated_at moves, then attempt a cross-owner update and confirm RLS rejects it.
Same task in other tools
Questions about this prompt
Why three migration files instead of one?
Separation by concern makes each file reviewable on its own, and when Bolt gets one piece wrong you rerun or amend a single migration instead of untangling a monolith. It also mirrors how the schema evolves later, since structural changes and policy changes rarely arrive together.
How do I adapt the tracker shape to my actual domain?
Rename the resource placeholder to your entity and keep the patterns: uuid keys, an enum status, timestamptz everywhere, the updated_at trigger. Then re-derive the indexes from your real query patterns. Columns change freely, and the RLS structure of owner-full-access plus scoped public reads transfers to most multi-user schemas intact.
The smoke check's cross-owner update succeeded when it should have failed. What do I check?
You are almost certainly running it as a role that bypasses RLS, and the Supabase SQL editor uses a privileged role by default. Rerun the statement as the anon or authenticated role, and confirm each table actually ran enable row level security, since a policy on an unenabled table protects nothing.