Merge origin/master

This commit is contained in:
2026-01-25 19:46:04 +01:00
429 changed files with 77997 additions and 25554 deletions
+119
View File
@@ -0,0 +1,119 @@
# How to Apply the Rate Limits Migration
## Quick Start (Manual Application)
Since the Supabase CLI is not configured for this project, please follow these steps to apply the migration manually through the Supabase dashboard:
### Step 1: Access the SQL Editor
Open the Supabase SQL Editor in your browser:
```
https://app.supabase.com/project/mxadgucxhmstlzsbgmoz/sql
```
### Step 2: Copy the Migration SQL
Open the migration file:
```
supabase/migrations/20260125_create_rate_limits_table.sql
```
Copy the entire contents (approximately 42 lines of SQL).
### Step 3: Execute the Migration
1. In the SQL Editor, paste the copied SQL
2. Click the **"RUN"** button (or press `Ctrl+Enter` / `Cmd+Enter`)
3. Wait for the success message: "Success. No rows returned"
### Step 4: Verify the Table Was Created
**Option A: Using Table Editor**
1. Navigate to: https://app.supabase.com/project/mxadgucxhmstlzsbgmoz/editor
2. Look for **"rate_limits"** in the table list (left sidebar)
3. Click on it to see the table structure
**Option B: Using SQL Query**
Run this query in the SQL Editor:
```sql
SELECT
table_name,
column_name,
data_type,
is_nullable
FROM information_schema.columns
WHERE table_name = 'rate_limits'
ORDER BY ordinal_position;
```
You should see 5 rows (one for each column):
- identifier (text)
- count (integer)
- window_start (timestamp with time zone)
- created_at (timestamp with time zone)
- updated_at (timestamp with time zone)
**Option C: Check Indexes**
Run this query to verify indexes were created:
```sql
SELECT
indexname,
indexdef
FROM pg_indexes
WHERE tablename = 'rate_limits';
```
You should see:
- Primary key on (identifier, window_start)
- idx_rate_limits_identifier_window
- idx_rate_limits_window_start
## Troubleshooting
### Error: "relation 'rate_limits' already exists"
The table is already created! No action needed. Verify it exists using the verification steps above.
### Error: "permission denied"
Make sure you're:
1. Logged into the correct Supabase account
2. Have admin/owner permissions on the project
3. Using the correct project URL
### Table not visible in Table Editor
1. Refresh the page (F5)
2. Check the SQL output for error messages
3. Try the SQL verification query in Option B above
### Need to Revert/Drop the Table?
If you need to start over, run this SQL:
```sql
DROP TABLE IF EXISTS rate_limits CASCADE;
```
Then re-apply the migration from Step 1.
## Alternative: Automated Scripts
We've provided scripts for automated migration, but they require additional setup:
### Using apply-migration.js (requires service role key)
1. Add `SUPABASE_SERVICE_ROLE_KEY` to `.env.local`
2. Run: `node scripts/apply-migration.js`
### Using Supabase CLI (if installed)
```bash
supabase migration up
```
## Next Steps
After the migration is applied successfully:
1. ✅ Verify the table exists (see Step 4 above)
2. ✅ Mark this subtask as complete
3. ✅ Proceed to Phase 2: Building the rate limiting utility
+85
View File
@@ -0,0 +1,85 @@
# Supabase Migration Instructions
## Apply Migration: Create rate_limits Table
### Quick Steps
1. **Open Supabase SQL Editor**
- Go to: https://app.supabase.com/project/mxadgucxhmstlzsbgmoz/sql
2. **Copy Migration SQL**
- Open: `supabase/migrations/20260125_create_rate_limits_table.sql`
- Copy all contents (Ctrl+A, Ctrl+C)
3. **Execute Migration**
- Paste the SQL into the Supabase SQL editor
- Click the "Run" button (or press Ctrl+Enter)
- Wait for "Success. No rows returned" message
4. **Verify Table Creation**
- Go to Table Editor: https://app.supabase.com/project/mxadgucxhmstlzsbgmoz/editor
- Look for "rate_limits" table in the list
- Click on it to verify the schema
### Expected Table Schema
The `rate_limits` table should have:
| Column | Type | Description |
|--------|------|-------------|
| identifier | TEXT | Client identifier (IP address) |
| count | INTEGER | Number of requests in window |
| window_start | TIMESTAMPTZ | Start of rate limit window |
| created_at | TIMESTAMPTZ | When record was created |
| updated_at | TIMESTAMPTZ | When record was last updated |
**Primary Key:** (identifier, window_start)
**Indexes:**
- `idx_rate_limits_identifier_window` on (identifier, window_start DESC)
- `idx_rate_limits_window_start` on (window_start)
### Alternative: Using Supabase CLI (if available)
If you have Supabase CLI installed:
```bash
supabase db push
```
Or apply the specific migration:
```bash
supabase migration up
```
### Verification Query
Run this query in the SQL editor to verify the table exists:
```sql
SELECT
table_name,
column_name,
data_type,
is_nullable
FROM information_schema.columns
WHERE table_name = 'rate_limits'
ORDER BY ordinal_position;
```
You should see all 5 columns listed.
### Troubleshooting
**Error: "relation already exists"**
- The table already exists. You can verify by checking Table Editor.
**Error: "permission denied"**
- Make sure you're logged into the correct Supabase project.
- Verify you have admin/owner access to the project.
**Table not appearing in Table Editor**
- Refresh the page (F5)
- Check the SQL editor for any error messages
- Verify the SQL was executed successfully
@@ -0,0 +1,41 @@
-- Create rate_limits table for persistent rate limiting
-- This replaces the in-memory Map-based rate limiter
CREATE TABLE IF NOT EXISTS rate_limits (
-- Unique identifier (typically IP address)
identifier TEXT NOT NULL,
-- Number of requests in the current time window
count INTEGER NOT NULL DEFAULT 1,
-- Start of the rate limit window (for sliding window algorithm)
window_start TIMESTAMPTZ NOT NULL,
-- Timestamp when the record was created
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Timestamp when the record was last updated
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Primary key ensures one record per identifier per time window
PRIMARY KEY (identifier, window_start)
);
-- Index for fast lookups by identifier and window_start
-- This is critical for rate limiting performance
CREATE INDEX IF NOT EXISTS idx_rate_limits_identifier_window
ON rate_limits(identifier, window_start DESC);
-- Index for cleanup queries (to remove old rate limit records)
CREATE INDEX IF NOT EXISTS idx_rate_limits_window_start
ON rate_limits(window_start);
-- Add a comment to the table
COMMENT ON TABLE rate_limits IS 'Stores rate limiting data for API endpoints. Each record tracks request counts within a time window for a specific identifier (typically IP address).';
-- Add comments to columns for documentation
COMMENT ON COLUMN rate_limits.identifier IS 'Unique identifier for the client (typically IP address)';
COMMENT ON COLUMN rate_limits.count IS 'Number of requests made in the current time window';
COMMENT ON COLUMN rate_limits.window_start IS 'Start timestamp of the rate limit window';
COMMENT ON COLUMN rate_limits.created_at IS 'Timestamp when this record was first created';
COMMENT ON COLUMN rate_limits.updated_at IS 'Timestamp when this record was last updated';