@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.
Files changed (35) hide show
  1. package/.claude-plugin/plugin.json +17 -0
  2. package/000-docs/001-BL-LICN-license.txt +3 -0
  3. package/LICENSE +21 -0
  4. package/README.md +69 -0
  5. package/package.json +43 -0
  6. package/skills/supabase-advanced-troubleshooting/SKILL.md +261 -0
  7. package/skills/supabase-architecture-variants/SKILL.md +284 -0
  8. package/skills/supabase-auth-storage-realtime-core/SKILL.md +73 -0
  9. package/skills/supabase-ci-integration/SKILL.md +124 -0
  10. package/skills/supabase-common-errors/SKILL.md +109 -0
  11. package/skills/supabase-cost-tuning/SKILL.md +201 -0
  12. package/skills/supabase-data-handling/SKILL.md +220 -0
  13. package/skills/supabase-debug-bundle/SKILL.md +111 -0
  14. package/skills/supabase-deploy-integration/SKILL.md +209 -0
  15. package/skills/supabase-enterprise-rbac/SKILL.md +222 -0
  16. package/skills/supabase-hello-world/SKILL.md +96 -0
  17. package/skills/supabase-incident-runbook/SKILL.md +203 -0
  18. package/skills/supabase-install-auth/SKILL.md +90 -0
  19. package/skills/supabase-known-pitfalls/SKILL.md +334 -0
  20. package/skills/supabase-load-scale/SKILL.md +274 -0
  21. package/skills/supabase-local-dev-loop/SKILL.md +117 -0
  22. package/skills/supabase-migration-deep-dive/SKILL.md +244 -0
  23. package/skills/supabase-multi-env-setup/SKILL.md +222 -0
  24. package/skills/supabase-observability/SKILL.md +250 -0
  25. package/skills/supabase-performance-tuning/SKILL.md +214 -0
  26. package/skills/supabase-policy-guardrails/SKILL.md +257 -0
  27. package/skills/supabase-prod-checklist/SKILL.md +119 -0
  28. package/skills/supabase-rate-limits/SKILL.md +149 -0
  29. package/skills/supabase-reference-architecture/SKILL.md +238 -0
  30. package/skills/supabase-reliability-patterns/SKILL.md +290 -0
  31. package/skills/supabase-schema-from-requirements/SKILL.md +71 -0
  32. package/skills/supabase-sdk-patterns/SKILL.md +147 -0
  33. package/skills/supabase-security-basics/SKILL.md +140 -0
  34. package/skills/supabase-upgrade-migration/SKILL.md +112 -0
  35. package/skills/supabase-webhooks-events/SKILL.md +199 -0
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: supabase-rate-limits
3
+ description: |
4
+ Implement Supabase rate limiting, backoff, and idempotency patterns.
5
+ Use when handling rate limit errors, implementing retry logic,
6
+ or optimizing API request throughput for Supabase.
7
+ Trigger with phrases like "supabase rate limit", "supabase throttling",
8
+ "supabase 429", "supabase retry", "supabase backoff".
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 Rate Limits
16
+
17
+ ## Overview
18
+ Handle Supabase rate limits gracefully with exponential backoff and idempotency.
19
+
20
+ ## Prerequisites
21
+ - Supabase SDK installed
22
+ - Understanding of async/await patterns
23
+ - Access to rate limit headers
24
+
25
+ ## Instructions
26
+
27
+ ### Step 1: Understand Rate Limit Tiers
28
+
29
+ | Tier | Requests/min | Requests/day | Burst |
30
+ |------|-------------|--------------|-------|
31
+ | Free | 500 | 50,000 | 10 |
32
+ | Pro | 5,000 | 1,000,000 | 50 |
33
+ | Enterprise | Unlimited | Unlimited | 200 |
34
+
35
+ ### Step 2: Implement Exponential Backoff with Jitter
36
+
37
+ ```typescript
38
+ async function withExponentialBackoff<T>(
39
+ operation: () => Promise<T>,
40
+ config = { maxRetries: 5, baseDelayMs: 1000, maxDelayMs: 32000, jitterMs: 500 }
41
+ ): Promise<T> {
42
+ for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
43
+ try {
44
+ return await operation();
45
+ } catch (error: any) {
46
+ if (attempt === config.maxRetries) throw error;
47
+ const status = error.status || error.response?.status;
48
+ if (status !== 429 && (status < 500 || status >= 600)) throw error;
49
+
50
+ // Exponential delay with jitter to prevent thundering herd
51
+ const exponentialDelay = config.baseDelayMs * Math.pow(2, attempt);
52
+ const jitter = Math.random() * config.jitterMs;
53
+ const delay = Math.min(exponentialDelay + jitter, config.maxDelayMs);
54
+
55
+ console.log(`Rate limited. Retrying in ${delay.toFixed(0)}ms...`);
56
+ await new Promise(r => setTimeout(r, delay));
57
+ }
58
+ }
59
+ throw new Error('Unreachable');
60
+ }
61
+ ```
62
+
63
+ ### Step 3: Add Idempotency Keys
64
+
65
+ ```typescript
66
+ import { v4 as uuidv4 } from 'uuid';
67
+ import crypto from 'crypto';
68
+
69
+ // Generate deterministic key from operation params (for safe retries)
70
+ function generateIdempotencyKey(operation: string, params: Record<string, any>): string {
71
+ const data = JSON.stringify({ operation, params });
72
+ return crypto.createHash('sha256').update(data).digest('hex');
73
+ }
74
+
75
+ async function idempotentRequest<T>(
76
+ client: SupabaseClient,
77
+ params: Record<string, any>,
78
+ idempotencyKey?: string // Pass existing key for retries
79
+ ): Promise<T> {
80
+ // Use provided key (for retries) or generate deterministic key from params
81
+ const key = idempotencyKey || generateIdempotencyKey(params.method || 'POST', params);
82
+ return client.request({
83
+ ...params,
84
+ headers: { 'Idempotency-Key': key, ...params.headers },
85
+ });
86
+ }
87
+ ```
88
+
89
+ ## Output
90
+ - Reliable API calls with automatic retry
91
+ - Idempotent requests preventing duplicates
92
+ - Rate limit headers properly handled
93
+
94
+ ## Error Handling
95
+ | Header | Description | Action |
96
+ |--------|-------------|--------|
97
+ | X-RateLimit-Limit | Max requests | Monitor usage |
98
+ | X-RateLimit-Remaining | Remaining requests | Throttle if low |
99
+ | X-RateLimit-Reset | Reset timestamp | Wait until reset |
100
+ | Retry-After | Seconds to wait | Honor this value |
101
+
102
+ ## Examples
103
+
104
+ ### Queue-Based Rate Limiting
105
+ ```typescript
106
+ import PQueue from 'p-queue';
107
+
108
+ const queue = new PQueue({
109
+ concurrency: 5,
110
+ interval: 1000,
111
+ intervalCap: 10,
112
+ });
113
+
114
+ async function queuedRequest<T>(operation: () => Promise<T>): Promise<T> {
115
+ return queue.add(operation);
116
+ }
117
+ ```
118
+
119
+ ### Monitor Rate Limit Usage
120
+ ```typescript
121
+ class RateLimitMonitor {
122
+ private remaining: number = 60;
123
+ private resetAt: Date = new Date();
124
+
125
+ updateFromHeaders(headers: Headers) {
126
+ this.remaining = parseInt(headers.get('X-RateLimit-Remaining') || '60');
127
+ const resetTimestamp = headers.get('X-RateLimit-Reset');
128
+ if (resetTimestamp) {
129
+ this.resetAt = new Date(parseInt(resetTimestamp) * 1000);
130
+ }
131
+ }
132
+
133
+ shouldThrottle(): boolean {
134
+ // Only throttle if low remaining AND reset hasn't happened yet
135
+ return this.remaining < 5 && new Date() < this.resetAt;
136
+ }
137
+
138
+ getWaitTime(): number {
139
+ return Math.max(0, this.resetAt.getTime() - Date.now());
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## Resources
145
+ - [Supabase Rate Limits](https://supabase.com/docs/rate-limits)
146
+ - [p-queue Documentation](https://github.com/sindresorhus/p-queue)
147
+
148
+ ## Next Steps
149
+ For security configuration, see `supabase-security-basics`.
@@ -0,0 +1,238 @@
1
+ ---
2
+ name: supabase-reference-architecture
3
+ description: |
4
+ Implement Supabase reference architecture with best-practice project layout.
5
+ Use when designing new Supabase integrations, reviewing project structure,
6
+ or establishing architecture standards for Supabase applications.
7
+ Trigger with phrases like "supabase architecture", "supabase best practices",
8
+ "supabase project structure", "how to organize supabase", "supabase layout".
9
+ allowed-tools: Read, Grep
10
+ version: 1.0.0
11
+ license: MIT
12
+ author: Jeremy Longshore <jeremy@intentsolutions.io>
13
+ ---
14
+
15
+ # Supabase Reference Architecture
16
+
17
+ ## Overview
18
+ Production-ready architecture patterns for Supabase integrations.
19
+
20
+ ## Prerequisites
21
+ - Understanding of layered architecture
22
+ - Supabase SDK knowledge
23
+ - TypeScript project setup
24
+ - Testing framework configured
25
+
26
+ ## Project Structure
27
+
28
+ ```
29
+ my-supabase-project/
30
+ ├── src/
31
+ │ ├── supabase/
32
+ │ │ ├── client.ts # Singleton client wrapper
33
+ │ │ ├── config.ts # Environment configuration
34
+ │ │ ├── types.ts # TypeScript types
35
+ │ │ ├── errors.ts # Custom error classes
36
+ │ │ └── handlers/
37
+ │ │ ├── webhooks.ts # Webhook handlers
38
+ │ │ └── events.ts # Event processing
39
+ │ ├── services/
40
+ │ │ └── supabase/
41
+ │ │ ├── index.ts # Service facade
42
+ │ │ ├── sync.ts # Data synchronization
43
+ │ │ └── cache.ts # Caching layer
44
+ │ ├── api/
45
+ │ │ └── supabase/
46
+ │ │ └── webhook.ts # Webhook endpoint
47
+ │ └── jobs/
48
+ │ └── supabase/
49
+ │ └── sync.ts # Background sync job
50
+ ├── tests/
51
+ │ ├── unit/
52
+ │ │ └── supabase/
53
+ │ └── integration/
54
+ │ └── supabase/
55
+ ├── config/
56
+ │ ├── supabase.development.json
57
+ │ ├── supabase.staging.json
58
+ │ └── supabase.production.json
59
+ └── docs/
60
+ └── supabase/
61
+ ├── SETUP.md
62
+ └── RUNBOOK.md
63
+ ```
64
+
65
+ ## Layer Architecture
66
+
67
+ ```
68
+ ┌─────────────────────────────────────────┐
69
+ │ API Layer │
70
+ │ (Controllers, Routes, Webhooks) │
71
+ ├─────────────────────────────────────────┤
72
+ │ Service Layer │
73
+ │ (Business Logic, Orchestration) │
74
+ ├─────────────────────────────────────────┤
75
+ │ Supabase Layer │
76
+ │ (Client, Types, Error Handling) │
77
+ ├─────────────────────────────────────────┤
78
+ │ Infrastructure Layer │
79
+ │ (Cache, Queue, Monitoring) │
80
+ └─────────────────────────────────────────┘
81
+ ```
82
+
83
+ ## Key Components
84
+
85
+ ### Step 1: Client Wrapper
86
+ ```typescript
87
+ // src/supabase/client.ts
88
+ export class SupabaseService {
89
+ private client: SupabaseClient;
90
+ private cache: Cache;
91
+ private monitor: Monitor;
92
+
93
+ constructor(config: SupabaseConfig) {
94
+ this.client = new SupabaseClient(config);
95
+ this.cache = new Cache(config.cacheOptions);
96
+ this.monitor = new Monitor('supabase');
97
+ }
98
+
99
+ async get(id: string): Promise<Resource> {
100
+ return this.cache.getOrFetch(id, () =>
101
+ this.monitor.track('get', () => this.client.get(id))
102
+ );
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Step 2: Error Boundary
108
+ ```typescript
109
+ // src/supabase/errors.ts
110
+ export class SupabaseServiceError extends Error {
111
+ constructor(
112
+ message: string,
113
+ public readonly code: string,
114
+ public readonly retryable: boolean,
115
+ public readonly originalError?: Error
116
+ ) {
117
+ super(message);
118
+ this.name = 'SupabaseServiceError';
119
+ }
120
+ }
121
+
122
+ export function wrapSupabaseError(error: unknown): SupabaseServiceError {
123
+ // Transform SDK errors to application errors
124
+ }
125
+ ```
126
+
127
+ ### Step 3: Health Check
128
+ ```typescript
129
+ // src/supabase/health.ts
130
+ export async function checkSupabaseHealth(): Promise<HealthStatus> {
131
+ try {
132
+ const start = Date.now();
133
+ await supabaseClient.ping();
134
+ return {
135
+ status: 'healthy',
136
+ latencyMs: Date.now() - start,
137
+ };
138
+ } catch (error) {
139
+ return { status: 'unhealthy', error: error.message };
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## Data Flow Diagram
145
+
146
+ ```
147
+ User Request
148
+
149
+
150
+ ┌─────────────┐
151
+ │ API │
152
+ │ Gateway │
153
+ └──────┬──────┘
154
+
155
+
156
+ ┌─────────────┐ ┌─────────────┐
157
+ │ Service │───▶│ Cache │
158
+ │ Layer │ │ (Redis) │
159
+ └──────┬──────┘ └─────────────┘
160
+
161
+
162
+ ┌─────────────┐
163
+ │ Supabase │
164
+ │ Client │
165
+ └──────┬──────┘
166
+
167
+
168
+ ┌─────────────┐
169
+ │ Supabase │
170
+ │ API │
171
+ └─────────────┘
172
+ ```
173
+
174
+ ## Configuration Management
175
+
176
+ ```typescript
177
+ // config/supabase.ts
178
+ export interface SupabaseConfig {
179
+ apiKey: string;
180
+ environment: 'development' | 'staging' | 'production';
181
+ timeout: number;
182
+ retries: number;
183
+ cache: {
184
+ enabled: boolean;
185
+ ttlSeconds: number;
186
+ };
187
+ }
188
+
189
+ export function loadSupabaseConfig(): SupabaseConfig {
190
+ const env = process.env.NODE_ENV || 'development';
191
+ return require(`./supabase.${env}.json`);
192
+ }
193
+ ```
194
+
195
+ ## Instructions
196
+
197
+ ### Step 1: Create Directory Structure
198
+ Set up the project layout following the reference structure above.
199
+
200
+ ### Step 2: Implement Client Wrapper
201
+ Create the singleton client with caching and monitoring.
202
+
203
+ ### Step 3: Add Error Handling
204
+ Implement custom error classes for Supabase operations.
205
+
206
+ ### Step 4: Configure Health Checks
207
+ Add health check endpoint for Supabase connectivity.
208
+
209
+ ## Output
210
+ - Structured project layout
211
+ - Client wrapper with caching
212
+ - Error boundary implemented
213
+ - Health checks configured
214
+
215
+ ## Error Handling
216
+ | Issue | Cause | Solution |
217
+ |-------|-------|----------|
218
+ | Circular dependencies | Wrong layering | Separate concerns by layer |
219
+ | Config not loading | Wrong paths | Verify config file locations |
220
+ | Type errors | Missing types | Add Supabase types |
221
+ | Test isolation | Shared state | Use dependency injection |
222
+
223
+ ## Examples
224
+
225
+ ### Quick Setup Script
226
+ ```bash
227
+ # Create reference structure
228
+ mkdir -p src/supabase/{handlers} src/services/supabase src/api/supabase
229
+ touch src/supabase/{client,config,types,errors}.ts
230
+ touch src/services/supabase/{index,sync,cache}.ts
231
+ ```
232
+
233
+ ## Resources
234
+ - [Supabase SDK Documentation](https://supabase.com/docs/sdk)
235
+ - [Supabase Best Practices](https://supabase.com/docs/best-practices)
236
+
237
+ ## Flagship Skills
238
+ For multi-environment setup, see `supabase-multi-env-setup`.
@@ -0,0 +1,290 @@
1
+ ---
2
+ name: supabase-reliability-patterns
3
+ description: |
4
+ Implement Supabase reliability patterns including circuit breakers, idempotency, and graceful degradation.
5
+ Use when building fault-tolerant Supabase integrations, implementing retry strategies,
6
+ or adding resilience to production Supabase services.
7
+ Trigger with phrases like "supabase reliability", "supabase circuit breaker",
8
+ "supabase idempotent", "supabase resilience", "supabase fallback", "supabase bulkhead".
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 Reliability Patterns
16
+
17
+ ## Overview
18
+ Production-grade reliability patterns for Supabase integrations.
19
+
20
+ ## Prerequisites
21
+ - Understanding of circuit breaker pattern
22
+ - opossum or similar library installed
23
+ - Queue infrastructure for DLQ
24
+ - Caching layer for fallbacks
25
+
26
+ ## Circuit Breaker
27
+
28
+ ```typescript
29
+ import CircuitBreaker from 'opossum';
30
+
31
+ const supabaseBreaker = new CircuitBreaker(
32
+ async (operation: () => Promise<any>) => operation(),
33
+ {
34
+ timeout: 30000,
35
+ errorThresholdPercentage: 50,
36
+ resetTimeout: 30000,
37
+ volumeThreshold: 10,
38
+ }
39
+ );
40
+
41
+ // Events
42
+ supabaseBreaker.on('open', () => {
43
+ console.warn('Supabase circuit OPEN - requests failing fast');
44
+ alertOps('Supabase circuit breaker opened');
45
+ });
46
+
47
+ supabaseBreaker.on('halfOpen', () => {
48
+ console.info('Supabase circuit HALF-OPEN - testing recovery');
49
+ });
50
+
51
+ supabaseBreaker.on('close', () => {
52
+ console.info('Supabase circuit CLOSED - normal operation');
53
+ });
54
+
55
+ // Usage
56
+ async function safeSupabaseCall<T>(fn: () => Promise<T>): Promise<T> {
57
+ return supabaseBreaker.fire(fn);
58
+ }
59
+ ```
60
+
61
+ ## Idempotency Keys
62
+
63
+ ```typescript
64
+ import { v4 as uuidv4 } from 'uuid';
65
+ import crypto from 'crypto';
66
+
67
+ // Generate deterministic idempotency key from input
68
+ function generateIdempotencyKey(
69
+ operation: string,
70
+ params: Record<string, any>
71
+ ): string {
72
+ const data = JSON.stringify({ operation, params });
73
+ return crypto.createHash('sha256').update(data).digest('hex');
74
+ }
75
+
76
+ // Or use random key with storage
77
+ class IdempotencyManager {
78
+ private store: Map<string, { key: string; expiresAt: Date }> = new Map();
79
+
80
+ getOrCreate(operationId: string): string {
81
+ const existing = this.store.get(operationId);
82
+ if (existing && existing.expiresAt > new Date()) {
83
+ return existing.key;
84
+ }
85
+
86
+ const key = uuidv4();
87
+ this.store.set(operationId, {
88
+ key,
89
+ expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
90
+ });
91
+ return key;
92
+ }
93
+ }
94
+ ```
95
+
96
+ ## Bulkhead Pattern
97
+
98
+ ```typescript
99
+ import PQueue from 'p-queue';
100
+
101
+ // Separate queues for different operations
102
+ const supabaseQueues = {
103
+ critical: new PQueue({ concurrency: 10 }),
104
+ normal: new PQueue({ concurrency: 5 }),
105
+ bulk: new PQueue({ concurrency: 2 }),
106
+ };
107
+
108
+ async function prioritizedSupabaseCall<T>(
109
+ priority: 'critical' | 'normal' | 'bulk',
110
+ fn: () => Promise<T>
111
+ ): Promise<T> {
112
+ return supabaseQueues[priority].add(fn);
113
+ }
114
+
115
+ // Usage
116
+ await prioritizedSupabaseCall('critical', () =>
117
+ supabaseClient.processPayment(order)
118
+ );
119
+
120
+ await prioritizedSupabaseCall('bulk', () =>
121
+ supabaseClient.syncCatalog(products)
122
+ );
123
+ ```
124
+
125
+ ## Timeout Hierarchy
126
+
127
+ ```typescript
128
+ const TIMEOUT_CONFIG = {
129
+ connect: 5000, // Initial connection
130
+ request: 30000, // Standard requests
131
+ upload: 120000, // File uploads
132
+ longPoll: 300000, // Webhook long-polling
133
+ };
134
+
135
+ async function timedoutSupabaseCall<T>(
136
+ operation: 'connect' | 'request' | 'upload' | 'longPoll',
137
+ fn: () => Promise<T>
138
+ ): Promise<T> {
139
+ const timeout = TIMEOUT_CONFIG[operation];
140
+
141
+ return Promise.race([
142
+ fn(),
143
+ new Promise<never>((_, reject) =>
144
+ setTimeout(() => reject(new Error(`Supabase ${operation} timeout`)), timeout)
145
+ ),
146
+ ]);
147
+ }
148
+ ```
149
+
150
+ ## Graceful Degradation
151
+
152
+ ```typescript
153
+ interface SupabaseFallback {
154
+ enabled: boolean;
155
+ data: any;
156
+ staleness: 'fresh' | 'stale' | 'very_stale';
157
+ }
158
+
159
+ async function withSupabaseFallback<T>(
160
+ fn: () => Promise<T>,
161
+ fallbackFn: () => Promise<T>
162
+ ): Promise<{ data: T; fallback: boolean }> {
163
+ try {
164
+ const data = await fn();
165
+ // Update cache for future fallback
166
+ await updateFallbackCache(data);
167
+ return { data, fallback: false };
168
+ } catch (error) {
169
+ console.warn('Supabase failed, using fallback:', error.message);
170
+ const data = await fallbackFn();
171
+ return { data, fallback: true };
172
+ }
173
+ }
174
+ ```
175
+
176
+ ## Dead Letter Queue
177
+
178
+ ```typescript
179
+ interface DeadLetterEntry {
180
+ id: string;
181
+ operation: string;
182
+ payload: any;
183
+ error: string;
184
+ attempts: number;
185
+ lastAttempt: Date;
186
+ }
187
+
188
+ class SupabaseDeadLetterQueue {
189
+ private queue: DeadLetterEntry[] = [];
190
+
191
+ add(entry: Omit<DeadLetterEntry, 'id' | 'lastAttempt'>): void {
192
+ this.queue.push({
193
+ ...entry,
194
+ id: uuidv4(),
195
+ lastAttempt: new Date(),
196
+ });
197
+ }
198
+
199
+ async processOne(): Promise<boolean> {
200
+ const entry = this.queue.shift();
201
+ if (!entry) return false;
202
+
203
+ try {
204
+ await supabaseClient[entry.operation](entry.payload);
205
+ console.log(`DLQ: Successfully reprocessed ${entry.id}`);
206
+ return true;
207
+ } catch (error) {
208
+ entry.attempts++;
209
+ entry.lastAttempt = new Date();
210
+
211
+ if (entry.attempts < 5) {
212
+ this.queue.push(entry);
213
+ } else {
214
+ console.error(`DLQ: Giving up on ${entry.id} after 5 attempts`);
215
+ await alertOnPermanentFailure(entry);
216
+ }
217
+ return false;
218
+ }
219
+ }
220
+ }
221
+ ```
222
+
223
+ ## Health Check with Degraded State
224
+
225
+ ```typescript
226
+ type HealthStatus = 'healthy' | 'degraded' | 'unhealthy';
227
+
228
+ async function supabaseHealthCheck(): Promise<{
229
+ status: HealthStatus;
230
+ details: Record<string, any>;
231
+ }> {
232
+ const checks = {
233
+ api: await checkApiConnectivity(),
234
+ circuitBreaker: supabaseBreaker.stats(),
235
+ dlqSize: deadLetterQueue.size(),
236
+ };
237
+
238
+ const status: HealthStatus =
239
+ !checks.api.connected ? 'unhealthy' :
240
+ checks.circuitBreaker.state === 'open' ? 'degraded' :
241
+ checks.dlqSize > 100 ? 'degraded' :
242
+ 'healthy';
243
+
244
+ return { status, details: checks };
245
+ }
246
+ ```
247
+
248
+ ## Instructions
249
+
250
+ ### Step 1: Implement Circuit Breaker
251
+ Wrap Supabase calls with circuit breaker.
252
+
253
+ ### Step 2: Add Idempotency Keys
254
+ Generate deterministic keys for operations.
255
+
256
+ ### Step 3: Configure Bulkheads
257
+ Separate queues for different priorities.
258
+
259
+ ### Step 4: Set Up Dead Letter Queue
260
+ Handle permanent failures gracefully.
261
+
262
+ ## Output
263
+ - Circuit breaker protecting Supabase calls
264
+ - Idempotency preventing duplicates
265
+ - Bulkhead isolation implemented
266
+ - DLQ for failed operations
267
+
268
+ ## Error Handling
269
+ | Issue | Cause | Solution |
270
+ |-------|-------|----------|
271
+ | Circuit stays open | Threshold too low | Adjust error percentage |
272
+ | Duplicate operations | Missing idempotency | Add idempotency key |
273
+ | Queue full | Rate too high | Increase concurrency |
274
+ | DLQ growing | Persistent failures | Investigate root cause |
275
+
276
+ ## Examples
277
+
278
+ ### Quick Circuit Check
279
+ ```typescript
280
+ const state = supabaseBreaker.stats().state;
281
+ console.log('Supabase circuit:', state);
282
+ ```
283
+
284
+ ## Resources
285
+ - [Circuit Breaker Pattern](https://martinfowler.com/bliki/CircuitBreaker.html)
286
+ - [Opossum Documentation](https://nodeshift.dev/opossum/)
287
+ - [Supabase Reliability Guide](https://supabase.com/docs/reliability)
288
+
289
+ ## Next Steps
290
+ For policy enforcement, see `supabase-policy-guardrails`.