@fayz-ai/plugin-agenda 0.9.0 → 0.9.1
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/README.md +3 -3
- package/dist/bridges/create-financial-bridge.d.ts +1 -1
- package/dist/bridges/create-financial-bridge.d.ts.map +1 -1
- package/dist/bridges/financial-bridge.d.ts.map +1 -0
- package/dist/{chunk-Q2PAWBPR.js → chunk-76ZOHRBM.js} +2 -2
- package/dist/{chunk-Q2PAWBPR.js.map → chunk-76ZOHRBM.js.map} +1 -1
- package/dist/components/PaymentStatusBadge.d.ts +1 -1
- package/dist/components/PaymentStatusBadge.d.ts.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/{AgendaContext.d.ts → context.d.ts} +1 -1
- package/dist/context.d.ts.map +1 -0
- package/dist/data/registries.d.ts.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +170 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/message-events.d.ts +12 -0
- package/dist/lib/message-events.d.ts.map +1 -0
- package/dist/public/{data.d.ts → data/index.d.ts} +4 -4
- package/dist/public/data/index.d.ts.map +1 -0
- package/dist/public/{data.supabase.d.ts → data/supabase.d.ts} +2 -2
- package/dist/public/data/supabase.d.ts.map +1 -0
- package/dist/public/{hooks.d.ts → hooks/index.d.ts} +4 -4
- package/dist/public/hooks/index.d.ts.map +1 -0
- package/dist/public/index.d.ts +4 -4
- package/dist/public/index.d.ts.map +1 -1
- package/dist/public/index.js +3 -3
- package/dist/public/index.js.map +1 -1
- package/dist/public/{format.d.ts → lib/format.d.ts} +1 -1
- package/dist/public/lib/format.d.ts.map +1 -0
- package/dist/public/views/BookingWidget.d.ts.map +1 -0
- package/dist/public/{steps → views/steps}/ContactStep.d.ts +1 -1
- package/dist/public/views/steps/ContactStep.d.ts.map +1 -0
- package/dist/public/{steps → views/steps}/DateTimeStep.d.ts +3 -3
- package/dist/public/views/steps/DateTimeStep.d.ts.map +1 -0
- package/dist/public/{steps → views/steps}/OverviewStep.d.ts +1 -1
- package/dist/public/views/steps/OverviewStep.d.ts.map +1 -0
- package/dist/public/{steps → views/steps}/PaymentStep.d.ts +1 -1
- package/dist/public/views/steps/PaymentStep.d.ts.map +1 -0
- package/dist/store.d.ts +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/styles/calendar-styles.d.ts.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/{AgendaPage.d.ts → views/AgendaPage.d.ts} +3 -3
- package/dist/views/AgendaPage.d.ts.map +1 -0
- package/package.json +6 -9
- package/dist/AgendaContext.d.ts.map +0 -1
- package/dist/AgendaPage.d.ts.map +0 -1
- package/dist/calendar-styles.d.ts.map +0 -1
- package/dist/financial-bridge.d.ts.map +0 -1
- package/dist/public/BookingWidget.d.ts.map +0 -1
- package/dist/public/data.d.ts.map +0 -1
- package/dist/public/data.supabase.d.ts.map +0 -1
- package/dist/public/format.d.ts.map +0 -1
- package/dist/public/hooks.d.ts.map +0 -1
- package/dist/public/steps/ContactStep.d.ts.map +0 -1
- package/dist/public/steps/DateTimeStep.d.ts.map +0 -1
- package/dist/public/steps/OverviewStep.d.ts.map +0 -1
- package/dist/public/steps/PaymentStep.d.ts.map +0 -1
- package/dist/registries.d.ts.map +0 -1
- package/src/AgendaContext.tsx +0 -11
- package/src/AgendaPage.tsx +0 -33
- package/src/bridges/create-financial-bridge.ts +0 -296
- package/src/calendar-styles.css +0 -245
- package/src/calendar-styles.ts +0 -285
- package/src/components/AgendaGeneralSettings.tsx +0 -86
- package/src/components/AgendaMobileList.tsx +0 -103
- package/src/components/AppointmentModal.tsx +0 -1050
- package/src/components/AppointmentPopover.tsx +0 -231
- package/src/components/BookingPaymentPanel.tsx +0 -394
- package/src/components/CalendarSidebar.tsx +0 -119
- package/src/components/CalendarToolbar.tsx +0 -86
- package/src/components/EventContextMenu.tsx +0 -125
- package/src/components/FloatingPanel.tsx +0 -123
- package/src/components/MiniCalendar.tsx +0 -120
- package/src/components/PaymentStatusBadge.tsx +0 -62
- package/src/components/StatusBadge.tsx +0 -23
- package/src/config.ts +0 -368
- package/src/data/index.ts +0 -4
- package/src/data/mock.ts +0 -344
- package/src/data/supabase.ts +0 -636
- package/src/data/types.ts +0 -37
- package/src/financial-bridge.ts +0 -96
- package/src/hooks/useAgendaSettings.ts +0 -17
- package/src/index.ts +0 -297
- package/src/integrations/google-calendar/GoogleCalendarSettings.tsx +0 -136
- package/src/integrations/google-calendar/components/CalendarColorDot.tsx +0 -23
- package/src/integrations/google-calendar/components/ChannelMappingList.tsx +0 -329
- package/src/integrations/google-calendar/components/ImportEventsWizard.tsx +0 -215
- package/src/integrations/google-calendar/components/useAgendaLookups.ts +0 -100
- package/src/integrations/google-calendar/connector.ts +0 -20
- package/src/integrations/google-calendar/connectorDef.tsx +0 -185
- package/src/integrations/google-calendar/data/supabase.ts +0 -170
- package/src/integrations/google-calendar/data/tables.ts +0 -12
- package/src/integrations/google-calendar/index.ts +0 -45
- package/src/integrations/google-calendar/integration.test.ts +0 -199
- package/src/integrations/google-calendar/mapping.ts +0 -183
- package/src/integrations/google-calendar/migrations/001_google_calendar.sql +0 -97
- package/src/integrations/google-calendar/migrations/002_smart_sync.sql +0 -517
- package/src/integrations/google-calendar/migrations/003_plg_rename.sql +0 -273
- package/src/integrations/google-calendar/types.ts +0 -142
- package/src/lib/tenant.ts +0 -3
- package/src/locales/en.ts +0 -220
- package/src/locales/index.ts +0 -7
- package/src/locales/pt-BR.ts +0 -220
- package/src/migrations/000b_v_bookings_rename.sql +0 -21
- package/src/migrations/000c_dedupe_customer_phones.sql +0 -43
- package/src/migrations/001_public_booking.sql +0 -296
- package/src/migrations/002_v_bookings_compat.sql +0 -14
- package/src/migrations/003_public_client_kind.sql +0 -175
- package/src/migrations/004_public_booking_assignee.sql +0 -176
- package/src/migrations/005_agent_rpcs.sql +0 -168
- package/src/migrations/006_agent_rpc_localtime.sql +0 -181
- package/src/migrations/007_schedule_exception_precedence.sql +0 -290
- package/src/migrations/008_agent_rpc_exception_precedence.sql +0 -172
- package/src/migrations/009_public_booking_location.sql +0 -162
- package/src/migrations/010_public_service_curation.sql +0 -31
- package/src/migrations/011_default_assignee.sql +0 -167
- package/src/migrations/012_drop_legacy_booking_overload.sql +0 -29
- package/src/migrations/013_normalize_v_appointments.sql +0 -199
- package/src/migrations/014_agent_rpc_update_appointment.sql +0 -199
- package/src/migrations/index.ts +0 -2377
- package/src/public/BookingWidget.tsx +0 -324
- package/src/public/components/BrandHeader.tsx +0 -27
- package/src/public/components/ServiceCard.tsx +0 -39
- package/src/public/components/SidebarExtras.tsx +0 -30
- package/src/public/components/StepRailItem.tsx +0 -27
- package/src/public/components/SuccessPanel.tsx +0 -27
- package/src/public/components/SummaryRail.tsx +0 -90
- package/src/public/components/defaults.ts +0 -14
- package/src/public/context.tsx +0 -103
- package/src/public/createPublicBookingPlugin.ts +0 -281
- package/src/public/data.supabase.ts +0 -97
- package/src/public/data.ts +0 -105
- package/src/public/format.ts +0 -96
- package/src/public/hooks.ts +0 -110
- package/src/public/index.ts +0 -69
- package/src/public/steps/ContactStep.tsx +0 -184
- package/src/public/steps/DateTimeStep.tsx +0 -138
- package/src/public/steps/OverviewStep.tsx +0 -81
- package/src/public/steps/PaymentStep.tsx +0 -180
- package/src/public/types.ts +0 -250
- package/src/registries.ts +0 -35
- package/src/store.ts +0 -311
- package/src/types.ts +0 -273
- package/src/views/CalendarView.tsx +0 -1112
- package/src/views/ConfirmationsView.tsx +0 -155
- /package/dist/{financial-bridge.d.ts → bridges/financial-bridge.d.ts} +0 -0
- /package/dist/{registries.d.ts → data/registries.d.ts} +0 -0
- /package/dist/public/{BookingWidget.d.ts → views/BookingWidget.d.ts} +0 -0
- /package/dist/{calendar-styles.d.ts → styles/calendar-styles.d.ts} +0 -0
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
-- ============================================================================
|
|
2
|
-
-- plugin-agenda 014: agent_agenda_update_appointment — remarcar / reatribuir /
|
|
3
|
-
-- cancelar um agendamento existente.
|
|
4
|
-
--
|
|
5
|
-
-- Lacuna que isso fecha: o agente sabia CRIAR e não sabia MEXER. Pedido real
|
|
6
|
-
-- ("remarca esse paciente pra 16:30") caía no updateRecord genérico, que bate
|
|
7
|
-
-- em v_appointments — uma view — e devolve read_only; o modelo então "resolvia"
|
|
8
|
-
-- abrindo um agendamento NOVO, deixando o antigo de pé. Duplicar a agenda de um
|
|
9
|
-
-- salão é pior do que não fazer nada.
|
|
10
|
-
--
|
|
11
|
-
-- Mesma cadeia de guardas do 008 (agent_guard → janela de trabalho com exceções
|
|
12
|
-
-- → lock advisory → checagem de conflito → auditoria), com três diferenças:
|
|
13
|
-
-- • ação 'edit', sem cota (remarcar não consome bookings_month);
|
|
14
|
-
-- • o próprio agendamento é excluído da checagem de conflito consigo mesmo;
|
|
15
|
-
-- • cancelar não precisa de horário livre — só o guard.
|
|
16
|
-
-- Requer 007 (agenda_working_windows). Idempotente.
|
|
17
|
-
-- ============================================================================
|
|
18
|
-
|
|
19
|
-
CREATE OR REPLACE FUNCTION public.agent_agenda_update_appointment(
|
|
20
|
-
p_tenant_id uuid,
|
|
21
|
-
p_actor_user_id uuid,
|
|
22
|
-
p_payload jsonb
|
|
23
|
-
) RETURNS jsonb
|
|
24
|
-
LANGUAGE plpgsql SECURITY DEFINER
|
|
25
|
-
SET search_path = public
|
|
26
|
-
AS $$
|
|
27
|
-
DECLARE
|
|
28
|
-
v_denial jsonb;
|
|
29
|
-
v_id uuid;
|
|
30
|
-
v_tz text;
|
|
31
|
-
v_row record;
|
|
32
|
-
v_starts_raw text;
|
|
33
|
-
v_starts timestamptz;
|
|
34
|
-
v_ends timestamptz;
|
|
35
|
-
v_duration int;
|
|
36
|
-
v_professional uuid;
|
|
37
|
-
v_status text;
|
|
38
|
-
v_notes text;
|
|
39
|
-
v_wants_move boolean;
|
|
40
|
-
v_wants_status boolean;
|
|
41
|
-
BEGIN
|
|
42
|
-
SELECT COALESCE(t.settings->>'timezone', 'America/Sao_Paulo') INTO v_tz
|
|
43
|
-
FROM tenants t WHERE t.id = p_tenant_id;
|
|
44
|
-
IF v_tz IS NULL THEN
|
|
45
|
-
RETURN jsonb_build_object('ok', false, 'error', 'unknown tenant');
|
|
46
|
-
END IF;
|
|
47
|
-
|
|
48
|
-
-- ── payload ──────────────────────────────────────────────────────────────
|
|
49
|
-
BEGIN
|
|
50
|
-
v_id := (p_payload->>'appointment_id')::uuid;
|
|
51
|
-
v_professional := (p_payload->>'professional_id')::uuid;
|
|
52
|
-
v_starts_raw := p_payload->>'starts_at';
|
|
53
|
-
EXCEPTION WHEN OTHERS THEN
|
|
54
|
-
RETURN jsonb_build_object('ok', false, 'error', 'invalid payload: ' || SQLERRM);
|
|
55
|
-
END;
|
|
56
|
-
v_status := nullif(trim(lower(p_payload->>'status')), '');
|
|
57
|
-
v_notes := left(p_payload->>'notes', 500);
|
|
58
|
-
v_wants_move := v_starts_raw IS NOT NULL OR v_professional IS NOT NULL;
|
|
59
|
-
v_wants_status := v_status IS NOT NULL;
|
|
60
|
-
|
|
61
|
-
IF v_id IS NULL THEN
|
|
62
|
-
RETURN jsonb_build_object('ok', false, 'error',
|
|
63
|
-
'appointment_id is required — search the agenda first and reuse the id of the appointment to change');
|
|
64
|
-
END IF;
|
|
65
|
-
IF NOT v_wants_move AND NOT v_wants_status AND v_notes IS NULL THEN
|
|
66
|
-
RETURN jsonb_build_object('ok', false, 'error',
|
|
67
|
-
'nothing to change: send starts_at, professional_id, status or notes');
|
|
68
|
-
END IF;
|
|
69
|
-
IF v_status IS NOT NULL
|
|
70
|
-
AND v_status NOT IN ('scheduled', 'confirmed', 'in_progress', 'completed', 'cancelled', 'no_show') THEN
|
|
71
|
-
RETURN jsonb_build_object('ok', false, 'error',
|
|
72
|
-
'status must be one of scheduled, confirmed, in_progress, completed, cancelled, no_show');
|
|
73
|
-
END IF;
|
|
74
|
-
|
|
75
|
-
-- ── the appointment must exist, in THIS tenant ───────────────────────────
|
|
76
|
-
SELECT b.id, b.starts_at, b.ends_at, b.assignee_id, b.status, b.party_id, b.order_id
|
|
77
|
-
INTO v_row
|
|
78
|
-
FROM appointments b
|
|
79
|
-
WHERE b.id = v_id AND b.tenant_id = p_tenant_id;
|
|
80
|
-
IF NOT FOUND THEN
|
|
81
|
-
RETURN jsonb_build_object('ok', false, 'error', 'unknown appointment for this tenant');
|
|
82
|
-
END IF;
|
|
83
|
-
|
|
84
|
-
-- ── authorization: role → plan. No cap: editing frees nothing and buys
|
|
85
|
-
-- nothing, so charging bookings_month for a reschedule would be wrong.
|
|
86
|
-
v_denial := agent_guard(p_tenant_id, p_actor_user_id, 'appointments', 'edit');
|
|
87
|
-
IF v_denial IS NOT NULL THEN
|
|
88
|
-
RETURN jsonb_build_object('ok', false, 'denial', v_denial);
|
|
89
|
-
END IF;
|
|
90
|
-
|
|
91
|
-
-- Duration is preserved across a move — a 60-minute appointment stays 60.
|
|
92
|
-
v_duration := GREATEST(
|
|
93
|
-
COALESCE(EXTRACT(EPOCH FROM (v_row.ends_at - v_row.starts_at)) / 60, 30)::int, 5);
|
|
94
|
-
v_professional := COALESCE(v_professional, v_row.assignee_id);
|
|
95
|
-
|
|
96
|
-
IF v_wants_move THEN
|
|
97
|
-
IF v_starts_raw IS NOT NULL THEN
|
|
98
|
-
BEGIN
|
|
99
|
-
IF v_starts_raw ~ '(Z|[+-][0-9]{2}:?[0-9]{2})$' THEN
|
|
100
|
-
v_starts := v_starts_raw::timestamptz; -- explicit offset
|
|
101
|
-
ELSE
|
|
102
|
-
v_starts := (v_starts_raw::timestamp) AT TIME ZONE v_tz; -- tenant-local
|
|
103
|
-
END IF;
|
|
104
|
-
EXCEPTION WHEN OTHERS THEN
|
|
105
|
-
RETURN jsonb_build_object('ok', false, 'error', 'invalid starts_at: ' || SQLERRM);
|
|
106
|
-
END;
|
|
107
|
-
ELSE
|
|
108
|
-
v_starts := v_row.starts_at;
|
|
109
|
-
END IF;
|
|
110
|
-
v_ends := v_starts + make_interval(mins => v_duration);
|
|
111
|
-
|
|
112
|
-
IF v_starts > now() + interval '365 days' THEN
|
|
113
|
-
RETURN jsonb_build_object('ok', false, 'error', 'starts_at must be within the next year');
|
|
114
|
-
END IF;
|
|
115
|
-
|
|
116
|
-
-- Working window (exception-aware, 007) for the target professional.
|
|
117
|
-
IF NOT EXISTS (
|
|
118
|
-
SELECT 1
|
|
119
|
-
FROM agenda_working_windows(
|
|
120
|
-
p_tenant_id, (v_starts AT TIME ZONE v_tz)::date, v_professional) w
|
|
121
|
-
WHERE w.assignee_id = v_professional
|
|
122
|
-
AND (v_starts AT TIME ZONE v_tz)::time >= w.win_start
|
|
123
|
-
AND (v_ends AT TIME ZONE v_tz)::time <= w.win_end
|
|
124
|
-
) THEN
|
|
125
|
-
RETURN jsonb_build_object('ok', false, 'error',
|
|
126
|
-
'that slot is outside the professional''s working hours. Suggest a different time. Times are tenant-local, tz ' || v_tz);
|
|
127
|
-
END IF;
|
|
128
|
-
|
|
129
|
-
PERFORM pg_advisory_xact_lock(hashtextextended(p_tenant_id::text || v_professional::text, 0));
|
|
130
|
-
IF EXISTS (
|
|
131
|
-
SELECT 1 FROM appointments b
|
|
132
|
-
WHERE b.tenant_id = p_tenant_id
|
|
133
|
-
AND b.assignee_id = v_professional
|
|
134
|
-
AND b.id <> v_id -- never conflicts with itself
|
|
135
|
-
AND b.status NOT IN ('cancelled', 'no_show')
|
|
136
|
-
AND b.starts_at < v_ends
|
|
137
|
-
AND COALESCE(b.ends_at, b.starts_at) > v_starts
|
|
138
|
-
) THEN
|
|
139
|
-
RETURN jsonb_build_object('ok', false, 'error',
|
|
140
|
-
'that slot is already taken. Suggest a different time.');
|
|
141
|
-
END IF;
|
|
142
|
-
END IF;
|
|
143
|
-
|
|
144
|
-
-- ── write + audit ────────────────────────────────────────────────────────
|
|
145
|
-
UPDATE appointments b SET
|
|
146
|
-
starts_at = COALESCE(v_starts, b.starts_at),
|
|
147
|
-
ends_at = COALESCE(v_ends, b.ends_at),
|
|
148
|
-
assignee_id = v_professional,
|
|
149
|
-
status = COALESCE(v_status, b.status),
|
|
150
|
-
notes = COALESCE(v_notes, b.notes),
|
|
151
|
-
metadata = COALESCE(b.metadata, '{}'::jsonb) || jsonb_build_object('lastAgentEdit', now()),
|
|
152
|
-
updated_at = now()
|
|
153
|
-
WHERE b.id = v_id AND b.tenant_id = p_tenant_id;
|
|
154
|
-
|
|
155
|
-
-- The order mirrors the appointment's assignee/status so the financial side
|
|
156
|
-
-- does not drift from the calendar.
|
|
157
|
-
IF v_row.order_id IS NOT NULL THEN
|
|
158
|
-
UPDATE orders o SET
|
|
159
|
-
assignee_id = v_professional,
|
|
160
|
-
status = CASE WHEN v_status = 'cancelled' THEN 'cancelled' ELSE o.status END,
|
|
161
|
-
updated_at = now()
|
|
162
|
-
WHERE o.id = v_row.order_id AND o.tenant_id = p_tenant_id;
|
|
163
|
-
END IF;
|
|
164
|
-
|
|
165
|
-
INSERT INTO audit_logs (tenant_id, user_id, action, entity_type, entity_id, metadata)
|
|
166
|
-
VALUES (p_tenant_id, p_actor_user_id, 'agent.updateAppointment', 'appointment', v_id::text,
|
|
167
|
-
jsonb_build_object('payload', p_payload,
|
|
168
|
-
'previous', jsonb_build_object(
|
|
169
|
-
'starts_at', v_row.starts_at,
|
|
170
|
-
'ends_at', v_row.ends_at,
|
|
171
|
-
'assignee_id', v_row.assignee_id,
|
|
172
|
-
'status', v_row.status)));
|
|
173
|
-
|
|
174
|
-
SELECT a.id, a.starts_at, a.ends_at, a.status, a.client_name, a.professional_name
|
|
175
|
-
INTO v_row
|
|
176
|
-
FROM v_appointments a WHERE a.id = v_id;
|
|
177
|
-
|
|
178
|
-
RETURN jsonb_build_object(
|
|
179
|
-
'ok', true,
|
|
180
|
-
'id', v_id,
|
|
181
|
-
'record', jsonb_build_object(
|
|
182
|
-
'ref', jsonb_build_object('id', v_id, 'resource', 'appointments',
|
|
183
|
-
'archetype', 'schedule:appointment'),
|
|
184
|
-
'starts_at', v_row.starts_at,
|
|
185
|
-
'ends_at', v_row.ends_at,
|
|
186
|
-
'starts_at_local', to_char(v_row.starts_at AT TIME ZONE v_tz, 'YYYY-MM-DD (Dy) HH24:MI') || ' ' || v_tz,
|
|
187
|
-
'ends_at_local', to_char(v_row.ends_at AT TIME ZONE v_tz, 'HH24:MI'),
|
|
188
|
-
'client_name', v_row.client_name,
|
|
189
|
-
'professional_name', v_row.professional_name,
|
|
190
|
-
'status', v_row.status
|
|
191
|
-
)
|
|
192
|
-
);
|
|
193
|
-
END;
|
|
194
|
-
$$;
|
|
195
|
-
|
|
196
|
-
REVOKE ALL ON FUNCTION public.agent_agenda_update_appointment(uuid, uuid, jsonb) FROM public;
|
|
197
|
-
REVOKE EXECUTE ON FUNCTION public.agent_agenda_update_appointment(uuid, uuid, jsonb) FROM anon;
|
|
198
|
-
GRANT EXECUTE ON FUNCTION public.agent_agenda_update_appointment(uuid, uuid, jsonb)
|
|
199
|
-
TO authenticated, service_role;
|