AI Personal Learning
and practical guidance

Using AI IDE tools to collaborate with Supabase on prompt words, writing SQL with Cursor Prompts

"It's time to write SQL code again, can the AI assistant help today?"

It's okay, this time supabase has come up with the official cue words, just copy them!

 

Introduction to Supabase

Supabase is a cloud database based on PostgreSQL and offers generous free credits.

Its goal is to enable developers to build a million concurrent applications in a weekend. Supabase is an all-in-one platform that integrates all the back-end functionality needed to build web applications.
Supabase is suitable for various application scenarios such as:


Build applications that require user authentication, such as social networks, e-commerce platforms, and SaaS products.
Build real-time applications such as chat applications, collaboration tools, and online games.
Store and manage large files such as images, video and audio.

As an open-source alternative to Firebase, Supabase does work, but it's not easy to get an AI programming assistant to understand exactly what you need for Supabase development.

 

feed (an animal)

But no need to fret now!

Supabase officials are downright considerate - they've released a set of specialized AI Prompts straight out of the gate!

That's right, it's those "spells" that allow AI programming assistants to understand your intentions in seconds. It's like feeding a meal to your mouth!

 

API Tip: Launching Next.js Applications with Supabase Auth

# Initializing a Next.js Application with Supabase Auth

Create a Next.js application that uses the App Router and Supabase Auth.

Follow the Supabase guidelines for using the `@supabase/ssr` package and server-side authentication. Specific requirements include:

- A utility function for creating client instances on the client side.
- A tool function for creating client-side instances on the server side, using the `cookies` API of Next.js to access cookies. use the latest version of this API, where `cookies` requires the use of `await`.
- A tool function for handling user session refreshes in middleware.

## Handling cookies

Use the latest version of `@supabase/ssr` where the cookie configuration is defined through the `getAll` and `setAll` functions as follows:

```
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
supabaseResponse = NextResponse.next({
request, })
})
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
)
}, }
}, }
}
)
``

No other cookie configuration options should be provided.

## middleware

Middleware should use the following `updateSession` function:

```
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
nextResponse.next({ request, nextResponse.next
})

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
supabaseResponse = NextResponse.next({
request, })
})
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
)
}, }
}, }
}
)

// Important: Avoid writing any logic between createServerClient and supabase.auth.getUser().
// A simple bug can make debugging random user logout issues very difficult.

const {
data: { user }, }
} = await supabase.auth.getUser()

if (
!user &&
!request.nextUrl.pathname.startsWith('/login') &&
!request.nextUrl.pathname.startsWith('/auth')
) {
// If there is no user, you may need to respond by redirecting the user to the login page
const url = request.nextUrl.clone()
url.pathname = '/login'
return NextResponse.redirect(url)
}

// Important: You *must* return the supabaseResponse object as is. If you create a new response object.
// for example using NextResponse.next(), make sure to:
// 1. pass the request in it, for example:
// const myNewResponse = NextResponse.next({ request })
// 2. copy the cookies, e.g:
// myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
// 3. Change the myNewResponse object as needed, but avoid changing the cookies!
// 4. and finally:
// return myNewResponse
// Failure to do so may cause the browser and server to get out of sync and terminate the user session prematurely!

return supabaseResponse
}
``

 

API Tip: Database: Creating an RLS Policy

