@intentsolutionsio/supabase-pack 1.0.0 → 1.0.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/LICENSE +1 -1
- package/README.md +73 -47
- package/package.json +4 -4
- package/skills/supabase-advanced-troubleshooting/SKILL.md +404 -200
- package/skills/supabase-advanced-troubleshooting/references/errors.md +11 -0
- package/skills/supabase-advanced-troubleshooting/references/evidence-collection-framework.md +34 -0
- package/skills/supabase-advanced-troubleshooting/references/examples.md +11 -0
- package/skills/supabase-advanced-troubleshooting/references/rls-edge-functions-realtime.md +363 -0
- package/skills/supabase-advanced-troubleshooting/references/systematic-isolation.md +56 -0
- package/skills/supabase-advanced-troubleshooting/references/timing-analysis.md +35 -0
- package/skills/supabase-architecture-variants/SKILL.md +395 -216
- package/skills/supabase-architecture-variants/references/errors.md +11 -0
- package/skills/supabase-architecture-variants/references/examples.md +12 -0
- package/skills/supabase-architecture-variants/references/serverless-and-multi-tenant.md +251 -0
- package/skills/supabase-architecture-variants/references/variant-a-monolith-(simple).md +44 -0
- package/skills/supabase-architecture-variants/references/variant-b-service-layer-(moderate).md +72 -0
- package/skills/supabase-architecture-variants/references/variant-c-microservice-(complex).md +81 -0
- package/skills/supabase-auth-storage-realtime-core/SKILL.md +471 -37
- package/skills/supabase-ci-integration/SKILL.md +315 -67
- package/skills/supabase-ci-integration/references/errors.md +10 -0
- package/skills/supabase-ci-integration/references/examples.md +36 -0
- package/skills/supabase-ci-integration/references/implementation.md +54 -0
- package/skills/supabase-common-errors/SKILL.md +320 -62
- package/skills/supabase-common-errors/references/errors.md +53 -0
- package/skills/supabase-common-errors/references/examples.md +23 -0
- package/skills/supabase-cost-tuning/SKILL.md +365 -131
- package/skills/supabase-cost-tuning/references/cost-estimation.md +34 -0
- package/skills/supabase-cost-tuning/references/cost-reduction-strategies.md +40 -0
- package/skills/supabase-cost-tuning/references/errors.md +11 -0
- package/skills/supabase-cost-tuning/references/examples.md +15 -0
- package/skills/supabase-data-handling/SKILL.md +378 -145
- package/skills/supabase-data-handling/references/errors.md +11 -0
- package/skills/supabase-data-handling/references/examples.md +27 -0
- package/skills/supabase-data-handling/references/implementation.md +223 -0
- package/skills/supabase-data-handling/references/retention-and-backup.md +221 -0
- package/skills/supabase-debug-bundle/SKILL.md +267 -73
- package/skills/supabase-debug-bundle/references/errors.md +12 -0
- package/skills/supabase-debug-bundle/references/examples.md +24 -0
- package/skills/supabase-debug-bundle/references/implementation.md +54 -0
- package/skills/supabase-deploy-integration/SKILL.md +258 -147
- package/skills/supabase-deploy-integration/references/errors.md +11 -0
- package/skills/supabase-deploy-integration/references/examples.md +21 -0
- package/skills/supabase-deploy-integration/references/google-cloud-run.md +36 -0
- package/skills/supabase-deploy-integration/references/vercel-deployment.md +35 -0
- package/skills/supabase-enterprise-rbac/SKILL.md +327 -160
- package/skills/supabase-enterprise-rbac/references/api-scoping-and-enforcement.md +255 -0
- package/skills/supabase-enterprise-rbac/references/errors.md +11 -0
- package/skills/supabase-enterprise-rbac/references/examples.md +12 -0
- package/skills/supabase-enterprise-rbac/references/role-implementation.md +33 -0
- package/skills/supabase-enterprise-rbac/references/sso-integration.md +35 -0
- package/skills/supabase-hello-world/SKILL.md +160 -54
- package/skills/supabase-incident-runbook/SKILL.md +453 -131
- package/skills/supabase-incident-runbook/references/errors.md +11 -0
- package/skills/supabase-incident-runbook/references/examples.md +10 -0
- package/skills/supabase-incident-runbook/references/immediate-actions-by-error-type.md +41 -0
- package/skills/supabase-install-auth/SKILL.md +186 -50
- package/skills/supabase-install-auth/references/examples.md +102 -0
- package/skills/supabase-known-pitfalls/SKILL.md +411 -241
- package/skills/supabase-known-pitfalls/references/errors.md +11 -0
- package/skills/supabase-known-pitfalls/references/examples.md +12 -0
- package/skills/supabase-load-scale/SKILL.md +346 -217
- package/skills/supabase-load-scale/references/capacity-planning.md +47 -0
- package/skills/supabase-load-scale/references/errors.md +11 -0
- package/skills/supabase-load-scale/references/examples.md +26 -0
- package/skills/supabase-load-scale/references/load-testing-with-k6.md +59 -0
- package/skills/supabase-load-scale/references/scaling-patterns.md +65 -0
- package/skills/supabase-load-scale/references/table-partitioning.md +263 -0
- package/skills/supabase-local-dev-loop/SKILL.md +272 -73
- package/skills/supabase-local-dev-loop/references/errors.md +11 -0
- package/skills/supabase-local-dev-loop/references/examples.md +21 -0
- package/skills/supabase-local-dev-loop/references/implementation.md +60 -0
- package/skills/supabase-migration-deep-dive/SKILL.md +338 -177
- package/skills/supabase-migration-deep-dive/references/backfill-versioning-rollback.md +258 -0
- package/skills/supabase-migration-deep-dive/references/errors.md +11 -0
- package/skills/supabase-migration-deep-dive/references/examples.md +12 -0
- package/skills/supabase-migration-deep-dive/references/implementation-plan.md +80 -0
- package/skills/supabase-migration-deep-dive/references/pre-migration-assessment.md +39 -0
- package/skills/supabase-multi-env-setup/SKILL.md +393 -152
- package/skills/supabase-multi-env-setup/references/configuration-structure.md +59 -0
- package/skills/supabase-multi-env-setup/references/errors.md +11 -0
- package/skills/supabase-multi-env-setup/references/examples.md +11 -0
- package/skills/supabase-observability/SKILL.md +318 -196
- package/skills/supabase-observability/references/alert-configuration.md +40 -0
- package/skills/supabase-observability/references/errors.md +11 -0
- package/skills/supabase-observability/references/examples.md +13 -0
- package/skills/supabase-observability/references/metrics-collection.md +65 -0
- package/skills/supabase-performance-tuning/SKILL.md +304 -160
- package/skills/supabase-performance-tuning/references/caching-strategy.md +49 -0
- package/skills/supabase-performance-tuning/references/errors.md +11 -0
- package/skills/supabase-performance-tuning/references/examples.md +13 -0
- package/skills/supabase-policy-guardrails/SKILL.md +248 -221
- package/skills/supabase-policy-guardrails/references/ci-cost-security.md +484 -0
- package/skills/supabase-policy-guardrails/references/errors.md +11 -0
- package/skills/supabase-policy-guardrails/references/eslint-rules.md +46 -0
- package/skills/supabase-policy-guardrails/references/examples.md +10 -0
- package/skills/supabase-prod-checklist/SKILL.md +474 -84
- package/skills/supabase-prod-checklist/references/errors.md +63 -0
- package/skills/supabase-prod-checklist/references/examples.md +153 -0
- package/skills/supabase-prod-checklist/references/implementation.md +113 -0
- package/skills/supabase-rate-limits/SKILL.md +311 -98
- package/skills/supabase-rate-limits/references/errors.md +11 -0
- package/skills/supabase-rate-limits/references/examples.md +46 -0
- package/skills/supabase-rate-limits/references/implementation.md +66 -0
- package/skills/supabase-reference-architecture/SKILL.md +249 -182
- package/skills/supabase-reference-architecture/references/errors.md +29 -0
- package/skills/supabase-reference-architecture/references/examples.md +116 -0
- package/skills/supabase-reference-architecture/references/key-components.md +244 -0
- package/skills/supabase-reference-architecture/references/project-structure.md +109 -0
- package/skills/supabase-reliability-patterns/SKILL.md +229 -234
- package/skills/supabase-reliability-patterns/references/circuit-breaker.md +36 -0
- package/skills/supabase-reliability-patterns/references/dead-letter-queue.md +48 -0
- package/skills/supabase-reliability-patterns/references/errors.md +11 -0
- package/skills/supabase-reliability-patterns/references/examples.md +11 -0
- package/skills/supabase-reliability-patterns/references/idempotency-keys.md +36 -0
- package/skills/supabase-reliability-patterns/references/offline-degradation-health-dualwrite.md +489 -0
- package/skills/supabase-schema-from-requirements/SKILL.md +373 -34
- package/skills/supabase-sdk-patterns/SKILL.md +388 -99
- package/skills/supabase-sdk-patterns/references/errors.md +11 -0
- package/skills/supabase-sdk-patterns/references/examples.md +45 -0
- package/skills/supabase-sdk-patterns/references/implementation.md +67 -0
- package/skills/supabase-security-basics/SKILL.md +282 -102
- package/skills/supabase-security-basics/references/errors.md +10 -0
- package/skills/supabase-security-basics/references/examples.md +70 -0
- package/skills/supabase-security-basics/references/implementation.md +39 -0
- package/skills/supabase-upgrade-migration/SKILL.md +248 -66
- package/skills/supabase-upgrade-migration/references/errors.md +10 -0
- package/skills/supabase-upgrade-migration/references/examples.md +51 -0
- package/skills/supabase-upgrade-migration/references/implementation.md +29 -0
- package/skills/supabase-webhooks-events/SKILL.md +412 -138
- package/skills/supabase-webhooks-events/references/errors.md +55 -0
- package/skills/supabase-webhooks-events/references/event-handler-pattern.md +106 -0
- package/skills/supabase-webhooks-events/references/examples.md +133 -0
- package/skills/supabase-webhooks-events/references/signature-verification.md +165 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Data Backfill, Versioning, and Rollback
|
|
2
|
+
|
|
3
|
+
Backfill data in batches to avoid overwhelming the database, track schema versions, and plan rollback strategies for failed migrations.
|
|
4
|
+
|
|
5
|
+
**Batch data backfill from the SDK:**
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { createClient } from '@supabase/supabase-js';
|
|
9
|
+
|
|
10
|
+
const supabase = createClient(
|
|
11
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
12
|
+
process.env.SUPABASE_SERVICE_ROLE_KEY!,
|
|
13
|
+
{ auth: { autoRefreshToken: false, persistSession: false } }
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
// Backfill a new column in batches (avoids long-running transactions)
|
|
17
|
+
async function backfillColumn(
|
|
18
|
+
table: string,
|
|
19
|
+
column: string,
|
|
20
|
+
computeValue: (row: any) => any,
|
|
21
|
+
batchSize = 500
|
|
22
|
+
) {
|
|
23
|
+
let processed = 0;
|
|
24
|
+
let lastId: string | null = null;
|
|
25
|
+
|
|
26
|
+
while (true) {
|
|
27
|
+
// Fetch a batch of rows that need backfilling
|
|
28
|
+
let query = supabase
|
|
29
|
+
.from(table)
|
|
30
|
+
.select('*')
|
|
31
|
+
.is(column, null)
|
|
32
|
+
.order('id', { ascending: true })
|
|
33
|
+
.limit(batchSize);
|
|
34
|
+
|
|
35
|
+
if (lastId) {
|
|
36
|
+
query = query.gt('id', lastId);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { data: rows, error } = await query;
|
|
40
|
+
if (error) throw error;
|
|
41
|
+
if (!rows || rows.length === 0) break;
|
|
42
|
+
|
|
43
|
+
// Update each row with the computed value
|
|
44
|
+
for (const row of rows) {
|
|
45
|
+
const newValue = computeValue(row);
|
|
46
|
+
const { error: updateError } = await supabase
|
|
47
|
+
.from(table)
|
|
48
|
+
.update({ [column]: newValue })
|
|
49
|
+
.eq('id', row.id);
|
|
50
|
+
|
|
51
|
+
if (updateError) {
|
|
52
|
+
console.error(`Failed to update ${row.id}:`, updateError.message);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
lastId = rows[rows.length - 1].id;
|
|
57
|
+
processed += rows.length;
|
|
58
|
+
console.log(`Backfilled ${processed} rows...`);
|
|
59
|
+
|
|
60
|
+
// Brief pause to avoid overwhelming the database
|
|
61
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`Backfill complete: ${processed} rows updated`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Example: backfill a slug column from name
|
|
68
|
+
await backfillColumn('projects', 'slug', (row) =>
|
|
69
|
+
row.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')
|
|
70
|
+
);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Schema versioning — track what's deployed where:**
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Check migration status on each environment
|
|
77
|
+
npx supabase link --project-ref <staging-ref>
|
|
78
|
+
npx supabase migration list
|
|
79
|
+
|
|
80
|
+
# Compare local migrations with remote
|
|
81
|
+
npx supabase db diff --linked
|
|
82
|
+
|
|
83
|
+
# Generate a diff between local and remote schemas
|
|
84
|
+
npx supabase db diff --linked --schema public > schema-diff.sql
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```sql
|
|
88
|
+
-- Query the migration history directly
|
|
89
|
+
SELECT version, name, statements_applied_at
|
|
90
|
+
FROM supabase_migrations.schema_migrations
|
|
91
|
+
ORDER BY version DESC
|
|
92
|
+
LIMIT 20;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Rollback strategies:**
|
|
96
|
+
|
|
97
|
+
```sql
|
|
98
|
+
-- Strategy 1: Write a compensating migration
|
|
99
|
+
-- supabase/migrations/20260327000000_rollback_status_column.sql
|
|
100
|
+
|
|
101
|
+
-- Reverse the previous migration
|
|
102
|
+
DROP INDEX IF EXISTS idx_orders_status;
|
|
103
|
+
ALTER TABLE public.orders DROP COLUMN IF EXISTS status;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Strategy 2: Repair migration history (if migration partially failed)
|
|
108
|
+
# Mark a migration as rolled back in the tracking table
|
|
109
|
+
npx supabase migration repair --status reverted 20260326000000
|
|
110
|
+
|
|
111
|
+
# Then re-apply after fixing
|
|
112
|
+
npx supabase db push
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// Strategy 3: Feature-flag a schema change
|
|
117
|
+
import { createClient } from '@supabase/supabase-js';
|
|
118
|
+
|
|
119
|
+
const supabase = createClient(url, anonKey);
|
|
120
|
+
|
|
121
|
+
// Use old or new column based on feature flag
|
|
122
|
+
async function getOrderStatus(orderId: string) {
|
|
123
|
+
const useNewSchema = process.env.USE_NEW_STATUS_COLUMN === 'true';
|
|
124
|
+
|
|
125
|
+
const { data, error } = await supabase
|
|
126
|
+
.from('orders')
|
|
127
|
+
.select(useNewSchema ? 'status_v2' : 'status')
|
|
128
|
+
.eq('id', orderId)
|
|
129
|
+
.single();
|
|
130
|
+
|
|
131
|
+
if (error) throw error;
|
|
132
|
+
return useNewSchema ? data.status_v2 : data.status;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Regenerate types after migration:**
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# From local development database (recommended)
|
|
140
|
+
npx supabase gen types typescript --local > lib/database.types.ts
|
|
141
|
+
|
|
142
|
+
# From linked remote project
|
|
143
|
+
npx supabase gen types typescript --linked > lib/database.types.ts
|
|
144
|
+
|
|
145
|
+
# Verify types compile
|
|
146
|
+
npx tsc --noEmit
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Output
|
|
150
|
+
|
|
151
|
+
After completing this skill, you will have:
|
|
152
|
+
|
|
153
|
+
- **Migration creation workflow** — `npx supabase migration new` with descriptive SQL files and local testing
|
|
154
|
+
- **Zero-downtime patterns** — safe column additions, two-phase renames, concurrent index creation
|
|
155
|
+
- **Batch backfill** — SDK-based row-by-row updates with progress logging and rate limiting
|
|
156
|
+
- **Schema versioning** — `supabase migration list` and `db diff` for comparing environments
|
|
157
|
+
- **Rollback strategies** — compensating migrations, `migration repair`, and feature-flagged schema changes
|
|
158
|
+
- **Type regeneration** — `supabase gen types typescript` after every schema change
|
|
159
|
+
- **Migration promotion** — `db push` workflow from local to staging to production
|
|
160
|
+
|
|
161
|
+
## Error Handling
|
|
162
|
+
|
|
163
|
+
| Error | Cause | Solution |
|
|
164
|
+
|-------|-------|----------|
|
|
165
|
+
| `migration has already been applied` | Re-running existing migration | Use `supabase migration list` to check status; never modify applied migrations |
|
|
166
|
+
| `cannot run inside a transaction block` | `CREATE INDEX CONCURRENTLY` in transaction | Add `-- supabase:disable-transaction` comment at top of migration file |
|
|
167
|
+
| `column does not exist` after migration | Migration not applied or types stale | Run `supabase db push` then `supabase gen types typescript` |
|
|
168
|
+
| `deadlock detected` during backfill | Concurrent updates on same rows | Reduce batch size; add retry logic with exponential backoff |
|
|
169
|
+
| `statement timeout` on large table | Migration takes longer than timeout | Increase `statement_timeout` in migration: `SET statement_timeout = '300s';` |
|
|
170
|
+
| `migration repair` failed | Wrong version number | Use exact version from `supabase migration list` (the timestamp prefix) |
|
|
171
|
+
| `db diff` shows unexpected changes | Schema drift from manual SQL Editor changes | Run `supabase db pull` to capture manual changes as a migration |
|
|
172
|
+
| Type mismatch after migration | Generated types don't match new schema | Delete `database.types.ts` and regenerate from `--local` or `--linked` |
|
|
173
|
+
|
|
174
|
+
## Examples
|
|
175
|
+
|
|
176
|
+
**Example 1 — Complete migration workflow:**
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# 1. Create migration
|
|
180
|
+
npx supabase migration new add_tags_to_projects
|
|
181
|
+
|
|
182
|
+
# 2. Write SQL
|
|
183
|
+
cat > supabase/migrations/20260322150000_add_tags_to_projects.sql << 'SQL'
|
|
184
|
+
ALTER TABLE public.projects ADD COLUMN tags text[] DEFAULT '{}';
|
|
185
|
+
CREATE INDEX idx_projects_tags ON public.projects USING GIN(tags);
|
|
186
|
+
SQL
|
|
187
|
+
|
|
188
|
+
# 3. Test locally
|
|
189
|
+
npx supabase db reset
|
|
190
|
+
npx supabase gen types typescript --local > lib/database.types.ts
|
|
191
|
+
|
|
192
|
+
# 4. Push to staging
|
|
193
|
+
npx supabase link --project-ref <staging-ref>
|
|
194
|
+
npx supabase db push
|
|
195
|
+
|
|
196
|
+
# 5. Push to production
|
|
197
|
+
npx supabase link --project-ref <prod-ref>
|
|
198
|
+
npx supabase db push
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Example 2 — Backfill with progress tracking:**
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { createClient } from '@supabase/supabase-js';
|
|
205
|
+
|
|
206
|
+
const supabase = createClient(url, serviceRoleKey, {
|
|
207
|
+
auth: { autoRefreshToken: false, persistSession: false },
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Backfill default tags for existing projects
|
|
211
|
+
const { count } = await supabase
|
|
212
|
+
.from('projects')
|
|
213
|
+
.select('*', { count: 'exact', head: true })
|
|
214
|
+
.is('tags', null);
|
|
215
|
+
|
|
216
|
+
console.log(`${count} projects need backfill`);
|
|
217
|
+
|
|
218
|
+
await backfillColumn('projects', 'tags', (row) => {
|
|
219
|
+
// Derive tags from project name and description
|
|
220
|
+
const tags: string[] = [];
|
|
221
|
+
if (row.name?.includes('API')) tags.push('api');
|
|
222
|
+
if (row.name?.includes('Web')) tags.push('web');
|
|
223
|
+
return tags.length > 0 ? tags : ['untagged'];
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Example 3 — Safe enum migration:**
|
|
228
|
+
|
|
229
|
+
```sql
|
|
230
|
+
-- supabase/migrations/20260328000000_add_order_status_enum.sql
|
|
231
|
+
|
|
232
|
+
-- DON'T: ALTER TYPE with new values inside a transaction
|
|
233
|
+
-- DO: Use text with CHECK constraint instead
|
|
234
|
+
|
|
235
|
+
ALTER TABLE public.orders
|
|
236
|
+
ADD CONSTRAINT chk_order_status
|
|
237
|
+
CHECK (status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled'));
|
|
238
|
+
|
|
239
|
+
-- To add a new status later, just drop and recreate the constraint:
|
|
240
|
+
-- ALTER TABLE public.orders DROP CONSTRAINT chk_order_status;
|
|
241
|
+
-- ALTER TABLE public.orders ADD CONSTRAINT chk_order_status
|
|
242
|
+
-- CHECK (status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded'));
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Resources
|
|
246
|
+
|
|
247
|
+
- [Database Migrations — Supabase Docs](https://supabase.com/docs/guides/deployment/database-migrations)
|
|
248
|
+
- [Supabase CLI Migration Commands](https://supabase.com/docs/reference/cli/supabase-migration)
|
|
249
|
+
- [supabase db push — Supabase Docs](https://supabase.com/docs/reference/cli/supabase-db-push)
|
|
250
|
+
- [supabase gen types — Supabase Docs](https://supabase.com/docs/reference/cli/supabase-gen-types)
|
|
251
|
+
- [Zero-Downtime PostgreSQL Migrations](https://www.postgresql.org/docs/current/sql-altertable.html)
|
|
252
|
+
- [supabase db diff — Supabase Docs](https://supabase.com/docs/reference/cli/supabase-db-diff)
|
|
253
|
+
|
|
254
|
+
## Next Steps
|
|
255
|
+
|
|
256
|
+
- For advanced troubleshooting after migrations, see `supabase-advanced-troubleshooting`
|
|
257
|
+
- For multi-environment migration promotion, see `supabase-multi-env-setup`
|
|
258
|
+
- For performance tuning after schema changes, see `supabase-performance-tuning`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Error Handling Reference
|
|
2
|
+
|
|
3
|
+
| Issue | Cause | Solution |
|
|
4
|
+
|-------|-------|----------|
|
|
5
|
+
| Data mismatch | Transform errors | Validate transform logic |
|
|
6
|
+
| Performance drop | No caching | Add caching layer |
|
|
7
|
+
| Rollback triggered | Errors spiked | Reduce traffic percentage |
|
|
8
|
+
| Validation failed | Missing data | Check batch processing |
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Examples
|
|
2
|
+
|
|
3
|
+
### Quick Migration Status
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const status = await validateSupabaseMigration();
|
|
7
|
+
console.log(`Migration ${status.passed ? 'PASSED' : 'FAILED'}`);
|
|
8
|
+
status.checks.forEach(c => console.log(` ${c.name}: ${c.result.success}`));
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
*[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Implementation Plan
|
|
2
|
+
|
|
3
|
+
## Implementation Plan
|
|
4
|
+
|
|
5
|
+
### Phase 1: Setup (Week 1-2)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install Supabase SDK
|
|
9
|
+
npm install @supabase/supabase-js
|
|
10
|
+
|
|
11
|
+
# Configure credentials
|
|
12
|
+
cp .env.example .env.supabase
|
|
13
|
+
# Edit with new credentials
|
|
14
|
+
|
|
15
|
+
# Verify connectivity
|
|
16
|
+
node -e "require('@supabase/supabase-js').ping()"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Phase 2: Adapter Layer (Week 3-4)
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// src/adapters/supabase.ts
|
|
23
|
+
interface ServiceAdapter {
|
|
24
|
+
create(data: CreateInput): Promise<Resource>;
|
|
25
|
+
read(id: string): Promise<Resource>;
|
|
26
|
+
update(id: string, data: UpdateInput): Promise<Resource>;
|
|
27
|
+
delete(id: string): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class SupabaseAdapter implements ServiceAdapter {
|
|
31
|
+
async create(data: CreateInput): Promise<Resource> {
|
|
32
|
+
const supabaseData = this.transform(data);
|
|
33
|
+
return supabaseClient.create(supabaseData);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private transform(data: CreateInput): SupabaseInput {
|
|
37
|
+
// Map from old format to Supabase format
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Phase 3: Data Migration (Week 5-6)
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
async function migrateSupabaseData(): Promise<MigrationResult> {
|
|
46
|
+
const batchSize = 100;
|
|
47
|
+
let processed = 0;
|
|
48
|
+
let errors: MigrationError[] = [];
|
|
49
|
+
|
|
50
|
+
for await (const batch of oldSystem.iterateBatches(batchSize)) {
|
|
51
|
+
try {
|
|
52
|
+
const transformed = batch.map(transform);
|
|
53
|
+
await supabaseClient.batchCreate(transformed);
|
|
54
|
+
processed += batch.length;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
errors.push({ batch, error });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Progress update
|
|
60
|
+
console.log(`Migrated ${processed} records`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { processed, errors };
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Phase 4: Traffic Shift (Week 7-8)
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// Feature flag controlled traffic split
|
|
71
|
+
function getServiceAdapter(): ServiceAdapter {
|
|
72
|
+
const supabasePercentage = getFeatureFlag('supabase_migration_percentage');
|
|
73
|
+
|
|
74
|
+
if (Math.random() * 100 < supabasePercentage) {
|
|
75
|
+
return new SupabaseAdapter();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return new LegacyAdapter();
|
|
79
|
+
}
|
|
80
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Pre-Migration Assessment
|
|
2
|
+
|
|
3
|
+
## Pre-Migration Assessment
|
|
4
|
+
|
|
5
|
+
### Step 1: Current State Analysis
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Document current implementation
|
|
9
|
+
find . -name "*.ts" -o -name "*.py" | xargs grep -l "supabase" > supabase-files.txt
|
|
10
|
+
|
|
11
|
+
# Count integration points
|
|
12
|
+
wc -l supabase-files.txt
|
|
13
|
+
|
|
14
|
+
# Identify dependencies
|
|
15
|
+
npm list | grep supabase
|
|
16
|
+
pip freeze | grep supabase
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Step 2: Data Inventory
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
interface MigrationInventory {
|
|
23
|
+
dataTypes: string[];
|
|
24
|
+
recordCounts: Record<string, number>;
|
|
25
|
+
dependencies: string[];
|
|
26
|
+
integrationPoints: string[];
|
|
27
|
+
customizations: string[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function assessSupabaseMigration(): Promise<MigrationInventory> {
|
|
31
|
+
return {
|
|
32
|
+
dataTypes: await getDataTypes(),
|
|
33
|
+
recordCounts: await getRecordCounts(),
|
|
34
|
+
dependencies: await analyzeDependencies(),
|
|
35
|
+
integrationPoints: await findIntegrationPoints(),
|
|
36
|
+
customizations: await documentCustomizations(),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
```
|