Guida processo

Gestione profilo dipendenti (HR / manager)

Caricamento CV via AI extractor + gestione profilo per HR e manager, con audit visibile e review diff.

Gestione profilo dipendenti (HR / manager)

Ultimo aggiornamento: 2026-07-03 Owner: Product Writer Audience: hr_admin, admin tenant, owner, manager

Scopo

Spiegare come HR e manager possono gestire il Profilo professionale di altri dipendenti del tenant — caricare CV, costruire profilo passo passo, aggiornare campi specifici — con audit visibile lato utente target per trasparenza GDPR.

Prerequisiti

  • ruolo platform/tenant abilitato:
  • owner, admin tenant, hr_admin con permission tenant.hr.data.manage → perimetro tenant intero
  • manager → perimetro propri diretti (relazione manager_user_id su organization_user_details)
  • per il caricamento CV: il servizio AI extractor deve essere configurato a livello platform (platform_ai_settings.cv_extractor_provider, default haiku)
  • per la persistenza degli audit: migration 0072_profile_audit_columns.sql applicata sul progetto

Concetti chiave

  • Perimetro HR: chi ha tenant.hr.data.manage vede tutti i dipendenti del tenant e puo editarne il profilo professionale
  • Perimetro manager: il manager vede e gestisce solo i propri diretti (badge Diretto nella picker list)
  • Audit visibile: ogni modifica registra last_edited_by_user_id, last_edited_at, last_edit_source (self/hr_admin/manager/system). L'utente target vede chi/quando ha modificato cosa
  • PII boundary: HR e manager possono editare firstName, lastName, headline, esperienze, skill. NON possono modificare email, phone, data nascita, indirizzo, IBAN, P.IVA (riservati al soggetto)
  • Dati contrattuali (paghe): HR e manager gestiscono matricola, codice fiscale (validato con checksum), date assunzione/cessazione, tipo contratto, CCNL + livello + inquadramento, ore settimanali, % part-time e sede — base giuridica: obbligo legale paghe. Matricola e CF compaiono nei report per il consulente del lavoro
  • CV import: caricare un file CV (PDF/DOCX/TXT/MD) attiva l'AI extractor che produce una bozza strutturata rivedibile campo per campo (review diff inline). Solo i campi confermati vengono salvati

Passi operativi base

  1. Modifica direttamente i campi e clicca Salva anagrafica per le basics
  2. Per import CV: vedi sezione dedicata sotto

Caricamento CV (import-from-cv)

  1. Toast di conferma con dettaglio: anagrafica salvata, N esperienze applicate, M esperienze fallite (skill mancanti — completare via wizard self-service)

Archivio CV e Centro CV globale (Storage 01)

Dal programma HORIS_HR_CV_STORAGE_01 (2026-05-15) ogni CV caricato viene archiviato in modo permanente sul tenant. Due punti di accesso:

Sezione "CV archiviati" nel profilo soggetto

Sopra il pannello blu Carica CV per pre-compilare trovi la lista dei CV già caricati per il soggetto. Ogni riga mostra:

  • Nome file originale + dimensione (KB)
  • Badge stato: Caricato (upload manuale senza apply), Estratto (parsato ma non ancora applicato), Applicato (dati confermati nel profilo), Archiviato
  • Data + autore upload (self/HR admin/manager)
  • Pulsante Apri → apre il PDF in nuova scheda via signed URL (TTL 5 minuti)
  • Pulsante Elimina → soft delete audit-tracked (solo HR admin / owner / self)

Centro CV globale `/workspace/hr/cv-library`

Pulsante 📚 Centro CV globale → in alto a destra nella pagina /workspace/hr/people. Vista riservata a HR admin / owner / admin (manager → 403 con messaggio dedicato). Caratteristiche:

  • Tabella paginata (default 25 righe) con tutti i CV vivi del tenant
  • Filtri combinabili: query filename, status, range date Dal / Al
  • Statistiche top: totale CV vivi, caricati ultimi 7 giorni, pagina corrente
  • Azioni per riga: Apri (signed URL), Profilo → (deep link al profilo soggetto già selezionato), Elimina

Auto-archivio nel flusso CV import

Quando un HR/manager carica un CV dal pannello blu Carica CV per pre-compilare:

  1. Il file viene parsato (parseCvBuffer) e inviato all'AI extractor
  2. In parallelo il PDF originale viene salvato nel bucket Supabase hr-cvs con status='extracted' e badge verde nel modal ✓ CV originale archiviato
  3. Se l'utente conferma Applica selezionati, il record viene aggiornato a status='applied' con applied_by_user_id audit
  4. Se l'upload del bucket fallisce (storage giù), il modal mostra ⚠ Archivio CV non riuscito ma l'estrazione e l'apply proseguono fail-soft

Permessi sintetici

  • Self: vede e cancella solo i propri CV (futuro: UI dentro /workspace/profile)
  • Manager: vede e cancella solo i CV dei direct report dalla sezione del profilo soggetto (NO Centro CV)
  • HR admin / owner / admin: vede e cancella TUTTI i CV del tenant dalla sezione del profilo + dal Centro CV globale

