diff --git a/.env.example b/.env.example index efb6bf0..074343e 100644 --- a/.env.example +++ b/.env.example @@ -16,6 +16,9 @@ REACT_APP_API_BASE_URL= # Used by docker-compose.yml (email / password resets / notifications) APP_PUBLIC_BASE_URL=https://jobs.cesnimda.uk +APP_VERSION= +APP_COMMIT_SHA= +APP_BUILD_STAMP= EMAIL_ENABLED=false EMAIL_SMTP_HOST=smtp.gmail.com EMAIL_SMTP_PORT=587 diff --git a/JobTrackerApi/Controllers/AdminSystemController.cs b/JobTrackerApi/Controllers/AdminSystemController.cs index ffe7b0b..d7004ee 100644 --- a/JobTrackerApi/Controllers/AdminSystemController.cs +++ b/JobTrackerApi/Controllers/AdminSystemController.cs @@ -33,6 +33,8 @@ public sealed class AdminSystemController : ControllerBase string Environment, string ContentRoot, string Version, + string? CommitSha, + string? BuildStamp, StorageStatusDto Storage, EmailStatusDto Email, SummarizerMetrics Summarizer @@ -48,12 +50,20 @@ public sealed class AdminSystemController : ControllerBase var companies = await _db.Companies.AsNoTracking().CountAsync(cancellationToken); var summarizer = await _summarizer.GetMetricsAsync(cancellationToken); - var version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown"; + var version = (_cfg["App:Version"] ?? "").Trim(); + if (string.IsNullOrWhiteSpace(version)) + { + version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown"; + } + var commitSha = (_cfg["App:CommitSha"] ?? "").Trim(); + var buildStamp = (_cfg["App:BuildStamp"] ?? "").Trim(); return Ok(new SystemStatusDto( Environment: _env.EnvironmentName, ContentRoot: _env.ContentRootPath, Version: version, + CommitSha: string.IsNullOrWhiteSpace(commitSha) ? null : commitSha, + BuildStamp: string.IsNullOrWhiteSpace(buildStamp) ? null : buildStamp, Storage: new StorageStatusDto( DataRoot: _paths.DataRoot, DbPath: dbPath, diff --git a/JobTrackerApi/Services/GmailOAuthService.cs b/JobTrackerApi/Services/GmailOAuthService.cs index 61995ad..9bfc77c 100644 --- a/JobTrackerApi/Services/GmailOAuthService.cs +++ b/JobTrackerApi/Services/GmailOAuthService.cs @@ -204,6 +204,10 @@ public sealed class GmailOAuthService : IGmailOAuthService { bodyText = StripHtml(bodyHtml); } + else if (LooksLikeHtml(bodyText)) + { + bodyText = StripHtml(bodyText); + } return new GmailMessageDetail( messageId, @@ -423,6 +427,17 @@ public sealed class GmailOAuthService : IGmailOAuthService } } + private static bool LooksLikeHtml(string? value) + { + if (string.IsNullOrWhiteSpace(value)) return false; + return value.Contains(" prev.map((j) => (j.id === id ? { ...j, status } : j))); }; + const currentMenuStatus = menuJobId == null + ? null + : normalizeStatus(jobs.find((j) => j.id === menuJobId)?.status ?? ""); + return ( @@ -105,7 +109,7 @@ export default function KanbanBoard() { }} > - + {status} - {(["Waiting", "Rejected", "Ghosted"] as const).map((s) => ( + {(["Applied", "Waiting", "Interview", "Offer", "Rejected", "Ghosted"] as const) + .filter((s) => s !== currentMenuStatus) + .map((s) => ( { diff --git a/job-tracker-ui/src/pages/AdminSystemPage.tsx b/job-tracker-ui/src/pages/AdminSystemPage.tsx index e03d734..4832e9f 100644 --- a/job-tracker-ui/src/pages/AdminSystemPage.tsx +++ b/job-tracker-ui/src/pages/AdminSystemPage.tsx @@ -20,6 +20,8 @@ type SystemStatus = { environment: string; contentRoot: string; version: string; + commitSha?: string | null; + buildStamp?: string | null; storage: { dataRoot: string; dbPath: string; @@ -89,6 +91,8 @@ export default function AdminSystemPage() { Environment {status?.environment ?? "-"} Version {status?.version ?? "-"} + {status?.commitSha ? Commit {status.commitSha} : null} + {status?.buildStamp ? {status.buildStamp} : null} Database