2.2 KiB
2.2 KiB
Multi-Tenant Patterns with TanStack
Multi-tenant isolation patterns for TanStack Start applications.
Server Function Pattern
ALWAYS include tenant_id parameter:
// ✅ 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:
// ✅ 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
// 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
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:
// 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
- Always include tenant_id: In server functions and query keys
- Use tenant context: Create
useTenant()hook for consistency - Enable guards: Use
enabled: !!tenantIdfor queries - RLS when possible: Prefer RLS over manual filtering
- Test isolation: Verify tenant isolation in tests