Bulk CV import — `/workspace/hr/cv-bulk` (Bulk 03)

Dal programma HORIS_HR_CV_INGESTION_03_BULK (2026-05-18) HR admin può caricare fino a 50 CV in un singolo flusso + opzionale CSV di mapping filename,target_email, ed eseguire estrazione + apply in batch.

Accesso: pulsante 📤 Bulk CV import → in alto a destra su /workspace/hr/people. Riservato a HR admin / owner / admin (manager → pagina di accesso negato).

Flusso 4 step

  1. Apply — barra di progresso blue con concorrenza 3. Per ogni riga selezionata il sistema chiama gli helper profile-service (riusa identico boundary PII del flusso single-upload). A fine: 4 stat card (totale, applicati, falliti, status job) + lista per-riga con apply_summary.

Constraints

  • Solo utenti già membri del tenant: il bulk import NON crea utenti nuovi. Per CV di candidati pre-assunzione vedi futuro programma PRE_ONBOARDING_01.
  • Max 50 file per job (configurabile via HR_CV_BULK_MAX_FILES_PER_JOB).
  • MIME whitelist: stessa del single-upload (PDF/DOC/DOCX/TXT).
  • Audit-tracked per riga: applied_by_user_id, applied_at, apply_summary (jsonb con per-step counters + errori).
  • Fail-soft per riga: una riga fallita non blocca il resto del job; lo status finale del job è partially_applied se ci sono fallimenti, completed se tutto ok.

Performance

  • Concorrenza client-orchestrata 3 parallele su entrambi gli step (estrazione + apply). Nessun endpoint server-side processa N file in serie → no timeout Vercel 60s.
  • 20 CV ≈ 30-50 secondi end-to-end (incluso review pause).

Visibilita audit lato utente target

L'utente Bob (dipendente target) puo vedere in API:

  • /api/people/<bob>/profile ritorna ogni esperienza/skill con last_edited_by_user_id, last_edited_at, last_edit_source
  • Una futura UI lato /workspace/profile self mostrera un banner "Profilo aggiornato da {{nome HR}} il {{data}} via {{source}}"

Per ora il banner self e' parte del backlog post-programma (richiede refactor del wizard self 2671 righe).

Configurazione provider AI extractor

Il provider per l'estrazione CV e' configurabile via SQL su platform_ai_settings:

```sql -- Default (Haiku 4.5, ~$0.01-0.02 per CV, latency ~2-4s) update public.platform_ai_settings set cv_extractor_provider = NULL where scope = 'global'; -- oppure esplicito update public.platform_ai_settings set cv_extractor_provider = 'haiku' where scope = 'global';

-- Upgrade qualita (Sonnet 4.6, ~$0.03-0.05 per CV, marginalmente piu accurato su CV complessi) update public.platform_ai_settings set cv_extractor_provider = 'sonnet' where scope = 'global'; ```

I costi sono monitorabili dal Workspace › Platform › AI Usage (filtro per kind=cv_extract o model=claude-haiku-4-5).

Risultato atteso

  • HR/manager puo gestire il profilo professionale di altri dipendenti senza accedere ai contatti personali
  • Caricamento CV → bozza strutturata in 2-4 secondi
  • Review diff campo per campo elimina rischio sovrascrittura dati esistenti senza consenso
  • Audit trail completo per GDPR + accountability
  • Telemetria costi disponibile in AI Usage dashboard

Skill matching catalog (W02 02_UX_POLISH)

Le skill estratte dal CV vengono automaticamente confrontate col catalog skill del tenant (hr_skills + hr_skill_catalog_extensions). Per ogni skill:

  • Badge confidence:
  • Alta (verde, >=95%): match esatto su nome o alias
  • Media (blu, 75-95%): substring match (es. "Java" matcha "Java SE 21")
  • Bassa (ambra, 55-75%): fuzzy match con Levenshtein (tolleranza typo, es. "Pyhton" → "Python")
  • Nessun match (grigio): skill non presente nel catalog — crea la skill dal pannello admin tenant prima di poterla applicare
  • Dropdown candidati: per ogni skill, top 5 candidati ordinati per confidence; puoi switch al candidato corretto
  • Auto-selection: le skill con confidence >=85% sono pre-selezionate per Apply
  • Warning "verifica" mostrato accanto a candidati < 85% per richiamare attenzione
  • Apply delle skill selezionate → POST /api/people/[userId]/profile/skills con audit last_edit_source="hr_admin" o "manager"

Esempio: il CV propone "Spring Boot, JS, Microsoft Office". Il matcher trova:

  • Spring Boot → match esatto 1.0 verso Spring Boot (catalog)
  • JS → match alias 0.92 verso JavaScript (alias=["JS","ECMAScript"])
  • Microsoft Office → match esatto 1.0 verso Microsoft Office

Tutti pre-selezionati con badge Alta. Click Salva e chiudi (5) → 5 skill applicate al profilo target con audit visibile.

Banner diagnostico persistente (W01+W04 02_UX_POLISH)

