create-claude-webapp 1.0.0 → 1.0.2

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.
Files changed (79) hide show
  1. package/.claude/agents/acceptance-test-generator.md +256 -0
  2. package/.claude/agents/auth-flow-designer.md +93 -0
  3. package/.claude/agents/code-reviewer.md +193 -0
  4. package/.claude/agents/code-verifier.md +194 -0
  5. package/.claude/agents/deployment-executor.md +90 -0
  6. package/.claude/agents/design-sync.md +226 -0
  7. package/.claude/agents/document-reviewer.md +304 -0
  8. package/.claude/agents/environment-validator.md +100 -0
  9. package/.claude/agents/integration-test-reviewer.md +196 -0
  10. package/.claude/agents/investigator.md +162 -0
  11. package/.claude/agents/prd-creator.md +220 -0
  12. package/.claude/agents/quality-fixer-frontend.md +323 -0
  13. package/.claude/agents/quality-fixer.md +280 -0
  14. package/.claude/agents/requirement-analyzer.md +149 -0
  15. package/.claude/agents/rls-policy-designer.md +86 -0
  16. package/.claude/agents/rule-advisor.md +123 -0
  17. package/.claude/agents/scope-discoverer.md +231 -0
  18. package/.claude/agents/solver.md +173 -0
  19. package/.claude/agents/supabase-migration-generator.md +85 -0
  20. package/.claude/agents/task-decomposer.md +246 -0
  21. package/.claude/agents/task-executor-frontend.md +264 -0
  22. package/.claude/agents/task-executor.md +261 -0
  23. package/.claude/agents/technical-designer-frontend.md +444 -0
  24. package/.claude/agents/technical-designer.md +370 -0
  25. package/.claude/agents/verifier.md +193 -0
  26. package/.claude/agents/work-planner.md +211 -0
  27. package/.claude/commands/add-integration-tests.md +116 -0
  28. package/.claude/commands/build.md +77 -0
  29. package/.claude/commands/db-migrate.md +96 -0
  30. package/.claude/commands/deploy.md +95 -0
  31. package/.claude/commands/design.md +75 -0
  32. package/.claude/commands/diagnose.md +202 -0
  33. package/.claude/commands/front-build.md +116 -0
  34. package/.claude/commands/front-design.md +61 -0
  35. package/.claude/commands/front-plan.md +53 -0
  36. package/.claude/commands/front-reverse-design.md +183 -0
  37. package/.claude/commands/front-review.md +89 -0
  38. package/.claude/commands/implement.md +80 -0
  39. package/.claude/commands/local-dev.md +94 -0
  40. package/.claude/commands/plan.md +61 -0
  41. package/.claude/commands/project-inject.md +76 -0
  42. package/.claude/commands/refine-skill.md +207 -0
  43. package/.claude/commands/reverse-engineer.md +301 -0
  44. package/.claude/commands/review.md +88 -0
  45. package/.claude/commands/setup-auth.md +68 -0
  46. package/.claude/commands/setup-supabase.md +66 -0
  47. package/.claude/commands/setup-vercel.md +71 -0
  48. package/.claude/commands/sync-skills.md +116 -0
  49. package/.claude/commands/task.md +13 -0
  50. package/.claude/skills/coding-standards/SKILL.md +246 -0
  51. package/.claude/skills/documentation-criteria/SKILL.md +184 -0
  52. package/.claude/skills/documentation-criteria/references/adr-template.md +64 -0
  53. package/.claude/skills/documentation-criteria/references/design-template.md +263 -0
  54. package/.claude/skills/documentation-criteria/references/plan-template.md +130 -0
  55. package/.claude/skills/documentation-criteria/references/prd-template.md +109 -0
  56. package/.claude/skills/documentation-criteria/references/task-template.md +38 -0
  57. package/.claude/skills/frontend/technical-spec/SKILL.md +147 -0
  58. package/.claude/skills/frontend/typescript-rules/SKILL.md +136 -0
  59. package/.claude/skills/frontend/typescript-testing/SKILL.md +129 -0
  60. package/.claude/skills/fullstack-integration/SKILL.md +466 -0
  61. package/.claude/skills/implementation-approach/SKILL.md +141 -0
  62. package/.claude/skills/integration-e2e-testing/SKILL.md +146 -0
  63. package/.claude/skills/interview/SKILL.md +345 -0
  64. package/.claude/skills/project-context/SKILL.md +53 -0
  65. package/.claude/skills/stack-auth/SKILL.md +519 -0
  66. package/.claude/skills/subagents-orchestration-guide/SKILL.md +218 -0
  67. package/.claude/skills/supabase/SKILL.md +289 -0
  68. package/.claude/skills/supabase-edge-functions/SKILL.md +386 -0
  69. package/.claude/skills/supabase-local/SKILL.md +328 -0
  70. package/.claude/skills/supabase-testing/SKILL.md +513 -0
  71. package/.claude/skills/task-analyzer/SKILL.md +131 -0
  72. package/.claude/skills/task-analyzer/references/skills-index.yaml +375 -0
  73. package/.claude/skills/technical-spec/SKILL.md +86 -0
  74. package/.claude/skills/typescript-rules/SKILL.md +121 -0
  75. package/.claude/skills/typescript-testing/SKILL.md +155 -0
  76. package/.claude/skills/vercel-deployment/SKILL.md +355 -0
  77. package/.claude/skills/vercel-edge/SKILL.md +407 -0
  78. package/README.md +4 -17
  79. package/package.json +1 -1
