Windows Desktop App — Beta v0.1.0

Job Application
Tracker

A production-quality .NET 8 WPF desktop application for managing the full job-hunt lifecycle — Kanban workflow, PDF job-posting extraction, and automatic Obsidian vault sync.

C# / .NET 8 WPF + MVVM Clean Architecture SQLite + Dapper xUnit MIT License
4
Architecture Layers
2
Dashboard Views
26
Pre-seeded IT Skills

What It Does

The Job Application Tracker is a Windows desktop app that centralizes the entire job-search workflow — every application, company, contact, and skill in one local SQLite database, no cloud account required.

Drop a job-posting PDF onto the form and it extracts the text and company name automatically. Every application syncs to your Obsidian vault as a structured markdown note, with your personal notes protected from being overwritten.

Built for a real job hunt:

  • Track applications from Applied through Offer or Rejected
  • Switch between sortable table and drag-and-drop Kanban board
  • See response rate and offer rate at a glance with stat cards
  • Keep long-form notes in Obsidian, auto-synced per application

Application Lifecycle

Every application moves through a status pipeline, visualized as columns on the Kanban board:

📨
Applied
Submission logged with date, salary range, and posting URL
📞
Screening
Recruiter call or HR screen in progress
💬
Interview
Technical or panel interviews scheduled
🎉
Offer
Offer received — celebrate and negotiate
📕
Rejected
Closed out, kept for response-rate analytics
APPLIED SCREENING INTERVIEW OFFER / REJECTED

Key Features

  <div class="bg-dark-800/60 border border-purple-700/30 rounded-xl p-6 hover:border-purple-500/50 transition-colors">
    <div class="flex items-center space-x-3 mb-4">
      <div class="w-10 h-10 rounded-lg bg-purple-500/20 flex items-center justify-center text-xl">📊</div>
      <h3 class="text-lg font-bold text-purple-400">Dashboard — Table & Kanban</h3>
    </div>
    <p class="text-gray-300 text-sm mb-4">Toggle between a sortable table with real-time status updates and a drag-and-drop Kanban board organized by application status. Stat cards show application count, response rate, and offer rate.</p>
    <div class="flex flex-wrap gap-2">
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Sortable columns</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Drag & drop</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Week stats</span>
    </div>
  </div>

  <div class="bg-dark-800/60 border border-pink-700/30 rounded-xl p-6 hover:border-pink-500/50 transition-colors">
    <div class="flex items-center space-x-3 mb-4">
      <div class="w-10 h-10 rounded-lg bg-pink-500/20 flex items-center justify-center text-xl">🗒️</div>
      <h3 class="text-lg font-bold text-pink-400">Obsidian Vault Sync</h3>
    </div>
    <p class="text-gray-300 text-sm mb-4">Every application auto-syncs to your Obsidian vault as a markdown note with YAML frontmatter, status, timeline, and skills. A protected User Notes section survives every re-sync — your notes are never overwritten.</p>
    <div class="flex flex-wrap gap-2">
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">YAML frontmatter</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Section-aware merge</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Protected notes</span>
    </div>
  </div>

  <div class="bg-dark-800/60 border border-blue-700/30 rounded-xl p-6 hover:border-blue-500/50 transition-colors">
    <div class="flex items-center space-x-3 mb-4">
      <div class="w-10 h-10 rounded-lg bg-blue-500/20 flex items-center justify-center text-xl">📄</div>
      <h3 class="text-lg font-bold text-blue-400">PDF Job-Posting Extraction</h3>
    </div>
    <p class="text-gray-300 text-sm mb-4">Load a job posting PDF directly into the application form — the extraction service pulls the full text and detects the company name, so you never retype a job description again.</p>
    <div class="flex flex-wrap gap-2">
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Text extraction</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Company detection</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Auto-fill form</span>
    </div>
  </div>

  <div class="bg-dark-800/60 border border-green-700/30 rounded-xl p-6 hover:border-green-500/50 transition-colors">
    <div class="flex items-center space-x-3 mb-4">
      <div class="w-10 h-10 rounded-lg bg-green-500/20 flex items-center justify-center text-xl">🗂️</div>
      <h3 class="text-lg font-bold text-green-400">Companies, Contacts & Skills</h3>
    </div>
    <p class="text-gray-300 text-sm mb-4">Full CRUD pages with inline edit panels for companies, recruiters, and skills. Tag each application with required vs. owned skills — 26 IT/security skills come pre-seeded on first run.</p>
    <div class="flex flex-wrap gap-2">
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Inline editing</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Skill matching</span>
      <span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">Delete confirmations</span>
    </div>
  </div>

