superkit-mcp-server 1.2.2 → 1.2.3
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/security-auditor.md +3 -2
- package/agents/tester.md +274 -274
- package/agents/ui-designer.md +208 -208
- package/build/index.js +18 -9
- package/build/tools/__tests__/loggerTools.test.js +5 -5
- package/build/tools/archTools.js +2 -19
- package/build/tools/autoPreview.js +2 -2
- package/build/tools/compoundTools.js +4 -4
- package/build/tools/docsTools.js +5 -10
- package/build/tools/loggerTools.js +1 -1
- 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/build/tools/validators/convertRules.js +2 -2
- 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/doc.md +6 -6
- 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 -139
- 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,373 +1,373 @@
|
|
|
1
|
-
# Common Supabase Patterns in [PROJECT_NAME]
|
|
2
|
-
|
|
3
|
-
Recurring patterns used across the [PROJECT_NAME] codebase.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Pattern 1: Multi-Fund Tenancy
|
|
8
|
-
|
|
9
|
-
**Use case:** Isolate data between different funds
|
|
10
|
-
|
|
11
|
-
**Implementation:**
|
|
12
|
-
|
|
13
|
-
```sql
|
|
14
|
-
-- Core fund table
|
|
15
|
-
CREATE TABLE funds (
|
|
16
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
17
|
-
name TEXT NOT NULL,
|
|
18
|
-
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
-- Fund-scoped data
|
|
22
|
-
CREATE TABLE fund_data (
|
|
23
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
24
|
-
fund_id UUID NOT NULL REFERENCES funds(id) ON DELETE CASCADE,
|
|
25
|
-
-- ... other columns
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
-- User access mapping
|
|
29
|
-
CREATE TABLE user_fund_access (
|
|
30
|
-
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE,
|
|
31
|
-
fund_id UUID REFERENCES funds(id) ON DELETE CASCADE,
|
|
32
|
-
PRIMARY KEY (user_id, fund_id)
|
|
33
|
-
);
|
|
34
|
-
|
|
35
|
-
-- RLS enforces isolation
|
|
36
|
-
CREATE POLICY "Users see own fund data"
|
|
37
|
-
ON fund_data FOR SELECT TO authenticated
|
|
38
|
-
USING (
|
|
39
|
-
fund_id IN (
|
|
40
|
-
SELECT fund_id FROM user_fund_access
|
|
41
|
-
WHERE user_id = auth.uid()
|
|
42
|
-
)
|
|
43
|
-
);
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**Example:** `backend/migrations/20251129_multi_fund_architecture.sql`
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Pattern 2: Role-Based Access Control
|
|
51
|
-
|
|
52
|
-
**Use case:** Different permissions for fund managers vs investors
|
|
53
|
-
|
|
54
|
-
**Implementation:**
|
|
55
|
-
|
|
56
|
-
```sql
|
|
57
|
-
-- Role enum
|
|
58
|
-
CREATE TYPE app_role AS ENUM ('fund_manager', 'investor');
|
|
59
|
-
|
|
60
|
-
-- Profiles with role
|
|
61
|
-
CREATE TABLE profiles (
|
|
62
|
-
id UUID PRIMARY KEY REFERENCES auth.users(id),
|
|
63
|
-
role app_role NOT NULL DEFAULT 'investor',
|
|
64
|
-
-- ... other columns
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
-- Role-based policy
|
|
68
|
-
CREATE POLICY "Fund Managers can view all"
|
|
69
|
-
ON sensitive_table FOR SELECT TO authenticated
|
|
70
|
-
USING (
|
|
71
|
-
EXISTS (
|
|
72
|
-
SELECT 1 FROM profiles
|
|
73
|
-
WHERE profiles.id = auth.uid()
|
|
74
|
-
AND profiles.role = 'fund_manager'
|
|
75
|
-
)
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
-- Regular users see filtered data
|
|
79
|
-
CREATE POLICY "Users see limited data"
|
|
80
|
-
ON sensitive_table FOR SELECT TO authenticated
|
|
81
|
-
USING (
|
|
82
|
-
user_id = auth.uid()
|
|
83
|
-
OR EXISTS (
|
|
84
|
-
SELECT 1 FROM profiles
|
|
85
|
-
WHERE profiles.id = auth.uid()
|
|
86
|
-
AND profiles.role = 'fund_manager'
|
|
87
|
-
)
|
|
88
|
-
);
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
**Example:** `backend/migrations/20251203_create_profiles_and_app_role.sql`
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
## Pattern 3: Audit Logging
|
|
96
|
-
|
|
97
|
-
**Use case:** Track sensitive operations for compliance
|
|
98
|
-
|
|
99
|
-
**Implementation:**
|
|
100
|
-
|
|
101
|
-
```sql
|
|
102
|
-
CREATE TABLE audit_events (
|
|
103
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
104
|
-
event_type TEXT NOT NULL,
|
|
105
|
-
actor_id UUID REFERENCES profiles(id),
|
|
106
|
-
resource_type TEXT NOT NULL,
|
|
107
|
-
resource_id UUID NOT NULL,
|
|
108
|
-
metadata JSONB,
|
|
109
|
-
ip_address INET,
|
|
110
|
-
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
-- Indexes for querying
|
|
114
|
-
CREATE INDEX idx_audit_events_actor
|
|
115
|
-
ON audit_events (actor_id, created_at DESC);
|
|
116
|
-
|
|
117
|
-
CREATE INDEX idx_audit_events_resource
|
|
118
|
-
ON audit_events (resource_type, resource_id);
|
|
119
|
-
|
|
120
|
-
-- RLS: Only fund managers can view audit logs
|
|
121
|
-
CREATE POLICY "Fund Managers can view audit logs"
|
|
122
|
-
ON audit_events FOR SELECT TO authenticated
|
|
123
|
-
USING (
|
|
124
|
-
EXISTS (
|
|
125
|
-
SELECT 1 FROM profiles
|
|
126
|
-
WHERE profiles.id = auth.uid()
|
|
127
|
-
AND profiles.role = 'fund_manager'
|
|
128
|
-
)
|
|
129
|
-
);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**Example:** `backend/migrations/20251202_create_audit_events.sql`
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
|
-
## Pattern 4: Performance Indexes
|
|
137
|
-
|
|
138
|
-
**Use case:** Optimize common queries
|
|
139
|
-
|
|
140
|
-
**Implementation:**
|
|
141
|
-
|
|
142
|
-
```sql
|
|
143
|
-
-- Foreign key indexes (always)
|
|
144
|
-
CREATE INDEX idx_transactions_fund_id
|
|
145
|
-
ON transactions (fund_id);
|
|
146
|
-
|
|
147
|
-
CREATE INDEX idx_transactions_investor_id
|
|
148
|
-
ON transactions (investor_id);
|
|
149
|
-
|
|
150
|
-
-- Composite index for fund + date queries
|
|
151
|
-
CREATE INDEX idx_transactions_fund_date
|
|
152
|
-
ON transactions (fund_id, created_at DESC);
|
|
153
|
-
|
|
154
|
-
-- Partial index for pending items only
|
|
155
|
-
CREATE INDEX idx_transactions_pending
|
|
156
|
-
ON transactions (status, created_at)
|
|
157
|
-
WHERE status = 'pending';
|
|
158
|
-
|
|
159
|
-
-- Index for frequent WHERE clauses
|
|
160
|
-
CREATE INDEX idx_profiles_investor_code
|
|
161
|
-
ON profiles (investor_code) WHERE investor_code IS NOT NULL;
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**Example:** `backend/migrations/performance_indexes.sql`
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Pattern 5: KYC Status Tracking
|
|
169
|
-
|
|
170
|
-
**Use case:** Track investor verification status
|
|
171
|
-
|
|
172
|
-
**Implementation:**
|
|
173
|
-
|
|
174
|
-
```sql
|
|
175
|
-
-- Status in profiles
|
|
176
|
-
ALTER TABLE profiles
|
|
177
|
-
ADD COLUMN kyc_status TEXT DEFAULT 'PENDING';
|
|
178
|
-
|
|
179
|
-
-- Index for compliance queries
|
|
180
|
-
CREATE INDEX idx_profiles_kyc_status
|
|
181
|
-
ON profiles (kyc_status);
|
|
182
|
-
|
|
183
|
-
-- RLS: Users can see own status, managers see all
|
|
184
|
-
CREATE POLICY "Users can view own KYC status"
|
|
185
|
-
ON profiles FOR SELECT TO authenticated
|
|
186
|
-
USING (id = auth.uid());
|
|
187
|
-
|
|
188
|
-
CREATE POLICY "Fund Managers can view all KYC status"
|
|
189
|
-
ON profiles FOR SELECT TO authenticated
|
|
190
|
-
USING (
|
|
191
|
-
EXISTS (
|
|
192
|
-
SELECT 1 FROM profiles p
|
|
193
|
-
WHERE p.id = auth.uid()
|
|
194
|
-
AND p.role = 'fund_manager'
|
|
195
|
-
)
|
|
196
|
-
);
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
**Example:** `backend/migrations/20251203_alter_profiles_for_identity_fortress.sql`
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
## Pattern 6: Updated At Trigger
|
|
204
|
-
|
|
205
|
-
**Use case:** Auto-update `updated_at` on row changes
|
|
206
|
-
|
|
207
|
-
**Implementation:**
|
|
208
|
-
|
|
209
|
-
```sql
|
|
210
|
-
-- Create reusable function (once per database)
|
|
211
|
-
CREATE OR REPLACE FUNCTION public.update_updated_at_column()
|
|
212
|
-
RETURNS TRIGGER AS $$
|
|
213
|
-
BEGIN
|
|
214
|
-
NEW.updated_at = NOW();
|
|
215
|
-
RETURN NEW;
|
|
216
|
-
END;
|
|
217
|
-
$$ LANGUAGE plpgsql;
|
|
218
|
-
|
|
219
|
-
-- Apply to any table
|
|
220
|
-
CREATE TRIGGER update_{table}_updated_at
|
|
221
|
-
BEFORE UPDATE ON {schema}.{table}
|
|
222
|
-
FOR EACH ROW
|
|
223
|
-
EXECUTE FUNCTION public.update_updated_at_column();
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**Usage:** All tables with `updated_at` column
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
## Pattern 7: Realtime Subscriptions
|
|
231
|
-
|
|
232
|
-
**Use case:** Live updates for fund data
|
|
233
|
-
|
|
234
|
-
**Implementation:**
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
// Client-side subscription
|
|
238
|
-
const subscription = supabase
|
|
239
|
-
.channel('fund-updates')
|
|
240
|
-
.on(
|
|
241
|
-
'postgres_changes',
|
|
242
|
-
{
|
|
243
|
-
event: '*',
|
|
244
|
-
schema: 'public',
|
|
245
|
-
table: 'transactions',
|
|
246
|
-
filter: `fund_id=eq.${fundId}`
|
|
247
|
-
},
|
|
248
|
-
(payload) => {
|
|
249
|
-
console.log('Change detected:', payload);
|
|
250
|
-
// Update UI
|
|
251
|
-
}
|
|
252
|
-
)
|
|
253
|
-
.subscribe();
|
|
254
|
-
|
|
255
|
-
// Cleanup
|
|
256
|
-
return () => subscription.unsubscribe();
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
**Example:** `lib/realtime/fundUpdates.ts`
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## Pattern 8: Safe Enum Migration
|
|
264
|
-
|
|
265
|
-
**Use case:** Add new enum value without breaking
|
|
266
|
-
|
|
267
|
-
**Implementation:**
|
|
268
|
-
|
|
269
|
-
```sql
|
|
270
|
-
-- Original enum
|
|
271
|
-
CREATE TYPE status AS ENUM ('pending', 'approved');
|
|
272
|
-
|
|
273
|
-
-- Safe way to add value (PostgreSQL 12+)
|
|
274
|
-
ALTER TYPE status ADD VALUE IF NOT EXISTS 'rejected';
|
|
275
|
-
|
|
276
|
-
-- For pre-12, must create new type and migrate
|
|
277
|
-
DO $$ BEGIN
|
|
278
|
-
-- Only if type doesn't exist
|
|
279
|
-
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'status_v2') THEN
|
|
280
|
-
CREATE TYPE status_v2 AS ENUM ('pending', 'approved', 'rejected');
|
|
281
|
-
|
|
282
|
-
-- Migrate column
|
|
283
|
-
ALTER TABLE table_name
|
|
284
|
-
ALTER COLUMN status TYPE status_v2
|
|
285
|
-
USING status::text::status_v2;
|
|
286
|
-
|
|
287
|
-
-- Drop old type
|
|
288
|
-
DROP TYPE status;
|
|
289
|
-
|
|
290
|
-
-- Rename new type
|
|
291
|
-
ALTER TYPE status_v2 RENAME TO status;
|
|
292
|
-
END IF;
|
|
293
|
-
END $$;
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## Pattern 9: Pending Cash Adjustments
|
|
299
|
-
|
|
300
|
-
**Use case:** Track transaction adjustments before approval
|
|
301
|
-
|
|
302
|
-
**Implementation:**
|
|
303
|
-
|
|
304
|
-
```sql
|
|
305
|
-
CREATE TABLE pending_cash_adjustments (
|
|
306
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
307
|
-
transaction_request_id UUID REFERENCES transaction_requests(id) ON DELETE CASCADE,
|
|
308
|
-
fund_id UUID NOT NULL REFERENCES funds(id),
|
|
309
|
-
adjustment_amount NUMERIC(12,2) NOT NULL,
|
|
310
|
-
reason TEXT,
|
|
311
|
-
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
312
|
-
);
|
|
313
|
-
|
|
314
|
-
-- Prevent duplicate adjustments
|
|
315
|
-
CREATE UNIQUE INDEX idx_pending_adjustments_unique
|
|
316
|
-
ON pending_cash_adjustments (transaction_request_id);
|
|
317
|
-
|
|
318
|
-
-- RLS: Only fund managers can view/manage
|
|
319
|
-
CREATE POLICY "Fund Managers manage adjustments"
|
|
320
|
-
ON pending_cash_adjustments FOR ALL TO authenticated
|
|
321
|
-
USING (
|
|
322
|
-
EXISTS (
|
|
323
|
-
SELECT 1 FROM profiles
|
|
324
|
-
WHERE profiles.id = auth.uid()
|
|
325
|
-
AND profiles.role = 'fund_manager'
|
|
326
|
-
)
|
|
327
|
-
);
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
**Example:** `backend/migrations/20251127_add_pending_cash_adjustments.sql`
|
|
331
|
-
|
|
332
|
-
---
|
|
333
|
-
|
|
334
|
-
## Pattern 10: System Logs with Test Flag
|
|
335
|
-
|
|
336
|
-
**Use case:** Separate test from production logs
|
|
337
|
-
|
|
338
|
-
**Implementation:**
|
|
339
|
-
|
|
340
|
-
```sql
|
|
341
|
-
CREATE TABLE system_logs (
|
|
342
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
343
|
-
event_type TEXT NOT NULL,
|
|
344
|
-
message TEXT,
|
|
345
|
-
metadata JSONB,
|
|
346
|
-
is_test BOOLEAN DEFAULT FALSE,
|
|
347
|
-
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
348
|
-
);
|
|
349
|
-
|
|
350
|
-
-- Index excluding test logs
|
|
351
|
-
CREATE INDEX idx_system_logs_production
|
|
352
|
-
ON system_logs (created_at DESC)
|
|
353
|
-
WHERE is_test = FALSE;
|
|
354
|
-
|
|
355
|
-
-- Query production logs only
|
|
356
|
-
SELECT * FROM system_logs
|
|
357
|
-
WHERE is_test = FALSE
|
|
358
|
-
ORDER BY created_at DESC;
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
**Example:** `backend/migrations/20251126_add_is_test_to_system_logs.sql`
|
|
362
|
-
|
|
363
|
-
---
|
|
364
|
-
|
|
365
|
-
## Reference Migrations
|
|
366
|
-
|
|
367
|
-
Study these for real-world examples:
|
|
368
|
-
|
|
369
|
-
- **Multi-tenancy:** `20251129_multi_fund_architecture.sql`
|
|
370
|
-
- **RBAC:** `20251203_create_profiles_and_app_role.sql`
|
|
371
|
-
- **Audit:** `20251202_create_audit_events.sql`
|
|
372
|
-
- **Performance:** `performance_indexes.sql`
|
|
373
|
-
- **Triggers:** `20251203_create_claims_sync_trigger.sql`
|
|
1
|
+
# Common Supabase Patterns in [PROJECT_NAME]
|
|
2
|
+
|
|
3
|
+
Recurring patterns used across the [PROJECT_NAME] codebase.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Pattern 1: Multi-Fund Tenancy
|
|
8
|
+
|
|
9
|
+
**Use case:** Isolate data between different funds
|
|
10
|
+
|
|
11
|
+
**Implementation:**
|
|
12
|
+
|
|
13
|
+
```sql
|
|
14
|
+
-- Core fund table
|
|
15
|
+
CREATE TABLE funds (
|
|
16
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
17
|
+
name TEXT NOT NULL,
|
|
18
|
+
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
-- Fund-scoped data
|
|
22
|
+
CREATE TABLE fund_data (
|
|
23
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
24
|
+
fund_id UUID NOT NULL REFERENCES funds(id) ON DELETE CASCADE,
|
|
25
|
+
-- ... other columns
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
-- User access mapping
|
|
29
|
+
CREATE TABLE user_fund_access (
|
|
30
|
+
user_id UUID REFERENCES profiles(id) ON DELETE CASCADE,
|
|
31
|
+
fund_id UUID REFERENCES funds(id) ON DELETE CASCADE,
|
|
32
|
+
PRIMARY KEY (user_id, fund_id)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
-- RLS enforces isolation
|
|
36
|
+
CREATE POLICY "Users see own fund data"
|
|
37
|
+
ON fund_data FOR SELECT TO authenticated
|
|
38
|
+
USING (
|
|
39
|
+
fund_id IN (
|
|
40
|
+
SELECT fund_id FROM user_fund_access
|
|
41
|
+
WHERE user_id = auth.uid()
|
|
42
|
+
)
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Example:** `backend/migrations/20251129_multi_fund_architecture.sql`
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Pattern 2: Role-Based Access Control
|
|
51
|
+
|
|
52
|
+
**Use case:** Different permissions for fund managers vs investors
|
|
53
|
+
|
|
54
|
+
**Implementation:**
|
|
55
|
+
|
|
56
|
+
```sql
|
|
57
|
+
-- Role enum
|
|
58
|
+
CREATE TYPE app_role AS ENUM ('fund_manager', 'investor');
|
|
59
|
+
|
|
60
|
+
-- Profiles with role
|
|
61
|
+
CREATE TABLE profiles (
|
|
62
|
+
id UUID PRIMARY KEY REFERENCES auth.users(id),
|
|
63
|
+
role app_role NOT NULL DEFAULT 'investor',
|
|
64
|
+
-- ... other columns
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
-- Role-based policy
|
|
68
|
+
CREATE POLICY "Fund Managers can view all"
|
|
69
|
+
ON sensitive_table FOR SELECT TO authenticated
|
|
70
|
+
USING (
|
|
71
|
+
EXISTS (
|
|
72
|
+
SELECT 1 FROM profiles
|
|
73
|
+
WHERE profiles.id = auth.uid()
|
|
74
|
+
AND profiles.role = 'fund_manager'
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
-- Regular users see filtered data
|
|
79
|
+
CREATE POLICY "Users see limited data"
|
|
80
|
+
ON sensitive_table FOR SELECT TO authenticated
|
|
81
|
+
USING (
|
|
82
|
+
user_id = auth.uid()
|
|
83
|
+
OR EXISTS (
|
|
84
|
+
SELECT 1 FROM profiles
|
|
85
|
+
WHERE profiles.id = auth.uid()
|
|
86
|
+
AND profiles.role = 'fund_manager'
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Example:** `backend/migrations/20251203_create_profiles_and_app_role.sql`
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Pattern 3: Audit Logging
|
|
96
|
+
|
|
97
|
+
**Use case:** Track sensitive operations for compliance
|
|
98
|
+
|
|
99
|
+
**Implementation:**
|
|
100
|
+
|
|
101
|
+
```sql
|
|
102
|
+
CREATE TABLE audit_events (
|
|
103
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
104
|
+
event_type TEXT NOT NULL,
|
|
105
|
+
actor_id UUID REFERENCES profiles(id),
|
|
106
|
+
resource_type TEXT NOT NULL,
|
|
107
|
+
resource_id UUID NOT NULL,
|
|
108
|
+
metadata JSONB,
|
|
109
|
+
ip_address INET,
|
|
110
|
+
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
-- Indexes for querying
|
|
114
|
+
CREATE INDEX idx_audit_events_actor
|
|
115
|
+
ON audit_events (actor_id, created_at DESC);
|
|
116
|
+
|
|
117
|
+
CREATE INDEX idx_audit_events_resource
|
|
118
|
+
ON audit_events (resource_type, resource_id);
|
|
119
|
+
|
|
120
|
+
-- RLS: Only fund managers can view audit logs
|
|
121
|
+
CREATE POLICY "Fund Managers can view audit logs"
|
|
122
|
+
ON audit_events FOR SELECT TO authenticated
|
|
123
|
+
USING (
|
|
124
|
+
EXISTS (
|
|
125
|
+
SELECT 1 FROM profiles
|
|
126
|
+
WHERE profiles.id = auth.uid()
|
|
127
|
+
AND profiles.role = 'fund_manager'
|
|
128
|
+
)
|
|
129
|
+
);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Example:** `backend/migrations/20251202_create_audit_events.sql`
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Pattern 4: Performance Indexes
|
|
137
|
+
|
|
138
|
+
**Use case:** Optimize common queries
|
|
139
|
+
|
|
140
|
+
**Implementation:**
|
|
141
|
+
|
|
142
|
+
```sql
|
|
143
|
+
-- Foreign key indexes (always)
|
|
144
|
+
CREATE INDEX idx_transactions_fund_id
|
|
145
|
+
ON transactions (fund_id);
|
|
146
|
+
|
|
147
|
+
CREATE INDEX idx_transactions_investor_id
|
|
148
|
+
ON transactions (investor_id);
|
|
149
|
+
|
|
150
|
+
-- Composite index for fund + date queries
|
|
151
|
+
CREATE INDEX idx_transactions_fund_date
|
|
152
|
+
ON transactions (fund_id, created_at DESC);
|
|
153
|
+
|
|
154
|
+
-- Partial index for pending items only
|
|
155
|
+
CREATE INDEX idx_transactions_pending
|
|
156
|
+
ON transactions (status, created_at)
|
|
157
|
+
WHERE status = 'pending';
|
|
158
|
+
|
|
159
|
+
-- Index for frequent WHERE clauses
|
|
160
|
+
CREATE INDEX idx_profiles_investor_code
|
|
161
|
+
ON profiles (investor_code) WHERE investor_code IS NOT NULL;
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Example:** `backend/migrations/performance_indexes.sql`
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Pattern 5: KYC Status Tracking
|
|
169
|
+
|
|
170
|
+
**Use case:** Track investor verification status
|
|
171
|
+
|
|
172
|
+
**Implementation:**
|
|
173
|
+
|
|
174
|
+
```sql
|
|
175
|
+
-- Status in profiles
|
|
176
|
+
ALTER TABLE profiles
|
|
177
|
+
ADD COLUMN kyc_status TEXT DEFAULT 'PENDING';
|
|
178
|
+
|
|
179
|
+
-- Index for compliance queries
|
|
180
|
+
CREATE INDEX idx_profiles_kyc_status
|
|
181
|
+
ON profiles (kyc_status);
|
|
182
|
+
|
|
183
|
+
-- RLS: Users can see own status, managers see all
|
|
184
|
+
CREATE POLICY "Users can view own KYC status"
|
|
185
|
+
ON profiles FOR SELECT TO authenticated
|
|
186
|
+
USING (id = auth.uid());
|
|
187
|
+
|
|
188
|
+
CREATE POLICY "Fund Managers can view all KYC status"
|
|
189
|
+
ON profiles FOR SELECT TO authenticated
|
|
190
|
+
USING (
|
|
191
|
+
EXISTS (
|
|
192
|
+
SELECT 1 FROM profiles p
|
|
193
|
+
WHERE p.id = auth.uid()
|
|
194
|
+
AND p.role = 'fund_manager'
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Example:** `backend/migrations/20251203_alter_profiles_for_identity_fortress.sql`
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Pattern 6: Updated At Trigger
|
|
204
|
+
|
|
205
|
+
**Use case:** Auto-update `updated_at` on row changes
|
|
206
|
+
|
|
207
|
+
**Implementation:**
|
|
208
|
+
|
|
209
|
+
```sql
|
|
210
|
+
-- Create reusable function (once per database)
|
|
211
|
+
CREATE OR REPLACE FUNCTION public.update_updated_at_column()
|
|
212
|
+
RETURNS TRIGGER AS $$
|
|
213
|
+
BEGIN
|
|
214
|
+
NEW.updated_at = NOW();
|
|
215
|
+
RETURN NEW;
|
|
216
|
+
END;
|
|
217
|
+
$$ LANGUAGE plpgsql;
|
|
218
|
+
|
|
219
|
+
-- Apply to any table
|
|
220
|
+
CREATE TRIGGER update_{table}_updated_at
|
|
221
|
+
BEFORE UPDATE ON {schema}.{table}
|
|
222
|
+
FOR EACH ROW
|
|
223
|
+
EXECUTE FUNCTION public.update_updated_at_column();
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Usage:** All tables with `updated_at` column
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Pattern 7: Realtime Subscriptions
|
|
231
|
+
|
|
232
|
+
**Use case:** Live updates for fund data
|
|
233
|
+
|
|
234
|
+
**Implementation:**
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
// Client-side subscription
|
|
238
|
+
const subscription = supabase
|
|
239
|
+
.channel('fund-updates')
|
|
240
|
+
.on(
|
|
241
|
+
'postgres_changes',
|
|
242
|
+
{
|
|
243
|
+
event: '*',
|
|
244
|
+
schema: 'public',
|
|
245
|
+
table: 'transactions',
|
|
246
|
+
filter: `fund_id=eq.${fundId}`
|
|
247
|
+
},
|
|
248
|
+
(payload) => {
|
|
249
|
+
console.log('Change detected:', payload);
|
|
250
|
+
// Update UI
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
.subscribe();
|
|
254
|
+
|
|
255
|
+
// Cleanup
|
|
256
|
+
return () => subscription.unsubscribe();
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Example:** `lib/realtime/fundUpdates.ts`
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Pattern 8: Safe Enum Migration
|
|
264
|
+
|
|
265
|
+
**Use case:** Add new enum value without breaking
|
|
266
|
+
|
|
267
|
+
**Implementation:**
|
|
268
|
+
|
|
269
|
+
```sql
|
|
270
|
+
-- Original enum
|
|
271
|
+
CREATE TYPE status AS ENUM ('pending', 'approved');
|
|
272
|
+
|
|
273
|
+
-- Safe way to add value (PostgreSQL 12+)
|
|
274
|
+
ALTER TYPE status ADD VALUE IF NOT EXISTS 'rejected';
|
|
275
|
+
|
|
276
|
+
-- For pre-12, must create new type and migrate
|
|
277
|
+
DO $$ BEGIN
|
|
278
|
+
-- Only if type doesn't exist
|
|
279
|
+
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'status_v2') THEN
|
|
280
|
+
CREATE TYPE status_v2 AS ENUM ('pending', 'approved', 'rejected');
|
|
281
|
+
|
|
282
|
+
-- Migrate column
|
|
283
|
+
ALTER TABLE table_name
|
|
284
|
+
ALTER COLUMN status TYPE status_v2
|
|
285
|
+
USING status::text::status_v2;
|
|
286
|
+
|
|
287
|
+
-- Drop old type
|
|
288
|
+
DROP TYPE status;
|
|
289
|
+
|
|
290
|
+
-- Rename new type
|
|
291
|
+
ALTER TYPE status_v2 RENAME TO status;
|
|
292
|
+
END IF;
|
|
293
|
+
END $$;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Pattern 9: Pending Cash Adjustments
|
|
299
|
+
|
|
300
|
+
**Use case:** Track transaction adjustments before approval
|
|
301
|
+
|
|
302
|
+
**Implementation:**
|
|
303
|
+
|
|
304
|
+
```sql
|
|
305
|
+
CREATE TABLE pending_cash_adjustments (
|
|
306
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
307
|
+
transaction_request_id UUID REFERENCES transaction_requests(id) ON DELETE CASCADE,
|
|
308
|
+
fund_id UUID NOT NULL REFERENCES funds(id),
|
|
309
|
+
adjustment_amount NUMERIC(12,2) NOT NULL,
|
|
310
|
+
reason TEXT,
|
|
311
|
+
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
-- Prevent duplicate adjustments
|
|
315
|
+
CREATE UNIQUE INDEX idx_pending_adjustments_unique
|
|
316
|
+
ON pending_cash_adjustments (transaction_request_id);
|
|
317
|
+
|
|
318
|
+
-- RLS: Only fund managers can view/manage
|
|
319
|
+
CREATE POLICY "Fund Managers manage adjustments"
|
|
320
|
+
ON pending_cash_adjustments FOR ALL TO authenticated
|
|
321
|
+
USING (
|
|
322
|
+
EXISTS (
|
|
323
|
+
SELECT 1 FROM profiles
|
|
324
|
+
WHERE profiles.id = auth.uid()
|
|
325
|
+
AND profiles.role = 'fund_manager'
|
|
326
|
+
)
|
|
327
|
+
);
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**Example:** `backend/migrations/20251127_add_pending_cash_adjustments.sql`
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Pattern 10: System Logs with Test Flag
|
|
335
|
+
|
|
336
|
+
**Use case:** Separate test from production logs
|
|
337
|
+
|
|
338
|
+
**Implementation:**
|
|
339
|
+
|
|
340
|
+
```sql
|
|
341
|
+
CREATE TABLE system_logs (
|
|
342
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
343
|
+
event_type TEXT NOT NULL,
|
|
344
|
+
message TEXT,
|
|
345
|
+
metadata JSONB,
|
|
346
|
+
is_test BOOLEAN DEFAULT FALSE,
|
|
347
|
+
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
-- Index excluding test logs
|
|
351
|
+
CREATE INDEX idx_system_logs_production
|
|
352
|
+
ON system_logs (created_at DESC)
|
|
353
|
+
WHERE is_test = FALSE;
|
|
354
|
+
|
|
355
|
+
-- Query production logs only
|
|
356
|
+
SELECT * FROM system_logs
|
|
357
|
+
WHERE is_test = FALSE
|
|
358
|
+
ORDER BY created_at DESC;
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Example:** `backend/migrations/20251126_add_is_test_to_system_logs.sql`
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Reference Migrations
|
|
366
|
+
|
|
367
|
+
Study these for real-world examples:
|
|
368
|
+
|
|
369
|
+
- **Multi-tenancy:** `20251129_multi_fund_architecture.sql`
|
|
370
|
+
- **RBAC:** `20251203_create_profiles_and_app_role.sql`
|
|
371
|
+
- **Audit:** `20251202_create_audit_events.sql`
|
|
372
|
+
- **Performance:** `performance_indexes.sql`
|
|
373
|
+
- **Triggers:** `20251203_create_claims_sync_trigger.sql`
|