import type { FastifyInstance } from 'fastify'; import { z } from 'zod'; import { computeScore } from './score'; const DiagnosisBody = z.object({ answers: z.record(z.string(), z.string()), }); export async function diagnosisRoutes(app: FastifyInstance) { app.addHook('onRequest', app.authenticate); app.get('/', async (req) => { return app.prisma.diagnosis.findMany({ where: { userId: req.user.sub }, orderBy: { createdAt: 'desc' }, take: 10, }); }); app.post('/', async (req, reply) => { const body = DiagnosisBody.parse(req.body); const score = await computeScore(app, req.user.sub); const recommendations = recommend(body.answers, score.breakdown); const saved = await app.prisma.diagnosis.create({ data: { userId: req.user.sub, answers: body.answers, score: score.total, breakdown: { categories: score.breakdown, recommendations }, }, }); reply.code(201); return saved; }); } function recommend(answers: Record, breakdown: Array<{ label: string; status: string }>) { const recs: Array<{ name: string; reason: string; priority: '필수' | '권장' | '선택' }> = []; const missing = breakdown.filter((b) => b.status === 'none' || b.status === 'bad'); missing.forEach((m) => { recs.push({ name: m.label, reason: `현재 ${m.status === 'none' ? '미가입' : '보장 부족'}`, priority: m.label === '실손보험' ? '필수' : '권장', }); }); if (answers.family === '있음') { recs.push({ name: '암보험 진단비 강화', reason: '가족력 있음', priority: '필수' }); } if (answers.smoke === '흡연') { recs.push({ name: '뇌혈관/심장 특약', reason: '흡연자 고위험군', priority: '권장' }); } if (answers.hospital === '3회 이상') { recs.push({ name: '입원일당 특약', reason: '잦은 입원 이력', priority: '권장' }); } return recs.slice(0, 6); }