longevity: #15 API della prima consulenza e flusso guidato nel check-up
Nuova API consulenza.ts (POST, autore da locals.user, redirect a checkup?flusso=nuovo o alla scheda cliente). clienti.ts ora apre il flusso guidato verso /consulenza?flusso=nuovo invece della scheda. checkup.ts: un check-up NUOVO con flusso=nuovo prosegue con flusso=questionario; una correzione lo ignora sempre. Refs #15 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -165,5 +165,9 @@ export const POST: APIRoute = async ({ request, locals }) => {
|
|||||||
|
|
||||||
const params = new URLSearchParams({ salvato: String(esito.sessioneId) });
|
const params = new URLSearchParams({ salvato: String(esito.sessioneId) });
|
||||||
if (esito.fuoriRange.length > 0) params.set('fuori', String(esito.fuoriRange.length));
|
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()}`);
|
return redirect(`/longevity/gestionale/cliente/${clientCode}?${params.toString()}`);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,5 +52,7 @@ export const POST: APIRoute = async ({ request }) => {
|
|||||||
telefono: telefono || undefined,
|
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`);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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`);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user