Files
Resume-Matcher/docs/frontend-workflow.md
srbhr b833bf3db7 feat: enhance documentation and remove deprecated files
- Added a comprehensive Table of Contents to AGENTS.md for improved navigation.
- Expanded documentation with new backend and frontend guides, detailing architecture, API contracts, and workflows.
- Introduced new documents for backend architecture and requirements, outlining system design and API specifications.
- Removed outdated Makefile and setup.sh scripts to streamline project setup.
- Deleted yarn.lock to eliminate unnecessary dependency management files.
- Updated AGENTS.md to reflect changes in documentation structure and links.
2025-12-29 16:27:39 +05:30

15 KiB
Raw Blame History

Frontend Workflow Documentation

This document outlines the user flow and architecture for the Resume Matcher frontend. The application follows a "Master Resume" centric workflow, allowing users to maintain a base resume and tailor it for specific job descriptions.

Core Workflow

1. Dashboard & Initialization (/dashboard)

The entry point of the application.

  • State: Checks localStorage for a master_resume_id.
  • No Master Resume: Displays an "Initialize Master Resume" card.
    • Triggers ResumeUploadDialog.
    • On success: Saves resume_id to localStorage and updates UI.
  • Master Resume Exists: Displays a "Master Resume" card.
    • Action: Clicking the card navigates to the Resume Viewer (/resumes/[id]).
  • Create Tailored Resume: A "+" card opens /tailor (enabled only when the master resume is ready) with label text "Create Resume".
  • Tailored Resume Tiles: Fetched from GET /api/v1/resumes/list and rendered as grey cards that open /resumes/[id].
    • Filtering: Excludes master resume by both is_master flag AND localStorage master_resume_id (handles sync issues).
  • Auto-Refresh: Dashboard refreshes resume list and master status when window gains focus (handles deletions from viewer).
  • Layout: Dashboard grid targets 5 columns at large breakpoints, with filler tiles using neutral greys to balance the canvas.
  • Navigation: Settings access lives in the footer as a Swiss-style orange button.

2. Resume Viewer (/resumes/[id])

