@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.
Files changed (133) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +73 -47
  3. package/package.json +4 -4
  4. package/skills/supabase-advanced-troubleshooting/SKILL.md +404 -200
  5. package/skills/supabase-advanced-troubleshooting/references/errors.md +11 -0
  6. package/skills/supabase-advanced-troubleshooting/references/evidence-collection-framework.md +34 -0
  7. package/skills/supabase-advanced-troubleshooting/references/examples.md +11 -0
  8. package/skills/supabase-advanced-troubleshooting/references/rls-edge-functions-realtime.md +363 -0
  9. package/skills/supabase-advanced-troubleshooting/references/systematic-isolation.md +56 -0
  10. package/skills/supabase-advanced-troubleshooting/references/timing-analysis.md +35 -0
  11. package/skills/supabase-architecture-variants/SKILL.md +395 -216
  12. package/skills/supabase-architecture-variants/references/errors.md +11 -0
  13. package/skills/supabase-architecture-variants/references/examples.md +12 -0
  14. package/skills/supabase-architecture-variants/references/serverless-and-multi-tenant.md +251 -0
  15. package/skills/supabase-architecture-variants/references/variant-a-monolith-(simple).md +44 -0
  16. package/skills/supabase-architecture-variants/references/variant-b-service-layer-(moderate).md +72 -0
  17. package/skills/supabase-architecture-variants/references/variant-c-microservice-(complex).md +81 -0
  18. package/skills/supabase-auth-storage-realtime-core/SKILL.md +471 -37
  19. package/skills/supabase-ci-integration/SKILL.md +315 -67
  20. package/skills/supabase-ci-integration/references/errors.md +10 -0
  21. package/skills/supabase-ci-integration/references/examples.md +36 -0
  22. package/skills/supabase-ci-integration/references/implementation.md +54 -0
  23. package/skills/supabase-common-errors/SKILL.md +320 -62
  24. package/skills/supabase-common-errors/references/errors.md +53 -0
  25. package/skills/supabase-common-errors/references/examples.md +23 -0
  26. package/skills/supabase-cost-tuning/SKILL.md +365 -131
  27. package/skills/supabase-cost-tuning/references/cost-estimation.md +34 -0
  28. package/skills/supabase-cost-tuning/references/cost-reduction-strategies.md +40 -0
  29. package/skills/supabase-cost-tuning/references/errors.md +11 -0
  30. package/skills/supabase-cost-tuning/references/examples.md +15 -0
  31. package/skills/supabase-data-handling/SKILL.md +378 -145
  32. package/skills/supabase-data-handling/references/errors.md +11 -0
  33. package/skills/supabase-data-handling/references/examples.md +27 -0
  34. package/skills/supabase-data-handling/references/implementation.md +223 -0
  35. package/skills/supabase-data-handling/references/retention-and-backup.md +221 -0
  36. package/skills/supabase-debug-bundle/SKILL.md +267 -73
  37. package/skills/supabase-debug-bundle/references/errors.md +12 -0
  38. package/skills/supabase-debug-bundle/references/examples.md +24 -0
  39. package/skills/supabase-debug-bundle/references/implementation.md +54 -0
  40. package/skills/supabase-deploy-integration/SKILL.md +258 -147
  41. package/skills/supabase-deploy-integration/references/errors.md +11 -0
  42. package/skills/supabase-deploy-integration/references/examples.md +21 -0
  43. package/skills/supabase-deploy-integration/references/google-cloud-run.md +36 -0
  44. package/skills/supabase-deploy-integration/references/vercel-deployment.md +35 -0
  45. package/skills/supabase-enterprise-rbac/SKILL.md +327 -160
  46. package/skills/supabase-enterprise-rbac/references/api-scoping-and-enforcement.md +255 -0
  47. package/skills/supabase-enterprise-rbac/references/errors.md +11 -0
  48. package/skills/supabase-enterprise-rbac/references/examples.md +12 -0
  49. package/skills/supabase-enterprise-rbac/references/role-implementation.md +33 -0
  50. package/skills/supabase-enterprise-rbac/references/sso-integration.md +35 -0
  51. package/skills/supabase-hello-world/SKILL.md +160 -54
  52. package/skills/supabase-incident-runbook/SKILL.md +453 -131
  53. package/skills/supabase-incident-runbook/references/errors.md +11 -0
  54. package/skills/supabase-incident-runbook/references/examples.md +10 -0
  55. package/skills/supabase-incident-runbook/references/immediate-actions-by-error-type.md +41 -0
  56. package/skills/supabase-install-auth/SKILL.md +186 -50
  57. package/skills/supabase-install-auth/references/examples.md +102 -0
  58. package/skills/supabase-known-pitfalls/SKILL.md +411 -241
  59. package/skills/supabase-known-pitfalls/references/errors.md +11 -0
  60. package/skills/supabase-known-pitfalls/references/examples.md +12 -0
  61. package/skills/supabase-load-scale/SKILL.md +346 -217
  62. package/skills/supabase-load-scale/references/capacity-planning.md +47 -0
  63. package/skills/supabase-load-scale/references/errors.md +11 -0
  64. package/skills/supabase-load-scale/references/examples.md +26 -0
  65. package/skills/supabase-load-scale/references/load-testing-with-k6.md +59 -0
  66. package/skills/supabase-load-scale/references/scaling-patterns.md +65 -0
  67. package/skills/supabase-load-scale/references/table-partitioning.md +263 -0
  68. package/skills/supabase-local-dev-loop/SKILL.md +272 -73
  69. package/skills/supabase-local-dev-loop/references/errors.md +11 -0
  70. package/skills/supabase-local-dev-loop/references/examples.md +21 -0
  71. package/skills/supabase-local-dev-loop/references/implementation.md +60 -0
  72. package/skills/supabase-migration-deep-dive/SKILL.md +338 -177
  73. package/skills/supabase-migration-deep-dive/references/backfill-versioning-rollback.md +258 -0
  74. package/skills/supabase-migration-deep-dive/references/errors.md +11 -0
  75. package/skills/supabase-migration-deep-dive/references/examples.md +12 -0
  76. package/skills/supabase-migration-deep-dive/references/implementation-plan.md +80 -0
  77. package/skills/supabase-migration-deep-dive/references/pre-migration-assessment.md +39 -0
  78. package/skills/supabase-multi-env-setup/SKILL.md +393 -152
  79. package/skills/supabase-multi-env-setup/references/configuration-structure.md +59 -0
  80. package/skills/supabase-multi-env-setup/references/errors.md +11 -0
  81. package/skills/supabase-multi-env-setup/references/examples.md +11 -0
  82. package/skills/supabase-observability/SKILL.md +318 -196
  83. package/skills/supabase-observability/references/alert-configuration.md +40 -0
  84. package/skills/supabase-observability/references/errors.md +11 -0
  85. package/skills/supabase-observability/references/examples.md +13 -0
  86. package/skills/supabase-observability/references/metrics-collection.md +65 -0
  87. package/skills/supabase-performance-tuning/SKILL.md +304 -160
  88. package/skills/supabase-performance-tuning/references/caching-strategy.md +49 -0
  89. package/skills/supabase-performance-tuning/references/errors.md +11 -0
  90. package/skills/supabase-performance-tuning/references/examples.md +13 -0
  91. package/skills/supabase-policy-guardrails/SKILL.md +248 -221
  92. package/skills/supabase-policy-guardrails/references/ci-cost-security.md +484 -0
  93. package/skills/supabase-policy-guardrails/references/errors.md +11 -0
  94. package/skills/supabase-policy-guardrails/references/eslint-rules.md +46 -0
  95. package/skills/supabase-policy-guardrails/references/examples.md +10 -0
  96. package/skills/supabase-prod-checklist/SKILL.md +474 -84
  97. package/skills/supabase-prod-checklist/references/errors.md +63 -0
  98. package/skills/supabase-prod-checklist/references/examples.md +153 -0
  99. package/skills/supabase-prod-checklist/references/implementation.md +113 -0
  100. package/skills/supabase-rate-limits/SKILL.md +311 -98
  101. package/skills/supabase-rate-limits/references/errors.md +11 -0
  102. package/skills/supabase-rate-limits/references/examples.md +46 -0
  103. package/skills/supabase-rate-limits/references/implementation.md +66 -0
  104. package/skills/supabase-reference-architecture/SKILL.md +249 -182
  105. package/skills/supabase-reference-architecture/references/errors.md +29 -0
  106. package/skills/supabase-reference-architecture/references/examples.md +116 -0
  107. package/skills/supabase-reference-architecture/references/key-components.md +244 -0
  108. package/skills/supabase-reference-architecture/references/project-structure.md +109 -0
  109. package/skills/supabase-reliability-patterns/SKILL.md +229 -234
  110. package/skills/supabase-reliability-patterns/references/circuit-breaker.md +36 -0
  111. package/skills/supabase-reliability-patterns/references/dead-letter-queue.md +48 -0
  112. package/skills/supabase-reliability-patterns/references/errors.md +11 -0
  113. package/skills/supabase-reliability-patterns/references/examples.md +11 -0
  114. package/skills/supabase-reliability-patterns/references/idempotency-keys.md +36 -0
  115. package/skills/supabase-reliability-patterns/references/offline-degradation-health-dualwrite.md +489 -0
  116. package/skills/supabase-schema-from-requirements/SKILL.md +373 -34
  117. package/skills/supabase-sdk-patterns/SKILL.md +388 -99
  118. package/skills/supabase-sdk-patterns/references/errors.md +11 -0
  119. package/skills/supabase-sdk-patterns/references/examples.md +45 -0
  120. package/skills/supabase-sdk-patterns/references/implementation.md +67 -0
  121. package/skills/supabase-security-basics/SKILL.md +282 -102
  122. package/skills/supabase-security-basics/references/errors.md +10 -0
  123. package/skills/supabase-security-basics/references/examples.md +70 -0
  124. package/skills/supabase-security-basics/references/implementation.md +39 -0
  125. package/skills/supabase-upgrade-migration/SKILL.md +248 -66
  126. package/skills/supabase-upgrade-migration/references/errors.md +10 -0
  127. package/skills/supabase-upgrade-migration/references/examples.md +51 -0
  128. package/skills/supabase-upgrade-migration/references/implementation.md +29 -0
  129. package/skills/supabase-webhooks-events/SKILL.md +412 -138
  130. package/skills/supabase-webhooks-events/references/errors.md +55 -0
  131. package/skills/supabase-webhooks-events/references/event-handler-pattern.md +106 -0
  132. package/skills/supabase-webhooks-events/references/examples.md +133 -0
  133. package/skills/supabase-webhooks-events/references/signature-verification.md +165 -0
