Skip to content

An application logger tool. The purpose is to track my applications and display them using a simple interface that offers filtering, status updates, email notifications. Later can be upgraded to also scrape for job listings which can automate the whole flow.

Notifications You must be signed in to change notification settings

victord03/applog

Repository files navigation

applog

An application logger tool to track job applications using a simple interface with filtering, status updates, and email notifications. Can be upgraded to scrape job listings and automate the workflow.


Implementation Status

1. User Interface

  • Design & Layout
    • Modern, minimal interface in beige/white color palette with dark grey text
    • Full dark mode support with theme-aware colors (light/dark modes fully functional)
    • Main layout with search bar (fully functional)
    • Job list/cards display with hover effects
    • Total applications counter displayed on main page
    • Sort jobs by latest/newest first on main screen (by application_date DESC)
  • Search & Filtering
    • Search field (main field, across the screen)
    • Filter sidebar with dropdowns (company, status, location)
    • Hide inactive job statuses (Rejected, Withdrawn, No Response) by default from main screen
    • Display filtered count in applications counter (shows "X of Y applications")
    • Add option to filter by location in the search bar
  • Forms & Input
    • Add job form (separate page at /add-job with all fields)
    • Vertically expandable text fields for description and notes
    • Job detail page with "View Details" navigation
    • Status editing from job detail page (click "Edit" button next to status badge)
    • Delete job from job detail page with confirmation dialog
    • Edit/delete buttons on job cards
    • Optional field to store apartment offer links (multiple links with '+ Add link' UI)
    • Edit job details functionality (Issue #3)
    • Auto-populate application date to today by default (Issue #4)
    • Reset edit mode when exiting job details page (Issue #5)
    • Add "Clear Fields" button in job creation form (Issue #6)
    • Auto-suggest/auto-fill for location, job title, and company fields (Issue #7)
  • Note History & Timeline
    • Vertical timeline display showing timestamped notes
    • Notes sorted in reverse chronological order (newest first)
    • Timestamps formatted as DD/MM/YYYY HH:mm for readability
    • "Add Note" form on job detail page
    • Note count indicator on job cards
    • Automatic timestamp capture for each note
  • Date & Value Formatting
    • Application dates displayed as DD/MM/YYYY on main page and detail page
    • Note timestamps displayed as DD/MM/YYYY HH:mm
    • Salary values formatted with K suffix (e.g., "120K" instead of "120000")
  • Note Templates
    • Templates Management page (/templates route)
    • Create, edit, and delete reusable note templates
    • Real-time search by template name or content
    • Template selector in job detail page with search
    • Hover tooltips showing full template content
    • Click to insert template into note textarea (non-destructive)
    • "View All Templates" dialog
    • Auto-clear success messages after 3 seconds
    • Settings icon link to Templates Management page
    • Handle note templates in job creation form (Issue #2)
      • Decision needed: Add template selector to creation form OR remove notes field from creation entirely

2. Core Application Logic

Data Management

  • CRUD Operations - job_service.py
    • Create job applications
    • Read by ID and URL
    • Update with partial or full field changes
    • Delete job applications
    • Add timestamped notes to existing applications
  • Validation & Data Integrity
    • Field validation (empty dict, invalid field names)
    • Atomic updates (all-or-nothing, no partial updates)
    • Transaction rollback on failures
    • Notes field migrated to JSON with automatic timestamp capture
    • Explicitly track job_url field presence (not just rely on SQLAlchemy NOT NULL)

Duplicate Prevention

  • Exact Duplicate Detection
    • Check for existing job_url (reject if already exists)
  • Similar Job Detection
    • Detect same job from different sources (LinkedIn, Indeed, company site)
    • Match criteria: company_name + job_title + location + different URL domain
    • Prompt user confirmation via UI layer before creating similar entry

Search & Discovery

  • Search Functionality
    • Full-text search across company, title, and description
  • Filtering System
    • Filter by company, status, and location

Tracking Features

  • Automatic Data Capture
    • Capture created date (created_at timestamp)
    • Automatically assign "Applied" status on creation
    • Track updated date (updated_at timestamp)
  • Location-Based Tracking
    • Track region of each job listing to align with apartment renting search

Note Templates

  • Template CRUD Operations - template_service.py
    • Create reusable note templates
    • Read templates by ID
    • Get all templates ordered by name
    • Search templates by name or content (case-insensitive)
    • Update existing templates
    • Delete templates
  • Template Validation
    • Require name and content fields
    • Field validation (empty dict, invalid field names)
    • Transaction rollback on failures

3. Database

  • Implementation
    • SQLite database (single-user, local storage)
    • SQLAlchemy ORM models and configuration
    • Notes field as JSON column storing timestamped note entries
  • Schema Enhancements
    • Convert salary_range field from string to tuple(int, int) or separate min/max columns
    • Extract and store keywords, company name, source website metadata
    • Optional: Create separate Company database table with relationships

4. Testing & Documentation

  • Unit Tests (49 tests with comprehensive coverage - all passing)
    • Job Service Tests (31 tests)
      • Create: duplicate detection, validation, empty data, rollback handling
      • Read: by ID and URL, valid/invalid cases, edge cases
      • Update: field validation, partial updates, nonexistent IDs, rollback
      • Delete: success/failure scenarios, rollback
      • Notes: add_note functionality, append to existing notes, edge cases
    • Template Service Tests (18 tests)
      • Create: validation, missing fields, empty data, rollback
      • Read: by ID, get all templates, search by name/content
      • Update: field validation, empty dict, nonexistent IDs
      • Delete: success/failure scenarios
  • Integration Tests
    • Search/filter functionality tests
    • Form submission end-to-end tests
  • Documentation
    • Usage documentation

5. Code Quality & Refactoring

  • Component Organization (✅ Complete - Branch: refactor/component-extraction)
    • Create applog/components/ directory structure
      • components/jobs/ - Job-related components
      • components/shared/ - Shared/reusable components
      • components/main/ - Main page components
      • components/templates/ - Template management components
    • Extract reusable UI components from applog.py (✅ 100% complete - App runs successfully!)
      • Job card component → jobs/job_card.py (with visual docstrings)
      • Job detail page → jobs/job_detail.py (877 lines, ~50 functions, with visual docstrings)
      • Add job form → jobs/add_job.py (with visual docstrings)
      • Note timeline → jobs/notes.py (with visual docstrings)
      • Filter sidebar → shared/sidebar.py (with visual docstrings)
      • Status badge → shared/status_badge.py (with visual docstrings)
      • Search bar → shared/search_bar.py (with visual docstrings)
      • Formatters → shared/formatters.py (date formatting utilities)
      • Job list wrapper → jobs/job_list.py (with visual docstrings)
      • Main index page → main/index_page.py (with visual docstrings)
      • Templates page → templates/template_form.py + templates/template_list.py (with visual docstrings)
    • Code Quality Improvements
      • Naming convention: _button_* prefix for all buttons (type-first organization)
      • Naming convention: _formatting_* prefix for all styling dictionaries
      • Visual docstrings added to all component functions (emoji + description + visual example)
      • Component organization documented in LESSONS.md (type vs. domain strategies)
    • Module Integration (✅ Complete)
      • Configured __init__.py files for proper module exports
      • Fixed import patterns (direct function calls vs. module.function access)
      • Created page wrapper functions in applog.py for state injection
      • Cleared stale bytecode cache and resolved import errors
    • Refactoring Complete!
      • All pages extracted into component modules
      • Visual docstrings added to all functions
      • Proper module exports via __init__.py files
      • Consistent naming conventions throughout
      • Full integration testing of all features (recommended before merge)
      • Optional: Split large files into sub-modules if needed (only if files exceed 500 lines)

6. Future Services (v2+)

  • Email Notifications
    • Create email notifications after a certain period of time
    • Email response parsing to update job status automatically
    • Batch check on next run if service was offline
  • URL Scraping
    • Auto-extract job details from posting URLs
  • Advanced Features
    • Authentication (if multi-user support needed)
    • Web hosting deployment
    • Company database with historical tracking
  • Security
    • SQL injection protection (SQLAlchemy parameterized queries handle automatically)
    • Input validation for URL formats
    • Rate limiting (if deployed publicly)

Project Architecture

Tech Stack

  • Frontend: Reflex (pure Python framework that compiles to React)
  • Backend: Python with SQLAlchemy ORM
  • Database: SQLite (single-user, local storage)
  • Testing: pytest with 49 comprehensive tests (all passing)
  • Deployment: Local development server only

Database Schema

JobApplication Table:

  • id - Primary key
  • company_name - Company name (indexed)
  • job_title - Position title
  • job_url - Job posting URL (unique, for duplicate detection)
  • location - Job location (indexed)
  • description - Job description text
  • status - Application status (indexed)
    • Options: Applied, Screening, Interview, Offer, Rejected, Accepted, Withdrawn, No Response
  • application_date - Date applied
  • salary_range - Salary range (optional, string format)
  • notes - JSON array of timestamped note entries: [{"timestamp": "ISO-8601", "note": "text"}, ...]
  • created_at - Record creation timestamp
  • updated_at - Record update timestamp

NoteTemplate Table:

  • id - Primary key
  • name - Template name (indexed)
  • content - Template text content
  • created_at - Template creation timestamp
  • updated_at - Template update timestamp

Component Organization

Current Approach: Hybrid Naming Convention

The project uses a hybrid naming convention that balances type-based and domain-based organization for components in single files:

Type-First Prefixes (for component kind):

  • _button_* - All button components (e.g., _button_save, _button_cancel)
  • _formatting_* - All styling dictionaries (e.g., _formatting_card, _formatting_dialog)
  • _grid_* - Grid row components
  • _section_* - Major page sections

Domain-First Prefixes (for features):

  • _template_* - Template system components
  • _note_* - Note management components
  • _job_* - Job-related components

Why This Works:

  • Enables both access patterns: "find all buttons" (_button_*) AND "find all template components" (_template_*)
  • Works well with IDE search (Cmd+T / Cmd+Shift+O in VSCode)
  • Scales up to ~100 components per file
  • No tooling overhead required

Example:

# Type-based grouping
_button_save          # Easy to find all buttons
_button_cancel
_button_template_insert

# Domain-based grouping
_template_selector_list   # Easy to find all template components
_template_search_input
_template_settings_tooltip

File Organization (Current)

applog/
├── components/
│   ├── jobs/
│   │   ├── __init__.py        # Module exports
│   │   ├── job_card.py        # Job card display (~120 lines)
│   │   ├── job_detail.py      # Job detail page (~877 lines, 50+ functions)
│   │   ├── add_job.py         # Add job form (~340 lines)
│   │   ├── job_list.py        # Job list wrapper component (~30 lines)
│   │   └── notes.py           # Note timeline components
│   ├── shared/
│   │   ├── __init__.py        # Module exports
│   │   ├── sidebar.py         # Filter sidebar
│   │   ├── search_bar.py      # Search bar component
│   │   ├── status_badge.py    # Status badge component
│   │   └── formatters.py      # Date/currency formatting utilities
│   ├── main/
│   │   ├── __init__.py        # Module exports
│   │   └── index_page.py      # Main index page layout (~160 lines)
│   └── templates/
│       ├── __init__.py        # Module exports
│       ├── template_form.py   # Template form components (~220 lines)
│       └── template_list.py   # Template list display (~252 lines)
├── applog.py                  # Main app (State + page assembly, ~530 lines)
├── models/                    # Database models
│   ├── job_application.py
│   └── note_template.py
├── services/                  # Business logic layer
│   ├── job_service.py
│   └── template_service.py
└── database.py                # Database initialization

Future: Directory Structure (100+ Components)

When the project grows beyond ~100 components, the plan is to reorganize into:

components/
├── jobs/
│   ├── detail/
│   │   ├── buttons.py      # All detail page buttons
│   │   ├── forms.py        # All form components
│   │   ├── dialogs.py      # Dialog components
│   │   └── __init__.py     # Barrel exports (dual access patterns)
│   ├── list/
│   │   ├── cards.py
│   │   └── filters.py
│   └── __init__.py
├── shared/
│   ├── buttons.py          # Shared button components
│   ├── inputs.py
│   └── status_badge.py
└── templates/
    ├── form.py
    └── list.py

Barrel Export Pattern (in __init__.py):

# Feature-domain exports (primary)
from .buttons import button_save, button_cancel, button_edit

# Component-type grouped exports (for refactoring)
__all_buttons__ = [button_save, button_cancel, button_edit]
__all_forms__ = [...]

This provides:

  • Feature-domain imports: from components.jobs.detail import button_save
  • Type-based refactoring: from components.jobs.detail import __all_buttons__

Design Philosophy

The Trade-off: You cannot optimize for both type-based AND domain-based access with a single hierarchy. The hybrid naming convention is a pragmatic compromise that works well for small-to-medium projects.

Scaling Path:

  1. < 100 components: Hybrid naming in flat files ✅ (current)
  2. 100-500 components: Directory structure + barrel exports (planned)
  3. 500+ components: Add component catalog + Storybook (future)

Key Principle: Don't over-engineer early. The current approach is optimal for the project's scale.

Full Details: See LESSONS_LEARNED.md "Component Organization" section for the complete analysis of type vs. domain trade-offs, barrel export examples, and production best practices.


Application Flow

Current MVP Flow

  1. Add Job: User navigates to /add-job and fills out the form with job details
  2. Data Storage: Job application is saved to SQLite database with automatic timestamp and "Applied" status
  3. View Jobs: Main page displays all applications with search/filter capabilities
    • Total applications counter displayed under "Add Job" button
    • "Templates" button for quick access to template management
    • Dates formatted as DD/MM/YYYY for easy reading
    • Salary values formatted with K suffix
    • Filter by company, status, or location
  4. View Details: Click "View Details" on any job card to see full information
  5. Edit Status: From job detail page, click "Edit" next to status badge to update application status
  6. Track Progress: Add timestamped notes to track application progress (emails, interviews, etc.)
    • Use template selector to quickly insert common note text
    • Search templates by name or content
    • Hover over templates to preview full content
    • Click template to insert into note textarea (non-destructive)
    • "View All" button to see all templates in a dialog
    • Settings icon to manage templates
  7. Note History: View vertical timeline of all notes with automatic timestamps
    • Notes displayed newest first (reverse chronological)
    • Timestamps formatted as DD/MM/YYYY HH:mm
  8. Delete Job: From job detail page, click "Delete Job Application" button at bottom with confirmation dialog
  9. Manage Templates: Navigate to /templates to create, edit, search, and delete note templates
    • Create reusable note templates with name and content
    • Real-time search across template names and content
    • Edit existing templates
    • Delete templates with confirmation
    • Success messages auto-clear after 3 seconds

Pages

  • / - Main dashboard with job list, search, filters, application counter, and Templates navigation button
  • /add-job - Add new job application form (wired to database)
  • /job/[id] - Job detail page with note history, status editing, add note with template selector, and delete job functionality
  • /templates - Templates Management page for creating, editing, searching, and deleting note templates

Roadmap

See ROADMAP.md for detailed upcoming features and implementation plan.

Phase 1: Complete ✅

  • ✅ Reset edit mode on page exit
  • ✅ Smart cancel with confirmation dialog
  • ✅ Auto-populate application date to today

Phase 2: Complete ✅

  • ✅ Sort jobs by application date (newest first)
  • ✅ Hide inactive job statuses by default
  • ✅ Filter-aware application counter (shows "X of Y")
  • ✅ Remove notes field from job creation (commented out for potential future re-add)

Coming Soon:

  • Location autocomplete with type-ahead
  • Full job editing capability

About

An application logger tool. The purpose is to track my applications and display them using a simple interface that offers filtering, status updates, email notifications. Later can be upgraded to also scrape for job listings which can automate the whole flow.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages