Skip to content

Fix gated chat funnel message limits and agent knowledge#41

Merged
peterod99 merged 2 commits intomainfrom
claude/fix-gated-chat-funnel-AOl1y
Jan 6, 2026
Merged

Fix gated chat funnel message limits and agent knowledge#41
peterod99 merged 2 commits intomainfrom
claude/fix-gated-chat-funnel-AOl1y

Conversation

@peterod99
Copy link
Copy Markdown
Owner

@peterod99 peterod99 commented Jan 6, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added semantic search for improved knowledge retrieval and more accurate results
    • Implemented multi-tenant support with automatic tenant context detection
  • Refactor

    • Updated access control logic to better align with funnel conversion workflows
    • Improved signup flow handling and user restriction management

✏️ Tip: You can customize this high-level summary in your review settings.

claude added 2 commits January 6, 2026 14:08
…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.
@peterod99 peterod99 merged commit 1e1af6f into main Jan 6, 2026
1 of 2 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 6, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Funnel-driven message restrictions
src/components/chat/useChatState.ts, src/components/chat/useMessageHandler.ts
Shifts from authentication-based branching to funnel-conversion-aware restrictions. Routes restricted users to signup step or inline UI based on session.converted state. Enhanced logging includes authentication status and funnel context. Dependency array updated to include funnelSlug.
Tenant resolution in public funnels
src/pages/PublicFunnelChat.tsx, src/pages/PublicFunnelLanding.tsx, src/pages/PublicFunnelOptin.tsx
Adds RPC-based tenant ID resolution from slug before funnel fetch. Sets tenant context via tenantAwareClient.setTenantContext() and persists to localStorage and sessionStorage. Error handling logs and throws on resolution failure.
Semantic search with embeddings
supabase/functions/chat-with-agent/knowledgeUtils.ts
Introduces generateQueryEmbedding() and searchWithEmbeddings() functions. Enhances getRelevantKnowledge() to attempt semantic search first, falling back to text search or expanded retrieval when no results found under restriction. Includes verbose logging and structured metadata output.

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
Loading
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
Loading
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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰✨ Funnels now know who's converted true,
Tenants find their homes through RPC's dew,
Embeddings dance with queries wise,
Fallbacks catch what semantics denies!
Logic flows funnel-first, tenant-aware—
A rabbit's delight in this layered affair! 🌟


📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Free

📥 Commits

Reviewing files that changed from the base of the PR and between 19e5080 and 5ec44cb.

📒 Files selected for processing (6)
  • src/components/chat/useChatState.ts
  • src/components/chat/useMessageHandler.ts
  • src/pages/PublicFunnelChat.tsx
  • src/pages/PublicFunnelLanding.tsx
  • src/pages/PublicFunnelOptin.tsx
  • supabase/functions/chat-with-agent/knowledgeUtils.ts

Note

🎁 Summarized by CodeRabbit Free

Your 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 @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants