Flow Document #

Flows v1.0 · ronilprasad8.tech · Interaction & Data Diagrams

This document visualizes the major user journeys and internal data processes within the application. The diagrams use Mermaid.js to illustrate routing decisions, authentication states, and the multi-layered LLM failover system.

The primary user journey for a public visitor navigating the portfolio. The persistent navigation bar (defined in base.html) and global routing (app.py) control access to different content areas.

graph TD A([Visitor Lands on Site]) --> B[/ GET / : Home View /] B --> C{Navigation Bar} C -->|Clicks 'About'| D[/ GET /about : Bio & Skills /] D --> D1(View Coursework) D --> D2(Download CV /cv) C -->|Clicks 'Projects'| E[/ GET /project : Portfolio /] E --> E1(External Link: Assistant Project) E --> E2(External Link: GitHub Repos) C -->|Clicks 'Contact'| F[/ GET /contact : Social Links /] C -->|Clicks Auth Icon| G[/ GET /login /] B --> H[Global Floating Chat Widget] D --> H E --> H F --> H H --> I{User Authenticated?} I -->|No| J[Display: 'Log in to chat'] I -->|Yes| K[Enable Chat Input]

Step-by-Step Breakdown:

  1. Entry Point: User hits the / route. app.py renders templates/index.html.
  2. Persistent UI: The navigation bar and floating chat widget (controlled by chatbot.js) persist across views.
  3. Exploration: The user browses static views (/about, /project, /contact).
  4. Chat Attempt: The user clicks the floating widget. chatbot.js verifies onAuthStateChanged. If null, the UI is blocked with a login prompt.

2. Authentication Flow #

The process by which a user registers, logs in, or resets their password. All authentication is client-side, managed by Firebase Auth and implemented in login.html.

graph TD Start([User navigates to /login]) --> Tabs{Select Action} Tabs -->|Login Tab| L1[Enter Email & Password] L1 --> L2{signInWithEmailAndPassword} L2 -->|Success| L3[Redirect to /] L2 -->|Error| L4[Show Error Banner] Tabs -->|Sign Up Tab| S1[Enter Details & Validate Rules] S1 --> S2{createUserWithEmailAndPassword} S2 -->|Error| S3[Show Error Banner] S2 -->|Success| S4[Write profile to Firestore 'users'] S4 --> S5[Redirect to /] Tabs -->|Google Button| G1{signInWithPopup} G1 -->|Success| G2{Is First Time?} G2 -->|Yes| G3[Write profile to Firestore 'users'] G2 -->|No| G4[Redirect to /] G3 --> G4 G1 -->|Error| G5[Show Error Banner] Tabs -->|Forgot Password| F1[Enter Email] F1 --> F2{sendPasswordResetEmail} F2 -->|Success| F3[Show Success Banner + Spam Notice] F2 -->|Error| F4[Show Error Banner] F3 --> L1

Step-by-Step Breakdown:

  1. UI Selection: User selects Login, Sign Up, or clicks "Forgot Password?" (controlled via DOM class toggling in login.html).
  2. Validation: Client-side JS validates inputs (e.g., regex matching for 8+ characters, symbols, and numbers).
  3. Firebase Auth: Calls the respective Firebase v10 SDK method.
  4. Firestore Profile: On new registration (Email or Google), a document is created in the users/{uid} collection with the user's name and email.
  5. State Change: Once authenticated, onAuthStateChanged fires globally across the app (in base.html and chatbot.js), unlocking protected elements.

3. AI Chatbot Data & Failover Flow #

The core technical pipeline of the application. This flow details how user messages are augmented with live context, routed to appropriate LLMs, and how system knowledge is extracted and saved.

