Introduction
The Interview Simulator follows a clean, layered architecture pattern that separates concerns across four distinct layers: Routes, Services, Repositories, and Models. This architecture promotes maintainability, testability, and scalability.Architectural Diagram
Layer Responsibilities
Routes Layer (app/routes)
Routes Layer (app/routes)
The Routes layer handles HTTP requests and responses. It’s responsible for:Key files:
- Receiving and validating incoming HTTP requests
- Extracting data from request forms, JSON, or query parameters
- Calling appropriate service methods
- Handling errors and returning appropriate HTTP responses
- Managing Flask sessions for user state
session_routes.py- Session CRUD operationsdocument_routes.py- CV and job description uploadsinterview_routes.py- Interview conversation flowfeedback_routes.py- Feedback generation and displayerrors.py- Error handlers
Services Layer (app/services)
Services Layer (app/services)
The Services layer contains business logic and orchestration. It:Key services:
- Implements core business rules and validation
- Orchestrates operations across multiple repositories
- Coordinates with external systems (AI providers)
- Handles complex workflows that span multiple data entities
SessionService- Session lifecycle managementDocumentService- File upload and text extractionInterviewService- Interview flow orchestrationFeedbackService- Feedback generation and analysis
Repositories Layer (app/repositories)
Repositories Layer (app/repositories)
The Repositories layer abstracts database operations. It:Key repositories:
- Provides a clean interface for data access
- Encapsulates all SQLAlchemy queries
- Handles database transactions and error handling
- Manages eager/lazy loading strategies
SessionRepository- Session CRUD and queriesMessageRepository- Conversation message storageFeedbackRepository- Feedback persistenceFileRepository- Uploaded file management
Models Layer (app/models)
Models Layer (app/models)
The Models layer defines data structures and relationships. It:
- Defines SQLAlchemy ORM models
- Declares database schema through Python classes
- Establishes relationships between entities
- Provides data validation at the database level
Tech Stack
Backend Framework
- Flask 3.0: Lightweight Python web framework
- SQLAlchemy: SQL toolkit and ORM
- SQLite: Development database (PostgreSQL recommended for production)
AI Integration
- Google Gemini: Primary AI provider for question generation
- OpenRouter: Alternative AI provider with multiple model options
- Provider Pattern: Abstracted
AIProviderprotocol for easy provider switching - Tenacity: Retry logic with exponential backoff for API reliability
Frontend
- HTMX: Dynamic server interactions without complex JavaScript
- Jinja2: Server-side HTML templating
- Custom CSS: Styling with
main.css
Document Processing
- pdfplumber: PDF text extraction
- python-docx: Word document parsing
- Plain text: Direct text input support
Key Design Decisions
1. Layered Architecture
Why this approach?- Separation of Concerns: Each layer has a single, well-defined responsibility
- Testability: Services can be tested in isolation by mocking repositories
- Maintainability: Changes to one layer don’t cascade to others
- Scalability: Layers can be optimized or replaced independently
- More boilerplate code for simple CRUD operations
- Requires discipline to maintain layer boundaries
2. HTMX Over React/Vue
Why HTMX?- Server-side rendering: All logic stays in Python
- Minimal JavaScript: No build process, webpack, or npm dependencies
- Progressive enhancement: Works without JavaScript enabled
- Fast development: No context switching between frontend/backend
- Limited client-side interactivity
- Not ideal for complex SPAs
- Less suitable for offline-first applications
3. Provider Pattern for AI
Implementation:- Easy to switch between AI providers
- Can add new providers without changing business logic
- Supports fallback strategies (try Gemini, fall back to OpenRouter)
- Enables A/B testing of different AI models
4. Session-Based State Management
Why sessions instead of authentication?- MVP scope: Authentication adds complexity for initial launch
- Quick onboarding: Users can start interviews immediately
- Privacy: No email or personal data collection required
- Simplicity: Flask sessions are built-in and straightforward
- Cross-device session access
- Long-term progress tracking
- Premium features
5. Document Parser Abstraction
Why abstract file parsing?- Single interface for PDF, DOCX, and TXT files
- Graceful error handling for corrupted files
- Easy to add new formats (e.g., Google Docs export)
- Consistent text extraction across formats
Application Flow
- Create Session → User provides job title and company name
- Upload Documents → CV and job description uploaded and parsed
- Start Interview → AI generates first question based on documents
- Conversation Loop → User answers, AI asks follow-up (up to 8 questions)
- Generate Feedback → AI analyzes performance and provides scores
- View Results → User sees strengths, weaknesses, and CV improvement tips
Next Steps
- Review the Database Schema to understand data models
- Explore the Project Structure to navigate the codebase
- Check the API Reference for endpoint documentation