Files
gh-greyhaven-ai-claude-code…/skills/tanstack-patterns/reference/multi-tenant.md
2025-11-29 18:29:26 +08:00

98 lines
2.2 KiB
Markdown

# Multi-Tenant Patterns with TanStack
Multi-tenant isolation patterns for TanStack Start applications.
## Server Function Pattern
**ALWAYS include tenant_id parameter:**
```typescript
// ✅ CORRECT
export const getUsers = createServerFn("GET", async (tenantId: string) => {
return await db.query.users.findMany({
where: eq(users.tenant_id, tenantId),
});
});
// ❌ WRONG - Missing tenant_id
export const getUsers = createServerFn("GET", async () => {
return await db.query.users.findMany();
});
```
## Query Key Pattern
Include tenant_id in query keys:
```typescript
// ✅ CORRECT
const { data } = useQuery({
queryKey: ["users", tenantId],
queryFn: () => getUsers(tenantId),
});
// ❌ WRONG - Missing tenant_id in key
const { data } = useQuery({
queryKey: ["users"],
queryFn: () => getUsers(tenantId),
});
```
## Tenant Context Hook
```typescript
// src/lib/hooks/use-tenant.ts
import { useQuery } from "@tanstack/react-query";
import { getAuthenticatedUser } from "~/lib/server/functions/auth";
export function useTenant() {
const { data: authData } = useQuery({
queryKey: ["auth", "current-user"],
queryFn: () => getAuthenticatedUser(),
staleTime: 5 * 60 * 1000, // 5 minutes
});
return {
tenantId: authData?.tenantId,
user: authData?.user,
};
}
```
## Usage in Components
```typescript
function UsersList() {
const { tenantId } = useTenant();
const { data: users } = useQuery({
queryKey: ["users", tenantId],
queryFn: () => getUsers(tenantId!),
enabled: !!tenantId, // Only run when tenantId is available
});
return <div>...</div>;
}
```
## Row Level Security (RLS)
With RLS, tenant_id filtering is automatic:
```typescript
// Server function with RLS-enabled connection
export const getUsers = createServerFn("GET", async () => {
// Uses authenticated database connection
// RLS policies automatically filter by tenant_id
return await db.query.users.findMany();
});
```
## Best Practices
1. **Always include tenant_id**: In server functions and query keys
2. **Use tenant context**: Create `useTenant()` hook for consistency
3. **Enable guards**: Use `enabled: !!tenantId` for queries
4. **RLS when possible**: Prefer RLS over manual filtering
5. **Test isolation**: Verify tenant isolation in tests