Feature: Sistema de Reservas de Turnos Medicos¶
Proposito¶
Spec completa de la feature core del sistema: permitir a pacientes reservar turnos con medicos segun especialidad, clinica, y disponibilidad. Este es el ejemplo transversal usado en todo el workspace.
Metadata¶
| Campo | Valor |
|---|---|
| Feature ID | FEAT-002 |
| Autor | Carlos Ramirez |
| Fecha | 2025-03-20 |
| Estado | Approved |
| Prioridad | Critical |
| Epic | Reservas de Turnos |
1. Problema¶
Contexto¶
Las clinicas gestionan turnos por telefono o WhatsApp. Los pacientes llaman, esperan, y muchas veces no consiguen turno. Los medicos no tienen visibilidad de su agenda en tiempo real.
Dolor del usuario¶
- Los pacientes pierden tiempo llamando para encontrar disponibilidad.
- Los medicos tienen agendas desorganizadas con solapamientos.
- Las clinicas pierden pacientes por la friccion del proceso manual.
Impacto del negocio¶
- Cada turno no reservado por friccion es ingreso perdido.
- El costo operativo de coordinar turnos manualmente es alto (recepcionistas dedicadas).
- Clinicas competidoras con sistema digital capturan pacientes insatisfechos.
2. Solucion Propuesta¶
Descripcion general¶
Sistema web donde los pacientes buscan medicos por especialidad y clinica, ven disponibilidad en tiempo real, y reservan turnos. Los medicos configuran su disponibilidad semanal y reciben notificaciones de nuevas reservas.
Usuarios objetivo¶
- Pacientes: Buscan y reservan turnos online.
- Medicos: Configuran disponibilidad y gestionan su agenda.
- Admins de clinica: Configuran clinicas, especialidades, y supervisan ocupacion.
Flujo principal (Happy Path)¶
Reserva de turno por paciente: 1. El paciente selecciona una especialidad (ej: "Cardiologia"). 2. El sistema muestra medicos disponibles con esa especialidad. 3. El paciente selecciona un medico. 4. El sistema muestra los horarios disponibles del medico (proximos 30 dias). 5. El paciente selecciona un horario. 6. El sistema muestra un resumen: medico, especialidad, clinica, fecha, hora, duracion. 7. El paciente confirma la reserva. 8. El sistema crea el turno, envia confirmacion al paciente y notificacion al medico.
Configuracion de disponibilidad por medico: 1. El medico accede a su panel de disponibilidad. 2. Define su horario semanal recurrente (ej: Lunes 9-13, Miercoles 14-18). 3. Define la duracion de cada turno (ej: 30 minutos). 4. Puede bloquear dias especificos (ej: vacaciones, feriados). 5. El sistema genera los slots disponibles automaticamente.
Flujos alternativos¶
- Sin disponibilidad: El sistema muestra "No hay turnos disponibles en los proximos 30 dias" y sugiere otros medicos de la misma especialidad.
- Paciente ya tiene turno con ese medico: El sistema advierte "Ya tienes un turno pendiente con este medico" y ofrece ver el turno existente.
- Medico modifica disponibilidad con turnos ya reservados: Los turnos existentes se mantienen. Solo los slots futuros sin reserva se ven afectados.
Flujos de error¶
- Conflicto de concurrencia (dos pacientes reservan el mismo slot): El segundo paciente ve "Este horario acaba de ser reservado" y el sistema le muestra el siguiente disponible.
- Error al enviar notificacion: La reserva se crea igual. La notificacion se encola para reintento (max 3 intentos).
- Sesion expirada durante la reserva: El sistema guarda el estado en la sesion. Al re-autenticarse, el paciente retoma donde quedo.
3. Reglas de Negocio¶
| ID | Regla | Ejemplo |
|---|---|---|
| RN-01 | Un paciente no puede tener 2 turnos con el mismo medico en el mismo dia | Si ya tiene turno con Dr. Garcia el lunes, no puede reservar otro el mismo dia |
| RN-02 | Los turnos se reservan con minimo 2 horas de anticipacion | A las 14:00 no puedes reservar un turno para las 15:00 del mismo dia |
| RN-03 | Un medico puede atender en multiples clinicas pero no en 2 clinicas al mismo tiempo | Dr. Garcia puede estar en Clinica A por la manana y Clinica B por la tarde |
| RN-04 | La duracion del turno la define el medico (15, 20, 30, 45, o 60 min) | Un dermatologo puede configurar 20 min, un psiquiatra 45 min |
| RN-05 | Los turnos cancelados con menos de 24h generan una penalizacion | Cancelar a las 8:00 un turno de las 10:00 del mismo dia cuenta como penalizacion |
| RN-06 | Despues de 3 penalizaciones, el paciente no puede reservar por 30 dias | Penalizacion 3 activa bloqueo hasta [fecha + 30 dias] |
| RN-07 | El horario disponible se muestra en la zona horaria de la clinica | Clinica en Buenos Aires muestra hora Argentina, no UTC |
| RN-08 | Un medico puede bloquear cualquier dia futuro de su agenda | Bloquear 25 de diciembre elimina todos los slots de ese dia |
4. Modelo de Datos¶
Entidades involucradas¶
Doctor | Atributo | Tipo | Requerido | Notas | |----------|------|-----------|-------| | id | UUID | Si | PK | | user_id | UUID | Si | FK -> User | | license_number | string | Si | Matricula profesional | | specialties | UUID[] | Si | FK -> Specialty (muchos) |
Specialty | Atributo | Tipo | Requerido | Notas | |----------|------|-----------|-------| | id | UUID | Si | PK | | name | string | Si | Ej: "Cardiologia" | | default_duration_minutes | integer | Si | Duracion sugerida |
Clinic | Atributo | Tipo | Requerido | Notas | |----------|------|-----------|-------| | id | UUID | Si | PK | | name | string | Si | | | address | string | Si | | | timezone | string | Si | Ej: "America/Argentina/Buenos_Aires" |
DoctorAvailability | Atributo | Tipo | Requerido | Notas | |----------|------|-----------|-------| | id | UUID | Si | PK | | doctor_id | UUID | Si | FK -> Doctor | | clinic_id | UUID | Si | FK -> Clinic | | day_of_week | integer | Si | 0=Domingo, 6=Sabado | | start_time | time | Si | Ej: "09:00" | | end_time | time | Si | Ej: "13:00" | | slot_duration_minutes | integer | Si | 15, 20, 30, 45, o 60 |
BlockedDate | Atributo | Tipo | Requerido | Notas | |----------|------|-----------|-------| | id | UUID | Si | PK | | doctor_id | UUID | Si | FK -> Doctor | | date | date | Si | Dia bloqueado | | reason | string | No | Opcional |
Booking | Atributo | Tipo | Requerido | Notas | |----------|------|-----------|-------| | id | UUID | Si | PK | | patient_id | UUID | Si | FK -> User (role=PATIENT) | | doctor_id | UUID | Si | FK -> Doctor | | clinic_id | UUID | Si | FK -> Clinic | | specialty_id | UUID | Si | FK -> Specialty | | date | date | Si | Fecha del turno | | start_time | time | Si | | | end_time | time | Si | | | status | enum | Si | CONFIRMED, CANCELLED, COMPLETED, NO_SHOW | | cancelled_at | timestamp | No | | | cancellation_penalty | boolean | Si | Default: false | | created_at | timestamp | Si | |
Relaciones¶
- Doctor N:M Specialty (a traves de tabla intermedia).
- Doctor N:M Clinic (a traves de DoctorAvailability).
- Doctor 1:N DoctorAvailability.
- Doctor 1:N BlockedDate.
- Booking pertenece a Patient, Doctor, Clinic, y Specialty.
5. Criterios de Aceptacion¶
- DADO un paciente autenticado CUANDO busca por especialidad "Cardiologia" ENTONCES ve la lista de medicos disponibles con esa especialidad.
- DADO un medico con disponibilidad configurada CUANDO un paciente selecciona al medico ENTONCES ve los slots disponibles de los proximos 30 dias.
- DADO un slot disponible CUANDO el paciente lo reserva ENTONCES el booking se crea con status CONFIRMED y el slot deja de estar disponible.
- DADO dos pacientes intentando reservar el mismo slot CUANDO el segundo confirma ENTONCES ve un mensaje de conflicto y se le sugiere el siguiente slot.
- DADO un paciente con turno CUANDO cancela con menos de 24h ENTONCES se registra una penalizacion.
- DADO un paciente con 3 penalizaciones CUANDO intenta reservar ENTONCES el sistema lo bloquea por 30 dias.
- DADO un medico CUANDO bloquea un dia futuro ENTONCES los slots de ese dia se eliminan y los turnos existentes se notifican.
- DADO una reserva confirmada CUANDO se crea ENTONCES el paciente recibe email de confirmacion y el medico recibe notificacion.
6. Out of Scope¶
- Pagos online: v1 es solo reserva, el pago se maneja en la clinica.
- Telemedicina / videollamadas: Feature separada para v2.
- Recetas electronicas: Fuera de alcance del sistema de reservas.
- Integracion con obras sociales / seguros: Complejidad regulatoria, fase posterior.
- App mobile nativa: v1 es web responsive, mobile nativa en v2.
7. Dependencias¶
| Dependencia | Tipo | Estado | Contacto |
|---|---|---|---|
| Modulo de autenticacion (FEAT-001) | Feature | Approved | Maria Lopez |
| Servicio de notificaciones (email) | Servicio | Ready | DevOps |
| Base de datos PostgreSQL | Infraestructura | Ready | Platform |
| Catalogo de especialidades medicas | Datos | In Progress | Product (Laura) |
| Configuracion de clinicas | Feature | In Progress | Backend team |
8. Consideraciones Tecnicas¶
Performance¶
- Busqueda de disponibilidad debe responder en < 1s (p95).
- Generacion de slots: calcular on-the-fly, no pre-generar en BD.
- Indice compuesto en
bookings(doctor_id, date)para evitar conflictos.
Seguridad¶
- Un paciente solo puede ver y gestionar sus propios bookings.
- Un medico solo puede ver los bookings de su propia agenda.
- Los datos del paciente (nombre, telefono) no se exponen en la busqueda publica.
- Proteger contra reservas automatizadas (bot) con rate limiting.
Escalabilidad¶
- Concurrencia en reservas: usar
SELECT ... FOR UPDATEo bloqueo optimista para evitar doble booking. - Para alta demanda (ej: vacunacion masiva): considerar sistema de cola con posicion.
- Particionar bookings por fecha para queries historicas eficientes.
9. Mockups / Wireframes¶
- Busqueda: Filtros por especialidad + clinica + fecha. Lista de medicos con foto, nombre, proxima disponibilidad.
- Calendario de slots: Vista semanal con slots disponibles resaltados en verde. Slots ocupados en gris (no clickeables).
- Confirmacion: Card con resumen del turno. Boton "Confirmar reserva". Checkbox "Acepto politica de cancelacion".
- Mi agenda (medico): Vista diaria con lista de turnos. Nombre del paciente, horario, especialidad. Acciones: completar, marcar no-show.
10. Metricas de Exito¶
| Metrica | Baseline | Target | Como se mide |
|---|---|---|---|
| Turnos reservados por dia | 0 (manual) | 50+ en primer mes | Query a bookings |
| Tiempo promedio de reserva (flujo completo) | ~5 min (telefono) | < 2 min (web) | Analytics de sesion |
| Tasa de no-show | ~20% (sin recordatorio) | < 10% | Status NO_SHOW / total |
| Satisfaccion del paciente | N/A | > 4.0/5.0 | Encuesta post-turno |
| Ocupacion de agenda medica | ~60% | > 80% | Slots reservados / disponibles |
Checklist de Completitud¶
- Problema claramente definido
- Solucion descrita sin ambiguedad
- Reglas de negocio listadas y con ejemplos
- Criterios de aceptacion escritos y testeables
- Out of scope definido
- Dependencias identificadas
- Consideraciones de seguridad documentadas
- Revisada por otro ingeniero
- Derivados generados (API contract / test plan / threat model)
Archivos relacionados¶
- _template.spec.md - Plantilla base
- feature-user-auth.spec.md - Spec de autenticacion (dependencia)
- ../03-domain-model/domain-booking.md - Modelo de dominio de reservas
- ../04-api-contracts/api-bookings.md - Contrato de API de reservas
- ../05-testing-strategy/bdd-scenarios-booking.md - Escenarios BDD