- Add notable Further Education colleges to recognised institutions
(Loughborough College, Hartpury College, etc.)
- Improve compound name matching to handle separators (/, &, -, ,)
so "Loughborough College/Motorsport UK Academy" now matches
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Education Verification section to report UI showing institution
verification status, qualifications, and dates
- Add differentiated icons for Information flags (career, timeline,
management, education types)
- Change potentially defamatory language to neutral terms:
- "Diploma Mill" → "Not Accredited"
- "Suspicious" → "Unrecognised"
- Flag descriptions now recommend manual verification rather than
making definitive claims about institution legitimacy
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename all TrueCV references to RealCV across the codebase
- Add new transparent RealCV logo
- Switch from JetBrains Mono to Inter font for better number clarity
- Update solution, project files, and namespaces
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change text-warning from bright yellow (#ffc107) to darker amber (#b45309)
for WCAG AA compliant 4.8:1 contrast ratio on white backgrounds.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Increase font sizes from 11px to 12px for employment headers and notes
- Improve color contrast (gray-500 to gray-600) for WCAG AA compliance
- Increase opacity for white text on dark backgrounds (0.6/0.8 to 0.8/0.9)
- Fix duplicate company penalty display to only apply for sequential entries
- Non-sequential entries of same company now each show their own penalty
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ProcessCVCheckJob:
- Recognize "contract", "contract work", "contract role" as freelance
- Add "various", "various clients" for multiple short-term contracts
- Prevents false matching of contract work to dissolved companies
Report.razor:
- Fix stat blocks centering (icon, number, label now centered)
- Fix employment table column alignment with fixed widths
- Add inline styles to header for consistent centering
- Improve GetPointsForCompany to show -10 for unverified companies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add universal cursor inherit rule for consistent cursor behavior
- Add user-select: none to prevent text selection on UI elements
- Expand element coverage to include modals, tooltips, and inline elements
- Preserve text cursor and selection for form inputs with !important
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- deploy.sh: Publish and deploy from dev machine
- server-setup.sh: One-time Ubuntu server setup (Nginx, Docker, SQL Server)
- README.md: Deployment documentation and troubleshooting guide
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace hero section PNG logo with clean SVG document illustration
- Add comprehensive cursor styling to prevent text cursor on non-editable elements
- Cover all SVG elements, Bootstrap components, and custom classes
- Ensure checkboxes and interactive elements have pointer cursor
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CandidateName property to VeracityReport and display on report page
- Simplify employment verification layout with compact row-based design
- Add UK employment history notice to Home and Check pages
- Improve hero section text readability with text shadow
- Update Login and Register page styling
- Remove Companies House references from UI text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move admin credentials from hardcoded values to configuration
- Add rate limiting (5/min) to login endpoint for brute force protection
- Extract CleanJsonResponse to shared JsonResponseHelper class
- Add DateHelpers.MonthsBetween utility and consolidate date calculations
- Update PdfReportService to use ScoreThresholds constants
- Remove 5 unused shared components (EmploymentTable, FlagsList, etc.)
- Clean up unused CSS from MainLayout.razor.css
- Create IPdfReportService interface for better testability
- Add authentication requirement to Hangfire dashboard in development
- Seal EducationVerifierService class
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add checkbox column with Select All in header
- Show selection count badge and Delete Selected button
- Enhanced confirmation modal for bulk operations
- Row highlighting for selected items
- Fixed button spacing (gap between View and Delete)
- Scrollable list in modal for many selected items
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add "partnership" detection to charity/voluntary check (excluding LLPs).
Most UK "X Partnership" organisations are registered charities or CICs,
e.g., North Halifax Partnership Limited (charity 1169746).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update flag assertions to filter by specific flag types
(job now creates additional informational flags)
- Update overlap tests: now "Concurrent Employment" with Info severity
- Update overlap score tests: no penalty for overlaps
(legitimate for part-time, consulting, job transitions)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enhance text contrast (darker grey #2d2b27)
- Soften footer with warmer dark (#3a3833)
- Use warmer primary blue (#3d5a80)
- Add subtle background gradient for depth
- Strengthen table header styling
- Increase logo size to 95px for better visibility
- Fix AI matcher to handle acronyms in parentheses (e.g., NHP)
- Improve matching rules for CIC/LLP legal suffixes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace bright white backgrounds with warmer off-white tones to reduce
eye strain while maintaining good contrast and professional appearance.
Changes:
- Update CSS variables with warmer neutral palette (#f5f3f0 page bg,
#faf9f7 surfaces, #f0ede8 muted sections)
- Soften primary blue from #2563eb to #3b6fd4
- Update navbar, cards, tables to use new surface colours
- Update upload area, file lists, and icon backgrounds
- Update flag item backgrounds with softer tints
- Update shared components (VeracityScoreCard, FlagsList)
The new colour scheme uses warm off-white/cream tones that are easier
on the eyes than pure white while maintaining professionalism.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace fuzzy string matching with semantic AI matching to fix false
positives where similar-sounding but different companies were matched
(e.g., "Families First CiC" incorrectly matching "FAMILIES AGAINST
CONFORMITY LTD").
Changes:
- Add ICompanyNameMatcherService interface and AICompanyNameMatcherService
implementation using Claude Sonnet 4 for semantic company name comparison
- Add SemanticMatchResult and related models for AI match results
- Update CompanyVerifierService to use AI matching with fuzzy fallback
- Add detection for public sector employers, charities, and self-employed
entries that cannot be verified via Companies House
- Update tests to work with new AI matcher integration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Red ring for low/zero scores
- Amber ring for medium scores
- Green ring for high scores
- Background ring now visible and coloured appropriately
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add explicit circumference calculation for clarity
- Apply rotate(-90deg) to start progress from 12 o'clock
- Add transform-origin: center for consistent rotation
- Clean up duplicate CSS rules
- Fix mobile responsive styles for score-roundel
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change header background to neutral blue gradient
- Add score roundel with coloured ring based on score
- Ring colour indicates score level (green/amber/red)
- Keeps header consistent regardless of score
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Filter out empty, "Unknown", and "Unknown Institution" values
from generating verification flags since there's nothing to verify.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove score rating labels (Excellent, Good, Fair, Poor, Very Poor)
- Display "TrueCV Score" instead of rating text
- Remove Rating column from batch PDF report
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add custom CSS design system with brand colours and variables
- Enhance Report page with SVG score ring and improved flag styling
- Improve Dashboard with better table design and score badges
- Enhance Check page upload area with animated icon and file styling
- Update spellings to UK English (analysing, recognised)
- Add user-select: none to prevent text cursor on clickable elements
- All date formats already use UK-friendly dd MMM yyyy format
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When the institution name is empty, "Unknown", or "Unknown Institution",
don't show the "not found in UK database" message since it's not useful.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Informational flags are context-only and don't affect the score,
so displaying "0 pts" was redundant and confusing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The SIC code mismatch check was flagging tech roles at companies not
registered as technology businesses. This is not a reliable measure
since many companies employ tech staff regardless of their SIC code.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New info flags (no penalty - provide context):
- Career Span: Total years of experience with label (Early Career to Extensive)
- Current Status: Currently employed at X / Available since Y
- Long Tenure: Highlight 5+ year roles positively
- Management Experience: X of Y roles with management titles
- Individual Contributor: When no management titles detected
- Company Size Pattern: Startup/SME/Corporate experience breakdown
- Career Trajectory: Upward/Lateral/Step-down progression analysis
- PLC Experience: Roles at publicly listed companies
- Director Experience: Director/officer roles without red flags
All flags have ScoreImpact = 0 (informational only)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CheckFrequentJobChanges() to detect short tenure patterns
- Flag when 3+ employers have <18 month tenure (no penalty, info only)
- Group multiple roles at same company/group together
- Calculate and display average tenure across all employers
- Add NormalizeCompanyForGrouping() to handle company name variations
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GenerateSingleReport() method to PdfReportService for individual CV reports
- PDF includes: score header, employment verification table, timeline analysis,
gaps/overlaps sections, and color-coded flags (critical/warning/info)
- Update Report.razor to use PdfReportService instead of JSON serialization
- Add TrueCV.Web.Services to _Imports.razor
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When matching brand names like "ASDA", prefer the main employer company
(ASDA STORES LIMITED) over subsidiaries (ASDA DELIVERY LIMITED).
- Add SubsidiaryIndicators set (delivery, distribution, holdings, property, etc.)
- Add MainCompanyIndicators set (stores, retail, manufacturing, etc.)
- Add CalculateCompanyPriorityScore() method for ranking matches
- Sort matches by priority score first, then by fuzzy score
- Subsidiaries get -10 priority unless explicitly searched for
- Main trading companies get +5 priority, PLCs get +3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add NonEmploymentEntityPatterns dictionary with 10 categories of non-employer entities
(clubs, associations, trusts, charities, investment, property, religious, sports, educational, professional)
- Expand SkipWords from ~30 to 120+ words for better core identifier extraction
- Add GetSearchEntityTypes() and IsValidEmploymentEntity() helper methods
- Refactor FindBestMatch() to use pattern-based filtering instead of hardcoded checks
- Fix UI showing duplicate points for same company appearing multiple times
(now only shows points on first occurrence, subsequent rows show 0)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Require ALL core identifier words to be present in match
(e.g., "Lloyds Bowmaker" needs both "LLOYDS" and "BOWMAKER")
- Filter out club/association/society type entities
(prevents "BMW" -> "BMW CAR CLUB LIMITED")
- Filter out benefit/trust/pension type entities
(prevents "BMW Group" -> "BMW GROUP BENEFIT TRUST LIMITED")
- Core word extraction now returns all significant words, not just first
Fixes false matches like:
- "BMW Group Canada" -> "CANADA LIFE GROUP" (missing BMW)
- "Bank of Scotland" -> "BANK AND CLIENTS PLC" (missing Scotland)
- "Lloyds Bowmaker" -> "LLOYDS ALARMS" (missing Bowmaker)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a company appears multiple times in employment history (e.g.,
multiple roles at same company), penalties are now applied only once
per unique company, not per employment entry.
- Unverified company: -10 pts once per company (not per role)
- Company flags (incorporation date, etc.): once per (company, flag type)
Description now shows "(X roles)" when multiple instances exist.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For company names like "UNILEVER BESTFOOD", now also tries searching
for just the first word ("UNILEVER") as it may be the registered
parent company name. Adds PLC/Limited variations for major corps.
Skips common prefixes like "The", "UK", "British", etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ensures fresh API lookups each time the app starts, avoiding stale
cached results that may have been stored before matching improvements.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Company Matching:
- Extract parent company from "Brand (Parent Company)" format
- Handle slash-separated names like "ASDA/WALMART"
- Match against both original name and search query for flexibility
- Add PLC/Plc case variations
Report UI:
- Remove separate Score Breakdown section
- Add Points column to Employment Verification table
- Calculate points per company from matching flags
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous search only tried a single query which often returned newer
companies with similar names. Now generates all combinations of name
variations (UK/U.K. + Ltd/Limited) to find the correct company.
For "Mattel UK Ltd", now searches:
- Mattel UK Ltd
- Mattel U.K. Ltd
- Mattel UK Limited
- Mattel U.K. Limited (finds MATTEL U.K. LIMITED from 1980)
- Plus core name variations
This ensures companies like "MATTEL U.K. LIMITED" (incorporated 1980)
are found instead of incorrectly matching "UK MATTEL LTD" (2025).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When searching Companies House, now generates multiple query variations
to find companies registered with different naming conventions (e.g.,
"U.K." vs "UK", "Limited" vs "Ltd"). This helps match older companies
like "MATTEL U.K. LIMITED" when CVs list "Mattel UK Ltd".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When no company in search results existed at the claimed employment
start date, return no match instead of falling back to wrong company.
This prevents matching "UK MATTEL LTD" (2025) when the CV claims
employment in 2006-2013 and the real "MATTEL U.K. LIMITED" (1980)
isn't in the search results.
Result: Company shows as "Unverified" instead of wrongly verified
with multiple "Employment Before Company Existed" flags.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cache lookup now validates company existed at claimed start date
- If cached company was incorporated after employment date, search for alternatives
- Fixes matching wrong company when cached data points to newer company
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
File upload fix:
- Buffer file data immediately on selection to prevent stale IBrowserFile references
- Add BufferedFile record to hold file data in memory
- Add loading indicator while files are being buffered
- Fixes "Cannot read properties of null (reading '_blazorFilesById')" error
Company matching improvement:
- Prefer companies that existed at the claimed employment start date
- Fixes matching wrong company when newer company has similar name
- Example: "UK MATTEL LTD" (2025) vs "MATTEL U.K. LIMITED" (1980)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename "Employment Overlap" to "Concurrent Employment"
- Remove score penalty for overlaps (often legitimate: part-time, consulting, transitions)
- Change severity from Warning/Critical to Info
- Update scoring explanation to note overlaps are not penalised
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>