Fix hardcoded user-facing strings (email fallbacks, AI parse errors, API error messages) #53
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
A review found three categories of hardcoded English strings shown to users (including Romanian users).
Fix 1 — API error messages (frontend-only)
Why frontend: Language is already known on the frontend. The error
codefield is already set on allErrorResponseobjects (cv_file_missing,captcha_verification_failed,request_cancelled). Thet()function returns the key string when a key is not found, which lets us detect a missing translation safely.1a —
web/wwwroot/js/utils/form-helpers.jsUpdate
extractApiErrorto checkbody.codebefore falling back tobody.error:javascript function extractApiError(body, status, fallbackKey, rateLimitKey) { if (status === 429) return window.MyAi.t(rateLimitKey || 'form.rateLimited'); if (status >= 400 && status < 500) { if (body && body.code) { var codeKey = 'error.' + body.code; var translated = window.MyAi.t(codeKey); if (translated !== codeKey) return translated; } var msg = body && (body.error || body.Error || body.title); if (msg) return msg; } return window.MyAi.t(fallbackKey); }1b —
web/wwwroot/js/i18n.jsAdd to both
enandrodictionaries:error.cv_file_missingMissing CV PDF.Fișierul CV PDF lipsește.error.captcha_verification_failedCaptcha verification failed.Verificarea captcha a eșuat.error.request_cancelledRequest was cancelled.Cererea a fost anulată.Fix 2 — Email fallback values
2a — New
email-datamigrationCommand:
powershell dotnet ef migrations add AddFallbackStringTemplates --context EmailDbContext --project Apis/email-data --startup-project Apis/email-apiSeed in
emailApi.Templates:email.match.fallback-naN/AN/Aemail.match.subject-fallback-labelJobJobemail.notification.unknown-ipUnknownNecunoscutemail.search-results.keywords-emptynone detectedniciunul detectatemail.search-results.providers-emptynoneniciunulemail.search-results.location-empty--2b —
Apis/api/Services/EmailApiEmailSender.csjobLabel ?? "N/A"jobLabel ?? _emailTemplates.Get("email.match.fallback-na", language)result.JobUrl ?? "N/A"result.JobUrl ?? _emailTemplates.Get("email.match.fallback-na", language)jobLabel ?? "Job"jobLabel ?? _emailTemplates.Get("email.match.subject-fallback-label", language)userIp ?? "Unknown"userIp ?? _emailTemplates.Get("email.notification.unknown-ip", "en")2c —
Jobs/cv-search-job/Services/CvSearchEmailSender.csIn
BuildScanSummary(already haslanguageparam and_emailTemplates):`csharp
var keywordsHtml = keywords.Count > 0
? string.Join(...)
: $"<span style="...">{_emailTemplates.Get("email.search-results.keywords-empty", language)}";
var providers = providerNames.Count > 0
? string.Join(", ", providerNames)
: _emailTemplates.Get("email.search-results.providers-empty", language);
var locationDisplay = string.IsNullOrWhiteSpace(location)
? _emailTemplates.Get("email.search-results.location-empty", language)
: location;
`
Fix 3 — AI parse failure messages
3a — New
cv-matcher-datamigrationCommand:
powershell dotnet ef migrations add AddParseErrorPrompts --context CvMatcherDbContext --project Apis/cv-matcher-data --startup-project Apis/cv-matcher-apiSeed in
cvMatcher.AiPrompts:parse-error.summaryenThe AI response could not be parsed. Please try again.parse-error.summaryroRăspunsul AI nu a putut fi interpretat. Vă rugăm să încercați din nou.parse-error.recommendationenIf the problem persists, try a different job link or description.parse-error.recommendationroDacă problema persistă, încercați un alt link sau descriere de job.3b —
Apis/cv-matcher-api/Services/CvMatcherService.csIn
MatchJobAsync, look up messages before callingParseResult:csharp var errorSummary = await _aiPrompts.GetAsync("parse-error.summary", normalizedLanguage, ct); var errorRec = await _aiPrompts.GetAsync("parse-error.recommendation", normalizedLanguage, ct); var result = ParseResult(json, errorSummary, errorRec);Change
ParseResultsignature:csharp private static JobMatchResponse ParseResult( string json, string? errorSummary = null, string? errorRec = null) { try { /* existing deserialize */ } catch { } return new JobMatchResponse { Score = 0, Summary = errorSummary ?? "The AI response could not be parsed as structured JSON.", Recommendations = [errorRec ?? "Inspect the raw model output and tune the scoring prompt."] }; }Verification
ro→ confirm email uses Romanian labels