Initial commit: TrueCV CV verification platform

Clean architecture solution with:
- Domain: Entities (User, CVCheck, CVFlag, CompanyCache) and Enums
- Application: Service interfaces, DTOs, and models
- Infrastructure: EF Core, Identity, Hangfire, external API clients, services
- Web: Blazor Server UI with pages and components

Features:
- CV upload and parsing (PDF/DOCX) using Claude API
- Employment verification against Companies House API
- Timeline analysis for gaps and overlaps
- Veracity scoring algorithm
- Background job processing with Hangfire
- Azure Blob Storage for file storage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-18 19:20:50 +01:00
commit 6d514e01b2
70 changed files with 5996 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
@page "/"
<PageTitle>TrueCV - Verify CVs with Confidence</PageTitle>
<!-- Hero Section -->
<section class="bg-primary text-white py-5">
<div class="container">
<div class="row align-items-center py-5">
<div class="col-lg-6">
<h1 class="display-4 fw-bold mb-4">Verify CVs with Confidence</h1>
<p class="lead mb-4">
TrueCV uses AI-powered analysis and official company records to verify employment history,
detect timeline inconsistencies, and flag potential issues in candidate CVs.
</p>
<div class="d-flex gap-3">
<a href="/check" class="btn btn-light btn-lg px-4">
Start Verification
</a>
<a href="#features" class="btn btn-outline-light btn-lg px-4">
Learn More
</a>
</div>
</div>
<div class="col-lg-6 text-center mt-4 mt-lg-0">
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" fill="currentColor" class="opacity-25" viewBox="0 0 16 16">
<path d="M10.067.87a2.89 2.89 0 0 0-4.134 0l-.622.638-.89-.011a2.89 2.89 0 0 0-2.924 2.924l.01.89-.636.622a2.89 2.89 0 0 0 0 4.134l.637.622-.011.89a2.89 2.89 0 0 0 2.924 2.924l.89-.01.622.636a2.89 2.89 0 0 0 4.134 0l.622-.637.89.011a2.89 2.89 0 0 0 2.924-2.924l-.01-.89.636-.622a2.89 2.89 0 0 0 0-4.134l-.637-.622.011-.89a2.89 2.89 0 0 0-2.924-2.924l-.89.01-.622-.636zm.287 5.984-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7 8.793l2.646-2.647a.5.5 0 0 1 .708.708z"/>
</svg>
</div>
</div>
</div>
</section>
<!-- Features Section -->
<section id="features" class="py-5 bg-light">
<div class="container">
<div class="text-center mb-5">
<h2 class="fw-bold">How TrueCV Works</h2>
<p class="text-muted lead">Comprehensive CV verification in three key areas</p>
</div>
<div class="row g-4">
<!-- Employment Verification -->
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="bg-primary bg-opacity-10 rounded-circle d-inline-flex p-3 mb-3">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-building-check text-primary" viewBox="0 0 16 16">
<path d="M12.5 16a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm1.679-4.493-1.335 2.226a.75.75 0 0 1-1.174.144l-.774-.773a.5.5 0 0 1 .708-.708l.547.548 1.17-1.951a.5.5 0 1 1 .858.514Z"/>
<path d="M2 1a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6.5a.5.5 0 0 1-1 0V1H3v14h3v-2.5a.5.5 0 0 1 .5-.5H8v4H3a1 1 0 0 1-1-1V1Z"/>
<path d="M4.5 2a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm-6 3a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm-6 3a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1Z"/>
</svg>
</div>
<h4 class="card-title fw-bold">Employment Verification</h4>
<p class="card-text text-muted">
Cross-reference claimed employers with official Companies House records to verify
company existence and match accuracy.
</p>
</div>
</div>
</div>
<!-- Timeline Analysis -->
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="bg-primary bg-opacity-10 rounded-circle d-inline-flex p-3 mb-3">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-calendar-range text-primary" viewBox="0 0 16 16">
<path d="M9 7a1 1 0 0 1 1-1h5v2h-5a1 1 0 0 1-1-1zM1 9h4a1 1 0 0 1 0 2H1V9z"/>
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
</svg>
</div>
<h4 class="card-title fw-bold">Timeline Analysis</h4>
<p class="card-text text-muted">
Detect unexplained employment gaps and overlapping job periods that may indicate
inconsistencies in the candidate's work history.
</p>
</div>
</div>
</div>
<!-- AI-Powered Parsing -->
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<div class="bg-primary bg-opacity-10 rounded-circle d-inline-flex p-3 mb-3">
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-cpu text-primary" viewBox="0 0 16 16">
<path d="M5 0a.5.5 0 0 1 .5.5V2h1V.5a.5.5 0 0 1 1 0V2h1V.5a.5.5 0 0 1 1 0V2h1V.5a.5.5 0 0 1 1 0V2A2.5 2.5 0 0 1 14 4.5h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14a2.5 2.5 0 0 1-2.5 2.5v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14A2.5 2.5 0 0 1 2 11.5H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2A2.5 2.5 0 0 1 4.5 2V.5A.5.5 0 0 1 5 0zm-.5 3A1.5 1.5 0 0 0 3 4.5v7A1.5 1.5 0 0 0 4.5 13h7a1.5 1.5 0 0 0 1.5-1.5v-7A1.5 1.5 0 0 0 11.5 3h-7zM5 6.5A1.5 1.5 0 0 1 6.5 5h3A1.5 1.5 0 0 1 11 6.5v3A1.5 1.5 0 0 1 9.5 11h-3A1.5 1.5 0 0 1 5 9.5v-3zM6.5 6a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5h-3z"/>
</svg>
</div>
<h4 class="card-title fw-bold">AI-Powered Parsing</h4>
<p class="card-text text-muted">
Advanced AI extracts and structures CV data from PDF and DOCX files, ensuring
accurate information capture for analysis.
</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- How It Works Section -->
<section class="py-5">
<div class="container">
<div class="text-center mb-5">
<h2 class="fw-bold">Get Started in Minutes</h2>
<p class="text-muted lead">Simple three-step verification process</p>
</div>
<div class="row g-4 justify-content-center">
<div class="col-md-4">
<div class="text-center">
<div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
<span class="fw-bold fs-4">1</span>
</div>
<h5 class="fw-bold">Upload CV</h5>
<p class="text-muted">Upload the candidate's CV in PDF or DOCX format</p>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
<span class="fw-bold fs-4">2</span>
</div>
<h5 class="fw-bold">AI Analysis</h5>
<p class="text-muted">Our AI parses the CV and verifies against official records</p>
</div>
</div>
<div class="col-md-4">
<div class="text-center">
<div class="bg-primary text-white rounded-circle d-inline-flex align-items-center justify-content-center mb-3" style="width: 60px; height: 60px;">
<span class="fw-bold fs-4">3</span>
</div>
<h5 class="fw-bold">Get Report</h5>
<p class="text-muted">Receive a detailed veracity report with actionable insights</p>
</div>
</div>
</div>
<div class="text-center mt-5">
<a href="/check" class="btn btn-primary btn-lg px-5">
Start Your First Check
</a>
</div>
</div>
</section>