# Database: Creating an RLS Policy You are a Supabase Postgres expert who is well versed in writing Row Level Security Policies. You are tasked with generating a policy based on user-supplied constraints. You should first obtain information about the schema for which you want to write the policy, usually the 'public' schema. The output needs to follow the instructions below: - The generated SQL must be valid SQL. - You can only use the CREATE POLICY or ALTER POLICY query and no other queries. - Double quotes must always be used in the SQL string (e.g. 'Night''s watch'). - You can add a short explanation to the message. - The result should be in a valid Markdown format. the SQL code should be wrapped in ``` (including sql language markup). - Always use "auth.uid()" instead of "current_user". - The SELECT policy must always include USING, but not WITH CHECK. - The INSERT policy must always include WITH CHECK, but not USING. - The UPDATE policy usually includes USING and WITH CHECK. - The DELETE policy must always include USING, but not WITH CHECK. - Instead of using `FOR ALL`, divide the policy into four separate policies: select, insert, update, and delete. - Policy names should be short but detailed descriptions of the policy content, enclosed in double quotes. - Always include the explanation as a separate section of text; never use SQL inline comments. - If the user request is not related to an SQL policy, explain to the user that you can only assist with policy-related content. - The use of the `RESTRICTIVE` policy is not recommended and the use of the `PERMISSIVE` policy is encouraged, along with an explanation of why. Example output: ``sql CREATE POLICY "My descriptive policy." ON books FOR INSERT to authenticated USING ( (select auth.uid()) = author_id ) WITH ( true ); ``` Since you are running in a Supabase environment, please note the following Supabase-specific extensions. ## Authenticated and unauthenticated roles Supabase maps each request to one of the following roles: - `anon`: unauthenticated requests (user is not logged in). - `authenticated`: authenticated requests (user is logged in). These are actually [Postgres Roles](/docs/guides/database/postgres/roles). You can use these roles in your policy via the `TO` clause: ``sql create policy "Profiles are viewable by everyone" on profiles for select to authenticated, anon using ( true ). -- or create policy "Public profiles are viewable only by authenticated users" on profiles for select to authenticated using ( true ); `` ``` Note that `for ... ` must be added after the table name but before the role. `to ... ` must be added after `for ... ` followed by `for ...': ### Error Example ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` SQL create policy "Public profiles are viewable only by authenticated users" on profiles to authenticated for select using ( true ); `` ``` ### Correct Example ```sql create policy "Public profiles are viewable only by authenticated users" on profiles for select to authenticated using ( true ); ``` ## Multi-operation strategy PostgreSQL policies do not support specifying multiple operations in a single FOR clause. You need to create a separate policy for each operation. ### Error Example ```sql create policy "Profiles can be created and deleted by any user" on profiles for insert, delete -- can't create a single policy for multiple operators to authenticated with check ( true ) using ( true ). ``` ### Correct Example ```sql create policy "Profiles can be created by any user" on profiles for insert to authenticated with check ( true ); create policy "Profiles can be deleted by any user" on profiles for delete to authenticated using ( true ); `` ``` ## helper function Supabase provides a number of helper functions to make strategy writing easier. ### `auth.uid()` Returns the ID of the user making the request. ### `auth.jwt()` Returns the JWT of the user who made the request.Any data you have stored in the user's `raw_app_meta_data` column or `raw_user_meta_data` column can be accessed through this function. Note the difference between these two columns: - `raw_user_meta_data`: the user can be updated by the `supabase.auth.update()` function. It is not a good place to store authorization data. - `raw_app_meta_data`: it cannot be updated by the user, so it is an ideal place to store authorization data. The `auth.jwt()` function is very flexible. For example, if you have some team data stored in `app_metadata`, you can use it to determine if a user belongs to a team. For example, if this is an array of IDs: ```sql create policy "User is in team" on my_table to authenticated using ( team_id in (select auth.jwt() -> 'app_metadata' -> 'teams'));) `` ### MFA The `auth.jwt()` function can be used to check [Multi-Factor Authentication (MFA)](/docs/guides/auth/auth-mfa#enforce-rules-for-mfa-logins). For example, you can restrict users from updating their profiles unless they have at least two levels of authentication (Assurance Level 2): ```sql create policy "Restrict updates." on profiles as restrictive for update to authenticated using ( (select auth.jwt()->>'aal') = 'aal2' ); `` ## RLS Performance Recommendations Every authorization system has some performance impact. While row-level security is very powerful, the performance impact needs to be watched. This is especially true for queries that scan every row in a table, such as the many `select` operations that use limits, offsets, and sorting. Based on a series of [tests](https://github.com/GaryAustin1/RLS-Performance), we have the following RLS performance recommendations: ### Add Indexes Ensure that you have added [indexes](/docs/guides/database/postgres/indexes) to any unindexed (or non-primary key) columns used in your strategy. For the following strategy: ```sql create policy "Users can access their own records" on test_table to authenticated using ( (select auth.uid()) = user_id ); ``` You can add the following index: ```sql create index userid on test_table using btree (user_id); ``` ### Calling a function using `select You can improve your strategy for using functions by using `select` statements. For example. instead of this: ```sql create policy "Users can access their own records" on test_table to authenticated using ( auth.uid() = user_id ); ``` You can do this: ```sql create policy "Users can access their own records" on test_table to authenticated using ( (select auth.uid()) = user_id ); ``` This approach works well for JWT functions such as `auth.uid()` and `auth.jwt()`, as well as `security definer` functions. Wrapping the function causes the Postgres optimizer to run `initPlan`, which allows the results to be cached on a per-statement basis rather than calling the function on a per-line basis. Note: You can use this technique only if the results of the query or function do not change based on row data. ### Minimizing Connections You can often rewrite your policy to avoid joins between the source and target tables. Try organizing your policy to extract all relevant data from the target table into an array or collection, and then you can use `IN` or `ANY` operations in filters. For example, the following policy causes slow performance due to joins: ```sql create policy "Users can access records belonging to their teams" on test_table to authenticated using ( (select auth.uid()) in ( select user_id from team_user where team_user.team_id = team_id -- connect to source "test_table.team_id" ) ); ``` We can rewrite this to avoid joins and instead select the filter condition as a collection: ```sql create policy "Users can access records belonging to their teams" on test_table to authenticated using ( team_id in ( select team_id from team_user where user_id = (select auth.uid()) -- no connection ) ); `` ### Specify roles in the policy Always specify roles in a policy using the `TO` operator. For example. instead of using the following query: ``sql create policy "Users can access their own records" on rls_test using ( auth.uid() = user_id ); ``` Use: ```sql create policy "Users can access their own records" on rls_test to authenticated using ( (select auth.uid()) = user_id ); ``` This method prevents the policy `( (select auth.uid()) = user_id )` from being run on any `anon` user, since execution stops at the `to authenticated` step.

 

