feat: refresh candidate traits after CV changes

Recalculate stored participant traits when job postings change and expose replacement CV uploads with live candidate refresh events.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Daniel Noulet 2026-10-01 17:36:43 +02:00
parent 30e3391adb
commit 5dbda53759
12 changed files with 373 additions and 9 deletions

View file

@ -297,6 +297,34 @@ func (h *Handler) CreateParticipant(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusCreated, webmapper.ParticipantToWeb(value))
}
func (h *Handler) UpdateParticipantCV(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, h.maxUpload)
if err := r.ParseMultipartForm(h.maxUpload); err != nil {
writeError(w, http.StatusBadRequest, fmt.Errorf("invalid multipart form or upload too large"))
return
}
cv, _, filename, err := readUpload(r, "cv")
if err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
if len(cv) == 0 {
writeError(w, http.StatusBadRequest, fmt.Errorf("cv is required"))
return
}
participant, err := h.participants.Get(r.Context(), idParam(r))
if handleServiceError(w, r, err) {
return
}
participant.CV = cv
participant.CVFilename = filename
value, err := h.participants.Update(r.Context(), participant)
if handleServiceError(w, r, err) {
return
}
writeJSON(w, http.StatusOK, webmapper.ParticipantToWeb(value))
}
func (h *Handler) ParticipantPhoto(w http.ResponseWriter, r *http.Request) {
value, err := h.participants.Get(r.Context(), idParam(r))
if handleServiceError(w, r, err) {

View file

@ -60,6 +60,7 @@ func New(h *handler.Handler, tokens security.ITokenManager, frontendURL string)
protected.Get("/api/participants", h.ListParticipants)
protected.Post("/api/participants", h.CreateParticipant)
protected.Get("/api/participants/{id}", h.GetParticipant)
protected.Put("/api/participants/{id}/cv", h.UpdateParticipantCV)
protected.Get("/api/participants/{id}/photo", h.ParticipantPhoto)
protected.Get("/api/participants/{id}/cv", h.ParticipantCV)
})

View file

@ -47,6 +47,10 @@ func (participantStub) Get(context.Context, uint) (model.Participant, error) {
func (participantStub) Create(context.Context, model.Participant) (model.Participant, error) {
return model.Participant{}, nil
}
func (participantStub) Update(context.Context, model.Participant) (model.Participant, error) {
return model.Participant{}, nil
}
func (participantStub) UpdateTraits(context.Context, uint) error { return nil }
type questionStub struct{}