🤖 AI Chatbot Architecture
Complete Technical Flow Documentation
System Overview
High-Level Architecture
┌─────────────────────────────────────────────────────────────────┐
│ USER INTERFACE │
│ (Browser - JavaScript) │
└────────────┬────────────────────────────────────────────────────┘
│
│ 1. User types: "What projects do we have?"
│ 2. Click Send Button
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND LAYER │
│ chat-widget.js │
│ • Capture user input │
│ • Validate message │
│ • Send POST request to API │
│ • Display response │
└────────────┬────────────────────────────────────────────────────┘
│
│ HTTP POST /api/chat.php
│ JSON: { "message": "...", "conversation_id": "..." }
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ API ENDPOINT │
│ api/chat.php │
│ • Receive request │
│ • Security checks (rate limiting, validation) │
│ • Route to processing │
└────────────┬────────────────────────────────────────────────────┘
│
├──────────────────────────────────────┐
│ │
▼ ▼
┌──────────────────────────┐ ┌─────────────────────────┐
│ DATABASE QUERY │ │ AI INTEGRATION │
│ database-query.php │ │ ai-integration.php │
│ │ │ │
│ • Extract keywords │ │ • Build prompt │
│ • Determine search scope │ │ • Call Claude API │
│ • Query databases │ │ • Parse response │
│ • Format results │ │ │
└──────────┬───────────────┘ └─────────┬───────────────┘
│ │
│ Database Context │ AI Response
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ DATABASE LAYER │
│ │
│ ┌─────────────────────┐ ┌──────────────────────┐ │
│ │ blackfla_Cms │ │ blackfla_Project │ │
│ │ │ │ Tracker │ │
│ │ • projects │ │ │ │
│ │ • contracts │ │ • projects │ │
│ │ • clients │ │ • submittal_events │ │
│ │ • agencies │ │ • agencies │ │
│ └─────────────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ │
└───────────────┬───────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ RESPONSE ASSEMBLY │
│ │
│ • Combine database results + AI response │
│ • Format as JSON │
│ • Return to frontend │
└────────────┬────────────────────────────────────────────────────┘
│
│ JSON Response
│ { "success": true, "response": "...", ... }
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND DISPLAY │
│ • Parse JSON response │
│ • Display AI message in chat │
│ • Scroll to bottom │
└─────────────────────────────────────────────────────────────────┘
Complete Request Flow
Step-by-Step Process
USER ACTION → VALIDATION → SECURITY → DATABASE → AI → RESPONSE
Detailed 20-Step Flow
Each user message goes through 20 distinct processing steps:
- User Input - User types message and clicks send
- Frontend Validation - Check message is not empty and within limits
- Prepare API Request - Display message, show loading indicator
- Send HTTP Request - POST to /api/chat.php
- API Receives Request - Load dependencies
- Security Validation - Check method, JSON, rate limits
- Input Sanitization - Remove HTML, special chars
- Keyword Extraction - Parse message for search terms
- Determine Search Scope - Decide which databases to query
- Database Connection - Connect to CMS & Tracker DBs
- Query Databases - Execute SQL queries
- Check Tracker Data - Get milestone/submittal info if needed
- Format Results for AI - Convert to readable string
- Build AI Prompt - Create structured prompt
- Call Claude AI API - Send to Claude
- Error Handling - Check for API errors
- Prepare Response - Format JSON response
- Send to Frontend - Transmit over network
- Frontend Receives Response - Parse JSON
- Display Response - Show in chat UI
⏱ Total Time: Typically 2-5 seconds from user click to AI response displayed
Frontend Layer
File: prototype/js/chat-widget.js
Key Functions
1. initChatWidget()
Purpose: Initialize the chat widget on page load
Actions:
• Check if enabled (localStorage)
• Create HTML elements
• Attach event listeners
• Load conversation ID
• Display welcome message
2. sendMessage()
Purpose: Send user message to API
Flow:
1. Validate message not empty
2. Validate message length ≤ 500
3. Display user message
4. Show loading indicator
5. Make fetch() POST request
6. Handle response or error
7. Display AI response
8. Re-enable input
3. displayMessage(content, type)
Purpose: Add message to chat UI
Parameters:
• content: Message text
• type: 'user' | 'ai' | 'error' | 'welcome'
Actions:
• Create message div
• Apply appropriate styling
• Format content (line breaks)
• Append to messages container
• Scroll to bottom
Backend Processing
File: api/chat.php
Main Flow
1. Load Dependencies
↓
2. Receive POST Request
↓
3. Validate Request Method → [Not POST] Return 405
↓
4. Parse JSON Body → [Invalid] Return 400
↓
5. Validate Message Field → [Missing] Return 400
↓
6. Sanitize Message
↓
7. Validate Message Length → [Invalid] Return 400
↓
8. Check Rate Limit → [Exceeded] Return 429
↓
9. Get/Generate Conversation ID
↓
10. Try-Catch Block:
├─ Search Databases
├─ Format Results
├─ Call AI
├─ Return Success Response
└─ [Error] Log & Return 500
Security Layers
Layer 1: CORS (config/cors.php)
- Check origin
- Set Access-Control headers
- Handle OPTIONS preflight
- Set Content-Type
Layer 2: Rate Limiting (config/security.php)
Class: RateLimiter
Storage: .rate_limits.json
Logic:
• Track requests per IP address
• Window: 60 seconds
• Limit: 10 requests
• Action: Block if exceeded
• Cleanup: Remove old entries
Layer 3: Input Validation
- Check method
- Validate JSON
- Check required fields
- Validate data types
- Sanitize strings
Database Query Logic
File: api/helpers/database-query.php
Decision Tree
User Message
│
▼
Extract Keywords
│
├─ Remove stop words
├─ Filter short words
└─ Return array of keywords
│
▼
Analyze Message Patterns
│
├─ Check for "list all" patterns
│ • Regex: /(all|list|show|how many|count)/i
│ • If matches + contains "project" → List ALL projects
│
├─ Check keyword presence
│ • containsKeywords(['project', 'projects']) → Search Projects
│ • containsKeywords(['contract', 'contracts']) → Search Contracts
│ • containsKeywords(['client', 'clients']) → Search Clients
│ • containsKeywords(['submittal', ...]) → Search Submittals
│ • containsKeywords(['approval', ...]) → Search Approvals
│ • containsKeywords(['status', 'phase', ...]) → Get Milestones
│
▼
Execute Appropriate Queries
│
├─ IF (listAllProjects):
│ └─ getAllCmsProjects($db, 10)
│ → SELECT * FROM projects LIMIT 10
│
├─ IF (searchProjects && !listAllProjects):
│ └─ searchCmsProjects($db, $keywords, 5)
│ → SELECT * FROM projects WHERE ... LIKE %keyword%
│
├─ IF (searchContracts):
│ └─ searchCmsContracts($db, $keywords, 5)
│
├─ IF (searchClients):
│ └─ searchCmsClients($db, $keywords, 5)
│
├─ IF (projects found && searchMilestones):
│ └─ getTrackerProjectMilestones($trackerDb, $projectNumber)
│
└─ IF (projects found && searchSubmittals):
└─ searchTrackerSubmittalEvents($trackerDb, $projectNumber, 5)
Query Functions
getAllCmsProjects($db, $limit)
Purpose: Get all projects (for "list all" queries)
SELECT
p.project_id, p.project_number, p.project_name,
p.project_status, p.total_lots_units,
c.client_name, a.agency_name
FROM projects p
LEFT JOIN clients c ON p.client_id = c.client_id
LEFT JOIN agencies a ON p.lead_agency_id = a.agency_id
ORDER BY p.updated_at DESC
LIMIT :limit
searchCmsProjects($db, $keywords, $limit)
Purpose: Search projects by keywords
WHERE p.project_number LIKE :keyword
OR p.project_name LIKE :keyword
OR c.client_name LIKE :keyword
LIMIT :limit
AI Integration
File: api/helpers/ai-integration.php
Prompt Engineering
Component Breakdown
1. System Context (Role Definition)
- Identity: "You are a helpful assistant for Bailey Engineering"
- Purpose: "Help users find information about projects, contracts..."
- Behavior: "Be concise, friendly, and professional"
- Constraints: "Answer based on database information provided"
- Formatting: "Use bullet points, format dates nicely"
- Honesty: "If you don't have information, say so clearly"
2. Database Context (Facts)
- Structured data from database queries
- Formatted as readable text
- Includes all relevant details
- Clearly labeled by section (PROJECTS, CONTRACTS, etc.)
3. User Question (Query)
- Exact user message
- Labeled as "USER QUESTION:"
4. Instructions (Guidelines)
- "Provide a helpful answer based on database information"
- "If no relevant information found, say so politely"
API Call Process
Request Structure
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "[Complete Prompt]"
}
]
}
Error Scenarios
| Status Code | Meaning | User Message |
|---|---|---|
| 200 | Success | Display AI response |
| 401 | Auth Failed | "Authentication issue" |
| 429 | Rate Limited | "Too many requests" |
| 500 | Server Error | "Service unavailable" |
| Timeout | No Response | "Request timed out" |
| Network Error | Connection Failed | "Unable to connect" |
Response Processing
How AI Evaluates and Responds
1. Claude's Internal Process
Input: Complete prompt with context
↓
Parse Components:
• Understand role (assistant for engineering firm)
• Read database facts
• Analyze user question
↓
Reasoning:
• User asks: "How many projects do we have?"
• Database shows: 10 project records
• Task: Count and summarize
↓
Generate Response:
• Start with direct answer: "We have 10 projects"
• Provide details: List project names
• Add context: Include client info, status
• Format nicely: Use bullets/numbers
↓
Output: Formatted text response
2. Response Quality Factors
Good Prompt = Good Response
- ✓ Clear system context
- ✓ Structured database facts
- ✓ Specific user question
- ✓ Clear instructions
- = High-quality, relevant response
Error Handling
Error Messages
User-Facing (Friendly)
- "Please enter a message"
- "Message is too long (max 500 characters)"
- "Unable to connect. Please try again"
- "Too many requests. Please wait 30 seconds"
- "An error occurred. Please try again"
Developer-Facing (Logged)
- "Chat API error: [exception message]"
- "Database connection failed: [details]"
- "Claude API error: HTTP 429 - [response]"
- "Rate limit check for IP: [ip_address]"
Performance Metrics
Timing Breakdown
Total Request Time: ~2-5 seconds
| Component | Time |
|---|---|
| Frontend Processing | ~50ms |
| Network to Server | ~20-50ms |
| Security Validation | ~10ms |
| Database Queries | ~50-100ms |
| Format for AI | ~5ms |
| Claude API Call | ~1-3s ← Largest component |
| Response Processing | ~10ms |
| Network to Client | ~20-50ms |
| Frontend Display | ~20ms |
Optimization Points
- Database Queries: < 100ms (indexed searches)
- AI API: 1-3 seconds (external service)
- Rate Limiting: File-based (fast access)
- Caching: Conversation ID in sessionStorage
Summary
Key Components
- Frontend:
chat-widget.js- User interface - API Endpoint:
chat.php- Request router - Security:
security.php- Rate limiting - Database:
database-query.php- Search logic - AI:
ai-integration.php- Claude API - Databases: CMS + ProjectTracker
Data Flow
User Input → Validation → Security → Database Search → AI Processing → Response
Decision Points
- Which database to query? → Keyword analysis
- List all or search? → Pattern detection
- Include milestones? → Keyword presence
- Include submittals? → Keyword presence
Success Factors
- ✅ Clear user questions
- ✅ Relevant database results
- ✅ Well-structured prompts
- ✅ Fast database queries
- ✅ Proper error handling
📝 Document Version: 1.0
📅 Last Updated: October 17, 2025
✅ Status: Complete Technical Documentation
📅 Last Updated: October 17, 2025
✅ Status: Complete Technical Documentation