needware-cli 1.5.17 → 1.5.19

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.
@@ -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
+ ```