Backend cleanup (todo el delivery vive ahora en delivery_zones.zones[]):
- Migration drop columns delivery_enabled / delivery_days / delivery_hours_start /
delivery_hours_end / delivery_min_order y limpieza de schedule.delivery JSONB.
- settingsRepo: SELECT/INSERT/UPDATE sólo con campos vigentes, formatScheduleHours
trabaja sobre pickup.
- handlers/settings: defaults sin legacy, validateSchedule sólo para pickup,
validateDeliveryZones nuevo (estructura GeoJSON + días).
- seed_piaf_settings_and_replies + tenant_settings migrations alineadas: schedule
sólo tiene pickup, delivery_zones queda en {} para reconfigurar via UI.
Frontend cleanup:
- settings-crud: borrado el panel "Delivery (Envío a domicilio)" + minOrder,
toggle deliveryEnabled, y el grid schedule.delivery. collectScheduleFromInputs
ahora sólo procesa pickup. save() ya no envía delivery_enabled/min_order.
Fix mapa (no cargaba):
- zone-map-editor: los <link> a leaflet.css/leaflet-geoman.css se inyectaban en
document.head, que NO cruza el shadow DOM de settings-crud, por lo que las
reglas de Leaflet no aplicaban al div del mapa. Ahora los <link> se anclan
como hijos del propio web component; al estar en light DOM dentro del shadow
root del padre, sí aplican.
- Espera explícita a que el stylesheet cargue antes de instanciar L.map.
- ResizeObserver + invalidateSize() para cuando el contenedor cambia tamaño
(router muestra/oculta panel, tabs, etc).
Smoke E2E sin regresión: 1kg vacío + envío → location en Centro → "martes 12hs"
→ orden confirmada con $28.000 (producto + envío). 157/157 tests verde.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
89 lines
5.1 KiB
SQL
89 lines
5.1 KiB
SQL
-- migrate:up
|
|
-- Seed mono-tenant: settings de tienda (horarios + zonas de delivery) +
|
|
-- reply_templates con todas las variantes hoy hardcodeadas en DEFAULTS.
|
|
-- Esto desbloquea editar respuestas vía UI/SQL sin redeploy.
|
|
|
|
-- 1) tenant_settings: schedule + delivery_zones para piaf
|
|
UPDATE tenant_settings
|
|
SET
|
|
store_name = COALESCE(NULLIF(store_name, 'Mi Negocio'), 'Piaf'),
|
|
bot_name = COALESCE(NULLIF(bot_name, 'Bot'), 'Piaf'),
|
|
pickup_enabled = true,
|
|
schedule = '{
|
|
"pickup": {
|
|
"lun": {"enabled": true, "start": "09:00", "end": "20:00"},
|
|
"mar": {"enabled": true, "start": "09:00", "end": "20:00"},
|
|
"mie": {"enabled": true, "start": "09:00", "end": "20:00"},
|
|
"jue": {"enabled": true, "start": "09:00", "end": "20:00"},
|
|
"vie": {"enabled": true, "start": "09:00", "end": "20:00"},
|
|
"sab": {"enabled": true, "start": "09:00", "end": "13:00"}
|
|
}
|
|
}'::jsonb,
|
|
delivery_zones = '{}'::jsonb
|
|
WHERE tenant_id = 'eb71b9a7-9ccf-430e-9b25-951a0c589c0f'::uuid;
|
|
|
|
-- 2) reply_templates: seed con DEFAULTS de replyTemplates.js para piaf
|
|
INSERT INTO reply_templates (tenant_id, template_key, variant, content, weight)
|
|
SELECT
|
|
'eb71b9a7-9ccf-430e-9b25-951a0c589c0f'::uuid,
|
|
v.template_key,
|
|
v.variant,
|
|
v.content,
|
|
v.weight
|
|
FROM (VALUES
|
|
-- IDLE
|
|
('idle.greeting', 1, '¡Hola! ¿En qué te puedo ayudar?', 1),
|
|
('idle.greeting', 2, '¡Hola! Estoy para ayudarte con tu pedido. ¿Qué andás buscando?', 1),
|
|
('idle.greeting', 3, 'Buenas. ¿Querés que te muestre algo en particular o hacemos un pedido?', 1),
|
|
('idle.help_prompt', 1, 'Decime qué necesitás. Podés pedirme productos, precios, o armar el pedido directo.', 1),
|
|
('idle.help_prompt', 2, '¿Qué te tiro? Podés pedir algo, preguntar precios o consultar disponibilidad.', 1),
|
|
-- CART
|
|
('cart.ask_more', 1, '¿Algo más?', 1),
|
|
('cart.ask_more', 2, '¿Querés agregar algo más al pedido?', 1),
|
|
('cart.ask_more', 3, '¿Sumamos algo más o cerramos así?', 1),
|
|
('cart.empty_prompt', 1, 'Tu carrito está vacío. ¿Qué querés agregar?', 1),
|
|
('cart.empty_prompt', 2, 'Todavía no hay nada en el carrito. ¿Por dónde empezamos?', 1),
|
|
('cart.not_found', 1, 'No encontré "{{query}}". ¿Podés decirlo de otra forma?', 1),
|
|
('cart.not_found', 2, 'Mmm, no tengo "{{query}}" exacto. ¿Probamos con otra cosa?', 1),
|
|
('cart.not_found', 3, 'No me aparece "{{query}}". Si querés, dame otro nombre o detalle más.', 1),
|
|
('cart.didnt_understand', 1, 'Perdón, no te entendí.', 1),
|
|
('cart.didnt_understand', 2, 'No me quedó claro, ¿me lo decís de otra forma?', 1),
|
|
('cart.didnt_understand', 3, 'No te seguí, ¿podés repetir?', 1),
|
|
('cart.skip_acknowledged', 1, 'Ok, lo dejamos.', 1),
|
|
('cart.skip_acknowledged', 2, 'Listo, no lo agregamos.', 1),
|
|
('cart.confirm_to_shipping', 1, 'Buenísimo. ¿Es para delivery o lo pasás a buscar?', 1),
|
|
('cart.confirm_to_shipping', 2, 'Perfecto. ¿Te lo enviamos o lo retirás?', 1),
|
|
('cart.pending_before_close', 1, 'Antes de cerrar, ¿qué hacemos con lo que quedó pendiente?', 1),
|
|
('cart.pending_before_close', 2, 'Tenemos algo pendiente para resolver antes de cerrar el pedido.', 1),
|
|
('cart.added_confirm', 1, 'Anoté {{summary}}. ¿Algo más?', 1),
|
|
('cart.added_confirm', 2, 'Listo, {{summary}} agregado. ¿Sumamos algo más?', 1),
|
|
('cart.added_confirm', 3, 'Sumé {{summary}}. ¿Querés agregar algo más?', 1),
|
|
('cart.added_confirm', 4, 'Va {{summary}}. ¿Algo más?', 1),
|
|
('cart.ask_what_product', 1, '¿Qué producto querés?', 1),
|
|
('cart.ask_what_product', 2, 'Decime el producto y lo busco.', 1),
|
|
('cart.price_no_query', 1, '¿De qué producto querés saber el precio?', 1),
|
|
('cart.price_no_query', 2, 'Decime el producto y te paso el precio.', 1),
|
|
('cart.price_results_header', 1, 'Estos son los precios:', 1),
|
|
('cart.price_results_header', 2, 'Precios disponibles:', 1),
|
|
-- SHIPPING (incluye {{delivery_zones_summary}} y {{delivery_hours}} cuando hay datos)
|
|
('shipping.ask_method', 1, '¿Lo enviamos a domicilio o lo pasás a buscar?', 1),
|
|
('shipping.ask_method', 2, '¿Es para delivery o pickup?', 1),
|
|
('shipping.ask_address', 1, 'Pasame la dirección de entrega.', 1),
|
|
('shipping.ask_address', 2, 'Decime dónde lo entregamos (calle y altura). Hacemos delivery en {{delivery_zones_summary}}.', 1),
|
|
('shipping.address_recorded', 1, 'Anotado: {{address}}.', 1),
|
|
('shipping.address_recorded', 2, 'Listo, dirección guardada: {{address}}.', 1),
|
|
-- ORDER CLOSE
|
|
('order.confirmed', 1, '¡Listo! Anotamos tu pedido. Te coordinamos por acá la entrega.', 1),
|
|
('order.confirmed', 2, 'Perfecto, ya quedó registrado. Te confirmamos en breve los detalles de entrega.', 1),
|
|
('order.confirmed', 3, 'Genial, anotado. Cualquier ajuste avisame por acá.', 1)
|
|
) AS v(template_key, variant, content, weight)
|
|
ON CONFLICT (tenant_id, template_key, variant) DO NOTHING;
|
|
|
|
-- migrate:down
|
|
DELETE FROM reply_templates
|
|
WHERE tenant_id = 'eb71b9a7-9ccf-430e-9b25-951a0c589c0f'::uuid;
|
|
-- Settings: limpiar schedule/zones (no borrar la fila)
|
|
UPDATE tenant_settings
|
|
SET schedule = '{}'::jsonb, delivery_zones = '{}'::jsonb
|
|
WHERE tenant_id = 'eb71b9a7-9ccf-430e-9b25-951a0c589c0f'::uuid;
|