needware-cli 1.5.17 → 1.5.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agent.js +2 -2
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/skill.d.ts +23 -1
- package/dist/commands/skill.d.ts.map +1 -1
- package/dist/commands/skill.js +91 -29
- package/dist/commands/skill.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/supabase-execute-sql-tool.d.ts +15 -0
- package/dist/tools/supabase-execute-sql-tool.d.ts.map +1 -0
- package/dist/tools/supabase-execute-sql-tool.js +83 -0
- package/dist/tools/supabase-execute-sql-tool.js.map +1 -0
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/tool-registry.js +2 -0
- package/dist/tools/tool-registry.js.map +1 -1
- package/package.json +1 -1
- package/skills/ai-integration/SKILL.md +793 -0
- package/skills/supabase-integration/SKILL.md +556 -0
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supabase-integration
|
|
3
|
+
description: Complete Supabase integration for React applications including database setup, authentication, storage, and Edge Functions. Use this skill when users mention Supabase, databases, user authentication, file storage, "Enable Cloud", or backend functionality. 使用此技能处理 Supabase 数据库、用户认证、文件存储、Edge Functions 等后端功能。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Supabase Integration
|
|
7
|
+
|
|
8
|
+
## Before Starting - Integration Check
|
|
9
|
+
|
|
10
|
+
**CRITICAL**: Before initializing Supabase, always check the current integration status:
|
|
11
|
+
|
|
12
|
+
**Step 1: Check Existing Integration**
|
|
13
|
+
|
|
14
|
+
Check if Supabase is already integrated:
|
|
15
|
+
- Look for `src/lib/supabase.ts` file
|
|
16
|
+
- Check `.env` file for Supabase environment variables:
|
|
17
|
+
- `VITE_SUPABASE_PROJECT_ID`
|
|
18
|
+
- `VITE_SUPABASE_PUBLISHABLE_KEY`
|
|
19
|
+
- `VITE_SUPABASE_URL`
|
|
20
|
+
|
|
21
|
+
**Step 2: Handle Based on Status**
|
|
22
|
+
|
|
23
|
+
**If already integrated (supabase.ts exists with valid configuration)**:
|
|
24
|
+
- Inform user: "✓ Supabase is already integrated and configured."
|
|
25
|
+
|
|
26
|
+
**If not integrated (no supabase.ts)**:
|
|
27
|
+
- Call `supabase-enable` tool
|
|
28
|
+
- Check if tool result contains required environment variables:
|
|
29
|
+
- `VITE_SUPABASE_PROJECT_ID`
|
|
30
|
+
- `VITE_SUPABASE_PUBLISHABLE_KEY`
|
|
31
|
+
- `VITE_SUPABASE_URL`
|
|
32
|
+
- **If variables are present**: Proceed with full "Enable Cloud" workflow below
|
|
33
|
+
- **If tool reports an error**: Stop execution immediately and notify user of error
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
Complete guide for integrating Supabase into React applications with database, authentication, storage, and serverless functions.
|
|
39
|
+
|
|
40
|
+
Supabase 集成指南,包括数据库、认证、存储和 Edge Functions。
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### When to Use This Skill
|
|
45
|
+
|
|
46
|
+
Use this skill when working with:
|
|
47
|
+
- Database operations (PostgreSQL via Supabase)
|
|
48
|
+
- User authentication and authorization
|
|
49
|
+
- File upload and storage
|
|
50
|
+
- Serverless backend logic (Edge Functions)
|
|
51
|
+
- Real-time data subscriptions
|
|
52
|
+
- Row Level Security (RLS) policies
|
|
53
|
+
|
|
54
|
+
**关键原则**: 默认使用 Supabase 作为数据库和后端服务,除非用户明确指定其他方案。
|
|
55
|
+
|
|
56
|
+
## Initial Setup
|
|
57
|
+
|
|
58
|
+
### Prerequisites
|
|
59
|
+
|
|
60
|
+
Supabase project must be configured by the user. If no project is selected, remind user to select a project.
|
|
61
|
+
|
|
62
|
+
### "Enable Cloud" Workflow
|
|
63
|
+
|
|
64
|
+
**CRITICAL**: When user says "Enable Cloud" or requests Supabase initialization, immediately execute these steps WITHOUT asking for confirmation:
|
|
65
|
+
|
|
66
|
+
**Step 1: Install Dependencies**
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pnpm add @supabase/supabase-js
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Step 2: Create Environment File**
|
|
73
|
+
|
|
74
|
+
Create `.env` file with project credentials:
|
|
75
|
+
|
|
76
|
+
```env
|
|
77
|
+
VITE_SUPABASE_PROJECT_ID=your_project_id
|
|
78
|
+
VITE_SUPABASE_PUBLISHABLE_KEY=your_publishable_key
|
|
79
|
+
VITE_SUPABASE_URL=your_supabase_url
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Step 3: Create Supabase Client**
|
|
83
|
+
|
|
84
|
+
Create `src/lib/supabase.ts`:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { createClient } from '@supabase/supabase-js';
|
|
88
|
+
|
|
89
|
+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
|
|
90
|
+
const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;
|
|
91
|
+
|
|
92
|
+
if (!supabaseUrl || !supabaseKey) {
|
|
93
|
+
throw new Error('Missing Supabase environment variables');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const supabase = createClient(supabaseUrl, supabaseKey);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Step 4: Create Migrations Directory**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
mkdir -p supabase/migrations
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Step 5: Confirm Setup**
|
|
106
|
+
|
|
107
|
+
Inform user: "Supabase is now initialized and ready to use."
|
|
108
|
+
|
|
109
|
+
## Database Migrations
|
|
110
|
+
|
|
111
|
+
### Data Safety Rules
|
|
112
|
+
|
|
113
|
+
**CRITICAL**: Data integrity is the highest priority - users must NEVER lose data.
|
|
114
|
+
|
|
115
|
+
**Forbidden Operations**:
|
|
116
|
+
- ❌ Destructive operations: `DROP`, `DELETE` that could cause data loss
|
|
117
|
+
- ❌ Transaction control: `BEGIN`, `COMMIT`, `ROLLBACK`, `END`
|
|
118
|
+
- ✅ **Exception**: `DO $$ BEGIN ... END $$` blocks (PL/pgSQL) are allowed
|
|
119
|
+
|
|
120
|
+
### Migration Workflow
|
|
121
|
+
|
|
122
|
+
For EVERY database change, create a migration file in `/supabase/migrations/`:
|
|
123
|
+
|
|
124
|
+
**Required Steps**:
|
|
125
|
+
1. Create new `.sql` file with descriptive name (e.g., `create_users_table.sql`)
|
|
126
|
+
2. Write complete SQL content with comments
|
|
127
|
+
3. Include safety checks (`IF EXISTS`/`IF NOT EXISTS`)
|
|
128
|
+
4. Enable RLS and add appropriate policies
|
|
129
|
+
|
|
130
|
+
**Migration Rules**:
|
|
131
|
+
- ✅ Always provide COMPLETE file content (never use diffs)
|
|
132
|
+
- ✅ Create new migration file for each change in `/home/project/supabase/migrations`
|
|
133
|
+
- ❌ NEVER update existing migration files
|
|
134
|
+
- ✅ Use descriptive names without number prefix (e.g., `create_users.sql`)
|
|
135
|
+
- ✅ Always enable RLS: `ALTER TABLE users ENABLE ROW LEVEL SECURITY;`
|
|
136
|
+
- ✅ Add RLS policies for CRUD operations
|
|
137
|
+
- ✅ Use default values: `DEFAULT false/true`, `DEFAULT 0`, `DEFAULT ''`, `DEFAULT now()`
|
|
138
|
+
- ✅ Start with markdown summary in multi-line comment
|
|
139
|
+
- ✅ Use `IF EXISTS`/`IF NOT EXISTS` for safe operations
|
|
140
|
+
|
|
141
|
+
### Migration Template
|
|
142
|
+
|
|
143
|
+
```sql
|
|
144
|
+
/*
|
|
145
|
+
# Create users table
|
|
146
|
+
1. New Tables: users (id uuid, email text, created_at timestamp)
|
|
147
|
+
2. Security: Enable RLS, add read policy for authenticated users
|
|
148
|
+
*/
|
|
149
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
150
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
151
|
+
email text UNIQUE NOT NULL,
|
|
152
|
+
created_at timestamptz DEFAULT now()
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
|
|
156
|
+
|
|
157
|
+
CREATE POLICY "Users read own data"
|
|
158
|
+
ON users
|
|
159
|
+
FOR SELECT
|
|
160
|
+
TO authenticated
|
|
161
|
+
USING (auth.uid() = id);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Client Setup
|
|
165
|
+
|
|
166
|
+
### Installation
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
pnpm add @supabase/supabase-js
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Client Configuration
|
|
173
|
+
|
|
174
|
+
Create singleton client in `src/lib/supabase.ts`:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { createClient } from '@supabase/supabase-js';
|
|
178
|
+
|
|
179
|
+
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
|
|
180
|
+
const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;
|
|
181
|
+
|
|
182
|
+
export const supabase = createClient(supabaseUrl, supabaseKey);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Required Environment Variables**:
|
|
186
|
+
- `VITE_SUPABASE_URL`
|
|
187
|
+
- `VITE_SUPABASE_PUBLISHABLE_KEY`
|
|
188
|
+
|
|
189
|
+
## Authentication
|
|
190
|
+
|
|
191
|
+
### Authentication Strategy
|
|
192
|
+
|
|
193
|
+
**Default Method**: Email/password authentication
|
|
194
|
+
- ✅ Always use email/password signup
|
|
195
|
+
- ❌ FORBIDDEN: Magic links, social providers, SSO (unless explicitly stated)
|
|
196
|
+
- ❌ FORBIDDEN: Custom auth systems (always use Supabase built-in auth)
|
|
197
|
+
- ⚙️ Email confirmation: Always disabled unless stated
|
|
198
|
+
|
|
199
|
+
### Authentication Examples
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// 注册
|
|
203
|
+
const { data, error } = await supabase.auth.signUp({
|
|
204
|
+
email: 'user@example.com',
|
|
205
|
+
password: 'securepassword'
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// 登录
|
|
209
|
+
const { data, error } = await supabase.auth.signInWithPassword({
|
|
210
|
+
email: 'user@example.com',
|
|
211
|
+
password: 'securepassword'
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// 登出
|
|
215
|
+
const { error } = await supabase.auth.signOut();
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## User Profiles
|
|
219
|
+
|
|
220
|
+
### Profile Table Setup
|
|
221
|
+
|
|
222
|
+
**REQUIRED**: Always create `public.profiles` table linked to `auth.users`:
|
|
223
|
+
|
|
224
|
+
```sql
|
|
225
|
+
CREATE TABLE IF NOT EXISTS profiles (
|
|
226
|
+
user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE UNIQUE NOT NULL,
|
|
227
|
+
username text,
|
|
228
|
+
avatar_url text,
|
|
229
|
+
created_at timestamptz DEFAULT now(),
|
|
230
|
+
updated_at timestamptz DEFAULT now(),
|
|
231
|
+
PRIMARY KEY (user_id)
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
|
|
235
|
+
|
|
236
|
+
-- 添加策略
|
|
237
|
+
CREATE POLICY "Users can view all profiles"
|
|
238
|
+
ON profiles
|
|
239
|
+
FOR SELECT
|
|
240
|
+
TO authenticated
|
|
241
|
+
USING (true);
|
|
242
|
+
|
|
243
|
+
CREATE POLICY "Users can update own profile"
|
|
244
|
+
ON profiles
|
|
245
|
+
FOR UPDATE
|
|
246
|
+
TO authenticated
|
|
247
|
+
USING (auth.uid() = user_id);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Auto-Create Profile Trigger
|
|
251
|
+
|
|
252
|
+
Create trigger to automatically insert profile on user signup:
|
|
253
|
+
|
|
254
|
+
```sql
|
|
255
|
+
CREATE OR REPLACE FUNCTION handle_new_user()
|
|
256
|
+
RETURNS trigger AS $$
|
|
257
|
+
BEGIN
|
|
258
|
+
INSERT INTO public.profiles (user_id, username)
|
|
259
|
+
VALUES (new.id, new.email);
|
|
260
|
+
RETURN new;
|
|
261
|
+
END;
|
|
262
|
+
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
263
|
+
|
|
264
|
+
CREATE TRIGGER on_auth_user_created
|
|
265
|
+
AFTER INSERT ON auth.users
|
|
266
|
+
FOR EACH ROW EXECUTE FUNCTION handle_new_user();
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Storage
|
|
270
|
+
|
|
271
|
+
Use Supabase Storage when users need file upload functionality (images, documents, etc.).
|
|
272
|
+
|
|
273
|
+
### Create Storage Bucket
|
|
274
|
+
|
|
275
|
+
Create buckets in migrations:
|
|
276
|
+
|
|
277
|
+
```sql
|
|
278
|
+
INSERT INTO storage.buckets (id, name, public)
|
|
279
|
+
VALUES ('avatars', 'avatars', true);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Storage RLS Policies
|
|
283
|
+
|
|
284
|
+
Always add RLS policies for `storage.objects` table with `bucket_id` filter:
|
|
285
|
+
|
|
286
|
+
```sql
|
|
287
|
+
CREATE POLICY "Avatar images are publicly accessible"
|
|
288
|
+
ON storage.objects FOR SELECT
|
|
289
|
+
USING (bucket_id = 'avatars');
|
|
290
|
+
|
|
291
|
+
CREATE POLICY "Users can upload avatars"
|
|
292
|
+
ON storage.objects FOR INSERT
|
|
293
|
+
TO authenticated
|
|
294
|
+
WITH CHECK (bucket_id = 'avatars');
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Common Storage Operations
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Upload file
|
|
301
|
+
const { data, error } = await supabase.storage
|
|
302
|
+
.from('avatars')
|
|
303
|
+
.upload('user-id/avatar.png', file);
|
|
304
|
+
|
|
305
|
+
// Download file
|
|
306
|
+
const { data, error } = await supabase.storage
|
|
307
|
+
.from('avatars')
|
|
308
|
+
.download('user-id/avatar.png');
|
|
309
|
+
|
|
310
|
+
// Get public URL
|
|
311
|
+
const { data } = supabase.storage
|
|
312
|
+
.from('avatars')
|
|
313
|
+
.getPublicUrl('user-id/avatar.png');
|
|
314
|
+
|
|
315
|
+
// Delete file
|
|
316
|
+
const { error } = await supabase.storage
|
|
317
|
+
.from('avatars')
|
|
318
|
+
.remove(['user-id/avatar.png']);
|
|
319
|
+
|
|
320
|
+
// List files
|
|
321
|
+
const { data, error } = await supabase.storage
|
|
322
|
+
.from('avatars')
|
|
323
|
+
.list('user-id/');
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### File Organization
|
|
327
|
+
|
|
328
|
+
- **Private files**: Use user ID prefix: `'{userId}/filename'`
|
|
329
|
+
- **Public files**: Use simple naming scheme
|
|
330
|
+
|
|
331
|
+
## Edge Functions
|
|
332
|
+
|
|
333
|
+
Use Edge Functions for server-side logic, background tasks, webhooks, or API integrations.
|
|
334
|
+
|
|
335
|
+
### Creating Edge Functions
|
|
336
|
+
|
|
337
|
+
Create functions in `/supabase/functions/<function-name>/index.ts`
|
|
338
|
+
|
|
339
|
+
### Runtime Environment
|
|
340
|
+
|
|
341
|
+
- **Runtime**: Deno with TypeScript support
|
|
342
|
+
- **Import Supabase**: `import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'`
|
|
343
|
+
- **Environment Variables**: `Deno.env.get('VARIABLE_NAME')`
|
|
344
|
+
|
|
345
|
+
### Edge Function Example
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
|
|
349
|
+
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
|
350
|
+
|
|
351
|
+
serve(async (req) => {
|
|
352
|
+
try {
|
|
353
|
+
const { name } = await req.json();
|
|
354
|
+
|
|
355
|
+
// Create Supabase client
|
|
356
|
+
const supabaseClient = createClient(
|
|
357
|
+
Deno.env.get('SUPABASE_URL') ?? '',
|
|
358
|
+
Deno.env.get('SUPABASE_ANON_KEY') ?? ''
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
// Execute business logic
|
|
362
|
+
const { data, error } = await supabaseClient
|
|
363
|
+
.from('users')
|
|
364
|
+
.select('*')
|
|
365
|
+
.eq('name', name);
|
|
366
|
+
|
|
367
|
+
if (error) throw error;
|
|
368
|
+
|
|
369
|
+
return new Response(
|
|
370
|
+
JSON.stringify({ data }),
|
|
371
|
+
{
|
|
372
|
+
headers: { 'Content-Type': 'application/json' },
|
|
373
|
+
status: 200
|
|
374
|
+
}
|
|
375
|
+
);
|
|
376
|
+
} catch (error) {
|
|
377
|
+
return new Response(
|
|
378
|
+
JSON.stringify({ error: error.message }),
|
|
379
|
+
{
|
|
380
|
+
headers: { 'Content-Type': 'application/json' },
|
|
381
|
+
status: 400
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Invoking from Client
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
const { data, error } = await supabase.functions.invoke('function-name', {
|
|
392
|
+
body: { name: 'John' }
|
|
393
|
+
});
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Common Use Cases
|
|
397
|
+
|
|
398
|
+
- Webhook handlers
|
|
399
|
+
- Scheduled jobs
|
|
400
|
+
- Third-party API calls
|
|
401
|
+
- Complex business logic
|
|
402
|
+
- Payment processing
|
|
403
|
+
- Email sending
|
|
404
|
+
|
|
405
|
+
## Security
|
|
406
|
+
|
|
407
|
+
### Row Level Security (RLS)
|
|
408
|
+
|
|
409
|
+
**Required Security Practices**:
|
|
410
|
+
- ✅ Enable RLS for every new table
|
|
411
|
+
- ✅ Create policies based on user authentication
|
|
412
|
+
- ✅ One migration per logical change
|
|
413
|
+
- ✅ Use descriptive policy names
|
|
414
|
+
|
|
415
|
+
### RLS Policy Examples
|
|
416
|
+
|
|
417
|
+
```sql
|
|
418
|
+
-- Enable RLS
|
|
419
|
+
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
|
|
420
|
+
|
|
421
|
+
-- SELECT policy: Everyone can view
|
|
422
|
+
CREATE POLICY "Posts are viewable by everyone"
|
|
423
|
+
ON posts FOR SELECT
|
|
424
|
+
USING (true);
|
|
425
|
+
|
|
426
|
+
-- INSERT policy: Authenticated users can create
|
|
427
|
+
CREATE POLICY "Authenticated users can create posts"
|
|
428
|
+
ON posts FOR INSERT
|
|
429
|
+
TO authenticated
|
|
430
|
+
WITH CHECK (auth.uid() = user_id);
|
|
431
|
+
|
|
432
|
+
-- UPDATE policy: Users can update own posts
|
|
433
|
+
CREATE POLICY "Users can update own posts"
|
|
434
|
+
ON posts FOR UPDATE
|
|
435
|
+
TO authenticated
|
|
436
|
+
USING (auth.uid() = user_id)
|
|
437
|
+
WITH CHECK (auth.uid() = user_id);
|
|
438
|
+
|
|
439
|
+
-- DELETE policy: Users can delete own posts
|
|
440
|
+
CREATE POLICY "Users can delete own posts"
|
|
441
|
+
ON posts FOR DELETE
|
|
442
|
+
TO authenticated
|
|
443
|
+
USING (auth.uid() = user_id);
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Performance Optimization
|
|
447
|
+
|
|
448
|
+
- Add indexes for frequently queried columns
|
|
449
|
+
- Use `EXPLAIN ANALYZE` to analyze query performance
|
|
450
|
+
- Consider materialized views for complex queries
|
|
451
|
+
|
|
452
|
+
### Index Examples
|
|
453
|
+
|
|
454
|
+
```sql
|
|
455
|
+
-- Add indexes for common query patterns
|
|
456
|
+
CREATE INDEX idx_posts_user_id ON posts(user_id);
|
|
457
|
+
CREATE INDEX idx_posts_created_at ON posts(created_at DESC);
|
|
458
|
+
CREATE INDEX idx_posts_status ON posts(status) WHERE status = 'published';
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Best Practices
|
|
462
|
+
|
|
463
|
+
1. **Data Integrity**: Never risk data loss
|
|
464
|
+
2. **Security First**: Always enable RLS and add policies
|
|
465
|
+
3. **Migration-Driven**: All database changes via migration files
|
|
466
|
+
4. **Type Safety**: Use TypeScript for database types
|
|
467
|
+
5. **Environment Variables**: Store sensitive info in `.env`
|
|
468
|
+
6. **Error Handling**: Always check `error` objects
|
|
469
|
+
7. **Performance**: Add indexes for common queries
|
|
470
|
+
8. **Documentation**: Include clear comments in migrations
|
|
471
|
+
|
|
472
|
+
## Common Patterns
|
|
473
|
+
|
|
474
|
+
### Database Relationships
|
|
475
|
+
|
|
476
|
+
Use foreign key constraints with `ON DELETE CASCADE` or `ON DELETE SET NULL`:
|
|
477
|
+
|
|
478
|
+
```sql
|
|
479
|
+
CREATE TABLE posts (
|
|
480
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
481
|
+
user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
482
|
+
title text NOT NULL,
|
|
483
|
+
content text
|
|
484
|
+
);
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Real-time Subscriptions
|
|
488
|
+
|
|
489
|
+
Use Supabase Realtime for live data updates:
|
|
490
|
+
|
|
491
|
+
```typescript
|
|
492
|
+
const subscription = supabase
|
|
493
|
+
.channel('posts')
|
|
494
|
+
.on('postgres_changes',
|
|
495
|
+
{ event: '*', schema: 'public', table: 'posts' },
|
|
496
|
+
(payload) => {
|
|
497
|
+
console.log('Change received!', payload);
|
|
498
|
+
}
|
|
499
|
+
)
|
|
500
|
+
.subscribe();
|
|
501
|
+
|
|
502
|
+
// Unsubscribe
|
|
503
|
+
subscription.unsubscribe();
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### File Upload Size Limits
|
|
507
|
+
|
|
508
|
+
Configure file size limits in bucket settings or validate on client:
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
|
512
|
+
|
|
513
|
+
if (file.size > MAX_FILE_SIZE) {
|
|
514
|
+
throw new Error('File too large');
|
|
515
|
+
}
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
## Debugging
|
|
519
|
+
|
|
520
|
+
**Troubleshooting Checklist**:
|
|
521
|
+
1. **Check RLS**: Verify RLS policies are correctly set
|
|
522
|
+
2. **View Logs**: Check logs in Supabase Dashboard
|
|
523
|
+
3. **Test Queries**: Use SQL Editor to test queries
|
|
524
|
+
4. **Verify Permissions**: Confirm user has correct permissions
|
|
525
|
+
5. **Environment Variables**: Validate all env vars are set correctly
|
|
526
|
+
|
|
527
|
+
## Additional Resources
|
|
528
|
+
|
|
529
|
+
For more detailed guidance, refer to:
|
|
530
|
+
- [Supabase Documentation](https://supabase.com/docs)
|
|
531
|
+
- [Supabase Auth Guide](https://supabase.com/docs/guides/auth)
|
|
532
|
+
- [Supabase Storage Guide](https://supabase.com/docs/guides/storage)
|
|
533
|
+
- [Supabase Edge Functions](https://supabase.com/docs/guides/functions)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
## Supabase Project Structure
|
|
538
|
+
|
|
539
|
+
```
|
|
540
|
+
project-root/
|
|
541
|
+
├── supabase/
|
|
542
|
+
│ ├── functions/
|
|
543
|
+
│ │ ├── <function-name-1>/
|
|
544
|
+
│ │ │ └── index.ts # AI Feature 1
|
|
545
|
+
│ │ ├── <function-name-2>/
|
|
546
|
+
│ │ │ └── index.ts # AI Feature 2
|
|
547
|
+
│ │ └── <function-name-3>/
|
|
548
|
+
│ │ └── index.ts # AI Feature 3
|
|
549
|
+
│ ├── .env.local # Functions environment variables
|
|
550
|
+
│ └── config.toml # Supabase configuration
|
|
551
|
+
├── src/
|
|
552
|
+
│ ├── lib/
|
|
553
|
+
│ │ └── supabase.ts # Supabase Client configuration
|
|
554
|
+
│ └── ...
|
|
555
|
+
└── .env # Frontend environment variables (VITE_SUPABASE_URL, etc.)
|
|
556
|
+
```
|