@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.
Files changed (153) hide show
  1. package/README.md +3 -3
  2. package/dist/bridges/create-financial-bridge.d.ts +1 -1
  3. package/dist/bridges/create-financial-bridge.d.ts.map +1 -1
  4. package/dist/bridges/financial-bridge.d.ts.map +1 -0
  5. package/dist/{chunk-Q2PAWBPR.js → chunk-76ZOHRBM.js} +2 -2
  6. package/dist/{chunk-Q2PAWBPR.js.map → chunk-76ZOHRBM.js.map} +1 -1
  7. package/dist/components/PaymentStatusBadge.d.ts +1 -1
  8. package/dist/components/PaymentStatusBadge.d.ts.map +1 -1
  9. package/dist/config.d.ts +2 -2
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/{AgendaContext.d.ts → context.d.ts} +1 -1
  12. package/dist/context.d.ts.map +1 -0
  13. package/dist/data/registries.d.ts.map +1 -0
  14. package/dist/index.d.ts +2 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +170 -7
  17. package/dist/index.js.map +1 -1
  18. package/dist/lib/message-events.d.ts +12 -0
  19. package/dist/lib/message-events.d.ts.map +1 -0
  20. package/dist/public/{data.d.ts → data/index.d.ts} +4 -4
  21. package/dist/public/data/index.d.ts.map +1 -0
  22. package/dist/public/{data.supabase.d.ts → data/supabase.d.ts} +2 -2
  23. package/dist/public/data/supabase.d.ts.map +1 -0
  24. package/dist/public/{hooks.d.ts → hooks/index.d.ts} +4 -4
  25. package/dist/public/hooks/index.d.ts.map +1 -0
  26. package/dist/public/index.d.ts +4 -4
  27. package/dist/public/index.d.ts.map +1 -1
  28. package/dist/public/index.js +3 -3
  29. package/dist/public/index.js.map +1 -1
  30. package/dist/public/{format.d.ts → lib/format.d.ts} +1 -1
  31. package/dist/public/lib/format.d.ts.map +1 -0
  32. package/dist/public/views/BookingWidget.d.ts.map +1 -0
  33. package/dist/public/{steps → views/steps}/ContactStep.d.ts +1 -1
  34. package/dist/public/views/steps/ContactStep.d.ts.map +1 -0
  35. package/dist/public/{steps → views/steps}/DateTimeStep.d.ts +3 -3
  36. package/dist/public/views/steps/DateTimeStep.d.ts.map +1 -0
  37. package/dist/public/{steps → views/steps}/OverviewStep.d.ts +1 -1
  38. package/dist/public/views/steps/OverviewStep.d.ts.map +1 -0
  39. package/dist/public/{steps → views/steps}/PaymentStep.d.ts +1 -1
  40. package/dist/public/views/steps/PaymentStep.d.ts.map +1 -0
  41. package/dist/store.d.ts +1 -1
  42. package/dist/store.d.ts.map +1 -1
  43. package/dist/styles/calendar-styles.d.ts.map +1 -0
  44. package/dist/types.d.ts +1 -1
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/{AgendaPage.d.ts → views/AgendaPage.d.ts} +3 -3
  47. package/dist/views/AgendaPage.d.ts.map +1 -0
  48. package/package.json +6 -9
  49. package/dist/AgendaContext.d.ts.map +0 -1
  50. package/dist/AgendaPage.d.ts.map +0 -1
  51. package/dist/calendar-styles.d.ts.map +0 -1
  52. package/dist/financial-bridge.d.ts.map +0 -1
  53. package/dist/public/BookingWidget.d.ts.map +0 -1
  54. package/dist/public/data.d.ts.map +0 -1
  55. package/dist/public/data.supabase.d.ts.map +0 -1
  56. package/dist/public/format.d.ts.map +0 -1
  57. package/dist/public/hooks.d.ts.map +0 -1
  58. package/dist/public/steps/ContactStep.d.ts.map +0 -1
  59. package/dist/public/steps/DateTimeStep.d.ts.map +0 -1
  60. package/dist/public/steps/OverviewStep.d.ts.map +0 -1
  61. package/dist/public/steps/PaymentStep.d.ts.map +0 -1
  62. package/dist/registries.d.ts.map +0 -1
  63. package/src/AgendaContext.tsx +0 -11
  64. package/src/AgendaPage.tsx +0 -33
  65. package/src/bridges/create-financial-bridge.ts +0 -296
  66. package/src/calendar-styles.css +0 -245
  67. package/src/calendar-styles.ts +0 -285
  68. package/src/components/AgendaGeneralSettings.tsx +0 -86
  69. package/src/components/AgendaMobileList.tsx +0 -103
  70. package/src/components/AppointmentModal.tsx +0 -1050
  71. package/src/components/AppointmentPopover.tsx +0 -231
  72. package/src/components/BookingPaymentPanel.tsx +0 -394
  73. package/src/components/CalendarSidebar.tsx +0 -119
  74. package/src/components/CalendarToolbar.tsx +0 -86
  75. package/src/components/EventContextMenu.tsx +0 -125
  76. package/src/components/FloatingPanel.tsx +0 -123
  77. package/src/components/MiniCalendar.tsx +0 -120
  78. package/src/components/PaymentStatusBadge.tsx +0 -62
  79. package/src/components/StatusBadge.tsx +0 -23
  80. package/src/config.ts +0 -368
  81. package/src/data/index.ts +0 -4
  82. package/src/data/mock.ts +0 -344
  83. package/src/data/supabase.ts +0 -636
  84. package/src/data/types.ts +0 -37
  85. package/src/financial-bridge.ts +0 -96
  86. package/src/hooks/useAgendaSettings.ts +0 -17
  87. package/src/index.ts +0 -297
  88. package/src/integrations/google-calendar/GoogleCalendarSettings.tsx +0 -136
  89. package/src/integrations/google-calendar/components/CalendarColorDot.tsx +0 -23
  90. package/src/integrations/google-calendar/components/ChannelMappingList.tsx +0 -329
  91. package/src/integrations/google-calendar/components/ImportEventsWizard.tsx +0 -215
  92. package/src/integrations/google-calendar/components/useAgendaLookups.ts +0 -100
  93. package/src/integrations/google-calendar/connector.ts +0 -20
  94. package/src/integrations/google-calendar/connectorDef.tsx +0 -185
  95. package/src/integrations/google-calendar/data/supabase.ts +0 -170
  96. package/src/integrations/google-calendar/data/tables.ts +0 -12
  97. package/src/integrations/google-calendar/index.ts +0 -45
  98. package/src/integrations/google-calendar/integration.test.ts +0 -199
  99. package/src/integrations/google-calendar/mapping.ts +0 -183
  100. package/src/integrations/google-calendar/migrations/001_google_calendar.sql +0 -97
  101. package/src/integrations/google-calendar/migrations/002_smart_sync.sql +0 -517
  102. package/src/integrations/google-calendar/migrations/003_plg_rename.sql +0 -273
  103. package/src/integrations/google-calendar/types.ts +0 -142
  104. package/src/lib/tenant.ts +0 -3
  105. package/src/locales/en.ts +0 -220
  106. package/src/locales/index.ts +0 -7
  107. package/src/locales/pt-BR.ts +0 -220
  108. package/src/migrations/000b_v_bookings_rename.sql +0 -21
  109. package/src/migrations/000c_dedupe_customer_phones.sql +0 -43
  110. package/src/migrations/001_public_booking.sql +0 -296
  111. package/src/migrations/002_v_bookings_compat.sql +0 -14
  112. package/src/migrations/003_public_client_kind.sql +0 -175
  113. package/src/migrations/004_public_booking_assignee.sql +0 -176
  114. package/src/migrations/005_agent_rpcs.sql +0 -168
  115. package/src/migrations/006_agent_rpc_localtime.sql +0 -181
  116. package/src/migrations/007_schedule_exception_precedence.sql +0 -290
  117. package/src/migrations/008_agent_rpc_exception_precedence.sql +0 -172
  118. package/src/migrations/009_public_booking_location.sql +0 -162
  119. package/src/migrations/010_public_service_curation.sql +0 -31
  120. package/src/migrations/011_default_assignee.sql +0 -167
  121. package/src/migrations/012_drop_legacy_booking_overload.sql +0 -29
  122. package/src/migrations/013_normalize_v_appointments.sql +0 -199
  123. package/src/migrations/014_agent_rpc_update_appointment.sql +0 -199
  124. package/src/migrations/index.ts +0 -2377
  125. package/src/public/BookingWidget.tsx +0 -324
  126. package/src/public/components/BrandHeader.tsx +0 -27
  127. package/src/public/components/ServiceCard.tsx +0 -39
  128. package/src/public/components/SidebarExtras.tsx +0 -30
  129. package/src/public/components/StepRailItem.tsx +0 -27
  130. package/src/public/components/SuccessPanel.tsx +0 -27
  131. package/src/public/components/SummaryRail.tsx +0 -90
  132. package/src/public/components/defaults.ts +0 -14
  133. package/src/public/context.tsx +0 -103
  134. package/src/public/createPublicBookingPlugin.ts +0 -281
  135. package/src/public/data.supabase.ts +0 -97
  136. package/src/public/data.ts +0 -105
  137. package/src/public/format.ts +0 -96
  138. package/src/public/hooks.ts +0 -110
  139. package/src/public/index.ts +0 -69
  140. package/src/public/steps/ContactStep.tsx +0 -184
  141. package/src/public/steps/DateTimeStep.tsx +0 -138
  142. package/src/public/steps/OverviewStep.tsx +0 -81
  143. package/src/public/steps/PaymentStep.tsx +0 -180
  144. package/src/public/types.ts +0 -250
  145. package/src/registries.ts +0 -35
  146. package/src/store.ts +0 -311
  147. package/src/types.ts +0 -273
  148. package/src/views/CalendarView.tsx +0 -1112
  149. package/src/views/ConfirmationsView.tsx +0 -155
  150. /package/dist/{financial-bridge.d.ts → bridges/financial-bridge.d.ts} +0 -0
  151. /package/dist/{registries.d.ts → data/registries.d.ts} +0 -0
  152. /package/dist/public/{BookingWidget.d.ts → views/BookingWidget.d.ts} +0 -0
  153. /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;