# Job Forge - Python/FastAPI Web Application Architecture **Version:** 1.0.0 Prototype **Status:** Development Phase 1 **Date:** August 2025 **Scope:** AI-powered job application management web application **Target:** Prototype development for server deployment --- ## 📋 Application Scope & Objectives ### Core Web Application Features - **User Authentication**: JWT-based secure authentication system - **Job Application Management**: Full CRUD operations for job applications - **AI-Powered Document Generation**: Automated cover letter and resume optimization - **Web Interface**: Modern responsive web interface using Dash + Mantine - **Multi-tenant Architecture**: Secure user data isolation with RLS ### Development Goals - Deploy functional prototype to personal server - Validate AI workflow effectiveness for job applications - Test web application performance and user experience - Establish scalable architecture for future enhancements - Demonstrate full-stack Python/FastAPI capabilities --- ## 🏗️ Web Application Architecture ### System Overview ```mermaid graph TB subgraph "Web Frontend (Dash + Mantine)" UI[Dashboard Interface] FORMS[Application Forms] EDITOR[Document Editor] VIEWER[Document Viewer] end subgraph "Backend API (FastAPI)" AUTH[JWT Authentication] CRUD[Application CRUD] AI[AI Service Layer] FILES[Document Management] end subgraph "AI Agents" RESEARCH[Research Agent] RESUME[Resume Optimizer] COVER[Cover Letter Generator] end subgraph "Data Storage" PG[(PostgreSQL + pgvector)] FILES[Document Storage] end subgraph "External AI" CLAUDE[Claude AI] OPENAI[OpenAI Embeddings] end UI --> AUTH FORMS --> CRUD EDITOR --> FILES VIEWER --> FILES CRUD --> AI AI --> RESEARCH AI --> RESUME AI --> COVER CRUD --> PG FILES --> PG RESEARCH --> CLAUDE RESUME --> CLAUDE COVER --> CLAUDE AI --> OPENAI ``` --- ## 🔐 User Authentication (Web Application) ### JWT-Based Authentication System ```python class AuthenticationService: """JWT-based authentication for web application""" async def register_user(self, user_data: UserCreate) -> User: """Register new user account with validation""" async def authenticate_user(self, credentials: UserLogin) -> AuthResult: """Authenticate user and return JWT access token""" async def verify_token(self, token: str) -> User: """Verify JWT token and return authenticated user""" async def refresh_token(self, refresh_token: str) -> AuthResult: """Refresh JWT access token""" def create_access_token(self, user_id: str) -> str: """Create JWT access token with expiration""" ``` ### Database Schema (Users) ```sql -- User table with enhanced security CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Enable row level security for multi-tenancy ALTER TABLE users ENABLE ROW LEVEL SECURITY; -- Create index for performance CREATE INDEX idx_users_email ON users(email); CREATE INDEX idx_users_active ON users(is_active); ``` --- ## 📋 Job Application Module ### Core Application Workflow ```python class ApplicationService: """Core job application management""" async def create_application(self, user_id: str, job_data: JobApplicationData) -> Application: """Create new job application with job description and URL""" async def get_user_applications(self, user_id: str) -> List[Application]: """Get all applications for user""" async def get_application(self, user_id: str, app_id: str) -> Application: """Get specific application with documents""" async def update_application_status(self, user_id: str, app_id: str, status: str) -> None: """Update application status through workflow phases""" ``` ### Application Data Model ```python class JobApplicationData(BaseModel): """Input data for creating new application""" job_url: Optional[str] = None job_description: str company_name: str role_title: str location: Optional[str] = None priority_level: str = "medium" additional_context: Optional[str] = None class Application(BaseModel): """Core application entity""" id: str user_id: str name: str # Auto-generated: company_role_YYYY_MM_DD company_name: str role_title: str job_url: Optional[str] job_description: str status: ApplicationStatus # draft, research_complete, resume_ready, cover_letter_ready # Phase completion tracking research_completed: bool = False resume_optimized: bool = False cover_letter_generated: bool = False created_at: datetime updated_at: datetime ``` ### Database Schema (Applications) ```sql CREATE TABLE applications ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, company_name VARCHAR(255) NOT NULL, role_title VARCHAR(255) NOT NULL, job_url TEXT, job_description TEXT NOT NULL, location VARCHAR(255), priority_level VARCHAR(20) DEFAULT 'medium', status VARCHAR(50) DEFAULT 'draft', -- Phase tracking research_completed BOOLEAN DEFAULT FALSE, resume_optimized BOOLEAN DEFAULT FALSE, cover_letter_generated BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); ALTER TABLE applications ENABLE ROW LEVEL SECURITY; CREATE POLICY user_applications_policy ON applications FOR ALL TO application_user USING (user_id = current_setting('app.current_user_id')::UUID); ``` --- ## 🤖 AI Processing Workflow ### 3-Phase AI Orchestrator ```python class AIOrchestrator: """Orchestrates the 3-phase AI workflow""" def __init__(self, research_agent, resume_optimizer, cover_letter_generator): self.research_agent = research_agent self.resume_optimizer = resume_optimizer self.cover_letter_generator = cover_letter_generator async def execute_research_phase(self, application_id: str) -> ResearchReport: """Phase 1: Job analysis and company research""" async def execute_resume_optimization(self, application_id: str) -> OptimizedResume: """Phase 2: Resume optimization based on research""" async def execute_cover_letter_generation(self, application_id: str, user_context: str) -> CoverLetter: """Phase 3: Cover letter generation with user inputs""" ``` ### Phase 1: Research Agent ```python class ResearchAgent: """Job description analysis and company research""" async def analyze_job_description(self, job_desc: str) -> JobAnalysis: """Extract requirements, skills, and key information""" async def research_company_info(self, company_name: str) -> CompanyIntelligence: """Basic company research and insights""" async def generate_strategic_positioning(self, job_analysis: JobAnalysis) -> StrategicPositioning: """Determine optimal candidate positioning""" async def create_research_report(self, job_desc: str, company_name: str) -> ResearchReport: """Complete research phase output""" ``` ### Phase 2: Resume Optimizer ```python class ResumeOptimizer: """Resume optimization based on job requirements""" async def analyze_resume_portfolio(self, user_id: str) -> ResumePortfolio: """Load and analyze user's resume library""" async def optimize_resume_for_job(self, portfolio: ResumePortfolio, research: ResearchReport) -> OptimizedResume: """Create job-specific optimized resume""" async def validate_resume_optimization(self, resume: OptimizedResume) -> ValidationReport: """Ensure resume meets requirements and constraints""" ``` ### Phase 3: Cover Letter Generator ```python class CoverLetterGenerator: """Cover letter generation with user context""" async def analyze_writing_style(self, user_id: str) -> WritingStyle: """Analyze user's writing patterns from reference documents""" async def generate_cover_letter(self, research: ResearchReport, resume: OptimizedResume, user_context: str, writing_style: WritingStyle) -> CoverLetter: """Generate personalized cover letter""" async def validate_cover_letter(self, cover_letter: CoverLetter) -> ValidationReport: """Ensure cover letter quality and authenticity""" ``` --- ## 📄 Document Management ### Document Storage & Retrieval ```python class DocumentService: """Handle document storage and retrieval""" async def save_document(self, user_id: str, app_id: str, doc_type: str, content: str) -> None: """Save generated document (research, resume, cover letter)""" async def get_document(self, user_id: str, app_id: str, doc_type: str) -> Document: """Retrieve document for viewing/editing""" async def update_document(self, user_id: str, app_id: str, doc_type: str, content: str) -> None: """Update document after user editing""" async def get_all_documents(self, user_id: str, app_id: str) -> ApplicationDocuments: """Get all documents for an application""" ``` ### Document Models ```python class Document(BaseModel): """Base document model""" id: str application_id: str document_type: str # research_report, optimized_resume, cover_letter content: str created_at: datetime updated_at: datetime class ApplicationDocuments(BaseModel): """All documents for an application""" research_report: Optional[Document] = None optimized_resume: Optional[Document] = None cover_letter: Optional[Document] = None ``` ### Database Schema (Documents) ```sql CREATE TABLE documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), application_id UUID REFERENCES applications(id) ON DELETE CASCADE, document_type VARCHAR(50) NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); ALTER TABLE documents ENABLE ROW LEVEL SECURITY; CREATE POLICY user_documents_policy ON documents FOR ALL TO application_user USING ( application_id IN ( SELECT id FROM applications WHERE user_id = current_setting('app.current_user_id')::UUID ) ); ``` --- ## 🎨 Frontend Interface (Dash + Mantine) ### Main Application Layout ```python class JobForgeApp: """Main Dash application layout""" def create_layout(self): return dmc.MantineProvider([ dmc.AppShell([ dmc.Navbar([ ApplicationSidebar() ], width={"base": 300}), dmc.Main([ ApplicationTopBar(), MainContent() ]) ]) ]) ``` ### Application Sidebar ```python class ApplicationSidebar: """Sidebar with applications list and navigation""" def render(self, user_id: str): return dmc.Stack([ # New Application Button dmc.Button( "➕ New Application", id="new-app-btn", fullWidth=True, variant="filled" ), # Applications List dmc.Title("Applications", order=4), dmc.ScrollArea([ ApplicationCard(app) for app in self.get_user_applications(user_id) ]), # Resume Library Section dmc.Divider(), dmc.Title("Resume Library", order=4), ResumeLibrarySection() ]) class ApplicationCard: """Individual application card in sidebar""" def render(self, application: Application): return dmc.Card([ dmc.Group([ dmc.Text(application.company_name, weight=600), StatusBadge(application.status) ]), dmc.Text(application.role_title, size="sm", color="dimmed"), dmc.Text(application.created_at.strftime("%Y-%m-%d"), size="xs") ], id=f"app-card-{application.id}") ``` ### Application Top Bar Navigation ```python class ApplicationTopBar: """Top navigation bar for application phases""" def render(self, application: Application): return dmc.Group([ # Phase Navigation Buttons PhaseButton("Research", "research", application.research_completed), PhaseButton("Resume", "resume", application.resume_optimized), PhaseButton("Cover Letter", "cover_letter", application.cover_letter_generated), # Application Actions dmc.Spacer(), dmc.ActionIcon( DashIconify(icon="tabler:settings"), id="app-settings-btn" ) ]) class PhaseButton: """Navigation button for each phase""" def render(self, label: str, phase: str, completed: bool): icon = "tabler:check" if completed else "tabler:clock" color = "green" if completed else "gray" return dmc.Button([ DashIconify(icon=icon), dmc.Text(label, ml="xs") ], variant="subtle" if not completed else "filled", color=color, id=f"phase-{phase}-btn" ) ``` ### Document Editor Interface ```python class DocumentEditor: """Markdown document editor with preview""" def render(self, document: Document): return dmc.Container([ dmc.Grid([ # Editor Column dmc.Col([ dmc.Title(f"Edit {document.document_type.replace('_', ' ').title()}", order=3), dmc.Textarea( value=document.content, placeholder="Document content...", minRows=20, autosize=True, id=f"editor-{document.document_type}" ), dmc.Group([ dmc.Button("Save Changes", id="save-btn"), dmc.Button("Cancel", variant="outline", id="cancel-btn") ]) ], span=6), # Preview Column dmc.Col([ dmc.Title("Preview", order=3), dmc.Container([ dcc.Markdown(document.content, id="preview-content") ], style={"border": "1px solid #e0e0e0", "padding": "1rem", "minHeight": "500px"}) ], span=6) ]) ]) ``` --- ## 🗄️ MVP Database Schema ### Complete Database Setup ```sql -- Enable required extensions CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE EXTENSION IF NOT EXISTS vector; -- Users table CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, full_name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Applications table CREATE TABLE applications ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, company_name VARCHAR(255) NOT NULL, role_title VARCHAR(255) NOT NULL, job_url TEXT, job_description TEXT NOT NULL, location VARCHAR(255), priority_level VARCHAR(20) DEFAULT 'medium', status VARCHAR(50) DEFAULT 'draft', research_completed BOOLEAN DEFAULT FALSE, resume_optimized BOOLEAN DEFAULT FALSE, cover_letter_generated BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Documents table CREATE TABLE documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), application_id UUID REFERENCES applications(id) ON DELETE CASCADE, document_type VARCHAR(50) NOT NULL, content TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), UNIQUE(application_id, document_type) ); -- Resume library table CREATE TABLE user_resumes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, name VARCHAR(255) NOT NULL, content TEXT NOT NULL, focus_area VARCHAR(100), is_primary BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Basic vector embeddings (for future enhancement) CREATE TABLE document_embeddings ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), document_id UUID REFERENCES documents(id) ON DELETE CASCADE, embedding vector(1536), created_at TIMESTAMP DEFAULT NOW() ); -- Row Level Security ALTER TABLE users ENABLE ROW LEVEL SECURITY; ALTER TABLE applications ENABLE ROW LEVEL SECURITY; ALTER TABLE documents ENABLE ROW LEVEL SECURITY; ALTER TABLE user_resumes ENABLE ROW LEVEL SECURITY; -- Security policies CREATE POLICY user_own_data ON applications FOR ALL USING (user_id = current_setting('app.current_user_id')::UUID); CREATE POLICY user_own_documents ON documents FOR ALL USING ( application_id IN (SELECT id FROM applications WHERE user_id = current_setting('app.current_user_id')::UUID) ); CREATE POLICY user_own_resumes ON user_resumes FOR ALL USING (user_id = current_setting('app.current_user_id')::UUID); ``` --- ## 🚀 Web Application Development Plan ### Development Phases #### **Phase 1: Infrastructure & Authentication (Weeks 1-2)** - Docker containerization for development and production - PostgreSQL 16 with pgvector extension setup - FastAPI backend with JWT authentication - Row Level Security (RLS) implementation - Basic CI/CD pipeline setup #### **Phase 2: Core Web Application (Weeks 3-4)** - Dash + Mantine responsive web interface - Application CRUD operations with API endpoints - User dashboard and application management - Database integration with async operations - Multi-tenant data isolation #### **Phase 3: AI Integration (Weeks 5-6)** - Claude API integration for document generation - OpenAI API for embeddings and analysis - Async AI service layer implementation - Error handling and retry mechanisms - AI service rate limiting and monitoring #### **Phase 4: Production Deployment (Weeks 7-8)** - Server deployment with Docker Compose - Nginx reverse proxy and SSL configuration - Database backup and monitoring setup - Performance optimization and caching - Security hardening and testing ### Prototype Success Criteria - ✅ Secure multi-user web application deployed to server - ✅ JWT-based authentication with user registration/login - ✅ Full CRUD operations for job applications - ✅ AI-powered cover letter generation via web interface - ✅ Responsive web UI with modern UX design - ✅ Secure data storage with user isolation (RLS) - ✅ Production-ready deployment with monitoring - ✅ Scalable architecture for future enhancements --- ## 🐳 Docker Production Deployment ### Production Environment ```yaml # docker-compose.yml version: '3.8' services: # FastAPI + Dash Web Application jobforge-app: build: context: . dockerfile: Dockerfile target: production container_name: jobforge-app environment: - DATABASE_URL=postgresql://jobforge:${DB_PASSWORD}@postgres:5432/jobforge - CLAUDE_API_KEY=${CLAUDE_API_KEY} - OPENAI_API_KEY=${OPENAI_API_KEY} - JWT_SECRET=${JWT_SECRET} - DEBUG=false - LOG_LEVEL=INFO volumes: - ./uploads:/app/uploads - ./logs:/var/log/jobforge depends_on: postgres: condition: service_healthy networks: - jobforge-network restart: unless-stopped # PostgreSQL with pgvector postgres: image: pgvector/pgvector:pg16 container_name: jobforge-postgres environment: - POSTGRES_DB=jobforge - POSTGRES_USER=jobforge - POSTGRES_PASSWORD=${DB_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data - ./backups:/backups networks: - jobforge-network restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U jobforge -d jobforge"] interval: 10s timeout: 5s retries: 5 # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: jobforge-nginx ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl:/etc/nginx/ssl:ro depends_on: - jobforge-app networks: - jobforge-network restart: unless-stopped networks: jobforge-network: driver: bridge volumes: postgres_data: driver: local ``` --- ## 📁 Web Application Project Structure ``` job-forge/ ├── docker-compose.yml ├── Dockerfile ├── requirements.txt ├── requirements-dev.txt ├── .env.example ├── pytest.ini ├── alembic.ini ├── CLAUDE.md ├── README.md ├── app/ │ ├── main.py # FastAPI + Dash application entry │ ├── core/ │ │ ├── config.py # Application configuration │ │ ├── database.py # Database connection and session │ │ ├── security.py # JWT authentication utilities │ │ └── exceptions.py # Custom exception handlers │ ├── api/ │ │ ├── v1/ │ │ │ ├── auth.py # Authentication endpoints │ │ │ ├── applications.py # Application CRUD endpoints │ │ │ └── documents.py # Document management endpoints │ │ └── dependencies.py # FastAPI dependencies │ ├── models/ │ │ ├── user.py # User SQLAlchemy model │ │ ├── application.py # Application SQLAlchemy model │ │ └── document.py # Document SQLAlchemy model │ ├── schemas/ │ │ ├── user.py # User Pydantic schemas │ │ ├── application.py # Application Pydantic schemas │ │ └── auth.py # Authentication schemas │ ├── crud/ │ │ ├── user.py # User database operations │ │ ├── application.py # Application database operations │ │ └── document.py # Document database operations │ ├── services/ │ │ ├── auth.py # Authentication service │ │ ├── application.py # Application business logic │ │ └── ai/ │ │ ├── claude_service.py # Claude API integration │ │ ├── openai_service.py # OpenAI API integration │ │ └── document_generator.py # AI document generation │ └── frontend/ │ ├── app.py # Dash application setup │ ├── layouts/ │ │ ├── dashboard.py # Main dashboard layout │ │ ├── auth.py # Login/register layouts │ │ └── application.py # Application detail layout │ ├── components/ │ │ ├── navigation.py # Navigation components │ │ ├── forms.py # Form components │ │ └── modals.py # Modal components │ └── callbacks/ │ ├── auth.py # Authentication callbacks │ ├── application.py # Application callbacks │ └── navigation.py # Navigation callbacks ├── alembic/ │ ├── versions/ # Database migration files │ └── env.py # Alembic configuration ├── tests/ │ ├── conftest.py # Pytest configuration and fixtures │ ├── unit/ # Unit tests │ ├── integration/ # Integration tests │ └── e2e/ # End-to-end tests ├── docs/ │ ├── README.md # Main documentation hub │ ├── development/ # Development documentation │ ├── infrastructure/ # Deployment documentation │ └── testing/ # Testing documentation ├── nginx/ │ └── nginx.conf # Nginx configuration ├── logs/ # Application logs ├── uploads/ # File uploads └── backups/ # Database backups ``` --- *This web application architecture provides a comprehensive, production-ready solution for AI-powered job application management. The FastAPI backend with Dash frontend delivers a modern web experience while maintaining scalability and security for prototype development and future enhancements.*