Dopo ogni Apply, un banner color-coded compare in basso-destra della pagina:

  • Verde (success): tutte le operazioni OK
  • Ambra (warning): operazioni miste — alcune OK, altre saltate/fallite (es. esperienze senza skill catalog)
  • Rosso (error): errore critico (es. permission, network)

Il banner mostra:

  • Titolo con summary ("Applicate: 3 campi anagrafica + 5 skill + 0 esperienze")
  • Detail con durata totale ms + motivo principale failure
  • Lista steps ognuno con icona ✓ / ✕ / —
  • Timestamp ISO
  • Pulsante per dismiss manuale

Resilienza refresh: il banner sopravvive a refresh pagina (10 minuti window). Letto da sessionStorage["horis.hr-people.lastApply"]. Pablo puo ricaricare pagina dopo apply e vedere ancora il risultato.

Limitazioni residue (post 02_UX_POLISH)

  1. Esperienze CV con skillIds vuoti (limit residuo): il service-layer richiede almeno 1 skillId per ogni esperienza. Le esperienze estratte dal CV NON vengono associate automaticamente alle skill (link experience↔skill richiede mapping piu complesso). Workaround: le skill estratte SONO salvate al profilo come standalone (hr_user_skills), e l'HR completa il linking experience↔skill via wizard self-service del soggetto post-save. Programma futuro: experience↔skill linking automatico tramite contesto LLM.
  2. Languages auto-save: estratte ma non persistite. Backlog.
  3. Skill senza match catalog: skill che il matcher non trova nel catalog tenant sono mostrate con badge Nessun match e checkbox disabled. L'HR deve creare la skill dal pannello admin (hr_skill_catalog_extensions) prima di poterla applicare. Programma futuro: workflow "Crea skill nel catalog tenant" inline dal modal review.
  4. ~~Add experience/skill UI inline lato HR: placeholder.~~ RISOLTO 2026-05-15: i bottoni + Aggiungi esperienza e + Aggiungi skill aprono ora modali HORIS-canonical funzionali con search live nel catalog skill + validazione client-side + auto-link experience↔skill.
  5. ~~OCR per PDF scansionati: non supportato.~~ RISOLTO 2026-05-18 (HORIS_HR_OCR_01): i PDF senza testo selezionabile vengono OCR-decifrati via Claude Haiku 4.5 vision come fallback automatico in parseCvBuffer. Trasparente per l'utente. Disable via env HORIS_OCR_FALLBACK_ENABLED=false.
  6. Pre-onboarding candidati: il flusso opera solo su utenti gia membri del tenant. Profilo candidato pre-assunzione e' fuori scope (futuro programma).
  7. Mass upload: caricamento massivo CSV + N CV in batch non disponibile (futuro programma HORIS_HR_CV_INGESTION_03_BULK).
  8. Banner audit lato self user `/workspace/profile`: l'utente target oggi vede l'audit info via API. Banner UI dedicato dentro il wizard self-service richiede refactor del monolite — backlog post-programma.

Errori frequenti

  • 403 Forbidden / Missing permission
  • causa: ruolo senza tenant.hr.data.manage, o manager che cerca di editare non-direct
  • soluzione: chiedi al owner di assegnare la permission, o verifica il manager scope
  • "PDF illeggibile, allega .txt o .md"
  • causa: PDF scansionato senza testo selezionabile (immagine)
  • soluzione: converti manualmente in testo
  • "N esperienze fallite (skill mancanti)"
  • causa: l'extractor estrae roleTitle/description ma il service-layer richiede almeno 1 skill linkata
  • soluzione: l'HR completa il linking skill via wizard self-service del soggetto
  • Email/telefono non aggiornati anche se nel CV
  • causa: PII riservata al soggetto, HR/manager non puo modificarli
  • soluzione: il soggetto aggiorna i propri dati personali dal proprio profilo
  • Provider AI non risponde / extractor empty
  • causa: anthropic_api_key non configurata, o provider in fail-soft
  • soluzione: verifica platform_ai_settings.anthropic_api_key + cv_extractor_provider; consulta Workspace › Platform › AI Usage per error rate

Guide collegate

FAQ

Posso vedere chi ha modificato il profilo di Bob?

Si. Ogni esperienza e skill ha campi audit last_edited_by_user_id, last_edited_at, last_edit_source. Visibili nell'editor HR + nel banner sticky.

HR puo modificare l'email di Bob?

No. Email, telefono, data nascita e indirizzo sono riservati al soggetto (PII contrattuale). Solo Bob puo modificarli dal proprio Profilo professionale.

Posso usare GPT/un altro LLM al posto di Haiku?

In questa versione il provider e' Anthropic (Haiku 4.5 default, Sonnet 4.6 opzionale). Switch a OpenAI/altro provider richiede sviluppo aggiuntivo non incluso nel programma.

Cosa succede se carico un CV gia uploadato in precedenza?

Il sistema rifa l'estrazione e mostra il review diff vs profilo attuale. Tu decidi cosa applicare. Nessun rischio di duplicati automatici.

I miei dipendenti vengono notificati quando modifico il loro profilo?

Per la versione MVP non c'e notifica push. L'utente target vede l'audit info quando apre il proprio profilo. Notifica email/in-app e' nel backlog post-programma.

Guide correlate