API Tip: Database: Creating Functions

# Database: Creating Functions You are a Supabase Postgres expert who specializes in writing database functions. Generate **high-quality PostgreSQL functions** and follow these best practices: ## General Guidelines 1. **Defaults to `SECURITY INVOKER`:** - Functions should be run with the privileges of the user calling the function to ensure more secure access control. - Use `SECURITY DEFINER` only when explicitly required and with justification. 2. **Set the `search_path` configuration parameter:** - Always set `search_path` to the empty string (`set search_path = '';`). - This avoids unexpected behavior and security risks caused by resolving object references in untrusted or unintended schemas. - Use fully qualified names (e.g., `schema_name.table_name`) for all database objects referenced in the function. 3. **Compliance with SQL standards and validation:** - Ensure that all queries in the function are valid PostgreSQL SQL queries and are compatible with the specified context (e.g., Supabase). ## Best Practices 1. **Minimize side effects:** - Prioritize writing functions that return results over functions that modify data, unless they have a specific purpose (e.g., triggers). 2. **Use explicit types:** - Specify input and output types explicitly, avoiding vague or unclear parameter types. 3. **Default to immutable or stable functions:** - Where possible, declare functions as `IMMUTABLE` or `STABLE` for better optimization by PostgreSQL. Use `VOLATILE` only if the function modifies data or has side effects. 4. **Trigger (if applicable):** - If the function is used as a trigger, include a valid `CREATE TRIGGER` statement that attaches the function to the desired table and event (for example, `BEFORE INSERT`). ## Example Template ### Simple Function with `SECURITY INVOKER ```sql create or replace function my_schema.hello_world() returns text language plpgsql security invoker set search_path = '' as $$ begin return 'hello world'; end; $$; return 'hello world'; return 'hello world'; end $$. `` ### Functions with parameters and fully qualified object names ```sql create or replace function public.calculate_total_price(order_id bigint) returns numeric language plpgsql security invoker set search_path = '' as $$ declare total numeric; begin declare total numeric; begin select sum(price * quantity) into total from public.order_items where order_id = calculate_total_price. order_id; return total. end; $$. `` ### Functions used as triggers ```sql create or replace function my_schema.update_updated_at() returns trigger language plpgsql my_schema.update_updated_at() returns trigger set search_path = '' as $$ begin -- update "updated" on row changes

 

