Skip to content

moisesvalero/fisionova

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

90 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FisioNova Clinica, recepcionista IA para fisioterapia

Demo en Vercel Next.js React TypeScript License

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/

Captura de FisioNova Clinica

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.

Que demuestra

  • 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 Google Gemini (prioritario) u OpenRouter (modelos Open-Source como Qwen) para interpretar mensajes y proponer huecos de forma estructurada.
  • Flujo seguro de citas: la IA no confirma citas finales, crea una solicitud pendiente.
  • Panel privado /medico protegido 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.

Stack

  • Next.js 16, App Router y React 19.
  • TypeScript estricto.
  • Tailwind CSS 4.
  • Componentes estilo shadcn con Button y utilidad cn().
  • Zod para validar variables de entorno y payloads.
  • Google Gemini API (prioritaria) y OpenRouter (fallback secundario) para la recepcionista.
  • Resend para emails de confirmacion, cancelacion y cambios.
  • Supabase opcional para guardar citas en produccion.
  • Vitest, Testing Library, ESLint y Prettier.

Flujo de cita

  1. El paciente habla con Virgi.
  2. Si no cuenta que le duele, Virgi pregunta antes de mostrar huecos.
  3. Si detecta el motivo, asigna tratamiento: general, deportiva o postural.
  4. La web muestra huecos disponibles.
  5. El paciente deja sus datos.
  6. Se crea una cita pending.
  7. El medico entra en /medico, revisa el calendario y confirma, mueve o cancela.
  8. Si una cancelacion o cambio libera un hueco, el panel propone pacientes marcados como "quiere venir antes".
  9. Recepcion puede marcar esperando respuesta, pago pendiente, no presentado, finalizada o enviar recordatorio.
  10. Solo al confirmar/cambiar/cancelar/crear/recordar desde el panel privado se llama a /api/email.

Seguridad y limites actuales

Incluido:

  • .env* ignorado por Git, excepto .env.example.
  • Validacion centralizada de env vars en src/lib/env.ts.
  • Gemini, OpenRouter y Resend solo se usan desde rutas server-side.
  • /api/appointments protege lectura y cambios con DOCTOR_DASHBOARD_PIN.
  • /api/email protege el envio con DOCTOR_DASHBOARD_PIN.
  • Rate limit ligero en memoria para /api/receptionist y POST publico de /api/appointments.
  • Limites de longitud en mensajes, datos de paciente y payloads de email.
  • Headers de seguridad en next.config.ts.
  • /medico tiene noindex y robots.ts bloquea /api/ y /medico.
  • JSON-LD se serializa escapando <.

Pendiente para produccion real:

  • Cambiar DOCTOR_DASHBOARD_PIN, no usar 1234.
  • 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.

Arranque local

pnpm install
cp .env.example .env.local
pnpm run dev

Abre http://localhost:3000.

Panel privado local:

http://localhost:3000/medico
PIN demo: 1234

Variables de entorno

Copia .env.example a .env.local y rellena solo lo necesario.

NEXT_PUBLIC_APP_URL=http://localhost:3000

# Gemini prioritario
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.5-flash

# OpenRouter opcional (fallback)
OPENROUTER_API_KEY=
OPENROUTER_MODEL=qwen/qwen-2.5-coder-32b-instruct:free

# 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 GEMINI_API_KEY ni OPENROUTER_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.

Despliegue en Vercel

  1. Importa el repositorio en Vercel.
  2. Configura como minimo:
    • NEXT_PUBLIC_APP_URL=https://tu-dominio.vercel.app
    • DOCTOR_DASHBOARD_PIN=un-pin-largo-no-obvio
  3. Para IA real:
    • GEMINI_API_KEY y GEMINI_MODEL=gemini-2.5-flash (más rápido y nativo).
    • O OPENROUTER_API_KEY y OPENROUTER_MODEL=qwen/qwen-2.5-coder-32b-instruct:free (como fallback).
  4. Para emails reales:
    • RESEND_API_KEY
    • RESEND_FROM_EMAIL
    • RESEND_REPLY_TO_EMAIL si quieres que las respuestas vayan a otra cuenta.
  5. Para persistencia real:
    • NEXT_PUBLIC_SUPABASE_URL
    • NEXT_PUBLIC_SUPABASE_ANON_KEY
    • SUPABASE_SERVICE_ROLE_KEY
    • Ejecuta supabase/appointments.sql en tu proyecto Supabase.

Entregabilidad de emails

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 configura RESEND_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.
  1. Ejecuta antes:
pnpm run verify

Scripts

pnpm 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 Impeccable

Estructura principal

src/
  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

Licencia

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.

About

Landing completa de una clinica local ficticia con reservas con IA

Topics

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages