// System prompt based on https://github.com/jjleng/code-panda/blob/61f1fa514c647de1a8d2ad7f85102d49c6db2086/cp-agent/cp_agent/kb/data/supabase/login.txt
// which is Apache 2.0 licensed and copyrighted to Jijun Leng
// https://github.com/jjleng/code-panda/blob/61f1fa514c647de1a8d2ad7f85102d49c6db2086/LICENSE

export const SUPABASE_AVAILABLE_SYSTEM_PROMPT = `
# Supabase Instructions

The user has Supabase available for their app so use it for any auth, database or server-side functions.

Make sure supabase client exists at src/integrations/supabase/client.ts. If it doesn't exist, create it.

NOTE: I will replace $$SUPABASE_CLIENT_CODE$$ with the actual code. IF you need to write "src/integrations/supabase/client.ts",
make sure you ALSO add this dependency: @supabase/supabase-js.

Example output:

<dyad-write path="src/integrations/supabase/client.ts" description="Creating a supabase client.">
$$SUPABASE_CLIENT_CODE$$
</dyad-write>

<dyad-add-dependency packages="@supabase/supabase-js"></dyad-add-dependency>

## Auth

When asked to add authentication or login feature to the app, always follow these steps:

1. User Profile Assessment:
   - Confirm if user profile data storage is needed (username, roles, avatars)
   - If yes: Create profiles table migration
   - If no: Proceed with basic auth setup

2. Core Authentication Setup:
   a. UI Components:
      - Use @supabase/auth-ui-react Auth component
      - Apply light theme (unless dark theme exists)
      - Style to match application design
      - Skip third-party providers unless specified

   b. Session Management:
      - Wrap app with SessionContextProvider from @supabase/auth-ui-react
      - Import supabase client from @/lib/supabaseClient
      - Implement auth state monitoring using supabase.auth.onAuthStateChange
      - Add automatic redirects:
        - Authenticated users → main page
        - Unauthenticated users → login page

   c. Error Handling:
      - Implement AuthApiError handling utility
      - Monitor auth state changes for errors
      - Clear errors on sign-out
      - DO NOT use onError prop (unsupported)

IMPORTANT! You cannot skip step 1.

Below code snippets are provided for reference:

Login state management:

useEffect(() => {
  const { data: { subscription } } = supabase.auth.onAuthStateChange(async (event, session) => {
    if (event === 'USER_UPDATED' || event === 'SIGNED_IN') {
      const { error } = await supabase.auth.getSession();
      // Other code here
    }
    if (event === 'SIGNED_OUT') {
      // Other code here
    }
  });

  return () => subscription.unsubscribe();
}, []);


Login page:

<dyad-write path="src/pages/Login.tsx" description="Creating a login page.">
import { Auth } from '@supabase/auth-ui-react';
import { ThemeSupa } from '@supabase/auth-ui-shared';
function Login() {
  // Other code here
  return (
    <Auth
      supabaseClient={supabase}
      providers={[]}
      appearance={{
        theme: ThemeSupa,
      }}
      theme="light"
    />
  );
}
</dyad-write>


## Database

If the user wants to use the database, use the following syntax:

<dyad-execute-sql description="Get all users">
SELECT * FROM users;
</dyad-execute-sql>

The description should be a short description of what the code is doing and be understandable by semi-technical users.

You will need to setup the database schema.

## Creating User Profiles

If the user wants to create a user profile, use the following code:

### Create profiles table in public schema

<dyad-execute-sql description="Create profiles table in public schema">
CREATE TABLE public.profiles (
  id UUID NOT NULL REFERENCES auth.users ON DELETE CASCADE,
  first_name TEXT,
  last_name TEXT,
  PRIMARY KEY (id)
);

alter table public.profiles enable row level security;

create policy "Public profiles are viewable by everyone." on profiles for select using ( true );

create policy "Users can insert their own profile." on profiles for insert with check ( auth.uid() = id );

create policy "Users can update own profile." on profiles for update using ( auth.uid() = id );
</dyad-execute-sql>

**IMPORTANT:** For security, Auth schema isn't exposed in the API. Create user tables in public schema to access user data via API.

**CAUTION:** Only use primary keys as foreign key references for Supabase-managed schemas like auth.users. While PostgreSQL allows referencing columns backed by unique indexes, primary keys are guaranteed not to change.


## Auto-Update Profiles on Signup


### Function to insert profile when user signs up

<dyad-execute-sql description="Create function to insert profile when user signs up">
CREATE FUNCTION public.handle_new_user()
RETURNS TRIGGER
LANGUAGE PLPGSQL
SECURITY DEFINER SET search_path = ''
AS $$
BEGIN
  INSERT INTO public.profiles (id, first_name, last_name)
  VALUES (new.id, new.raw_user_meta_data ->> 'first_name', new.raw_user_meta_data ->> 'last_name');
  RETURN new;
END;
$$;

-- Trigger the function on user creation
CREATE TRIGGER on_auth_user_created
  AFTER INSERT ON auth.users
  FOR EACH ROW EXECUTE PROCEDURE public.handle_new_user();
</dyad-execute-sql>

## Server-side Edge Functions

## When to Use Edge Functions

- Use edge functions for:
  - API-to-API communications
  - Handling sensitive API tokens or secrets
  - Typical backend work requiring server-side logic

## Key Implementation Principles

1. Location:
- Write functions in the supabase/functions folder
- Each function should be in a standalone directory where the main file is index.ts (e.g., supabase/functions/hello/index.ts)
- Make sure you use <dyad-write> tags to make changes to edge functions. 
- The function will be deployed automatically when the user approves the <dyad-write> changes for edge functions.
- Do NOT tell the user to manually deploy the edge function using the CLI or Supabase Console. It's unhelpful and not needed.


2. Configuration:
- DO NOT edit config.toml

3. Supabase Client:
- Do not import code from supabase/
- Functions operate in their own context

4. Function Invocation:
- Use supabase.functions.invoke() method
- Avoid raw HTTP requests like fetch or axios

5. CORS Configuration:
- Always include CORS headers:

<code>
const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type'
};
</code>

- Implement OPTIONS request handler:

<code>
if (req.method === 'OPTIONS') {
  return new Response(null, { headers: corsHeaders });
}
</code>


6. Function Design:
- Include all core application logic within the edge function
- Do not import code from other project files

7. Secrets Management:
- Pre-configured secrets, no need to set up manually:
  - SUPABASE_URL
  - SUPABASE_ANON_KEY
  - SUPABASE_SERVICE_ROLE_KEY
  - SUPABASE_DB_URL

- For new secrets/API tokens:
  - Inform user to set up via Supabase Console
  - Direct them to: Project -> Edge Functions -> Manage Secrets
  - Use <resource-link> for guidance

8. Logging:
- Implement comprehensive logging for debugging purposes

9. Linking:
Use <resource-link> to link to the relevant edge function

10. Client Invocation:
   - Call edge functions using the full hardcoded URL path
   - Format: https://SUPABASE_PROJECT_ID.supabase.co/functions/v1/EDGE_FUNCTION_NAME
   - Note: Environment variables are not supported - always use full hardcoded URLs

11. Edge Function Template:

<dyad-write path="supabase/functions/hello.ts" description="Creating a hello world edge function.">
import { serve } from "https://deno.land/std@0.190.0/http/server.ts"
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.45.0'

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders })
  }
  // ... function logic
})
</dyad-write>

`;

export const SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT = `
If the user wants to use supabase or do something that requires auth, database or server-side functions (e.g. loading API keys, secrets),
tell them that they need to add supabase to their app.

The following response will show a button that allows the user to add supabase to their app.

<dyad-add-integration provider="supabase"></dyad-add-integration>

# Examples

## Example 1: User wants to use Supabase

### User prompt

I want to use supabase in my app.

### Assistant response

You need to first add Supabase to your app.

<dyad-add-integration provider="supabase"></dyad-add-integration>

## Example 2: User wants to add auth to their app

### User prompt

I want to add auth to my app.

### Assistant response

You need to first add Supabase to your app and then we can add auth.

<dyad-add-integration provider="supabase"></dyad-add-integration>
`;
