Fix gated chat funnel message limits and agent knowledge#41
Conversation
…uth status This commit fixes two major issues with gated chat funnels: 1. Message limit bypass fix: - Previously, authenticated users bypassed ALL message restrictions - Now, restrictions are based on session.converted status, not user auth - Users must convert through the funnel (opt-in) to unlock unlimited messages - This affects both useChatState.ts and useMessageHandler.ts 2. Knowledge base retrieval fix: - Added semantic/vector search using embeddings for better relevance - Falls back to text search if semantic search unavailable - Added final fallback to fetch ALL knowledge when search filters fail - This ensures agents with knowledge bases can access their content Root causes: - Issue 1: Logic checked `if (user)` to bypass restrictions instead of `session.converted` - Issue 2: textSearch() requires exact word matches; semantic search is more flexible
Public funnel pages (Landing, Chat, Optin) were failing in incognito mode because RLS policies require tenant_id = get_current_tenant_id(). Root cause: The tenant context was being set asynchronously in the tenantAwareClient constructor, but the React components would query the database immediately on mount before context was established. Fix: Each public funnel page now explicitly: 1. Resolves tenant ID from URL slug using get_tenant_id_from_slug RPC 2. Sets tenant context via setTenantContext() before any DB queries 3. Persists context to localStorage/sessionStorage for subsequent requests This ensures the tenant context is always set before querying, even for anonymous users in incognito mode.
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughThis pull request introduces funnel-conversion-based message restrictions replacing authentication-based logic, adds tenant resolution to public funnel pages with storage persistence, and implements embedding-based semantic search with fallback retrieval in knowledge utilities. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant PublicFunnel as Public Funnel Page
participant Supabase as Supabase RPC
participant Storage as localStorage/<br/>sessionStorage
participant TenantClient as TenantAwareClient
Note over Client,TenantClient: Tenant Resolution Flow
Client->>PublicFunnel: Navigate with tenantSlug
alt tenantSlug provided
PublicFunnel->>Supabase: get_tenant_id_from_slug(tenantSlug)
alt Resolution successful
Supabase-->>PublicFunnel: tenantId
PublicFunnel->>TenantClient: setTenantContext(tenantId)
PublicFunnel->>Storage: Store tenantId & slug
Storage-->>PublicFunnel: Persisted
else Resolution failed
Supabase-->>PublicFunnel: Error
PublicFunnel->>PublicFunnel: Log error & throw
end
else No tenantSlug
PublicFunnel->>PublicFunnel: Proceed without resolution
end
PublicFunnel->>Supabase: Fetch funnel data
sequenceDiagram
participant User
participant ChatHandler as Message Handler
participant FunnelConfig as Funnel Context
participant Session as Session State
participant SignupUI as Signup Flow
Note over User,SignupUI: Funnel-Conversion-Based Restriction
User->>ChatHandler: Send message
ChatHandler->>Session: Check session.converted
alt Already converted
ChatHandler->>ChatHandler: Allow message (debug log)
ChatHandler->>User: Process normally
else Not converted & in funnel
ChatHandler->>FunnelConfig: shouldEnforceRestrictions?
alt Restrictions apply
ChatHandler->>ChatHandler: Log restriction context
alt onNavigateToStep provided
ChatHandler->>SignupUI: Navigate to signup step
else Fallback
ChatHandler->>SignupUI: Trigger inline signup
end
else No restrictions (fallback)
ChatHandler->>User: Process message
end
end
sequenceDiagram
participant Handler as Message Handler
participant Knowledge as Knowledge Utils
participant OpenAI as OpenAI API
participant Supabase as Supabase RPC
participant Fallback as Fallback Retrieval
Note over Handler,Fallback: Semantic Search with Fallback
Handler->>Knowledge: getRelevantKnowledge(query)
alt OpenAI key available
Knowledge->>OpenAI: generateQueryEmbedding(query)
alt Embedding success
OpenAI-->>Knowledge: embedding vector
Knowledge->>Supabase: search_knowledge_semantic(embedding)
alt Results found
Supabase-->>Knowledge: semantic matches
Knowledge-->>Handler: Return results
else No results
Knowledge->>Fallback: Fetch all chunks<br/>(restricted context)
Fallback-->>Knowledge: expanded set
Knowledge-->>Handler: Return fallback
end
else Embedding failed
Knowledge->>Knowledge: Fall back to text search
Knowledge-->>Handler: Return text results
end
else No OpenAI key
Knowledge->>Knowledge: Use text search
Knowledge-->>Handler: Return results
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Free 📒 Files selected for processing (6)
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
Summary by CodeRabbit
Release Notes
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.