@intentsolutionsio/supabase-pack 1.0.0
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/.claude-plugin/plugin.json +17 -0
- package/000-docs/001-BL-LICN-license.txt +3 -0
- package/LICENSE +21 -0
- package/README.md +69 -0
- package/package.json +43 -0
- package/skills/supabase-advanced-troubleshooting/SKILL.md +261 -0
- package/skills/supabase-architecture-variants/SKILL.md +284 -0
- package/skills/supabase-auth-storage-realtime-core/SKILL.md +73 -0
- package/skills/supabase-ci-integration/SKILL.md +124 -0
- package/skills/supabase-common-errors/SKILL.md +109 -0
- package/skills/supabase-cost-tuning/SKILL.md +201 -0
- package/skills/supabase-data-handling/SKILL.md +220 -0
- package/skills/supabase-debug-bundle/SKILL.md +111 -0
- package/skills/supabase-deploy-integration/SKILL.md +209 -0
- package/skills/supabase-enterprise-rbac/SKILL.md +222 -0
- package/skills/supabase-hello-world/SKILL.md +96 -0
- package/skills/supabase-incident-runbook/SKILL.md +203 -0
- package/skills/supabase-install-auth/SKILL.md +90 -0
- package/skills/supabase-known-pitfalls/SKILL.md +334 -0
- package/skills/supabase-load-scale/SKILL.md +274 -0
- package/skills/supabase-local-dev-loop/SKILL.md +117 -0
- package/skills/supabase-migration-deep-dive/SKILL.md +244 -0
- package/skills/supabase-multi-env-setup/SKILL.md +222 -0
- package/skills/supabase-observability/SKILL.md +250 -0
- package/skills/supabase-performance-tuning/SKILL.md +214 -0
- package/skills/supabase-policy-guardrails/SKILL.md +257 -0
- package/skills/supabase-prod-checklist/SKILL.md +119 -0
- package/skills/supabase-rate-limits/SKILL.md +149 -0
- package/skills/supabase-reference-architecture/SKILL.md +238 -0
- package/skills/supabase-reliability-patterns/SKILL.md +290 -0
- package/skills/supabase-schema-from-requirements/SKILL.md +71 -0
- package/skills/supabase-sdk-patterns/SKILL.md +147 -0
- package/skills/supabase-security-basics/SKILL.md +140 -0
- package/skills/supabase-upgrade-migration/SKILL.md +112 -0
- package/skills/supabase-webhooks-events/SKILL.md +199 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supabase-data-handling
|
|
3
|
+
description: |
|
|
4
|
+
Implement Supabase PII handling, data retention, and GDPR/CCPA compliance patterns.
|
|
5
|
+
Use when handling sensitive data, implementing data redaction, configuring retention policies,
|
|
6
|
+
or ensuring compliance with privacy regulations for Supabase integrations.
|
|
7
|
+
Trigger with phrases like "supabase data", "supabase PII",
|
|
8
|
+
"supabase GDPR", "supabase data retention", "supabase privacy", "supabase CCPA".
|
|
9
|
+
allowed-tools: Read, Write, Edit
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Supabase Data Handling
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Handle sensitive data correctly when integrating with Supabase.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Understanding of GDPR/CCPA requirements
|
|
22
|
+
- Supabase SDK with data export capabilities
|
|
23
|
+
- Database for audit logging
|
|
24
|
+
- Scheduled job infrastructure for cleanup
|
|
25
|
+
|
|
26
|
+
## Data Classification
|
|
27
|
+
|
|
28
|
+
| Category | Examples | Handling |
|
|
29
|
+
|----------|----------|----------|
|
|
30
|
+
| PII | Email, name, phone | Encrypt, minimize |
|
|
31
|
+
| Sensitive | API keys, tokens | Never log, rotate |
|
|
32
|
+
| Business | Usage metrics | Aggregate when possible |
|
|
33
|
+
| Public | Product names | Standard handling |
|
|
34
|
+
|
|
35
|
+
## PII Detection
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const PII_PATTERNS = [
|
|
39
|
+
{ type: 'email', regex: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g },
|
|
40
|
+
{ type: 'phone', regex: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g },
|
|
41
|
+
{ type: 'ssn', regex: /\b\d{3}-\d{2}-\d{4}\b/g },
|
|
42
|
+
{ type: 'credit_card', regex: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
function detectPII(text: string): { type: string; match: string }[] {
|
|
46
|
+
const findings: { type: string; match: string }[] = [];
|
|
47
|
+
|
|
48
|
+
for (const pattern of PII_PATTERNS) {
|
|
49
|
+
const matches = text.matchAll(pattern.regex);
|
|
50
|
+
for (const match of matches) {
|
|
51
|
+
findings.push({ type: pattern.type, match: match[0] });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return findings;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Data Redaction
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
function redactPII(data: Record<string, any>): Record<string, any> {
|
|
63
|
+
const sensitiveFields = ['email', 'phone', 'ssn', 'password', 'apiKey'];
|
|
64
|
+
const redacted = { ...data };
|
|
65
|
+
|
|
66
|
+
for (const field of sensitiveFields) {
|
|
67
|
+
if (redacted[field]) {
|
|
68
|
+
redacted[field] = '[REDACTED]';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return redacted;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Use in logging
|
|
76
|
+
console.log('Supabase request:', redactPII(requestData));
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Data Retention Policy
|
|
80
|
+
|
|
81
|
+
### Retention Periods
|
|
82
|
+
| Data Type | Retention | Reason |
|
|
83
|
+
|-----------|-----------|--------|
|
|
84
|
+
| API logs | 30 days | Debugging |
|
|
85
|
+
| Error logs | 90 days | Root cause analysis |
|
|
86
|
+
| Audit logs | 7 years | Compliance |
|
|
87
|
+
| PII | Until deletion request | GDPR/CCPA |
|
|
88
|
+
|
|
89
|
+
### Automatic Cleanup
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
async function cleanupSupabaseData(retentionDays: number): Promise<void> {
|
|
93
|
+
const cutoff = new Date();
|
|
94
|
+
cutoff.setDate(cutoff.getDate() - retentionDays);
|
|
95
|
+
|
|
96
|
+
await db.supabaseLogs.deleteMany({
|
|
97
|
+
createdAt: { $lt: cutoff },
|
|
98
|
+
type: { $nin: ['audit', 'compliance'] },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Schedule daily cleanup
|
|
103
|
+
cron.schedule('0 3 * * *', () => cleanupSupabaseData(30));
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## GDPR/CCPA Compliance
|
|
107
|
+
|
|
108
|
+
### Data Subject Access Request (DSAR)
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
async function exportUserData(userId: string): Promise<DataExport> {
|
|
112
|
+
const supabaseData = await supabaseClient.getUserData(userId);
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
source: 'Supabase',
|
|
116
|
+
exportedAt: new Date().toISOString(),
|
|
117
|
+
data: {
|
|
118
|
+
profile: supabaseData.profile,
|
|
119
|
+
activities: supabaseData.activities,
|
|
120
|
+
// Include all user-related data
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Right to Deletion
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
async function deleteUserData(userId: string): Promise<DeletionResult> {
|
|
130
|
+
// 1. Delete from Supabase
|
|
131
|
+
await supabaseClient.deleteUser(userId);
|
|
132
|
+
|
|
133
|
+
// 2. Delete local copies
|
|
134
|
+
await db.supabaseUserCache.deleteMany({ userId });
|
|
135
|
+
|
|
136
|
+
// 3. Audit log (required to keep)
|
|
137
|
+
await auditLog.record({
|
|
138
|
+
action: 'GDPR_DELETION',
|
|
139
|
+
userId,
|
|
140
|
+
service: 'supabase',
|
|
141
|
+
timestamp: new Date(),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return { success: true, deletedAt: new Date() };
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Data Minimization
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// Only request needed fields
|
|
152
|
+
const user = await supabaseClient.getUser(userId, {
|
|
153
|
+
fields: ['id', 'name'], // Not email, phone, address
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Don't store unnecessary data
|
|
157
|
+
const cacheData = {
|
|
158
|
+
id: user.id,
|
|
159
|
+
name: user.name,
|
|
160
|
+
// Omit sensitive fields
|
|
161
|
+
};
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Instructions
|
|
165
|
+
|
|
166
|
+
### Step 1: Classify Data
|
|
167
|
+
Categorize all Supabase data by sensitivity level.
|
|
168
|
+
|
|
169
|
+
### Step 2: Implement PII Detection
|
|
170
|
+
Add regex patterns to detect sensitive data in logs.
|
|
171
|
+
|
|
172
|
+
### Step 3: Configure Redaction
|
|
173
|
+
Apply redaction to sensitive fields before logging.
|
|
174
|
+
|
|
175
|
+
### Step 4: Set Up Retention
|
|
176
|
+
Configure automatic cleanup with appropriate retention periods.
|
|
177
|
+
|
|
178
|
+
## Output
|
|
179
|
+
- Data classification documented
|
|
180
|
+
- PII detection implemented
|
|
181
|
+
- Redaction in logging active
|
|
182
|
+
- Retention policy enforced
|
|
183
|
+
|
|
184
|
+
## Error Handling
|
|
185
|
+
| Issue | Cause | Solution |
|
|
186
|
+
|-------|-------|----------|
|
|
187
|
+
| PII in logs | Missing redaction | Wrap logging with redact |
|
|
188
|
+
| Deletion failed | Data locked | Check dependencies |
|
|
189
|
+
| Export incomplete | Timeout | Increase batch size |
|
|
190
|
+
| Audit gap | Missing entries | Review log pipeline |
|
|
191
|
+
|
|
192
|
+
## Examples
|
|
193
|
+
|
|
194
|
+
### Quick PII Scan
|
|
195
|
+
```typescript
|
|
196
|
+
const findings = detectPII(JSON.stringify(userData));
|
|
197
|
+
if (findings.length > 0) {
|
|
198
|
+
console.warn(`PII detected: ${findings.map(f => f.type).join(', ')}`);
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Redact Before Logging
|
|
203
|
+
```typescript
|
|
204
|
+
const safeData = redactPII(apiResponse);
|
|
205
|
+
logger.info('Supabase response:', safeData);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### GDPR Data Export
|
|
209
|
+
```typescript
|
|
210
|
+
const userExport = await exportUserData('user-123');
|
|
211
|
+
await sendToUser(userExport);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Resources
|
|
215
|
+
- [GDPR Developer Guide](https://gdpr.eu/developers/)
|
|
216
|
+
- [CCPA Compliance Guide](https://oag.ca.gov/privacy/ccpa)
|
|
217
|
+
- [Supabase Privacy Guide](https://supabase.com/docs/privacy)
|
|
218
|
+
|
|
219
|
+
## Next Steps
|
|
220
|
+
For enterprise access control, see `supabase-enterprise-rbac`.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supabase-debug-bundle
|
|
3
|
+
description: |
|
|
4
|
+
Collect Supabase debug evidence for support tickets and troubleshooting.
|
|
5
|
+
Use when encountering persistent issues, preparing support tickets,
|
|
6
|
+
or collecting diagnostic information for Supabase problems.
|
|
7
|
+
Trigger with phrases like "supabase debug", "supabase support bundle",
|
|
8
|
+
"collect supabase logs", "supabase diagnostic".
|
|
9
|
+
allowed-tools: Read, Bash(grep:*), Bash(curl:*), Bash(tar:*), Grep
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Supabase Debug Bundle
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Collect all necessary diagnostic information for Supabase support tickets.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Supabase SDK installed
|
|
22
|
+
- Access to application logs
|
|
23
|
+
- Permission to collect environment info
|
|
24
|
+
|
|
25
|
+
## Instructions
|
|
26
|
+
|
|
27
|
+
### Step 1: Create Debug Bundle Script
|
|
28
|
+
```bash
|
|
29
|
+
#!/bin/bash
|
|
30
|
+
# supabase-debug-bundle.sh
|
|
31
|
+
|
|
32
|
+
BUNDLE_DIR="supabase-debug-$(date +%Y%m%d-%H%M%S)"
|
|
33
|
+
mkdir -p "$BUNDLE_DIR"
|
|
34
|
+
|
|
35
|
+
echo "=== Supabase Debug Bundle ===" > "$BUNDLE_DIR/summary.txt"
|
|
36
|
+
echo "Generated: $(date)" >> "$BUNDLE_DIR/summary.txt"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Step 2: Collect Environment Info
|
|
40
|
+
```bash
|
|
41
|
+
# Environment info
|
|
42
|
+
echo "--- Environment ---" >> "$BUNDLE_DIR/summary.txt"
|
|
43
|
+
node --version >> "$BUNDLE_DIR/summary.txt" 2>&1
|
|
44
|
+
npm --version >> "$BUNDLE_DIR/summary.txt" 2>&1
|
|
45
|
+
echo "SUPABASE_API_KEY: ${SUPABASE_API_KEY:+[SET]}" >> "$BUNDLE_DIR/summary.txt"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Step 3: Gather SDK and Logs
|
|
49
|
+
```bash
|
|
50
|
+
# SDK version
|
|
51
|
+
npm list @supabase/supabase-js 2>/dev/null >> "$BUNDLE_DIR/summary.txt"
|
|
52
|
+
|
|
53
|
+
# Recent logs (redacted)
|
|
54
|
+
grep -i "supabase" ~/.npm/_logs/*.log 2>/dev/null | tail -50 >> "$BUNDLE_DIR/logs.txt"
|
|
55
|
+
|
|
56
|
+
# Configuration (redacted - secrets masked)
|
|
57
|
+
echo "--- Config (redacted) ---" >> "$BUNDLE_DIR/summary.txt"
|
|
58
|
+
cat .env 2>/dev/null | sed 's/=.*/=***REDACTED***/' >> "$BUNDLE_DIR/config-redacted.txt"
|
|
59
|
+
|
|
60
|
+
# Network connectivity test
|
|
61
|
+
echo "--- Network Test ---" >> "$BUNDLE_DIR/summary.txt"
|
|
62
|
+
echo -n "API Health: " >> "$BUNDLE_DIR/summary.txt"
|
|
63
|
+
curl -s -o /dev/null -w "%{http_code}" https://api.supabase.com/health >> "$BUNDLE_DIR/summary.txt"
|
|
64
|
+
echo "" >> "$BUNDLE_DIR/summary.txt"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Step 4: Package Bundle
|
|
68
|
+
```bash
|
|
69
|
+
tar -czf "$BUNDLE_DIR.tar.gz" "$BUNDLE_DIR"
|
|
70
|
+
echo "Bundle created: $BUNDLE_DIR.tar.gz"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Output
|
|
74
|
+
- `supabase-debug-YYYYMMDD-HHMMSS.tar.gz` archive containing:
|
|
75
|
+
- `summary.txt` - Environment and SDK info
|
|
76
|
+
- `logs.txt` - Recent redacted logs
|
|
77
|
+
- `config-redacted.txt` - Configuration (secrets removed)
|
|
78
|
+
|
|
79
|
+
## Error Handling
|
|
80
|
+
| Item | Purpose | Included |
|
|
81
|
+
|------|---------|----------|
|
|
82
|
+
| Environment versions | Compatibility check | ✓ |
|
|
83
|
+
| SDK version | Version-specific bugs | ✓ |
|
|
84
|
+
| Error logs (redacted) | Root cause analysis | ✓ |
|
|
85
|
+
| Config (redacted) | Configuration issues | ✓ |
|
|
86
|
+
| Network test | Connectivity issues | ✓ |
|
|
87
|
+
|
|
88
|
+
## Examples
|
|
89
|
+
|
|
90
|
+
### Sensitive Data Handling
|
|
91
|
+
**ALWAYS REDACT:**
|
|
92
|
+
- API keys and tokens
|
|
93
|
+
- Passwords and secrets
|
|
94
|
+
- PII (emails, names, IDs)
|
|
95
|
+
|
|
96
|
+
**Safe to Include:**
|
|
97
|
+
- Error messages
|
|
98
|
+
- Stack traces (redacted)
|
|
99
|
+
- SDK/runtime versions
|
|
100
|
+
|
|
101
|
+
### Submit to Support
|
|
102
|
+
1. Create bundle: `bash supabase-debug-bundle.sh`
|
|
103
|
+
2. Review for sensitive data
|
|
104
|
+
3. Upload to Supabase support portal
|
|
105
|
+
|
|
106
|
+
## Resources
|
|
107
|
+
- [Supabase Support](https://supabase.com/docs/support)
|
|
108
|
+
- [Supabase Status](https://status.supabase.com)
|
|
109
|
+
|
|
110
|
+
## Next Steps
|
|
111
|
+
For rate limit issues, see `supabase-rate-limits`.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supabase-deploy-integration
|
|
3
|
+
description: |
|
|
4
|
+
Deploy Supabase integrations to Vercel, Fly.io, and Cloud Run platforms.
|
|
5
|
+
Use when deploying Supabase-powered applications to production,
|
|
6
|
+
configuring platform-specific secrets, or setting up deployment pipelines.
|
|
7
|
+
Trigger with phrases like "deploy supabase", "supabase Vercel",
|
|
8
|
+
"supabase production deploy", "supabase Cloud Run", "supabase Fly.io".
|
|
9
|
+
allowed-tools: Read, Write, Edit, Bash(vercel:*), Bash(fly:*), Bash(gcloud:*)
|
|
10
|
+
version: 1.0.0
|
|
11
|
+
license: MIT
|
|
12
|
+
author: Jeremy Longshore <jeremy@intentsolutions.io>
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Supabase Deploy Integration
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
Deploy Supabase-powered applications to popular platforms with proper secrets management.
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
- Supabase API keys for production environment
|
|
22
|
+
- Platform CLI installed (vercel, fly, or gcloud)
|
|
23
|
+
- Application code ready for deployment
|
|
24
|
+
- Environment variables documented
|
|
25
|
+
|
|
26
|
+
## Vercel Deployment
|
|
27
|
+
|
|
28
|
+
### Environment Setup
|
|
29
|
+
```bash
|
|
30
|
+
# Add Supabase secrets to Vercel
|
|
31
|
+
vercel secrets add supabase_api_key sk_live_***
|
|
32
|
+
vercel secrets add supabase_webhook_secret whsec_***
|
|
33
|
+
|
|
34
|
+
# Link to project
|
|
35
|
+
vercel link
|
|
36
|
+
|
|
37
|
+
# Deploy preview
|
|
38
|
+
vercel
|
|
39
|
+
|
|
40
|
+
# Deploy production
|
|
41
|
+
vercel --prod
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### vercel.json Configuration
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"env": {
|
|
48
|
+
"SUPABASE_API_KEY": "@supabase_api_key"
|
|
49
|
+
},
|
|
50
|
+
"functions": {
|
|
51
|
+
"api/**/*.ts": {
|
|
52
|
+
"maxDuration": 30
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Fly.io Deployment
|
|
59
|
+
|
|
60
|
+
### fly.toml
|
|
61
|
+
```toml
|
|
62
|
+
app = "my-supabase-app"
|
|
63
|
+
primary_region = "iad"
|
|
64
|
+
|
|
65
|
+
[env]
|
|
66
|
+
NODE_ENV = "production"
|
|
67
|
+
|
|
68
|
+
[http_service]
|
|
69
|
+
internal_port = 3000
|
|
70
|
+
force_https = true
|
|
71
|
+
auto_stop_machines = true
|
|
72
|
+
auto_start_machines = true
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Secrets
|
|
76
|
+
```bash
|
|
77
|
+
# Set Supabase secrets
|
|
78
|
+
fly secrets set SUPABASE_API_KEY=sk_live_***
|
|
79
|
+
fly secrets set SUPABASE_WEBHOOK_SECRET=whsec_***
|
|
80
|
+
|
|
81
|
+
# Deploy
|
|
82
|
+
fly deploy
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Google Cloud Run
|
|
86
|
+
|
|
87
|
+
### Dockerfile
|
|
88
|
+
```dockerfile
|
|
89
|
+
FROM node:20-slim
|
|
90
|
+
WORKDIR /app
|
|
91
|
+
COPY package*.json ./
|
|
92
|
+
RUN npm ci --only=production
|
|
93
|
+
COPY . .
|
|
94
|
+
CMD ["npm", "start"]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Deploy Script
|
|
98
|
+
```bash
|
|
99
|
+
#!/bin/bash
|
|
100
|
+
# deploy-cloud-run.sh
|
|
101
|
+
|
|
102
|
+
PROJECT_ID="${GOOGLE_CLOUD_PROJECT}"
|
|
103
|
+
SERVICE_NAME="supabase-service"
|
|
104
|
+
REGION="us-central1"
|
|
105
|
+
|
|
106
|
+
# Build and push image
|
|
107
|
+
gcloud builds submit --tag gcr.io/$PROJECT_ID/$SERVICE_NAME
|
|
108
|
+
|
|
109
|
+
# Deploy to Cloud Run
|
|
110
|
+
gcloud run deploy $SERVICE_NAME \
|
|
111
|
+
--image gcr.io/$PROJECT_ID/$SERVICE_NAME \
|
|
112
|
+
--region $REGION \
|
|
113
|
+
--platform managed \
|
|
114
|
+
--allow-unauthenticated \
|
|
115
|
+
--set-secrets=SUPABASE_API_KEY=supabase-api-key:latest
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Environment Configuration Pattern
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// config/supabase.ts
|
|
122
|
+
interface SupabaseConfig {
|
|
123
|
+
apiKey: string;
|
|
124
|
+
environment: 'development' | 'staging' | 'production';
|
|
125
|
+
webhookSecret?: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function getSupabaseConfig(): SupabaseConfig {
|
|
129
|
+
const env = process.env.NODE_ENV || 'development';
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
apiKey: process.env.SUPABASE_API_KEY!,
|
|
133
|
+
environment: env as SupabaseConfig['environment'],
|
|
134
|
+
webhookSecret: process.env.SUPABASE_WEBHOOK_SECRET,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Health Check Endpoint
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// api/health.ts
|
|
143
|
+
export async function GET() {
|
|
144
|
+
const supabaseStatus = await checkSupabaseConnection();
|
|
145
|
+
|
|
146
|
+
return Response.json({
|
|
147
|
+
status: supabaseStatus ? 'healthy' : 'degraded',
|
|
148
|
+
services: {
|
|
149
|
+
supabase: supabaseStatus,
|
|
150
|
+
},
|
|
151
|
+
timestamp: new Date().toISOString(),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Instructions
|
|
157
|
+
|
|
158
|
+
### Step 1: Choose Deployment Platform
|
|
159
|
+
Select the platform that best fits your infrastructure needs and follow the platform-specific guide below.
|
|
160
|
+
|
|
161
|
+
### Step 2: Configure Secrets
|
|
162
|
+
Store Supabase API keys securely using the platform's secrets management.
|
|
163
|
+
|
|
164
|
+
### Step 3: Deploy Application
|
|
165
|
+
Use the platform CLI to deploy your application with Supabase integration.
|
|
166
|
+
|
|
167
|
+
### Step 4: Verify Health
|
|
168
|
+
Test the health check endpoint to confirm Supabase connectivity.
|
|
169
|
+
|
|
170
|
+
## Output
|
|
171
|
+
- Application deployed to production
|
|
172
|
+
- Supabase secrets securely configured
|
|
173
|
+
- Health check endpoint functional
|
|
174
|
+
- Environment-specific configuration in place
|
|
175
|
+
|
|
176
|
+
## Error Handling
|
|
177
|
+
| Issue | Cause | Solution |
|
|
178
|
+
|-------|-------|----------|
|
|
179
|
+
| Secret not found | Missing configuration | Add secret via platform CLI |
|
|
180
|
+
| Deploy timeout | Large build | Increase build timeout |
|
|
181
|
+
| Health check fails | Wrong API key | Verify environment variable |
|
|
182
|
+
| Cold start issues | No warm-up | Configure minimum instances |
|
|
183
|
+
|
|
184
|
+
## Examples
|
|
185
|
+
|
|
186
|
+
### Quick Deploy Script
|
|
187
|
+
```bash
|
|
188
|
+
#!/bin/bash
|
|
189
|
+
# Platform-agnostic deploy helper
|
|
190
|
+
case "$1" in
|
|
191
|
+
vercel)
|
|
192
|
+
vercel secrets add supabase_api_key "$SUPABASE_API_KEY"
|
|
193
|
+
vercel --prod
|
|
194
|
+
;;
|
|
195
|
+
fly)
|
|
196
|
+
fly secrets set SUPABASE_API_KEY="$SUPABASE_API_KEY"
|
|
197
|
+
fly deploy
|
|
198
|
+
;;
|
|
199
|
+
esac
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Resources
|
|
203
|
+
- [Vercel Documentation](https://vercel.com/docs)
|
|
204
|
+
- [Fly.io Documentation](https://fly.io/docs)
|
|
205
|
+
- [Cloud Run Documentation](https://cloud.google.com/run/docs)
|
|
206
|
+
- [Supabase Deploy Guide](https://supabase.com/docs/deploy)
|
|
207
|
+
|
|
208
|
+
## Next Steps
|
|
209
|
+
For webhook handling, see `supabase-webhooks-events`.
|