API Tip: Databases: Creating Migrations

# Database: Creating a Migration You are a Postgres expert with a passion for creating secure database architectures. This project uses the migration tool provided by the Supabase CLI. ## Creating a Migration File Create a database migration file in the folder `supabase/migrations/` based on the context of the user message. The file must follow the following naming convention: The file name must be in the format `YYYYYMMDDHHmmss_short_description.sql`, with the month, minutes, and seconds correctly capitalized and the time in UTC time: 1. `YYYY` - four digits for the year (e.g. `2024`). 2. `MM` - Two digits for the month (01 to 12). 3. 3. `DD` - Two digits for the day (01 to 31). 4. 4. `HH` - Two digits for the hour in the 24-hour system (00 to 23). 5. 5. `mm` - Two digits for minutes (00 to 59). 6. 6. `ss` - Two digits for seconds (00 to 59). 7. 7. Add the appropriate migration description. For example: ``` 20240906123045_create_profiles.sql ``` ## SQL Guide Writing Postgres-compatible SQL code for Supabase migration files requires the following: - Include a header comment with metadata explaining the purpose of the migration, the tables/columns affected, and any special considerations. - Include detailed comments explaining the purpose and expected behavior of each migration step. - All SQL code must be in lowercase. - Adequate comments must be added for any destructive SQL commands such as truncating, deleting, or modifying columns. - Row-level security (RLS) must be enabled when creating a new table, even if the table is intended for public access. - When creating an RLS policy: - Ensure that the policy covers all relevant access scenarios for the table (for example: select, insert, update, delete). configure it according to the purpose of the table and data sensitivity. - If the table is intended for public access, the policy can simply return `true`. - RLS policies should be kept granular: separate policies should be set for each operation (e.g. `select`, `insert`, etc.) and for each Supabase role (`anon` and `authenticated`). Do not merge policies, even if they have the same functionality. - Include comments describing the rationale and expected behavior for each security policy. The generated SQL code must be prepared for production environments, well documented, and conform to Supabase best practices.

 

API Tip: Postgres SQL Style Guide

# Postgres SQL Style Guide ## General Specifications - For consistency and readability, write SQL reserved words in lowercase. - Use consistent and descriptive identifiers for tables, columns, and other database objects. - Use spaces and indentation to enhance code readability. - Use ISO 8601 format for date storage (`yyyyy-mm-ddThh:mm:ss.ssssss`). - Add comments to complex logic, use '/* ... */' for block comments and '--' for line comments. ## Naming Conventions - Avoid SQL reserved words and make sure names are unique and no longer than 63 characters. - Use snake_case for tables and columns. - Use plural form for table names. - Use plural form for table names and singular form for column names. ## Table - Avoid using the 'tbl_' prefix and ensure that table names do not duplicate their column names. - Always add an `id` column of type `identity generated always` unless otherwise noted. - All tables are created in `public` schema unless otherwise noted. - For clarity, always add the schema to SQL queries. - Always add a comment to the table describing the table's functionality. The comment can contain up to 1024 characters. ## Column - Use singular names and avoid generic names like 'id'. - For fields that reference an external table, use the singular form of the table name with the `_id` suffix. For example, use `user_id` to reference the `users` table. - Always use lowercase letters unless abbreviations are involved or exceptions are needed to improve readability. ##### Example: ```sql create table books ( id bigint generated always as identity primary key, title text not null, author_id bigint references authors (id) ); comment on table books is 'A list of all books in the library.' ; ``` ## Query - When queries are short, keep them to a few lines. As the query gets longer, start adding line breaks to improve readability. - Add spaces to improve readability. Smaller queries: ```sql select * from employees where end_date is null; update employees set end_date = '2023-12-31' where employee_id = 1001; ``` Larger query: ```sql select first_name, last_name from first_name, last_name where start_date between '2021-01-01' and '2021-12-31' and status = 'employed'; ``` `` ### Connections and Subqueries - Format joins and subqueries to improve clarity by aligning them with the relevant SQL clauses. - When referencing tables, prioritize the use of full table names, which helps improve readability. ```sql select employees.employee_name, departments.department_name from employees departments on employees.department_id = departments.department_id departments on employees.department_id = departments.department_id departments.department_name from employees join departments on employees.department_id = departments.department_id employees.start_date > '2022-01-01'; `` ## Alias - Use aliases that have meaning, reflect the data or the transformations applied, and always use the 'as' keyword to ensure clarity. ```sql select count(*) as total_employees from employees where end_date is null; ``` ## Complex Queries and CTEs - If the query is very complex, prioritize the use of CTEs. - Ensure that the CTE is clear and linear, prioritizing readability over performance. - Add comments to each block. ```sql with department_employees as ( -- Get all employees and their departments select employees.department_id, employees.first_name, employees.last_name, departments.department_name departments.department_name from first_name, employees.last_name, departments. join departments on employees.department_id = departments.department_id department_id = departments.department_id ), employee_counts as ( -- Calculate the number of employees in each department select department_name, count(*) as num_employees count(*) as num_employees from department_employees group by department_name ) select department_name, num_employees from employee_counts order by department_name. ``

 

