@proteos/sdk 0.53.0 → 0.54.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.
@@ -0,0 +1,790 @@
1
+ import type { ContactRef, WindowDay } from '../conversation/types.js'
2
+ import type { ResponseMeta, UserRef } from '../types/index.js'
3
+
4
+ /* =========================================================================
5
+ scheduling-service wire types — a 1:1 mirror of
6
+ packages/go/model/scheduling (schedulingmodel) and scheduling/api
7
+ (schedulingapi). snake_case fields, string enums, ISO timestamps.
8
+ ========================================================================= */
9
+
10
+ // ── Enums ────────────────────────────────────────────────────────────────────
11
+
12
+ /** The calendar backend behind a connection. */
13
+ export type CalendarProvider = 'google' | 'microsoft'
14
+
15
+ /** The health of our binding to a connector-service grant. */
16
+ export type CalendarConnectionStatus = 'active' | 'error' | 'revoked'
17
+
18
+ /** What COLLEAGUES see of a calendar's events: nothing, busy blocks, everything. */
19
+ export type CalendarVisibility = 'private' | 'busy_only' | 'full'
20
+
21
+ /** The mirror state of one calendar. */
22
+ export type CalendarSyncStatus = 'idle' | 'syncing' | 'error'
23
+
24
+ /** An attendee's RSVP. */
25
+ export type ParticipationStatus = 'needs_action' | 'accepted' | 'declined' | 'tentative'
26
+
27
+ /** Whether an event blocks its owner's time. */
28
+ export type EventTransparency = 'busy' | 'free'
29
+
30
+ /** The provider lifecycle state of an event. */
31
+ export type EventStatus = 'confirmed' | 'tentative' | 'cancelled'
32
+
33
+ /** Provider-side visibility of one event (distinct from CalendarVisibility). */
34
+ export type EventVisibility = 'default' | 'private' | 'public'
35
+
36
+ /** Who created the row first: the provider (mirrored) or the platform. */
37
+ export type EventSource = 'provider' | 'platform'
38
+
39
+ /**
40
+ * Delivery state of a platform write to the provider. `pending_mirror` marks a
41
+ * host's copy of a meeting written to the ORGANIZER's calendar, merged onto by
42
+ * that host's own sync (by ical_uid).
43
+ */
44
+ export type EventWriteStatus = 'synced' | 'pending' | 'pending_mirror' | 'failed'
45
+
46
+ /** Integrated conferencing minted by the provider. */
47
+ export type ConferencingProvider = 'google_meet' | 'teams'
48
+
49
+ /** How many of a link's hosts end up in the meeting. */
50
+ export type Assignment = 'single' | 'round_robin' | 'collective'
51
+
52
+ /** Whom the provider emails about a platform write. */
53
+ export type NotifyMode = 'all' | 'external_only' | 'none'
54
+
55
+ /** What an edit of a recurring instance targets. */
56
+ export type RecurrenceScope = 'instance' | 'series'
57
+
58
+ /** How a calendar event type meets. */
59
+ export type LocationKind = 'video' | 'phone' | 'in_person' | 'custom'
60
+
61
+ /** What an availability constraint does to the window it covers. */
62
+ export type AvailabilityKind = 'available' | 'unavailable'
63
+
64
+ /** Why a host is not offered at a time (verbose slot reads). */
65
+ export type SlotUnavailabilityReason =
66
+ | 'no_calendar'
67
+ | 'outside_hours'
68
+ | 'blocked'
69
+ | 'other_event_type'
70
+ | 'calendar_busy'
71
+ | 'exclusive_event'
72
+ | 'minimum_notice'
73
+ | 'scheduling_window'
74
+ | 'daily_limit'
75
+
76
+ // ── Entities ─────────────────────────────────────────────────────────────────
77
+
78
+ /**
79
+ * Our binding to one connector-service grant (a `google-calendar` /
80
+ * `microsoft-calendar` connection of scope user). A user may hold several;
81
+ * the same provider account cannot be bound twice. Calendars hang off it.
82
+ */
83
+ export interface CalendarConnection {
84
+ id: string
85
+ org_id: string
86
+ /** The platform user who owns the grant. */
87
+ owner: UserRef
88
+ connection_id: string
89
+ provider: CalendarProvider
90
+ /** The provider account (e-mail address / UPN), copied from the grant. */
91
+ external_account_id: string
92
+ status: CalendarConnectionStatus
93
+ status_detail?: string
94
+ last_synced_at?: string
95
+ created_at: string
96
+ created_by: UserRef
97
+ updated_at: string
98
+ updated_by: UserRef
99
+ }
100
+
101
+ /** The mirror state of one calendar: change cursor, backfilled window, last outcome. */
102
+ export interface CalendarSync {
103
+ cursor?: string
104
+ backfill_from?: string
105
+ backfill_to?: string
106
+ last_synced_at?: string
107
+ status: CalendarSyncStatus
108
+ error?: string
109
+ }
110
+
111
+ /**
112
+ * The open push subscription for one calendar. Google fills channel_id +
113
+ * resource_id, Microsoft fills subscription_id. Only the HASH of the secret
114
+ * the provider echoes is stored.
115
+ */
116
+ export interface CalendarWatch {
117
+ channel_id?: string
118
+ resource_id?: string
119
+ subscription_id?: string
120
+ client_state_hash?: string
121
+ expires_at?: string
122
+ }
123
+
124
+ /**
125
+ * One provider calendar under a connection, plus the platform's roles for it:
126
+ * is_synced (mirrored + watched), is_availability_source (its busy time counts
127
+ * against the owner's slots), is_target (the ONE calendar per user the
128
+ * platform writes exclusive events to), visibility (what colleagues see).
129
+ */
130
+ export interface Calendar {
131
+ id: string
132
+ org_id: string
133
+ calendar_connection_id: string
134
+ /** The calendar's owner (the connection's owner, denormalized). */
135
+ owner: UserRef
136
+ provider_calendar_id: string
137
+ name: string
138
+ color?: string
139
+ timezone?: string
140
+ is_primary: boolean
141
+ is_readonly: boolean
142
+ has_integrated_conferencing: boolean
143
+ is_synced: boolean
144
+ is_availability_source: boolean
145
+ is_target: boolean
146
+ visibility: CalendarVisibility
147
+ sync: CalendarSync
148
+ watch: CalendarWatch
149
+ created_at: string
150
+ created_by: UserRef
151
+ updated_at: string
152
+ updated_by: UserRef
153
+ }
154
+
155
+ /**
156
+ * A user's scheduling settings: the zone their hours are expressed in, the
157
+ * weekly hours themselves ({day, from, until} windows, the sending-rule
158
+ * shape; empty = bookable any time), what a scheduling page shows about
159
+ * them, and whether they can be booked at all. One per (org, user).
160
+ */
161
+ export interface SchedulingProfile {
162
+ id: string
163
+ org_id: string
164
+ user_id: string
165
+ timezone: string
166
+ weekly_hours: WindowDay[]
167
+ display_name?: string
168
+ headline?: string
169
+ is_bookable: boolean
170
+ created_at: string
171
+ created_by: UserRef
172
+ updated_at: string
173
+ updated_by: UserRef
174
+ }
175
+
176
+ /**
177
+ * One person or resource on an event: the platform's person snapshot
178
+ * (ContactRef — the same shape a conversation participant carries) plus the
179
+ * calendar facts. Hosts of a platform-scheduled event are attendees too
180
+ * (is_host); the calendar owner's own row is is_self.
181
+ */
182
+ export interface CalendarAttendee extends ContactRef {
183
+ response_status: ParticipationStatus
184
+ is_optional: boolean
185
+ is_organizer: boolean
186
+ is_self: boolean
187
+ /** A platform user whose time this event claims; always false on mirrored events. */
188
+ is_host: boolean
189
+ /** Rooms and equipment — never resolved to a contact. */
190
+ is_resource: boolean
191
+ }
192
+
193
+ /**
194
+ * The one seam between the platform's calendar and a module's business
195
+ * object: the record this event belongs to (an appointment, an interview…).
196
+ */
197
+ export interface RecordRef {
198
+ entity_slug: string
199
+ record_id: string
200
+ }
201
+
202
+ /**
203
+ * ONE entry in ONE provider calendar, mirrored two-way. A platform-created row
204
+ * with is_exclusive claims its owner's time (DB exclusion constraint);
205
+ * mirrored provider rows never do. All copies of one meeting share ical_uid.
206
+ */
207
+ export interface CalendarEvent {
208
+ id: string
209
+ org_id: string
210
+ calendar_id: string
211
+ /** The calendar's owner (denormalized for per-user window reads). */
212
+ owner: UserRef
213
+ /** The id in THIS calendar; absent while a platform write is pending. */
214
+ provider_event_id?: string
215
+ /** RFC 5545 UID shared by every copy of the meeting. */
216
+ ical_uid?: string
217
+ /** The recurring master's id on expanded instances. */
218
+ series_id?: string
219
+ is_recurring_instance: boolean
220
+ /** RRULE / EXDATE lines — series master only. */
221
+ recurrence?: string[]
222
+ title: string
223
+ description?: string
224
+ start_at: string
225
+ end_at: string
226
+ is_all_day: boolean
227
+ /** The provider's zone for the event — display and all-day boundaries only. */
228
+ timezone?: string
229
+ location?: string
230
+ join_url?: string
231
+ conferencing_provider?: ConferencingProvider
232
+ organizer: ContactRef
233
+ attendees: CalendarAttendee[]
234
+ owner_response_status: ParticipationStatus
235
+ transparency: EventTransparency
236
+ status: EventStatus
237
+ visibility: EventVisibility
238
+ etag?: string
239
+ provider_updated_at?: string
240
+ source: EventSource
241
+ is_exclusive: boolean
242
+ /** Set when the platform scheduled the event through a calendar_event_type / scheduling_link. */
243
+ type_key?: string
244
+ link_key?: string
245
+ record?: RecordRef
246
+ /** A read where the viewer only sees busy blocks of a colleague's calendar. */
247
+ is_projected?: boolean
248
+ write_status: EventWriteStatus
249
+ write_error?: string
250
+ /** The tombstone: the provider (or a platform delete) removed the event. */
251
+ deleted_at?: string
252
+ created_at: string
253
+ created_by: UserRef
254
+ updated_at: string
255
+ updated_by: UserRef
256
+ }
257
+
258
+ /** Where events of a type meet; is_integrated_conferencing asks the provider for a Meet / Teams link. */
259
+ export interface EventLocation {
260
+ kind: LocationKind
261
+ is_integrated_conferencing: boolean
262
+ join_url?: string
263
+ phone?: string
264
+ address?: string
265
+ instructions?: string
266
+ }
267
+
268
+ /**
269
+ * The *what* of a scheduled event — the reusable preset of slot rules a link,
270
+ * an internal booking or a module books against. Config, keyed by (org, key).
271
+ */
272
+ export interface CalendarEventType {
273
+ org_id: string
274
+ key: string
275
+ name: string
276
+ description?: string
277
+ color?: string
278
+ duration_minutes: number
279
+ /** The candidate grid: 5 | 10 | 15 | 20 | 30 | 60. */
280
+ slot_interval_minutes: number
281
+ buffer_before_minutes: number
282
+ buffer_after_minutes: number
283
+ minimum_notice_minutes: number
284
+ /** How far ahead a slot may be taken; 0 = no cap. */
285
+ scheduling_window_days: number
286
+ /** Exclusive events of this type per host per day; 0 = no cap. */
287
+ max_per_day: number
288
+ location: EventLocation
289
+ /** Soft reference to conversation-service's conversation_type. */
290
+ conversation_type_key?: string
291
+ is_cancel_allowed: boolean
292
+ is_reschedule_allowed: boolean
293
+ cancel_notice_minutes: number
294
+ is_enabled: boolean
295
+ created_at: string
296
+ created_by: UserRef
297
+ updated_at: string
298
+ updated_by: UserRef
299
+ }
300
+
301
+ /**
302
+ * One rule about a user's time on top of their weekly hours: a recurring
303
+ * window (recurrence_rule = "DTSTART;TZID=…\nRRULE:…", duration_minutes
304
+ * long, or is_all_day) that opens time (available, also outside the weekly
305
+ * hours) or blocks it (unavailable). calendar_event_type_keys scopes the rule
306
+ * to some types: an available window "for intro calls" opens it for them and
307
+ * keeps every other type out; an unavailable window "for demos" blocks demos
308
+ * only. Empty = every type.
309
+ */
310
+ export interface AvailabilityConstraint {
311
+ id: string
312
+ org_id: string
313
+ user_id: string
314
+ kind: AvailabilityKind
315
+ recurrence_rule: string
316
+ duration_minutes: number
317
+ is_all_day: boolean
318
+ calendar_event_type_keys: string[]
319
+ label?: string
320
+ created_at: string
321
+ created_by: UserRef
322
+ updated_at: string
323
+ updated_by: UserRef
324
+ }
325
+
326
+ /** One bookable start; host_user_ids = the hosts free for it. */
327
+ export interface Slot {
328
+ start_at: string
329
+ end_at: string
330
+ host_user_ids: string[]
331
+ }
332
+
333
+ /** Why a host is not offered at a time; calendar_event_id when a mirrored event is the cause. */
334
+ export interface SlotUnavailability {
335
+ start_at: string
336
+ end_at: string
337
+ host_user_id: string
338
+ reason: SlotUnavailabilityReason
339
+ calendar_event_id?: string
340
+ }
341
+
342
+ // ── Requests / queries ───────────────────────────────────────────────────────
343
+
344
+ /** Creates or replaces a calendar event type (PUT /calendar-event-types/:key). */
345
+ export interface PutCalendarEventTypeRequest {
346
+ name: string
347
+ description?: string
348
+ color?: string
349
+ duration_minutes: number
350
+ slot_interval_minutes?: number
351
+ buffer_before_minutes?: number
352
+ buffer_after_minutes?: number
353
+ minimum_notice_minutes?: number
354
+ scheduling_window_days?: number
355
+ max_per_day?: number
356
+ location?: EventLocation
357
+ conversation_type_key?: string
358
+ /** Policy flags default to TRUE when absent; send false to switch one off. */
359
+ is_cancel_allowed?: boolean
360
+ is_reschedule_allowed?: boolean
361
+ cancel_notice_minutes?: number
362
+ is_enabled?: boolean
363
+ }
364
+
365
+ /** Partial update of a calendar event type; location replaces wholesale. */
366
+ export interface UpdateCalendarEventTypeRequest {
367
+ name?: string
368
+ description?: string
369
+ color?: string
370
+ duration_minutes?: number
371
+ slot_interval_minutes?: number
372
+ buffer_before_minutes?: number
373
+ buffer_after_minutes?: number
374
+ minimum_notice_minutes?: number
375
+ scheduling_window_days?: number
376
+ max_per_day?: number
377
+ location?: EventLocation
378
+ conversation_type_key?: string
379
+ /** Policy flags default to TRUE when absent; send false to switch one off. */
380
+ is_cancel_allowed?: boolean
381
+ is_reschedule_allowed?: boolean
382
+ cancel_notice_minutes?: number
383
+ is_enabled?: boolean
384
+ }
385
+
386
+ export interface ListCalendarEventTypesQuery {
387
+ is_enabled?: boolean
388
+ search?: string
389
+ page?: number
390
+ page_size?: number
391
+ sort_by?: string
392
+ sort_direction?: 'asc' | 'desc'
393
+ }
394
+
395
+ /**
396
+ * Adds one rule about a user's time. recurrence_rule is
397
+ * "DTSTART;TZID=<zone>:<local time>\nRRULE:<rule>" with a quarter-hour DTSTART.
398
+ */
399
+ export interface CreateAvailabilityConstraintRequest {
400
+ kind: AvailabilityKind
401
+ recurrence_rule: string
402
+ duration_minutes?: number
403
+ is_all_day?: boolean
404
+ calendar_event_type_keys?: string[]
405
+ label?: string
406
+ }
407
+
408
+ /** Partial update; calendar_event_type_keys present replaces the list. */
409
+ export interface UpdateAvailabilityConstraintRequest {
410
+ kind?: AvailabilityKind
411
+ recurrence_rule?: string
412
+ duration_minutes?: number
413
+ is_all_day?: boolean
414
+ calendar_event_type_keys?: string[]
415
+ label?: string
416
+ }
417
+
418
+ export interface ListAvailabilityConstraintsQuery {
419
+ kind?: AvailabilityKind
420
+ page?: number
421
+ page_size?: number
422
+ sort_by?: string
423
+ sort_direction?: 'asc' | 'desc'
424
+ }
425
+
426
+ /** Explicit slot rules when no calendar_event_type governs the request. */
427
+ export interface SlotParameters {
428
+ duration_minutes: number
429
+ slot_interval_minutes?: number
430
+ buffer_before_minutes?: number
431
+ buffer_after_minutes?: number
432
+ minimum_notice_minutes?: number
433
+ scheduling_window_days?: number
434
+ max_per_day?: number
435
+ }
436
+
437
+ /**
438
+ * Asks for the bookable starts of some hosts in [from, to) (≤ 31 days).
439
+ * Exactly one of type_key | link_key | parameters governs the rules;
440
+ * assignment picks union (single / round_robin) or intersection (collective).
441
+ * timezone is the requester's zone: slots are grouped by its local day.
442
+ */
443
+ export interface GetSlotsRequest {
444
+ type_key?: string
445
+ link_key?: string
446
+ parameters?: SlotParameters
447
+ host_user_ids?: string[]
448
+ assignment?: Assignment
449
+ from: string
450
+ to: string
451
+ timezone: string
452
+ is_verbose?: boolean
453
+ }
454
+
455
+ /** Slots grouped by the requester's local day ("YYYY-MM-DD"); unavailability only when verbose. */
456
+ export interface GetSlotsResponse {
457
+ slots: Record<string, Slot[]>
458
+ unavailability?: SlotUnavailability[]
459
+ }
460
+
461
+ /**
462
+ * Binds a connector-service grant (a `google-calendar` / `microsoft-calendar`
463
+ * connection of scope user owned by the caller) to the calendar mirror.
464
+ */
465
+ export interface CreateCalendarConnectionRequest {
466
+ connection_id: string
467
+ }
468
+
469
+ /** Re-activates a repaired connection. Only `active` can be requested. */
470
+ export interface UpdateCalendarConnectionRequest {
471
+ status?: 'active'
472
+ }
473
+
474
+ export interface ListCalendarConnectionsQuery {
475
+ provider?: CalendarProvider
476
+ status?: CalendarConnectionStatus
477
+ page?: number
478
+ page_size?: number
479
+ sort_by?: string
480
+ sort_direction?: 'asc' | 'desc'
481
+ }
482
+
483
+ /**
484
+ * Changes the platform roles of a calendar. Every field is tri-state;
485
+ * is_synced flips the mirror on/off, is_target=true demotes the user's
486
+ * current target calendar in the same transaction.
487
+ */
488
+ export interface UpdateCalendarRequest {
489
+ is_synced?: boolean
490
+ is_availability_source?: boolean
491
+ is_target?: boolean
492
+ visibility?: CalendarVisibility
493
+ color?: string
494
+ }
495
+
496
+ export interface ListCalendarsQuery {
497
+ calendar_connection_id?: string
498
+ is_synced?: boolean
499
+ is_availability_source?: boolean
500
+ is_target?: boolean
501
+ page?: number
502
+ page_size?: number
503
+ sort_by?: string
504
+ sort_direction?: 'asc' | 'desc'
505
+ }
506
+
507
+ /** Replaces a user's scheduling profile (PUT semantics: every field is the new value). */
508
+ export interface PutSchedulingProfileRequest {
509
+ timezone: string
510
+ weekly_hours: WindowDay[]
511
+ display_name?: string
512
+ headline?: string
513
+ is_bookable: boolean
514
+ }
515
+
516
+ /**
517
+ * Reads a window of events. user_ids / calendar_ids pick whose calendars
518
+ * (default: the caller's); colleagues' events come back projected by their
519
+ * calendar's visibility. from/to are required (≤ 93 days).
520
+ */
521
+ export interface ListCalendarEventsQuery {
522
+ user_ids?: string[]
523
+ calendar_ids?: string[]
524
+ from: string
525
+ to: string
526
+ timezone?: string
527
+ type_key?: string
528
+ record_entity_slug?: string
529
+ record_id?: string
530
+ contact_id?: string
531
+ is_deleted_included?: boolean
532
+ }
533
+
534
+ /** One person to invite on a platform write. */
535
+ export interface CalendarAttendeeRequest {
536
+ email: string
537
+ name?: string
538
+ is_optional?: boolean
539
+ }
540
+
541
+ /**
542
+ * Schedules the event for platform users instead of one explicit calendar:
543
+ * the service resolves each host's target calendar and writes one provider
544
+ * event owned by the organizer.
545
+ */
546
+ export interface HostsRequest {
547
+ user_ids: string[]
548
+ assignment: Assignment
549
+ organizer_user_id?: string
550
+ }
551
+
552
+ /**
553
+ * Writes an event through to the provider. Exactly one of calendar_id (the
554
+ * caller's own calendar) or hosts is given. is_exclusive makes the row claim
555
+ * the owner's time (409 slot_unavailable on overlap).
556
+ */
557
+ export interface CreateCalendarEventRequest {
558
+ calendar_id?: string
559
+ hosts?: HostsRequest
560
+ title: string
561
+ description?: string
562
+ location?: string
563
+ start_at: string
564
+ end_at: string
565
+ is_all_day?: boolean
566
+ timezone?: string
567
+ attendees?: CalendarAttendeeRequest[]
568
+ is_conferencing_requested?: boolean
569
+ transparency?: EventTransparency
570
+ visibility?: EventVisibility
571
+ notify?: NotifyMode
572
+ is_exclusive?: boolean
573
+ type_key?: string
574
+ link_key?: string
575
+ record?: RecordRef
576
+ }
577
+
578
+ /**
579
+ * Partial update; an absent field is left as is. attendees present replaces
580
+ * the whole list (an empty list clears it).
581
+ */
582
+ export interface UpdateCalendarEventRequest {
583
+ title?: string
584
+ description?: string
585
+ location?: string
586
+ start_at?: string
587
+ end_at?: string
588
+ is_all_day?: boolean
589
+ timezone?: string
590
+ attendees?: CalendarAttendeeRequest[]
591
+ is_conferencing_requested?: boolean
592
+ transparency?: EventTransparency
593
+ visibility?: EventVisibility
594
+ notify?: NotifyMode
595
+ type_key?: string
596
+ record?: RecordRef
597
+ /** Removes the record back-link (an absent record cannot say so). */
598
+ is_record_cleared?: boolean
599
+ }
600
+
601
+ /** Records the caller's RSVP on an event they were invited to. */
602
+ export interface RespondCalendarEventRequest {
603
+ status: Exclude<ParticipationStatus, 'needs_action'>
604
+ comment?: string
605
+ }
606
+
607
+ /** Body of POST /me/calendar-connections/:id/sync. */
608
+ // ── Scheduling links + bookings (phase 6) ───────────────────────────────────
609
+
610
+ /** Which host a rescheduled link booking lands on. */
611
+ export type RescheduleHost = 'same' | 'any'
612
+
613
+ /** The entry point for taking a slot: hosts, assignment, governing type. Keyed by (org, key). */
614
+ export interface SchedulingLink {
615
+ org_id: string
616
+ key: string
617
+ name: string
618
+ /** Types offered: one = pre-defined, several = the booker picks (type_key then required). */
619
+ calendar_event_type_keys: string[]
620
+ host_user_ids: string[]
621
+ assignment: Assignment
622
+ is_public: boolean
623
+ is_enabled: boolean
624
+ /** The booker may pick one of the hosts on the page. */
625
+ is_host_selectable: boolean
626
+ reschedule_host: RescheduleHost
627
+ /** Computed: the public page address (absent without WEB_PUBLIC_URL). */
628
+ url?: string
629
+ created_at: string
630
+ created_by: UserRef
631
+ updated_at: string
632
+ updated_by: UserRef
633
+ }
634
+
635
+ export interface CreateSchedulingLinkRequest {
636
+ key: string
637
+ name: string
638
+ calendar_event_type_keys: string[]
639
+ host_user_ids: string[]
640
+ assignment: Assignment
641
+ is_public?: boolean
642
+ is_enabled?: boolean
643
+ is_host_selectable?: boolean
644
+ reschedule_host?: RescheduleHost
645
+ }
646
+
647
+ export interface UpdateSchedulingLinkRequest {
648
+ name?: string
649
+ calendar_event_type_keys?: string[]
650
+ host_user_ids?: string[]
651
+ assignment?: Assignment
652
+ is_public?: boolean
653
+ is_enabled?: boolean
654
+ is_host_selectable?: boolean
655
+ reschedule_host?: RescheduleHost
656
+ }
657
+
658
+ export interface ListSchedulingLinksQuery {
659
+ /** Links offering this type. */
660
+ type_key?: string
661
+ is_public?: boolean
662
+ is_enabled?: boolean
663
+ search?: string
664
+ page?: number
665
+ page_size?: number
666
+ sort_by?: string
667
+ sort_direction?: 'asc' | 'desc'
668
+ }
669
+
670
+ /** The person a link booking is for: by id (contact-bound page) or by email. */
671
+ export interface BookingContact {
672
+ id?: string
673
+ name?: string
674
+ email?: string
675
+ phone?: string
676
+ }
677
+
678
+ export interface BookSchedulingLinkRequest {
679
+ /** Picks the type on a multi-type link (optional when the link offers one). */
680
+ type_key?: string
681
+ start_at: string
682
+ timezone: string
683
+ contact?: BookingContact
684
+ notes?: string
685
+ host_user_id?: string
686
+ }
687
+
688
+ /** Authenticated booking answer: the event plus the one-time manage token. */
689
+ export interface BookSchedulingLinkResponse extends CalendarEvent {
690
+ manage_token: string
691
+ manage_url?: string
692
+ }
693
+
694
+ export interface PublicEventLocation {
695
+ kind: LocationKind
696
+ address?: string
697
+ instructions?: string
698
+ }
699
+
700
+ export interface PublicCalendarEventType {
701
+ key: string
702
+ name: string
703
+ description?: string
704
+ duration_minutes: number
705
+ location: PublicEventLocation
706
+ is_cancel_allowed: boolean
707
+ is_reschedule_allowed: boolean
708
+ cancel_notice_minutes: number
709
+ }
710
+
711
+ export interface PublicHost {
712
+ user_id: string
713
+ display_name: string
714
+ headline?: string
715
+ }
716
+
717
+ /** What the unauthenticated scheduling page sees of a link. */
718
+ export interface PublicSchedulingLink {
719
+ org_id: string
720
+ key: string
721
+ name: string
722
+ /** Types offered in link order; one = pre-defined, several = show a picker. */
723
+ types: PublicCalendarEventType[]
724
+ hosts: PublicHost[]
725
+ assignment: Assignment
726
+ is_host_selectable: boolean
727
+ reschedule_host: RescheduleHost
728
+ /** Opened with a contact_id the org knows: no name / email asked. */
729
+ is_contact_bound: boolean
730
+ }
731
+
732
+ export interface GetPublicSlotsQuery {
733
+ type_key?: string
734
+ from: string
735
+ to: string
736
+ timezone: string
737
+ host_user_id?: string
738
+ }
739
+
740
+ /** A booked event as its contact sees it on the manage page. */
741
+ export interface PublicCalendarEvent {
742
+ id: string
743
+ org_id: string
744
+ title: string
745
+ start_at: string
746
+ end_at: string
747
+ timezone?: string
748
+ status: EventStatus
749
+ location: EventLocation
750
+ join_url?: string
751
+ link: PublicSchedulingLink
752
+ host: PublicHost
753
+ contact: BookingContact
754
+ is_cancelled: boolean
755
+ deleted_at?: string
756
+ }
757
+
758
+ export interface PublicBookSchedulingLinkResponse extends PublicCalendarEvent {
759
+ manage_token: string
760
+ manage_url?: string
761
+ }
762
+
763
+ export interface CancelPublicCalendarEventRequest {
764
+ token: string
765
+ reason?: string
766
+ }
767
+
768
+ export interface ReschedulePublicCalendarEventRequest {
769
+ token: string
770
+ start_at: string
771
+ timezone: string
772
+ host_user_id?: string
773
+ }
774
+
775
+ /** Body of POST /me/calendar-connections/:id/sync (mirrors Go UpdateCalendarSyncRequest). */
776
+ export interface UpdateCalendarSyncRequest {
777
+ /** Drop the change cursors so the worker re-reads the whole window. */
778
+ is_rebaseline?: boolean
779
+ }
780
+
781
+ /** Scheduling-local page envelope ({meta, data}) — same shape as the conversation module's. */
782
+ export interface ListResponse<T> {
783
+ meta: ResponseMeta
784
+ data: T[]
785
+ }
786
+
787
+ /** Window reads carry no pagination — the window itself bounds the result. */
788
+ export interface CalendarEventsResponse {
789
+ data: CalendarEvent[]
790
+ }