superkit-mcp-server 1.2.3 → 1.2.4
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/ARCHITECTURE.md +102 -102
- package/README.md +71 -71
- package/SUPERKIT.md +168 -168
- package/agents/code-archaeologist.md +106 -106
- package/agents/coder.md +90 -90
- package/agents/data-engineer.md +28 -28
- package/agents/devops-engineer.md +242 -242
- package/agents/git-manager.md +203 -203
- package/agents/orchestrator.md +420 -420
- package/agents/penetration-tester.md +188 -188
- package/agents/performance-optimizer.md +187 -187
- package/agents/planner.md +270 -270
- package/agents/qa-automation-engineer.md +103 -103
- package/agents/quant-developer.md +32 -32
- package/agents/reviewer.md +100 -100
- package/agents/scout.md +222 -222
- package/agents/tester.md +274 -274
- package/agents/ui-designer.md +208 -208
- package/build/tools/sessionManager.js +79 -10
- package/build/tools/todoTools.js +39 -39
- package/build/tools/validators/__tests__/apiSchema.test.js +23 -23
- package/build/tools/validators/__tests__/convertRules.test.js +5 -5
- package/build/tools/validators/__tests__/frontendDesign.test.js +12 -12
- package/build/tools/validators/__tests__/geoChecker.test.js +19 -19
- package/build/tools/validators/__tests__/mobileAudit.test.js +12 -12
- package/build/tools/validators/__tests__/reactPerformanceChecker.test.js +17 -17
- package/build/tools/validators/__tests__/securityScan.test.js +6 -6
- package/build/tools/validators/__tests__/seoChecker.test.js +16 -16
- package/build/tools/validators/__tests__/typeCoverage.test.js +14 -14
- package/commands/README.md +122 -122
- package/commands/ask.toml +72 -72
- package/commands/brainstorm.toml +119 -119
- package/commands/chat.toml +77 -77
- package/commands/code-preview.toml +37 -37
- package/commands/code.toml +28 -28
- package/commands/content.toml +200 -200
- package/commands/cook.toml +77 -77
- package/commands/copywrite.toml +131 -131
- package/commands/db.toml +192 -192
- package/commands/debug.toml +166 -166
- package/commands/design.toml +158 -158
- package/commands/dev-rules.toml +14 -14
- package/commands/do.toml +117 -117
- package/commands/doc-rules.toml +14 -14
- package/commands/docs.toml +148 -148
- package/commands/fix.toml +440 -440
- package/commands/fullstack.toml +175 -175
- package/commands/git.toml +235 -235
- package/commands/help.toml +84 -84
- package/commands/integrate.toml +127 -127
- package/commands/journal.toml +136 -136
- package/commands/kit-setup.toml +40 -40
- package/commands/mcp.toml +183 -183
- package/commands/orchestration.toml +15 -15
- package/commands/plan.toml +171 -171
- package/commands/pm.toml +148 -148
- package/commands/pr.toml +50 -50
- package/commands/project.toml +32 -32
- package/commands/research.toml +117 -117
- package/commands/review-pr.toml +63 -63
- package/commands/review.toml +190 -190
- package/commands/scout-ext.toml +97 -97
- package/commands/scout.toml +79 -79
- package/commands/screenshot.toml +65 -65
- package/commands/session.toml +102 -102
- package/commands/skill.toml +384 -384
- package/commands/status.toml +22 -22
- package/commands/team.toml +56 -56
- package/commands/test.toml +164 -164
- package/commands/ticket.toml +70 -70
- package/commands/use.toml +106 -106
- package/commands/video.toml +83 -83
- package/commands/watzup.toml +71 -71
- package/commands/workflow.toml +14 -14
- package/package.json +35 -35
- package/skills/meta/README.md +30 -30
- package/skills/meta/api-design/SKILL.md +134 -134
- package/skills/meta/code-review/SKILL.md +44 -44
- package/skills/meta/code-review/checklists/pre-merge.md +25 -25
- package/skills/meta/code-review/workflows/architecture-pass.md +26 -26
- package/skills/meta/code-review/workflows/performance-pass.md +27 -27
- package/skills/meta/code-review/workflows/security-pass.md +29 -29
- package/skills/meta/compound-docs/SKILL.md +133 -133
- package/skills/meta/debug/SKILL.md +40 -40
- package/skills/meta/debug/templates/bug-report.template.md +31 -31
- package/skills/meta/debug/workflows/reproduce-issue.md +20 -20
- package/skills/meta/docker/SKILL.md +126 -126
- package/skills/meta/examples/supabase/SKILL.md +46 -46
- package/skills/meta/examples/supabase/references/best-practices.md +319 -319
- package/skills/meta/examples/supabase/references/common-patterns.md +373 -373
- package/skills/meta/examples/supabase/templates/migration-template.sql +49 -49
- package/skills/meta/examples/supabase/templates/rls-policy-template.sql +77 -77
- package/skills/meta/examples/supabase/workflows/debugging.md +260 -260
- package/skills/meta/examples/supabase/workflows/migration-workflow.md +211 -211
- package/skills/meta/examples/supabase/workflows/rls-policies.md +244 -244
- package/skills/meta/examples/supabase/workflows/schema-design.md +321 -321
- package/skills/meta/file-todos/SKILL.md +88 -88
- package/skills/meta/mobile/SKILL.md +140 -140
- package/skills/meta/nextjs/SKILL.md +101 -101
- package/skills/meta/performance/SKILL.md +130 -130
- package/skills/meta/react-patterns/SKILL.md +83 -83
- package/skills/meta/security/SKILL.md +114 -114
- package/skills/meta/session-resume/SKILL.md +96 -96
- package/skills/meta/tailwind/SKILL.md +139 -139
- package/skills/meta/testing/SKILL.md +43 -43
- package/skills/meta/testing/references/vitest-patterns.md +45 -45
- package/skills/meta/testing/templates/component-test.template.tsx +37 -37
- package/skills/tech/alpha-vantage/SKILL.md +142 -142
- package/skills/tech/alpha-vantage/references/commodities.md +153 -153
- package/skills/tech/alpha-vantage/references/economic-indicators.md +158 -158
- package/skills/tech/alpha-vantage/references/forex-crypto.md +154 -154
- package/skills/tech/alpha-vantage/references/fundamentals.md +223 -223
- package/skills/tech/alpha-vantage/references/intelligence.md +138 -138
- package/skills/tech/alpha-vantage/references/options.md +93 -93
- package/skills/tech/alpha-vantage/references/technical-indicators.md +374 -374
- package/skills/tech/alpha-vantage/references/time-series.md +157 -157
- package/skills/tech/financial-modeling/SKILL.md +18 -18
- package/skills/tech/financial-modeling/skills/3-statements/SKILL.md +368 -368
- package/skills/tech/financial-modeling/skills/3-statements/references/formatting.md +118 -118
- package/skills/tech/financial-modeling/skills/3-statements/references/formulas.md +292 -292
- package/skills/tech/financial-modeling/skills/3-statements/references/sec-filings.md +125 -125
- package/skills/tech/financial-modeling/skills/dcf-model/SKILL.md +1210 -1210
- package/skills/tech/financial-modeling/skills/dcf-model/TROUBLESHOOTING.md +40 -40
- package/skills/tech/financial-modeling/skills/dcf-model/requirements.txt +8 -8
- package/skills/tech/financial-modeling/skills/dcf-model/scripts/validate_dcf.py +292 -292
- package/skills/tech/financial-modeling/skills/lbo-model/SKILL.md +236 -236
- package/skills/tech/financial-modeling/skills/merger-model/SKILL.md +108 -108
- package/skills/workflows/README.md +203 -203
- package/skills/workflows/adr.md +174 -174
- package/skills/workflows/changelog.md +74 -74
- package/skills/workflows/compound.md +323 -323
- package/skills/workflows/compound_health.md +74 -74
- package/skills/workflows/create-agent-skill.md +138 -138
- package/skills/workflows/cycle.md +144 -144
- package/skills/workflows/deploy-docs.md +84 -84
- package/skills/workflows/development-rules.md +42 -42
- package/skills/workflows/doc.md +95 -95
- package/skills/workflows/documentation-management.md +34 -34
- package/skills/workflows/explore.md +146 -146
- package/skills/workflows/generate_command.md +106 -106
- package/skills/workflows/heal-skill.md +97 -97
- package/skills/workflows/housekeeping.md +229 -229
- package/skills/workflows/kit-setup.md +102 -102
- package/skills/workflows/map-codebase.md +78 -78
- package/skills/workflows/orchestration-protocol.md +43 -43
- package/skills/workflows/plan-compound.md +439 -439
- package/skills/workflows/plan_review.md +269 -269
- package/skills/workflows/primary-workflow.md +37 -37
- package/skills/workflows/promote_pattern.md +86 -86
- package/skills/workflows/release-docs.md +82 -82
- package/skills/workflows/report-bug.md +135 -135
- package/skills/workflows/reproduce-bug.md +118 -118
- package/skills/workflows/resolve_pr.md +133 -133
- package/skills/workflows/resolve_todo.md +128 -128
- package/skills/workflows/review-compound.md +376 -376
- package/skills/workflows/skill-review.md +127 -127
- package/skills/workflows/specs.md +257 -257
- package/skills/workflows/triage-sprint.md +102 -102
- package/skills/workflows/triage.md +152 -152
- package/skills/workflows/work.md +399 -399
- package/skills/workflows/xcode-test.md +93 -93
|
@@ -1,319 +1,319 @@
|
|
|
1
|
-
# Supabase Best Practices for [PROJECT_NAME]
|
|
2
|
-
|
|
3
|
-
[PROJECT_NAME]-specific guidelines for working with Supabase.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Migration Conventions
|
|
8
|
-
|
|
9
|
-
### Naming
|
|
10
|
-
|
|
11
|
-
**Format:** `YYYYMMDD_description.sql`
|
|
12
|
-
|
|
13
|
-
**Examples:**
|
|
14
|
-
- `20251203_create_profiles_and_app_role.sql`
|
|
15
|
-
- `20251129_multi_fund_architecture.sql`
|
|
16
|
-
- `20251124_add_lot_performance.sql`
|
|
17
|
-
|
|
18
|
-
**Rules:**
|
|
19
|
-
- Use current date (not future dates)
|
|
20
|
-
- Use underscores, not hyphens
|
|
21
|
-
- Be descriptive but concise
|
|
22
|
-
- Use `create`, `add`, `update`, `remove` prefixes
|
|
23
|
-
|
|
24
|
-
### Header Comments
|
|
25
|
-
|
|
26
|
-
**Always include:**
|
|
27
|
-
```sql
|
|
28
|
-
-- Migration: {Description}
|
|
29
|
-
-- Date: {YYYY-MM-DD}
|
|
30
|
-
-- Purpose: {Why this is needed}
|
|
31
|
-
-- Requirements: {IDs if applicable}
|
|
32
|
-
-- Feature: {feature-name if applicable}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
**Example:**
|
|
36
|
-
```sql
|
|
37
|
-
-- Migration: Create app_role ENUM and profiles table for Identity Fortress
|
|
38
|
-
-- Date: 2025-12-03
|
|
39
|
-
-- Purpose: Establish role-based authentication foundation with JWT custom claims
|
|
40
|
-
-- Requirements: 4.1
|
|
41
|
-
-- Feature: identity-fortress
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Idempotency
|
|
45
|
-
|
|
46
|
-
**All operations must be safe to re-run:**
|
|
47
|
-
|
|
48
|
-
```sql
|
|
49
|
-
-- ✅ GOOD: Safe to re-run
|
|
50
|
-
CREATE TABLE IF NOT EXISTS ...
|
|
51
|
-
CREATE INDEX IF NOT EXISTS ...
|
|
52
|
-
ALTER TABLE ... ADD COLUMN IF NOT EXISTS ...
|
|
53
|
-
|
|
54
|
-
-- ✅ GOOD: Type handling
|
|
55
|
-
DO $$ BEGIN
|
|
56
|
-
CREATE TYPE status_type AS ENUM ('active', 'inactive');
|
|
57
|
-
EXCEPTION
|
|
58
|
-
WHEN duplicate_object THEN null;
|
|
59
|
-
END $$;
|
|
60
|
-
|
|
61
|
-
-- ❌ BAD: Fails on re-run
|
|
62
|
-
CREATE TABLE ...
|
|
63
|
-
CREATE INDEX ...
|
|
64
|
-
CREATE TYPE ...
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Auth Integration
|
|
70
|
-
|
|
71
|
-
### Stateless Client Pattern
|
|
72
|
-
|
|
73
|
-
[PROJECT_NAME] uses a **stateless Supabase client** with SessionStore as single source of truth.
|
|
74
|
-
|
|
75
|
-
**Architecture:**
|
|
76
|
-
```
|
|
77
|
-
SessionStore (localStorage)
|
|
78
|
-
↓ hydrates ↓
|
|
79
|
-
Supabase Client (in-memory only)
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Configuration (`lib/supabaseClient.ts`):**
|
|
83
|
-
```typescript
|
|
84
|
-
export const supabase = createClient(url, anonKey, {
|
|
85
|
-
auth: {
|
|
86
|
-
persistSession: false, // ← SessionStore handles persistence
|
|
87
|
-
autoRefreshToken: true,
|
|
88
|
-
detectSessionInUrl: true,
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Why this pattern?**
|
|
94
|
-
- Single source of truth (no sync issues)
|
|
95
|
-
- Explicit session management
|
|
96
|
-
- No localStorage conflicts
|
|
97
|
-
- Proper session validation
|
|
98
|
-
|
|
99
|
-
**See:** `lib/supabaseClient.ts` for full implementation
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## RLS Security
|
|
104
|
-
|
|
105
|
-
### Enable by Default
|
|
106
|
-
|
|
107
|
-
**On all tables with sensitive data:**
|
|
108
|
-
```sql
|
|
109
|
-
CREATE TABLE table_name (...);
|
|
110
|
-
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Policy Naming
|
|
114
|
-
|
|
115
|
-
**Use descriptive names:**
|
|
116
|
-
```sql
|
|
117
|
-
-- ✅ GOOD
|
|
118
|
-
CREATE POLICY "Users can view own profile" ...
|
|
119
|
-
CREATE POLICY "Fund Managers can view all profiles" ...
|
|
120
|
-
|
|
121
|
-
-- ❌ BAD
|
|
122
|
-
CREATE POLICY "select_policy" ...
|
|
123
|
-
CREATE POLICY "policy1" ...
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
### Always Use WITH CHECK
|
|
127
|
-
|
|
128
|
-
**For UPDATE/INSERT operations:**
|
|
129
|
-
```sql
|
|
130
|
-
-- ✅ GOOD: Enforces ownership on write
|
|
131
|
-
CREATE POLICY "Users can update own profile"
|
|
132
|
-
ON profiles
|
|
133
|
-
FOR UPDATE
|
|
134
|
-
TO authenticated
|
|
135
|
-
USING (id = auth.uid())
|
|
136
|
-
WITH CHECK (id = auth.uid()); -- ← Prevents claiming other data
|
|
137
|
-
|
|
138
|
-
-- ❌ BAD: Allows escalation
|
|
139
|
-
CREATE POLICY "Users can update own profile"
|
|
140
|
-
ON profiles
|
|
141
|
-
FOR UPDATE
|
|
142
|
-
TO authenticated
|
|
143
|
-
USING (id = auth.uid()); -- Missing WITH CHECK
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Performance
|
|
149
|
-
|
|
150
|
-
### Index Foreign Keys
|
|
151
|
-
|
|
152
|
-
**Always create indexes for foreign keys:**
|
|
153
|
-
```sql
|
|
154
|
-
CREATE TABLE transactions (
|
|
155
|
-
id UUID PRIMARY KEY,
|
|
156
|
-
fund_id UUID NOT NULL REFERENCES funds(id),
|
|
157
|
-
investor_id UUID NOT NULL REFERENCES profiles(id)
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
-- Required indexes
|
|
161
|
-
CREATE INDEX idx_transactions_fund_id ON transactions (fund_id);
|
|
162
|
-
CREATE INDEX idx_transactions_investor_id ON transactions (investor_id);
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### Composite Indexes for Common Queries
|
|
166
|
-
|
|
167
|
-
```sql
|
|
168
|
-
-- If querying by fund_id + created_at frequently
|
|
169
|
-
CREATE INDEX idx_transactions_fund_date
|
|
170
|
-
ON transactions (fund_id, created_at DESC);
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Avoid N+1 Queries
|
|
174
|
-
|
|
175
|
-
**Use Supabase joins:**
|
|
176
|
-
```typescript
|
|
177
|
-
// ❌ BAD: N+1 queries
|
|
178
|
-
const funds = await supabase.from('funds').select('*');
|
|
179
|
-
for (const fund of funds.data) {
|
|
180
|
-
const transactions = await supabase
|
|
181
|
-
.from('transactions')
|
|
182
|
-
.select('*')
|
|
183
|
-
.eq('fund_id', fund.id);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// ✅ GOOD: Single query
|
|
187
|
-
const funds = await supabase
|
|
188
|
-
.from('funds')
|
|
189
|
-
.select('*, transactions(*)');
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## Data Types
|
|
195
|
-
|
|
196
|
-
### Standard Types
|
|
197
|
-
|
|
198
|
-
| Use Case | Type | Notes |
|
|
199
|
-
|----------|------|-------|
|
|
200
|
-
| Primary Key | `UUID DEFAULT gen_random_uuid()` | Always UUID |
|
|
201
|
-
| Money | `NUMERIC(12,2)` | Never FLOAT |
|
|
202
|
-
| Timestamps | `TIMESTAMPTZ` | Always with timezone |
|
|
203
|
-
| Booleans | `BOOLEAN` | Not TEXT |
|
|
204
|
-
| Enums | `CREATE TYPE` | Not TEXT strings |
|
|
205
|
-
| IP Address | `INET` | Native support |
|
|
206
|
-
| JSON | `JSONB` | Not TEXT |
|
|
207
|
-
|
|
208
|
-
### Always Add Timestamps
|
|
209
|
-
|
|
210
|
-
```sql
|
|
211
|
-
CREATE TABLE table_name (
|
|
212
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
213
|
-
-- ... columns
|
|
214
|
-
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
|
|
215
|
-
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
-- Trigger for updated_at
|
|
219
|
-
CREATE TRIGGER update_table_updated_at
|
|
220
|
-
BEFORE UPDATE ON table_name
|
|
221
|
-
FOR EACH ROW
|
|
222
|
-
EXECUTE FUNCTION public.update_updated_at_column();
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## Documentation
|
|
228
|
-
|
|
229
|
-
### Comment Everything
|
|
230
|
-
|
|
231
|
-
```sql
|
|
232
|
-
COMMENT ON TABLE profiles IS
|
|
233
|
-
'Extended user profiles with role-based access control';
|
|
234
|
-
|
|
235
|
-
COMMENT ON COLUMN profiles.role IS
|
|
236
|
-
'User role (fund_manager or investor) for authorization';
|
|
237
|
-
|
|
238
|
-
COMMENT ON COLUMN profiles.kyc_status IS
|
|
239
|
-
'KYC verification status (PENDING, APPROVED, REJECTED)';
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Why?**
|
|
243
|
-
- Helps future developers
|
|
244
|
-
- Shows up in database tools
|
|
245
|
-
- Documents business logic
|
|
246
|
-
|
|
247
|
-
---
|
|
248
|
-
|
|
249
|
-
## Common Pitfalls
|
|
250
|
-
|
|
251
|
-
### ❌ Missing ON DELETE Actions
|
|
252
|
-
|
|
253
|
-
```sql
|
|
254
|
-
-- BAD: No ON DELETE action
|
|
255
|
-
user_id UUID REFERENCES users(id)
|
|
256
|
-
|
|
257
|
-
-- GOOD: Explicit cascade or restrict
|
|
258
|
-
user_id UUID REFERENCES users(id) ON DELETE CASCADE
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### ❌ TIMESTAMP Instead of TIMESTAMPTZ
|
|
262
|
-
|
|
263
|
-
```sql
|
|
264
|
-
-- BAD: Loses timezone info
|
|
265
|
-
created_at TIMESTAMP
|
|
266
|
-
|
|
267
|
-
-- GOOD: Preserves timezone
|
|
268
|
-
created_at TIMESTAMPTZ
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### ❌ No RLS on Sensitive Tables
|
|
272
|
-
|
|
273
|
-
```sql
|
|
274
|
-
-- BAD: Anyone can read all data
|
|
275
|
-
CREATE TABLE sensitive_data (...);
|
|
276
|
-
|
|
277
|
-
-- GOOD: RLS enforced
|
|
278
|
-
CREATE TABLE sensitive_data (...);
|
|
279
|
-
ALTER TABLE sensitive_data ENABLE ROW LEVEL SECURITY;
|
|
280
|
-
CREATE POLICY "..." ON sensitive_data ...;
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
### ❌ Using Service Role in Client
|
|
284
|
-
|
|
285
|
-
```typescript
|
|
286
|
-
// ❌ BAD: Bypasses ALL RLS policies
|
|
287
|
-
const supabase = createClient(url, serviceRoleKey);
|
|
288
|
-
|
|
289
|
-
// ✅ GOOD: Enforces RLS
|
|
290
|
-
const supabase = createClient(url, anonKey);
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**Service role only for:**
|
|
294
|
-
- Admin operations
|
|
295
|
-
- Server-side code
|
|
296
|
-
- Database migrations
|
|
297
|
-
|
|
298
|
-
---
|
|
299
|
-
|
|
300
|
-
## Migration Workflow
|
|
301
|
-
|
|
302
|
-
1. **Plan** - Document what needs to change
|
|
303
|
-
2. **Create file** - Use date prefix naming
|
|
304
|
-
3. **Write SQL** - Use idempotent operations
|
|
305
|
-
4. **Add indexes** - For foreign keys and queries
|
|
306
|
-
5. **Enable RLS** - On sensitive tables
|
|
307
|
-
6. **Add comments** - Document tables and columns
|
|
308
|
-
7. **Test locally** - Verify migration works
|
|
309
|
-
8. **Review** - Check against this guide
|
|
310
|
-
9. **Deploy** - Apply to production
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
## References
|
|
315
|
-
|
|
316
|
-
- **Existing migrations:** `backend/migrations/`
|
|
317
|
-
- **Supabase client:** `lib/supabaseClient.ts`
|
|
318
|
-
- **Auth context:** `context/AuthContext.tsx`
|
|
319
|
-
- **Session storage:** `lib/auth/SessionStore.ts`
|
|
1
|
+
# Supabase Best Practices for [PROJECT_NAME]
|
|
2
|
+
|
|
3
|
+
[PROJECT_NAME]-specific guidelines for working with Supabase.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Migration Conventions
|
|
8
|
+
|
|
9
|
+
### Naming
|
|
10
|
+
|
|
11
|
+
**Format:** `YYYYMMDD_description.sql`
|
|
12
|
+
|
|
13
|
+
**Examples:**
|
|
14
|
+
- `20251203_create_profiles_and_app_role.sql`
|
|
15
|
+
- `20251129_multi_fund_architecture.sql`
|
|
16
|
+
- `20251124_add_lot_performance.sql`
|
|
17
|
+
|
|
18
|
+
**Rules:**
|
|
19
|
+
- Use current date (not future dates)
|
|
20
|
+
- Use underscores, not hyphens
|
|
21
|
+
- Be descriptive but concise
|
|
22
|
+
- Use `create`, `add`, `update`, `remove` prefixes
|
|
23
|
+
|
|
24
|
+
### Header Comments
|
|
25
|
+
|
|
26
|
+
**Always include:**
|
|
27
|
+
```sql
|
|
28
|
+
-- Migration: {Description}
|
|
29
|
+
-- Date: {YYYY-MM-DD}
|
|
30
|
+
-- Purpose: {Why this is needed}
|
|
31
|
+
-- Requirements: {IDs if applicable}
|
|
32
|
+
-- Feature: {feature-name if applicable}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Example:**
|
|
36
|
+
```sql
|
|
37
|
+
-- Migration: Create app_role ENUM and profiles table for Identity Fortress
|
|
38
|
+
-- Date: 2025-12-03
|
|
39
|
+
-- Purpose: Establish role-based authentication foundation with JWT custom claims
|
|
40
|
+
-- Requirements: 4.1
|
|
41
|
+
-- Feature: identity-fortress
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Idempotency
|
|
45
|
+
|
|
46
|
+
**All operations must be safe to re-run:**
|
|
47
|
+
|
|
48
|
+
```sql
|
|
49
|
+
-- ✅ GOOD: Safe to re-run
|
|
50
|
+
CREATE TABLE IF NOT EXISTS ...
|
|
51
|
+
CREATE INDEX IF NOT EXISTS ...
|
|
52
|
+
ALTER TABLE ... ADD COLUMN IF NOT EXISTS ...
|
|
53
|
+
|
|
54
|
+
-- ✅ GOOD: Type handling
|
|
55
|
+
DO $$ BEGIN
|
|
56
|
+
CREATE TYPE status_type AS ENUM ('active', 'inactive');
|
|
57
|
+
EXCEPTION
|
|
58
|
+
WHEN duplicate_object THEN null;
|
|
59
|
+
END $$;
|
|
60
|
+
|
|
61
|
+
-- ❌ BAD: Fails on re-run
|
|
62
|
+
CREATE TABLE ...
|
|
63
|
+
CREATE INDEX ...
|
|
64
|
+
CREATE TYPE ...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Auth Integration
|
|
70
|
+
|
|
71
|
+
### Stateless Client Pattern
|
|
72
|
+
|
|
73
|
+
[PROJECT_NAME] uses a **stateless Supabase client** with SessionStore as single source of truth.
|
|
74
|
+
|
|
75
|
+
**Architecture:**
|
|
76
|
+
```
|
|
77
|
+
SessionStore (localStorage)
|
|
78
|
+
↓ hydrates ↓
|
|
79
|
+
Supabase Client (in-memory only)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Configuration (`lib/supabaseClient.ts`):**
|
|
83
|
+
```typescript
|
|
84
|
+
export const supabase = createClient(url, anonKey, {
|
|
85
|
+
auth: {
|
|
86
|
+
persistSession: false, // ← SessionStore handles persistence
|
|
87
|
+
autoRefreshToken: true,
|
|
88
|
+
detectSessionInUrl: true,
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Why this pattern?**
|
|
94
|
+
- Single source of truth (no sync issues)
|
|
95
|
+
- Explicit session management
|
|
96
|
+
- No localStorage conflicts
|
|
97
|
+
- Proper session validation
|
|
98
|
+
|
|
99
|
+
**See:** `lib/supabaseClient.ts` for full implementation
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## RLS Security
|
|
104
|
+
|
|
105
|
+
### Enable by Default
|
|
106
|
+
|
|
107
|
+
**On all tables with sensitive data:**
|
|
108
|
+
```sql
|
|
109
|
+
CREATE TABLE table_name (...);
|
|
110
|
+
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Policy Naming
|
|
114
|
+
|
|
115
|
+
**Use descriptive names:**
|
|
116
|
+
```sql
|
|
117
|
+
-- ✅ GOOD
|
|
118
|
+
CREATE POLICY "Users can view own profile" ...
|
|
119
|
+
CREATE POLICY "Fund Managers can view all profiles" ...
|
|
120
|
+
|
|
121
|
+
-- ❌ BAD
|
|
122
|
+
CREATE POLICY "select_policy" ...
|
|
123
|
+
CREATE POLICY "policy1" ...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Always Use WITH CHECK
|
|
127
|
+
|
|
128
|
+
**For UPDATE/INSERT operations:**
|
|
129
|
+
```sql
|
|
130
|
+
-- ✅ GOOD: Enforces ownership on write
|
|
131
|
+
CREATE POLICY "Users can update own profile"
|
|
132
|
+
ON profiles
|
|
133
|
+
FOR UPDATE
|
|
134
|
+
TO authenticated
|
|
135
|
+
USING (id = auth.uid())
|
|
136
|
+
WITH CHECK (id = auth.uid()); -- ← Prevents claiming other data
|
|
137
|
+
|
|
138
|
+
-- ❌ BAD: Allows escalation
|
|
139
|
+
CREATE POLICY "Users can update own profile"
|
|
140
|
+
ON profiles
|
|
141
|
+
FOR UPDATE
|
|
142
|
+
TO authenticated
|
|
143
|
+
USING (id = auth.uid()); -- Missing WITH CHECK
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Performance
|
|
149
|
+
|
|
150
|
+
### Index Foreign Keys
|
|
151
|
+
|
|
152
|
+
**Always create indexes for foreign keys:**
|
|
153
|
+
```sql
|
|
154
|
+
CREATE TABLE transactions (
|
|
155
|
+
id UUID PRIMARY KEY,
|
|
156
|
+
fund_id UUID NOT NULL REFERENCES funds(id),
|
|
157
|
+
investor_id UUID NOT NULL REFERENCES profiles(id)
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
-- Required indexes
|
|
161
|
+
CREATE INDEX idx_transactions_fund_id ON transactions (fund_id);
|
|
162
|
+
CREATE INDEX idx_transactions_investor_id ON transactions (investor_id);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Composite Indexes for Common Queries
|
|
166
|
+
|
|
167
|
+
```sql
|
|
168
|
+
-- If querying by fund_id + created_at frequently
|
|
169
|
+
CREATE INDEX idx_transactions_fund_date
|
|
170
|
+
ON transactions (fund_id, created_at DESC);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Avoid N+1 Queries
|
|
174
|
+
|
|
175
|
+
**Use Supabase joins:**
|
|
176
|
+
```typescript
|
|
177
|
+
// ❌ BAD: N+1 queries
|
|
178
|
+
const funds = await supabase.from('funds').select('*');
|
|
179
|
+
for (const fund of funds.data) {
|
|
180
|
+
const transactions = await supabase
|
|
181
|
+
.from('transactions')
|
|
182
|
+
.select('*')
|
|
183
|
+
.eq('fund_id', fund.id);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ✅ GOOD: Single query
|
|
187
|
+
const funds = await supabase
|
|
188
|
+
.from('funds')
|
|
189
|
+
.select('*, transactions(*)');
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Data Types
|
|
195
|
+
|
|
196
|
+
### Standard Types
|
|
197
|
+
|
|
198
|
+
| Use Case | Type | Notes |
|
|
199
|
+
|----------|------|-------|
|
|
200
|
+
| Primary Key | `UUID DEFAULT gen_random_uuid()` | Always UUID |
|
|
201
|
+
| Money | `NUMERIC(12,2)` | Never FLOAT |
|
|
202
|
+
| Timestamps | `TIMESTAMPTZ` | Always with timezone |
|
|
203
|
+
| Booleans | `BOOLEAN` | Not TEXT |
|
|
204
|
+
| Enums | `CREATE TYPE` | Not TEXT strings |
|
|
205
|
+
| IP Address | `INET` | Native support |
|
|
206
|
+
| JSON | `JSONB` | Not TEXT |
|
|
207
|
+
|
|
208
|
+
### Always Add Timestamps
|
|
209
|
+
|
|
210
|
+
```sql
|
|
211
|
+
CREATE TABLE table_name (
|
|
212
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
213
|
+
-- ... columns
|
|
214
|
+
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
|
|
215
|
+
updated_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
-- Trigger for updated_at
|
|
219
|
+
CREATE TRIGGER update_table_updated_at
|
|
220
|
+
BEFORE UPDATE ON table_name
|
|
221
|
+
FOR EACH ROW
|
|
222
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Documentation
|
|
228
|
+
|
|
229
|
+
### Comment Everything
|
|
230
|
+
|
|
231
|
+
```sql
|
|
232
|
+
COMMENT ON TABLE profiles IS
|
|
233
|
+
'Extended user profiles with role-based access control';
|
|
234
|
+
|
|
235
|
+
COMMENT ON COLUMN profiles.role IS
|
|
236
|
+
'User role (fund_manager or investor) for authorization';
|
|
237
|
+
|
|
238
|
+
COMMENT ON COLUMN profiles.kyc_status IS
|
|
239
|
+
'KYC verification status (PENDING, APPROVED, REJECTED)';
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Why?**
|
|
243
|
+
- Helps future developers
|
|
244
|
+
- Shows up in database tools
|
|
245
|
+
- Documents business logic
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Common Pitfalls
|
|
250
|
+
|
|
251
|
+
### ❌ Missing ON DELETE Actions
|
|
252
|
+
|
|
253
|
+
```sql
|
|
254
|
+
-- BAD: No ON DELETE action
|
|
255
|
+
user_id UUID REFERENCES users(id)
|
|
256
|
+
|
|
257
|
+
-- GOOD: Explicit cascade or restrict
|
|
258
|
+
user_id UUID REFERENCES users(id) ON DELETE CASCADE
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### ❌ TIMESTAMP Instead of TIMESTAMPTZ
|
|
262
|
+
|
|
263
|
+
```sql
|
|
264
|
+
-- BAD: Loses timezone info
|
|
265
|
+
created_at TIMESTAMP
|
|
266
|
+
|
|
267
|
+
-- GOOD: Preserves timezone
|
|
268
|
+
created_at TIMESTAMPTZ
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### ❌ No RLS on Sensitive Tables
|
|
272
|
+
|
|
273
|
+
```sql
|
|
274
|
+
-- BAD: Anyone can read all data
|
|
275
|
+
CREATE TABLE sensitive_data (...);
|
|
276
|
+
|
|
277
|
+
-- GOOD: RLS enforced
|
|
278
|
+
CREATE TABLE sensitive_data (...);
|
|
279
|
+
ALTER TABLE sensitive_data ENABLE ROW LEVEL SECURITY;
|
|
280
|
+
CREATE POLICY "..." ON sensitive_data ...;
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### ❌ Using Service Role in Client
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// ❌ BAD: Bypasses ALL RLS policies
|
|
287
|
+
const supabase = createClient(url, serviceRoleKey);
|
|
288
|
+
|
|
289
|
+
// ✅ GOOD: Enforces RLS
|
|
290
|
+
const supabase = createClient(url, anonKey);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Service role only for:**
|
|
294
|
+
- Admin operations
|
|
295
|
+
- Server-side code
|
|
296
|
+
- Database migrations
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Migration Workflow
|
|
301
|
+
|
|
302
|
+
1. **Plan** - Document what needs to change
|
|
303
|
+
2. **Create file** - Use date prefix naming
|
|
304
|
+
3. **Write SQL** - Use idempotent operations
|
|
305
|
+
4. **Add indexes** - For foreign keys and queries
|
|
306
|
+
5. **Enable RLS** - On sensitive tables
|
|
307
|
+
6. **Add comments** - Document tables and columns
|
|
308
|
+
7. **Test locally** - Verify migration works
|
|
309
|
+
8. **Review** - Check against this guide
|
|
310
|
+
9. **Deploy** - Apply to production
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## References
|
|
315
|
+
|
|
316
|
+
- **Existing migrations:** `backend/migrations/`
|
|
317
|
+
- **Supabase client:** `lib/supabaseClient.ts`
|
|
318
|
+
- **Auth context:** `context/AuthContext.tsx`
|
|
319
|
+
- **Session storage:** `lib/auth/SessionStore.ts`
|