A read-only hub for a specific resume (either the Master or a Tailored version).

  • Data Fetching: Fetches resume details from the backend using the id from the URL.
  • Processing Status: Shows loading, processing, or failed states with appropriate messaging.
  • Display: Uses the Resume component to render the document at 250mm width with Swiss-style shadow (shadow-[8px_8px_0px_0px_#000000]).
  • Navigation: Back to Dashboard button in header.
  • Actions:
    • Edit Resume: Navigates to /builder?id=[id].
    • Download Resume: Requests GET /api/v1/resumes/{id}/pdf for a headless-Chromium PDF.
    • Delete Resume: Full delete workflow with confirmation dialogs (see Delete Flow below).

3. Tailoring Process (/tailor)

The core AI feature where a Master Resume is optimized for a specific job.

  • Input: Large text area for the Job Description (JD).
  • Validation: Enforces a minimum character count (e.g., 50 chars) to ensure valid input.
  • Process:
    1. Upload JD: Sends JD to /api/v1/jobs/upload.
    2. Improve: Calls /api/v1/resumes/improve with master_resume_id and job_id.
  • Output:
    • Redirects to the Resume Viewer (/resumes/[new_id]) for the newly created resume.
    • The new resume is saved in the backend and can be edited further.

4. Resume Builder (/builder)

The editor interface for modifying resume content with WYSIWYG paginated preview.

  • Navigation: Back to Dashboard button in header with Swiss styling.
  • Modes:
    • Create/Preview Mode: If accessed via the tailored flow (data passed via ResumePreviewContext).
    • Edit Mode: If accessed via URL query param (?id=xyz). Fetches data from the backend.
  • Template & Formatting Controls (collapsible panel in Editor Panel):
    • Template Selection: Visual thumbnail buttons for switching templates.
      • swiss-single: Traditional single-column layout (default)
      • swiss-two-column: Two-column layout with experience sidebar
    • Page Size: Toggle between A4 (210×297mm) and US Letter (8.5×11in).
    • Margins: Sliders for top/bottom/left/right (5-25mm range).
    • Spacing: Button groups for section spacing, item spacing, line height (1-5 levels).
    • Font Size: Button groups for base font size and header scale (1-5 levels).
    • All settings apply in real-time to the live preview via CSS custom properties.
    • Settings persist to localStorage under resume_builder_settings.
  • Components:
    • Left Panel: ResumeForm for editing fields (Personal Info, Experience, etc.). Scrollable with fixed height.
      • Header: Blue square indicator (bg-blue-700) + "EDITOR PANEL" label
      • Contains: FormattingControls panel (template, page size, formatting) + ResumeForm sections
    • Right Panel: WYSIWYG Paginated Preview (PaginatedPreview component).
      • Header: Green square indicator (bg-green-700) + "LIVE PREVIEW" label
      • See Paginated Preview System section below for details.
  • Data Recovery:
    • Auto-saves drafts to localStorage under key resume_builder_draft.
    • Auto-saves template settings to localStorage under key resume_builder_settings.
    • Warns user before leaving page with unsaved changes.
    • Priority loading: API (if ID) → Context (tailor flow) → localStorage → defaults.
  • Actions:
    • Save: PATCHes the resume to the backend when an id is present.
    • Reset: Reverts to the last saved state.
    • Download: Requests GET /api/v1/resumes/{id}/pdf with all template settings (including page size) as query params.
  • Footer: Shows current template type and page size.

Paginated Preview System

The right panel uses a true WYSIWYG preview that shows exactly what the PDF will look like.

Preview Controls (toolbar at top of preview):

  • Zoom: +/- buttons (40% to 150%), shows current zoom percentage
  • Margins Toggle: Eye icon to show/hide dashed margin guides (hidden by default)
  • Page Count: Shows total number of pages (e.g., "2 pages")

Page Display:

  • Each page rendered at exact dimensions (A4: 210×297mm, US Letter: 215.9×279.4mm)
  • Pages scaled to fit preview area with auto-zoom
  • Swiss-style shadow on each page (shadow-[6px_6px_0px_0px_#000000])
  • Page number indicator: "Page X of Y" (bottom-right of each page)
  • Visual "Page Break" separator between pages

Pagination Rules:

  • Sections (Experience, Projects, etc.) CAN span multiple pages - this is normal
  • Individual items (single job entry, single project) stay together on one page
  • Pages must be at least 50% full before moving an item to the next page
  • Section titles won't be orphaned at the bottom of a page

Architecture:

components/preview/
├── page-container.tsx      # Single page with margin guides
├── paginated-preview.tsx   # Main component with controls
├── use-pagination.ts       # Page break calculation hook
└── index.ts

lib/constants/
└── page-dimensions.ts      # A4/Letter dimensions, mm↔px utilities

5. Settings (/settings)

System configuration and status monitoring page.

System Status Panel

Displays cached health and statistics (see Status Caching below):

  • LLM Status: Shows HEALTHY (green) or OFFLINE (red) based on provider connectivity.
  • Database Status: Shows CONNECTED when backend is reachable.
  • Resumes Count: Total number of resumes stored in the database.
  • Jobs Count: Total number of job descriptions stored.
  • Improvements Count: Total number of tailored resumes generated.
  • Master Resume: Shows CONFIGURED or NOT SET status.
  • Last Fetched: Shows when status was last refreshed (e.g., "Just now", "5m ago").
  • Refresh Button: Manually refresh system status from backend.

Status Caching

The Settings page uses cached status data to avoid expensive LLM health check API calls:

  • No API call on page load: Uses useStatusCache() hook for cached data.
  • Initial load: Status fetched once when app starts (via StatusCacheProvider).
  • Auto-refresh: Background refresh every 30 minutes.
  • Manual refresh: User can click "Refresh" to fetch fresh data.
  • Last fetched indicator: Shows relative time since last refresh.

LLM Configuration

Configure the AI provider for resume tailoring:

  • Provider Selection: Choose from 6 providers:
    • OpenAI (default: gpt-4o-mini)
    • Anthropic (default: claude-3-5-sonnet-20241022)
    • OpenRouter (default: anthropic/claude-3.5-sonnet)
    • Google Gemini (default: gemini-1.5-flash)
    • DeepSeek (default: deepseek-chat)
    • Ollama (default: llama3.2, local models)
  • Model Input: Customize the model name for the selected provider.
  • API Key: Enter API key (not required for Ollama).
  • Ollama Server URL: Configure local Ollama endpoint (shown only for Ollama provider).

Actions

  • Save Configuration: Validates config with backend before saving, then refreshes cached status.
  • Test Connection: Makes a test LLM call and displays success/failure result.

Displays overall system readiness with Swiss-style visual indicators:

  • Ready State: Green square indicator (bg-green-700) + green text "STATUS: READY"
  • Setup Required: Amber square indicator (bg-amber-500) + amber text "STATUS: SETUP REQUIRED"
  • Checking State: Spinner + "CHECKING..." during refresh
  • Offline State: "STATUS: OFFLINE" if no cached status available
  • Visual Pattern: w-3 h-3 square + matching colored text with font-bold emphasis

6. Delete Flow

The complete workflow for deleting a resume (Master or Tailored).

From Resume Viewer

  1. Trigger: User clicks "Delete Resume" button (red, bottom-right of viewer).
  2. Confirmation Dialog: Swiss-style danger variant dialog appears.
    • Title: "Delete Master Resume" or "Delete Resume" based on type.
    • Description: Warns that action cannot be undone.
    • Actions: "Keep Resume" (cancel) or "Delete Resume" (confirm with trash icon).
  3. API Call: DELETE /api/v1/resumes/{resume_id} via deleteResume() function.
  4. localStorage Cleanup: If deleting master resume, removes master_resume_id from localStorage.
  5. Success Dialog: Swiss-style success variant dialog confirms deletion.
    • Title: "Resume Deleted"
    • Single action: "Return to Dashboard"
  6. Navigation: Redirects to /dashboard.
  7. Dashboard Refresh: List auto-refreshes on window focus.

From Dashboard (Master Only)

  1. Trigger: Delete action from dashboard confirmation dialog.
  2. API Call: Same as above.
  3. State Update: Clears master state and refreshes tailored resume list.

Error Handling

  • If deletion fails, shows error dialog with "OK" button.
  • Error message displayed in Swiss-style danger variant.

ConfirmDialog Variants

The ConfirmDialog component (components/ui/confirm-dialog.tsx) supports:

  • danger: Red styling, trash icon (for delete confirmations)
  • warning: Orange styling, alert icon
  • success: Green styling, checkmark icon (for success confirmations)
  • default: Blue styling, alert icon
  • showCancelButton: Optional prop to hide cancel button (for info/success dialogs)

Key Components

  • ResumePreviewProvider: React Context for passing transient state (like AI generation results) between routes.
  • ResumeUploadDialog: Handles file upload to the backend with progress states.
  • Resume: Shared component for rendering the resume layout. Used in Viewer, Builder (Preview), and Dashboard (thumbnail).
    • Width: Fills parent container (parent sets max-w-[250mm])
    • Padding: p-10 md:p-16 for comfortable spacing
    • Typography: Serif headers, mono metadata, sans body text
    • No internal shadow (parent provides Swiss-style shadow)
  • ResumeForm: Form editor with collapsible sections for Personal Info, Experience, Education, Projects, and Additional info.
  • PaginatedPreview: WYSIWYG preview component that shows exact page layout with pagination.
    • Renders pages at actual dimensions (A4 or US Letter)
    • Auto-calculates page breaks based on content
    • Zoom controls (40%-150%) and margin guide toggle
    • Shows page count and page break indicators
  • PageContainer: Single page wrapper with margin guides and page number.
    • Renders at exact page dimensions, scaled for preview
    • Optional dashed margin guides (toggleable)
    • Clips content to prevent overlap between pages
  • usePagination: Custom hook for calculating page breaks.
    • Measures content height using hidden container
    • Respects .resume-item boundaries (won't split individual entries)
    • Uses ResizeObserver + MutationObserver for real-time updates
    • 150ms debounce for performance

State Management

  • Local Storage: Persists the master_resume_id to maintain the user's setup across sessions.
  • URL Params: Used to identify specific resumes for viewing (/resumes/[id]) or editing (/builder?id=...).
  • Context API: Used for passing immediate results from the AI tailoring process to the Builder/Viewer.
  • Status Cache: Global cache for system status with optimistic counter updates (see below).

Status Cache Context (lib/context/status-cache.tsx)

The StatusCacheProvider wraps the app and provides cached system status:

const {
  status,              // SystemStatus | null
  isLoading,           // boolean
  lastFetched,         // Date | null
  refreshStatus,       // Manual refresh
  incrementResumes,    // Optimistic counter update
  decrementResumes,
  incrementJobs,
  incrementImprovements,
  setHasMasterResume,
} = useStatusCache();

Optimistic Updates: When user actions modify data, counters update instantly:

Action Updates
Upload master resume incrementResumes(), setHasMasterResume(true)
Delete master resume decrementResumes(), setHasMasterResume(false)
Upload job description incrementJobs()
Generate tailored resume incrementJobs(), incrementImprovements(), incrementResumes()
Delete any resume decrementResumes()

API Client (lib/api/)

Centralized Client (lib/api/client.ts)

Single source of truth for API configuration:

  • API_URL - Base URL from environment or default
  • API_BASE - Full API path (${API_URL}/api/v1)
  • apiFetch(endpoint, options?) - Base fetch wrapper
  • apiPost(endpoint, body) - POST with JSON
  • apiPatch(endpoint, body) - PATCH with JSON
  • apiPut(endpoint, body) - PUT with JSON
  • apiDelete(endpoint) - DELETE request
  • getUploadUrl() - Returns upload endpoint URL

Barrel Export (lib/api/index.ts)

All API functions re-exported for clean imports:

import { fetchResume, API_BASE } from '@/lib/api';

Resume Operations (lib/api/resume.ts)

  • uploadJobDescriptions(descriptions, resumeId) - Upload job descriptions
  • improveResume(resumeId, jobId) - Generate tailored resume
  • fetchResume(resumeId) - Fetch resume by ID
  • fetchResumeList(includeMaster) - List all resumes (optionally include master)
  • updateResume(resumeId, resumeData) - Update resume with structured JSON
  • downloadResumePdf(resumeId, template) - Download resume as PDF
  • deleteResume(resumeId) - Delete a resume permanently

Configuration Operations (lib/api/config.ts)

  • fetchLlmConfig() - Get current LLM configuration
  • updateLlmConfig(config) - Update LLM provider/model/key
  • fetchSystemStatus() - Get system health and database stats
  • testLlmConnection() - Test LLM provider connectivity
  • PROVIDER_INFO - Provider metadata (names, defaults, requirements)