Demo publica para portfolio tecnico: una web app de una clinica de fisioterapia ficticia con recepcionista IA, solicitud de citas, agenda privada para el medico y confirmaciones por email.
Demo online: https://proyecto-ia-recepcionista.vercel.app/
FisioNova Clinica no es una clinica real. Es un proyecto de portfolio para demostrar producto, UX, frontend, backend ligero e integracion con IA. El chat incluye una barrera de seguridad: ante urgencias, diagnosticos, medicacion o sintomas serios, informa de que es una demo ficticia y deriva a urgencias o a un profesional sanitario real.
- Landing completa de una clinica local ficticia, con hero visual, tratamientos, equipo, contacto, FAQ y politica de cookies.
- Chat con Virgi, recepcionista IA, integrado en la web y ampliable en modal.
- Integracion opcional con OpenAI para interpretar mensajes y proponer huecos.
- Flujo seguro de citas: la IA no confirma citas finales, crea una solicitud pendiente.
- Panel privado
/medicoprotegido por PIN. - Calendario operativo tipo agenda, con horario fijo 10:00-19:00, filtro por profesional, click en citas, ficha del paciente, acciones y movimiento por drag and drop.
- Gestion manual desde
/medico: crear, modificar, cancelar y confirmar citas sin depender al cien por cien de la IA. - Panel enfocado a recepcion: estados operativos, recordatorios por email, bloqueos manuales, no presentado, pago pendiente y cita finalizada.
- Tratamientos con tiempo de sesion y lista de espera para recolocar pacientes que quieren venir antes cuando se libera un hueco.
- Enlaces firmados en emails para que el paciente pueda confirmar o cancelar sin entrar al panel privado.
- Emails transaccionales con Resend solo desde el panel privado.
- Modo demo sin base de datos, mas opcion Supabase para persistencia real.
- SEO tecnico: metadata, sitemap, robots, manifest, Open Graph, JSON-LD y
llms.txt. - Verificacion con TypeScript, ESLint, Prettier, Vitest, build y audit.
- Next.js 16, App Router y React 19.
- TypeScript estricto.
- Tailwind CSS 4.
- Componentes estilo shadcn con
Buttony utilidadcn(). - Zod para validar variables de entorno y payloads.
- OpenAI Responses API para la recepcionista.
- Resend para emails de confirmacion, cancelacion y cambios.
- Supabase opcional para guardar citas en produccion.
- Vitest, Testing Library, ESLint y Prettier.
- El paciente habla con Virgi.
- Si no cuenta que le duele, Virgi pregunta antes de mostrar huecos.
- Si detecta el motivo, asigna tratamiento: general, deportiva o postural.
- La web muestra huecos disponibles.
- El paciente deja sus datos.
- Se crea una cita
pending. - El medico entra en
/medico, revisa el calendario y confirma, mueve o cancela. - Si una cancelacion o cambio libera un hueco, el panel propone pacientes marcados como "quiere venir antes".
- Recepcion puede marcar esperando respuesta, pago pendiente, no presentado, finalizada o enviar recordatorio.
- Solo al confirmar/cambiar/cancelar/crear/recordar desde el panel privado se llama a
/api/email.
Incluido:
.env*ignorado por Git, excepto.env.example.- Validacion centralizada de env vars en
src/lib/env.ts. - OpenAI y Resend solo se usan desde rutas server-side.
/api/appointmentsprotege lectura y cambios conDOCTOR_DASHBOARD_PIN./api/emailprotege el envio conDOCTOR_DASHBOARD_PIN.- Rate limit ligero en memoria para
/api/receptionisty POST publico de/api/appointments. - Limites de longitud en mensajes, datos de paciente y payloads de email.
- Headers de seguridad en
next.config.ts. /medicotienenoindexyrobots.tsbloquea/api/y/medico.- JSON-LD se serializa escapando
<.
Pendiente para produccion real:
- Cambiar
DOCTOR_DASHBOARD_PIN, no usar1234. - Activar Supabase si quieres persistencia real de citas.
- Configurar reglas/RLS y backups si se usa Supabase.
- Anadir proteccion perimetral real si el proyecto recibe trafico: Vercel Firewall, WAF, Turnstile, captcha o rate limit persistente.
- Rotar cualquier API key que se haya pegado en chats, capturas o commits.
- Revisar textos legales con un profesional si se va a usar comercialmente.
pnpm install
cp .env.example .env.local
pnpm run devAbre http://localhost:3000.
Panel privado local:
http://localhost:3000/medico
PIN demo: 1234
Copia .env.example a .env.local y rellena solo lo necesario.
NEXT_PUBLIC_APP_URL=http://localhost:3000
# OpenAI opcional
OPENAI_API_KEY=
OPENAI_MODEL=gpt-5.4-nano
# Supabase opcional
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Panel privado
DOCTOR_DASHBOARD_PIN=1234
APPOINTMENT_ACTION_SECRET=
# Resend opcional
RESEND_API_KEY=
RESEND_FROM_EMAIL=onboarding@resend.dev
RESEND_REPLY_TO_EMAIL=Sin OPENAI_API_KEY, se usa fallback local basado en reglas. Sin SUPABASE_SERVICE_ROLE_KEY, las citas viven en memoria durante la sesion del servidor. Sin RESEND_API_KEY, los emails se simulan.
- Importa el repositorio en Vercel.
- Configura como minimo:
NEXT_PUBLIC_APP_URL=https://tu-dominio.vercel.appDOCTOR_DASHBOARD_PIN=un-pin-largo-no-obvio
- Para IA real:
OPENAI_API_KEYOPENAI_MODEL=gpt-5.4-nanoo el modelo gratuito/disponible que quieras probar.
- Para emails reales:
RESEND_API_KEYRESEND_FROM_EMAILRESEND_REPLY_TO_EMAILsi quieres que las respuestas vayan a otra cuenta.
- Para persistencia real:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEY- Ejecuta
supabase/appointments.sqlen tu proyecto Supabase.
Para reducir la probabilidad de spam en Resend:
- Usa un dominio verificado con SPF y DKIM activos.
- Mantén DMARC publicado en DNS. Para empezar:
v=DMARC1; p=none; rua=mailto:tu-email@tu-dominio.com;. - Envía desde una cuenta real del dominio, por ejemplo
FisioNova <citas@moisesvalero.es>, y configuraRESEND_REPLY_TO_EMAIL. - Evita mezclar emails transaccionales con llamadas comerciales agresivas. El email de cita mantiene el portfolio como firma pequeña.
- En Resend, revisa cada envío en Emails > Insights para confirmar que pasan SPF, DKIM y DMARC.
- Ejecuta antes:
pnpm run verifypnpm run dev # servidor local
pnpm run build # build de produccion
pnpm run start # servir build
pnpm run lint # ESLint
pnpm run check # TypeScript sin emitir
pnpm run format # formatear con Prettier
pnpm run format:check # comprobar formato
pnpm test # tests unitarios
pnpm run audit # pnpm audit high+
pnpm run verify # formato, lint, tipos, tests, build y audit
pnpm run design:audit # auditoria visual con Impeccablesrc/
app/
api/appointments/ # citas, agenda privada y acciones
api/email/ # emails protegidos por PIN
api/receptionist/ # chat IA y fallback local
medico/ # panel privado
components/
receptionist/ # landing, chat, calendario y panel medico
legal/ # cookies
seo/ # JSON-LD
ui/ # componentes base
lib/
receptionist/ # agenda, datos demo, emails y store
env.ts # validacion de entorno
rate-limit.ts # rate limit demo en memoria
supabase/
appointments.sql # esquema opcional
Este proyecto es source-available no comercial. El codigo se puede ver, estudiar, bifurcar y adaptar para aprendizaje, evaluacion tecnica y portfolio, pero no se puede usar para ganar dinero sin permiso escrito del autor.
Licencia base: PolyForm Noncommercial License 1.0.0.
No esta permitido, sin permiso escrito de Moises Valero:
- Revender este proyecto o versiones modificadas.
- Usarlo para entregar un trabajo pagado a un cliente.
- Desplegarlo como producto de pago, SaaS, plantilla, starter kit o white-label.
- Integrarlo en un producto o servicio comercial.
- Presentarlo como producto comercial propio.
Para licencia comercial, contratacion o colaboracion: https://moisesvalero.es/.
Ver LICENSE.
