graph TB
subgraph "Client Layer"
User[👤 User Browser]
API_Client[🔌 API Client<br/>Enterprise Tier]
end
subgraph "Vercel Platform"
subgraph "Flask Application"
WebApp[🌐 Flask Web Server<br/>api/index.py]
Auth[🔐 Flask-Login<br/>Session Management]
Routes[📍 Route Handlers<br/>Upload/Status/Results]
LLM_Service[🧠 LLM Service<br/>api/llm_service.py<br/>Document Analysis]
API_Routes[🔌 API Endpoints<br/>/api/v1/*<br/>Enterprise Access]
end
end
subgraph "External Authentication"
Google[🔑 Google OAuth 2.0<br/>Identity Provider]
end
subgraph "Payment Processing"
Stripe[💳 Stripe<br/>Subscription Management<br/>Free/Pro/Enterprise]
end
subgraph "AWS Cloud Services"
subgraph "Storage Layer"
S3[📦 Amazon S3<br/>Document Storage<br/>CSV & JSON Results<br/>Presigned URLs]
end
subgraph "Processing Layer"
Textract[📄 AWS Textract<br/>OCR Processing<br/>Text Extraction]
Bedrock[🤖 Amazon Bedrock<br/>Claude 3 Haiku<br/>Intelligent Analysis]
end
IAM[🔒 AWS IAM<br/>Access Control<br/>S3/Textract/Bedrock]
end
subgraph "Database Layer"
Neon[(🗄️ PostgreSQL<br/>Neon Hosted<br/>User Data & Usage<br/>Document History<br/>API Keys)]
end
%% User Interactions
User -->|HTTPS Requests| WebApp
User -->|OAuth Flow| Google
User -->|Payment Flow| Stripe
API_Client -->|Bearer Token| API_Routes
%% Application Flow
WebApp -->|Authenticate| Auth
WebApp -->|Query/Update| Neon
WebApp -->|OAuth Callback| Google
WebApp -->|Create Checkout| Stripe
Stripe -->|Webhook Events| WebApp
API_Routes -->|Validate API Key| Neon
API_Routes -->|Process Request| Routes
%% AWS Service Interactions
WebApp -->|Upload Documents| S3
WebApp -->|Start OCR Job| Textract
WebApp -->|Invoke LLM Analysis| LLM_Service
LLM_Service -->|Analyze Text| Bedrock
WebApp -->|Store JSON Results| S3
WebApp -->|Generate Download URL| S3
Textract -->|Read Documents| S3
Bedrock -->|Return Structured Data| LLM_Service
IAM -->|Authorize| S3
IAM -->|Authorize| Textract
IAM -->|Authorize| Bedrock
%% Styling
classDef aws fill:#FF9900,stroke:#232F3E,stroke-width:2px,color:#232F3E
classDef vercel fill:#000000,stroke:#FFFFFF,stroke-width:2px,color:#FFFFFF
classDef external fill:#4285F4,stroke:#1967D2,stroke-width:2px,color:#FFFFFF
classDef database fill:#336791,stroke:#1A3A52,stroke-width:2px,color:#FFFFFF
classDef user fill:#34A853,stroke:#1E8E3E,stroke-width:2px,color:#FFFFFF
class S3,Textract,Bedrock,IAM aws
class WebApp,Auth,Routes,LLM_Service,API_Routes vercel
class Google,Stripe external
class Neon database
class User,API_Client user
- User Browser: End users interact with the application through web browsers
- API Client: Enterprise tier users access via REST API with Bearer token authentication
- HTTPS: All communication secured with TLS encryption
- Flask Web Server: Python-based web application with factory pattern
- Flask-Login: Manages user sessions and authentication state
- Route Handlers: Process uploads, status checks, and result delivery
- LLM Service (
api/llm_service.py):- Orchestrates document analysis with Amazon Bedrock
- Supports multiple analysis types (general, invoice, contract, form)
- Generates structured JSON output from extracted text
- API Endpoints: RESTful API for Enterprise tier programmatic access
/api/v1/analyze- Submit documents for processing/api/v1/status/{job_id}- Check processing status/api/v1/result/{job_id}- Retrieve analysis results
- Google OAuth 2.0: Handles user authentication and identity verification
- Stripe: Manages subscription payments across three tiers:
- Free: 5 docs/month, 2 LLM analyses
- Pro: 200 docs/month, 50 LLM analyses ($10/month)
- Enterprise: 1000 docs/month, 500 LLM analyses, API access ($99/month)
- Amazon S3:
- Stores uploaded documents
- Hosts processed CSV files (raw text)
- Stores JSON files (structured analysis results)
- Generates presigned URLs for secure downloads
- Retention policies: 90 days (Free), 365 days (Pro), 730 days (Enterprise)
- AWS Textract:
- Performs OCR on uploaded documents
- Extracts text from PDFs and images
- Supports multi-page documents
- Async processing with job polling
- Amazon Bedrock (NEW):
- Claude 3 Haiku model for intelligent document analysis
- Extracts structured data from unstructured text
- Identifies entities, key terms, and document insights
- Specialized prompts for different document types
- Low-temperature inference for consistent results
- AWS IAM:
- Controls access permissions for S3, Textract, and Bedrock
- Secures service-to-service communication
- Enforces least-privilege access
- PostgreSQL (Neon):
- Stores user profiles and OAuth data
- Tracks usage metrics for freemium limits (documents + LLM analyses)
- Manages subscription status and tier information
- Document history with metadata (filename, type, processing time)
- API key storage for Enterprise users (hashed)
- User uploads document via web interface
- User selects analysis type (general/invoice/contract/form) and enables LLM
- Flask app checks user quota (documents + LLM analyses remaining)
- Flask app stores document in S3
- Flask app initiates Textract OCR job
- Textract reads document from S3 and processes
- Flask app polls for job completion
- [NEW] If LLM enabled: Flask invokes LLM Service with extracted text
- [NEW] LLM Service sends text to Amazon Bedrock (Claude 3 Haiku)
- [NEW] Bedrock returns structured JSON analysis
- [NEW] Flask stores JSON results to S3
- Flask saves CSV (raw text) to S3
- [NEW] Flask saves document metadata to database (history table)
- User views results in tabbed interface (Text + Analysis)
- User downloads CSV and/or JSON via presigned URLs
- User clicks "Login with Google"
- Redirected to Google OAuth consent screen
- Google returns authorization code
- Flask exchanges code for user profile
- User session created with Flask-Login
- User data stored/updated in PostgreSQL
- Usage counters initialized (documents, LLM analyses)
- User clicks upgrade to Pro or Enterprise
- Flask creates Stripe checkout session with appropriate price ID
- User completes payment on Stripe
- Stripe sends webhook to Flask
- Flask updates user subscription status in database
- User quota limits updated based on new tier
- [NEW] Enterprise users can generate API keys
- Client sends POST request to
/api/v1/analyzewith Bearer token - Flask validates API key against database
- Flask checks Enterprise tier and rate limits (100 req/hour)
- Document processed through standard OCR + LLM pipeline
- Flask returns job ID and status URL
- Client polls
/api/v1/status/{job_id}for completion - Client retrieves results from
/api/v1/result/{job_id} - Response includes CSV URL, JSON URL, and structured analysis data
- Check if user enabled "AI Analysis" toggle
- Verify user has LLM analyses remaining in quota
- Determine analysis type from user selection or auto-detect
- Select specialized prompt template:
- General: Summary, key points, entities, document type
- Invoice: Vendor, amounts, line items, dates, tax
- Contract: Parties, terms, obligations, important clauses
- Form: Field extraction, completeness, structured data
- Send prompt + extracted text to Bedrock
- Parse and validate JSON response
- Increment user's LLM usage counter
- Store results and return to user
This application demonstrates autonomous AI agent behavior through:
- Automatically selects appropriate analysis strategy based on document type
- Determines optimal prompt template without human intervention
- Manages quota enforcement and tier-based feature access
- Orchestrates multi-service workflow: S3 → Textract → Bedrock → S3
- Handles async processing with intelligent polling
- Manages error recovery and retry logic
- Uses Claude 3 Haiku to understand document context
- Extracts structured insights from unstructured text
- Identifies entities, relationships, and key information
- Adapts analysis depth based on document complexity
- Processes documents end-to-end without human intervention
- Automatically stores results and generates download links
- Maintains document history and usage tracking
- Handles payment webhooks and tier upgrades autonomously
| Service | Cost per Document | Notes |
|---|---|---|
| AWS Textract | $0.0015 | 1 page average |
| Amazon Bedrock (Claude 3 Haiku) | $0.0001 | ~400 tokens input/output |
| S3 Storage | $0.000023 | Per MB per month |
| Total with LLM | ~$0.0016 | Per document with AI analysis |
| Total without LLM | ~$0.0015 | OCR only |
| Tier | Monthly Price | Max Docs | Max LLM | AWS Cost | Margin |
|---|---|---|---|---|---|
| Free | $0 | 5 | 2 | $0.0083 | -100% (acquisition) |
| Pro | $10 | 200 | 50 | $0.38 | 96.2% |
| Enterprise | $99 | 1000 | 500 | $1.88 | 98.1% |
Note: Margins assume maximum usage. Actual margins are higher due to typical usage patterns.
- All documents encrypted in transit (HTTPS) and at rest (S3 encryption)
- Presigned URLs expire after 5 minutes
- API keys hashed using cryptography library
- No document content stored in database
- IAM policies enforce least-privilege access
- API rate limiting (100 requests/hour per key)
- Tier-based feature gating
- Session management with secure cookies
- GDPR-ready with data retention policies
- User data deletion on account closure
- Audit trail in database for all operations
- Webhook signature verification for Stripe events
- Vercel: Serverless auto-scaling for web tier
- AWS Services: Managed services with automatic scaling
- Neon PostgreSQL: Connection pooling and auto-scaling storage
- S3: Unlimited storage capacity
- OCR Processing: 2-5 seconds per page (Textract)
- LLM Analysis: 1-3 seconds per document (Bedrock)
- Total Processing: 3-8 seconds for typical document
- API Response: <100ms for status checks
- Download Speed: Limited by S3 presigned URL bandwidth
- Database Connections: Neon connection pooling handles concurrent users
- Textract Rate Limits: Async processing with job queuing
- Bedrock Rate Limits: 10,000 requests/minute (well above needs)
- S3 Rate Limits: 5,500 PUT/s per prefix (no practical limit)
- Jinja2 Templates: Server-side rendering
- Vanilla JavaScript: AJAX polling, dynamic UI updates
- Font Awesome: Icons and UI elements
- CSS: Inline styling for simplicity
- Flask: Web framework with application factory pattern
- Flask-Login: Session management and authentication
- Flask-SQLAlchemy: ORM for PostgreSQL
- boto3: AWS SDK for Python (S3, Textract, Bedrock)
- python-dotenv: Environment variable management
- Amazon S3: Document and result storage
- AWS Textract: OCR text extraction
- Amazon Bedrock: LLM-powered document analysis (Claude 3 Haiku)
- AWS IAM: Access control and security
- Google OAuth 2.0: User authentication
- Stripe: Payment processing and subscriptions
- Neon: Managed PostgreSQL hosting
- Vercel: Application hosting and deployment
- Python 3.9+: Programming language
- pip: Package management
- venv: Virtual environment
- AWS CLI: AWS service testing (optional)
User Request → Vercel Edge Network → Flask App (Serverless) → AWS Services
→ PostgreSQL (Neon)
→ External APIs
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGIONS3_BUCKETGOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRETSTRIPE_SECRET_KEY,STRIPE_PUBLISHABLE_KEY,STRIPE_WEBHOOK_SECRETSTRIPE_SUBSCRIPTION_PRICE_ID,STRIPE_ENTERPRISE_PRICE_IDDATABASE_URLSECRET_KEY
- Vercel Logs: Application logs and errors
- AWS CloudWatch: Service-level metrics (Textract, Bedrock)
- Stripe Dashboard: Payment and subscription analytics
- Database Metrics: Query performance and connection pooling (Neon)
- Multi-language OCR: Support for non-English documents
- Batch Processing: Upload and process multiple documents at once
- Webhook Notifications: Real-time alerts when processing completes
- Custom Prompts: Enterprise users can define custom analysis templates
- Document Comparison: Diff analysis between document versions
- Advanced Analytics: Dashboard with usage trends and insights
- Caching Layer: Redis for frequently accessed results
- Queue System: SQS for better async job management
- CDN Integration: CloudFront for faster global access
- Multi-region: Deploy to multiple AWS regions for lower latency
- Database Optimization: Read replicas for history queries
- API Versioning: Support multiple API versions for backward compatibility
- Multi-model Support: GPT-4, Gemini, or custom models
- Fine-tuning: Custom Claude models for specific document types
- Confidence Scores: Quality metrics for extracted data
- Auto-classification: Automatic document type detection
- Entity Linking: Connect extracted entities to knowledge bases
- Summarization: Multi-document summarization and comparison