</div>

Clean Architecture

Why MVVM + WPF?

  • WPF's data binding engine is built for MVVM — {Binding} targets INotifyPropertyChanged
  • ViewModels are fully testable without UI — no Window or Page references
  • Commands (ICommand) replace controller actions cleanly
  • Dependency injection container wires every layer at startup

Testing & Data

  • xUnit test suite — service, settings, and in-memory repository tests
  • SQLite + Dapper with WAL mode and multi-map joins
  • Indexes on the three most-filtered columns: AppliedDate, Status, CompanyId
  • Settings persisted as JSON in %APPDATA%\JobTracker
PRESENTATION
JobTracker.WPF
XAML Views · ViewModels · Converters · Dark Theme
USE CASES
JobTracker.Application
Services · DTOs · Interfaces · SettingsService
DOMAIN
JobTracker.Domain
Entities · Enums · Repository Contracts
INFRASTRUCTURE — JobTracker.Infrastructure
🗄️
SQLite + Dapper
Repositories
🗒️
Markdown Sync
Obsidian vault
📄
PDF Extraction
Job postings

Obsidian Markdown Sync

SYNCED NOTE One .md file per application
2025-04-02_KPMG_IT-Infrastructure.md
---
tags: [job-application, applied, 2025]
status: Applied
company: "KPMG Ireland"
role: "IT Infrastructure Specialist"
applied_date: 2025-04-02
---

# Job Application — IT Infrastructure

## Skills Required - Azure ✅ - PowerShell ✅ - SIEM - Defender XDR

## User Notes <!— USER_NOTES_START —> My notes survive every re-sync <!— USER_NOTES_END —>

HOW SYNC WORKS
1
Point at your vault
Settings → Browse → select your Obsidian vault root folder.
2
Auto-generated filenames
Notes are written as YYYY-MM-DD_company_role.md with structured YAML frontmatter.
3
Section-aware merge
The sync service rewrites status, timeline, and skills on every change — but the USER_NOTES markers protect anything you wrote by hand.

Database Schema

Companies        (Id, Name, Website, Industry…)
Contacts         (Id, Name, Email, LinkedInUrl…)
Skills           (Id, Name, Category)
JobApplications  (Id, RoleName, Status, AppliedDate,
SalaryRange, IsRemote, CompanyId FK…)
ApplicationSkills (JobAppId FK, SkillId FK,
IsOwned, IsRequired)

Tech Stack

💜
C# / .NET 8
Core language
🖥️
WPF + MVVM
UI framework
🗄️
SQLite + Dapper
Local database
🧪
xUnit
Test suite
🗒️
Obsidian
Markdown sync

Roadmap

📤
CSV / Excel Export
Export the full application history for analysis in spreadsheets.
📅
Interview Calendar View
Timeline view with urgency indicators for upcoming interviews.
📧
Email Parsing
Poll the inbox with MailKit to auto-create draft applications.
🤖
AI CV Analysis
Match CV text against job descriptions with DPAPI-encrypted API keys.

Getting Started

terminal
# Clone the repository
$ git clone https://github.com/juandresrodca/job-application-tracker.git
# Run the app (requires .NET 8 SDK on Windows 10/11)
$ cd src/JobTracker.WPF
$ dotnet run
# First run auto-creates the SQLite DB, settings, and 26 IT skills
# %APPDATA%\JobTracker\jobtracker.db · settings.json
# Run the test suite
$ dotnet test
View on GitHub ← Back to Projects