@@ -0,0 +1,11 @@
1
+ # Error Handling Reference
2
+
3
+ | Issue | Cause | Solution |
4
+ |-------|-------|----------|
5
+ | Over-engineering | Wrong variant choice | Start simpler |
6
+ | Performance issues | Wrong layer | Add caching/async |
7
+ | Team friction | Complex architecture | Simplify or train |
8
+ | Deployment complexity | Microservice overhead | Consider service layer |
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 Variant Check
4
+
5
+ ```bash
6
+ # Count team size and DAU to select variant
7
+ echo "Team: $(git log --format='%ae' | sort -u | wc -l) developers"
8
+ echo "DAU: Check analytics dashboard"
9
+ ```
10
+
11
+ ---
12
+ *[Tons of Skills](https://tonsofskills.com) by [Intent Solutions](https://intentsolutions.io) | [jeremylongshore.com](https://jeremylongshore.com)*
@@ -0,0 +1,251 @@
1
+ ## Serverless (Edge Functions) and Multi-Tenant Patterns
2
+
3
+ ### Edge Functions with Per-Request Clients
4
+
5
+ Edge Functions create a new Supabase client per request, extracting the user's JWT from the Authorization header. This ensures proper RLS scoping.
6
+
7
+ ```typescript
8
+ // supabase/functions/api/index.ts
9
+ import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
10
+
11
+ Deno.serve(async (req) => {
12
+ // Per-request client with the user's JWT for RLS
13
+ const supabase = createClient(
14
+ Deno.env.get('SUPABASE_URL')!,
15
+ Deno.env.get('SUPABASE_ANON_KEY')!,
16
+ {
17
+ global: {
18
+ headers: { Authorization: req.headers.get('Authorization')! },
19
+ },
20
+ }
21
+ )
22
+
23
+ // This client respects RLS using the user's JWT
24
+ const { data: { user } } = await supabase.auth.getUser()
25
+ if (!user) {
26
+ return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401 })
27
+ }
28
+
29
+ // Queries are scoped to the authenticated user via RLS
30
+ const { data, error } = await supabase
31
+ .from('todos')
32
+ .select('id, title, is_complete')
33
+ .order('created_at', { ascending: false })
34
+
35
+ if (error) {
36
+ return new Response(JSON.stringify({ error: error.message }), { status: 500 })
37
+ }
38
+
39
+ return new Response(JSON.stringify(data), {
40
+ headers: { 'Content-Type': 'application/json' },
41
+ })
42
+ })
43
+ ```
44
+
45
+ ### Edge Function with Admin Operations
46
+
47
+ ```typescript
48
+ // supabase/functions/admin-task/index.ts
49
+ import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
50
+
51
+ Deno.serve(async (req) => {
52
+ // Verify the request has a valid admin JWT first
53
+ const userClient = createClient(
54
+ Deno.env.get('SUPABASE_URL')!,
55
+ Deno.env.get('SUPABASE_ANON_KEY')!,
56
+ { global: { headers: { Authorization: req.headers.get('Authorization')! } } }
57
+ )
58
+
59
+ const { data: { user } } = await userClient.auth.getUser()
60
+ if (!user) {
61
+ return new Response('Unauthorized', { status: 401 })
62
+ }
63
+
64
+ // Check if user is admin
65
+ const { data: profile } = await userClient
66
+ .from('profiles')
67
+ .select('role')
68
+ .eq('id', user.id)
69
+ .single()
70
+
71
+ if (profile?.role !== 'admin') {
72
+ return new Response('Forbidden', { status: 403 })
73
+ }
74
+
75
+ // Now use service_role for admin operations
76
+ const adminClient = createClient(
77
+ Deno.env.get('SUPABASE_URL')!,
78
+ Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
79
+ )
80
+
81
+ // Admin operation: get all users
82
+ const { data, error } = await adminClient.auth.admin.listUsers()
83
+ if (error) {
84
+ return new Response(JSON.stringify({ error: error.message }), { status: 500 })
85
+ }
86
+
87
+ return new Response(JSON.stringify({ users: data.users.length }))
88
+ })
89
+ ```
90
+
91
+ ### Multi-Tenant: RLS-Based Isolation (Recommended)
92
+
93
+ The simplest multi-tenant approach uses a single database with RLS policies scoping all queries to the tenant.
94
+
95
+ ```sql
96
+ -- Schema for RLS-based multi-tenancy
97
+ CREATE TABLE public.tenants (
98
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
99
+ name text NOT NULL,
100
+ slug text UNIQUE NOT NULL,
101
+ plan text DEFAULT 'free',
102
+ created_at timestamptz DEFAULT now()
103
+ );
104
+
105
+ CREATE TABLE public.tenant_members (
106
+ tenant_id uuid REFERENCES public.tenants(id) ON DELETE CASCADE,
107
+ user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE,
108
+ role text NOT NULL DEFAULT 'member' CHECK (role IN ('owner', 'admin', 'member')),
109
+ PRIMARY KEY (tenant_id, user_id)
110
+ );
111
+
112
+ -- Store current tenant in user's JWT claims (set via custom claims hook)
113
+ -- Or look up from tenant_members table
114
+
115
+ CREATE TABLE public.projects (
116
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
117
+ tenant_id uuid NOT NULL REFERENCES public.tenants(id),
118
+ name text NOT NULL,
119
+ created_at timestamptz DEFAULT now()
120
+ );
121
+
122
+ ALTER TABLE public.projects ENABLE ROW LEVEL SECURITY;
123
+
124
+ -- RLS: users can only see projects belonging to their tenant
125
+ CREATE POLICY "tenant_isolation" ON public.projects
126
+ FOR ALL USING (
127
+ tenant_id IN (
128
+ SELECT tenant_id FROM public.tenant_members
129
+ WHERE user_id = auth.uid()
130
+ )
131
+ );
132
+
133
+ CREATE INDEX idx_projects_tenant_id ON public.projects(tenant_id);
134
+ CREATE INDEX idx_tenant_members_user_id ON public.tenant_members(user_id);
135
+ ```
136
+
137
+ ```typescript
138
+ // lib/supabase-tenant.ts
139
+ import { createClient } from '@supabase/supabase-js'
140
+ import type { Database } from './database.types'
141
+
142
+ const supabase = createClient<Database>(
143
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
144
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
145
+ )
146
+
147
+ // All queries are automatically scoped to the user's tenant via RLS
148
+ export async function getTenantProjects() {
149
+ const { data, error } = await supabase
150
+ .from('projects')
151
+ .select('id, name, created_at, tenant_id')
152
+ .order('created_at', { ascending: false })
153
+
154
+ if (error) throw new Error(`Failed to load projects: ${error.message}`)
155
+ return data // Only returns projects for the authenticated user's tenant(s)
156
+ }
157
+
158
+ // Switch active tenant (for users in multiple tenants)
159
+ export async function getUserTenants() {
160
+ const { data, error } = await supabase
161
+ .from('tenant_members')
162
+ .select(`
163
+ role,
164
+ tenants:tenant_id (id, name, slug, plan)
165
+ `)
166
+
167
+ if (error) throw new Error(`Failed to load tenants: ${error.message}`)
168
+ return data
169
+ }
170
+
171
+ // Create project in a specific tenant
172
+ export async function createProject(tenantId: string, name: string) {
173
+ const { data, error } = await supabase
174
+ .from('projects')
175
+ .insert({ tenant_id: tenantId, name })
176
+ .select('id, name, tenant_id, created_at')
177
+ .single()
178
+
179
+ if (error) throw new Error(`Failed to create project: ${error.message}`)
180
+ return data
181
+ }
182
+ ```
183
+
184
+ ## Output
185
+
186
+ - Next.js SSR setup with server client (cookies-based auth), browser client, and middleware
187
+ - Server Actions using admin client with service_role for privileged operations
188
+ - SPA pattern with singleton client, React Query integration, and auth state listener
189
+ - React Native setup with AsyncStorage, deep link OAuth, and in-app browser
190
+ - Edge Function patterns for per-request auth and admin escalation
191
+ - Multi-tenant RLS isolation with tenant_members lookup and scoped queries
192
+ - Decision matrix for choosing the right architecture per stack
193
+
194
+ ## Error Handling
195
+
196
+ | Issue | Cause | Solution |
197
+ |-------|-------|----------|
198
+ | `AuthSessionMissingError` in Server Component | Cookies not passed to Supabase client | Use `createServerClient` from `@supabase/ssr` with cookie handlers |
199
+ | OAuth redirect fails in React Native | Missing deep link scheme | Add `scheme` to app.json and configure Supabase redirect URL |
200
+ | service_role key in client bundle | Wrong env var prefix (`NEXT_PUBLIC_`) | Remove `NEXT_PUBLIC_` prefix; only server code should access it |
201
+ | Multi-tenant data leak | Missing RLS policy or missing tenant_id filter | Verify RLS is enabled and policies check `tenant_members` |
202
+ | Edge Function `auth.getUser()` returns null | Missing Authorization header | Forward user's JWT from the client call |
203
+ | Session not persisting on mobile | AsyncStorage not configured | Pass `AsyncStorage` in auth config; ensure package is installed |
204
+
205
+ ## Examples
206
+
207
+ ### Test Auth Flow End-to-End (Next.js)
208
+
209
+ ```typescript
210
+ // app/auth/callback/route.ts
211
+ import { createSupabaseServer } from '@/lib/supabase/server'
212
+ import { NextResponse } from 'next/server'
213
+
214
+ export async function GET(request: Request) {
215
+ const { searchParams } = new URL(request.url)
216
+ const code = searchParams.get('code')
217
+
218
+ if (code) {
219
+ const supabase = await createSupabaseServer()
220
+ const { error } = await supabase.auth.exchangeCodeForSession(code)
221
+ if (error) {
222
+ return NextResponse.redirect(new URL('/login?error=auth_failed', request.url))
223
+ }
224
+ }
225
+
226
+ return NextResponse.redirect(new URL('/dashboard', request.url))
227
+ }
228
+ ```
229
+
230
+ ### Verify Tenant Isolation
231
+
232
+ ```sql
233
+ -- Test that RLS properly isolates tenants
234
+ SET request.jwt.claims = '{"sub": "user-uuid-1"}';
235
+
236
+ -- Should only return projects for user-uuid-1's tenant
237
+ SELECT * FROM public.projects;
238
+ ```
239
+
240
+ ## Resources
241
+
242
+ - [Supabase SSR (Next.js)](https://supabase.com/docs/guides/auth/server-side/nextjs)
243
+ - [Supabase React Native](https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native)
244
+ - [Supabase Edge Functions](https://supabase.com/docs/guides/functions)
245
+ - [Multi-Tenant with RLS](https://supabase.com/docs/guides/database/postgres/row-level-security)
246
+ - [Supabase Auth Deep Linking](https://supabase.com/docs/guides/auth/native-mobile-deep-linking)
247
+ - [@supabase/ssr Package](https://supabase.com/docs/guides/auth/server-side/overview)
248
+
249
+ ## Next Steps
250
+
251
+ For common mistakes and anti-patterns to avoid, see `supabase-known-pitfalls`.
@@ -0,0 +1,44 @@
1
+ # Variant A: Monolith (Simple)
2
+
3
+ ## Variant A: Monolith (Simple)
4
+
5
+ **Best for:** MVPs, small teams, < 10K daily active users
6
+
7
+ ```
8
+ my-app/
9
+ ├── src/
10
+ │ ├── supabase/
11
+ │ │ ├── client.ts # Singleton client
12
+ │ │ ├── types.ts # Types
13
+ │ │ └── middleware.ts # Express middleware
14
+ │ ├── routes/
15
+ │ │ └── api/
16
+ │ │ └── supabase.ts # API routes
17
+ │ └── index.ts
18
+ ├── tests/
19
+ │ └── supabase.test.ts
20
+ └── package.json
21
+ ```
22
+
23
+ ### Key Characteristics
24
+
25
+ - Single deployment unit
26
+ - Synchronous Supabase calls in request path
27
+ - In-memory caching
28
+ - Simple error handling
29
+
30
+ ### Code Pattern
31
+
32
+ ```typescript
33
+ // Direct integration in route handler
34
+ app.post('/api/create', async (req, res) => {
35
+ try {
36
+ const result = await supabaseClient.create(req.body);
37
+ res.json(result);
38
+ } catch (error) {
39
+ res.status(500).json({ error: error.message });
40
+ }
41
+ });
42
+ ```
43
+
44
+ ---
@@ -0,0 +1,72 @@
1
+ # Variant B: Service Layer (Moderate)
2
+
3
+ ## Variant B: Service Layer (Moderate)
4
+
5
+ **Best for:** Growing startups, 10K-100K DAU, multiple integrations
6
+
7
+ ```
8
+ my-app/
9
+ ├── src/
10
+ │ ├── services/
11
+ │ │ ├── supabase/
12
+ │ │ │ ├── client.ts # Client wrapper
13
+ │ │ │ ├── service.ts # Business logic
14
+ │ │ │ ├── repository.ts # Data access
15
+ │ │ │ └── types.ts
16
+ │ │ └── index.ts # Service exports
17
+ │ ├── controllers/
18
+ │ │ └── supabase.ts
19
+ │ ├── routes/
20
+ │ ├── middleware/
21
+ │ ├── queue/
22
+ │ │ └── supabase-processor.ts # Async processing
23
+ │ └── index.ts
24
+ ├── config/
25
+ │ └── supabase/
26
+ └── package.json
27
+ ```
28
+
29
+ ### Key Characteristics
30
+
31
+ - Separation of concerns
32
+ - Background job processing
33
+ - Redis caching
34
+ - Circuit breaker pattern
35
+ - Structured error handling
36
+
37
+ ### Code Pattern
38
+
39
+ ```typescript
40
+ // Service layer abstraction
41
+ class SupabaseService {
42
+ constructor(
43
+ private client: SupabaseClient,
44
+ private cache: CacheService,
45
+ private queue: QueueService
46
+ ) {}
47
+
48
+ async createResource(data: CreateInput): Promise<Resource> {
49
+ // Business logic before API call
50
+ const validated = this.validate(data);
51
+
52
+ // Check cache
53
+ const cached = await this.cache.get(cacheKey);
54
+ if (cached) return cached;
55
+
56
+ // API call with retry
57
+ const result = await this.withRetry(() =>
58
+ this.client.create(validated)
59
+ );
60
+
61
+ // Cache result
62
+ await this.cache.set(cacheKey, result, 300);
63
+
64
+ // Async follow-up
65
+ await this.queue.enqueue('supabase.post-create', result);
66
+
67
+ return result;
68
+ }
69
+ }
70
+ ```
71
+
72
+ ---
@@ -0,0 +1,81 @@
1
+ # Variant C: Microservice (Complex)
2
+
3
+ ## Variant C: Microservice (Complex)
4
+
5
+ **Best for:** Enterprise, 100K+ DAU, strict SLAs
6
+
7
+ ```
8
+ supabase-service/ # Dedicated microservice
9
+ ├── src/
10
+ │ ├── api/
11
+ │ │ ├── grpc/
12
+ │ │ │ └── supabase.proto
13
+ │ │ └── rest/
14
+ │ │ └── routes.ts
15
+ │ ├── domain/
16
+ │ │ ├── entities/
17
+ │ │ ├── events/
18
+ │ │ └── services/
19
+ │ ├── infrastructure/
20
+ │ │ ├── supabase/
21
+ │ │ │ ├── client.ts
22
+ │ │ │ ├── mapper.ts
23
+ │ │ │ └── circuit-breaker.ts
24
+ │ │ ├── cache/
25
+ │ │ ├── queue/
26
+ │ │ └── database/
27
+ │ └── index.ts
28
+ ├── config/
29
+ ├── k8s/
30
+ │ ├── deployment.yaml
31
+ │ ├── service.yaml
32
+ │ └── hpa.yaml
33
+ └── package.json
34
+
35
+ other-services/
36
+ ├── order-service/ # Calls supabase-service
37
+ ├── payment-service/
38
+ └── notification-service/
39
+ ```
40
+
41
+ ### Key Characteristics
42
+
43
+ - Dedicated Supabase microservice
44
+ - gRPC for internal communication
45
+ - Event-driven architecture
46
+ - Database per service
47
+ - Kubernetes autoscaling
48
+ - Distributed tracing
49
+ - Circuit breaker per service
50
+
51
+ ### Code Pattern
52
+
53
+ ```typescript
54
+ // Event-driven with domain isolation
55
+ class SupabaseAggregate {
56
+ private events: DomainEvent[] = [];
57
+
58
+ process(command: SupabaseCommand): void {
59
+ // Domain logic
60
+ const result = this.execute(command);
61
+
62
+ // Emit domain event
63
+ this.events.push(new SupabaseProcessedEvent(result));
64
+ }
65
+
66
+ getUncommittedEvents(): DomainEvent[] {
67
+ return [...this.events];
68
+ }
69
+ }
70
+
71
+ // Event handler
72
+ @EventHandler(SupabaseProcessedEvent)
73
+ class SupabaseEventHandler {
74
+ async handle(event: SupabaseProcessedEvent): Promise<void> {
75
+ // Saga orchestration
76
+ await this.sagaOrchestrator.continue(event);
77
+ }
78
+ }
79
+ ```
80
+
81
+ ---