File size: 3,282 Bytes
407c78b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
Run this script once to create the Supabase users table.
Usage: python scripts/migrate_supabase.py

Requires the SUPABASE_URL and SUPABASE_SERVICE_KEY env vars to be set.
This uses the Supabase REST API to execute SQL via the pg_query extension.
If that fails, manually run migrations/001_create_users.sql in your Supabase SQL editor.
"""
import os
import sys

import httpx

SQL = """
CREATE TABLE IF NOT EXISTS users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    hf_username TEXT UNIQUE NOT NULL,
    hf_email TEXT DEFAULT '',
    hf_avatar_url TEXT DEFAULT '',
    created_at TIMESTAMPTZ DEFAULT now(),
    last_login_at TIMESTAMPTZ DEFAULT now(),
    onboarding_complete BOOLEAN DEFAULT false
);

CREATE INDEX IF NOT EXISTS idx_users_hf_username ON users (hf_username);

-- Enable RLS
ALTER TABLE users ENABLE ROW LEVEL SECURITY;

-- Drop existing policies if they exist and recreate
DROP POLICY IF EXISTS "Users can read own row" ON users;
CREATE POLICY "Users can read own row" ON users
    FOR SELECT USING (hf_username = current_setting('request.jwt.claims', true)::json->>'hf_username');

DROP POLICY IF EXISTS "Users can update own row" ON users;
CREATE POLICY "Users can update own row" ON users
    FOR UPDATE USING (hf_username = current_setting('request.jwt.claims', true)::json->>'hf_username')
    WITH CHECK (hf_username = current_setting('request.jwt.claims', true)::json->>'hf_username');
"""


async def main():
    url = os.environ.get("SUPABASE_URL", "").rstrip("/")
    service_key = os.environ.get("SUPABASE_SERVICE_KEY", "")
    anon_key = os.environ.get("SUPABASE_ANON_KEY", "")

    if not url or not service_key:
        print("ERROR: SUPABASE_URL and SUPABASE_SERVICE_KEY must be set")
        print("\nAlternatively, run the SQL in migrations/001_create_users.sql")
        print("directly in your Supabase dashboard SQL editor.")
        sys.exit(1)

    headers = {
        "apikey": anon_key or service_key,
        "Authorization": f"Bearer {service_key}",
        "Content-Type": "application/json",
    }

    # Try using pg_query RPC (requires the pg_query function to exist)
    print("Attempting migration via pg_query RPC...")
    async with httpx.AsyncClient(timeout=15) as client:
        resp = await client.post(
            f"{url}/rest/v1/rpc/pg_query",
            json={"query": SQL},
            headers=headers,
        )
        if resp.status_code == 200:
            print("Migration successful via pg_query RPC.")
            return

        # If pg_query doesn't exist, try raw SQL via the management API
        print(f"pg_query RPC failed ({resp.status_code}), trying /sql endpoint...")

        resp2 = await client.post(
            f"{url}/sql",
            json={"query": SQL},
            headers=headers,
        )
        if resp2.status_code == 200:
            print("Migration successful via /sql endpoint.")
            return

        print(f"/sql endpoint failed ({resp2.status_code})")
        print(f"Response: {resp2.text[:200]}")
        print("\nPlease run the SQL in migrations/001_create_users.sql")
        print("manually in your Supabase dashboard SQL editor.")
        print(f"URL: {url}/project/default/sql/new")


if __name__ == "__main__":
    import asyncio

    asyncio.run(main())