@@ -0,0 +1,386 @@
1
+ ---
2
+ name: supabase-edge-functions
3
+ description: Supabase Edge Functions with Deno runtime. Use when creating serverless functions, webhooks, or API endpoints that run on Supabase Edge.
4
+ ---
5
+
6
+ # Supabase Edge Functions
7
+
8
+ ## Function Structure
9
+
10
+ ### Directory Layout
11
+ ```
12
+ supabase/
13
+ functions/
14
+ _shared/ # Shared code between functions
15
+ cors.ts
16
+ supabase.ts
17
+ function-name/
18
+ index.ts # Entry point (required)
19
+ another-function/
20
+ index.ts
21
+ ```
22
+
23
+ ### Basic Function Template
24
+ ```typescript
25
+ // supabase/functions/hello-world/index.ts
26
+ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
27
+
28
+ serve(async (req: Request) => {
29
+ const { name } = await req.json()
30
+
31
+ return new Response(
32
+ JSON.stringify({ message: `Hello ${name}!` }),
33
+ {
34
+ headers: { 'Content-Type': 'application/json' },
35
+ }
36
+ )
37
+ })
38
+ ```
39
+
40
+ ## Type Safety in Deno
41
+
42
+ ### Import Maps
43
+ ```json
44
+ // supabase/functions/import_map.json
45
+ {
46
+ "imports": {
47
+ "@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2",
48
+ "shared/": "../_shared/"
49
+ }
50
+ }
51
+ ```
52
+
53
+ ### Type Definitions
54
+ ```typescript
55
+ // supabase/functions/_shared/types.ts
56
+ export interface ApiResponse<T> {
57
+ data: T | null
58
+ error: string | null
59
+ }
60
+
61
+ export interface UserPayload {
62
+ userId: string
63
+ email: string
64
+ action: string
65
+ }
66
+ ```
67
+
68
+ ### Using Types in Functions
69
+ ```typescript
70
+ // supabase/functions/process-user/index.ts
71
+ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
72
+ import type { UserPayload, ApiResponse } from 'shared/types.ts'
73
+
74
+ serve(async (req: Request): Promise<Response> => {
75
+ try {
76
+ const payload: UserPayload = await req.json()
77
+
78
+ // Process...
79
+
80
+ const response: ApiResponse<{ processed: boolean }> = {
81
+ data: { processed: true },
82
+ error: null,
83
+ }
84
+
85
+ return new Response(JSON.stringify(response), {
86
+ headers: { 'Content-Type': 'application/json' },
87
+ })
88
+ } catch (error) {
89
+ const response: ApiResponse<null> = {
90
+ data: null,
91
+ error: error.message,
92
+ }
93
+
94
+ return new Response(JSON.stringify(response), {
95
+ status: 400,
96
+ headers: { 'Content-Type': 'application/json' },
97
+ })
98
+ }
99
+ })
100
+ ```
101
+
102
+ ## Authentication in Edge Functions
103
+
104
+ ### Extracting User from JWT
105
+ ```typescript
106
+ // supabase/functions/_shared/supabase.ts
107
+ import { createClient } from '@supabase/supabase-js'
108
+
109
+ export const getSupabaseClient = (authHeader: string | null) => {
110
+ return createClient(
111
+ Deno.env.get('SUPABASE_URL')!,
112
+ Deno.env.get('SUPABASE_ANON_KEY')!,
113
+ {
114
+ global: {
115
+ headers: authHeader ? { Authorization: authHeader } : {},
116
+ },
117
+ }
118
+ )
119
+ }
120
+
121
+ export const getUser = async (req: Request) => {
122
+ const authHeader = req.headers.get('Authorization')
123
+
124
+ if (!authHeader) {
125
+ return { user: null, error: 'No authorization header' }
126
+ }
127
+
128
+ const supabase = getSupabaseClient(authHeader)
129
+ const { data: { user }, error } = await supabase.auth.getUser()
130
+
131
+ return { user, error: error?.message ?? null }
132
+ }
133
+ ```
134
+
135
+ ### Protected Function Example
136
+ ```typescript
137
+ // supabase/functions/protected/index.ts
138
+ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
139
+ import { getUser, getSupabaseClient } from 'shared/supabase.ts'
140
+ import { corsHeaders } from 'shared/cors.ts'
141
+
142
+ serve(async (req: Request) => {
143
+ // Handle CORS preflight
144
+ if (req.method === 'OPTIONS') {
145
+ return new Response('ok', { headers: corsHeaders })
146
+ }
147
+
148
+ const { user, error } = await getUser(req)
149
+
150
+ if (error || !user) {
151
+ return new Response(
152
+ JSON.stringify({ error: 'Unauthorized' }),
153
+ { status: 401, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
154
+ )
155
+ }
156
+
157
+ // User is authenticated, proceed with logic
158
+ const supabase = getSupabaseClient(req.headers.get('Authorization'))
159
+
160
+ const { data, error: dbError } = await supabase
161
+ .from('user_data')
162
+ .select('*')
163
+ .eq('user_id', user.id)
164
+
165
+ return new Response(
166
+ JSON.stringify({ data }),
167
+ { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
168
+ )
169
+ })
170
+ ```
171
+
172
+ ### Service Role Access
173
+ ```typescript
174
+ // For admin operations, use service role key
175
+ import { createClient } from '@supabase/supabase-js'
176
+
177
+ const supabaseAdmin = createClient(
178
+ Deno.env.get('SUPABASE_URL')!,
179
+ Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
180
+ )
181
+
182
+ // Bypasses RLS
183
+ const { data } = await supabaseAdmin.from('users').select('*')
184
+ ```
185
+
186
+ ## CORS Handling
187
+
188
+ ### Shared CORS Configuration
189
+ ```typescript
190
+ // supabase/functions/_shared/cors.ts
191
+ export const corsHeaders = {
192
+ 'Access-Control-Allow-Origin': '*',
193
+ 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
194
+ }
195
+
196
+ export const handleCors = (req: Request): Response | null => {
197
+ if (req.method === 'OPTIONS') {
198
+ return new Response('ok', { headers: corsHeaders })
199
+ }
200
+ return null
201
+ }
202
+ ```
203
+
204
+ ### Using CORS in Functions
205
+ ```typescript
206
+ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
207
+ import { corsHeaders, handleCors } from 'shared/cors.ts'
208
+
209
+ serve(async (req: Request) => {
210
+ const corsResponse = handleCors(req)
211
+ if (corsResponse) return corsResponse
212
+
213
+ // Function logic...
214
+
215
+ return new Response(
216
+ JSON.stringify({ success: true }),
217
+ { headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
218
+ )
219
+ })
220
+ ```
221
+
222
+ ## Local Development
223
+
224
+ ### Running Functions Locally
225
+ ```bash
226
+ # Start all functions
227
+ supabase functions serve
228
+
229
+ # Start specific function
230
+ supabase functions serve hello-world
231
+
232
+ # With environment variables
233
+ supabase functions serve --env-file .env.local
234
+ ```
235
+
236
+ ### Testing Locally
237
+ ```bash
238
+ # Invoke function
239
+ curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/hello-world' \
240
+ --header 'Authorization: Bearer YOUR_ANON_KEY' \
241
+ --header 'Content-Type: application/json' \
242
+ --data '{"name": "World"}'
243
+ ```
244
+
245
+ ## Deployment
246
+
247
+ ### Deploy Single Function
248
+ ```bash
249
+ supabase functions deploy hello-world
250
+ ```
251
+
252
+ ### Deploy All Functions
253
+ ```bash
254
+ supabase functions deploy
255
+ ```
256
+
257
+ ### Setting Secrets
258
+ ```bash
259
+ # Set secret
260
+ supabase secrets set MY_SECRET=value
261
+
262
+ # List secrets
263
+ supabase secrets list
264
+
265
+ # Unset secret
266
+ supabase secrets unset MY_SECRET
267
+ ```
268
+
269
+ ## Webhooks Pattern
270
+
271
+ ### Database Webhook Handler
272
+ ```typescript
273
+ // supabase/functions/on-user-created/index.ts
274
+ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
275
+
276
+ interface WebhookPayload {
277
+ type: 'INSERT' | 'UPDATE' | 'DELETE'
278
+ table: string
279
+ record: Record<string, unknown>
280
+ schema: string
281
+ old_record: Record<string, unknown> | null
282
+ }
283
+
284
+ serve(async (req: Request) => {
285
+ const payload: WebhookPayload = await req.json()
286
+
287
+ if (payload.type === 'INSERT' && payload.table === 'users') {
288
+ // Send welcome email, create related records, etc.
289
+ console.log('New user created:', payload.record)
290
+ }
291
+
292
+ return new Response(JSON.stringify({ received: true }), {
293
+ headers: { 'Content-Type': 'application/json' },
294
+ })
295
+ })
296
+ ```
297
+
298
+ ### Setting Up Database Webhook
299
+ ```sql
300
+ -- In Supabase Studio or migration
301
+ CREATE OR REPLACE FUNCTION notify_user_created()
302
+ RETURNS trigger AS $$
303
+ BEGIN
304
+ PERFORM net.http_post(
305
+ url := 'https://YOUR_PROJECT.supabase.co/functions/v1/on-user-created',
306
+ headers := '{"Authorization": "Bearer ' || current_setting('app.service_role_key') || '"}'::jsonb,
307
+ body := jsonb_build_object(
308
+ 'type', TG_OP,
309
+ 'table', TG_TABLE_NAME,
310
+ 'record', row_to_json(NEW),
311
+ 'old_record', row_to_json(OLD)
312
+ )
313
+ );
314
+ RETURN NEW;
315
+ END;
316
+ $$ LANGUAGE plpgsql;
317
+
318
+ CREATE TRIGGER on_user_created
319
+ AFTER INSERT ON users
320
+ FOR EACH ROW
321
+ EXECUTE FUNCTION notify_user_created();
322
+ ```
323
+
324
+ ## Environment Variables
325
+
326
+ ### Available by Default
327
+ | Variable | Description |
328
+ |----------|-------------|
329
+ | `SUPABASE_URL` | Project URL |
330
+ | `SUPABASE_ANON_KEY` | Anon/public key |
331
+ | `SUPABASE_SERVICE_ROLE_KEY` | Service role key |
332
+ | `SUPABASE_DB_URL` | Direct database connection |
333
+
334
+ ### Accessing Environment Variables
335
+ ```typescript
336
+ const supabaseUrl = Deno.env.get('SUPABASE_URL')!
337
+ const customSecret = Deno.env.get('MY_CUSTOM_SECRET')!
338
+ ```
339
+
340
+ ## Error Handling Best Practices
341
+
342
+ ```typescript
343
+ serve(async (req: Request) => {
344
+ try {
345
+ // Validate request method
346
+ if (req.method !== 'POST') {
347
+ return new Response(
348
+ JSON.stringify({ error: 'Method not allowed' }),
349
+ { status: 405, headers: { 'Content-Type': 'application/json' } }
350
+ )
351
+ }
352
+
353
+ // Validate content type
354
+ const contentType = req.headers.get('content-type')
355
+ if (!contentType?.includes('application/json')) {
356
+ return new Response(
357
+ JSON.stringify({ error: 'Content-Type must be application/json' }),
358
+ { status: 400, headers: { 'Content-Type': 'application/json' } }
359
+ )
360
+ }
361
+
362
+ // Parse and validate body
363
+ const body = await req.json()
364
+ if (!body.requiredField) {
365
+ return new Response(
366
+ JSON.stringify({ error: 'requiredField is required' }),
367
+ { status: 400, headers: { 'Content-Type': 'application/json' } }
368
+ )
369
+ }
370
+
371
+ // Process...
372
+ return new Response(
373
+ JSON.stringify({ success: true }),
374
+ { headers: { 'Content-Type': 'application/json' } }
375
+ )
376
+
377
+ } catch (error) {
378
+ console.error('Function error:', error)
379
+
380
+ return new Response(
381
+ JSON.stringify({ error: 'Internal server error' }),
382
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
383
+ )
384
+ }
385
+ })
386
+ ```
@@ -0,0 +1,328 @@
1
+ ---
2
+ name: supabase-local
3
+ description: Local Supabase development with CLI, migrations, and seeding. Use when setting up local development environment, running migrations, or managing local Supabase instance.
4
+ ---
5
+
6
+ # Supabase Local Development
7
+
8
+ ## CLI Commands Reference
9
+
10
+ ### Essential Commands
11
+
12
+ | Command | Purpose |
13
+ |---------|---------|
14
+ | `supabase start` | Start local Supabase stack |
15
+ | `supabase stop` | Stop local Supabase stack |
16
+ | `supabase status` | Show running services and URLs |
17
+ | `supabase db reset` | Reset database and apply migrations |
18
+ | `supabase db diff` | Generate migration from schema changes |
19
+ | `supabase db push` | Push migrations to remote |
20
+
21
+ ### Starting Local Development
22
+ ```bash
23
+ # Initialize Supabase in project (first time)
24
+ supabase init
25
+
26
+ # Start local stack
27
+ supabase start
28
+
29
+ # Output includes local URLs and keys:
30
+ # API URL: http://127.0.0.1:54321
31
+ # GraphQL URL: http://127.0.0.1:54321/graphql/v1
32
+ # DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
33
+ # Studio URL: http://127.0.0.1:54323
34
+ # Inbucket URL: http://127.0.0.1:54324
35
+ # anon key: eyJ...
36
+ # service_role key: eyJ...
37
+ ```
38
+
39
+ ### Stopping and Resetting
40
+ ```bash
41
+ # Stop (preserves data)
42
+ supabase stop
43
+
44
+ # Stop and reset all data
45
+ supabase stop --no-backup
46
+
47
+ # Reset database (reapply all migrations + seed)
48
+ supabase db reset
49
+ ```
50
+
51
+ ## Local Configuration
52
+
53
+ ### config.toml Structure
54
+ ```toml
55
+ # supabase/config.toml
56
+
57
+ [api]
58
+ enabled = true
59
+ port = 54321
60
+ schemas = ["public", "graphql_public"]
61
+ extra_search_path = ["public", "extensions"]
62
+ max_rows = 1000
63
+
64
+ [db]
65
+ port = 54322
66
+ shadow_port = 54320
67
+ major_version = 15
68
+
69
+ [studio]
70
+ enabled = true
71
+ port = 54323
72
+ api_url = "http://127.0.0.1"
73
+
74
+ [inbucket]
75
+ enabled = true
76
+ port = 54324
77
+ smtp_port = 54325
78
+ pop3_port = 54326
79
+
80
+ [auth]
81
+ enabled = true
82
+ site_url = "http://127.0.0.1:3000"
83
+ additional_redirect_urls = ["https://127.0.0.1:3000"]
84
+ jwt_expiry = 3600
85
+ enable_signup = true
86
+ enable_anonymous_sign_ins = false
87
+
88
+ [auth.email]
89
+ enable_signup = true
90
+ double_confirm_changes = true
91
+ enable_confirmations = false
92
+
93
+ [auth.sms]
94
+ enable_signup = false
95
+ enable_confirmations = false
96
+
97
+ [storage]
98
+ enabled = true
99
+ file_size_limit = "50MiB"
100
+
101
+ [edge_runtime]
102
+ enabled = true
103
+ policy = "per_worker"
104
+ inspector_port = 8083
105
+
106
+ [analytics]
107
+ enabled = false
108
+ port = 54327
109
+ vector_port = 54328
110
+ ```
111
+
112
+ ### Port Allocation Summary
113
+
114
+ | Service | Default Port |
115
+ |---------|-------------|
116
+ | API | 54321 |
117
+ | Database | 54322 |
118
+ | Studio | 54323 |
119
+ | Inbucket | 54324 |
120
+ | SMTP | 54325 |
121
+ | POP3 | 54326 |
122
+ | Analytics | 54327 |
123
+
124
+ ## Migration Workflow
125
+
126
+ ### Creating Migrations
127
+
128
+ **Option 1: Manual Creation**
129
+ ```bash
130
+ # Create empty migration file
131
+ supabase migration new create_users_table
132
+
133
+ # Edit: supabase/migrations/TIMESTAMP_create_users_table.sql
134
+ ```
135
+
136
+ **Option 2: Generate from Schema Changes**
137
+ ```bash
138
+ # Make changes in Studio, then:
139
+ supabase db diff -f add_avatar_to_users
140
+
141
+ # Creates: supabase/migrations/TIMESTAMP_add_avatar_to_users.sql
142
+ ```
143
+
144
+ **Option 3: Pull from Remote**
145
+ ```bash
146
+ # Pull schema from remote project
147
+ supabase db pull
148
+
149
+ # Creates migration files from remote schema
150
+ ```
151
+
152
+ ### Applying Migrations
153
+ ```bash
154
+ # Apply to local
155
+ supabase db reset # Resets and applies all migrations
156
+
157
+ # Push to remote
158
+ supabase db push
159
+ ```
160
+
161
+ ### Migration File Example
162
+ ```sql
163
+ -- supabase/migrations/20240115120000_create_users_table.sql
164
+
165
+ -- Create users table
166
+ CREATE TABLE public.users (
167
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
168
+ email TEXT UNIQUE NOT NULL,
169
+ name TEXT,
170
+ avatar_url TEXT,
171
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
172
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
173
+ );
174
+
175
+ -- Enable RLS
176
+ ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
177
+
178
+ -- Create policies
179
+ CREATE POLICY "Users can view own profile"
180
+ ON public.users FOR SELECT
181
+ TO authenticated
182
+ USING (auth.uid() = id);
183
+
184
+ CREATE POLICY "Users can update own profile"
185
+ ON public.users FOR UPDATE
186
+ TO authenticated
187
+ USING (auth.uid() = id)
188
+ WITH CHECK (auth.uid() = id);
189
+
190
+ -- Create updated_at trigger
191
+ CREATE OR REPLACE FUNCTION update_updated_at()
192
+ RETURNS TRIGGER AS $$
193
+ BEGIN
194
+ NEW.updated_at = now();
195
+ RETURN NEW;
196
+ END;
197
+ $$ LANGUAGE plpgsql;
198
+
199
+ CREATE TRIGGER update_users_updated_at
200
+ BEFORE UPDATE ON public.users
201
+ FOR EACH ROW
202
+ EXECUTE FUNCTION update_updated_at();
203
+ ```
204
+
205
+ ## Seeding Data
206
+
207
+ ### Seed File Location
208
+ ```
209
+ supabase/seed.sql
210
+ ```
211
+
212
+ ### Seed File Example
213
+ ```sql
214
+ -- supabase/seed.sql
215
+
216
+ -- Insert test users (for development only)
217
+ INSERT INTO auth.users (id, email, encrypted_password, email_confirmed_at)
218
+ VALUES
219
+ ('d0d8c4c0-0000-0000-0000-000000000001', 'alice@example.com', crypt('password123', gen_salt('bf')), now()),
220
+ ('d0d8c4c0-0000-0000-0000-000000000002', 'bob@example.com', crypt('password123', gen_salt('bf')), now());
221
+
222
+ -- Insert corresponding profiles
223
+ INSERT INTO public.users (id, email, name)
224
+ VALUES
225
+ ('d0d8c4c0-0000-0000-0000-000000000001', 'alice@example.com', 'Alice'),
226
+ ('d0d8c4c0-0000-0000-0000-000000000002', 'bob@example.com', 'Bob');
227
+
228
+ -- Insert sample data
229
+ INSERT INTO public.posts (id, user_id, title, content, published)
230
+ VALUES
231
+ (gen_random_uuid(), 'd0d8c4c0-0000-0000-0000-000000000001', 'First Post', 'Hello World!', true),
232
+ (gen_random_uuid(), 'd0d8c4c0-0000-0000-0000-000000000002', 'Another Post', 'Testing...', false);
233
+ ```
234
+
235
+ ### Running Seeds
236
+ ```bash
237
+ # Seeds run automatically on db reset
238
+ supabase db reset
239
+
240
+ # Or manually
241
+ psql -h 127.0.0.1 -p 54322 -U postgres -d postgres -f supabase/seed.sql
242
+ ```
243
+
244
+ ## Local vs Production Parity
245
+
246
+ ### Environment-Specific Configurations
247
+
248
+ | Setting | Local | Production |
249
+ |---------|-------|------------|
250
+ | Email confirmation | Disabled | Enabled |
251
+ | JWT expiry | 3600s (testing) | 3600s+ (security) |
252
+ | Anonymous sign-ins | Disabled | As needed |
253
+ | SMTP | Inbucket (fake) | Real provider |
254
+
255
+ ### Testing Email Locally
256
+ ```bash
257
+ # Emails captured in Inbucket
258
+ # Access: http://127.0.0.1:54324
259
+
260
+ # No real emails sent in local development
261
+ ```
262
+
263
+ ### Environment Variables for Local
264
+ ```env
265
+ # .env.local
266
+ NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
267
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... # From supabase start output
268
+ ```
269
+
270
+ ## Common Local Development Tasks
271
+
272
+ ### Inspect Database
273
+ ```bash
274
+ # Connect to local database
275
+ psql postgresql://postgres:postgres@127.0.0.1:54322/postgres
276
+
277
+ # Or use Studio
278
+ open http://127.0.0.1:54323
279
+ ```
280
+
281
+ ### View Logs
282
+ ```bash
283
+ # All services
284
+ supabase logs
285
+
286
+ # Specific service
287
+ supabase logs --api
288
+ supabase logs --db
289
+ supabase logs --auth
290
+ ```
291
+
292
+ ### Type Generation
293
+ ```bash
294
+ # Generate types from local schema
295
+ supabase gen types typescript --local > src/types/database.types.ts
296
+ ```
297
+
298
+ ## Troubleshooting
299
+
300
+ ### Port Conflicts
301
+ ```bash
302
+ # Check what's using the port
303
+ lsof -i :54321
304
+
305
+ # Use different ports in config.toml
306
+ [api]
307
+ port = 54421
308
+ ```
309
+
310
+ ### Docker Issues
311
+ ```bash
312
+ # Ensure Docker is running
313
+ docker info
314
+
315
+ # Reset Supabase Docker containers
316
+ supabase stop --no-backup
317
+ docker system prune -f
318
+ supabase start
319
+ ```
320
+
321
+ ### Migration Conflicts
322
+ ```bash
323
+ # If migrations are out of sync
324
+ supabase db reset # Local only
325
+
326
+ # For remote, may need manual intervention
327
+ supabase migration repair --status reverted MIGRATION_VERSION
328
+ ```