@fayz-ai/plugin-orders 0.23.0-canary.20261027164140 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DeliverySettings-2KMZ25CI.js → DeliverySettings-5ACP5XAG.js} +33 -198
- package/dist/DeliverySettings-5ACP5XAG.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -254
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +1 -2
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/main.browser.js +2 -3
- package/dist/migrations/main.browser.js.map +1 -1
- package/dist/migrations/main.js +77 -115
- package/dist/migrations/main.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/settings/DeliverySettings.d.ts.map +1 -1
- package/dist/settings/useDeliverySettings.d.ts +0 -3
- package/dist/settings/useDeliverySettings.d.ts.map +1 -1
- package/package.json +8 -8
- package/dist/DeliverySettings-2KMZ25CI.js.map +0 -1
- package/dist/chunk-O4W3DNIC.js +0 -174
- package/dist/chunk-O4W3DNIC.js.map +0 -1
- package/dist/lib/delivery-zones.d.ts +0 -67
- package/dist/lib/delivery-zones.d.ts.map +0 -1
- package/dist/lib/onboarding.d.ts +0 -77
- package/dist/lib/onboarding.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { summarizeZonesShort, renderZonesTable, labelZones, zonesToSetting, classifySettingWriteError, describeZones, zonesFromSetting, normalizeZones, parseDeliveryZonesText } from './chunk-O4W3DNIC.js';
|
|
2
1
|
export { ORDER_DETAIL_COMPONENT_ID } from './chunk-YVC7R552.js';
|
|
3
2
|
import React2 from 'react';
|
|
4
|
-
import { createConnectionStore, connectionRuns, connectionSettings, connectionStatus, settingsStatus, tl, lazyComponent, useTranslation, getSupabaseClientOptional, getActiveTenantId, getActiveUnitId
|
|
3
|
+
import { createConnectionStore, connectionRuns, connectionSettings, connectionStatus, settingsStatus, tl, lazyComponent, useTranslation, getSupabaseClientOptional, getActiveTenantId, getActiveUnitId } from '@fayz-ai/core';
|
|
5
4
|
import { createSupabaseOrdersProvider } from '@fayz-ai/orders/data/supabase';
|
|
6
5
|
export { createSupabaseOrdersProvider as createCoreOrdersProvider } from '@fayz-ai/orders/data/supabase';
|
|
7
6
|
import { createOrdersStore } from '@fayz-ai/orders/store';
|
|
8
7
|
import { MIGRATIONS } from '#migrations/main';
|
|
9
8
|
import { RefreshCw, Play, Pause, Loader2, Trash2, Plus, Save, Image, Pencil, Link2, Unlink, X } from 'lucide-react';
|
|
10
9
|
import { Button, Input } from '@fayz-ai/ui';
|
|
11
|
-
import { fayzConnectorOAuth, defineSettingsTab, PluginSettingsPanel, serviceBaseUrl
|
|
10
|
+
import { fayzConnectorOAuth, defineSettingsTab, PluginSettingsPanel, serviceBaseUrl } from '@fayz-ai/admin';
|
|
12
11
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
13
12
|
export { ADVANCE_VERB, DEFAULT_STATUS_CONFIGS, KANBAN_COLUMNS, STATUS_FLOW, getNextStatus, getPreviousStatus, mapToKanbanColumn } from '@fayz-ai/orders/domain/order';
|
|
14
13
|
export { createFayzOrdersProvider } from '@fayz-ai/orders/data/platform';
|
|
@@ -280,25 +279,7 @@ var en = {
|
|
|
280
279
|
"orders.ifoodStore.error.categoryRequired": "Choose the product's category.",
|
|
281
280
|
"orders.ifoodStore.error.badImage": "iFood takes PNG or JPEG photos. Send the photo in one of those formats.",
|
|
282
281
|
"orders.ifoodStore.error.imageTooBig": "The photo is larger than 3.9 MB, iFood's limit. Send a smaller photo.",
|
|
283
|
-
"orders.ifoodStore.error.generic": "The action could not be completed."
|
|
284
|
-
// Delivery bands by distance (Settings › Delivery)
|
|
285
|
-
"orders.zones.title": "Bands by distance",
|
|
286
|
-
"orders.zones.description": "Fee and time per kilometre from the house. Empty = the single fee above applies to everyone.",
|
|
287
|
-
"orders.zones.empty": "No bands. The delivery fee above applies at any distance.",
|
|
288
|
-
"orders.zones.upTo": "up to",
|
|
289
|
-
"orders.zones.km": "km",
|
|
290
|
-
"orders.zones.fee": "Fee",
|
|
291
|
-
"orders.zones.eta": "min",
|
|
292
|
-
"orders.zones.add": "Add band",
|
|
293
|
-
"orders.zones.remove": "Remove band up to {{km}} km",
|
|
294
|
-
"orders.zones.invalid": "Use numbers, like 3 and 5.90.",
|
|
295
|
-
"orders.zones.radius": "Delivery radius: {{km}} km (the largest band).",
|
|
296
|
-
// Delivery by conversation: the confirmation card and the screen's warning
|
|
297
|
-
"orders.delivery.saveFailed": "Could not save delivery",
|
|
298
|
-
"chat.tool.proposeDeliveryZones": "Propose delivery bands",
|
|
299
|
-
"chat.tool.saveDeliveryZones": "Save delivery bands",
|
|
300
|
-
"chat.field.saveDeliveryZones.zones": "Bands",
|
|
301
|
-
"chat.field.saveDeliveryZones.summary": "Summary"
|
|
282
|
+
"orders.ifoodStore.error.generic": "The action could not be completed."
|
|
302
283
|
};
|
|
303
284
|
|
|
304
285
|
// src/locales/pt-BR.ts
|
|
@@ -537,25 +518,7 @@ var ptBR = {
|
|
|
537
518
|
"orders.ifoodStore.error.categoryRequired": "Escolha a categoria do produto.",
|
|
538
519
|
"orders.ifoodStore.error.badImage": "O iFood aceita fotos PNG ou JPEG. Envie a foto em um desses formatos.",
|
|
539
520
|
"orders.ifoodStore.error.imageTooBig": "A foto passa de 3,9 MB, o limite do iFood. Envie uma foto menor.",
|
|
540
|
-
"orders.ifoodStore.error.generic": "N\xE3o foi poss\xEDvel concluir a a\xE7\xE3o."
|
|
541
|
-
// Faixas de entrega por distância (Configurações › Delivery)
|
|
542
|
-
"orders.zones.title": "Faixas por dist\xE2ncia",
|
|
543
|
-
"orders.zones.description": "Taxa e tempo por quil\xF4metro a partir da casa. Vazio = a taxa \xFAnica acima vale para todo mundo.",
|
|
544
|
-
"orders.zones.empty": "Nenhuma faixa. A taxa de entrega acima vale para qualquer dist\xE2ncia.",
|
|
545
|
-
"orders.zones.upTo": "at\xE9",
|
|
546
|
-
"orders.zones.km": "km",
|
|
547
|
-
"orders.zones.fee": "Taxa",
|
|
548
|
-
"orders.zones.eta": "min",
|
|
549
|
-
"orders.zones.add": "Adicionar faixa",
|
|
550
|
-
"orders.zones.remove": "Remover faixa at\xE9 {{km}} km",
|
|
551
|
-
"orders.zones.invalid": "Use n\xFAmeros, como 3 e 5,90.",
|
|
552
|
-
"orders.zones.radius": "Raio de entrega: {{km}} km (a maior faixa).",
|
|
553
|
-
// Entrega por conversa: o card de confirmação e o aviso da tela
|
|
554
|
-
"orders.delivery.saveFailed": "N\xE3o foi poss\xEDvel salvar a entrega",
|
|
555
|
-
"chat.tool.proposeDeliveryZones": "Montar faixas de entrega",
|
|
556
|
-
"chat.tool.saveDeliveryZones": "Gravar faixas de entrega",
|
|
557
|
-
"chat.field.saveDeliveryZones.zones": "Faixas",
|
|
558
|
-
"chat.field.saveDeliveryZones.summary": "Resumo"
|
|
521
|
+
"orders.ifoodStore.error.generic": "N\xE3o foi poss\xEDvel concluir a a\xE7\xE3o."
|
|
559
522
|
};
|
|
560
523
|
|
|
561
524
|
// src/locales/index.ts
|
|
@@ -2553,142 +2516,7 @@ var ordersV1SettingsTabs = [
|
|
|
2553
2516
|
]
|
|
2554
2517
|
})
|
|
2555
2518
|
];
|
|
2556
|
-
var
|
|
2557
|
-
var OWN_DELIVERY_MODE = "own-delivery";
|
|
2558
|
-
var DELIVERY_ZONES_SAVED_EVENT = "orders.delivery_zones_saved";
|
|
2559
|
-
var PROPOSE_DELIVERY_ZONES_TOOL = "proposeDeliveryZones";
|
|
2560
|
-
var SAVE_DELIVERY_ZONES_TOOL = "saveDeliveryZones";
|
|
2561
|
-
var DELIVERY_ROUTING_RULE = 'Qualquer frase sobre entrega/delivery/taxa de entrega/frete/raio com km, R$ ou minutos ("at\xE9 3 km R$ 5 em 30 min, 5 km por R$ 8 em 40 min", "configurar entrega", "cobro 6 reais at\xE9 4 km") \xE9 proposeDeliveryZones. NUNCA \xE9 conta a pagar, despesa, fornecedor ou financeiro: "entrega" aqui n\xE3o \xE9 um fornecedor e esses R$ s\xE3o a taxa cobrada do cliente.';
|
|
2562
|
-
var NOT_UNDERSTOOD_HINT = "N\xE3o consegui montar as faixas com isso. Pe\xE7a assim: at\xE9 3 km R$ 5 em 30 min; at\xE9 5 km R$ 8 em 40 min.";
|
|
2563
|
-
var MISSING_ETA_HINT = "Entendi as dist\xE2ncias, mas n\xE3o o tempo de todas as faixas. Pergunte s\xF3 o que faltou e mantenha o resto.";
|
|
2564
|
-
function client() {
|
|
2565
|
-
return getSupabaseClientOptional();
|
|
2566
|
-
}
|
|
2567
|
-
async function deliveryConfigured() {
|
|
2568
|
-
const db2 = client();
|
|
2569
|
-
if (!db2) return false;
|
|
2570
|
-
const { data, error } = await db2.rpc("tenant_settings");
|
|
2571
|
-
if (error || !data || typeof data !== "object") return false;
|
|
2572
|
-
const flat = data;
|
|
2573
|
-
if (zonesFromSetting(flat["delivery.zones"]).length > 0) return true;
|
|
2574
|
-
const fee = Number(flat["delivery.fee"]);
|
|
2575
|
-
return Number.isFinite(fee) && fee > 0;
|
|
2576
|
-
}
|
|
2577
|
-
function zonesFromArgs(args) {
|
|
2578
|
-
const structured = Array.isArray(args.zones) ? normalizeZones(args.zones) : [];
|
|
2579
|
-
return structured.length > 0 ? structured : parseDeliveryZonesText(String(args.text ?? ""));
|
|
2580
|
-
}
|
|
2581
|
-
function proposeDeliveryZones(args) {
|
|
2582
|
-
const zones = zonesFromArgs(args);
|
|
2583
|
-
if (zones.length === 0) return { ok: false, reason: "not_understood", hint: NOT_UNDERSTOOD_HINT };
|
|
2584
|
-
const missingEta = zones.some((z) => !z.etaMinutes);
|
|
2585
|
-
const summary = summarizeZonesShort(zones);
|
|
2586
|
-
return {
|
|
2587
|
-
ok: true,
|
|
2588
|
-
saved: false,
|
|
2589
|
-
proposal: labelZones(zones),
|
|
2590
|
-
card: renderZonesTable(zones),
|
|
2591
|
-
summary,
|
|
2592
|
-
missingEta,
|
|
2593
|
-
...missingEta ? { hint: MISSING_ETA_HINT } : {},
|
|
2594
|
-
next: missingEta ? `Nada foi gravado. Comece o texto da sua resposta pela tabela de card, copiada tal qual (\xE9 markdown), e pergunte s\xF3 o que faltou (tempo ou valor), mantendo o resto; depois proponha de novo.` : `Nada foi gravado. Sua resposta em texto DEVE come\xE7ar pela tabela de card, copiada tal qual (\xE9 markdown; n\xE3o a resuma nem a descreva) \u2014 a pessoa precisa ler as faixas antes do card de confirma\xE7\xE3o. Em seguida, NESTA MESMA resposta, chame ${SAVE_DELIVERY_ZONES_TOOL} com estas mesmas faixas em zones (com label e etaMinutes) e este summary. O card nativo dessa ferramenta \xE9 onde a pessoa confirma ou cancela \u2014 n\xE3o pergunte "posso gravar?" em texto, a pergunta \xE9 o card. Se ela cancelar, pergunte o que ajustar.`
|
|
2595
|
-
};
|
|
2596
|
-
}
|
|
2597
|
-
async function saveDeliveryZones(args) {
|
|
2598
|
-
const zones = zonesFromArgs(args);
|
|
2599
|
-
if (zones.length === 0) {
|
|
2600
|
-
return { ok: false, reason: "not_understood", message: "Nenhuma faixa para gravar.", hint: NOT_UNDERSTOOD_HINT };
|
|
2601
|
-
}
|
|
2602
|
-
const db2 = client();
|
|
2603
|
-
if (!db2) return { ok: false, reason: "unsupported", message: "Este app n\xE3o guarda a configura\xE7\xE3o de entrega." };
|
|
2604
|
-
const writes = [
|
|
2605
|
-
["delivery.zones", zonesToSetting(zones)],
|
|
2606
|
-
["delivery.enabled", true],
|
|
2607
|
-
["delivery.radius_km", zones[zones.length - 1].maxKm]
|
|
2608
|
-
];
|
|
2609
|
-
const firstEta = zones[0].etaMinutes;
|
|
2610
|
-
if (firstEta) writes.push(["delivery.eta_minutes", firstEta]);
|
|
2611
|
-
try {
|
|
2612
|
-
for (const [key, value] of writes) {
|
|
2613
|
-
const { error } = await db2.rpc("tenant_setting_set", { p_key: key, p_value: value });
|
|
2614
|
-
if (error) throw error;
|
|
2615
|
-
}
|
|
2616
|
-
} catch (e) {
|
|
2617
|
-
const failure = classifySettingWriteError(e);
|
|
2618
|
-
return {
|
|
2619
|
-
ok: false,
|
|
2620
|
-
...failure,
|
|
2621
|
-
hint: failure.reason === "migration_missing" ? "Diga \xE0 pessoa, com estas palavras, que a migration 007 ainda n\xE3o foi aplicada no banco e que as faixas podem ser gravadas assim que ela estiver no ar. N\xE3o tente de novo agora." : void 0
|
|
2622
|
-
};
|
|
2623
|
-
}
|
|
2624
|
-
emitDomainEvent(DELIVERY_ZONES_SAVED_EVENT, { zones: zones.length }, { tenantId: getActiveTenantId() ?? null });
|
|
2625
|
-
return { ok: true, saved: true, zones, card: renderZonesTable(zones), summary: describeZones(zones) };
|
|
2626
|
-
}
|
|
2627
|
-
function registerDeliveryZonesHandler() {
|
|
2628
|
-
registerAIToolHandler(PROPOSE_DELIVERY_ZONES_TOOL, (args) => proposeDeliveryZones(args));
|
|
2629
|
-
registerAIToolHandler(SAVE_DELIVERY_ZONES_TOOL, (args) => saveDeliveryZones(args));
|
|
2630
|
-
}
|
|
2631
|
-
function buildOrdersOnboarding() {
|
|
2632
|
-
return {
|
|
2633
|
-
id: "orders",
|
|
2634
|
-
title: tl("Your orders", "Seus pedidos"),
|
|
2635
|
-
order: 20,
|
|
2636
|
-
instructions: tl(
|
|
2637
|
-
`You are setting up delivery. ROUTING: any sentence about delivery/delivery fee/radius with km, R$ or minutes ("at\xE9 3 km R$ 5 em 30 min, 5 km por R$ 8 em 40 min", "configurar entrega") goes to ${PROPOSE_DELIVERY_ZONES_TOOL} \u2014 never to payables, expenses, suppliers or anything financial; "entrega" is not a supplier and those R$ are what the customer pays.
|
|
2638
|
-
- Call ${PROPOSE_DELIVERY_ZONES_TOOL} with the text EXACTLY as typed (never rewrite it: "em 40 min" is a time). It never writes and asks nothing: it returns the table and the labelled bands.
|
|
2639
|
-
- Start your reply's text with the table (the card field, verbatim markdown) and, in the SAME reply, call ${SAVE_DELIVERY_ZONES_TOOL} with those bands (zones with label and etaMinutes) and the summary. Its native confirmation card is the ONE place the person approves or cancels \u2014 never ask "can I save?" in text, and never confirm twice.
|
|
2640
|
-
- If a band is missing its time or fee, ask only for what is missing and keep the rest; propose again before saving.
|
|
2641
|
-
- If saving fails because the key does not exist yet (migration 007), say exactly that and do not retry. If the person cancels the card, ask what to change.
|
|
2642
|
-
- A house that charges by neighbourhood: ask for the neighbourhoods and the fee of each, then translate with the person ("how far is the farthest one?") into distance bands; a single fee is one band.
|
|
2643
|
-
- Every step has a guide (readSetupGuide). Read it before leading.`,
|
|
2644
|
-
`Voc\xEA est\xE1 configurando a entrega. ROTEAMENTO: ${DELIVERY_ROUTING_RULE}
|
|
2645
|
-
- Chame ${PROPOSE_DELIVERY_ZONES_TOOL} com o texto EXATAMENTE como veio (nunca reescreva: "em 40 min" \xE9 tempo). Ela nunca grava e n\xE3o pergunta nada: devolve a tabela e as faixas com r\xF3tulo.
|
|
2646
|
-
- Comece o texto da resposta pela tabela (o campo card, markdown copiado tal qual) e, NA MESMA resposta, chame ${SAVE_DELIVERY_ZONES_TOOL} com essas faixas (zones com label e etaMinutes) e o summary. O card nativo de confirma\xE7\xE3o dela \xE9 o \xDANICO lugar em que a pessoa aprova ou cancela \u2014 nunca pergunte "posso gravar?" em texto, nunca confirme duas vezes.
|
|
2647
|
-
- Se faltou o tempo ou o valor de uma faixa, pergunte s\xF3 o que faltou, mantenha o resto e proponha de novo antes de gravar.
|
|
2648
|
-
- Se a grava\xE7\xE3o falhar porque a chave ainda n\xE3o existe (migration 007), diga exatamente isso e n\xE3o tente de novo. Se a pessoa cancelar o card, pergunte o que mudar.
|
|
2649
|
-
- Casa que cobra por bairro: pe\xE7a os bairros e o valor de cada um e traduza com a pessoa ("o mais longe fica a quantos km?") em faixas por dist\xE2ncia; taxa \xFAnica \xE9 uma faixa s\xF3.
|
|
2650
|
-
- Cada passo tem um guia (readSetupGuide). Leia antes de conduzir.`
|
|
2651
|
-
),
|
|
2652
|
-
steps: [
|
|
2653
|
-
{
|
|
2654
|
-
key: "delivery-zones",
|
|
2655
|
-
title: tl("Delivery areas", "\xC1reas de entrega"),
|
|
2656
|
-
description: tl(
|
|
2657
|
-
"How far you deliver and what each band costs \u2014 said in a sentence.",
|
|
2658
|
-
"At\xE9 onde voc\xEA entrega e quanto custa cada faixa \u2014 dito numa frase."
|
|
2659
|
-
),
|
|
2660
|
-
icon: "Bike",
|
|
2661
|
-
route: "/settings/orders-delivery",
|
|
2662
|
-
priority: "high",
|
|
2663
|
-
journey: { group: "launch" },
|
|
2664
|
-
// How the house serves is answered by conversation now (the
|
|
2665
|
-
// getting-started profile step writes the same key the wizard did);
|
|
2666
|
-
// "own delivery" absent from the answer rules the step out, and no
|
|
2667
|
-
// answer yet (older tenant, profile still loading) keeps it.
|
|
2668
|
-
appliesWhen: (answers) => {
|
|
2669
|
-
const modes = answers[SERVICE_MODES_ANSWER];
|
|
2670
|
-
if (!Array.isArray(modes)) return true;
|
|
2671
|
-
return modes.includes(OWN_DELIVERY_MODE);
|
|
2672
|
-
},
|
|
2673
|
-
agentHint: tl(
|
|
2674
|
-
"Ask how the house charges for delivery and wait for the sentence. Any km/R$/min sentence about delivery is proposeDeliveryZones (never a payable): show its table, then call saveDeliveryZones in the same reply \u2014 its native card is the one confirmation.",
|
|
2675
|
-
"Pergunte como a casa cobra a entrega e espere a frase. Toda frase com km/R$/min sobre entrega \xE9 proposeDeliveryZones (nunca conta a pagar): mostre a tabela e chame saveDeliveryZones na mesma resposta \u2014 o card nativo dela \xE9 a \xFAnica confirma\xE7\xE3o."
|
|
2676
|
-
),
|
|
2677
|
-
howTo: tl(
|
|
2678
|
-
'Configura\xE7\xF5es \u203A Delivery. Tell the assistant how you charge ("up to 3 km R$ 5 in 30 min, up to 5 km R$ 8 in 40 min") and confirm the table it shows; or type the bands by hand on the Delivery screen. One fee for everyone is one band.',
|
|
2679
|
-
'Configura\xE7\xF5es \u203A Delivery. Diga \xE0 assistente como voc\xEA cobra ("at\xE9 3 km R$ 5 em 30 min, at\xE9 5 km R$ 8 em 40 min") e confirme a tabela que ela mostrar; ou digite as faixas \xE0 m\xE3o na tela de Delivery. Taxa \xFAnica para todo mundo \xE9 uma faixa s\xF3.'
|
|
2680
|
-
),
|
|
2681
|
-
celebrate: tl("Delivery saved.", "Entrega salva."),
|
|
2682
|
-
script: [
|
|
2683
|
-
{ kind: "say", text: tl("How do you charge for delivery? Send it your way.", "Como voc\xEA cobra a entrega? Pode me mandar do seu jeito.") },
|
|
2684
|
-
{ kind: "await" }
|
|
2685
|
-
],
|
|
2686
|
-
check: deliveryConfigured
|
|
2687
|
-
}
|
|
2688
|
-
]
|
|
2689
|
-
};
|
|
2690
|
-
}
|
|
2691
|
-
var DeliverySettings = lazyComponent(() => import('./DeliverySettings-2KMZ25CI.js').then((m) => m.DeliverySettings));
|
|
2519
|
+
var DeliverySettings = lazyComponent(() => import('./DeliverySettings-5ACP5XAG.js').then((m) => m.DeliverySettings));
|
|
2692
2520
|
var OrdersPage = React2.lazy(() => import('./OrdersPage-PMYISO2D.js').then((m) => ({ default: m.OrdersPage })));
|
|
2693
2521
|
var OrderDetailRoute = React2.lazy(() => import('./OrderDetailRoute-HBLR4UUO.js').then((m) => ({ default: m.OrderDetailRoute })));
|
|
2694
2522
|
var DEFAULT_LABELS = {
|
|
@@ -2729,7 +2557,6 @@ function createOrdersPlugin(options) {
|
|
|
2729
2557
|
onOrderCompleted: config.onOrderCompleted,
|
|
2730
2558
|
onOrderCancelled: config.onOrderCancelled
|
|
2731
2559
|
});
|
|
2732
|
-
registerDeliveryZonesHandler();
|
|
2733
2560
|
const PageComponent = () => React2.createElement(
|
|
2734
2561
|
React2.Suspense,
|
|
2735
2562
|
{ fallback: null },
|
|
@@ -2884,84 +2711,8 @@ function createOrdersPlugin(options) {
|
|
|
2884
2711
|
required: ["kind", "items"]
|
|
2885
2712
|
},
|
|
2886
2713
|
permission: { feature: "orders", action: "create" }
|
|
2887
|
-
},
|
|
2888
|
-
{
|
|
2889
|
-
id: "orders.propose-delivery-zones",
|
|
2890
|
-
name: PROPOSE_DELIVERY_ZONES_TOOL,
|
|
2891
|
-
description: `ENTREGA POR DIST\xC2NCIA (taxa de entrega, delivery, frete, raio, km) \u2014 ${DELIVERY_ROUTING_RULE} FASE 1 de 2: monta as faixas a partir do que a casa escreveu e devolve a tabela e as faixas com r\xF3tulo. NUNCA grava e n\xE3o pergunta nada. Passe o texto EXATAMENTE como a pessoa escreveu em text (n\xE3o reescreva nem resuma: "em 40 min" \xE9 o tempo da faixa); use zones s\xF3 se as faixas j\xE1 vieram estruturadas. Em seguida, na mesma resposta, chame saveDeliveryZones com as faixas devolvidas \u2014 o card nativo dela \xE9 a \xFAnica confirma\xE7\xE3o.`,
|
|
2892
|
-
icon: "Bike",
|
|
2893
|
-
mode: "read",
|
|
2894
|
-
category: "Orders",
|
|
2895
|
-
execution: { plane: "client" },
|
|
2896
|
-
permission: { feature: "settings", action: "read" },
|
|
2897
|
-
parameters: {
|
|
2898
|
-
type: "object",
|
|
2899
|
-
properties: {
|
|
2900
|
-
text: { type: "string", description: 'A frase da casa, sem alterar, ex.: "at\xE9 3 km R$ 5 em 30 min, 5 km por R$ 8 em 40 min".' },
|
|
2901
|
-
zones: {
|
|
2902
|
-
type: "array",
|
|
2903
|
-
description: "Faixas j\xE1 estruturadas, em vez do texto (maxKm, fee e etaMinutes em minutos).",
|
|
2904
|
-
items: {
|
|
2905
|
-
type: "object",
|
|
2906
|
-
properties: {
|
|
2907
|
-
maxKm: { type: "number" },
|
|
2908
|
-
fee: { type: "number" },
|
|
2909
|
-
etaMinutes: { type: "number" },
|
|
2910
|
-
label: { type: "string", description: 'A faixa como a pessoa l\xEA no card ("at\xE9 3 km \xB7 R$ 5,00 \xB7 30 min"), copiada de proposeDeliveryZones.' }
|
|
2911
|
-
},
|
|
2912
|
-
required: ["maxKm", "fee"]
|
|
2913
|
-
}
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
},
|
|
2917
|
-
suggestions: [
|
|
2918
|
-
{
|
|
2919
|
-
label: "Configurar entrega por dist\xE2ncia",
|
|
2920
|
-
prompt: "Quero configurar a entrega por dist\xE2ncia (faixas de km, taxa e tempo). Me pergunte como eu cobro."
|
|
2921
|
-
},
|
|
2922
|
-
{
|
|
2923
|
-
label: "Mudar a taxa de entrega",
|
|
2924
|
-
prompt: "Quero mudar a taxa de entrega por dist\xE2ncia. Pergunte como eu cobro hoje e monte as faixas."
|
|
2925
|
-
}
|
|
2926
|
-
]
|
|
2927
|
-
},
|
|
2928
|
-
{
|
|
2929
|
-
id: "orders.save-delivery-zones",
|
|
2930
|
-
name: SAVE_DELIVERY_ZONES_TOOL,
|
|
2931
|
-
description: 'FASE 2 de 2 da entrega por dist\xE2ncia (taxa de entrega \u2014 nunca financeiro). Grava as faixas em delivery.zones e liga a entrega. Abre o card nativo em que a PESSOA confirma ou cancela antes de qualquer grava\xE7\xE3o \u2014 \xE9 a \xDANICA confirma\xE7\xE3o do fluxo. Chame logo depois de proposeDeliveryZones, na mesma resposta, com as mesmas faixas (zones, com label e etaMinutes) e o summary; n\xE3o pergunte "posso gravar?" em texto. Nunca chame por conta pr\xF3pria com faixas que a pessoa n\xE3o disse.',
|
|
2932
|
-
icon: "Bike",
|
|
2933
|
-
mode: "persist",
|
|
2934
|
-
category: "Orders",
|
|
2935
|
-
execution: { plane: "client" },
|
|
2936
|
-
// The person's gate, and the only one: the runtime draws the
|
|
2937
|
-
// ConfirmActionCard with the labelled bands and nothing runs until they
|
|
2938
|
-
// tap. A model that skips phase 1 still cannot skip this.
|
|
2939
|
-
requiresConfirmation: true,
|
|
2940
|
-
permission: { feature: "settings", action: "manage" },
|
|
2941
|
-
parameters: {
|
|
2942
|
-
type: "object",
|
|
2943
|
-
properties: {
|
|
2944
|
-
zones: {
|
|
2945
|
-
type: "array",
|
|
2946
|
-
description: "As faixas confirmadas pela pessoa, em ordem crescente de maxKm.",
|
|
2947
|
-
items: {
|
|
2948
|
-
type: "object",
|
|
2949
|
-
properties: {
|
|
2950
|
-
maxKm: { type: "number" },
|
|
2951
|
-
fee: { type: "number" },
|
|
2952
|
-
etaMinutes: { type: "number" },
|
|
2953
|
-
label: { type: "string", description: 'A faixa como a pessoa l\xEA no card ("at\xE9 3 km \xB7 R$ 5,00 \xB7 30 min"), copiada de proposeDeliveryZones.' }
|
|
2954
|
-
},
|
|
2955
|
-
required: ["maxKm", "fee"]
|
|
2956
|
-
}
|
|
2957
|
-
},
|
|
2958
|
-
summary: { type: "string", description: "O resumo que proposeDeliveryZones devolveu, para a pessoa ler no card." }
|
|
2959
|
-
},
|
|
2960
|
-
required: ["zones"]
|
|
2961
|
-
}
|
|
2962
2714
|
}
|
|
2963
2715
|
],
|
|
2964
|
-
onboarding: { program: buildOrdersOnboarding() },
|
|
2965
2716
|
registries: ordersRegistries,
|
|
2966
2717
|
facets: [
|
|
2967
2718
|
{ id: "scale", label: "Balan\xE7a", description: "Venda por peso com balan\xE7a e etiqueta." },
|