graph TD Client1([User submits message]) --> Client2[chatbot.js packages Bearer Token + Message + History] Client2 --> HTTP[POST /chat Header: Authorization Bearer] HTTP --> AuthCheck{app.py: verify_firebase_token} AuthCheck -->|Token Missing/Invalid| 401[Return 401 Unauthorized] AuthCheck -->|Verified Token| RateCheck{Rate Limiter: <= 15 req/min} RateCheck -->|Exceeded| 429[Return 429 Too Many Requests] RateCheck -->|Passed| Server1[Extract Verified Identity email/uid] Server1 --> PreFetch[ThreadPoolExecutor: Parallel Pre-Fetch <200ms] PreFetch --> P1[Worker 1: Firestore Knowledge] PreFetch --> P2[Worker 2: Episodic Memory] PreFetch --> P3[Worker 3: Sports Cache Daemon] P1 --> AggPrompt[Aggregate Prompt Context] P2 --> AggPrompt P3 --> AggPrompt AggPrompt --> IntentGate{Intent Classifier: Query Mode} IntentGate -->|Conversational| SetIntro[Adaptive Context Synthesis] IntentGate -->|Direct Technical| SuppressIntro[Direct Structured Answer] SetIntro --> GroqPool[Groq Multi-Key Pool: gpt-oss-120b] SuppressIntro --> GroqPool GroqPool -->|Key 1 429 Error| GroqFailover[In-Flight Failover to Next Key <50ms] GroqFailover --> StreamGroq[Stream Groq Tokens: TTFT <250ms] GroqPool -->|Success| StreamGroq GroqPool -->|All Keys 429 or Disruption| GeminiFallback[Gemini Multi-Key Fallback Pool: gemini-2.5-flash] GeminiFallback --> StreamGemini[Stream Gemini Tokens] StreamGroq --> StreamFilter[StreamTagFilter: Output Governance & Stream Sanitization] StreamGemini --> StreamFilter StreamFilter --> SSE_Stream[Server-Sent Events: text/event-stream] StreamFilter -.->|Async Fire-and-Forget| BgWorker[_bg_executor: Async Firestore Audit & Facts] SSE_Stream --> TypewriterUI[Client: 60fps Adaptive Typewriter & Dynamic Markdown]

Step-by-Step Breakdown:

  1. Client Payload & Bearer Token: chatbot.js retrieves the active user's Firebase ID token via getIdToken() (or guest token) and packages it inside the Authorization: Bearer header, requesting streaming via Accept: text/event-stream.
  2. Server-Side Auth & Rate Limiting: app.py validates the cryptographic JWT against Google public signing keys via verify_firebase_token() (returning 401 on failure) and checks the in-memory sliding window rate limiter (max 15 requests/minute per UID/IP, returning 429 if exceeded).
  3. Concurrent Multi-Threaded Pre-Fetching: A concurrent.futures.ThreadPoolExecutor(max_workers=3) fetches global knowledge facts, episodic memory summaries, and pre-warmed sports match cache simultaneously, dropping pre-fetch latency from ~750ms sequentially down to 150–200ms.
  4. Intent Routing & Context Synthesis: An intent classifier analyzes the user's inquiry, activating conversational dialogue for exploratory queries while enforcing an immediate, structured direct-answer policy without preambles for technical questions.
  5. Multi-Key Round-Robin & Inverted Failover: Primary inference routes directly to the Groq multi-key pool for ultra-low TTFT (<250ms) across all user interactions with in-flight sub-50ms key failover. If all Groq keys are exhausted or rate-limited (HTTP 429), the engine seamlessly falls back to Google Gemini multi-key rotation, guaranteeing zero downtime.
  6. StreamTagFilter & Adaptive 60fps Typewriter: The backend StreamTagFilter intercepts in-flight control tokens, memory directives, and redundant framing headers before stream chunks are yielded to the network. The client consumes text/event-stream SSE chunks, driving an adaptive 60fps typewriter engine (1–3 chars/frame accelerated to 6–16 chars/frame dynamically) with live markdown synthesis.
  7. Non-Blocking Background Audit: Firestore message logging, trigger updates, and learned memory extraction execute in a background daemon thread (_bg_executor) with 0ms latency impact on streaming.