Repository navigation
Sprint 2: HU-002, HU-003, HU-004, HU-005, HU-006 y HU-009 - #5
Merged
Merged
Conversation
…la autorización base Módulo organization (domain, application, infrastructure, api): - Registro público del proveedor con cuenta propia (rol PROVIDER), al menos una sede y su política de operación v1. Queda PENDING_APPROVAL. Rechaza la identificación duplicada (409, también en carrera), la categoría o ciudad desconocidas y la anticipación mínima mayor que la máxima. Lo que falla después de crear la cuenta la borra (como D7). - Aprobación por un administrador con motivo obligatorio (HU-003). El correo se envía después del commit. - Cambio de los parámetros de operación por OWNER o MANAGER: crea una versión nueva y las reservas existentes conservan la suya. - Consulta del propio proveedor y catálogos públicos de categorías y ciudades. Autorización base (ADR-0008): /admin/** solo ADMIN; /organizations/** solo PROVIDER o ADMIN; OrganizationAccess responde 404 fuera del proveedor y 403 si el rol no alcanza. Módulo notification (ADR-0007): SMTP con Spring Mail; sin SPRING_MAIL_HOST, el correo se registra en el log. Migraciones: V4 tipo y número de identificación (renombra nit); V5 categorías, 32 ciudades y COP como datos de referencia. Otros: auth crea cuentas PROVIDER; la confirmación de correo acepta cuentas sin perfil de cliente; runbook (primer admin, SMTP), render.yaml y README al día. Pruebas: 718 unitarias y 89 de integración; ProviderOnboardingIT cubre los escenarios de HU-002 y los 404/403 de HU-022. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
El plan gratuito de Render bloquea la salida a los puertos SMTP desde septiembre de 2025, así que el correo por Gmail no funcionaría en producción. Para el MVP y la demo, sin cuentas ni claves externas: - V6 crea sent_emails, con RLS. Sin SMTP configurado, InboxEmailSender guarda ahí cada correo, en su propia transacción porque se envía en un listener AFTER_COMMIT. - GET /api/v1/notifications/emails devuelve los correos dirigidos al email del token, del más reciente al más antiguo. - SMTP queda como opción con SPRING_MAIL_HOST. Se elimina LoggingEmailSender. - ProviderOnboardingIT comprueba que la aprobación llega a la bandeja del proveedor. - ADR-0007 reescrito con la decisión real. README, runbook, render.yaml y el conteo de tablas del workflow (20) quedan al día. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Módulo catalog (domain, application, infrastructure, api) bajo
/api/v1/organizations/{id}:
- Tipos de recurso con nombre único por proveedor (409 DUPLICATE_NAME).
- Recursos de un tipo propio en una sede propia, con capacidad
simultánea y nombre único por sede. Tipo o sede ajenos dan 400 por
campo.
- Mantenimientos por rango de fechas: el recurso queda IN_MAINTENANCE
y Resource.isAvailableDuring lo excluye (regla que usará HU-008).
Dos periodos solapados dan 409 OVERLAPPING_PERIOD.
- Retiro bloqueado con reservas futuras (409 HAS_FUTURE_BOOKINGS con su
número). Se consulta booking_resources mediante un puerto hasta que
exista el módulo de reservas.
- Leen todos los miembros; cambian OWNER y MANAGER; fuera del proveedor,
404 (ADR-0008).
V7: capacity, estado ACTIVE/RETIRED (INACTIVE pasa a RETIRED),
organization_id con FK compuestas que cuadran tipo y sede, y
resource_maintenances con EXCLUDE de solape. seed.sql, modelo lógico y
dos pruebas de integridad nuevas (21 en total).
ProviderFixture crea proveedores activos por JDBC para las pruebas de
integración de los módulos que dependen de organization.
Pruebas: 751 unitarias y 99 de integración.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bajo /api/v1/organizations/{id}/services:
- Crear un servicio con nombre único por proveedor, duración,
preparación, limpieza, precio en COP, cupo (1 individual, más de 1
grupal), sus sedes y al menos un tipo de recurso requerido. Sedes o
tipos ajenos dan 400 por posición. Nace INACTIVE.
- Activar exige, en cada sede, suficientes recursos ACTIVE de cada tipo
requerido (HU-009). Si falta alguno, 409 INSUFFICIENT_RESOURCES con
el faltante por sede y tipo.
- Desactivar conserva el servicio y sus reservas. Eliminar solo si nunca
tuvo reservas; si las tiene, 409 HAS_BOOKINGS.
- Actualizar nombre, duración, tiempos, precio y cupo: las reservas
existentes conservan sus horarios. Sedes y requisitos se fijan al
crear el servicio.
services va por JPA; service_locations y service_resource_requirements
por JDBC en la misma transacción. Sus CF compuestas ya impedían cruzar
proveedores (V1). ProviderFixture crea servicios activos y reservas
por JDBC, compartidos con ResourceManagementIT.
Pruebas: 779 unitarias y 110 de integración.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Módulo scheduling bajo /api/v1/organizations/{id}/agendas:
- Crear una agenda de una sede, u opcionalmente de un recurso de ella,
con granularidad de 15, 30 o 60 minutos, vigencia, servicios
reservables (deben prestarse en la sede) y bloques semanales.
- Un bloque que termina antes de empezar, o dos solapados el mismo día,
no se guardan. Dos agendas vigentes a la vez para la misma sede o
recurso dan 409 (EXCLUDE en la base).
- Reemplazar los bloques o duplicar un día solo si ninguna reserva
futura queda fuera de horario; si alguna queda fuera, 409 con la
lista de reservas. La comparación se hace en la hora local de la
sede.
- La granularidad no cambia mientras haya reservas futuras.
- Leen todos los miembros; cambian OWNER y MANAGER; fuera del
proveedor, 404.
V8: agendas, agenda_services y schedules como bloques de una agenda.
seed.sql crea una agenda por recurso activo. Se actualizan la consulta
clave 6, la prueba de integridad 13 y se suman tres más (24 en total).
El workflow comprueba la idempotencia de V1 y V2 antes de las demás
migraciones, como ocurre en una base anterior a Flyway.
Fachadas nuevas: OrganizationAccess.locationZone y
CatalogLookup.resourceAt / serviceOfferedAt.
Pruebas: 823 unitarias y 121 de integración.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/v1/catalog/services, sin token: - Solo muestra servicios ACTIVE de proveedores ACTIVE en sedes ACTIVE. Los proveedores pendientes o suspendidos y los servicios inactivos no aparecen. Cada tarjeta es una pareja servicio-sede. - La palabra clave busca en el nombre o la descripción del servicio y en el nombre del proveedor, sin distinguir mayúsculas ni tildes. Los comodines de LIKE escritos por el cliente se buscan literalmente. - Filtros combinables con AND: categoría, ciudad, proveedor y rango de precio. Orden por nombre, precio, duración o proveedor (lista blanca), con paginación y total. - Sin resultados, la respuesta trae un mensaje que sugiere ampliar los filtros. V9: función f_sin_tildes (translate) en lugar de la extensión unaccent, que cambia de esquema entre Supabase y PostgreSQL. La "próxima franja disponible" de cada tarjeta queda para HU-008. ProviderFixture permite elegir la categoría, la ciudad y el estado del proveedor y de sus servicios. Pruebas: 836 unitarias y 131 de integración. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bajo /api/v1/admin (solo ADMIN), separado por clientes (identity) y proveedores (organization): - Listados paginados con total y filtros combinables: estado, ciudad (por nombre, sin tildes), rango de fechas de registro (días en Colombia) y, para proveedores, categoría. Orden por columna (lista blanca) ascendente o descendente. Sin filtros se listan todos, que es "Restablecer filtros". - Exportación a CSV del listado filtrado, de todas las páginas. Csv en shared: RFC 4180, BOM para Excel y protección contra inyección de fórmulas. - Suspender un proveedor con reservas futuras devuelve 409 CONFIRMATION_REQUIRED con el número de reservas afectadas; con "confirm": true lo suspende y guarda ese número con el motivo. Las reservas se conservan. También reactivar y rechazar, con motivo. - Suspender y reactivar clientes con motivo, que queda en account_status_changes. Repetir una suspensión da 409. Otros: un parámetro con tipo inválido (status=FOO, page=x) devuelve 400 nombrando el parámetro en lugar de 500, también en el catálogo. ListingParams y ResultPage en shared, compartidos con HU-005. Pruebas: 873 unitarias y 143 de integración. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- S8696: DayOfWeek se compara con equals() en TimeBlock y Agenda. - S2077: los adaptadores de listado y búsqueda (clientes, proveedores y catálogo) arman el SQL con texto, pero todos los valores son parámetros enlazados y lo único interpolado es la columna de orden, tomada de un mapa fijo. Se suprime la regla en esos métodos con la justificación. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Qué trae
Las seis HU del Sprint 2, cada una en su propio commit, sobre los habilitadores que ya están en
main(Flyway, V3, D7, D9 y reglas ArchUnit genéricas).48c8fe3PROVIDER, sede, política v1 yOWNER. Aprobación porADMINcon motivo. Cambio de política por versiones. Autorización base (ADR-0008): fuera del proveedor, 404; con un rol insuficiente, 403.db84dbfGET /api/v1/notifications/emails), porque Render gratis bloquea SMTP (ADR-0007).6ce1020a21ac44INACTIVE. Para activarlos, cada sede necesita recursos suficientes (HU-009). Desactivar o eliminar depende de si tienen reservas.ee142108c551bd0dfe634Módulos nuevos:
organization,catalog,schedulingynotification, con la misma estructura de capas y cubiertos por las reglas ArchUnit genéricas.Migraciones (se aplican a Supabase al desplegar)
nitpasa aidentification_numbersent_emails, la bandeja de correoRETIRED, organización en la fila (las FK compuestas impiden mezclar proveedores) yresource_maintenancesagendas,agenda_servicesyschedulescomo bloques de una agendaf_sin_tildes()para la búsquedaTodas las tablas nuevas tienen RLS. El workflow de base de datos cuenta 23 tablas y 24 rechazos de integridad. La idempotencia de V1 y V2 ahora se comprueba antes de las demás migraciones, que es el orden real en una base anterior a Flyway.
Pruebas
mvn clean verifyen local con JDK 21: 873 unitarias y 143 de integración, con el umbral de JaCoCo cumplido. Cada HU tiene una prueba de integración de punta a punta (ProviderOnboardingIT,ResourceManagementIT,ServiceManagementIT,AgendaManagementIT,CatalogSearchIT,AdminUsersIT) que también cubre los 403 y 404 de HU-022.Queda para otras HU
Resource.isAvailableDuringya está lista para usarse.MANAGERySTAFF, y aplicar al instante un cambio de rol (HU-022 y D8).Antes o después de fusionar
flyway_schema_historyque las migraciones llegaron a la versión 9.🤖 Generated with Claude Code