diff --git a/apps/platforms/src/pages/api/longevity/gestionale/checkup.ts b/apps/platforms/src/pages/api/longevity/gestionale/checkup.ts index 4afce49..6ff6259 100644 --- a/apps/platforms/src/pages/api/longevity/gestionale/checkup.ts +++ b/apps/platforms/src/pages/api/longevity/gestionale/checkup.ts @@ -165,5 +165,9 @@ export const POST: APIRoute = async ({ request, locals }) => { const params = new URLSearchParams({ salvato: String(esito.sessioneId) }); if (esito.fuoriRange.length > 0) params.set('fuori', String(esito.fuoriRange.length)); + // Passo 3 → 4 del flusso guidato (#15): solo un check-up NUOVO (mai una correzione, che + // non passa da questo ramo) con flusso=nuovo prosegue verso il questionario. + const flusso = String(form.get('flusso') ?? '').trim(); + if (flusso === 'nuovo') params.set('flusso', 'questionario'); return redirect(`/longevity/gestionale/cliente/${clientCode}?${params.toString()}`); }; diff --git a/apps/platforms/src/pages/api/longevity/gestionale/clienti.ts b/apps/platforms/src/pages/api/longevity/gestionale/clienti.ts index e10d011..6ccb228 100644 --- a/apps/platforms/src/pages/api/longevity/gestionale/clienti.ts +++ b/apps/platforms/src/pages/api/longevity/gestionale/clienti.ts @@ -52,5 +52,7 @@ export const POST: APIRoute = async ({ request }) => { telefono: telefono || undefined, }); - return redirect(`/longevity/gestionale/cliente/${code}`); + // Dopo l'apertura del fascicolo comincia il flusso guidato (#15, passo 1 → 2): prima + // consulenza, poi check-up, poi questionario — non più direttamente alla scheda. + return redirect(`/longevity/gestionale/cliente/${code}/consulenza?flusso=nuovo`); }; diff --git a/apps/platforms/src/pages/api/longevity/gestionale/consulenza.ts b/apps/platforms/src/pages/api/longevity/gestionale/consulenza.ts new file mode 100644 index 0000000..515988b --- /dev/null +++ b/apps/platforms/src/pages/api/longevity/gestionale/consulenza.ts @@ -0,0 +1,64 @@ +import type { APIRoute } from 'astro'; +import { getLongevityDb } from '../../../../lib/longevity/db'; +import { salvaConsulenza } from '../../../../lib/longevity/consulenza'; + +export const prerender = false; + +// Riservato a admin+trainer da src/lib/auth.ts (RULES, /^\/api\/longevity\/gestionale(\/|$)/). + +const REGEX_CODE = /^ISL-\d{4}$/; + +const redirect = (location: string): Response => new Response(null, { status: 303, headers: { Location: location } }); + +/** + * Salva la scheda di prima consulenza (#15). Autore SEMPRE da `locals.user`, mai dal form — + * stesso principio di giornale.ts e checkup.ts. Il flusso guidato (`flusso=nuovo`, passo 1 + * → 2) prosegue verso il check-up; fuori dal flusso torna alla scheda cliente, sezione + * #consulenza dove il form e la lettura vivono. + */ +export const POST: APIRoute = async ({ request, locals }) => { + const form = await request.formData(); + const clientCode = String(form.get('client_code') ?? '').trim(); + const flusso = String(form.get('flusso') ?? '').trim(); + + if (!REGEX_CODE.test(clientCode)) { + return redirect(`/longevity/gestionale?errore=${encodeURIComponent('Codice cliente non valido.')}`); + } + + // Il ritorno in caso di errore resta sulla stessa pagina del form, conservando `flusso`: + // altrimenti un errore fuori dal flusso guidato riporterebbe dentro il flusso, o viceversa. + const query = new URLSearchParams(); + if (flusso !== '') query.set('flusso', flusso); + const tornaAlModulo = (testo: string) => { + const q = new URLSearchParams(query); + q.set('errore', testo); + return redirect(`/longevity/gestionale/cliente/${clientCode}/consulenza?${q.toString()}`); + }; + + const db = getLongevityDb(); + const autore = locals.user!.username; + + const esito = salvaConsulenza(db, { + clientCode, + autore, + campi: { + livello: String(form.get('livello') ?? ''), + obiettivoPrimario: String(form.get('obiettivo_primario') ?? ''), + obiettivoSpecifico: String(form.get('obiettivo_specifico') ?? ''), + dataTarget: String(form.get('data_target') ?? ''), + noteMediche: String(form.get('note_mediche') ?? ''), + storiaSportiva: String(form.get('storia_sportiva') ?? ''), + limitazioni: String(form.get('limitazioni') ?? ''), + disponibilitaGiorni: String(form.get('disponibilita_giorni') ?? ''), + fasciaOraria: String(form.get('fascia_oraria') ?? ''), + noteScreening: String(form.get('note_screening') ?? ''), + }, + }); + if (!esito.ok) return tornaAlModulo(esito.errore); + + if (flusso === 'nuovo') { + // Passo 2 → 3 del flusso guidato (#15): dopo la consulenza si va al check-up. + return redirect(`/longevity/gestionale/cliente/${clientCode}/checkup?flusso=nuovo`); + } + return redirect(`/longevity/gestionale/cliente/${clientCode}?consulenza=salvata#consulenza`); +};