feat: complete release readiness work

- consolidate API ownership and remove dead vendor code

- add Stripe billing, learning paths, and public CV hardening

- add migration, recovery, security, audit, and browser gates
This commit is contained in:
cesnimda
2026-07-31 16:54:16 +02:00
parent a23c3dfc97
commit ce76046a29
1634 changed files with 6889 additions and 135429 deletions
@@ -326,6 +326,24 @@ export default function JobDetailsDialog({ open, jobId, onClose, initialTab = 0,
}).catch(() => setMatchScore(null)).finally(() => setLoadingMatchScore(false));
}, [open, jobId, tab, matchScore, matchScoreCache]);
const updateLearningRecommendation = useCallback(async (id: number, status: "done" | "dismissed") => {
if (!jobId) return;
try {
await api.patch(`/jobapplications/${jobId}/checklist/${id}`, { status });
setMatchScore(current => {
if (!current) return current;
const updated = {
...current,
learningRecommendations: (current.learningRecommendations ?? []).map(item => item.id === id ? { ...item, status } : item),
};
matchScoreCache.setCached(`${jobId}:match-score`, updated);
return updated;
});
} catch (error: any) {
toast(getApiErrorMessage(error, t("matchScoreLearningUpdateFailed")), "error");
}
}, [jobId, matchScoreCache, t, toast]);
// Suggest a status move from the latest inbound email when the workspace opens.
useEffect(() => {
if (!open || !jobId) return;
@@ -1195,6 +1213,7 @@ export default function JobDetailsDialog({ open, jobId, onClose, initialTab = 0,
tab={tab}
matchScore={matchScore}
loadingMatchScore={loadingMatchScore}
updateLearningRecommendation={updateLearningRecommendation}
candidateFit={candidateFit}
loadingCandidateFit={loadingCandidateFit}
regenerateCandidateFit={regenerateCandidateFit}