refactor(cv): remove abandoned profile builder
CI and Deploy / test (push) Failing after 5m7s
CI and Deploy / deploy (push) Has been skipped

This commit is contained in:
cesnimda
2026-08-27 21:13:54 +02:00
parent 7c4e6fb5b7
commit b0d9a90285
2 changed files with 7 additions and 183 deletions
+2 -180
View File
@@ -1,11 +1,9 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Accordion, AccordionDetails, AccordionSummary, Alert, Avatar, Box, Button, Chip, Dialog, DialogContent, DialogTitle, Divider, FormControl, IconButton, InputLabel, LinearProgress, MenuItem, Paper, Select, TextField, Typography } from "@mui/material";
import { Alert, Avatar, Box, Button, Chip, Divider, Paper, TextField, Typography } from "@mui/material";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import PhotoCameraOutlinedIcon from "@mui/icons-material/PhotoCameraOutlined";
import ZoomInOutlinedIcon from "@mui/icons-material/ZoomInOutlined";
import { api, getApiErrorMessage } from "../api";
import GoogleAuthCard from "../components/GoogleAuthCard";
@@ -16,97 +14,9 @@ import SessionsSettingsCard from "../components/SessionsSettingsCard";
import CropImageDialog from "../components/CropImageDialog";
import { useToast } from "../toast";
import { useI18n } from "../i18n/I18nProvider";
import {
emptyStructuredCv,
getStructuredCvFieldMetadata,
joinLines,
normalizeStructuredCv,
parseStructuredCvJson,
splitLines,
StructuredCvFieldMetadata,
StructuredCvProfile,
} from "../profileCv";
import { JobApplication } from "../types";
import { parseStructuredCvJson } from "../profileCv";
import { getUserScopedStorageKey } from "../auth";
type CvSectionOption = "" | "Professional Summary" | "Core Skills" | "Experience Highlights" | "Selected Achievements" | "Projects";
type CvSectionStyle = "ats-minimal" | "harvard" | "auckland" | "edinburgh" | "monarch" | "fjord";
type CvBuilderTone = "Concise and direct" | "Executive and polished" | "Technical and detailed" | "Warm and people-focused";
type CvBuilderLanguage = "English" | "Norwegian" | "Spanish" | "French" | "German";
type ExtractionRun = {
id: number;
trigger: string;
status: string;
artifactFileName?: string;
startedAtUtc: string;
completedAtUtc?: string;
appliedAtUtc?: string;
parserVersion: string;
normalizerVersion: string;
llmPromptVersion: string;
errorMessage?: string;
};
type QueuedCvRunResponse = {
queued: boolean;
extractionRunId: number;
status: string;
};
type JobListResponse = {
items: JobApplication[];
total: number;
page: number;
pageSize: number;
};
type RewriteTemplateOption = {
id: CvSectionStyle;
title: string;
eyebrow: string;
accent: string;
blurb: string;
sampleHeading: string;
sampleMeta: string;
sampleBullets: string[];
};
type CvBuilderPreview = {
templateId: CvSectionStyle;
html: string;
suggestedFileName: string;
fullText: string;
rewrittenText: string;
structuredCv: StructuredCvProfile;
sectionName?: string | null;
targetRole?: string | null;
jobApplicationId?: number | null;
};
type PdfCarouselItem = {
templateId: CvSectionStyle;
title: string;
fileName: string;
pdfUrl?: string;
status: "loading" | "ready" | "error";
error?: string;
};
type RewriteRequestPayload = {
sectionName: string | null;
style: CvSectionStyle;
templateId: CvSectionStyle;
targetRole: string | null;
jobApplicationId: number | null;
sourceText: string | null;
promptBackground: string | null;
tone: string | null;
language: string | null;
};
type MeResponse = {
provider?: "local" | "google" | "external";
id?: string;
@@ -131,70 +41,7 @@ type PendingEmailChange = {
requestedAtUtc?: string | null;
};
const CV_UPLOAD_ACCEPT = ".pdf,.docx,.txt,.md,image/png,image/jpeg,image/webp,application/pdf,application/vnd.openxmlformats-officedocument.wordprocessingml.document,text/plain,text/markdown";
const AVATAR_UPLOAD_ACCEPT = "image/png,image/jpeg,image/webp";
const REWRITE_TEMPLATES: RewriteTemplateOption[] = [
{
id: "ats-minimal",
title: "ATS Minimal",
eyebrow: "Scanner-friendly",
accent: "#0f172a",
blurb: "Compact, direct, and easy for screening systems to parse.",
sampleHeading: "Senior Backend Engineer",
sampleMeta: "Acme Systems · Oslo · 2021 - Present",
sampleBullets: ["Built API workflows with measurable delivery outcomes.", "Kept skills and achievements easy to scan."]
},
{
id: "harvard",
title: "Harvard",
eyebrow: "Traditional",
accent: "#7f1d1d",
blurb: "Formal hierarchy and restrained tone for conservative hiring flows.",
sampleHeading: "Professional Summary",
sampleMeta: "Clear structure · precise dates · credible language",
sampleBullets: ["Emphasizes polished summaries.", "Works well for broad professional roles."]
},
{
id: "auckland",
title: "Auckland",
eyebrow: "Modern sidebar",
accent: "#0f766e",
blurb: "Sharper highlights with a more contemporary, design-forward rhythm.",
sampleHeading: "Selected Impact",
sampleMeta: "Focused strengths · compact highlights",
sampleBullets: ["Pulls skills into stronger highlight clusters.", "Good when you want a fresher feel."]
},
{
id: "edinburgh",
title: "Edinburgh",
eyebrow: "Editorial",
accent: "#5b21b6",
blurb: "More personality and stronger section contrast without losing clarity.",
sampleHeading: "Experience Highlights",
sampleMeta: "Refined spacing · stronger visual voice",
sampleBullets: ["Useful when the CV should feel more distinctive.", "Still keeps wording grounded and factual."]
},
{
id: "monarch",
title: "Monarch",
eyebrow: "Executive",
accent: "#7c2d12",
blurb: "High-contrast presentation for leadership-heavy applications.",
sampleHeading: "Executive Profile",
sampleMeta: "Leadership clarity · refined hierarchy",
sampleBullets: ["Adds more top-level summary emphasis.", "Well suited to senior strategic roles."]
},
{
id: "fjord",
title: "Fjord",
eyebrow: "Technical",
accent: "#0f4c5c",
blurb: "Calm, high-density layout for engineering resumes and project-heavy CVs.",
sampleHeading: "Projects & Systems",
sampleMeta: "Technical depth · practical readability",
sampleBullets: ["Gives projects and skills more weight.", "Better for technical detail without chaos."]
},
];
function initialsFrom(values: Array<string | undefined>) {
const joined = values.map((x) => (x ?? "").trim()).filter(Boolean);
@@ -207,31 +54,6 @@ function initialsFrom(values: Array<string | undefined>) {
return (joined[0][0] + joined[1][0]).toUpperCase();
}
function confidenceTone(confidence?: number) {
if (typeof confidence !== "number") return { label: "Review", color: "default" as const };
if (confidence >= 0.8) return { label: `High ${Math.round(confidence * 100)}%`, color: "success" as const };
if (confidence >= 0.65) return { label: `Medium ${Math.round(confidence * 100)}%`, color: "warning" as const };
return { label: `Low ${Math.round(confidence * 100)}%`, color: "error" as const };
}
function FieldReviewNote({ metadata }: { metadata?: StructuredCvFieldMetadata }) {
if (!metadata) return null;
const tone = confidenceTone(metadata.confidence);
return (
<Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 0.75, alignItems: "center" }}>
<Chip size="small" color={tone.color} variant={tone.color === "default" ? "outlined" : "filled"} label={tone.label} />
{metadata.method ? <Chip size="small" variant="outlined" label={metadata.method} /> : null}
{metadata.sourceBlockId ? <Chip size="small" variant="outlined" label={metadata.sourceBlockId} /> : null}
{metadata.reviewState ? <Chip size="small" variant="outlined" label={metadata.reviewState} /> : null}
{metadata.sourceSnippet ? (
<Typography variant="caption" sx={{ color: "text.secondary" }}>
{metadata.sourceSnippet}
</Typography>
) : null}
</Box>
);
}
// ProfilePage backs /profile: account identity + security + preferences. The master career
// profile lives in CareerProfilePage (/career). Split in Phase 2.2. Saves only identity fields
// (partial update), never the master profile.