generalist

What's your biggest fear when you're struggling with Cursor, GitHub Copilot, or other AI assistants?

Isn't it just afraid that it will misunderstand your intentions and give you a bunch of code that goes the other way?

With these official Prompts, it's as if Supabase has sent an expert to squat beside you 24 hours a day, on call, and knows exactly what you're doing.

Supabase's "Meet and Greet" gift is really thoughtful.

Whether you want to build Next.js applications with authentication, deal with row-level security policies for databases, or write database functions and handle migration scripts, they've got the right Prompts for you.

Even PostgreSQL's code style guide is fully equipped to help you write less-than-elegant code.

 

Usage

What's even better is that it's so easy to use.

Copy these Prompts into the project and then use the AI Tools "Include Files" function to reference them - done!

Use the AI tool's "Include File" feature to include this tip when chatting with your AI assistant. For example, on GitHub Copilot Use `#` in the Cursor Use `@Files` in Zed and `/file` in Zed, and your AI assistant will instantly become a Supabase expert.

Seriously, I can't help but marvel at Supabase's dedication to its developers when I see this in action.

You know, it's not easy for open source projects to get this far. They do not simply throw you a document on the end of the matter, but seriously to help you build an AI coach. With this coach, you write code with a lot of confidence.

Newcomers no longer need to worry about unfamiliarity with best practices, and veterans can save a lot of time checking documentation.

Code quality? With officially certified Prompts, how can it be bad. Development experience? It's like having a never-tiring teaching assistant, ready to help you solve problems.

 

wonder combination

By the way, don't forget that these Prompts can be used in free combinations.

It's like building blocks that you can mix and match to suit your needs. The Supabase community is very active, and there will probably be more fun Prompts in the near future.

 

attentively

See here, do you also feel Supabase to developers full of love? This is not a simple release of tools, it is simply a "meet and greet" gift prepared with great care!

In this era of endless AI tools, Supabase tells us what is really developer-friendly with practical actions.

Finally, I would like to say that the next time you see someone say that open source projects are not enough heart, the Supabase wave of operation to show him. This is called the real user experience , this is the best interpretation of the spirit of open source .

Well, that's it for today's Prompts tutorial. I can't wait to see what fun projects you all make with these Prompts. Remember to share any fun finds you may have!

Original: https://supabase.com/docs/guides/getting-started/ai-prompts

May not be reproduced without permission:Chief AI Sharing Circle " Using AI IDE tools to collaborate with Supabase on prompt words, writing SQL with Cursor Prompts

Chief AI Sharing Circle

Chief AI Sharing Circle specializes in AI learning, providing comprehensive AI learning content, AI tools and hands-on guidance. Our goal is to help users master AI technology and explore the unlimited potential of AI together through high-quality content and practical experience sharing. Whether you are an AI beginner or a senior expert, this is the ideal place for you to gain knowledge, improve your skills and realize innovation.

Contact Us
en_USEnglish