Skip to main content

pidgr_proto/pidgr/v1/
pidgr.v1.rs

1// @generated
2// This file is @generated by prost-build.
3// ─── Messages ───────────────────────────────────────────────────────────────
4
5/// Request to submit a user action on a delivered message.
6#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7pub struct SubmitActionRequest {
8    /// ID of the delivery the user is acting on.
9    /// Constraints: UUID format (36 characters).
10    #[prost(string, tag="1")]
11    pub delivery_id: ::prost::alloc::string::String,
12    /// ID of the action being performed (matches MessageAction.id).
13    /// Constraints: Max length 100 characters.
14    #[prost(string, tag="2")]
15    pub action_id: ::prost::alloc::string::String,
16    /// Optional action-specific payload (e.g. poll response data). Empty for ACK.
17    /// Constraints: Max size 10000 bytes.
18    #[prost(bytes="vec", tag="3")]
19    pub payload: ::prost::alloc::vec::Vec<u8>,
20}
21/// Response after submitting an action.
22#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
23pub struct SubmitActionResponse {
24    /// Whether the action was successfully recorded and forwarded to the workflow.
25    #[prost(bool, tag="1")]
26    pub success: bool,
27}
28// ─── Messages ───────────────────────────────────────────────────────────────
29
30/// A single channel dispatch event for the audit trail. Append-only; the
31/// receiver enforces idempotency on terminal states via a partial unique index
32/// on (campaign_id, recipient_user_id, channel, step_kind).
33#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
34pub struct ChannelEvent {
35    #[prost(string, tag="1")]
36    pub org_id: ::prost::alloc::string::String,
37    #[prost(string, tag="2")]
38    pub campaign_id: ::prost::alloc::string::String,
39    #[prost(string, tag="3")]
40    pub recipient_user_id: ::prost::alloc::string::String,
41    #[prost(enumeration="ChannelName", tag="4")]
42    pub channel: i32,
43    #[prost(enumeration="ChannelStepKind", tag="5")]
44    pub step_kind: i32,
45    #[prost(enumeration="ChannelEventStatus", tag="6")]
46    pub status: i32,
47    /// Set only when status = SKIPPED. UNSPECIFIED in all other cases.
48    #[prost(enumeration="ChannelSkipReason", tag="7")]
49    pub skip_reason: i32,
50    /// Provider's identifier for this dispatch. Empty for SKIPPED events.
51    #[prost(string, tag="8")]
52    pub provider_message_id: ::prost::alloc::string::String,
53    /// Cost in micros (1/1000000 of a USD). Zero for absorbed channels.
54    /// Negative is invalid.
55    #[prost(int64, tag="9")]
56    pub cost_micros: i64,
57    /// Free-form provider error payload on FAILED. JSON-encoded; opaque to
58    /// the platform.
59    #[prost(string, tag="10")]
60    pub metadata_json: ::prost::alloc::string::String,
61    #[prost(message, optional, tag="11")]
62    pub occurred_at: ::core::option::Option<::prost_types::Timestamp>,
63}
64#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
65pub struct RecordChannelEventRequest {
66    #[prost(message, optional, tag="1")]
67    pub event: ::core::option::Option<ChannelEvent>,
68}
69#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
70pub struct RecordChannelEventResponse {
71    /// True if the row was inserted. False if rejected as a duplicate of an
72    /// existing terminal-state row.
73    #[prost(bool, tag="1")]
74    pub accepted: bool,
75    /// "duplicate" when accepted=false and the partial unique index rejected
76    /// the insert. Empty when accepted=true.
77    #[prost(string, tag="2")]
78    pub reason: ::prost::alloc::string::String,
79}
80#[derive(Clone, PartialEq, ::prost::Message)]
81pub struct RecordChannelEventBatchRequest {
82    #[prost(message, repeated, tag="1")]
83    pub events: ::prost::alloc::vec::Vec<ChannelEvent>,
84}
85/// Per-event result inside a batch. Order matches the request's events list.
86#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
87pub struct RecordChannelEventBatchResult {
88    #[prost(bool, tag="1")]
89    pub accepted: bool,
90    #[prost(string, tag="2")]
91    pub reason: ::prost::alloc::string::String,
92}
93#[derive(Clone, PartialEq, ::prost::Message)]
94pub struct RecordChannelEventBatchResponse {
95    #[prost(message, repeated, tag="1")]
96    pub results: ::prost::alloc::vec::Vec<RecordChannelEventBatchResult>,
97}
98// ─── Enums ──────────────────────────────────────────────────────────────────
99
100/// Third-party notification channel for reminder + escalation dispatch.
101///
102/// Push is intentionally NOT in this enum. Push is the primary channel; it
103/// always fires alongside any third-party channels. The third-party channels
104/// here are additive. Channels carry only a deeplink notification — message
105/// content stays in the platform.
106#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
107#[repr(i32)]
108pub enum ChannelName {
109    Unspecified = 0,
110    Email = 1,
111    Webhook = 2,
112    Telegram = 3,
113    Slack = 4,
114    Sms = 5,
115    Whatsapp = 6,
116    MicrosoftTeams = 7,
117    Line = 8,
118}
119impl ChannelName {
120    /// String value of the enum field names used in the ProtoBuf definition.
121    ///
122    /// The values are not transformed in any way and thus are considered stable
123    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
124    pub fn as_str_name(&self) -> &'static str {
125        match self {
126            Self::Unspecified => "CHANNEL_NAME_UNSPECIFIED",
127            Self::Email => "CHANNEL_NAME_EMAIL",
128            Self::Webhook => "CHANNEL_NAME_WEBHOOK",
129            Self::Telegram => "CHANNEL_NAME_TELEGRAM",
130            Self::Slack => "CHANNEL_NAME_SLACK",
131            Self::Sms => "CHANNEL_NAME_SMS",
132            Self::Whatsapp => "CHANNEL_NAME_WHATSAPP",
133            Self::MicrosoftTeams => "CHANNEL_NAME_MICROSOFT_TEAMS",
134            Self::Line => "CHANNEL_NAME_LINE",
135        }
136    }
137    /// Creates an enum from field names used in the ProtoBuf definition.
138    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
139        match value {
140            "CHANNEL_NAME_UNSPECIFIED" => Some(Self::Unspecified),
141            "CHANNEL_NAME_EMAIL" => Some(Self::Email),
142            "CHANNEL_NAME_WEBHOOK" => Some(Self::Webhook),
143            "CHANNEL_NAME_TELEGRAM" => Some(Self::Telegram),
144            "CHANNEL_NAME_SLACK" => Some(Self::Slack),
145            "CHANNEL_NAME_SMS" => Some(Self::Sms),
146            "CHANNEL_NAME_WHATSAPP" => Some(Self::Whatsapp),
147            "CHANNEL_NAME_MICROSOFT_TEAMS" => Some(Self::MicrosoftTeams),
148            "CHANNEL_NAME_LINE" => Some(Self::Line),
149            _ => None,
150        }
151    }
152}
153/// Workflow step kind that triggered the channel dispatch. Different step
154/// kinds for the same (campaign, recipient, channel) tuple are treated as
155/// distinct dispatch events for idempotency purposes.
156#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
157#[repr(i32)]
158pub enum ChannelStepKind {
159    Unspecified = 0,
160    Reminder = 1,
161    Escalation = 2,
162}
163impl ChannelStepKind {
164    /// String value of the enum field names used in the ProtoBuf definition.
165    ///
166    /// The values are not transformed in any way and thus are considered stable
167    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
168    pub fn as_str_name(&self) -> &'static str {
169        match self {
170            Self::Unspecified => "CHANNEL_STEP_KIND_UNSPECIFIED",
171            Self::Reminder => "CHANNEL_STEP_KIND_REMINDER",
172            Self::Escalation => "CHANNEL_STEP_KIND_ESCALATION",
173        }
174    }
175    /// Creates an enum from field names used in the ProtoBuf definition.
176    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
177        match value {
178            "CHANNEL_STEP_KIND_UNSPECIFIED" => Some(Self::Unspecified),
179            "CHANNEL_STEP_KIND_REMINDER" => Some(Self::Reminder),
180            "CHANNEL_STEP_KIND_ESCALATION" => Some(Self::Escalation),
181            _ => None,
182        }
183    }
184}
185/// Status of a channel dispatch attempt. The table is append-only — each state
186/// transition (e.g. SENT → DELIVERED via provider webhook) is its own row keyed
187/// off provider_message_id, not an UPDATE.
188#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
189#[repr(i32)]
190pub enum ChannelEventStatus {
191    Unspecified = 0,
192    Sent = 1,
193    Delivered = 2,
194    Opened = 3,
195    Clicked = 4,
196    Bounced = 5,
197    Failed = 6,
198    Skipped = 7,
199}
200impl ChannelEventStatus {
201    /// String value of the enum field names used in the ProtoBuf definition.
202    ///
203    /// The values are not transformed in any way and thus are considered stable
204    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
205    pub fn as_str_name(&self) -> &'static str {
206        match self {
207            Self::Unspecified => "CHANNEL_EVENT_STATUS_UNSPECIFIED",
208            Self::Sent => "CHANNEL_EVENT_STATUS_SENT",
209            Self::Delivered => "CHANNEL_EVENT_STATUS_DELIVERED",
210            Self::Opened => "CHANNEL_EVENT_STATUS_OPENED",
211            Self::Clicked => "CHANNEL_EVENT_STATUS_CLICKED",
212            Self::Bounced => "CHANNEL_EVENT_STATUS_BOUNCED",
213            Self::Failed => "CHANNEL_EVENT_STATUS_FAILED",
214            Self::Skipped => "CHANNEL_EVENT_STATUS_SKIPPED",
215        }
216    }
217    /// Creates an enum from field names used in the ProtoBuf definition.
218    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
219        match value {
220            "CHANNEL_EVENT_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
221            "CHANNEL_EVENT_STATUS_SENT" => Some(Self::Sent),
222            "CHANNEL_EVENT_STATUS_DELIVERED" => Some(Self::Delivered),
223            "CHANNEL_EVENT_STATUS_OPENED" => Some(Self::Opened),
224            "CHANNEL_EVENT_STATUS_CLICKED" => Some(Self::Clicked),
225            "CHANNEL_EVENT_STATUS_BOUNCED" => Some(Self::Bounced),
226            "CHANNEL_EVENT_STATUS_FAILED" => Some(Self::Failed),
227            "CHANNEL_EVENT_STATUS_SKIPPED" => Some(Self::Skipped),
228            _ => None,
229        }
230    }
231}
232/// Reason a dispatch was SKIPPED rather than attempted. Set when status is
233/// CHANNEL_EVENT_STATUS_SKIPPED; UNSPECIFIED otherwise.
234#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
235#[repr(i32)]
236pub enum ChannelSkipReason {
237    Unspecified = 0,
238    OptedOut = 1,
239    RegionBlocked = 2,
240    CostCapExceeded = 3,
241    NoIdentifier = 4,
242}
243impl ChannelSkipReason {
244    /// String value of the enum field names used in the ProtoBuf definition.
245    ///
246    /// The values are not transformed in any way and thus are considered stable
247    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
248    pub fn as_str_name(&self) -> &'static str {
249        match self {
250            Self::Unspecified => "CHANNEL_SKIP_REASON_UNSPECIFIED",
251            Self::OptedOut => "CHANNEL_SKIP_REASON_OPTED_OUT",
252            Self::RegionBlocked => "CHANNEL_SKIP_REASON_REGION_BLOCKED",
253            Self::CostCapExceeded => "CHANNEL_SKIP_REASON_COST_CAP_EXCEEDED",
254            Self::NoIdentifier => "CHANNEL_SKIP_REASON_NO_IDENTIFIER",
255        }
256    }
257    /// Creates an enum from field names used in the ProtoBuf definition.
258    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
259        match value {
260            "CHANNEL_SKIP_REASON_UNSPECIFIED" => Some(Self::Unspecified),
261            "CHANNEL_SKIP_REASON_OPTED_OUT" => Some(Self::OptedOut),
262            "CHANNEL_SKIP_REASON_REGION_BLOCKED" => Some(Self::RegionBlocked),
263            "CHANNEL_SKIP_REASON_COST_CAP_EXCEEDED" => Some(Self::CostCapExceeded),
264            "CHANNEL_SKIP_REASON_NO_IDENTIFIER" => Some(Self::NoIdentifier),
265            _ => None,
266        }
267    }
268}
269/// A named role within an organization with a set of permissions.
270#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
271pub struct Role {
272    /// Unique identifier for the role.
273    #[prost(string, tag="1")]
274    pub id: ::prost::alloc::string::String,
275    /// URL-safe slug (unique within the organization, e.g. "admin", "manager").
276    #[prost(string, tag="2")]
277    pub slug: ::prost::alloc::string::String,
278    /// Human-readable display name.
279    #[prost(string, tag="3")]
280    pub name: ::prost::alloc::string::String,
281    /// Whether this role was seeded by the system on organization creation.
282    #[prost(bool, tag="4")]
283    pub is_default: bool,
284    /// Permissions granted to users with this role.
285    #[prost(enumeration="Permission", repeated, tag="5")]
286    pub permissions: ::prost::alloc::vec::Vec<i32>,
287    /// Whether this role is system-managed and immutable (e.g. super_admin).
288    #[prost(bool, tag="6")]
289    pub is_system: bool,
290}
291// ─── Pagination ─────────────────────────────────────────────────────────────
292
293/// Cursor-based pagination parameters for list requests.
294#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
295pub struct Pagination {
296    /// Maximum number of items to return per page.
297    #[prost(int32, tag="1")]
298    pub page_size: i32,
299    /// Opaque token from a previous response to fetch the next page.
300    #[prost(string, tag="2")]
301    pub page_token: ::prost::alloc::string::String,
302}
303/// Pagination metadata returned alongside list responses.
304#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
305pub struct PaginationMeta {
306    /// Token to pass in the next request to get the following page. Empty if no more pages.
307    #[prost(string, tag="1")]
308    pub next_page_token: ::prost::alloc::string::String,
309    /// Total number of items matching the query (across all pages).
310    #[prost(int32, tag="2")]
311    pub total_count: i32,
312}
313// ─── Message & Action Model ─────────────────────────────────────────────────
314
315/// An action button attached to a message that a recipient can interact with.
316#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
317pub struct MessageAction {
318    /// Unique identifier for this action within the message.
319    #[prost(string, tag="1")]
320    pub id: ::prost::alloc::string::String,
321    /// The type of action (e.g. ACK).
322    #[prost(enumeration="ActionType", tag="2")]
323    pub r#type: i32,
324    /// Display label shown to the recipient (e.g. "Got it").
325    /// Constraints: Max length 50 characters.
326    #[prost(string, tag="3")]
327    pub label: ::prost::alloc::string::String,
328}
329/// Canonical message type used across rendering, inbox, and delivery.
330/// Represents the fully rendered content delivered to a recipient.
331#[derive(Clone, PartialEq, ::prost::Message)]
332pub struct Message {
333    /// SHA-256 hash of the rendered content, used as a content-addressable ID.
334    #[prost(string, tag="1")]
335    pub content_id: ::prost::alloc::string::String,
336    /// ID of the campaign this message belongs to.
337    #[prost(string, tag="2")]
338    pub campaign_id: ::prost::alloc::string::String,
339    /// Display name of the sender (e.g. organization or campaign name).
340    /// Constraints: Max length 200 characters.
341    #[prost(string, tag="3")]
342    pub sender_name: ::prost::alloc::string::String,
343    /// Short one-line summary shown in notification banners.
344    /// Constraints: Max length 500 characters.
345    #[prost(string, tag="4")]
346    pub summary: ::prost::alloc::string::String,
347    /// Preview text shown in inbox list views.
348    /// Constraints: Max length 500 characters.
349    #[prost(string, tag="5")]
350    pub preview: ::prost::alloc::string::String,
351    /// Full message body content.
352    /// Constraints: Max length 100000 characters.
353    #[prost(string, tag="6")]
354    pub body: ::prost::alloc::string::String,
355    /// Whether this message requires immediate attention from the recipient.
356    #[prost(bool, tag="7")]
357    pub critical: bool,
358    /// Actions available to the recipient (e.g. acknowledge button).
359    #[prost(message, repeated, tag="8")]
360    pub actions: ::prost::alloc::vec::Vec<MessageAction>,
361    /// Timestamp when the message was created.
362    #[prost(message, optional, tag="9")]
363    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
364    /// User-facing title of the message (resolved from campaign or template).
365    /// Constraints: Max length 200 characters.
366    #[prost(string, tag="10")]
367    pub title: ::prost::alloc::string::String,
368}
369// ─── Workflow Definition Model ──────────────────────────────────────────────
370
371/// A data-driven workflow represented as a directed acyclic graph (DAG) of steps.
372/// Defines the automation logic for a campaign's lifecycle.
373/// Backend MUST validate the graph is a DAG (no cycles) before execution.
374#[derive(Clone, PartialEq, ::prost::Message)]
375pub struct WorkflowDefinition {
376    /// Ordered list of steps in the workflow DAG.
377    /// Constraints: Max 100 steps. Backend MUST validate the graph is a DAG (no cycles).
378    #[prost(message, repeated, tag="1")]
379    pub steps: ::prost::alloc::vec::Vec<WorkflowStep>,
380}
381/// A single step in a workflow DAG with typed configuration and transitions.
382#[derive(Clone, PartialEq, ::prost::Message)]
383pub struct WorkflowStep {
384    /// Unique identifier for this step within the workflow.
385    #[prost(string, tag="1")]
386    pub id: ::prost::alloc::string::String,
387    /// The type of operation this step performs.
388    #[prost(enumeration="StepType", tag="2")]
389    pub r#type: i32,
390    /// Map of outcome labels to the next step ID (e.g. "completed" -> "step_3").
391    /// Constraints: Max 10 transitions per step.
392    #[prost(map="string, string", tag="7")]
393    pub transitions: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
394    /// Step-specific configuration — exactly one must be set, matching the type.
395    #[prost(oneof="workflow_step::Config", tags="3, 4, 5, 6, 8")]
396    pub config: ::core::option::Option<workflow_step::Config>,
397}
398/// Nested message and enum types in `WorkflowStep`.
399pub mod workflow_step {
400    /// Step-specific configuration — exactly one must be set, matching the type.
401    #[derive(Clone, PartialEq, ::prost::Oneof)]
402    pub enum Config {
403        /// Configuration for SEND_NOTIFICATION steps.
404        #[prost(message, tag="3")]
405        SendNotification(super::SendNotificationConfig),
406        /// Configuration for DEADLINE_CHECK steps.
407        #[prost(message, tag="4")]
408        DeadlineCheck(super::DeadlineCheckConfig),
409        /// Configuration for SEND_REMINDER steps.
410        #[prost(message, tag="5")]
411        SendReminder(super::SendReminderConfig),
412        /// Configuration for CALL_WEBHOOK steps.
413        #[prost(message, tag="6")]
414        CallWebhook(super::CallWebhookConfig),
415        /// Configuration for STEP_TYPE_ESCALATE steps.
416        #[prost(message, tag="8")]
417        EscalateConfig(super::EscalateConfig),
418    }
419}
420/// Configuration for a step that sends the initial push notification.
421#[derive(Clone, PartialEq, ::prost::Message)]
422pub struct SendNotificationConfig {
423    /// Notification delivery type (e.g. "push").
424    /// Constraints: Accepted values: "push". Max length 50 characters.
425    #[prost(string, tag="1")]
426    pub r#type: ::prost::alloc::string::String,
427    /// ID of the template to use for this step's notification.
428    /// Empty falls back to campaign-level template_id.
429    /// Constraints: Max length 36 characters (UUID).
430    #[prost(string, tag="2")]
431    pub template_id: ::prost::alloc::string::String,
432    /// Pinned template version for this step.
433    /// 0 falls back to campaign-level template_version.
434    #[prost(int32, tag="3")]
435    pub template_version: i32,
436    /// Display label for the action button (e.g. "Acknowledge", "Got it").
437    /// Constraints: Max length 50 characters.
438    #[prost(string, tag="4")]
439    pub action_label: ::prost::alloc::string::String,
440    /// Action type for this step's message button.
441    #[prost(enumeration="ActionType", tag="5")]
442    pub action_type: i32,
443    /// Values for custom-sourced template variables specific to this step.
444    /// Constraints: Max 100 entries. Key max length 100 characters, value max length 10000 characters.
445    #[prost(map="string, string", tag="6")]
446    pub custom_variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
447}
448/// Configuration for a deadline-based timer step that sleeps for a configured
449/// delay before proceeding. Acknowledgments happen independently at the delivery
450/// level and are evaluated by subsequent steps (e.g. SEND_REMINDER).
451#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
452pub struct DeadlineCheckConfig {
453    /// Duration string for the deadline delay (e.g. "120h", "72h").
454    /// Constraints: Valid range 1m to 8760h (1 year).
455    #[prost(string, tag="1")]
456    pub delay: ::prost::alloc::string::String,
457}
458/// Configuration for a step that sends a one-time reminder to non-responsive recipients.
459#[derive(Clone, PartialEq, ::prost::Message)]
460pub struct SendReminderConfig {
461    /// Reminder delivery type (e.g. "push").
462    /// Constraints: Accepted values: "push". Max length 50 characters.
463    #[prost(string, tag="1")]
464    pub r#type: ::prost::alloc::string::String,
465    /// Additional third-party channels to dispatch the reminder through
466    /// alongside the primary push notification. Empty = push-only behaviour
467    /// (the platform's historical default; no surprise for existing
468    /// workflows). Each entry produces an independent dispatch attempt
469    /// recorded in `channel_events`; per-org configuration in
470    /// pidgr-integrations decides which channels are eligible at runtime.
471    #[prost(enumeration="ChannelName", repeated, tag="4")]
472    pub third_party_channels: ::prost::alloc::vec::Vec<i32>,
473    /// Third parties to loop in when this reminder fires. Each resolved
474    /// target receives a passive inbox delivery (no action button) plus a
475    /// fan-out via the same `third_party_channels` list as the employee
476    /// reminder. The delivery auto-dismisses when the original recipient
477    /// acknowledges the campaign.
478    ///
479    /// Each entry reuses the existing `EscalationTarget` shape
480    /// (USER / GROUP / MANAGER / ROLE). When `type` is MANAGER, `target_id`
481    /// is empty and is resolved at runtime from the original recipient's
482    /// `manager_id`. Self-targets (resolved user_id == original recipient)
483    /// are dropped at dispatch time.
484    /// Constraints: Max 5 entries.
485    #[prost(message, repeated, tag="5")]
486    pub notify_targets: ::prost::alloc::vec::Vec<EscalationTarget>,
487}
488/// Configuration for a step that calls an external webhook.
489#[derive(Clone, PartialEq, ::prost::Message)]
490pub struct CallWebhookConfig {
491    /// Human-readable name for this webhook (for logging/display).
492    /// Constraints: Max length 200 characters.
493    #[prost(string, tag="1")]
494    pub name: ::prost::alloc::string::String,
495    /// URL to POST campaign context to.
496    /// Constraints: Max length 2048 characters.
497    /// Security: HTTPS required in production. Backend MUST reject private,
498    /// loopback, and link-local addresses to prevent SSRF attacks.
499    #[prost(string, tag="2")]
500    pub url: ::prost::alloc::string::String,
501    /// Additional HTTP headers to include in the webhook request.
502    /// Constraints: Max 20 entries. Key max length 200 characters, value max length 2000 characters.
503    #[prost(map="string, string", tag="3")]
504    pub headers: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
505}
506/// A target for escalation — who should be notified when escalation fires.
507#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
508pub struct EscalationTarget {
509    /// Type of target.
510    #[prost(enumeration="EscalationTargetType", tag="1")]
511    pub r#type: i32,
512    /// ID of the target (user_id, group_id, or role_id).
513    /// Empty for MANAGER type (resolved at runtime from recipient's manager_id).
514    #[prost(string, tag="2")]
515    pub target_id: ::prost::alloc::string::String,
516}
517/// Configuration for an escalation step in the workflow DAG.
518#[derive(Clone, PartialEq, ::prost::Message)]
519pub struct EscalateConfig {
520    /// Condition that triggers escalation.
521    #[prost(enumeration="EscalationCondition", tag="1")]
522    pub condition: i32,
523    /// Targets to notify when escalation fires.
524    #[prost(message, repeated, tag="2")]
525    pub targets: ::prost::alloc::vec::Vec<EscalationTarget>,
526    /// Number of times to repeat this escalation before moving to the next step.
527    /// Constraints: Max 5.
528    #[prost(int32, tag="3")]
529    pub repeat_count: i32,
530    /// Minutes between repeat attempts.
531    #[prost(int32, tag="4")]
532    pub repeat_interval_minutes: i32,
533    /// Behavior mode for this escalation. UNSPECIFIED is normalized to DELIVER.
534    #[prost(enumeration="EscalateMode", tag="5")]
535    pub mode: i32,
536    /// Additional third-party channels to dispatch the escalation through
537    /// alongside the primary push / delivery side effect. Empty = no
538    /// third-party fan-out (existing behaviour). Each entry produces an
539    /// independent dispatch attempt recorded in `channel_events`. ALERT_ONLY
540    /// and DELIVER modes both support third-party fan-out — the channel
541    /// adapters render the alert content from the campaign + a
542    /// mode-aware copy variant.
543    #[prost(enumeration="ChannelName", repeated, tag="6")]
544    pub third_party_channels: ::prost::alloc::vec::Vec<i32>,
545}
546// ─── Status Enums ───────────────────────────────────────────────────────────
547
548/// Lifecycle status of a campaign.
549#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
550#[repr(i32)]
551pub enum CampaignStatus {
552    /// Default value; not a valid status.
553    Unspecified = 0,
554    /// Campaign has been created but not yet started.
555    Created = 1,
556    /// Campaign is actively delivering messages and processing actions.
557    Running = 2,
558    /// All recipients have been processed; campaign is finished.
559    Completed = 3,
560    /// Campaign terminated due to an unrecoverable error.
561    Failed = 4,
562    /// Campaign was manually cancelled before completion.
563    Cancelled = 5,
564}
565impl CampaignStatus {
566    /// String value of the enum field names used in the ProtoBuf definition.
567    ///
568    /// The values are not transformed in any way and thus are considered stable
569    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
570    pub fn as_str_name(&self) -> &'static str {
571        match self {
572            Self::Unspecified => "CAMPAIGN_STATUS_UNSPECIFIED",
573            Self::Created => "CAMPAIGN_STATUS_CREATED",
574            Self::Running => "CAMPAIGN_STATUS_RUNNING",
575            Self::Completed => "CAMPAIGN_STATUS_COMPLETED",
576            Self::Failed => "CAMPAIGN_STATUS_FAILED",
577            Self::Cancelled => "CAMPAIGN_STATUS_CANCELLED",
578        }
579    }
580    /// Creates an enum from field names used in the ProtoBuf definition.
581    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
582        match value {
583            "CAMPAIGN_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
584            "CAMPAIGN_STATUS_CREATED" => Some(Self::Created),
585            "CAMPAIGN_STATUS_RUNNING" => Some(Self::Running),
586            "CAMPAIGN_STATUS_COMPLETED" => Some(Self::Completed),
587            "CAMPAIGN_STATUS_FAILED" => Some(Self::Failed),
588            "CAMPAIGN_STATUS_CANCELLED" => Some(Self::Cancelled),
589            _ => None,
590        }
591    }
592}
593/// Delivery status for a single message sent to a recipient.
594#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
595#[repr(i32)]
596pub enum DeliveryStatus {
597    /// Default value; not a valid status.
598    Unspecified = 0,
599    /// Message is queued but has not been sent yet.
600    Pending = 1,
601    /// Push notification was sent to the delivery provider.
602    Sent = 2,
603    /// Message was confirmed delivered to the device.
604    Delivered = 3,
605    /// Recipient completed the required action (e.g. acknowledged).
606    Acknowledged = 4,
607    /// Recipient did not act before the deadline.
608    Missed = 5,
609    /// Recipient has no registered device; delivery was skipped.
610    NoDevice = 6,
611    /// Delivery failed due to a provider or system error.
612    Failed = 7,
613}
614impl DeliveryStatus {
615    /// String value of the enum field names used in the ProtoBuf definition.
616    ///
617    /// The values are not transformed in any way and thus are considered stable
618    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
619    pub fn as_str_name(&self) -> &'static str {
620        match self {
621            Self::Unspecified => "DELIVERY_STATUS_UNSPECIFIED",
622            Self::Pending => "DELIVERY_STATUS_PENDING",
623            Self::Sent => "DELIVERY_STATUS_SENT",
624            Self::Delivered => "DELIVERY_STATUS_DELIVERED",
625            Self::Acknowledged => "DELIVERY_STATUS_ACKNOWLEDGED",
626            Self::Missed => "DELIVERY_STATUS_MISSED",
627            Self::NoDevice => "DELIVERY_STATUS_NO_DEVICE",
628            Self::Failed => "DELIVERY_STATUS_FAILED",
629        }
630    }
631    /// Creates an enum from field names used in the ProtoBuf definition.
632    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
633        match value {
634            "DELIVERY_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
635            "DELIVERY_STATUS_PENDING" => Some(Self::Pending),
636            "DELIVERY_STATUS_SENT" => Some(Self::Sent),
637            "DELIVERY_STATUS_DELIVERED" => Some(Self::Delivered),
638            "DELIVERY_STATUS_ACKNOWLEDGED" => Some(Self::Acknowledged),
639            "DELIVERY_STATUS_MISSED" => Some(Self::Missed),
640            "DELIVERY_STATUS_NO_DEVICE" => Some(Self::NoDevice),
641            "DELIVERY_STATUS_FAILED" => Some(Self::Failed),
642            _ => None,
643        }
644    }
645}
646/// Mobile platform for device registration.
647#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
648#[repr(i32)]
649pub enum Platform {
650    /// Default value; not a valid platform.
651    Unspecified = 0,
652    /// Apple iOS.
653    Ios = 1,
654    /// Google Android.
655    Android = 2,
656}
657impl Platform {
658    /// String value of the enum field names used in the ProtoBuf definition.
659    ///
660    /// The values are not transformed in any way and thus are considered stable
661    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
662    pub fn as_str_name(&self) -> &'static str {
663        match self {
664            Self::Unspecified => "PLATFORM_UNSPECIFIED",
665            Self::Ios => "PLATFORM_IOS",
666            Self::Android => "PLATFORM_ANDROID",
667        }
668    }
669    /// Creates an enum from field names used in the ProtoBuf definition.
670    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
671        match value {
672            "PLATFORM_UNSPECIFIED" => Some(Self::Unspecified),
673            "PLATFORM_IOS" => Some(Self::Ios),
674            "PLATFORM_ANDROID" => Some(Self::Android),
675            _ => None,
676        }
677    }
678}
679/// Granular permission for authorization checks.
680/// Stored in the database as enum names (e.g. "PERMISSION_ORG_READ").
681/// New values MUST be appended with the next sequential number; existing values
682/// MUST NOT be renumbered or removed (enforced by buf breaking).
683#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
684#[repr(i32)]
685pub enum Permission {
686    /// Default value; not a valid permission.
687    Unspecified = 0,
688    /// View organization settings.
689    OrgRead = 1,
690    /// Modify organization settings.
691    OrgWrite = 2,
692    /// View organization members.
693    MembersRead = 3,
694    /// Invite new users to the organization.
695    MembersInvite = 4,
696    /// Change user roles, deactivate users.
697    MembersManage = 5,
698    /// View campaigns and deliveries.
699    CampaignsRead = 6,
700    /// Create and edit campaigns.
701    CampaignsWrite = 7,
702    /// Start campaign execution.
703    CampaignsStart = 8,
704    /// View templates.
705    TemplatesRead = 9,
706    /// Create and edit templates.
707    TemplatesWrite = 10,
708    /// View inbox messages and deliveries.
709    InboxRead = 11,
710    /// Submit actions on deliveries.
711    InboxAct = 12,
712    /// View all groups in the organization.
713    GroupsAllRead = 13,
714    /// Create, edit, delete groups the caller created, manage own group membership.
715    GroupsWrite = 14,
716    /// Create, edit, delete any group in the organization, manage any group membership.
717    GroupsAllWrite = 15,
718    /// View all teams (organizational units) in the organization.
719    TeamsAllRead = 16,
720    /// Create, edit, delete teams the caller created, manage own team membership.
721    TeamsWrite = 17,
722    /// Create, edit, delete any team in the organization, manage any team membership.
723    TeamsAllWrite = 18,
724    /// View privacy requests (exports, deletions) for the organization.
725    PrivacyRead = 19,
726    /// Schedule deletions, export user data, restrict processing.
727    PrivacyWrite = 20,
728    /// View audit trail events for the organization.
729    AuditRead = 21,
730    /// Review and approve template translations.
731    TemplatesReview = 22,
732    /// Cross-organization read access for platform-level support operations.
733    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
734    PlatformSupport = 23,
735    /// Manage platform access codes (generation, listing, revocation).
736    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
737    PlatformAccessCodes = 24,
738    /// Provision and manage organizations at the platform level.
739    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
740    PlatformProvision = 25,
741    /// Take abuse-response actions against organizations (suspend, revoke, quota overrides).
742    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
743    PlatformAbuseResponse = 26,
744    /// Write subprocessor and compliance records at the platform level.
745    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
746    PlatformComplianceWrite = 27,
747}
748impl Permission {
749    /// String value of the enum field names used in the ProtoBuf definition.
750    ///
751    /// The values are not transformed in any way and thus are considered stable
752    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
753    pub fn as_str_name(&self) -> &'static str {
754        match self {
755            Self::Unspecified => "PERMISSION_UNSPECIFIED",
756            Self::OrgRead => "PERMISSION_ORG_READ",
757            Self::OrgWrite => "PERMISSION_ORG_WRITE",
758            Self::MembersRead => "PERMISSION_MEMBERS_READ",
759            Self::MembersInvite => "PERMISSION_MEMBERS_INVITE",
760            Self::MembersManage => "PERMISSION_MEMBERS_MANAGE",
761            Self::CampaignsRead => "PERMISSION_CAMPAIGNS_READ",
762            Self::CampaignsWrite => "PERMISSION_CAMPAIGNS_WRITE",
763            Self::CampaignsStart => "PERMISSION_CAMPAIGNS_START",
764            Self::TemplatesRead => "PERMISSION_TEMPLATES_READ",
765            Self::TemplatesWrite => "PERMISSION_TEMPLATES_WRITE",
766            Self::InboxRead => "PERMISSION_INBOX_READ",
767            Self::InboxAct => "PERMISSION_INBOX_ACT",
768            Self::GroupsAllRead => "PERMISSION_GROUPS_ALL_READ",
769            Self::GroupsWrite => "PERMISSION_GROUPS_WRITE",
770            Self::GroupsAllWrite => "PERMISSION_GROUPS_ALL_WRITE",
771            Self::TeamsAllRead => "PERMISSION_TEAMS_ALL_READ",
772            Self::TeamsWrite => "PERMISSION_TEAMS_WRITE",
773            Self::TeamsAllWrite => "PERMISSION_TEAMS_ALL_WRITE",
774            Self::PrivacyRead => "PERMISSION_PRIVACY_READ",
775            Self::PrivacyWrite => "PERMISSION_PRIVACY_WRITE",
776            Self::AuditRead => "PERMISSION_AUDIT_READ",
777            Self::TemplatesReview => "PERMISSION_TEMPLATES_REVIEW",
778            Self::PlatformSupport => "PERMISSION_PLATFORM_SUPPORT",
779            Self::PlatformAccessCodes => "PERMISSION_PLATFORM_ACCESS_CODES",
780            Self::PlatformProvision => "PERMISSION_PLATFORM_PROVISION",
781            Self::PlatformAbuseResponse => "PERMISSION_PLATFORM_ABUSE_RESPONSE",
782            Self::PlatformComplianceWrite => "PERMISSION_PLATFORM_COMPLIANCE_WRITE",
783        }
784    }
785    /// Creates an enum from field names used in the ProtoBuf definition.
786    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
787        match value {
788            "PERMISSION_UNSPECIFIED" => Some(Self::Unspecified),
789            "PERMISSION_ORG_READ" => Some(Self::OrgRead),
790            "PERMISSION_ORG_WRITE" => Some(Self::OrgWrite),
791            "PERMISSION_MEMBERS_READ" => Some(Self::MembersRead),
792            "PERMISSION_MEMBERS_INVITE" => Some(Self::MembersInvite),
793            "PERMISSION_MEMBERS_MANAGE" => Some(Self::MembersManage),
794            "PERMISSION_CAMPAIGNS_READ" => Some(Self::CampaignsRead),
795            "PERMISSION_CAMPAIGNS_WRITE" => Some(Self::CampaignsWrite),
796            "PERMISSION_CAMPAIGNS_START" => Some(Self::CampaignsStart),
797            "PERMISSION_TEMPLATES_READ" => Some(Self::TemplatesRead),
798            "PERMISSION_TEMPLATES_WRITE" => Some(Self::TemplatesWrite),
799            "PERMISSION_INBOX_READ" => Some(Self::InboxRead),
800            "PERMISSION_INBOX_ACT" => Some(Self::InboxAct),
801            "PERMISSION_GROUPS_ALL_READ" => Some(Self::GroupsAllRead),
802            "PERMISSION_GROUPS_WRITE" => Some(Self::GroupsWrite),
803            "PERMISSION_GROUPS_ALL_WRITE" => Some(Self::GroupsAllWrite),
804            "PERMISSION_TEAMS_ALL_READ" => Some(Self::TeamsAllRead),
805            "PERMISSION_TEAMS_WRITE" => Some(Self::TeamsWrite),
806            "PERMISSION_TEAMS_ALL_WRITE" => Some(Self::TeamsAllWrite),
807            "PERMISSION_PRIVACY_READ" => Some(Self::PrivacyRead),
808            "PERMISSION_PRIVACY_WRITE" => Some(Self::PrivacyWrite),
809            "PERMISSION_AUDIT_READ" => Some(Self::AuditRead),
810            "PERMISSION_TEMPLATES_REVIEW" => Some(Self::TemplatesReview),
811            "PERMISSION_PLATFORM_SUPPORT" => Some(Self::PlatformSupport),
812            "PERMISSION_PLATFORM_ACCESS_CODES" => Some(Self::PlatformAccessCodes),
813            "PERMISSION_PLATFORM_PROVISION" => Some(Self::PlatformProvision),
814            "PERMISSION_PLATFORM_ABUSE_RESPONSE" => Some(Self::PlatformAbuseResponse),
815            "PERMISSION_PLATFORM_COMPLIANCE_WRITE" => Some(Self::PlatformComplianceWrite),
816            _ => None,
817        }
818    }
819}
820/// Type of action a recipient can perform on a message.
821#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
822#[repr(i32)]
823pub enum ActionType {
824    /// Default value; not a valid action type.
825    Unspecified = 0,
826    /// Simple acknowledgment — recipient confirms they received the message.
827    Ack = 1,
828}
829impl ActionType {
830    /// String value of the enum field names used in the ProtoBuf definition.
831    ///
832    /// The values are not transformed in any way and thus are considered stable
833    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
834    pub fn as_str_name(&self) -> &'static str {
835        match self {
836            Self::Unspecified => "ACTION_TYPE_UNSPECIFIED",
837            Self::Ack => "ACTION_TYPE_ACK",
838        }
839    }
840    /// Creates an enum from field names used in the ProtoBuf definition.
841    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
842        match value {
843            "ACTION_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
844            "ACTION_TYPE_ACK" => Some(Self::Ack),
845            _ => None,
846        }
847    }
848}
849/// Type of step within a workflow definition DAG.
850#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
851#[repr(i32)]
852pub enum StepType {
853    /// Default value; not a valid step type.
854    Unspecified = 0,
855    /// Send the initial push notification to all recipients.
856    SendNotification = 1,
857    /// Sleep for a configurable deadline, then proceed to the next step.
858    DeadlineCheck = 2,
859    /// Send a follow-up reminder to recipients who have not acted.
860    SendReminder = 3,
861    /// Call an external webhook with campaign context.
862    CallWebhook = 4,
863    /// Mark unacknowledged deliveries (SENT/DELIVERED) as MISSED. No config required.
864    MarkMissed = 5,
865    /// Escalate unacknowledged deliveries to configured targets.
866    Escalate = 6,
867}
868impl StepType {
869    /// String value of the enum field names used in the ProtoBuf definition.
870    ///
871    /// The values are not transformed in any way and thus are considered stable
872    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
873    pub fn as_str_name(&self) -> &'static str {
874        match self {
875            Self::Unspecified => "STEP_TYPE_UNSPECIFIED",
876            Self::SendNotification => "STEP_TYPE_SEND_NOTIFICATION",
877            Self::DeadlineCheck => "STEP_TYPE_DEADLINE_CHECK",
878            Self::SendReminder => "STEP_TYPE_SEND_REMINDER",
879            Self::CallWebhook => "STEP_TYPE_CALL_WEBHOOK",
880            Self::MarkMissed => "STEP_TYPE_MARK_MISSED",
881            Self::Escalate => "STEP_TYPE_ESCALATE",
882        }
883    }
884    /// Creates an enum from field names used in the ProtoBuf definition.
885    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
886        match value {
887            "STEP_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
888            "STEP_TYPE_SEND_NOTIFICATION" => Some(Self::SendNotification),
889            "STEP_TYPE_DEADLINE_CHECK" => Some(Self::DeadlineCheck),
890            "STEP_TYPE_SEND_REMINDER" => Some(Self::SendReminder),
891            "STEP_TYPE_CALL_WEBHOOK" => Some(Self::CallWebhook),
892            "STEP_TYPE_MARK_MISSED" => Some(Self::MarkMissed),
893            "STEP_TYPE_ESCALATE" => Some(Self::Escalate),
894            _ => None,
895        }
896    }
897}
898/// Condition that must be met for an escalation to fire.
899#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
900#[repr(i32)]
901pub enum EscalationCondition {
902    Unspecified = 0,
903    /// Escalate if the delivery has not been acknowledged.
904    IfNotAcked = 1,
905    /// Escalate if the campaign is still open (even if some deliveries are acknowledged).
906    IfNotClosed = 2,
907}
908impl EscalationCondition {
909    /// String value of the enum field names used in the ProtoBuf definition.
910    ///
911    /// The values are not transformed in any way and thus are considered stable
912    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
913    pub fn as_str_name(&self) -> &'static str {
914        match self {
915            Self::Unspecified => "ESCALATION_CONDITION_UNSPECIFIED",
916            Self::IfNotAcked => "ESCALATION_CONDITION_IF_NOT_ACKED",
917            Self::IfNotClosed => "ESCALATION_CONDITION_IF_NOT_CLOSED",
918        }
919    }
920    /// Creates an enum from field names used in the ProtoBuf definition.
921    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
922        match value {
923            "ESCALATION_CONDITION_UNSPECIFIED" => Some(Self::Unspecified),
924            "ESCALATION_CONDITION_IF_NOT_ACKED" => Some(Self::IfNotAcked),
925            "ESCALATION_CONDITION_IF_NOT_CLOSED" => Some(Self::IfNotClosed),
926            _ => None,
927        }
928    }
929}
930/// Type of escalation target.
931#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
932#[repr(i32)]
933pub enum EscalationTargetType {
934    Unspecified = 0,
935    /// Escalate to a specific user by ID.
936    User = 1,
937    /// Escalate to all members of a group.
938    Group = 2,
939    /// Escalate to the recipient's direct manager (resolved from manager_id at runtime).
940    Manager = 3,
941    /// Escalate to all users with a specific role in the org.
942    Role = 4,
943}
944impl EscalationTargetType {
945    /// String value of the enum field names used in the ProtoBuf definition.
946    ///
947    /// The values are not transformed in any way and thus are considered stable
948    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
949    pub fn as_str_name(&self) -> &'static str {
950        match self {
951            Self::Unspecified => "ESCALATION_TARGET_TYPE_UNSPECIFIED",
952            Self::User => "ESCALATION_TARGET_TYPE_USER",
953            Self::Group => "ESCALATION_TARGET_TYPE_GROUP",
954            Self::Manager => "ESCALATION_TARGET_TYPE_MANAGER",
955            Self::Role => "ESCALATION_TARGET_TYPE_ROLE",
956        }
957    }
958    /// Creates an enum from field names used in the ProtoBuf definition.
959    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
960        match value {
961            "ESCALATION_TARGET_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
962            "ESCALATION_TARGET_TYPE_USER" => Some(Self::User),
963            "ESCALATION_TARGET_TYPE_GROUP" => Some(Self::Group),
964            "ESCALATION_TARGET_TYPE_MANAGER" => Some(Self::Manager),
965            "ESCALATION_TARGET_TYPE_ROLE" => Some(Self::Role),
966            _ => None,
967        }
968    }
969}
970/// Behavior mode controlling what an escalation produces for its targets.
971#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
972#[repr(i32)]
973pub enum EscalateMode {
974    /// Default value; servers normalize this to ESCALATE_MODE_DELIVER.
975    Unspecified = 0,
976    /// Targets receive a delivery for the campaign just like primary recipients.
977    Deliver = 1,
978    /// Targets receive an out-of-band alert only; no delivery is created.
979    AlertOnly = 2,
980}
981impl EscalateMode {
982    /// String value of the enum field names used in the ProtoBuf definition.
983    ///
984    /// The values are not transformed in any way and thus are considered stable
985    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
986    pub fn as_str_name(&self) -> &'static str {
987        match self {
988            Self::Unspecified => "ESCALATE_MODE_UNSPECIFIED",
989            Self::Deliver => "ESCALATE_MODE_DELIVER",
990            Self::AlertOnly => "ESCALATE_MODE_ALERT_ONLY",
991        }
992    }
993    /// Creates an enum from field names used in the ProtoBuf definition.
994    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
995        match value {
996            "ESCALATE_MODE_UNSPECIFIED" => Some(Self::Unspecified),
997            "ESCALATE_MODE_DELIVER" => Some(Self::Deliver),
998            "ESCALATE_MODE_ALERT_ONLY" => Some(Self::AlertOnly),
999            _ => None,
1000        }
1001    }
1002}
1003// ─── Messages ───────────────────────────────────────────────────────────────
1004
1005/// A scoped API key for programmatic access (MCP agents, service integrations).
1006#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1007pub struct ApiKey {
1008    /// Unique identifier.
1009    #[prost(string, tag="1")]
1010    pub id: ::prost::alloc::string::String,
1011    /// Human-friendly label (e.g. "MCP Production", "CI Pipeline").
1012    #[prost(string, tag="2")]
1013    pub name: ::prost::alloc::string::String,
1014    /// Displayable prefix of the key (e.g. "pidgr_k_abc12345").
1015    /// Used for identification — the full key is only returned on creation.
1016    #[prost(string, tag="3")]
1017    pub key_prefix: ::prost::alloc::string::String,
1018    /// Permissions granted to this key.
1019    #[prost(enumeration="Permission", repeated, tag="4")]
1020    pub permissions: ::prost::alloc::vec::Vec<i32>,
1021    /// When the key was created.
1022    #[prost(message, optional, tag="5")]
1023    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1024    /// Last time the key was used to authenticate a request. Empty if never used.
1025    #[prost(message, optional, tag="6")]
1026    pub last_used_at: ::core::option::Option<::prost_types::Timestamp>,
1027    /// When the key expires. Empty means no expiration.
1028    #[prost(message, optional, tag="7")]
1029    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
1030    /// Type of this key (API key or SCIM token).
1031    /// Defaults to KEY_TYPE_API_KEY for existing keys.
1032    #[prost(enumeration="KeyType", tag="8")]
1033    pub key_type: i32,
1034}
1035/// Request to create a new API key.
1036#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1037pub struct CreateApiKeyRequest {
1038    /// Human-friendly label. Required, max 200 characters.
1039    #[prost(string, tag="1")]
1040    pub name: ::prost::alloc::string::String,
1041    /// Permissions to grant. Required, at least one.
1042    /// PERMISSION_UNSPECIFIED values are rejected.
1043    #[prost(enumeration="Permission", repeated, tag="2")]
1044    pub permissions: ::prost::alloc::vec::Vec<i32>,
1045    /// Optional expiration time. If omitted, the key does not expire.
1046    #[prost(message, optional, tag="3")]
1047    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
1048    /// Type of key to create. Defaults to KEY_TYPE_API_KEY.
1049    /// SCIM tokens use the "pidgr_scim_" prefix instead of "pidgr_k_".
1050    #[prost(enumeration="KeyType", tag="4")]
1051    pub key_type: i32,
1052}
1053/// Response after creating an API key.
1054/// IMPORTANT: The full key is only returned here — it cannot be retrieved later.
1055#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1056pub struct CreateApiKeyResponse {
1057    /// The created API key metadata.
1058    #[prost(message, optional, tag="1")]
1059    pub api_key: ::core::option::Option<ApiKey>,
1060    /// The full secret key value (e.g. "pidgr_k_abc12345...").
1061    /// Store this securely — it is not retrievable after this response.
1062    #[prost(string, tag="2")]
1063    pub key: ::prost::alloc::string::String,
1064}
1065/// Request to list all API keys in the caller's organization.
1066#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1067pub struct ListApiKeysRequest {
1068    /// Optional filter by key type. Unspecified returns all keys.
1069    #[prost(enumeration="KeyType", tag="1")]
1070    pub key_type: i32,
1071}
1072/// Response containing the organization's API keys.
1073#[derive(Clone, PartialEq, ::prost::Message)]
1074pub struct ListApiKeysResponse {
1075    /// All active (non-revoked) API keys. Full key values are not included.
1076    #[prost(message, repeated, tag="1")]
1077    pub api_keys: ::prost::alloc::vec::Vec<ApiKey>,
1078}
1079/// Request to revoke an API key.
1080#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1081pub struct RevokeApiKeyRequest {
1082    /// ID of the API key to revoke. Required.
1083    #[prost(string, tag="1")]
1084    pub api_key_id: ::prost::alloc::string::String,
1085}
1086/// Response after revoking an API key.
1087#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1088pub struct RevokeApiKeyResponse {
1089}
1090// ─── Enums ──────────────────────────────────────────────────────────────────
1091
1092/// Type of API key, distinguishing platform keys from SCIM provisioning tokens.
1093#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1094#[repr(i32)]
1095pub enum KeyType {
1096    Unspecified = 0,
1097    ApiKey = 1,
1098    ScimToken = 2,
1099}
1100impl KeyType {
1101    /// String value of the enum field names used in the ProtoBuf definition.
1102    ///
1103    /// The values are not transformed in any way and thus are considered stable
1104    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1105    pub fn as_str_name(&self) -> &'static str {
1106        match self {
1107            Self::Unspecified => "KEY_TYPE_UNSPECIFIED",
1108            Self::ApiKey => "KEY_TYPE_API_KEY",
1109            Self::ScimToken => "KEY_TYPE_SCIM_TOKEN",
1110        }
1111    }
1112    /// Creates an enum from field names used in the ProtoBuf definition.
1113    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1114        match value {
1115            "KEY_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
1116            "KEY_TYPE_API_KEY" => Some(Self::ApiKey),
1117            "KEY_TYPE_SCIM_TOKEN" => Some(Self::ScimToken),
1118            _ => None,
1119        }
1120    }
1121}
1122// ─── Messages ───────────────────────────────────────────────────────────────
1123
1124/// Request to export all personal data associated with a user.
1125/// Auth: Requires JWT. Callable by the user themselves or an org admin.
1126#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1127pub struct ExportUserDataRequest {
1128    /// Internal user ID whose data is being exported.
1129    /// Constraints: UUID format (36 characters).
1130    #[prost(string, tag="1")]
1131    pub user_id: ::prost::alloc::string::String,
1132}
1133/// Response containing the export status and download location.
1134#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1135pub struct ExportUserDataResponse {
1136    /// Current status of the export request.
1137    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1138    pub status: i32,
1139    /// Pre-signed S3 URL to download the exported data (ZIP format).
1140    /// Only populated when status is COMPLETED.
1141    #[prost(string, tag="2")]
1142    pub result_url: ::prost::alloc::string::String,
1143    /// Unique identifier for this export request.
1144    /// Constraints: UUID format (36 characters).
1145    #[prost(string, tag="3")]
1146    pub export_id: ::prost::alloc::string::String,
1147}
1148/// Request to delete or anonymize all personal data associated with a user.
1149/// Auth: Requires JWT. Admin only.
1150#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1151pub struct DeleteUserDataRequest {
1152    /// Internal user ID whose data is being deleted.
1153    /// Constraints: UUID format (36 characters).
1154    #[prost(string, tag="1")]
1155    pub user_id: ::prost::alloc::string::String,
1156    /// When true, PII is replaced with placeholders instead of hard-deleted.
1157    /// This preserves audit trail integrity while removing personal data.
1158    #[prost(bool, tag="2")]
1159    pub anonymize: bool,
1160}
1161/// Response confirming the deletion request.
1162#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1163pub struct DeleteUserDataResponse {
1164    /// Current status of the deletion request.
1165    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1166    pub status: i32,
1167    /// Timestamp when deletion was completed (or scheduled).
1168    /// Only populated when status is COMPLETED.
1169    #[prost(message, optional, tag="2")]
1170    pub deleted_at: ::core::option::Option<::prost_types::Timestamp>,
1171    /// Unique identifier for this deletion request.
1172    #[prost(string, tag="3")]
1173    pub request_id: ::prost::alloc::string::String,
1174}
1175/// Request to list privacy requests for the organization.
1176/// Auth: Requires JWT. Admin only.
1177#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1178pub struct ListPrivacyRequestsRequest {
1179    /// Maximum number of results per page.
1180    /// Constraints: 1–100, default 25.
1181    #[prost(int32, tag="1")]
1182    pub page_size: i32,
1183    /// Continuation token from a previous response.
1184    #[prost(string, tag="2")]
1185    pub page_token: ::prost::alloc::string::String,
1186    /// Filter by request type (export, delete, rectify, restrict). Empty = all.
1187    #[prost(string, tag="3")]
1188    pub request_type: ::prost::alloc::string::String,
1189    /// Filter by status. UNSPECIFIED = all.
1190    #[prost(enumeration="PrivacyRequestStatus", tag="4")]
1191    pub status: i32,
1192}
1193/// Response containing privacy requests.
1194#[derive(Clone, PartialEq, ::prost::Message)]
1195pub struct ListPrivacyRequestsResponse {
1196    /// The privacy requests matching the filters.
1197    #[prost(message, repeated, tag="1")]
1198    pub requests: ::prost::alloc::vec::Vec<PrivacyRequest>,
1199    /// Token for the next page. Empty if no more results.
1200    #[prost(string, tag="2")]
1201    pub next_page_token: ::prost::alloc::string::String,
1202}
1203/// A privacy request record.
1204#[derive(Clone, PartialEq, ::prost::Message)]
1205pub struct PrivacyRequest {
1206    /// Unique identifier.
1207    #[prost(string, tag="1")]
1208    pub id: ::prost::alloc::string::String,
1209    /// The user this request applies to.
1210    #[prost(string, tag="2")]
1211    pub user_id: ::prost::alloc::string::String,
1212    /// Email of the target user.
1213    #[prost(string, tag="3")]
1214    pub user_email: ::prost::alloc::string::String,
1215    /// Type of request (export, delete, rectify, restrict).
1216    #[prost(string, tag="4")]
1217    pub request_type: ::prost::alloc::string::String,
1218    /// Current status.
1219    #[prost(enumeration="PrivacyRequestStatus", tag="5")]
1220    pub status: i32,
1221    /// Whether to anonymize (true) or hard-delete (false). Only for delete requests.
1222    #[prost(bool, tag="6")]
1223    pub anonymize: bool,
1224    /// Email of the admin who initiated this request.
1225    #[prost(string, tag="7")]
1226    pub requested_by_email: ::prost::alloc::string::String,
1227    /// When the request was created.
1228    #[prost(message, optional, tag="8")]
1229    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1230    /// When the request was completed (if applicable).
1231    #[prost(message, optional, tag="9")]
1232    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1233    /// Additional metadata (JSON).
1234    #[prost(map="string, string", tag="10")]
1235    pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1236}
1237/// Request to cancel a pending deletion.
1238/// Auth: Requires JWT. Admin only.
1239#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1240pub struct CancelDeletionRequest {
1241    /// The privacy request ID to cancel.
1242    #[prost(string, tag="1")]
1243    pub request_id: ::prost::alloc::string::String,
1244    /// Admin must type the target user's email to confirm.
1245    #[prost(string, tag="2")]
1246    pub confirmation_email: ::prost::alloc::string::String,
1247}
1248/// Response confirming the cancellation.
1249#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1250pub struct CancelDeletionResponse {
1251    /// Updated status (should be FAILED with reason cancelled).
1252    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1253    pub status: i32,
1254}
1255/// Request to skip the grace period and delete immediately.
1256/// Auth: Requires JWT. Admin only.
1257#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1258pub struct ImmediateDeleteRequest {
1259    /// The privacy request ID to expedite.
1260    #[prost(string, tag="1")]
1261    pub request_id: ::prost::alloc::string::String,
1262    /// Admin must type the target user's email to confirm.
1263    #[prost(string, tag="2")]
1264    pub confirmation_email: ::prost::alloc::string::String,
1265}
1266/// Response confirming the immediate deletion was triggered.
1267#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1268pub struct ImmediateDeleteResponse {
1269    /// Updated status (should be PROCESSING).
1270    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1271    pub status: i32,
1272}
1273/// Request to correct personal data for a user.
1274/// Auth: Requires JWT. Callable by the user themselves or an org admin.
1275#[derive(Clone, PartialEq, ::prost::Message)]
1276pub struct RectifyUserDataRequest {
1277    /// Internal user ID whose data is being corrected.
1278    /// Constraints: UUID format (36 characters).
1279    #[prost(string, tag="1")]
1280    pub user_id: ::prost::alloc::string::String,
1281    /// Map of field names to corrected values.
1282    /// Corrections are propagated to all stored locations.
1283    /// Constraints: Max 50 corrections per request.
1284    #[prost(map="string, string", tag="2")]
1285    pub corrections: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1286}
1287/// Response listing which fields were successfully corrected.
1288#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1289pub struct RectifyUserDataResponse {
1290    /// Names of fields that were rectified.
1291    #[prost(string, repeated, tag="1")]
1292    pub rectified_fields: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1293}
1294/// Request to restrict or unrestrict processing for a user.
1295/// Auth: Requires JWT. Admin only.
1296#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1297pub struct RestrictProcessingRequest {
1298    /// Internal user ID whose processing is being restricted.
1299    /// Constraints: UUID format (36 characters).
1300    #[prost(string, tag="1")]
1301    pub user_id: ::prost::alloc::string::String,
1302    /// When true, processing is restricted. When false, restriction is lifted.
1303    #[prost(bool, tag="2")]
1304    pub restricted: bool,
1305}
1306/// Response confirming the processing restriction status.
1307#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1308pub struct RestrictProcessingResponse {
1309    /// Current restriction status.
1310    #[prost(bool, tag="1")]
1311    pub restricted: bool,
1312    /// Timestamp when the restriction was applied or removed.
1313    #[prost(message, optional, tag="2")]
1314    pub restricted_at: ::core::option::Option<::prost_types::Timestamp>,
1315}
1316/// Request to confirm whether personal data exists for a user.
1317/// LGPD-specific: confirmação de existência (Art. 18, I).
1318/// Auth: Requires JWT. Admin only.
1319#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1320pub struct GetDataExistenceConfirmationRequest {
1321    /// Internal user ID to check.
1322    /// Constraints: UUID format (36 characters).
1323    #[prost(string, tag="1")]
1324    pub user_id: ::prost::alloc::string::String,
1325}
1326/// Response confirming data existence and listing data categories.
1327#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1328pub struct GetDataExistenceConfirmationResponse {
1329    /// Whether any personal data exists for this user.
1330    #[prost(bool, tag="1")]
1331    pub exists: bool,
1332    /// Categories of data stored (e.g., "profile", "deliveries", "analytics").
1333    #[prost(string, repeated, tag="2")]
1334    pub data_categories: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1335}
1336/// Request to list the calling user's own privacy requests.
1337/// Auth: Requires JWT. No admin permission required — returns only the caller's requests.
1338#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1339pub struct ListMyPrivacyRequestsRequest {
1340    /// Maximum number of results per page.
1341    /// Constraints: 1–100, default 25.
1342    #[prost(int32, tag="1")]
1343    pub page_size: i32,
1344    /// Continuation token from a previous response.
1345    #[prost(string, tag="2")]
1346    pub page_token: ::prost::alloc::string::String,
1347    /// Filter by request type (export, rectify). Empty = all.
1348    #[prost(string, tag="3")]
1349    pub request_type: ::prost::alloc::string::String,
1350    /// Filter by status. UNSPECIFIED = all.
1351    #[prost(enumeration="PrivacyRequestStatus", tag="4")]
1352    pub status: i32,
1353}
1354/// Response containing the calling user's privacy requests.
1355#[derive(Clone, PartialEq, ::prost::Message)]
1356pub struct ListMyPrivacyRequestsResponse {
1357    /// The privacy requests belonging to the calling user.
1358    #[prost(message, repeated, tag="1")]
1359    pub requests: ::prost::alloc::vec::Vec<PrivacyRequest>,
1360    /// Token for the next page. Empty if no more results.
1361    #[prost(string, tag="2")]
1362    pub next_page_token: ::prost::alloc::string::String,
1363}
1364// ─── Enums ──────────────────────────────────────────────────────────────────
1365
1366/// Status of a privacy request (export, delete, rectify, restrict).
1367#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1368#[repr(i32)]
1369pub enum PrivacyRequestStatus {
1370    /// Default value; should not be used explicitly.
1371    Unspecified = 0,
1372    /// Request has been created but not yet started.
1373    Pending = 1,
1374    /// Request is currently being processed.
1375    Processing = 2,
1376    /// Request completed successfully.
1377    Completed = 3,
1378    /// Request failed during processing.
1379    Failed = 4,
1380}
1381impl PrivacyRequestStatus {
1382    /// String value of the enum field names used in the ProtoBuf definition.
1383    ///
1384    /// The values are not transformed in any way and thus are considered stable
1385    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1386    pub fn as_str_name(&self) -> &'static str {
1387        match self {
1388            Self::Unspecified => "PRIVACY_REQUEST_STATUS_UNSPECIFIED",
1389            Self::Pending => "PRIVACY_REQUEST_STATUS_PENDING",
1390            Self::Processing => "PRIVACY_REQUEST_STATUS_PROCESSING",
1391            Self::Completed => "PRIVACY_REQUEST_STATUS_COMPLETED",
1392            Self::Failed => "PRIVACY_REQUEST_STATUS_FAILED",
1393        }
1394    }
1395    /// Creates an enum from field names used in the ProtoBuf definition.
1396    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1397        match value {
1398            "PRIVACY_REQUEST_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
1399            "PRIVACY_REQUEST_STATUS_PENDING" => Some(Self::Pending),
1400            "PRIVACY_REQUEST_STATUS_PROCESSING" => Some(Self::Processing),
1401            "PRIVACY_REQUEST_STATUS_COMPLETED" => Some(Self::Completed),
1402            "PRIVACY_REQUEST_STATUS_FAILED" => Some(Self::Failed),
1403            _ => None,
1404        }
1405    }
1406}
1407// ─── Messages ───────────────────────────────────────────────────────────────
1408
1409/// An immutable audit event capturing a significant platform action.
1410/// Audit events are append-only — they cannot be updated or deleted.
1411#[derive(Clone, PartialEq, ::prost::Message)]
1412pub struct AuditEvent {
1413    /// Unique identifier for this audit event.
1414    /// Constraints: UUID format (36 characters).
1415    #[prost(string, tag="1")]
1416    pub id: ::prost::alloc::string::String,
1417    /// Organization in which the event occurred.
1418    /// Constraints: UUID format (36 characters).
1419    #[prost(string, tag="2")]
1420    pub org_id: ::prost::alloc::string::String,
1421    /// User who performed the action. Empty for system-initiated events.
1422    /// Constraints: UUID format (36 characters) when present.
1423    #[prost(string, tag="3")]
1424    pub actor_id: ::prost::alloc::string::String,
1425    /// Type of action that was performed.
1426    #[prost(enumeration="AuditEventType", tag="4")]
1427    pub event_type: i32,
1428    /// Type of entity affected (e.g., "campaign", "user", "template").
1429    /// Constraints: Max length 50 characters.
1430    #[prost(string, tag="5")]
1431    pub entity_type: ::prost::alloc::string::String,
1432    /// Identifier of the entity affected.
1433    /// Constraints: UUID format (36 characters).
1434    #[prost(string, tag="6")]
1435    pub entity_id: ::prost::alloc::string::String,
1436    /// Additional context about the event (e.g., old/new values for changes).
1437    /// Constraints: Max 20 key-value pairs, keys max 50 chars, values max 500 chars.
1438    #[prost(map="string, string", tag="7")]
1439    pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1440    /// Timestamp when the event was recorded.
1441    #[prost(message, optional, tag="10")]
1442    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1443}
1444/// Request to list audit events with optional filters.
1445/// Auth: Requires JWT. Admin only.
1446#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1447pub struct ListAuditEventsRequest {
1448    /// Pagination token from a previous response.
1449    #[prost(string, tag="1")]
1450    pub page_token: ::prost::alloc::string::String,
1451    /// Maximum number of events to return.
1452    /// Constraints: Min 1, max 100. Default 50.
1453    #[prost(int32, tag="2")]
1454    pub page_size: i32,
1455    /// Optional filter: only return events of this type.
1456    #[prost(enumeration="AuditEventType", tag="3")]
1457    pub event_type: i32,
1458    /// Optional filter: only return events by this actor.
1459    /// Constraints: UUID format (36 characters).
1460    #[prost(string, tag="4")]
1461    pub actor_id: ::prost::alloc::string::String,
1462    /// Optional filter: events after this timestamp (inclusive).
1463    #[prost(message, optional, tag="5")]
1464    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
1465    /// Optional filter: events before this timestamp (exclusive).
1466    #[prost(message, optional, tag="6")]
1467    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
1468}
1469/// Response containing a paginated list of audit events.
1470#[derive(Clone, PartialEq, ::prost::Message)]
1471pub struct ListAuditEventsResponse {
1472    /// Audit events matching the request filters.
1473    #[prost(message, repeated, tag="1")]
1474    pub events: ::prost::alloc::vec::Vec<AuditEvent>,
1475    /// Token for fetching the next page. Empty when no more events.
1476    #[prost(string, tag="2")]
1477    pub next_page_token: ::prost::alloc::string::String,
1478}
1479/// Request to export the audit trail to S3 in a specified format.
1480/// Auth: Requires JWT. Admin only.
1481#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1482pub struct ExportAuditTrailRequest {
1483    /// Export format.
1484    #[prost(enumeration="AuditExportFormat", tag="1")]
1485    pub format: i32,
1486    /// Optional: export events after this timestamp.
1487    #[prost(message, optional, tag="2")]
1488    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
1489    /// Optional: export events before this timestamp.
1490    #[prost(message, optional, tag="3")]
1491    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
1492}
1493/// Response containing the export download URL.
1494#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1495pub struct ExportAuditTrailResponse {
1496    /// Pre-signed S3 URL to download the exported audit trail.
1497    /// Only populated when status is COMPLETED.
1498    #[prost(string, tag="1")]
1499    pub export_url: ::prost::alloc::string::String,
1500    /// Current status of the export request.
1501    #[prost(enumeration="PrivacyRequestStatus", tag="2")]
1502    pub status: i32,
1503}
1504/// A persistent record of an audit trail export request.
1505#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1506pub struct AuditExport {
1507    /// Unique identifier.
1508    #[prost(string, tag="1")]
1509    pub id: ::prost::alloc::string::String,
1510    /// Export format (csv, json).
1511    #[prost(string, tag="2")]
1512    pub format: ::prost::alloc::string::String,
1513    /// Current status.
1514    #[prost(enumeration="PrivacyRequestStatus", tag="3")]
1515    pub status: i32,
1516    /// Pre-signed download URL. Only populated when status is COMPLETED.
1517    #[prost(string, tag="4")]
1518    pub result_url: ::prost::alloc::string::String,
1519    /// Error message if the export failed.
1520    #[prost(string, tag="5")]
1521    pub error_message: ::prost::alloc::string::String,
1522    /// Email of the admin who requested the export.
1523    #[prost(string, tag="6")]
1524    pub requested_by_email: ::prost::alloc::string::String,
1525    /// When the export was requested.
1526    #[prost(message, optional, tag="7")]
1527    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1528    /// When the export completed (if applicable).
1529    #[prost(message, optional, tag="8")]
1530    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1531}
1532/// Request to list audit export history.
1533/// Auth: Requires JWT. Admin only.
1534#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1535pub struct ListAuditExportsRequest {
1536}
1537/// Response containing the list of audit exports.
1538#[derive(Clone, PartialEq, ::prost::Message)]
1539pub struct ListAuditExportsResponse {
1540    /// Audit export records, newest first.
1541    #[prost(message, repeated, tag="1")]
1542    pub exports: ::prost::alloc::vec::Vec<AuditExport>,
1543}
1544/// Request to append a single audit event from an internal service.
1545///
1546/// Auth: INTERNAL-mTLS ONLY. Unlike the read-side RPCs which authenticate
1547/// via Cognito JWT and infer `org_id` from the caller's claim, this RPC is
1548/// invoked by sibling services (e.g. pidgr-integrations) over the internal
1549/// mTLS mesh and therefore carries `org_id` in the request payload. The
1550/// server MUST reject any caller presenting only a JWT.
1551#[derive(Clone, PartialEq, ::prost::Message)]
1552pub struct AppendRequest {
1553    /// String form of the event type. Sibling services use a stable string
1554    /// identifier (e.g. "REACHABILITY_UPSERT", "REACHABILITY_REMOVE") so a
1555    /// new event type does not require a coordinated proto release across
1556    /// every internal service before it can be recorded. The audit server
1557    /// is responsible for mapping the string into its internal taxonomy.
1558    #[prost(string, tag="1")]
1559    pub event_type: ::prost::alloc::string::String,
1560    /// Organization in which the event occurred. UUID.
1561    #[prost(string, tag="2")]
1562    pub org_id: ::prost::alloc::string::String,
1563    /// User the audit event is about, if applicable. UUID. Unset when the
1564    /// event is not subject-bound (e.g. an org-wide policy change).
1565    #[prost(string, optional, tag="3")]
1566    pub subject_user_id: ::core::option::Option<::prost::alloc::string::String>,
1567    /// Actor who initiated the action, if any. UUID. Unset for system-initiated
1568    /// or sibling-service-initiated events.
1569    #[prost(string, optional, tag="4")]
1570    pub actor_id: ::core::option::Option<::prost::alloc::string::String>,
1571    /// Structured event-specific payload. Used in lieu of the rigid
1572    /// `map<string, string> metadata` on `AuditEvent` so sibling services
1573    /// can record nested objects (e.g. a `prefetch_signals` block) without
1574    /// string-encoding every value. Servers SHOULD redact PII before persist
1575    /// and MUST NOT log this field at INFO or above. Sensitive cryptographic
1576    /// material (plaintext identifiers, envelope ciphertext, raw HMAC keys)
1577    /// MUST NOT be placed here.
1578    #[prost(message, optional, tag="5")]
1579    pub details: ::core::option::Option<::prost_types::Struct>,
1580}
1581#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1582pub struct AppendResponse {
1583    /// Server-assigned audit event identifier (UUID).
1584    #[prost(string, tag="1")]
1585    pub event_id: ::prost::alloc::string::String,
1586}
1587// ─── Enums ──────────────────────────────────────────────────────────────────
1588
1589/// Type of auditable platform action.
1590#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1591#[repr(i32)]
1592pub enum AuditEventType {
1593    /// Default value; should not be used explicitly.
1594    Unspecified = 0,
1595    /// ── Campaign lifecycle ───────────────────────────────────────────────────
1596    /// A campaign was created.
1597    CampaignCreated = 1,
1598    /// A message was sent to a recipient.
1599    MessageSent = 2,
1600    /// A message was opened by a recipient.
1601    MessageOpened = 3,
1602    /// A recipient acknowledged a campaign.
1603    AckRegistered = 4,
1604    /// An escalation was triggered by the workflow.
1605    EscalationExecuted = 5,
1606    /// A campaign was started.
1607    CampaignStarted = 12,
1608    /// A campaign was cancelled.
1609    CampaignCancelled = 13,
1610    /// A campaign was updated.
1611    CampaignUpdated = 14,
1612    /// ── User lifecycle ───────────────────────────────────────────────────────
1613    /// A user was invited to the organization.
1614    UserInvited = 6,
1615    /// A user was deactivated.
1616    UserDeactivated = 7,
1617    /// A user was reactivated.
1618    UserReactivated = 15,
1619    /// A user's role was changed (assigned to a different role).
1620    RoleChanged = 10,
1621    /// A user's invite was revoked.
1622    InviteRevoked = 16,
1623    /// A user's profile was updated.
1624    ProfileUpdated = 17,
1625    /// A user's settings were updated.
1626    SettingsUpdated = 18,
1627    /// A user enrolled a passkey.
1628    PasskeyEnrolled = 19,
1629    /// ── GDPR / Privacy ──────────────────────────────────────────────────────
1630    /// A data export was requested (GDPR Art. 15).
1631    DataExportRequested = 8,
1632    /// A data deletion was requested (GDPR Art. 17).
1633    DataDeletionRequested = 9,
1634    /// User data was rectified (GDPR Art. 16).
1635    DataRectified = 20,
1636    /// Data processing was restricted (GDPR Art. 18).
1637    ProcessingRestricted = 21,
1638    /// A scheduled deletion was cancelled.
1639    DeletionCancelled = 22,
1640    /// An immediate deletion was executed.
1641    DeletionImmediate = 23,
1642    /// ── Organization / SSO ───────────────────────────────────────────────────
1643    /// An SSO provider was configured.
1644    SsoConfigured = 11,
1645    /// An SSO provider was created.
1646    SsoProviderCreated = 24,
1647    /// An SSO provider was deleted.
1648    SsoProviderDeleted = 25,
1649    /// Organization settings were updated.
1650    OrgUpdated = 26,
1651    /// ── Roles ────────────────────────────────────────────────────────────────
1652    /// A role was created.
1653    RoleCreated = 27,
1654    /// A role's name or permissions were updated.
1655    RoleUpdated = 28,
1656    /// A role was deleted.
1657    RoleDeleted = 29,
1658    /// ── Templates ────────────────────────────────────────────────────────────
1659    /// A template was created.
1660    TemplateCreated = 30,
1661    /// A template was updated.
1662    TemplateUpdated = 31,
1663    /// ── API Keys ─────────────────────────────────────────────────────────────
1664    /// An API key was created.
1665    ApiKeyCreated = 32,
1666    /// An API key was revoked.
1667    ApiKeyRevoked = 33,
1668    /// ── Invite Links ─────────────────────────────────────────────────────────
1669    /// An invite link was created.
1670    InviteLinkCreated = 34,
1671    /// An invite link was revoked.
1672    InviteLinkRevoked = 35,
1673    /// ── Groups ───────────────────────────────────────────────────────────────
1674    /// A group was created.
1675    GroupCreated = 36,
1676    /// A group was updated.
1677    GroupUpdated = 37,
1678    /// A group was deleted.
1679    GroupDeleted = 38,
1680    /// Members were added to a group.
1681    GroupMembersAdded = 39,
1682    /// Members were removed from a group.
1683    GroupMembersRemoved = 40,
1684    /// ── Teams ────────────────────────────────────────────────────────────────
1685    /// A team was created.
1686    TeamCreated = 41,
1687    /// A team was updated.
1688    TeamUpdated = 42,
1689    /// A team was deleted.
1690    TeamDeleted = 43,
1691    /// Members were added to a team.
1692    TeamMembersAdded = 44,
1693    /// Members were removed from a team.
1694    TeamMembersRemoved = 45,
1695    /// ── SCIM Provisioning ───────────────────────────────────────────────────
1696    /// A user was provisioned via SCIM.
1697    ScimUserProvisioned = 46,
1698    /// A user was deprovisioned via SCIM.
1699    ScimUserDeprovisioned = 47,
1700    /// A user was updated via SCIM.
1701    ScimUserUpdated = 48,
1702    /// ── Translations ────────────────────────────────────────────────────────
1703    /// A template translation was created.
1704    TranslationCreated = 49,
1705    /// A template translation was approved.
1706    TranslationApproved = 50,
1707    /// ── Sandbox Orgs ────────────────────────────────────────────────────────
1708    /// A sandbox organization was created.
1709    SandboxCreated = 51,
1710    /// A sandbox organization expired and was deleted.
1711    SandboxExpired = 52,
1712    /// ── AI/Insights ─────────────────────────────────────────────────────────
1713    /// An AI prediction was served and logged (EU AI Act Art. 12).
1714    AiPredictionLogged = 53,
1715    /// The ML pipeline (archetype clustering + enrichment) was manually triggered.
1716    MlPipelineTriggered = 54,
1717    /// Per-group archetype clustering was manually triggered.
1718    ArchetypeClusteringTriggered = 55,
1719    /// ── Org lifecycle ───────────────────────────────────────────────────────
1720    /// An organization was created.
1721    OrgCreated = 56,
1722    /// An organization was deleted (sandbox cleanup or manual deletion).
1723    OrgDeleted = 57,
1724    /// ── Reachability registry (pidgr-integrations) ──────────────────────────
1725    /// A reachability identifier (email, phone, Slack ID, etc.) was upserted.
1726    /// GDPR-relevant per Chikorita audit classification.
1727    ReachabilityUpsert = 58,
1728    /// A reachability identifier was removed. GDPR Art. 17 "right to erasure"
1729    /// event; written BEFORE the registry row is deleted per Recital 30.
1730    ReachabilityRemove = 59,
1731}
1732impl AuditEventType {
1733    /// String value of the enum field names used in the ProtoBuf definition.
1734    ///
1735    /// The values are not transformed in any way and thus are considered stable
1736    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1737    pub fn as_str_name(&self) -> &'static str {
1738        match self {
1739            Self::Unspecified => "AUDIT_EVENT_TYPE_UNSPECIFIED",
1740            Self::CampaignCreated => "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED",
1741            Self::MessageSent => "AUDIT_EVENT_TYPE_MESSAGE_SENT",
1742            Self::MessageOpened => "AUDIT_EVENT_TYPE_MESSAGE_OPENED",
1743            Self::AckRegistered => "AUDIT_EVENT_TYPE_ACK_REGISTERED",
1744            Self::EscalationExecuted => "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED",
1745            Self::CampaignStarted => "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED",
1746            Self::CampaignCancelled => "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED",
1747            Self::CampaignUpdated => "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED",
1748            Self::UserInvited => "AUDIT_EVENT_TYPE_USER_INVITED",
1749            Self::UserDeactivated => "AUDIT_EVENT_TYPE_USER_DEACTIVATED",
1750            Self::UserReactivated => "AUDIT_EVENT_TYPE_USER_REACTIVATED",
1751            Self::RoleChanged => "AUDIT_EVENT_TYPE_ROLE_CHANGED",
1752            Self::InviteRevoked => "AUDIT_EVENT_TYPE_INVITE_REVOKED",
1753            Self::ProfileUpdated => "AUDIT_EVENT_TYPE_PROFILE_UPDATED",
1754            Self::SettingsUpdated => "AUDIT_EVENT_TYPE_SETTINGS_UPDATED",
1755            Self::PasskeyEnrolled => "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED",
1756            Self::DataExportRequested => "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED",
1757            Self::DataDeletionRequested => "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED",
1758            Self::DataRectified => "AUDIT_EVENT_TYPE_DATA_RECTIFIED",
1759            Self::ProcessingRestricted => "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED",
1760            Self::DeletionCancelled => "AUDIT_EVENT_TYPE_DELETION_CANCELLED",
1761            Self::DeletionImmediate => "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE",
1762            Self::SsoConfigured => "AUDIT_EVENT_TYPE_SSO_CONFIGURED",
1763            Self::SsoProviderCreated => "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED",
1764            Self::SsoProviderDeleted => "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED",
1765            Self::OrgUpdated => "AUDIT_EVENT_TYPE_ORG_UPDATED",
1766            Self::RoleCreated => "AUDIT_EVENT_TYPE_ROLE_CREATED",
1767            Self::RoleUpdated => "AUDIT_EVENT_TYPE_ROLE_UPDATED",
1768            Self::RoleDeleted => "AUDIT_EVENT_TYPE_ROLE_DELETED",
1769            Self::TemplateCreated => "AUDIT_EVENT_TYPE_TEMPLATE_CREATED",
1770            Self::TemplateUpdated => "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED",
1771            Self::ApiKeyCreated => "AUDIT_EVENT_TYPE_API_KEY_CREATED",
1772            Self::ApiKeyRevoked => "AUDIT_EVENT_TYPE_API_KEY_REVOKED",
1773            Self::InviteLinkCreated => "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED",
1774            Self::InviteLinkRevoked => "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED",
1775            Self::GroupCreated => "AUDIT_EVENT_TYPE_GROUP_CREATED",
1776            Self::GroupUpdated => "AUDIT_EVENT_TYPE_GROUP_UPDATED",
1777            Self::GroupDeleted => "AUDIT_EVENT_TYPE_GROUP_DELETED",
1778            Self::GroupMembersAdded => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED",
1779            Self::GroupMembersRemoved => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED",
1780            Self::TeamCreated => "AUDIT_EVENT_TYPE_TEAM_CREATED",
1781            Self::TeamUpdated => "AUDIT_EVENT_TYPE_TEAM_UPDATED",
1782            Self::TeamDeleted => "AUDIT_EVENT_TYPE_TEAM_DELETED",
1783            Self::TeamMembersAdded => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED",
1784            Self::TeamMembersRemoved => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED",
1785            Self::ScimUserProvisioned => "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED",
1786            Self::ScimUserDeprovisioned => "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED",
1787            Self::ScimUserUpdated => "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED",
1788            Self::TranslationCreated => "AUDIT_EVENT_TYPE_TRANSLATION_CREATED",
1789            Self::TranslationApproved => "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED",
1790            Self::SandboxCreated => "AUDIT_EVENT_TYPE_SANDBOX_CREATED",
1791            Self::SandboxExpired => "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED",
1792            Self::AiPredictionLogged => "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED",
1793            Self::MlPipelineTriggered => "AUDIT_EVENT_TYPE_ML_PIPELINE_TRIGGERED",
1794            Self::ArchetypeClusteringTriggered => "AUDIT_EVENT_TYPE_ARCHETYPE_CLUSTERING_TRIGGERED",
1795            Self::OrgCreated => "AUDIT_EVENT_TYPE_ORG_CREATED",
1796            Self::OrgDeleted => "AUDIT_EVENT_TYPE_ORG_DELETED",
1797            Self::ReachabilityUpsert => "AUDIT_EVENT_TYPE_REACHABILITY_UPSERT",
1798            Self::ReachabilityRemove => "AUDIT_EVENT_TYPE_REACHABILITY_REMOVE",
1799        }
1800    }
1801    /// Creates an enum from field names used in the ProtoBuf definition.
1802    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1803        match value {
1804            "AUDIT_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
1805            "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED" => Some(Self::CampaignCreated),
1806            "AUDIT_EVENT_TYPE_MESSAGE_SENT" => Some(Self::MessageSent),
1807            "AUDIT_EVENT_TYPE_MESSAGE_OPENED" => Some(Self::MessageOpened),
1808            "AUDIT_EVENT_TYPE_ACK_REGISTERED" => Some(Self::AckRegistered),
1809            "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED" => Some(Self::EscalationExecuted),
1810            "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED" => Some(Self::CampaignStarted),
1811            "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED" => Some(Self::CampaignCancelled),
1812            "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED" => Some(Self::CampaignUpdated),
1813            "AUDIT_EVENT_TYPE_USER_INVITED" => Some(Self::UserInvited),
1814            "AUDIT_EVENT_TYPE_USER_DEACTIVATED" => Some(Self::UserDeactivated),
1815            "AUDIT_EVENT_TYPE_USER_REACTIVATED" => Some(Self::UserReactivated),
1816            "AUDIT_EVENT_TYPE_ROLE_CHANGED" => Some(Self::RoleChanged),
1817            "AUDIT_EVENT_TYPE_INVITE_REVOKED" => Some(Self::InviteRevoked),
1818            "AUDIT_EVENT_TYPE_PROFILE_UPDATED" => Some(Self::ProfileUpdated),
1819            "AUDIT_EVENT_TYPE_SETTINGS_UPDATED" => Some(Self::SettingsUpdated),
1820            "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED" => Some(Self::PasskeyEnrolled),
1821            "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED" => Some(Self::DataExportRequested),
1822            "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED" => Some(Self::DataDeletionRequested),
1823            "AUDIT_EVENT_TYPE_DATA_RECTIFIED" => Some(Self::DataRectified),
1824            "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED" => Some(Self::ProcessingRestricted),
1825            "AUDIT_EVENT_TYPE_DELETION_CANCELLED" => Some(Self::DeletionCancelled),
1826            "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE" => Some(Self::DeletionImmediate),
1827            "AUDIT_EVENT_TYPE_SSO_CONFIGURED" => Some(Self::SsoConfigured),
1828            "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED" => Some(Self::SsoProviderCreated),
1829            "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED" => Some(Self::SsoProviderDeleted),
1830            "AUDIT_EVENT_TYPE_ORG_UPDATED" => Some(Self::OrgUpdated),
1831            "AUDIT_EVENT_TYPE_ROLE_CREATED" => Some(Self::RoleCreated),
1832            "AUDIT_EVENT_TYPE_ROLE_UPDATED" => Some(Self::RoleUpdated),
1833            "AUDIT_EVENT_TYPE_ROLE_DELETED" => Some(Self::RoleDeleted),
1834            "AUDIT_EVENT_TYPE_TEMPLATE_CREATED" => Some(Self::TemplateCreated),
1835            "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED" => Some(Self::TemplateUpdated),
1836            "AUDIT_EVENT_TYPE_API_KEY_CREATED" => Some(Self::ApiKeyCreated),
1837            "AUDIT_EVENT_TYPE_API_KEY_REVOKED" => Some(Self::ApiKeyRevoked),
1838            "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED" => Some(Self::InviteLinkCreated),
1839            "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED" => Some(Self::InviteLinkRevoked),
1840            "AUDIT_EVENT_TYPE_GROUP_CREATED" => Some(Self::GroupCreated),
1841            "AUDIT_EVENT_TYPE_GROUP_UPDATED" => Some(Self::GroupUpdated),
1842            "AUDIT_EVENT_TYPE_GROUP_DELETED" => Some(Self::GroupDeleted),
1843            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED" => Some(Self::GroupMembersAdded),
1844            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED" => Some(Self::GroupMembersRemoved),
1845            "AUDIT_EVENT_TYPE_TEAM_CREATED" => Some(Self::TeamCreated),
1846            "AUDIT_EVENT_TYPE_TEAM_UPDATED" => Some(Self::TeamUpdated),
1847            "AUDIT_EVENT_TYPE_TEAM_DELETED" => Some(Self::TeamDeleted),
1848            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED" => Some(Self::TeamMembersAdded),
1849            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED" => Some(Self::TeamMembersRemoved),
1850            "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED" => Some(Self::ScimUserProvisioned),
1851            "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED" => Some(Self::ScimUserDeprovisioned),
1852            "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED" => Some(Self::ScimUserUpdated),
1853            "AUDIT_EVENT_TYPE_TRANSLATION_CREATED" => Some(Self::TranslationCreated),
1854            "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED" => Some(Self::TranslationApproved),
1855            "AUDIT_EVENT_TYPE_SANDBOX_CREATED" => Some(Self::SandboxCreated),
1856            "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED" => Some(Self::SandboxExpired),
1857            "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED" => Some(Self::AiPredictionLogged),
1858            "AUDIT_EVENT_TYPE_ML_PIPELINE_TRIGGERED" => Some(Self::MlPipelineTriggered),
1859            "AUDIT_EVENT_TYPE_ARCHETYPE_CLUSTERING_TRIGGERED" => Some(Self::ArchetypeClusteringTriggered),
1860            "AUDIT_EVENT_TYPE_ORG_CREATED" => Some(Self::OrgCreated),
1861            "AUDIT_EVENT_TYPE_ORG_DELETED" => Some(Self::OrgDeleted),
1862            "AUDIT_EVENT_TYPE_REACHABILITY_UPSERT" => Some(Self::ReachabilityUpsert),
1863            "AUDIT_EVENT_TYPE_REACHABILITY_REMOVE" => Some(Self::ReachabilityRemove),
1864            _ => None,
1865        }
1866    }
1867}
1868/// Format for audit trail export.
1869#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1870#[repr(i32)]
1871pub enum AuditExportFormat {
1872    /// Default value; should not be used explicitly.
1873    Unspecified = 0,
1874    /// Comma-separated values.
1875    Csv = 1,
1876    /// JSON lines format.
1877    Json = 2,
1878    /// Apache Parquet columnar format.
1879    Parquet = 3,
1880}
1881impl AuditExportFormat {
1882    /// String value of the enum field names used in the ProtoBuf definition.
1883    ///
1884    /// The values are not transformed in any way and thus are considered stable
1885    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1886    pub fn as_str_name(&self) -> &'static str {
1887        match self {
1888            Self::Unspecified => "AUDIT_EXPORT_FORMAT_UNSPECIFIED",
1889            Self::Csv => "AUDIT_EXPORT_FORMAT_CSV",
1890            Self::Json => "AUDIT_EXPORT_FORMAT_JSON",
1891            Self::Parquet => "AUDIT_EXPORT_FORMAT_PARQUET",
1892        }
1893    }
1894    /// Creates an enum from field names used in the ProtoBuf definition.
1895    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1896        match value {
1897            "AUDIT_EXPORT_FORMAT_UNSPECIFIED" => Some(Self::Unspecified),
1898            "AUDIT_EXPORT_FORMAT_CSV" => Some(Self::Csv),
1899            "AUDIT_EXPORT_FORMAT_JSON" => Some(Self::Json),
1900            "AUDIT_EXPORT_FORMAT_PARQUET" => Some(Self::Parquet),
1901            _ => None,
1902        }
1903    }
1904}
1905// ─── Messages ───────────────────────────────────────────────────────────────
1906
1907/// A campaign that delivers structured messages to a set of recipients
1908/// and tracks their engagement through a workflow.
1909#[derive(Clone, PartialEq, ::prost::Message)]
1910pub struct Campaign {
1911    /// Unique identifier for the campaign.
1912    /// Constraints: UUID format (36 characters).
1913    #[prost(string, tag="1")]
1914    pub id: ::prost::alloc::string::String,
1915    /// Human-readable campaign name.
1916    /// Constraints: Max length 200 characters.
1917    #[prost(string, tag="2")]
1918    pub name: ::prost::alloc::string::String,
1919    /// ID of the template used to render messages.
1920    /// Constraints: UUID format (36 characters).
1921    #[prost(string, tag="3")]
1922    pub template_id: ::prost::alloc::string::String,
1923    /// Pinned version of the template used for this campaign.
1924    #[prost(int32, tag="4")]
1925    pub template_version: i32,
1926    /// Object storage reference to the audience snapshot taken at campaign creation.
1927    #[prost(string, tag="5")]
1928    pub audience_snapshot_ref: ::prost::alloc::string::String,
1929    /// Current lifecycle status of the campaign.
1930    #[prost(enumeration="CampaignStatus", tag="6")]
1931    pub status: i32,
1932    /// Workflow DAG that drives the campaign's automation logic.
1933    #[prost(message, optional, tag="7")]
1934    pub workflow: ::core::option::Option<WorkflowDefinition>,
1935    /// Total number of recipients in the audience snapshot.
1936    #[prost(int32, tag="8")]
1937    pub total_recipients: i32,
1938    /// Number of recipients who completed the required action.
1939    #[prost(int32, tag="9")]
1940    pub action_completed_count: i32,
1941    /// Number of recipients who did not act before the deadline.
1942    #[prost(int32, tag="10")]
1943    pub missed_count: i32,
1944    /// Timestamp when the campaign was created.
1945    #[prost(message, optional, tag="11")]
1946    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1947    /// Timestamp when the campaign was started (workflow execution began).
1948    #[prost(message, optional, tag="12")]
1949    pub started_at: ::core::option::Option<::prost_types::Timestamp>,
1950    /// Timestamp when the campaign finished (completed, failed, or cancelled).
1951    #[prost(message, optional, tag="13")]
1952    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1953    /// Display name of the sender shown to recipients (e.g. "HR Team").
1954    /// Constraints: Max length 200 characters.
1955    #[prost(string, tag="14")]
1956    pub sender_name: ::prost::alloc::string::String,
1957    /// Optional user-facing title override. If set, takes precedence over the template title.
1958    /// Constraints: Max length 200 characters.
1959    #[prost(string, tag="15")]
1960    pub title: ::prost::alloc::string::String,
1961    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
1962    #[prost(bool, tag="16")]
1963    pub critical: bool,
1964    /// Optional locale override for all recipients in this campaign.
1965    /// When set, all recipients receive the campaign in this locale regardless of
1966    /// their preferred_locale. Empty means per-recipient locale resolution.
1967    /// Valid values: en, es, pt-BR, zh, ja.
1968    #[prost(string, tag="17")]
1969    pub default_locale: ::prost::alloc::string::String,
1970    /// Whether the campaign deadline waits for users without registered devices.
1971    /// When true, NO_DEVICE users remain in pending_count and can acknowledge
1972    /// via inbox after installing the app. Default false preserves current behavior.
1973    #[prost(bool, tag="18")]
1974    pub wait_for_enrollment: bool,
1975    /// Optional. Set when the campaign was created from a Compass archetype CTA.
1976    /// Drives post-campaign archetype-response analytics.
1977    #[prost(message, optional, tag="19")]
1978    pub originating_archetype: ::core::option::Option<CampaignOriginatingArchetype>,
1979}
1980/// Identifies the archetype that motivated the creation of a campaign.
1981/// The audience is NOT filtered by archetype membership — this is metadata
1982/// about the campaign's authoring intent only. See OpenSpec change
1983/// archetype-targeted-campaign-cta.
1984#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1985pub struct CampaignOriginatingArchetype {
1986    /// UUID of the group whose archetype set the label belongs to.
1987    #[prost(string, tag="1")]
1988    pub group_id: ::prost::alloc::string::String,
1989    /// Stable archetype label (e.g., "Swift Acknowledger"). Labels are stable
1990    /// across clustering retrains; archetype IDs are not.
1991    #[prost(string, tag="2")]
1992    pub archetype_label: ::prost::alloc::string::String,
1993}
1994/// A single audience member with optional per-user template variables.
1995#[derive(Clone, PartialEq, ::prost::Message)]
1996pub struct AudienceMember {
1997    /// User ID (UUID).
1998    #[prost(string, tag="1")]
1999    pub user_id: ::prost::alloc::string::String,
2000    /// Template variable values for this user (e.g. {"name": "Alice"}).
2001    #[prost(map="string, string", tag="2")]
2002    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
2003}
2004/// Request to create a new campaign.
2005#[derive(Clone, PartialEq, ::prost::Message)]
2006pub struct CreateCampaignRequest {
2007    /// Human-readable campaign name (admin-facing label).
2008    /// Constraints: Max length 200 characters.
2009    #[prost(string, tag="1")]
2010    pub name: ::prost::alloc::string::String,
2011    /// ID of the template to use for rendering messages.
2012    /// Constraints: UUID format (36 characters).
2013    #[prost(string, tag="2")]
2014    pub template_id: ::prost::alloc::string::String,
2015    /// Version of the template to pin for this campaign.
2016    #[prost(int32, tag="3")]
2017    pub template_version: i32,
2018    /// List of user IDs that form the campaign audience.
2019    /// Constraints: Max 100000 items.
2020    #[prost(string, repeated, tag="4")]
2021    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2022    /// Workflow DAG defining the campaign's automation steps.
2023    #[prost(message, optional, tag="5")]
2024    pub workflow: ::core::option::Option<WorkflowDefinition>,
2025    /// Display name of the sender shown to recipients (e.g. "HR Team").
2026    /// Constraints: Max length 200 characters.
2027    #[prost(string, tag="6")]
2028    pub sender_name: ::prost::alloc::string::String,
2029    /// Optional user-facing title override. If empty, the template title is used.
2030    /// Constraints: Max length 200 characters.
2031    #[prost(string, tag="7")]
2032    pub title: ::prost::alloc::string::String,
2033    /// Rich audience with per-user template variables.
2034    /// When set, takes precedence over user_ids.
2035    /// Constraints: Max 100000 items.
2036    #[prost(message, repeated, tag="8")]
2037    pub audience: ::prost::alloc::vec::Vec<AudienceMember>,
2038    /// Whether to include users with processing_restricted=true in the audience.
2039    /// Default false: restricted users are excluded. Set true only with Art. 18(2) legal basis.
2040    #[prost(bool, tag="9")]
2041    pub include_restricted: bool,
2042    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
2043    #[prost(bool, tag="10")]
2044    pub critical: bool,
2045    /// Optional locale override for all recipients.
2046    #[prost(string, tag="11")]
2047    pub default_locale: ::prost::alloc::string::String,
2048    /// Whether the campaign deadline should wait for users without registered devices.
2049    /// When true, NO_DEVICE users are not decremented from pending_count,
2050    /// allowing them to acknowledge via inbox after installing the app.
2051    #[prost(bool, tag="12")]
2052    pub wait_for_enrollment: bool,
2053    /// Optional. Set when the campaign is created from a Compass archetype CTA.
2054    /// The server validates the caller has access to group_id and that
2055    /// archetype_label exists in the group's current archetype set; cross-org
2056    /// group_id returns PERMISSION_DENIED, unknown label returns NOT_FOUND.
2057    #[prost(message, optional, tag="13")]
2058    pub originating_archetype: ::core::option::Option<CampaignOriginatingArchetype>,
2059}
2060/// Response after creating a campaign.
2061#[derive(Clone, PartialEq, ::prost::Message)]
2062pub struct CreateCampaignResponse {
2063    /// The newly created campaign.
2064    #[prost(message, optional, tag="1")]
2065    pub campaign: ::core::option::Option<Campaign>,
2066}
2067/// Request to start a campaign's workflow execution.
2068#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2069pub struct StartCampaignRequest {
2070    /// ID of the campaign to start.
2071    /// Constraints: UUID format (36 characters).
2072    #[prost(string, tag="1")]
2073    pub campaign_id: ::prost::alloc::string::String,
2074}
2075/// Response after starting a campaign.
2076#[derive(Clone, PartialEq, ::prost::Message)]
2077pub struct StartCampaignResponse {
2078    /// The campaign with updated status.
2079    #[prost(message, optional, tag="1")]
2080    pub campaign: ::core::option::Option<Campaign>,
2081}
2082/// Request to retrieve a single campaign by ID.
2083#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2084pub struct GetCampaignRequest {
2085    /// ID of the campaign to retrieve.
2086    /// Constraints: UUID format (36 characters).
2087    #[prost(string, tag="1")]
2088    pub campaign_id: ::prost::alloc::string::String,
2089}
2090/// Response containing the requested campaign.
2091#[derive(Clone, PartialEq, ::prost::Message)]
2092pub struct GetCampaignResponse {
2093    /// The requested campaign.
2094    #[prost(message, optional, tag="1")]
2095    pub campaign: ::core::option::Option<Campaign>,
2096}
2097/// Request to list campaigns with pagination.
2098#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2099pub struct ListCampaignsRequest {
2100    /// Pagination parameters.
2101    #[prost(message, optional, tag="1")]
2102    pub pagination: ::core::option::Option<Pagination>,
2103}
2104/// Response containing a page of campaigns.
2105#[derive(Clone, PartialEq, ::prost::Message)]
2106pub struct ListCampaignsResponse {
2107    /// List of campaigns in this page.
2108    #[prost(message, repeated, tag="1")]
2109    pub campaigns: ::prost::alloc::vec::Vec<Campaign>,
2110    /// Pagination metadata for fetching subsequent pages.
2111    #[prost(message, optional, tag="2")]
2112    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2113}
2114/// Request to cancel a running campaign.
2115#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2116pub struct CancelCampaignRequest {
2117    /// ID of the campaign to cancel.
2118    /// Constraints: UUID format (36 characters).
2119    #[prost(string, tag="1")]
2120    pub campaign_id: ::prost::alloc::string::String,
2121}
2122/// Response after cancelling a campaign.
2123#[derive(Clone, PartialEq, ::prost::Message)]
2124pub struct CancelCampaignResponse {
2125    /// The campaign with updated status (CANCELLED).
2126    #[prost(message, optional, tag="1")]
2127    pub campaign: ::core::option::Option<Campaign>,
2128}
2129/// Request to update a draft campaign (status must be CREATED).
2130/// Only non-empty/non-zero fields are updated; omitted fields remain unchanged.
2131#[derive(Clone, PartialEq, ::prost::Message)]
2132pub struct UpdateCampaignRequest {
2133    /// ID of the campaign to update.
2134    /// Constraints: UUID format (36 characters).
2135    #[prost(string, tag="1")]
2136    pub campaign_id: ::prost::alloc::string::String,
2137    /// Updated campaign name. Empty string means no change.
2138    /// Constraints: Max length 200 characters.
2139    #[prost(string, tag="2")]
2140    pub name: ::prost::alloc::string::String,
2141    /// Updated sender display name. Empty string means no change.
2142    /// Constraints: Max length 200 characters.
2143    #[prost(string, tag="3")]
2144    pub sender_name: ::prost::alloc::string::String,
2145    /// Updated title override. Empty string means no change.
2146    /// Constraints: Max length 200 characters.
2147    #[prost(string, tag="4")]
2148    pub title: ::prost::alloc::string::String,
2149    /// Updated template ID. Empty string means no change.
2150    /// Constraints: UUID format (36 characters).
2151    #[prost(string, tag="5")]
2152    pub template_id: ::prost::alloc::string::String,
2153    /// Updated template version. Zero means no change.
2154    #[prost(int32, tag="6")]
2155    pub template_version: i32,
2156    /// Updated workflow DAG. Null/omitted means no change.
2157    #[prost(message, optional, tag="7")]
2158    pub workflow: ::core::option::Option<WorkflowDefinition>,
2159}
2160/// Response after updating a campaign.
2161#[derive(Clone, PartialEq, ::prost::Message)]
2162pub struct UpdateCampaignResponse {
2163    /// The campaign with updated fields.
2164    #[prost(message, optional, tag="1")]
2165    pub campaign: ::core::option::Option<Campaign>,
2166}
2167/// A single delivery record tracking message delivery to one recipient.
2168/// Out-of-band context attached to a delivery beyond its canonical
2169/// recipient + status + content payload. Optional; fields are populated
2170/// per delivery kind. Currently only REMINDER_FYI children carry values,
2171/// to snapshot context from the parent delivery so clients can render
2172/// without fetching additional resources.
2173#[derive(Clone, PartialEq, ::prost::Message)]
2174pub struct DeliveryMetadata {
2175    /// REMINDER_FYI: the rendered Message payload from the parent delivery,
2176    /// used to render the blockquoted "Original message" panel on the
2177    /// notify-target's inbox card.
2178    #[prost(message, optional, tag="1")]
2179    pub original_message: ::core::option::Option<Message>,
2180    /// REMINDER_FYI: display name of the original recipient (the employee
2181    /// who hasn't responded). Used to interpolate the FYI title and banner.
2182    #[prost(string, tag="2")]
2183    pub original_recipient_name: ::prost::alloc::string::String,
2184    /// REMINDER_FYI: campaign title, denormalized so the notify-target's
2185    /// client can render without a separate campaign lookup.
2186    #[prost(string, tag="3")]
2187    pub campaign_title: ::prost::alloc::string::String,
2188    /// REMINDER_FYI: when the parent reminder step fired, used to render
2189    /// the "fired X ago" footer on the FYI card.
2190    #[prost(message, optional, tag="4")]
2191    pub reminder_fired_at: ::core::option::Option<::prost_types::Timestamp>,
2192}
2193#[derive(Clone, PartialEq, ::prost::Message)]
2194pub struct Delivery {
2195    /// Unique identifier for this delivery.
2196    /// Constraints: UUID format (36 characters).
2197    #[prost(string, tag="1")]
2198    pub id: ::prost::alloc::string::String,
2199    /// ID of the recipient user.
2200    /// Constraints: UUID format (36 characters).
2201    #[prost(string, tag="2")]
2202    pub user_id: ::prost::alloc::string::String,
2203    /// ID of the campaign this delivery belongs to.
2204    /// Constraints: UUID format (36 characters).
2205    #[prost(string, tag="3")]
2206    pub campaign_id: ::prost::alloc::string::String,
2207    /// Current delivery status.
2208    #[prost(enumeration="DeliveryStatus", tag="4")]
2209    pub status: i32,
2210    /// Timestamp when the message was delivered to the device.
2211    #[prost(message, optional, tag="5")]
2212    pub delivered_at: ::core::option::Option<::prost_types::Timestamp>,
2213    /// Timestamp when the recipient read the message.
2214    #[prost(message, optional, tag="6")]
2215    pub read_at: ::core::option::Option<::prost_types::Timestamp>,
2216    /// Timestamp when the recipient performed the required action.
2217    #[prost(message, optional, tag="7")]
2218    pub acted_at: ::core::option::Option<::prost_types::Timestamp>,
2219    /// Email address of the recipient, populated from the users table on read.
2220    #[prost(string, tag="8")]
2221    pub recipient_email: ::prost::alloc::string::String,
2222    /// Discriminator distinguishing primary recipient deliveries from
2223    /// deliveries generated by downstream workflow steps.
2224    #[prost(enumeration="delivery::Kind", tag="12")]
2225    pub kind: i32,
2226    /// For non-primary deliveries, the UUID of the originating delivery this
2227    /// row was derived from. Empty for primary deliveries.
2228    /// Constraints: UUID format (36 characters) when set.
2229    #[prost(string, tag="13")]
2230    pub parent_delivery_id: ::prost::alloc::string::String,
2231    /// The locale this delivery's body was actually rendered in after fallback
2232    /// resolution (recipient preference, campaign override, template default).
2233    /// Valid values: en, es, pt-BR, zh, ja.
2234    #[prost(string, tag="14")]
2235    pub rendered_locale: ::prost::alloc::string::String,
2236    /// Optional out-of-band context. See `DeliveryMetadata` for which
2237    /// delivery kinds populate which fields. Empty for legacy / PRIMARY
2238    /// deliveries.
2239    #[prost(message, optional, tag="15")]
2240    pub metadata: ::core::option::Option<DeliveryMetadata>,
2241}
2242/// Nested message and enum types in `Delivery`.
2243pub mod delivery {
2244    /// Discriminator describing what produced this delivery row.
2245    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2246    #[repr(i32)]
2247    pub enum Kind {
2248        /// Default value; not a valid kind.
2249        Unspecified = 0,
2250        /// Delivery generated for an audience recipient at campaign start.
2251        Primary = 1,
2252        /// Delivery generated by an escalation step targeting a non-audience user.
2253        Escalation = 2,
2254        /// Passive heads-up delivery generated when a reminder step fans out to
2255        /// its `notify_targets`. Carries no action button; auto-dismisses when
2256        /// the parent delivery is acknowledged. See
2257        /// `SendReminderConfig.notify_targets`.
2258        ReminderFyi = 3,
2259    }
2260    impl Kind {
2261        /// String value of the enum field names used in the ProtoBuf definition.
2262        ///
2263        /// The values are not transformed in any way and thus are considered stable
2264        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2265        pub fn as_str_name(&self) -> &'static str {
2266            match self {
2267                Self::Unspecified => "KIND_UNSPECIFIED",
2268                Self::Primary => "KIND_PRIMARY",
2269                Self::Escalation => "KIND_ESCALATION",
2270                Self::ReminderFyi => "KIND_REMINDER_FYI",
2271            }
2272        }
2273        /// Creates an enum from field names used in the ProtoBuf definition.
2274        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2275            match value {
2276                "KIND_UNSPECIFIED" => Some(Self::Unspecified),
2277                "KIND_PRIMARY" => Some(Self::Primary),
2278                "KIND_ESCALATION" => Some(Self::Escalation),
2279                "KIND_REMINDER_FYI" => Some(Self::ReminderFyi),
2280                _ => None,
2281            }
2282        }
2283    }
2284}
2285/// Request to list deliveries for a campaign with optional status filtering.
2286#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2287pub struct ListDeliveriesRequest {
2288    /// ID of the campaign to list deliveries for.
2289    /// Constraints: UUID format (36 characters).
2290    #[prost(string, tag="1")]
2291    pub campaign_id: ::prost::alloc::string::String,
2292    /// Optional filter by delivery status. UNSPECIFIED returns all.
2293    #[prost(enumeration="DeliveryStatus", tag="2")]
2294    pub status_filter: i32,
2295    /// Pagination parameters.
2296    #[prost(message, optional, tag="3")]
2297    pub pagination: ::core::option::Option<Pagination>,
2298}
2299/// Response containing a page of delivery records.
2300#[derive(Clone, PartialEq, ::prost::Message)]
2301pub struct ListDeliveriesResponse {
2302    /// List of deliveries in this page.
2303    #[prost(message, repeated, tag="1")]
2304    pub deliveries: ::prost::alloc::vec::Vec<Delivery>,
2305    /// Pagination metadata for fetching subsequent pages.
2306    #[prost(message, optional, tag="2")]
2307    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2308}
2309/// Request to compute the archetype-tendency-shift surface for a campaign:
2310/// how each archetype's share of the originating group has moved between
2311/// the snapshot closest to campaign-creation time and the most recent
2312/// snapshot. Only valid for campaigns whose originating_archetype is set.
2313#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2314pub struct GetCampaignArchetypeBreakdownRequest {
2315    /// ID of the campaign to break down.
2316    /// Constraints: UUID format (36 characters).
2317    #[prost(string, tag="1")]
2318    pub campaign_id: ::prost::alloc::string::String,
2319}
2320/// Movement in one archetype's share of the originating group between the
2321/// "before" and "after" archetype-clustering snapshots. Cohort-level only;
2322/// no joining to user identity. The `is_origin` row is the archetype the
2323/// campaign was authored for.
2324#[derive(Clone, PartialEq, ::prost::Message)]
2325pub struct ArchetypeShareShift {
2326    /// Stable archetype label, e.g. "Swift Acknowledger".
2327    #[prost(string, tag="1")]
2328    pub label: ::prost::alloc::string::String,
2329    /// Archetype's share of the group at the snapshot closest to (but not
2330    /// after) the campaign's created_at. Range 0.0 – 1.0.
2331    #[prost(double, tag="2")]
2332    pub share_before: f64,
2333    /// Archetype's share of the group at the most recent snapshot. Range
2334    /// 0.0 – 1.0. Equals share_before when no clustering has run since.
2335    #[prost(double, tag="3")]
2336    pub share_after: f64,
2337    /// True when this row's label matches the campaign's
2338    /// originating_archetype.archetype_label.
2339    #[prost(bool, tag="4")]
2340    pub is_origin: bool,
2341    /// Count of email DELIVERED events recorded for this archetype's members
2342    /// across the campaign window. Denominator for both open-rate fields.
2343    #[prost(uint64, tag="5")]
2344    pub email_delivered_count: u64,
2345    /// Open rate excluding events flagged as Apple-MPP prefetches
2346    /// (prefetch_suspected=true). Range 0.0 – 1.0.
2347    #[prost(double, tag="6")]
2348    pub email_open_rate_real: f64,
2349    /// Open rate including all OPENED events, prefetches included.
2350    /// Range 0.0 – 1.0.
2351    #[prost(double, tag="7")]
2352    pub email_open_rate_raw: f64,
2353}
2354/// Response containing per-archetype share shifts. The admin renders
2355/// these as a comparison table — origin row marked, others as peers, so
2356/// the admin can tell campaign-coincident drift apart from background
2357/// drift across the rest of the group.
2358#[derive(Clone, PartialEq, ::prost::Message)]
2359pub struct GetCampaignArchetypeBreakdownResponse {
2360    /// One entry per archetype in the originating group. Empty when
2361    /// insufficient_history is true.
2362    #[prost(message, repeated, tag="1")]
2363    pub shifts: ::prost::alloc::vec::Vec<ArchetypeShareShift>,
2364    /// When the "before" sample was taken (closest snapshot at or before
2365    /// campaign creation).
2366    #[prost(message, optional, tag="2")]
2367    pub before_snapshot_at: ::core::option::Option<::prost_types::Timestamp>,
2368    /// When the "after" sample was taken (most recent snapshot).
2369    #[prost(message, optional, tag="3")]
2370    pub after_snapshot_at: ::core::option::Option<::prost_types::Timestamp>,
2371    /// True when fewer than two clustering snapshots exist for the group,
2372    /// so no shift can be computed yet. Admin renders an "awaiting next
2373    /// clustering cycle" empty state.
2374    #[prost(bool, tag="4")]
2375    pub insufficient_history: bool,
2376}
2377// ─── Short-code messages ────────────────────────────────────────────────────
2378
2379/// Request to resolve a campaign's short-code, lazily generating one on
2380/// first call. Used by internal-service callers (the dispatch layer)
2381/// when assembling a third-party-channel deeplink:
2382/// `links.pidgr.com/c/{short_code}?t={token}`.
2383#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2384pub struct ResolveOrCreateShortCodeRequest {
2385    /// The campaign whose short-code is being resolved.
2386    /// Constraints: Required, must be a UUID and exist within the caller's organization.
2387    #[prost(string, tag="1")]
2388    pub campaign_id: ::prost::alloc::string::String,
2389}
2390/// Response carrying the resolved short-code. The same campaign always
2391/// resolves to the same code for its lifetime; the value is safe to
2392/// cache by the caller.
2393#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2394pub struct ResolveOrCreateShortCodeResponse {
2395    /// 8-character base62 short-code stable for the campaign's lifetime.
2396    #[prost(string, tag="1")]
2397    pub short_code: ::prost::alloc::string::String,
2398}
2399/// Request to look up a campaign by its public short-code. Called by the
2400/// native app when the recipient taps a third-party-channel deeplink and
2401/// the URL handler needs to route to the right campaign card. Designed to
2402/// be safe to call without authentication — the response carries no PII
2403/// and only enough context for the app to route correctly and show org
2404/// branding before the auth gate.
2405#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2406pub struct GetCampaignByShortCodeRequest {
2407    /// The 8-character short-code from the deeplink path.
2408    /// Constraints: Required, exactly 8 base62 characters.
2409    #[prost(string, tag="1")]
2410    pub short_code: ::prost::alloc::string::String,
2411}
2412/// Response carrying the minimum metadata the native app needs to route
2413/// the deeplink. Subject is the campaign's title text (already visible
2414/// in the recipient's inbox after dispatch — no new PII exposure). Body
2415/// content, audience size, delivery status and any other operational
2416/// fields are NOT included; the app fetches those via authenticated
2417/// `GetCampaign` after the recipient signs in.
2418#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2419pub struct GetCampaignByShortCodeResponse {
2420    /// Campaign UUID — the app uses this for the authenticated `GetCampaign`
2421    /// follow-up after the deeplink token validates.
2422    #[prost(string, tag="1")]
2423    pub campaign_id: ::prost::alloc::string::String,
2424    /// Organization UUID owning the campaign — lets the app pick the
2425    /// correct SSO / sign-in flow when the recipient is logged out.
2426    #[prost(string, tag="2")]
2427    pub org_id: ::prost::alloc::string::String,
2428    /// Display name of the organization for sign-in branding ("Sign in to
2429    /// Acme Inc to view this campaign"). Public information; the
2430    /// organization's profile already exposes it elsewhere.
2431    #[prost(string, tag="3")]
2432    pub organization_name: ::prost::alloc::string::String,
2433    /// Campaign subject (title). Same string the recipient already saw in
2434    /// their inbox; included so the deeplink interstitial can show
2435    /// "Acme Inc — All-hands Q3" before the auth gate.
2436    #[prost(string, tag="4")]
2437    pub subject: ::prost::alloc::string::String,
2438}
2439// ─── Messages ───────────────────────────────────────────────────────────────
2440
2441/// A registered device that can receive push notifications.
2442/// INTERNAL: This message is for server-side use only. Use DeviceSummary for API responses.
2443#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2444pub struct Device {
2445    /// Unique identifier for this device.
2446    /// Constraints: UUID format (36 characters).
2447    #[prost(string, tag="1")]
2448    pub device_id: ::prost::alloc::string::String,
2449    /// ID of the user who owns this device.
2450    /// Constraints: UUID format (36 characters).
2451    #[prost(string, tag="2")]
2452    pub user_id: ::prost::alloc::string::String,
2453    /// Mobile platform (iOS or Android).
2454    #[prost(enumeration="Platform", tag="3")]
2455    pub platform: i32,
2456    /// Push token used to send notifications to this device.
2457    #[prost(string, tag="4")]
2458    pub push_token: ::prost::alloc::string::String,
2459    /// Whether the device is currently active and eligible for push delivery.
2460    #[prost(bool, tag="5")]
2461    pub active: bool,
2462    /// Timestamp of the last activity from this device.
2463    #[prost(message, optional, tag="6")]
2464    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
2465    /// Timestamp when the device was first registered.
2466    #[prost(message, optional, tag="7")]
2467    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2468}
2469/// A device summary safe for API responses — excludes sensitive push_token.
2470#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2471pub struct DeviceSummary {
2472    /// Unique identifier for this device.
2473    #[prost(string, tag="1")]
2474    pub device_id: ::prost::alloc::string::String,
2475    /// ID of the user who owns this device.
2476    #[prost(string, tag="2")]
2477    pub user_id: ::prost::alloc::string::String,
2478    /// Mobile platform (iOS or Android).
2479    #[prost(enumeration="Platform", tag="3")]
2480    pub platform: i32,
2481    /// Whether the device is currently active and eligible for push delivery.
2482    #[prost(bool, tag="4")]
2483    pub active: bool,
2484    /// Timestamp of the last activity from this device.
2485    #[prost(message, optional, tag="5")]
2486    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
2487    /// Timestamp when the device was first registered.
2488    #[prost(message, optional, tag="6")]
2489    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2490}
2491/// Request to register a device for push notifications.
2492#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2493pub struct RegisterRequest {
2494    /// Client-generated unique device identifier.
2495    /// Constraints: UUID format (36 characters).
2496    #[prost(string, tag="1")]
2497    pub device_id: ::prost::alloc::string::String,
2498    /// Mobile platform of the device.
2499    #[prost(enumeration="Platform", tag="2")]
2500    pub platform: i32,
2501    /// Push token obtained from the push notification provider on the client.
2502    /// Constraints: Max length 4096 characters.
2503    #[prost(string, tag="3")]
2504    pub push_token: ::prost::alloc::string::String,
2505}
2506/// Response after registering a device.
2507#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2508pub struct RegisterResponse {
2509    /// The registered device summary (excludes push_token).
2510    #[prost(message, optional, tag="1")]
2511    pub device: ::core::option::Option<DeviceSummary>,
2512}
2513/// Request to deactivate a device, stopping push notifications.
2514#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2515pub struct DeactivateRequest {
2516    /// ID of the device to deactivate.
2517    /// Constraints: UUID format (36 characters).
2518    #[prost(string, tag="1")]
2519    pub device_id: ::prost::alloc::string::String,
2520}
2521/// Response after deactivating a device.
2522#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2523pub struct DeactivateResponse {
2524    /// Whether the device was successfully deactivated.
2525    #[prost(bool, tag="1")]
2526    pub success: bool,
2527}
2528/// Request to list all devices for the authenticated user.
2529#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2530pub struct ListDevicesRequest {
2531}
2532/// Response containing all devices for the user.
2533#[derive(Clone, PartialEq, ::prost::Message)]
2534pub struct ListDevicesResponse {
2535    /// List of devices registered to the authenticated user.
2536    #[prost(message, repeated, tag="1")]
2537    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
2538}
2539/// Request to list devices for a specific member (admin use).
2540#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2541pub struct ListMemberDevicesRequest {
2542    /// ID of the user whose devices to list.
2543    /// Constraints: UUID format (36 characters).
2544    #[prost(string, tag="1")]
2545    pub user_id: ::prost::alloc::string::String,
2546}
2547/// Response containing all devices for the specified member.
2548#[derive(Clone, PartialEq, ::prost::Message)]
2549pub struct ListMemberDevicesResponse {
2550    /// List of devices registered to the specified user.
2551    #[prost(message, repeated, tag="1")]
2552    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
2553}
2554// ─── Messages ───────────────────────────────────────────────────────────────
2555
2556/// User-configurable platform settings that apply across all clients.
2557/// All fields use their UNSPECIFIED/zero value to mean "no change" in updates.
2558#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2559pub struct UserSettings {
2560    /// Preferred color scheme for the UI.
2561    #[prost(enumeration="ThemePreference", tag="1")]
2562    pub theme_preference: i32,
2563    /// User's preferred language for the UI and push notifications.
2564    /// Empty string means "use organization default" or "auto-detect".
2565    /// Valid values: en, es, pt-BR, zh, ja.
2566    #[prost(string, tag="2")]
2567    pub preferred_locale: ::prost::alloc::string::String,
2568}
2569/// Structured profile attributes for a user within an organization.
2570/// Populated through admin invitation, mobile onboarding, or SSO attribute sync.
2571#[derive(Clone, PartialEq, ::prost::Message)]
2572pub struct UserProfile {
2573    /// User's given name.
2574    /// Constraints: Max length 200 characters.
2575    #[prost(string, tag="1")]
2576    pub first_name: ::prost::alloc::string::String,
2577    /// User's family name.
2578    /// Constraints: Max length 200 characters.
2579    #[prost(string, tag="2")]
2580    pub last_name: ::prost::alloc::string::String,
2581    /// Department or team within the organization.
2582    /// Constraints: Max length 200 characters.
2583    #[prost(string, tag="3")]
2584    pub department: ::prost::alloc::string::String,
2585    /// Job title.
2586    /// Constraints: Max length 200 characters.
2587    #[prost(string, tag="4")]
2588    pub title: ::prost::alloc::string::String,
2589    /// Phone number.
2590    /// Constraints: Max length 200 characters.
2591    #[prost(string, tag="5")]
2592    pub phone: ::prost::alloc::string::String,
2593    /// Office or geographic location.
2594    /// Constraints: Max length 200 characters.
2595    #[prost(string, tag="6")]
2596    pub location: ::prost::alloc::string::String,
2597    /// Organization-specific employee identifier.
2598    /// Constraints: Max length 200 characters.
2599    #[prost(string, tag="7")]
2600    pub employee_id: ::prost::alloc::string::String,
2601    /// Display name of the user's direct manager.
2602    /// Constraints: Max length 200 characters.
2603    #[prost(string, tag="8")]
2604    pub manager_name: ::prost::alloc::string::String,
2605    /// Employment start date in ISO 8601 format (YYYY-MM-DD).
2606    /// Constraints: Max length 200 characters.
2607    #[prost(string, tag="9")]
2608    pub start_date: ::prost::alloc::string::String,
2609    /// Organization-defined custom attributes for fields not covered by the fixed schema.
2610    /// Constraints: Max 50 entries. Key max length 100 characters, value max length 1000 characters.
2611    #[prost(map="string, string", tag="10")]
2612    pub custom_attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
2613    /// UUID of the user's direct manager within the same organization.
2614    /// Populated from SCIM enterprise extension (manager.value), manual admin
2615    /// assignment, or SSO attribute mapping. Empty if not set.
2616    #[prost(string, tag="11")]
2617    pub manager_id: ::prost::alloc::string::String,
2618}
2619/// A user within an organization.
2620#[derive(Clone, PartialEq, ::prost::Message)]
2621pub struct User {
2622    /// Unique identifier for the user (internal platform UUID, not identity provider subject ID).
2623    #[prost(string, tag="1")]
2624    pub id: ::prost::alloc::string::String,
2625    /// User's email address.
2626    /// Constraints: Max length 254 characters (RFC 5321).
2627    #[prost(string, tag="2")]
2628    pub email: ::prost::alloc::string::String,
2629    /// User's display name.
2630    /// Constraints: Max length 200 characters.
2631    #[prost(string, tag="3")]
2632    pub name: ::prost::alloc::string::String,
2633    /// Current account status.
2634    #[prost(enumeration="UserStatus", tag="5")]
2635    pub status: i32,
2636    /// Timestamp when the user was created.
2637    #[prost(message, optional, tag="6")]
2638    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2639    /// The user's role with its permission set.
2640    #[prost(message, optional, tag="7")]
2641    pub role: ::core::option::Option<Role>,
2642    /// ID of the user's role (for assignment operations).
2643    #[prost(string, tag="8")]
2644    pub role_id: ::prost::alloc::string::String,
2645    /// Structured profile attributes (department, title, etc.).
2646    /// May be empty if the user has not completed their profile.
2647    #[prost(message, optional, tag="9")]
2648    pub profile: ::core::option::Option<UserProfile>,
2649    /// Whether data processing is restricted for this user (GDPR Art. 18).
2650    /// When true, the user is excluded from campaign audiences by default.
2651    #[prost(bool, tag="10")]
2652    pub processing_restricted: bool,
2653    /// Data governance region override. Empty string means "inherit from org default".
2654    /// Valid values: EU, LATAM, BR, APAC, US.
2655    #[prost(string, tag="11")]
2656    pub data_governance_region: ::prost::alloc::string::String,
2657}
2658// ─── Enums ──────────────────────────────────────────────────────────────────
2659
2660/// Lifecycle status of a user account.
2661#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2662#[repr(i32)]
2663pub enum UserStatus {
2664    /// Default value; not a valid status.
2665    Unspecified = 0,
2666    /// User has been invited but has not completed onboarding.
2667    Invited = 1,
2668    /// User is active and can receive messages.
2669    Active = 2,
2670    /// User has been deactivated and will not receive messages.
2671    Deactivated = 3,
2672}
2673impl UserStatus {
2674    /// String value of the enum field names used in the ProtoBuf definition.
2675    ///
2676    /// The values are not transformed in any way and thus are considered stable
2677    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2678    pub fn as_str_name(&self) -> &'static str {
2679        match self {
2680            Self::Unspecified => "USER_STATUS_UNSPECIFIED",
2681            Self::Invited => "USER_STATUS_INVITED",
2682            Self::Active => "USER_STATUS_ACTIVE",
2683            Self::Deactivated => "USER_STATUS_DEACTIVATED",
2684        }
2685    }
2686    /// Creates an enum from field names used in the ProtoBuf definition.
2687    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2688        match value {
2689            "USER_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
2690            "USER_STATUS_INVITED" => Some(Self::Invited),
2691            "USER_STATUS_ACTIVE" => Some(Self::Active),
2692            "USER_STATUS_DEACTIVATED" => Some(Self::Deactivated),
2693            _ => None,
2694        }
2695    }
2696}
2697/// User's preferred color scheme.
2698#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2699#[repr(i32)]
2700pub enum ThemePreference {
2701    /// Default value; treated as SYSTEM when reading, "no change" when updating.
2702    Unspecified = 0,
2703    /// Always use light mode regardless of system setting.
2704    Light = 1,
2705    /// Always use dark mode regardless of system setting.
2706    Dark = 2,
2707    /// Follow the operating system or browser preference.
2708    System = 3,
2709}
2710impl ThemePreference {
2711    /// String value of the enum field names used in the ProtoBuf definition.
2712    ///
2713    /// The values are not transformed in any way and thus are considered stable
2714    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2715    pub fn as_str_name(&self) -> &'static str {
2716        match self {
2717            Self::Unspecified => "THEME_PREFERENCE_UNSPECIFIED",
2718            Self::Light => "THEME_PREFERENCE_LIGHT",
2719            Self::Dark => "THEME_PREFERENCE_DARK",
2720            Self::System => "THEME_PREFERENCE_SYSTEM",
2721        }
2722    }
2723    /// Creates an enum from field names used in the ProtoBuf definition.
2724    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2725        match value {
2726            "THEME_PREFERENCE_UNSPECIFIED" => Some(Self::Unspecified),
2727            "THEME_PREFERENCE_LIGHT" => Some(Self::Light),
2728            "THEME_PREFERENCE_DARK" => Some(Self::Dark),
2729            "THEME_PREFERENCE_SYSTEM" => Some(Self::System),
2730            _ => None,
2731        }
2732    }
2733}
2734// ─── Messages ───────────────────────────────────────────────────────────────
2735
2736/// A named collection of users within an organization, used for campaign
2737/// audience targeting (recipient groups).
2738#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2739pub struct Group {
2740    /// Unique identifier for the group.
2741    #[prost(string, tag="1")]
2742    pub id: ::prost::alloc::string::String,
2743    /// Human-readable display name (unique within the organization).
2744    /// Constraints: Max length 200 characters.
2745    #[prost(string, tag="2")]
2746    pub name: ::prost::alloc::string::String,
2747    /// Optional description of the group's purpose.
2748    /// Constraints: Max length 1000 characters.
2749    #[prost(string, tag="3")]
2750    pub description: ::prost::alloc::string::String,
2751    /// Number of users currently in the group.
2752    #[prost(int32, tag="4")]
2753    pub member_count: i32,
2754    /// Timestamp when the group was created.
2755    #[prost(message, optional, tag="5")]
2756    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2757    /// Timestamp when the group was last updated.
2758    #[prost(message, optional, tag="6")]
2759    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
2760    /// Whether this is the organization's default group (cannot be deleted or renamed).
2761    #[prost(bool, tag="7")]
2762    pub is_default: bool,
2763    /// ID of the user who created this group. Empty for system-seeded defaults.
2764    #[prost(string, tag="8")]
2765    pub created_by: ::prost::alloc::string::String,
2766}
2767/// Request to create a new group.
2768#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2769pub struct CreateGroupRequest {
2770    /// Display name for the group. Required.
2771    /// Constraints: Max length 200 characters.
2772    #[prost(string, tag="1")]
2773    pub name: ::prost::alloc::string::String,
2774    /// Optional description.
2775    /// Constraints: Max length 1000 characters.
2776    #[prost(string, tag="2")]
2777    pub description: ::prost::alloc::string::String,
2778}
2779/// Response after creating a group.
2780#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2781pub struct CreateGroupResponse {
2782    /// The newly created group.
2783    #[prost(message, optional, tag="1")]
2784    pub group: ::core::option::Option<Group>,
2785}
2786/// Request to retrieve a group by ID.
2787#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2788pub struct GetGroupRequest {
2789    /// ID of the group to retrieve. Required.
2790    #[prost(string, tag="1")]
2791    pub group_id: ::prost::alloc::string::String,
2792}
2793/// Response containing the requested group.
2794#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2795pub struct GetGroupResponse {
2796    /// The requested group.
2797    #[prost(message, optional, tag="1")]
2798    pub group: ::core::option::Option<Group>,
2799}
2800/// Request to list groups in the organization with pagination.
2801#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2802pub struct ListGroupsRequest {
2803    /// Pagination parameters.
2804    #[prost(message, optional, tag="1")]
2805    pub pagination: ::core::option::Option<Pagination>,
2806}
2807/// Response containing a page of groups.
2808#[derive(Clone, PartialEq, ::prost::Message)]
2809pub struct ListGroupsResponse {
2810    /// Groups in this page.
2811    #[prost(message, repeated, tag="1")]
2812    pub groups: ::prost::alloc::vec::Vec<Group>,
2813    /// Pagination metadata for fetching subsequent pages.
2814    #[prost(message, optional, tag="2")]
2815    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2816}
2817/// Request to update a group's name and/or description.
2818#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2819pub struct UpdateGroupRequest {
2820    /// ID of the group to update. Required.
2821    #[prost(string, tag="1")]
2822    pub group_id: ::prost::alloc::string::String,
2823    /// New display name. If empty, the name is not changed.
2824    /// Default groups cannot be renamed.
2825    /// Constraints: Max length 200 characters.
2826    #[prost(string, tag="2")]
2827    pub name: ::prost::alloc::string::String,
2828    /// New description. If empty, the description is not changed.
2829    /// Constraints: Max length 1000 characters.
2830    #[prost(string, tag="3")]
2831    pub description: ::prost::alloc::string::String,
2832}
2833/// Response after updating a group.
2834#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2835pub struct UpdateGroupResponse {
2836    /// The updated group.
2837    #[prost(message, optional, tag="1")]
2838    pub group: ::core::option::Option<Group>,
2839}
2840/// Request to delete a group.
2841#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2842pub struct DeleteGroupRequest {
2843    /// ID of the group to delete. Required.
2844    /// Default groups cannot be deleted.
2845    #[prost(string, tag="1")]
2846    pub group_id: ::prost::alloc::string::String,
2847}
2848/// Response after deleting a group.
2849#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2850pub struct DeleteGroupResponse {
2851}
2852/// Request to add users to a group.
2853#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2854pub struct AddGroupMembersRequest {
2855    /// ID of the group to add members to. Required.
2856    #[prost(string, tag="1")]
2857    pub group_id: ::prost::alloc::string::String,
2858    /// IDs of users to add. Must belong to the same organization.
2859    /// Adding an existing member is a no-op (idempotent).
2860    /// Constraints: Max 100 user IDs per request.
2861    #[prost(string, repeated, tag="2")]
2862    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2863}
2864/// Response after adding group members.
2865#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2866pub struct AddGroupMembersResponse {
2867    /// The group with updated member_count.
2868    #[prost(message, optional, tag="1")]
2869    pub group: ::core::option::Option<Group>,
2870}
2871/// Request to remove users from a group.
2872#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2873pub struct RemoveGroupMembersRequest {
2874    /// ID of the group to remove members from. Required.
2875    #[prost(string, tag="1")]
2876    pub group_id: ::prost::alloc::string::String,
2877    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
2878    /// Constraints: Max 100 user IDs per request.
2879    #[prost(string, repeated, tag="2")]
2880    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2881}
2882/// Response after removing group members.
2883#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2884pub struct RemoveGroupMembersResponse {
2885    /// The group with updated member_count.
2886    #[prost(message, optional, tag="1")]
2887    pub group: ::core::option::Option<Group>,
2888}
2889/// Request to list members of a group with pagination.
2890#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2891pub struct ListGroupMembersRequest {
2892    /// ID of the group whose members to list. Required.
2893    #[prost(string, tag="1")]
2894    pub group_id: ::prost::alloc::string::String,
2895    /// Pagination parameters.
2896    #[prost(message, optional, tag="2")]
2897    pub pagination: ::core::option::Option<Pagination>,
2898}
2899/// Response containing a page of group members.
2900#[derive(Clone, PartialEq, ::prost::Message)]
2901pub struct ListGroupMembersResponse {
2902    /// Users in this page.
2903    #[prost(message, repeated, tag="1")]
2904    pub users: ::prost::alloc::vec::Vec<User>,
2905    /// Pagination metadata for fetching subsequent pages.
2906    #[prost(message, optional, tag="2")]
2907    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2908}
2909/// A group membership entry for batch lookups.
2910#[derive(Clone, PartialEq, ::prost::Message)]
2911pub struct UserGroupMembership {
2912    /// ID of the user.
2913    #[prost(string, tag="1")]
2914    pub user_id: ::prost::alloc::string::String,
2915    /// Groups the user belongs to.
2916    #[prost(message, repeated, tag="2")]
2917    pub groups: ::prost::alloc::vec::Vec<Group>,
2918}
2919/// Request to get group memberships for a batch of users.
2920#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2921pub struct GetUserGroupMembershipsRequest {
2922    /// IDs of users to look up. Required.
2923    /// Constraints: Max 200 user IDs per request.
2924    #[prost(string, repeated, tag="1")]
2925    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2926}
2927/// Response containing group memberships for the requested users.
2928#[derive(Clone, PartialEq, ::prost::Message)]
2929pub struct GetUserGroupMembershipsResponse {
2930    /// Group memberships per user. Only users with at least one group are included.
2931    #[prost(message, repeated, tag="1")]
2932    pub memberships: ::prost::alloc::vec::Vec<UserGroupMembership>,
2933}
2934// ─── Messages ───────────────────────────────────────────────────────────────
2935
2936/// A single touch event captured from the mobile app.
2937#[derive(Clone, PartialEq, ::prost::Message)]
2938pub struct TouchEvent {
2939    /// Screen name from React Navigation route.
2940    /// Constraints: Max length 200 characters.
2941    #[prost(string, tag="1")]
2942    pub screen_name: ::prost::alloc::string::String,
2943    /// Horizontal coordinate as a percentage of screen width (0.0–1.0).
2944    /// Constraints: Range 0.0 to 1.0 inclusive.
2945    #[prost(float, tag="2")]
2946    pub x_pct: f32,
2947    /// Vertical coordinate as a percentage of screen height (0.0–1.0).
2948    /// Constraints: Range 0.0 to 1.0 inclusive.
2949    #[prost(float, tag="3")]
2950    pub y_pct: f32,
2951    /// Type of touch event.
2952    #[prost(enumeration="TouchEventType", tag="4")]
2953    pub event_type: i32,
2954    /// Screen width in device pixels at the time of capture.
2955    #[prost(int32, tag="5")]
2956    pub screen_width: i32,
2957    /// Screen height in device pixels at the time of capture.
2958    #[prost(int32, tag="6")]
2959    pub screen_height: i32,
2960    /// Client-side timestamp when the touch occurred.
2961    #[prost(message, optional, tag="7")]
2962    pub client_timestamp: ::core::option::Option<::prost_types::Timestamp>,
2963    /// Campaign ID if the touch occurred during a campaign message view.
2964    /// Empty string for organic (non-campaign) navigation.
2965    #[prost(string, tag="8")]
2966    pub campaign_id: ::prost::alloc::string::String,
2967}
2968/// Request to ingest a batch of touch events from the mobile app.
2969#[derive(Clone, PartialEq, ::prost::Message)]
2970pub struct IngestTouchEventsRequest {
2971    /// Batch of touch events to ingest.
2972    /// Constraints: Max 100 events per batch.
2973    #[prost(message, repeated, tag="1")]
2974    pub events: ::prost::alloc::vec::Vec<TouchEvent>,
2975}
2976/// Response after ingesting touch events.
2977#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2978pub struct IngestTouchEventsResponse {
2979    /// Number of events successfully ingested.
2980    #[prost(int32, tag="1")]
2981    pub ingested_count: i32,
2982}
2983/// A single aggregated data point in a heatmap grid cell.
2984#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2985pub struct HeatmapDataPoint {
2986    /// Grid cell horizontal center as a percentage (0.0–1.0).
2987    #[prost(float, tag="1")]
2988    pub x_pct: f32,
2989    /// Grid cell vertical center as a percentage (0.0–1.0).
2990    #[prost(float, tag="2")]
2991    pub y_pct: f32,
2992    /// Aggregated value for this cell (count, median, or z-score depending on mode).
2993    #[prost(float, tag="3")]
2994    pub value: f32,
2995}
2996/// Request to query aggregated heatmap data for a screen.
2997#[derive(Clone, PartialEq, ::prost::Message)]
2998pub struct QueryHeatmapDataRequest {
2999    /// Screen name to query.
3000    /// Constraints: Max length 200 characters.
3001    #[prost(string, tag="1")]
3002    pub screen_name: ::prost::alloc::string::String,
3003    /// Start of the time range filter (inclusive).
3004    #[prost(message, optional, tag="2")]
3005    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
3006    /// End of the time range filter (inclusive).
3007    #[prost(message, optional, tag="3")]
3008    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
3009    /// Optional: filter by campaign ID.
3010    /// Constraints: UUID format (36 characters).
3011    #[prost(string, tag="4")]
3012    pub campaign_id: ::prost::alloc::string::String,
3013    /// Grid resolution for coordinate rounding. Default: 0.02 (50×50 grid).
3014    /// Constraints: Range 0.005 to 0.1.
3015    #[prost(float, tag="6")]
3016    pub grid_resolution: f32,
3017    /// Aggregation mode (TOTAL or MEDIAN).
3018    #[prost(enumeration="HeatmapMode", tag="7")]
3019    pub mode: i32,
3020    /// Optional: filter by event types. Empty list means all types.
3021    #[prost(enumeration="TouchEventType", repeated, tag="8")]
3022    pub event_types: ::prost::alloc::vec::Vec<i32>,
3023}
3024/// Response containing aggregated heatmap data.
3025#[derive(Clone, PartialEq, ::prost::Message)]
3026pub struct QueryHeatmapDataResponse {
3027    /// Aggregated data points for heatmap rendering.
3028    #[prost(message, repeated, tag="1")]
3029    pub data_points: ::prost::alloc::vec::Vec<HeatmapDataPoint>,
3030    /// URL to a mobile-captured screenshot for this screen, if available.
3031    /// Empty string when no screenshot exists.
3032    #[prost(string, tag="3")]
3033    pub screenshot_url: ::prost::alloc::string::String,
3034    /// Whether per-cohort bucket breakdowns are available (k >= 5).
3035    #[prost(bool, tag="4")]
3036    pub cohort_enabled: bool,
3037}
3038/// Request to upload a screenshot captured from the mobile app.
3039#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3040pub struct UploadScreenshotRequest {
3041    /// Screen name matching React Navigation route (e.g. "MessageDetail::<campaign_uuid>").
3042    /// Constraints: Max length 200 characters.
3043    #[prost(string, tag="1")]
3044    pub screen_name: ::prost::alloc::string::String,
3045    /// App version that captured the screenshot (e.g. "1.15.0").
3046    #[prost(string, tag="2")]
3047    pub app_version: ::prost::alloc::string::String,
3048    /// PNG image data.
3049    /// Constraints: Max 512KB.
3050    #[prost(bytes="vec", tag="3")]
3051    pub image_data: ::prost::alloc::vec::Vec<u8>,
3052}
3053/// Response after uploading a screenshot.
3054#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3055pub struct UploadScreenshotResponse {
3056    /// S3 URL where the screenshot was stored.
3057    #[prost(string, tag="1")]
3058    pub url: ::prost::alloc::string::String,
3059}
3060/// A screen screenshot stored as a static asset.
3061#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3062pub struct ScreenScreenshot {
3063    /// Screen name matching React Navigation route.
3064    #[prost(string, tag="1")]
3065    pub screen_name: ::prost::alloc::string::String,
3066    /// S3 URL to the screenshot image.
3067    #[prost(string, tag="2")]
3068    pub url: ::prost::alloc::string::String,
3069    /// App version this screenshot corresponds to.
3070    #[prost(string, tag="3")]
3071    pub app_version: ::prost::alloc::string::String,
3072}
3073/// Request to list available screen screenshots.
3074#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3075pub struct ListScreenshotsRequest {
3076}
3077/// Response containing available screen screenshots.
3078#[derive(Clone, PartialEq, ::prost::Message)]
3079pub struct ListScreenshotsResponse {
3080    /// Available screen screenshots with their URLs and versions.
3081    #[prost(message, repeated, tag="1")]
3082    pub screenshots: ::prost::alloc::vec::Vec<ScreenScreenshot>,
3083}
3084// ─── Enums ──────────────────────────────────────────────────────────────────
3085
3086/// Type of touch event captured on the mobile app.
3087#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3088#[repr(i32)]
3089pub enum TouchEventType {
3090    /// Default value; not a valid event type.
3091    Unspecified = 0,
3092    /// A single tap on the screen.
3093    Tap = 1,
3094    /// A long press (held for 500ms+).
3095    LongPress = 2,
3096    /// A periodic scroll position sample (viewport midpoint every 2s).
3097    Scroll = 3,
3098    /// The user tapped an action button (e.g. "Acknowledge").
3099    ActionClick = 4,
3100}
3101impl TouchEventType {
3102    /// String value of the enum field names used in the ProtoBuf definition.
3103    ///
3104    /// The values are not transformed in any way and thus are considered stable
3105    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3106    pub fn as_str_name(&self) -> &'static str {
3107        match self {
3108            Self::Unspecified => "TOUCH_EVENT_TYPE_UNSPECIFIED",
3109            Self::Tap => "TOUCH_EVENT_TYPE_TAP",
3110            Self::LongPress => "TOUCH_EVENT_TYPE_LONG_PRESS",
3111            Self::Scroll => "TOUCH_EVENT_TYPE_SCROLL",
3112            Self::ActionClick => "TOUCH_EVENT_TYPE_ACTION_CLICK",
3113        }
3114    }
3115    /// Creates an enum from field names used in the ProtoBuf definition.
3116    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3117        match value {
3118            "TOUCH_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
3119            "TOUCH_EVENT_TYPE_TAP" => Some(Self::Tap),
3120            "TOUCH_EVENT_TYPE_LONG_PRESS" => Some(Self::LongPress),
3121            "TOUCH_EVENT_TYPE_SCROLL" => Some(Self::Scroll),
3122            "TOUCH_EVENT_TYPE_ACTION_CLICK" => Some(Self::ActionClick),
3123            _ => None,
3124        }
3125    }
3126}
3127/// Aggregation mode for heatmap data queries.
3128#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3129#[repr(i32)]
3130pub enum HeatmapMode {
3131    /// Default value; not a valid mode.
3132    Unspecified = 0,
3133    /// Sum of all cohort buckets' touches per grid cell (default).
3134    Total = 1,
3135    /// Median touch count per grid cell across cohort buckets.
3136    Median = 2,
3137}
3138impl HeatmapMode {
3139    /// String value of the enum field names used in the ProtoBuf definition.
3140    ///
3141    /// The values are not transformed in any way and thus are considered stable
3142    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3143    pub fn as_str_name(&self) -> &'static str {
3144        match self {
3145            Self::Unspecified => "HEATMAP_MODE_UNSPECIFIED",
3146            Self::Total => "HEATMAP_MODE_TOTAL",
3147            Self::Median => "HEATMAP_MODE_MEDIAN",
3148        }
3149    }
3150    /// Creates an enum from field names used in the ProtoBuf definition.
3151    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3152        match value {
3153            "HEATMAP_MODE_UNSPECIFIED" => Some(Self::Unspecified),
3154            "HEATMAP_MODE_TOTAL" => Some(Self::Total),
3155            "HEATMAP_MODE_MEDIAN" => Some(Self::Median),
3156            _ => None,
3157        }
3158    }
3159}
3160// ─── Messages ───────────────────────────────────────────────────────────────
3161
3162/// A single entry in a user's inbox, combining a message with its delivery state.
3163#[derive(Clone, PartialEq, ::prost::Message)]
3164pub struct InboxEntry {
3165    /// ID of the delivery record for this inbox entry.
3166    /// Constraints: UUID format (36 characters).
3167    #[prost(string, tag="1")]
3168    pub delivery_id: ::prost::alloc::string::String,
3169    /// The fully rendered message content.
3170    #[prost(message, optional, tag="2")]
3171    pub message: ::core::option::Option<Message>,
3172    /// Current delivery status (e.g. DELIVERED, ACKNOWLEDGED).
3173    #[prost(enumeration="DeliveryStatus", tag="3")]
3174    pub status: i32,
3175    /// Whether the user has read this message.
3176    #[prost(bool, tag="4")]
3177    pub read: bool,
3178    /// Timestamp when the message was received in the inbox.
3179    #[prost(message, optional, tag="5")]
3180    pub received_at: ::core::option::Option<::prost_types::Timestamp>,
3181    /// Discriminator: PRIMARY for normal deliveries, ESCALATION for delivery-grade
3182    /// escalations. Mirrors Delivery.kind so inbox-sync clients can branch on the
3183    /// same dimension as listDeliveries clients.
3184    #[prost(enumeration="delivery::Kind", tag="6")]
3185    pub kind: i32,
3186    /// For ESCALATION entries, the UUID of the unacked delivery that triggered this
3187    /// entry. Empty for PRIMARY entries.
3188    #[prost(string, tag="7")]
3189    pub parent_delivery_id: ::prost::alloc::string::String,
3190    /// The locale the body actually rendered in after fallback resolution. Empty
3191    /// for legacy/PRIMARY entries.
3192    #[prost(string, tag="8")]
3193    pub rendered_locale: ::prost::alloc::string::String,
3194    /// Optional out-of-band context mirrored from the underlying delivery.
3195    /// See `DeliveryMetadata` for which delivery kinds populate which fields.
3196    /// Empty for PRIMARY entries.
3197    #[prost(message, optional, tag="9")]
3198    pub metadata: ::core::option::Option<DeliveryMetadata>,
3199}
3200/// Request to sync inbox entries since a given timestamp.
3201#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3202pub struct SyncRequest {
3203    /// Fetch entries newer than this timestamp. Omit for initial sync.
3204    #[prost(message, optional, tag="1")]
3205    pub since: ::core::option::Option<::prost_types::Timestamp>,
3206    /// Maximum number of entries to return.
3207    /// Constraints: Valid range 1 to 200.
3208    #[prost(int32, tag="2")]
3209    pub limit: i32,
3210}
3211/// Response containing synced inbox entries.
3212#[derive(Clone, PartialEq, ::prost::Message)]
3213pub struct SyncResponse {
3214    /// Inbox entries newer than the requested timestamp.
3215    #[prost(message, repeated, tag="1")]
3216    pub entries: ::prost::alloc::vec::Vec<InboxEntry>,
3217    /// Cursor timestamp to use for the next sync call.
3218    #[prost(message, optional, tag="2")]
3219    pub next_since: ::core::option::Option<::prost_types::Timestamp>,
3220}
3221/// Request to mark a message as read.
3222#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3223pub struct MarkReadRequest {
3224    /// ID of the delivery to mark as read.
3225    /// Constraints: UUID format (36 characters).
3226    #[prost(string, tag="1")]
3227    pub delivery_id: ::prost::alloc::string::String,
3228}
3229/// Response after marking a message as read.
3230#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3231pub struct MarkReadResponse {
3232    /// Whether the read status was successfully updated.
3233    #[prost(bool, tag="1")]
3234    pub success: bool,
3235}
3236/// Request to retrieve a single message by delivery ID.
3237#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3238pub struct GetMessageRequest {
3239    /// ID of the delivery to retrieve.
3240    /// Constraints: UUID format (36 characters).
3241    #[prost(string, tag="1")]
3242    pub delivery_id: ::prost::alloc::string::String,
3243}
3244/// Response containing the requested inbox entry.
3245#[derive(Clone, PartialEq, ::prost::Message)]
3246pub struct GetMessageResponse {
3247    /// The inbox entry for the requested delivery.
3248    #[prost(message, optional, tag="1")]
3249    pub entry: ::core::option::Option<InboxEntry>,
3250}
3251// ─── Messages ───────────────────────────────────────────────────────────────
3252
3253/// A behavioral archetype describing a cohort pattern (never an individual).
3254/// Derived from k-anonymized, DP-noised behavioral feature vectors.
3255#[derive(Clone, PartialEq, ::prost::Message)]
3256pub struct Archetype {
3257    /// Human-readable label (e.g., "Swift Acknowledger", "Thorough Reader").
3258    #[prost(string, tag="1")]
3259    pub label: ::prost::alloc::string::String,
3260    /// Description of the behavioral pattern this archetype represents.
3261    #[prost(string, tag="2")]
3262    pub description: ::prost::alloc::string::String,
3263    /// Proportion of the group that belongs to this archetype (0.0-1.0).
3264    #[prost(float, tag="3")]
3265    pub percentage: f32,
3266    /// Centroid of the behavioral feature vector for this archetype.
3267    /// Keys are stable dimension names from the feature extractor
3268    /// vocabulary (e.g., "tap_density", "engagement_depth",
3269    /// "scroll_velocity_p50", "idle_gap_p75"). Single-letter keys are
3270    /// reserved for backward compatibility with pre-v0.64 servers and
3271    /// SHALL be ignored by clients.
3272    #[prost(map="string, double", tag="4")]
3273    pub feature_centroid: ::std::collections::HashMap<::prost::alloc::string::String, f64>,
3274    /// Per-dimension distribution of the archetype's members. Lets the
3275    /// admin render percentile bands instead of single-point centroids.
3276    /// Absent until at least k members exist in the cluster. Keys mirror
3277    /// `feature_centroid` keys.
3278    #[prost(map="string, message", tag="5")]
3279    pub feature_breakdown: ::std::collections::HashMap<::prost::alloc::string::String, DimensionStats>,
3280    /// Tap density heatmap aggregated across sessions for this
3281    /// archetype. Cohort-level only — never per-session timing.
3282    /// Absent when fewer than k sessions have tap data.
3283    #[prost(message, optional, tag="6")]
3284    pub tap_heatmap: ::core::option::Option<TapHeatmap>,
3285    /// Forecast of cluster share at fixed horizons (7/14/30/90 days).
3286    /// Absent during cold start before historical clustering runs exist
3287    /// to extrapolate from.
3288    #[prost(message, optional, tag="7")]
3289    pub forecast: ::core::option::Option<ArchetypeForecast>,
3290    /// Sessions that sit at the median and quartiles of the archetype's
3291    /// centroid distance, ranked by distance. Bounded at three entries.
3292    /// Absent until at least 50 sessions have been scored.
3293    /// Sessions can come from any client that emits to ReplayService —
3294    /// mobile (iOS, Android) or desktop (macOS, Windows, Linux).
3295    #[prost(message, repeated, tag="8")]
3296    pub exemplar_sessions: ::prost::alloc::vec::Vec<ExemplarSession>,
3297    /// Per-screen dwell time distribution, derived from session replay.
3298    /// Absent when fewer than k sessions per screen exist.
3299    #[prost(message, optional, tag="9")]
3300    pub screen_dwell: ::core::option::Option<ScreenDwell>,
3301    /// End-to-end response latencies (push delivered → read → ack) for
3302    /// members of this archetype, as percentiles. Absent until at least
3303    /// k campaign deliveries have been recorded for this archetype.
3304    #[prost(message, optional, tag="10")]
3305    pub response_timeline: ::core::option::Option<ResponseTimeline>,
3306}
3307/// Per-dimension distribution stats for one feature dimension within
3308/// an archetype's cohort. All values are in the same units as
3309/// `Archetype.feature_centroid`. Used to render percentile bands on
3310/// the admin's behavioral profile panel.
3311#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3312pub struct DimensionStats {
3313    /// Centroid value (same as Archetype.feature_centroid\[key\]).
3314    #[prost(double, tag="1")]
3315    pub centroid: f64,
3316    /// 25th percentile across the archetype's members.
3317    #[prost(double, tag="2")]
3318    pub p25: f64,
3319    /// Median across the archetype's members.
3320    #[prost(double, tag="3")]
3321    pub p50: f64,
3322    /// 75th percentile across the archetype's members.
3323    #[prost(double, tag="4")]
3324    pub p75: f64,
3325    /// Median across the entire group (all archetypes), included so the
3326    /// admin can render "this archetype is X% above group median".
3327    #[prost(double, tag="5")]
3328    pub group_p50: f64,
3329}
3330/// A density grid of tap activity for one archetype, normalized to
3331/// \[0.0, 1.0\] where 1.0 is the hottest cell in the cohort. Cohort-
3332/// level only.
3333#[derive(Clone, PartialEq, ::prost::Message)]
3334pub struct TapHeatmap {
3335    /// Width of the density grid in cells.
3336    #[prost(int32, tag="1")]
3337    pub width: i32,
3338    /// Height of the density grid in cells.
3339    #[prost(int32, tag="2")]
3340    pub height: i32,
3341    /// Row-major density values, length must equal width*height. All in
3342    /// \[0.0, 1.0\].
3343    #[prost(double, repeated, tag="3")]
3344    pub values: ::prost::alloc::vec::Vec<f64>,
3345    /// Number of sessions aggregated. Always >= MinFeatureVectorsForClustering
3346    /// when the field is present.
3347    #[prost(int32, tag="4")]
3348    pub session_count: i32,
3349    /// Optional per-event-type breakdown. When present, the writer
3350    /// SHALL emit one entry for each event type in the source data
3351    /// (TAP, LONG_PRESS, SCROLL, ACTION_CLICK).
3352    #[prost(message, repeated, tag="5")]
3353    pub layers: ::prost::alloc::vec::Vec<TapHeatmapLayer>,
3354}
3355/// One per-event-type layer of a TapHeatmap.
3356#[derive(Clone, PartialEq, ::prost::Message)]
3357pub struct TapHeatmapLayer {
3358    /// Event type this layer represents (e.g., "TAP", "LONG_PRESS",
3359    /// "SCROLL", "ACTION_CLICK").
3360    #[prost(string, tag="1")]
3361    pub event_type: ::prost::alloc::string::String,
3362    /// Row-major density values, same dimensions as the parent
3363    /// TapHeatmap. Independently normalized to \[0.0, 1.0\].
3364    #[prost(double, repeated, tag="2")]
3365    pub values: ::prost::alloc::vec::Vec<f64>,
3366}
3367/// Predicted cluster share at fixed horizons with confidence bands.
3368#[derive(Clone, PartialEq, ::prost::Message)]
3369pub struct ArchetypeForecast {
3370    /// Horizons in increasing days. Always one entry each for 7, 14,
3371    /// 30, and 90 days when the field is present.
3372    #[prost(message, repeated, tag="1")]
3373    pub horizons: ::prost::alloc::vec::Vec<ForecastHorizon>,
3374}
3375/// Predicted share at one horizon with a 90% prediction interval.
3376#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3377pub struct ForecastHorizon {
3378    /// Horizon length in days (one of: 7, 14, 30, 90).
3379    #[prost(int32, tag="1")]
3380    pub days: i32,
3381    /// Predicted fraction of the group falling in this archetype at the
3382    /// horizon (0.0-1.0).
3383    #[prost(double, tag="2")]
3384    pub predicted_share: f64,
3385    /// 5th-percentile lower bound of the prediction interval.
3386    #[prost(double, tag="3")]
3387    pub lower: f64,
3388    /// 95th-percentile upper bound of the prediction interval.
3389    #[prost(double, tag="4")]
3390    pub upper: f64,
3391    /// Confidence in this horizon's prediction.
3392    #[prost(enumeration="ConfidenceLevel", tag="5")]
3393    pub confidence: i32,
3394}
3395/// Pointer to a representative session for one archetype, ranked by
3396/// distance to the archetype centroid.
3397#[derive(Clone, PartialEq, ::prost::Message)]
3398pub struct ExemplarSession {
3399    /// Session recording ID retrievable via ReplayService for the same
3400    /// org. Linkable from the admin regardless of originating platform.
3401    #[prost(string, tag="1")]
3402    pub session_id: ::prost::alloc::string::String,
3403    /// Quantile rank within the archetype: 25, 50, or 75. The writer
3404    /// emits at most one session per rank.
3405    #[prost(int32, tag="2")]
3406    pub rank: i32,
3407    /// L2 distance from the session's feature vector to the centroid.
3408    #[prost(double, tag="3")]
3409    pub distance: f64,
3410    /// Optional duration metadata for quick admin labelling.
3411    #[prost(int32, tag="4")]
3412    pub duration_seconds: i32,
3413    /// Optional platform identifier from the vocabulary
3414    /// {"ios", "android", "macos", "windows", "linux"}. The admin
3415    /// renders unknown values verbatim for forward compatibility.
3416    #[prost(string, tag="5")]
3417    pub platform: ::prost::alloc::string::String,
3418}
3419/// Per-screen dwell distribution within an archetype. Lets the admin
3420/// surface "this archetype lingers 8.2s on the Message Detail screen
3421/// vs 0.4s on the Inbox list".
3422#[derive(Clone, PartialEq, ::prost::Message)]
3423pub struct ScreenDwell {
3424    /// One entry per screen. Screens with fewer than k members in the
3425    /// archetype are dropped from the list (not marked as absent).
3426    #[prost(message, repeated, tag="1")]
3427    pub entries: ::prost::alloc::vec::Vec<ScreenDwellEntry>,
3428}
3429#[derive(Clone, PartialEq, ::prost::Message)]
3430pub struct ScreenDwellEntry {
3431    /// Stable screen identifier (e.g., "MessageDetail", "Inbox",
3432    /// "ProfileSettings"). Sourced from the same screen_name vocabulary
3433    /// used by heatmap_cells.
3434    #[prost(string, tag="1")]
3435    pub screen_name: ::prost::alloc::string::String,
3436    /// Median dwell time in seconds for this archetype on this screen.
3437    #[prost(double, tag="2")]
3438    pub median_seconds: f64,
3439    /// 75th-percentile dwell time in seconds.
3440    #[prost(double, tag="3")]
3441    pub p75_seconds: f64,
3442    /// Number of distinct sessions aggregated for this screen.
3443    #[prost(int32, tag="4")]
3444    pub session_count: i32,
3445}
3446/// End-to-end response latencies for members of one archetype, in
3447/// seconds. Each percentile is computed across all qualifying campaign
3448/// deliveries for the archetype's members within the rolling window.
3449#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3450pub struct ResponseTimeline {
3451    /// Time from `delivered_at` to `read_at`, in seconds.
3452    #[prost(message, optional, tag="1")]
3453    pub read_after_delivered: ::core::option::Option<LatencyPercentiles>,
3454    /// Time from `read_at` to `acknowledged_at`, in seconds. Only
3455    /// includes deliveries that were both read and acknowledged.
3456    #[prost(message, optional, tag="2")]
3457    pub ack_after_read: ::core::option::Option<LatencyPercentiles>,
3458    /// End-to-end time from `delivered_at` to `acknowledged_at`, in
3459    /// seconds. Only includes deliveries that were acknowledged.
3460    #[prost(message, optional, tag="3")]
3461    pub ack_after_delivered: ::core::option::Option<LatencyPercentiles>,
3462    /// Number of deliveries the timeline is computed over.
3463    #[prost(int32, tag="4")]
3464    pub delivery_count: i32,
3465}
3466/// Latency distribution stats. Values are in seconds.
3467#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3468pub struct LatencyPercentiles {
3469    #[prost(double, tag="1")]
3470    pub p50: f64,
3471    #[prost(double, tag="2")]
3472    pub p75: f64,
3473    #[prost(double, tag="3")]
3474    pub p95: f64,
3475}
3476/// A cohort-level prediction for campaign acknowledgment rate.
3477/// Never targets or scores individuals — always represents an audience aggregate.
3478#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3479pub struct CohortPrediction {
3480    /// Predicted ACK rate for the audience (0.0-1.0).
3481    #[prost(float, tag="1")]
3482    pub predicted_ack_rate: f32,
3483    /// Lower bound of the confidence interval.
3484    #[prost(float, tag="2")]
3485    pub confidence_low: f32,
3486    /// Upper bound of the confidence interval.
3487    #[prost(float, tag="3")]
3488    pub confidence_high: f32,
3489    /// Confidence level based on available data volume.
3490    #[prost(enumeration="ConfidenceLevel", tag="4")]
3491    pub confidence_level: i32,
3492    /// Number of anonymous data points used for this prediction.
3493    #[prost(int32, tag="5")]
3494    pub data_point_count: i32,
3495}
3496/// Advisory information for campaign configuration, combining predictions and archetypes.
3497#[derive(Clone, PartialEq, ::prost::Message)]
3498pub struct CampaignAdvisory {
3499    /// Cohort-level ACK prediction for the target audience.
3500    #[prost(message, optional, tag="1")]
3501    pub predicted_ack: ::core::option::Option<CohortPrediction>,
3502    /// Suggested escalation delay in minutes based on historical cohort patterns.
3503    /// 0 if insufficient data.
3504    #[prost(int32, tag="2")]
3505    pub suggested_escalation_delay_minutes: i32,
3506    /// Behavioral archetypes for the target audience.
3507    #[prost(message, repeated, tag="3")]
3508    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
3509}
3510/// Request to retrieve behavioral archetypes for a group.
3511#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3512pub struct GetGroupArchetypesRequest {
3513    /// ID of the group to query archetypes for. Required.
3514    #[prost(string, tag="1")]
3515    pub group_id: ::prost::alloc::string::String,
3516}
3517/// Response containing behavioral archetypes for a group.
3518#[derive(Clone, PartialEq, ::prost::Message)]
3519pub struct GetGroupArchetypesResponse {
3520    /// Behavioral archetypes for the group (empty if insufficient data).
3521    #[prost(message, repeated, tag="1")]
3522    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
3523    /// Number of anonymous feature vectors used for clustering.
3524    #[prost(int32, tag="2")]
3525    pub data_point_count: i32,
3526    /// Why `archetypes` looks the way it does. Lets the UI render a
3527    /// distinct empty-state affordance for "never trained" vs
3528    /// "below threshold" vs "no clusters" vs "ready". See PipelineState.
3529    #[prost(enumeration="PipelineState", tag="3")]
3530    pub pipeline_state: i32,
3531}
3532/// Request to predict cohort-level ACK rate for a campaign configuration.
3533#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3534pub struct PredictCampaignAckRequest {
3535    /// ID of the target audience group. Required.
3536    #[prost(string, tag="1")]
3537    pub group_id: ::prost::alloc::string::String,
3538    /// Template type (optional, for prediction refinement).
3539    #[prost(string, tag="2")]
3540    pub template_type: ::prost::alloc::string::String,
3541    /// Number of workflow steps (optional, for prediction refinement).
3542    #[prost(int32, tag="3")]
3543    pub workflow_step_count: i32,
3544}
3545/// Response containing a cohort-level ACK prediction.
3546#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3547pub struct PredictCampaignAckResponse {
3548    /// Cohort-level prediction.
3549    #[prost(message, optional, tag="1")]
3550    pub prediction: ::core::option::Option<CohortPrediction>,
3551}
3552/// Request for campaign configuration advisory.
3553#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3554pub struct GetCampaignAdvisoryRequest {
3555    /// ID of the target audience group. Required.
3556    #[prost(string, tag="1")]
3557    pub group_id: ::prost::alloc::string::String,
3558    /// Template ID (optional, for advisory context).
3559    #[prost(string, tag="2")]
3560    pub template_id: ::prost::alloc::string::String,
3561    /// Template version (optional).
3562    #[prost(int32, tag="3")]
3563    pub template_version: i32,
3564    /// Number of workflow steps (optional).
3565    #[prost(int32, tag="4")]
3566    pub workflow_step_count: i32,
3567}
3568/// Response containing campaign advisory information.
3569#[derive(Clone, PartialEq, ::prost::Message)]
3570pub struct GetCampaignAdvisoryResponse {
3571    /// Campaign advisory with prediction, suggested escalation, and archetypes.
3572    #[prost(message, optional, tag="1")]
3573    pub advisory: ::core::option::Option<CampaignAdvisory>,
3574}
3575/// Request to generate an AI narrative for a group's insights.
3576#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3577pub struct GetInsightNarrativeRequest {
3578    /// ID of the group to generate a narrative for. Required.
3579    #[prost(string, tag="1")]
3580    pub group_id: ::prost::alloc::string::String,
3581    /// Name of the prompt template to use (e.g., "campaign-advisory", "archetype-explanation").
3582    #[prost(string, tag="2")]
3583    pub prompt_name: ::prost::alloc::string::String,
3584}
3585/// Response containing an AI-generated narrative.
3586#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3587pub struct GetInsightNarrativeResponse {
3588    /// AI-generated narrative text (Markdown formatted).
3589    #[prost(string, tag="1")]
3590    pub narrative: ::prost::alloc::string::String,
3591    /// Timestamp when the narrative was generated.
3592    #[prost(message, optional, tag="2")]
3593    pub generated_at: ::core::option::Option<::prost_types::Timestamp>,
3594    /// Model identifier used for generation.
3595    #[prost(string, tag="3")]
3596    pub model_id: ::prost::alloc::string::String,
3597}
3598/// Request to manually trigger the ML training pipeline.
3599/// Empty — organization is extracted from the JWT.
3600#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3601pub struct TriggerMlPipelineRequest {
3602}
3603/// Response after triggering the ML pipeline.
3604#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3605pub struct TriggerMlPipelineResponse {
3606    /// Remaining manual retrains allowed this month.
3607    #[prost(int32, tag="1")]
3608    pub remaining_this_month: i32,
3609    /// Timestamp of the last successful training (null if never trained).
3610    #[prost(message, optional, tag="2")]
3611    pub last_trained_at: ::core::option::Option<::prost_types::Timestamp>,
3612}
3613/// Request to manually retrigger archetype clustering for a single group
3614/// without rerunning the full SageMaker training pipeline. Reuses the
3615/// already-deployed clustering model.
3616#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3617pub struct TriggerArchetypeClusteringRequest {
3618    /// Group to recluster. Org is extracted from the JWT.
3619    #[prost(string, tag="1")]
3620    pub group_id: ::prost::alloc::string::String,
3621}
3622/// Response after triggering archetype clustering for one group.
3623#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3624pub struct TriggerArchetypeClusteringResponse {
3625    /// Temporal workflow id — useful for client-side dedupe + operator
3626    /// debugging via the Temporal UI.
3627    #[prost(string, tag="1")]
3628    pub workflow_id: ::prost::alloc::string::String,
3629    /// Remaining manual retrains allowed this month. Shares the same
3630    /// monthly counter as TriggerMLPipeline (ml_manual_limit_monthly).
3631    #[prost(int32, tag="2")]
3632    pub remaining_this_month: i32,
3633    /// Timestamp of the last successful archetype clustering for this
3634    /// (org, group), null if never clustered.
3635    #[prost(message, optional, tag="3")]
3636    pub last_clustered_at: ::core::option::Option<::prost_types::Timestamp>,
3637}
3638/// Request to draft a campaign body for a given archetype using Bedrock.
3639/// Used by the Compass "Target this archetype in a new campaign" CTA to
3640/// pre-fill the campaign creation wizard's body field.
3641#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3642pub struct GenerateCampaignBodyDraftRequest {
3643    /// UUID of the source group whose archetype set the label belongs to.
3644    #[prost(string, tag="1")]
3645    pub group_id: ::prost::alloc::string::String,
3646    /// Stable archetype label, e.g. "Swift Acknowledger".
3647    #[prost(string, tag="2")]
3648    pub archetype_label: ::prost::alloc::string::String,
3649    /// Lane-recommended action copy passed through from the admin (e.g.
3650    /// "Simplify the call-to-action"). Used as a tone hint for the prompt.
3651    #[prost(string, tag="3")]
3652    pub lane_action: ::prost::alloc::string::String,
3653}
3654/// Response containing the generated draft body in Markdown.
3655#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3656pub struct GenerateCampaignBodyDraftResponse {
3657    /// Draft Markdown body, 3-5 sentences. Authored as if written for the
3658    /// recipient — does not mention the archetype name.
3659    #[prost(string, tag="1")]
3660    pub body_markdown: ::prost::alloc::string::String,
3661}
3662// ─── Enums ──────────────────────────────────────────────────────────────────
3663
3664/// Confidence level for cohort-level predictions, based on available data volume.
3665#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3666#[repr(i32)]
3667pub enum ConfidenceLevel {
3668    Unspecified = 0,
3669    /// Fewer than 50 campaigns — predictions based on heuristics/industry benchmarks.
3670    Low = 1,
3671    /// 50-200 campaigns — basic clustering available, wide confidence intervals.
3672    Medium = 2,
3673    /// 200+ campaigns — full ML pipeline, narrow confidence intervals.
3674    High = 3,
3675}
3676impl ConfidenceLevel {
3677    /// String value of the enum field names used in the ProtoBuf definition.
3678    ///
3679    /// The values are not transformed in any way and thus are considered stable
3680    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3681    pub fn as_str_name(&self) -> &'static str {
3682        match self {
3683            Self::Unspecified => "CONFIDENCE_LEVEL_UNSPECIFIED",
3684            Self::Low => "CONFIDENCE_LEVEL_LOW",
3685            Self::Medium => "CONFIDENCE_LEVEL_MEDIUM",
3686            Self::High => "CONFIDENCE_LEVEL_HIGH",
3687        }
3688    }
3689    /// Creates an enum from field names used in the ProtoBuf definition.
3690    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3691        match value {
3692            "CONFIDENCE_LEVEL_UNSPECIFIED" => Some(Self::Unspecified),
3693            "CONFIDENCE_LEVEL_LOW" => Some(Self::Low),
3694            "CONFIDENCE_LEVEL_MEDIUM" => Some(Self::Medium),
3695            "CONFIDENCE_LEVEL_HIGH" => Some(Self::High),
3696            _ => None,
3697        }
3698    }
3699}
3700/// Pipeline state for a group's archetypes. Lets the admin UI render
3701/// distinct empty-state affordances ("run clustering" vs "need N more
3702/// sessions" vs "pipeline ran but audience was too homogeneous") instead
3703/// of treating every empty archetype list the same. Populated by
3704/// InsightsService.GetGroupArchetypes.
3705#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3706#[repr(i32)]
3707pub enum PipelineState {
3708    Unspecified = 0,
3709    /// The ML pipeline has never fired for this org. Archetypes are
3710    /// empty because nothing ran, not because of data shape.
3711    NeverRun = 1,
3712    /// The pipeline ran but the group had fewer than the k-anonymization
3713    /// minimum feature vectors (50), so clustering was skipped. UI
3714    /// renders "keep running campaigns" affordance.
3715    BelowThreshold = 2,
3716    /// The pipeline ran with enough vectors but the clustering provider
3717    /// returned zero clusters — typically means the audience is too
3718    /// homogeneous to separate into distinct archetypes.
3719    NoClusters = 3,
3720    /// Archetypes are populated and ready to render.
3721    Ready = 4,
3722}
3723impl PipelineState {
3724    /// String value of the enum field names used in the ProtoBuf definition.
3725    ///
3726    /// The values are not transformed in any way and thus are considered stable
3727    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3728    pub fn as_str_name(&self) -> &'static str {
3729        match self {
3730            Self::Unspecified => "PIPELINE_STATE_UNSPECIFIED",
3731            Self::NeverRun => "PIPELINE_STATE_NEVER_RUN",
3732            Self::BelowThreshold => "PIPELINE_STATE_BELOW_THRESHOLD",
3733            Self::NoClusters => "PIPELINE_STATE_NO_CLUSTERS",
3734            Self::Ready => "PIPELINE_STATE_READY",
3735        }
3736    }
3737    /// Creates an enum from field names used in the ProtoBuf definition.
3738    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3739        match value {
3740            "PIPELINE_STATE_UNSPECIFIED" => Some(Self::Unspecified),
3741            "PIPELINE_STATE_NEVER_RUN" => Some(Self::NeverRun),
3742            "PIPELINE_STATE_BELOW_THRESHOLD" => Some(Self::BelowThreshold),
3743            "PIPELINE_STATE_NO_CLUSTERS" => Some(Self::NoClusters),
3744            "PIPELINE_STATE_READY" => Some(Self::Ready),
3745            _ => None,
3746        }
3747    }
3748}
3749// ─── Messages ───────────────────────────────────────────────────────────────
3750
3751/// A single reachability registry row, returned by `GetReachability` and
3752/// `ListReachabilityForUser`. The plaintext identifier and envelope ciphertext
3753/// are NEVER returned over the wire — only metadata. The dispatch worker reads
3754/// the plaintext directly from the database and decrypts via KMS.
3755#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3756pub struct Reachability {
3757    /// Server-assigned row identifier (UUID).
3758    #[prost(string, tag="1")]
3759    pub id: ::prost::alloc::string::String,
3760    /// Organization that owns this reachability entry.
3761    #[prost(string, tag="2")]
3762    pub org_id: ::prost::alloc::string::String,
3763    /// User this reachability entry is for.
3764    #[prost(string, tag="3")]
3765    pub user_id: ::prost::alloc::string::String,
3766    /// Channel for which this entry stores a contact identifier.
3767    #[prost(enumeration="ChannelName", tag="4")]
3768    pub channel: i32,
3769    /// When the row was first written.
3770    #[prost(message, optional, tag="5")]
3771    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3772    /// When the row was last upserted.
3773    #[prost(message, optional, tag="6")]
3774    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
3775    /// Optional AWS region identifier (e.g. "eu-west-1") this user's data must
3776    /// remain in for GDPR/residency reasons. Unset means "no constraint."
3777    /// Enforcement happens at dispatch time, not write time.
3778    #[prost(string, optional, tag="7")]
3779    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
3780}
3781/// Per-(org, channel) region allowlist used by the dispatch worker to enforce
3782/// data-residency policy. An empty `allowed_regions` list means "no policy
3783/// configured" — NOT "no regions allowed."
3784#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3785pub struct RegionPolicy {
3786    #[prost(string, tag="1")]
3787    pub org_id: ::prost::alloc::string::String,
3788    #[prost(enumeration="ChannelName", tag="2")]
3789    pub channel: i32,
3790    /// AWS region identifiers (e.g. "eu-west-1", "us-east-1"). Empty list ==
3791    /// "no policy configured" — the dispatch worker SHALL NOT block on empty.
3792    #[prost(string, repeated, tag="3")]
3793    pub allowed_regions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3794    #[prost(message, optional, tag="4")]
3795    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
3796}
3797// ─── Enums ──────────────────────────────────────────────────────────────────
3798
3799/// Terminal status of a single dispatch attempt as returned by the worker-mode
3800/// `DispatchToChannel` RPC. Distinct from the richer `ChannelEventStatus` in
3801/// `channel_events.proto`, which models the audit-trail row for every state
3802/// transition (SENT → DELIVERED → OPENED → …). DispatchStatus is the immediate
3803/// outcome of one worker call.
3804#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3805#[repr(i32)]
3806pub enum DispatchStatus {
3807    /// Default value; should not be used explicitly.
3808    Unspecified = 0,
3809    /// The adapter accepted the message for delivery (provider returned success).
3810    Sent = 1,
3811    /// The adapter returned a terminal error (e.g. recipient blocked, domain not
3812    /// verified). Retries SHALL NOT be attempted; consult `failure_reason`.
3813    Failed = 2,
3814    /// An existing `(dispatch_id, SENT)` row was found by the idempotency guard
3815    /// before the adapter was called; the prior receipt was returned without a
3816    /// second provider call.
3817    Deduped = 3,
3818}
3819impl DispatchStatus {
3820    /// String value of the enum field names used in the ProtoBuf definition.
3821    ///
3822    /// The values are not transformed in any way and thus are considered stable
3823    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3824    pub fn as_str_name(&self) -> &'static str {
3825        match self {
3826            Self::Unspecified => "DISPATCH_STATUS_UNSPECIFIED",
3827            Self::Sent => "DISPATCH_STATUS_SENT",
3828            Self::Failed => "DISPATCH_STATUS_FAILED",
3829            Self::Deduped => "DISPATCH_STATUS_DEDUPED",
3830        }
3831    }
3832    /// Creates an enum from field names used in the ProtoBuf definition.
3833    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3834        match value {
3835            "DISPATCH_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
3836            "DISPATCH_STATUS_SENT" => Some(Self::Sent),
3837            "DISPATCH_STATUS_FAILED" => Some(Self::Failed),
3838            "DISPATCH_STATUS_DEDUPED" => Some(Self::Deduped),
3839            _ => None,
3840        }
3841    }
3842}
3843// ─── DispatchToChannel ──────────────────────────────────────────────────────
3844
3845/// Worker-mode entry point invoked by the Temporal worker for one recipient.
3846/// Idempotent on `dispatch_id`: if a `(dispatch_id, SENT)` row already exists
3847/// in `channel_dispatches`, the worker SHALL return DISPATCH_STATUS_DEDUPED
3848/// without re-invoking the channel adapter.
3849#[derive(Clone, PartialEq, ::prost::Message)]
3850pub struct DispatchToChannelRequest {
3851    /// Idempotency key. Must be stable across retries from pidgr-api side.
3852    #[prost(string, tag="1")]
3853    pub dispatch_id: ::prost::alloc::string::String,
3854    #[prost(string, tag="2")]
3855    pub org_id: ::prost::alloc::string::String,
3856    #[prost(string, tag="3")]
3857    pub user_id: ::prost::alloc::string::String,
3858    /// Which channel adapter to invoke (EMAIL is the Wave 1 implementation).
3859    #[prost(enumeration="ChannelName", tag="4")]
3860    pub channel: i32,
3861    /// Template to render before dispatch.
3862    #[prost(string, tag="5")]
3863    pub template_id: ::prost::alloc::string::String,
3864    /// Per-recipient template variables.
3865    #[prost(map="string, string", tag="6")]
3866    pub template_vars: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
3867    /// BCP-47 locale used to select the template translation.
3868    #[prost(string, tag="7")]
3869    pub locale: ::prost::alloc::string::String,
3870    /// Optional AWS region the worker MUST dispatch from (typically copied from
3871    /// the recipient's reachability row). Unset means "no constraint."
3872    #[prost(string, optional, tag="8")]
3873    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
3874}
3875#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3876pub struct DispatchToChannelResponse {
3877    /// Echoes back the request's `dispatch_id`.
3878    #[prost(string, tag="1")]
3879    pub dispatch_id: ::prost::alloc::string::String,
3880    /// Terminal outcome of this call.
3881    #[prost(enumeration="DispatchStatus", tag="2")]
3882    pub status: i32,
3883    /// Human-readable failure reason; set only when `status` is
3884    /// DISPATCH_STATUS_FAILED.
3885    #[prost(string, optional, tag="3")]
3886    pub failure_reason: ::core::option::Option<::prost::alloc::string::String>,
3887}
3888// ─── UpsertReachability ─────────────────────────────────────────────────────
3889
3890/// Records a recipient identifier for a (user, channel) tuple. The plaintext
3891/// identifier is column-level KMS-encrypted on insert and never logged or
3892/// returned. The server computes the org-scoped HMAC lookup hash so opt-out
3893/// webhooks can find the row without decrypt.
3894#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3895pub struct UpsertReachabilityRequest {
3896    #[prost(string, tag="1")]
3897    pub org_id: ::prost::alloc::string::String,
3898    #[prost(string, tag="2")]
3899    pub user_id: ::prost::alloc::string::String,
3900    #[prost(enumeration="ChannelName", tag="3")]
3901    pub channel: i32,
3902    /// The plaintext identifier (email address, phone number, Slack user ID,
3903    /// Telegram chat ID, etc.). Encrypted at rest server-side. Servers MUST NOT
3904    /// log this field. Clients SHOULD treat this message as sensitive.
3905    #[prost(string, tag="4")]
3906    pub identifier_plaintext: ::prost::alloc::string::String,
3907    /// Optional AWS region this user's data must remain in (e.g. "eu-west-1").
3908    /// Recorded but NOT enforced at write time; enforcement is at dispatch.
3909    #[prost(string, optional, tag="5")]
3910    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
3911}
3912#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3913pub struct UpsertReachabilityResponse {
3914    /// The metadata for the upserted row. Plaintext identifier and envelope
3915    /// ciphertext are intentionally absent.
3916    #[prost(message, optional, tag="1")]
3917    pub reachability: ::core::option::Option<Reachability>,
3918}
3919// ─── RemoveReachability ─────────────────────────────────────────────────────
3920
3921/// Idempotent removal. GDPR Recital 30 audit row is appended via internal-mTLS
3922/// BEFORE the registry row is deleted (see AuditService.Append). If no row
3923/// existed, `removed = false` and no audit row is emitted.
3924#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3925pub struct RemoveReachabilityRequest {
3926    #[prost(string, tag="1")]
3927    pub org_id: ::prost::alloc::string::String,
3928    #[prost(string, tag="2")]
3929    pub user_id: ::prost::alloc::string::String,
3930    #[prost(enumeration="ChannelName", tag="3")]
3931    pub channel: i32,
3932}
3933#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3934pub struct RemoveReachabilityResponse {
3935    /// True if a row was deleted. False if no row existed for the tuple
3936    /// (idempotent success).
3937    #[prost(bool, tag="1")]
3938    pub removed: bool,
3939}
3940// ─── GetReachability ────────────────────────────────────────────────────────
3941
3942/// Returns the reachability metadata for a single (user, channel) tuple.
3943/// Returns NOT_FOUND if no row exists.
3944#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3945pub struct GetReachabilityRequest {
3946    #[prost(string, tag="1")]
3947    pub org_id: ::prost::alloc::string::String,
3948    #[prost(string, tag="2")]
3949    pub user_id: ::prost::alloc::string::String,
3950    #[prost(enumeration="ChannelName", tag="3")]
3951    pub channel: i32,
3952}
3953#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3954pub struct GetReachabilityResponse {
3955    /// Plaintext identifier and envelope ciphertext are intentionally absent.
3956    #[prost(message, optional, tag="1")]
3957    pub reachability: ::core::option::Option<Reachability>,
3958}
3959// ─── ListReachabilityForUser ────────────────────────────────────────────────
3960
3961/// Returns one Reachability entry per channel configured for a (org, user)
3962/// pair. Used by the admin-side per-user matrix view. Plaintext identifiers
3963/// and envelope ciphertext are intentionally absent — the admin UI only needs
3964/// to know which channels are configured.
3965#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3966pub struct ListReachabilityForUserRequest {
3967    #[prost(string, tag="1")]
3968    pub org_id: ::prost::alloc::string::String,
3969    #[prost(string, tag="2")]
3970    pub user_id: ::prost::alloc::string::String,
3971}
3972#[derive(Clone, PartialEq, ::prost::Message)]
3973pub struct ListReachabilityForUserResponse {
3974    /// One entry per channel that has a row for the (org_id, user_id) pair.
3975    #[prost(message, repeated, tag="1")]
3976    pub reachabilities: ::prost::alloc::vec::Vec<Reachability>,
3977}
3978// ─── GetRegionPolicy / SetRegionPolicy ──────────────────────────────────────
3979
3980#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3981pub struct GetRegionPolicyRequest {
3982    #[prost(string, tag="1")]
3983    pub org_id: ::prost::alloc::string::String,
3984    #[prost(enumeration="ChannelName", tag="2")]
3985    pub channel: i32,
3986}
3987#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3988pub struct GetRegionPolicyResponse {
3989    /// Always populated. Empty `allowed_regions` means "no policy configured"
3990    /// — NOT "no regions allowed."
3991    #[prost(message, optional, tag="1")]
3992    pub policy: ::core::option::Option<RegionPolicy>,
3993}
3994/// Admin-only upsert. Empty `allowed_regions` clears the policy.
3995#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3996pub struct SetRegionPolicyRequest {
3997    #[prost(string, tag="1")]
3998    pub org_id: ::prost::alloc::string::String,
3999    #[prost(enumeration="ChannelName", tag="2")]
4000    pub channel: i32,
4001    /// AWS region identifiers (e.g. "eu-west-1"). Empty list == "no policy."
4002    #[prost(string, repeated, tag="3")]
4003    pub allowed_regions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4004}
4005#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4006pub struct SetRegionPolicyResponse {
4007    #[prost(message, optional, tag="1")]
4008    pub policy: ::core::option::Option<RegionPolicy>,
4009}
4010// ─── GetCostCapPolicy / SetCostCapPolicy ────────────────────────────────────
4011
4012/// Get the cost-cap state for the current calendar-month period (UTC). When
4013/// no row exists for `(org_id, channel, period_yyyymm)`, the server returns
4014/// the channel default cap from server config
4015/// (`COST_CAP_DEFAULT_${CHANNEL}_MICROS`) with `used_micros = 0`.
4016#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4017pub struct GetCostCapPolicyRequest {
4018    #[prost(string, tag="1")]
4019    pub org_id: ::prost::alloc::string::String,
4020    #[prost(enumeration="ChannelName", tag="2")]
4021    pub channel: i32,
4022}
4023#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4024pub struct GetCostCapPolicyResponse {
4025    #[prost(string, tag="1")]
4026    pub org_id: ::prost::alloc::string::String,
4027    #[prost(enumeration="ChannelName", tag="2")]
4028    pub channel: i32,
4029    /// Current period's cap in micros (1/1_000_000 of a USD).
4030    #[prost(int64, tag="3")]
4031    pub cap_micros: i64,
4032    /// Current period's accumulated spend in micros.
4033    #[prost(int64, tag="4")]
4034    pub used_micros: i64,
4035    /// Calendar-month period in integer YYYYMM form (e.g. 202605 for May 2026).
4036    #[prost(int32, tag="5")]
4037    pub period_yyyymm: i32,
4038}
4039/// Admin-only upsert of the cap for the current calendar-month period. Future
4040/// periods inherit the most recent SetCostCapPolicy value until the next call.
4041#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4042pub struct SetCostCapPolicyRequest {
4043    #[prost(string, tag="1")]
4044    pub org_id: ::prost::alloc::string::String,
4045    #[prost(enumeration="ChannelName", tag="2")]
4046    pub channel: i32,
4047    #[prost(int64, tag="3")]
4048    pub cap_micros: i64,
4049}
4050#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4051pub struct SetCostCapPolicyResponse {
4052    #[prost(string, tag="1")]
4053    pub org_id: ::prost::alloc::string::String,
4054    #[prost(enumeration="ChannelName", tag="2")]
4055    pub channel: i32,
4056    #[prost(int64, tag="3")]
4057    pub cap_micros: i64,
4058    #[prost(int64, tag="4")]
4059    pub used_micros: i64,
4060    #[prost(int32, tag="5")]
4061    pub period_yyyymm: i32,
4062}
4063// ─── Messages ───────────────────────────────────────────────────────────────
4064
4065/// A shareable invite link that allows users to self-join an organization.
4066/// Links carry a role assignment and optional usage/expiry constraints.
4067#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4068pub struct InviteLink {
4069    /// Unique identifier for the invite link.
4070    #[prost(string, tag="1")]
4071    pub id: ::prost::alloc::string::String,
4072    /// Cryptographically random base64url-encoded token (43 characters).
4073    #[prost(string, tag="2")]
4074    pub token: ::prost::alloc::string::String,
4075    /// ID of the role assigned to users who redeem this link.
4076    #[prost(string, tag="3")]
4077    pub role_id: ::prost::alloc::string::String,
4078    /// Maximum number of times this link can be redeemed.
4079    /// 0 means unlimited.
4080    #[prost(int32, tag="4")]
4081    pub max_uses: i32,
4082    /// Number of times this link has been redeemed.
4083    #[prost(int32, tag="5")]
4084    pub use_count: i32,
4085    /// When the link expires. Empty if no expiry.
4086    #[prost(message, optional, tag="6")]
4087    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
4088    /// When the link was revoked. Empty if not revoked.
4089    #[prost(message, optional, tag="7")]
4090    pub revoked_at: ::core::option::Option<::prost_types::Timestamp>,
4091    /// ID of the admin who created the link.
4092    #[prost(string, tag="8")]
4093    pub created_by: ::prost::alloc::string::String,
4094    /// When the link was created.
4095    #[prost(message, optional, tag="9")]
4096    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4097    /// Data governance region assigned to users who redeem this link. Empty means inherit from org default.
4098    /// Valid values: EU, LATAM, BR, APAC, US.
4099    #[prost(string, tag="10")]
4100    pub data_governance_region: ::prost::alloc::string::String,
4101}
4102/// Request to create a new invite link for the organization.
4103#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4104pub struct CreateInviteLinkRequest {
4105    /// ID of the role to assign. Defaults to the organization's employee role if empty.
4106    #[prost(string, tag="1")]
4107    pub role_id: ::prost::alloc::string::String,
4108    /// Maximum number of redemptions. 0 means unlimited.
4109    #[prost(int32, tag="2")]
4110    pub max_uses: i32,
4111    /// Number of hours until the link expires. 0 means no expiry.
4112    /// Constraints: Valid range 0 to 8760 (1 year).
4113    #[prost(int32, tag="3")]
4114    pub expires_in_hours: i32,
4115    /// Optional data governance region. Users who redeem this link inherit this region. Empty means inherit from org default.
4116    /// Valid values: EU, LATAM, BR, APAC, US.
4117    #[prost(string, tag="4")]
4118    pub data_governance_region: ::prost::alloc::string::String,
4119}
4120/// Response after creating an invite link.
4121#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4122pub struct CreateInviteLinkResponse {
4123    /// The newly created invite link.
4124    #[prost(message, optional, tag="1")]
4125    pub invite_link: ::core::option::Option<InviteLink>,
4126    /// Full URL for sharing (e.g. "<https://app.pidgr.com/join?token=<TOKEN>">).
4127    #[prost(string, tag="2")]
4128    pub url: ::prost::alloc::string::String,
4129}
4130/// Request to list all invite links for the organization.
4131#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4132pub struct ListInviteLinksRequest {
4133}
4134/// Response containing all invite links for the organization.
4135#[derive(Clone, PartialEq, ::prost::Message)]
4136pub struct ListInviteLinksResponse {
4137    /// All invite links (active, expired, maxed-out, and revoked), ordered by creation date descending.
4138    #[prost(message, repeated, tag="1")]
4139    pub invite_links: ::prost::alloc::vec::Vec<InviteLink>,
4140}
4141/// Request to revoke an invite link.
4142#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4143pub struct RevokeInviteLinkRequest {
4144    /// ID of the invite link to revoke. Required.
4145    #[prost(string, tag="1")]
4146    pub invite_link_id: ::prost::alloc::string::String,
4147}
4148/// Response after revoking an invite link.
4149#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4150pub struct RevokeInviteLinkResponse {
4151}
4152/// Request to redeem an invite link (authenticated — email extracted from JWT).
4153#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4154pub struct RedeemInviteLinkRequest {
4155    /// The invite link token from the URL query parameter.
4156    #[prost(string, tag="1")]
4157    pub token: ::prost::alloc::string::String,
4158}
4159/// Response after redeeming an invite link.
4160#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4161pub struct RedeemInviteLinkResponse {
4162    /// Name of the organization the user was added to.
4163    #[prost(string, tag="1")]
4164    pub organization_name: ::prost::alloc::string::String,
4165}
4166/// Request to validate an invite link and provision a user account if needed (unauthenticated).
4167#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4168pub struct ValidateInviteLinkRequest {
4169    /// The invite link token from the URL query parameter.
4170    #[prost(string, tag="1")]
4171    pub token: ::prost::alloc::string::String,
4172    /// Email address of the user joining the organization.
4173    /// Constraints: Max length 254 characters (RFC 5321).
4174    #[prost(string, tag="2")]
4175    pub email: ::prost::alloc::string::String,
4176}
4177/// Response after validating an invite link.
4178#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4179pub struct ValidateInviteLinkResponse {
4180    /// Name of the organization the invite link belongs to.
4181    #[prost(string, tag="1")]
4182    pub organization_name: ::prost::alloc::string::String,
4183}
4184// ─── Messages ───────────────────────────────────────────────────────────────
4185
4186/// Request to invite a new user to the organization.
4187#[derive(Clone, PartialEq, ::prost::Message)]
4188pub struct InviteUserRequest {
4189    /// Email address to send the invitation to.
4190    /// Constraints: Max length 254 characters (RFC 5321).
4191    #[prost(string, tag="1")]
4192    pub email: ::prost::alloc::string::String,
4193    /// Display name for the invited user.
4194    /// Constraints: Max length 200 characters.
4195    #[prost(string, tag="2")]
4196    pub name: ::prost::alloc::string::String,
4197    /// ID of the role to assign. Defaults to the organization's employee role if empty.
4198    #[prost(string, tag="4")]
4199    pub role_id: ::prost::alloc::string::String,
4200    /// Optional profile attributes to pre-fill at invitation time.
4201    #[prost(message, optional, tag="5")]
4202    pub profile: ::core::option::Option<UserProfile>,
4203    /// Optional data governance region for the invited user. Empty means inherit from org default.
4204    /// Valid values: EU, LATAM, BR, APAC, US.
4205    #[prost(string, tag="6")]
4206    pub data_governance_region: ::prost::alloc::string::String,
4207}
4208/// Response after inviting a user.
4209#[derive(Clone, PartialEq, ::prost::Message)]
4210pub struct InviteUserResponse {
4211    /// The newly created user (status: INVITED).
4212    #[prost(message, optional, tag="1")]
4213    pub user: ::core::option::Option<User>,
4214}
4215/// Request to retrieve a user by ID.
4216#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4217pub struct GetUserRequest {
4218    /// ID of the user to retrieve.
4219    #[prost(string, tag="1")]
4220    pub user_id: ::prost::alloc::string::String,
4221}
4222/// Response containing the requested user.
4223#[derive(Clone, PartialEq, ::prost::Message)]
4224pub struct GetUserResponse {
4225    /// The requested user.
4226    #[prost(message, optional, tag="1")]
4227    pub user: ::core::option::Option<User>,
4228}
4229/// Request to list users in the organization with pagination.
4230#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4231pub struct ListUsersRequest {
4232    /// Pagination parameters.
4233    #[prost(message, optional, tag="1")]
4234    pub pagination: ::core::option::Option<Pagination>,
4235}
4236/// Response containing a page of users.
4237#[derive(Clone, PartialEq, ::prost::Message)]
4238pub struct ListUsersResponse {
4239    /// List of users in this page.
4240    #[prost(message, repeated, tag="1")]
4241    pub users: ::prost::alloc::vec::Vec<User>,
4242    /// Pagination metadata for fetching subsequent pages.
4243    #[prost(message, optional, tag="2")]
4244    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4245}
4246/// Request to change a user's role within the organization.
4247#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4248pub struct UpdateUserRoleRequest {
4249    /// ID of the user whose role to update.
4250    #[prost(string, tag="1")]
4251    pub user_id: ::prost::alloc::string::String,
4252    /// ID of the new role to assign.
4253    #[prost(string, tag="2")]
4254    pub role_id: ::prost::alloc::string::String,
4255}
4256/// Response after updating a user's role.
4257#[derive(Clone, PartialEq, ::prost::Message)]
4258pub struct UpdateUserRoleResponse {
4259    /// The updated user with the new role.
4260    #[prost(message, optional, tag="1")]
4261    pub user: ::core::option::Option<User>,
4262}
4263/// Request to deactivate a user within the organization.
4264#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4265pub struct DeactivateUserRequest {
4266    /// ID of the user to deactivate.
4267    #[prost(string, tag="1")]
4268    pub user_id: ::prost::alloc::string::String,
4269}
4270/// Response after deactivating a user.
4271#[derive(Clone, PartialEq, ::prost::Message)]
4272pub struct DeactivateUserResponse {
4273    /// The deactivated user (status: DEACTIVATED).
4274    #[prost(message, optional, tag="1")]
4275    pub user: ::core::option::Option<User>,
4276}
4277/// Request to reactivate a deactivated user.
4278#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4279pub struct ReactivateUserRequest {
4280    /// ID of the user to reactivate.
4281    #[prost(string, tag="1")]
4282    pub user_id: ::prost::alloc::string::String,
4283}
4284/// Response after reactivating a user.
4285#[derive(Clone, PartialEq, ::prost::Message)]
4286pub struct ReactivateUserResponse {
4287    /// The reactivated user (status: INVITED).
4288    #[prost(message, optional, tag="1")]
4289    pub user: ::core::option::Option<User>,
4290}
4291/// Request to revoke an invitation for a user who has not yet registered.
4292#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4293pub struct RevokeInviteRequest {
4294    /// ID of the invited user to remove.
4295    /// Constraints: UUID format (36 characters).
4296    #[prost(string, tag="1")]
4297    pub user_id: ::prost::alloc::string::String,
4298}
4299/// Response after revoking an invitation. Empty on success.
4300#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4301pub struct RevokeInviteResponse {
4302}
4303/// Request to update a user's profile attributes.
4304#[derive(Clone, PartialEq, ::prost::Message)]
4305pub struct UpdateUserProfileRequest {
4306    /// ID of the user whose profile to update.
4307    /// Empty or matching the caller's own ID allows self-update without PERMISSION_MEMBERS_MANAGE.
4308    #[prost(string, tag="1")]
4309    pub user_id: ::prost::alloc::string::String,
4310    /// Profile attributes to set. All provided fields overwrite existing values.
4311    #[prost(message, optional, tag="2")]
4312    pub profile: ::core::option::Option<UserProfile>,
4313}
4314/// Response after updating a user's profile.
4315#[derive(Clone, PartialEq, ::prost::Message)]
4316pub struct UpdateUserProfileResponse {
4317    /// The updated user with the new profile.
4318    #[prost(message, optional, tag="1")]
4319    pub user: ::core::option::Option<User>,
4320}
4321/// Request to retrieve the caller's platform settings.
4322#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4323pub struct GetUserSettingsRequest {
4324}
4325/// Response containing the caller's platform settings.
4326#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4327pub struct GetUserSettingsResponse {
4328    /// Current settings. Fields at their default value indicate the platform default.
4329    #[prost(message, optional, tag="1")]
4330    pub settings: ::core::option::Option<UserSettings>,
4331}
4332/// Request to update the caller's platform settings.
4333#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4334pub struct UpdateUserSettingsRequest {
4335    /// Settings to update. Only fields with non-default (non-UNSPECIFIED) values
4336    /// are applied; default-valued fields are left unchanged.
4337    #[prost(message, optional, tag="1")]
4338    pub settings: ::core::option::Option<UserSettings>,
4339}
4340/// Response after updating the caller's platform settings.
4341#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4342pub struct UpdateUserSettingsResponse {
4343    /// The full settings after the update.
4344    #[prost(message, optional, tag="1")]
4345    pub settings: ::core::option::Option<UserSettings>,
4346}
4347/// Request to invite multiple users to the organization in a single call.
4348#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4349pub struct BulkInviteUsersRequest {
4350    /// Email addresses to invite.
4351    /// Constraints: Min 1, max 100 emails. Duplicates are deduplicated before processing.
4352    #[prost(string, repeated, tag="1")]
4353    pub emails: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4354    /// ID of the role to assign. Defaults to the organization's employee role if empty.
4355    #[prost(string, tag="2")]
4356    pub role_id: ::prost::alloc::string::String,
4357}
4358/// Per-email result within a bulk invite operation.
4359#[derive(Clone, PartialEq, ::prost::Message)]
4360pub struct BulkInviteResult {
4361    /// The email address that was processed.
4362    #[prost(string, tag="1")]
4363    pub email: ::prost::alloc::string::String,
4364    /// Whether the invitation succeeded.
4365    #[prost(bool, tag="2")]
4366    pub success: bool,
4367    /// Error message if the invitation failed (e.g. "user already exists").
4368    /// Empty on success.
4369    #[prost(string, tag="3")]
4370    pub error: ::prost::alloc::string::String,
4371    /// The created user. Only set on success.
4372    #[prost(message, optional, tag="4")]
4373    pub user: ::core::option::Option<User>,
4374}
4375/// Response after bulk inviting users.
4376#[derive(Clone, PartialEq, ::prost::Message)]
4377pub struct BulkInviteUsersResponse {
4378    /// Per-email results in the same order as the deduplicated input.
4379    #[prost(message, repeated, tag="1")]
4380    pub results: ::prost::alloc::vec::Vec<BulkInviteResult>,
4381    /// Number of users successfully invited.
4382    #[prost(int32, tag="2")]
4383    pub invited_count: i32,
4384    /// Number of emails that failed.
4385    #[prost(int32, tag="3")]
4386    pub failed_count: i32,
4387}
4388/// Request to confirm passkey enrollment after client-side WebAuthn registration.
4389/// The server verifies that the caller has at least one registered WebAuthn
4390/// credential before setting the enrollment attribute.
4391#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4392pub struct ConfirmPasskeyEnrollmentRequest {
4393}
4394/// Response after confirming passkey enrollment.
4395#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4396pub struct ConfirmPasskeyEnrollmentResponse {
4397    /// Whether enrollment was confirmed and the user attribute was updated.
4398    #[prost(bool, tag="1")]
4399    pub confirmed: bool,
4400}
4401/// Request to update a user's data governance region.
4402#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4403pub struct UpdateUserRegionRequest {
4404    /// ID of the user whose region to update. Required.
4405    #[prost(string, tag="1")]
4406    pub user_id: ::prost::alloc::string::String,
4407    /// New governance region, or empty to inherit from org default.
4408    /// Valid values: EU, LATAM, BR, APAC, US.
4409    #[prost(string, tag="2")]
4410    pub data_governance_region: ::prost::alloc::string::String,
4411}
4412/// Response after updating a user's governance region.
4413#[derive(Clone, PartialEq, ::prost::Message)]
4414pub struct UpdateUserRegionResponse {
4415    /// The updated user.
4416    #[prost(message, optional, tag="1")]
4417    pub user: ::core::option::Option<User>,
4418    /// Temporal workflow ID for the region migration, if a migration was triggered.
4419    /// Empty if the region didn't actually change.
4420    #[prost(string, tag="2")]
4421    pub migration_workflow_id: ::prost::alloc::string::String,
4422}
4423// ─── Messages ───────────────────────────────────────────────────────────────
4424
4425/// A single non-retired pepper version. Returned by GetPeppers.
4426///
4427/// During a rotation overlap, multiple versions are returned — callers
4428/// (e.g. pidgr-integrations) compute lookup hashes under EVERY returned
4429/// version to write or match against `identifier_lookup_hash_v1` and
4430/// `identifier_lookup_hash_v2` on the reachability registry.
4431#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4432pub struct Pepper {
4433    /// Monotonically-increasing version number. Lower versions retire first.
4434    #[prost(int32, tag="1")]
4435    pub version: i32,
4436    /// Raw HMAC key material. Sensitive — callers MUST NOT log or persist
4437    /// this value to disk. In-memory caching keyed on (org_id, version) with
4438    /// a short TTL is permitted and expected.
4439    #[prost(bytes="vec", tag="2")]
4440    pub key_material: ::prost::alloc::vec::Vec<u8>,
4441}
4442/// Request to fetch the active (non-retired) peppers for one org/purpose.
4443///
4444/// Auth: internal-mTLS only. This RPC exposes raw cryptographic key material
4445/// and MUST NOT be reachable from the public ingress or from JWT-authenticated
4446/// clients. The server SHALL reject any caller whose mTLS identity is not on
4447/// the configured allowlist.
4448#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4449pub struct GetPeppersRequest {
4450    /// Organization whose peppers are requested.
4451    #[prost(string, tag="1")]
4452    pub org_id: ::prost::alloc::string::String,
4453    /// Purpose identifier scoping which key family to return. Use
4454    /// `"reachability_lookup"` for the pidgr-integrations registry lookup hash.
4455    #[prost(string, tag="2")]
4456    pub purpose: ::prost::alloc::string::String,
4457}
4458#[derive(Clone, PartialEq, ::prost::Message)]
4459pub struct GetPeppersResponse {
4460    /// All non-retired pepper versions for the (org_id, purpose) pair, in
4461    /// ascending version order. Typically exactly one entry; two during a
4462    /// rotation overlap window; zero only when no pepper has ever been
4463    /// generated for this (org, purpose).
4464    #[prost(message, repeated, tag="1")]
4465    pub peppers: ::prost::alloc::vec::Vec<Pepper>,
4466}
4467// ─── Messages ───────────────────────────────────────────────────────────────
4468
4469/// Maps an identity provider claim to a user profile field.
4470/// Used for automatic profile population when users authenticate via SSO/SAML.
4471#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4472pub struct SsoAttributeMapping {
4473    /// Claim name from the identity provider (e.g. "urn:oid:2.5.4.11", "given_name").
4474    /// Constraints: Max length 500 characters.
4475    #[prost(string, tag="1")]
4476    pub idp_claim: ::prost::alloc::string::String,
4477    /// Target UserProfile field name (e.g. "department", "first_name").
4478    /// For custom attributes, use "custom:" prefix (e.g. "custom:cost_center").
4479    /// Constraints: Max length 100 characters.
4480    #[prost(string, tag="2")]
4481    pub profile_field: ::prost::alloc::string::String,
4482}
4483/// An organization (tenant) in the Pidgr platform.
4484#[derive(Clone, PartialEq, ::prost::Message)]
4485pub struct Organization {
4486    /// Unique identifier for the organization.
4487    #[prost(string, tag="1")]
4488    pub id: ::prost::alloc::string::String,
4489    /// Organization display name.
4490    /// Constraints: Max length 200 characters.
4491    #[prost(string, tag="2")]
4492    pub name: ::prost::alloc::string::String,
4493    /// Default workflow used when campaigns don't specify one.
4494    #[prost(message, optional, tag="3")]
4495    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
4496    /// Timestamp when the organization was created.
4497    #[prost(message, optional, tag="4")]
4498    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4499    /// Industry vertical.
4500    #[prost(enumeration="Industry", tag="5")]
4501    pub industry: i32,
4502    /// Employee headcount range.
4503    #[prost(enumeration="CompanySize", tag="6")]
4504    pub company_size: i32,
4505    /// SSO identity provider claim-to-profile mappings.
4506    /// Empty when the organization does not use SSO.
4507    #[prost(message, repeated, tag="7")]
4508    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
4509    /// Default language for new users in this organization.
4510    /// Empty means no org default (users auto-detect from device/browser).
4511    /// Valid values: en, es, pt-BR, zh, ja.
4512    #[prost(string, tag="8")]
4513    pub default_locale: ::prost::alloc::string::String,
4514    /// Organization lifecycle type.
4515    #[prost(enumeration="OrgType", tag="9")]
4516    pub org_type: i32,
4517    /// Expiration time for sandbox organizations. Empty for standard orgs.
4518    #[prost(message, optional, tag="10")]
4519    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
4520    /// Data governance framework (EU, LATAM, BR, APAC, US).
4521    /// Determines legal framework, DPA template, and Bedrock endpoint routing.
4522    #[prost(string, tag="11")]
4523    pub data_governance_region: ::prost::alloc::string::String,
4524    /// AWS region for content storage (resolved from data_governance_region).
4525    /// e.g., "eu-west-1", "us-east-1".
4526    #[prost(string, tag="12")]
4527    pub data_content_region: ::prost::alloc::string::String,
4528    /// ─── ML pipeline settings ──────────────────────────────────────────────────
4529    /// Cold-start threshold: completed campaigns below this count trigger immediate
4530    /// retraining. At or above, the org is flagged for the weekly cron.
4531    /// Default 10, range 1-100.
4532    #[prost(int32, tag="13")]
4533    pub ml_retrain_cold_threshold: i32,
4534    /// Whether cancelled campaigns count toward the training counter. Default true.
4535    #[prost(bool, tag="14")]
4536    pub ml_cancelled_counts: bool,
4537    /// Monthly limit on manual retrain triggers. Default 3, range 0-10.
4538    #[prost(int32, tag="15")]
4539    pub ml_manual_limit_monthly: i32,
4540    /// Number of manual retrains used in the current month (resets monthly).
4541    #[prost(int32, tag="16")]
4542    pub ml_manual_retrains_used: i32,
4543    /// Whether the org is flagged for the next weekly cron run.
4544    #[prost(bool, tag="17")]
4545    pub ml_needs_retrain: bool,
4546    /// Campaigns completed since the last ML training run.
4547    #[prost(int32, tag="18")]
4548    pub campaigns_since_last_training: i32,
4549    /// Total campaigns completed across the organization lifetime.
4550    #[prost(int32, tag="19")]
4551    pub total_completed_campaigns: i32,
4552    /// Timestamp of the most recent successful ML training. Empty if never trained.
4553    #[prost(message, optional, tag="20")]
4554    pub last_ml_training_at: ::core::option::Option<::prost_types::Timestamp>,
4555}
4556/// Request to create a new organization.
4557/// JWT auth only — the authenticated caller becomes the initial admin. Additional
4558/// admins are added via CreateInviteLink after the org exists.
4559#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4560pub struct CreateOrganizationRequest {
4561    /// Name for the new organization.
4562    /// Constraints: Max length 200 characters.
4563    #[prost(string, tag="1")]
4564    pub name: ::prost::alloc::string::String,
4565    /// Industry vertical for the organization.
4566    #[prost(enumeration="Industry", tag="2")]
4567    pub industry: i32,
4568    /// Employee headcount range.
4569    #[prost(enumeration="CompanySize", tag="3")]
4570    pub company_size: i32,
4571    /// Access code required during early access.
4572    /// Format: PIDGR-XXXXXXXX (8 alphanumeric characters).
4573    #[prost(string, tag="4")]
4574    pub access_code: ::prost::alloc::string::String,
4575    /// Data governance framework. Defaults to "US" if omitted.
4576    /// Valid values: EU, LATAM, BR, APAC, US.
4577    #[prost(string, tag="5")]
4578    pub data_governance_region: ::prost::alloc::string::String,
4579    /// Optional bootstrap fixture to seed the organization with starter data.
4580    /// Empty string means the default fixture.
4581    #[prost(string, tag="6")]
4582    pub fixture_id: ::prost::alloc::string::String,
4583}
4584/// Response after creating an organization.
4585#[derive(Clone, PartialEq, ::prost::Message)]
4586pub struct CreateOrganizationResponse {
4587    /// The newly created organization.
4588    #[prost(message, optional, tag="1")]
4589    pub organization: ::core::option::Option<Organization>,
4590    /// The admin user created for the organization.
4591    #[prost(message, optional, tag="2")]
4592    pub admin_user: ::core::option::Option<User>,
4593}
4594/// Request to retrieve the organization for the authenticated user.
4595#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4596pub struct GetOrganizationRequest {
4597}
4598/// Response containing the organization.
4599#[derive(Clone, PartialEq, ::prost::Message)]
4600pub struct GetOrganizationResponse {
4601    /// The organization the authenticated user belongs to.
4602    #[prost(message, optional, tag="1")]
4603    pub organization: ::core::option::Option<Organization>,
4604}
4605/// Request to update organization settings.
4606#[derive(Clone, PartialEq, ::prost::Message)]
4607pub struct UpdateOrganizationRequest {
4608    /// New organization name. Empty string leaves unchanged.
4609    /// Constraints: Max length 200 characters.
4610    #[prost(string, tag="1")]
4611    pub name: ::prost::alloc::string::String,
4612    /// New default workflow definition. Null leaves unchanged.
4613    #[prost(message, optional, tag="2")]
4614    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
4615    /// New industry vertical. UNSPECIFIED leaves unchanged.
4616    #[prost(enumeration="Industry", tag="3")]
4617    pub industry: i32,
4618    /// New employee headcount range. UNSPECIFIED leaves unchanged.
4619    #[prost(enumeration="CompanySize", tag="4")]
4620    pub company_size: i32,
4621    /// New default language for new users. Empty string leaves unchanged.
4622    /// Valid values: en, es, pt-BR, zh, ja.
4623    #[prost(string, tag="5")]
4624    pub default_locale: ::prost::alloc::string::String,
4625    /// New ML cold-start threshold. 0 leaves unchanged, otherwise must be in \[1, 100\].
4626    #[prost(int32, tag="6")]
4627    pub ml_retrain_cold_threshold: i32,
4628    /// New ML cancelled-counts flag. Uses google.protobuf.BoolValue-style semantics
4629    /// via optional to distinguish "not provided" from "set to false".
4630    #[prost(bool, optional, tag="7")]
4631    pub ml_cancelled_counts: ::core::option::Option<bool>,
4632    /// New ML monthly manual limit. Negative leaves unchanged, otherwise must be in \[0, 10\].
4633    /// Encoded as int32 with -1 meaning "leave unchanged".
4634    #[prost(int32, tag="8")]
4635    pub ml_manual_limit_monthly: i32,
4636}
4637/// Response after updating the organization.
4638#[derive(Clone, PartialEq, ::prost::Message)]
4639pub struct UpdateOrganizationResponse {
4640    /// The updated organization.
4641    #[prost(message, optional, tag="1")]
4642    pub organization: ::core::option::Option<Organization>,
4643}
4644/// Request to replace all SSO attribute mappings for the organization.
4645#[derive(Clone, PartialEq, ::prost::Message)]
4646pub struct UpdateSsoAttributeMappingsRequest {
4647    /// Complete list of SSO mappings (replaces all existing mappings).
4648    #[prost(message, repeated, tag="1")]
4649    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
4650}
4651/// Response after updating SSO attribute mappings.
4652#[derive(Clone, PartialEq, ::prost::Message)]
4653pub struct UpdateSsoAttributeMappingsResponse {
4654    /// The updated organization with the new SSO mappings.
4655    #[prost(message, optional, tag="1")]
4656    pub organization: ::core::option::Option<Organization>,
4657}
4658/// Request to rotate the analytics salt and optionally increase the bucket count.
4659#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4660pub struct RotateAnalyticsSaltRequest {
4661    /// New bucket count. Must be >= current bucket count. 0 means keep current.
4662    #[prost(int32, tag="1")]
4663    pub new_bucket_count: i32,
4664}
4665/// Response after rotating the analytics salt.
4666#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4667pub struct RotateAnalyticsSaltResponse {
4668    /// The new bucket count after rotation.
4669    #[prost(int32, tag="1")]
4670    pub bucket_count: i32,
4671}
4672/// Request to update the analytics epsilon (differential privacy parameter).
4673#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4674pub struct UpdateAnalyticsEpsilonRequest {
4675    /// New epsilon value. Must be in range \[0.5, 5.0\].
4676    #[prost(float, tag="1")]
4677    pub epsilon: f32,
4678}
4679/// Response after updating the analytics epsilon.
4680#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4681pub struct UpdateAnalyticsEpsilonResponse {
4682    /// The new epsilon value.
4683    #[prost(float, tag="1")]
4684    pub epsilon: f32,
4685}
4686/// Request to create a sandbox organization for testing.
4687#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4688pub struct CreateSandboxOrganizationRequest {
4689    /// Name for the sandbox organization.
4690    /// Constraints: Max length 200 characters.
4691    #[prost(string, tag="1")]
4692    pub name: ::prost::alloc::string::String,
4693    /// Required expiration time. Max 30 days from now for interactive callers;
4694    /// API-key callers may set shorter TTLs for ephemeral test sandboxes.
4695    #[prost(message, optional, tag="2")]
4696    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
4697    /// Data governance framework. Defaults to "US" if omitted.
4698    /// Valid values: EU, LATAM, BR, APAC, US.
4699    #[prost(string, tag="3")]
4700    pub data_governance_region: ::prost::alloc::string::String,
4701    /// Optional bootstrap fixture to seed the sandbox with starter data.
4702    /// Empty string means the default fixture.
4703    /// Must match an id returned by ListSandboxFixtures.
4704    #[prost(string, tag="4")]
4705    pub fixture_id: ::prost::alloc::string::String,
4706}
4707/// Response after creating a sandbox organization.
4708#[derive(Clone, PartialEq, ::prost::Message)]
4709pub struct CreateSandboxOrganizationResponse {
4710    /// The newly created sandbox organization (org_type: SANDBOX).
4711    #[prost(message, optional, tag="1")]
4712    pub organization: ::core::option::Option<Organization>,
4713    /// The admin user created for the sandbox.
4714    #[prost(message, optional, tag="2")]
4715    pub admin_user: ::core::option::Option<User>,
4716}
4717/// Request to delete a sandbox organization. Only callable for orgs with
4718/// org_type=SANDBOX. Allowed for super admins of the sandbox or the creator.
4719#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4720pub struct DeleteSandboxOrganizationRequest {
4721    /// ID of the sandbox organization to delete.
4722    #[prost(string, tag="1")]
4723    pub org_id: ::prost::alloc::string::String,
4724}
4725/// Response after requesting deletion. Deletion runs asynchronously via
4726/// the DeleteOrgWorkflow; a success response means the workflow started.
4727#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4728pub struct DeleteSandboxOrganizationResponse {
4729    /// ID of the Temporal workflow handling the deletion.
4730    #[prost(string, tag="1")]
4731    pub workflow_id: ::prost::alloc::string::String,
4732}
4733/// A bootstrap fixture that can be applied when creating a new organization.
4734#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4735pub struct SandboxFixture {
4736    /// Stable UUID for referencing this fixture.
4737    #[prost(string, tag="1")]
4738    pub id: ::prost::alloc::string::String,
4739    /// Display name for admin UI (e.g. "Sample data").
4740    #[prost(string, tag="2")]
4741    pub name: ::prost::alloc::string::String,
4742    /// Description shown alongside the fixture option in the UI.
4743    #[prost(string, tag="3")]
4744    pub description: ::prost::alloc::string::String,
4745    /// Exactly one fixture has is_default=true. Clients that show a simple
4746    /// "fill with sample data" checkbox send this fixture's id when checked.
4747    #[prost(bool, tag="4")]
4748    pub is_default: bool,
4749}
4750/// Request to list all bootstrap fixtures available for seeding.
4751/// No parameters — catalog is the same for all callers.
4752#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4753pub struct ListSandboxFixturesRequest {
4754}
4755/// Response containing the bootstrap fixture catalog.
4756#[derive(Clone, PartialEq, ::prost::Message)]
4757pub struct ListSandboxFixturesResponse {
4758    /// All registered fixtures, ordered by name.
4759    #[prost(message, repeated, tag="1")]
4760    pub fixtures: ::prost::alloc::vec::Vec<SandboxFixture>,
4761}
4762/// Request to list all organizations the authenticated user belongs to.
4763/// No parameters — user identity is extracted from the JWT sub claim.
4764#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4765pub struct ListUserOrganizationsRequest {
4766}
4767/// Response containing all organizations the authenticated user belongs to.
4768#[derive(Clone, PartialEq, ::prost::Message)]
4769pub struct ListUserOrganizationsResponse {
4770    /// Organizations the user belongs to, ordered by created_at ascending.
4771    /// Excludes expired sandbox organizations.
4772    #[prost(message, repeated, tag="1")]
4773    pub organizations: ::prost::alloc::vec::Vec<Organization>,
4774}
4775/// Request to list only the sandbox organizations the authenticated user
4776/// belongs to (i.e. orgs where org_type = SANDBOX, filtered from the full
4777/// membership set). No parameters — user identity is extracted from the JWT
4778/// sub claim.
4779#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4780pub struct ListUserSandboxesRequest {
4781}
4782/// Response containing the user's sandbox organizations.
4783#[derive(Clone, PartialEq, ::prost::Message)]
4784pub struct ListUserSandboxesResponse {
4785    /// Sandbox organizations the user belongs to, ordered by expires_at
4786    /// ascending (soonest-expiring first — matches the admin UI
4787    /// /organization/sandboxes ordering). Excludes already-expired sandboxes
4788    /// (those are pending cleanup by SandboxCleanupWorkflow).
4789    #[prost(message, repeated, tag="1")]
4790    pub sandboxes: ::prost::alloc::vec::Vec<Organization>,
4791}
4792// ─── Enums ───────────────────────────────────────────────────────────────────
4793
4794/// Industry vertical for an organization.
4795#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4796#[repr(i32)]
4797pub enum Industry {
4798    Unspecified = 0,
4799    Technology = 1,
4800    Finance = 2,
4801    Healthcare = 3,
4802    Education = 4,
4803    Retail = 5,
4804    Manufacturing = 6,
4805    Media = 7,
4806    Other = 8,
4807}
4808impl Industry {
4809    /// String value of the enum field names used in the ProtoBuf definition.
4810    ///
4811    /// The values are not transformed in any way and thus are considered stable
4812    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4813    pub fn as_str_name(&self) -> &'static str {
4814        match self {
4815            Self::Unspecified => "INDUSTRY_UNSPECIFIED",
4816            Self::Technology => "INDUSTRY_TECHNOLOGY",
4817            Self::Finance => "INDUSTRY_FINANCE",
4818            Self::Healthcare => "INDUSTRY_HEALTHCARE",
4819            Self::Education => "INDUSTRY_EDUCATION",
4820            Self::Retail => "INDUSTRY_RETAIL",
4821            Self::Manufacturing => "INDUSTRY_MANUFACTURING",
4822            Self::Media => "INDUSTRY_MEDIA",
4823            Self::Other => "INDUSTRY_OTHER",
4824        }
4825    }
4826    /// Creates an enum from field names used in the ProtoBuf definition.
4827    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4828        match value {
4829            "INDUSTRY_UNSPECIFIED" => Some(Self::Unspecified),
4830            "INDUSTRY_TECHNOLOGY" => Some(Self::Technology),
4831            "INDUSTRY_FINANCE" => Some(Self::Finance),
4832            "INDUSTRY_HEALTHCARE" => Some(Self::Healthcare),
4833            "INDUSTRY_EDUCATION" => Some(Self::Education),
4834            "INDUSTRY_RETAIL" => Some(Self::Retail),
4835            "INDUSTRY_MANUFACTURING" => Some(Self::Manufacturing),
4836            "INDUSTRY_MEDIA" => Some(Self::Media),
4837            "INDUSTRY_OTHER" => Some(Self::Other),
4838            _ => None,
4839        }
4840    }
4841}
4842/// Employee headcount range for an organization.
4843#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4844#[repr(i32)]
4845pub enum CompanySize {
4846    Unspecified = 0,
4847    CompanySize1200 = 1,
4848    CompanySize200500 = 2,
4849    CompanySize5001000 = 3,
4850    CompanySize10005000 = 4,
4851    CompanySize5000Plus = 5,
4852}
4853impl CompanySize {
4854    /// String value of the enum field names used in the ProtoBuf definition.
4855    ///
4856    /// The values are not transformed in any way and thus are considered stable
4857    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4858    pub fn as_str_name(&self) -> &'static str {
4859        match self {
4860            Self::Unspecified => "COMPANY_SIZE_UNSPECIFIED",
4861            Self::CompanySize1200 => "COMPANY_SIZE_1_200",
4862            Self::CompanySize200500 => "COMPANY_SIZE_200_500",
4863            Self::CompanySize5001000 => "COMPANY_SIZE_500_1000",
4864            Self::CompanySize10005000 => "COMPANY_SIZE_1000_5000",
4865            Self::CompanySize5000Plus => "COMPANY_SIZE_5000_PLUS",
4866        }
4867    }
4868    /// Creates an enum from field names used in the ProtoBuf definition.
4869    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4870        match value {
4871            "COMPANY_SIZE_UNSPECIFIED" => Some(Self::Unspecified),
4872            "COMPANY_SIZE_1_200" => Some(Self::CompanySize1200),
4873            "COMPANY_SIZE_200_500" => Some(Self::CompanySize200500),
4874            "COMPANY_SIZE_500_1000" => Some(Self::CompanySize5001000),
4875            "COMPANY_SIZE_1000_5000" => Some(Self::CompanySize10005000),
4876            "COMPANY_SIZE_5000_PLUS" => Some(Self::CompanySize5000Plus),
4877            _ => None,
4878        }
4879    }
4880}
4881/// Classification of an organization's lifecycle type.
4882#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4883#[repr(i32)]
4884pub enum OrgType {
4885    Unspecified = 0,
4886    Standard = 1,
4887    Sandbox = 2,
4888    /// Reserved for platform operations. At most one per deployment, seeded
4889    /// by migration. Cannot be created via CreateOrganization.
4890    Staff = 3,
4891}
4892impl OrgType {
4893    /// String value of the enum field names used in the ProtoBuf definition.
4894    ///
4895    /// The values are not transformed in any way and thus are considered stable
4896    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4897    pub fn as_str_name(&self) -> &'static str {
4898        match self {
4899            Self::Unspecified => "ORG_TYPE_UNSPECIFIED",
4900            Self::Standard => "ORG_TYPE_STANDARD",
4901            Self::Sandbox => "ORG_TYPE_SANDBOX",
4902            Self::Staff => "ORG_TYPE_STAFF",
4903        }
4904    }
4905    /// Creates an enum from field names used in the ProtoBuf definition.
4906    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4907        match value {
4908            "ORG_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
4909            "ORG_TYPE_STANDARD" => Some(Self::Standard),
4910            "ORG_TYPE_SANDBOX" => Some(Self::Sandbox),
4911            "ORG_TYPE_STAFF" => Some(Self::Staff),
4912            _ => None,
4913        }
4914    }
4915}
4916// ─── Messages ───────────────────────────────────────────────────────────────
4917
4918/// Per-user rendering context containing variable substitutions.
4919#[derive(Clone, PartialEq, ::prost::Message)]
4920pub struct UserRenderContext {
4921    /// ID of the user being rendered for.
4922    #[prost(string, tag="1")]
4923    pub user_id: ::prost::alloc::string::String,
4924    /// Variable name-value pairs to substitute into the template.
4925    /// Constraints: Max 100 entries. Key max length 100 characters, value max length 10000 characters.
4926    #[prost(map="string, string", tag="2")]
4927    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
4928}
4929/// Request to render a template for a batch of users.
4930#[derive(Clone, PartialEq, ::prost::Message)]
4931pub struct RenderBatchRequest {
4932    /// ID of the template to render.
4933    #[prost(string, tag="1")]
4934    pub template_id: ::prost::alloc::string::String,
4935    /// Version of the template to render.
4936    #[prost(int32, tag="2")]
4937    pub version: i32,
4938    /// Per-user rendering contexts with variable substitutions.
4939    /// Constraints: Max 10000 users per batch.
4940    #[prost(message, repeated, tag="3")]
4941    pub users: ::prost::alloc::vec::Vec<UserRenderContext>,
4942}
4943/// Streamed response for each user's rendered message.
4944/// One response is emitted per user in the batch.
4945#[derive(Clone, PartialEq, ::prost::Message)]
4946pub struct RenderBatchResponse {
4947    /// ID of the user this result is for.
4948    #[prost(string, tag="1")]
4949    pub user_id: ::prost::alloc::string::String,
4950    /// The rendered message (set on success).
4951    #[prost(message, optional, tag="2")]
4952    pub message: ::core::option::Option<Message>,
4953    /// Error message if rendering failed for this user (empty on success).
4954    #[prost(string, tag="3")]
4955    pub error: ::prost::alloc::string::String,
4956}
4957// ─── Messages ───────────────────────────────────────────────────────────────
4958
4959/// A session recording summary from the analytics provider.
4960/// Anonymous: no user identifiers are included.
4961#[derive(Clone, PartialEq, ::prost::Message)]
4962pub struct SessionRecording {
4963    /// Recording ID from the analytics provider.
4964    #[prost(string, tag="1")]
4965    pub id: ::prost::alloc::string::String,
4966    /// Timestamp when the recording started.
4967    #[prost(message, optional, tag="2")]
4968    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
4969    /// Timestamp when the recording ended.
4970    #[prost(message, optional, tag="3")]
4971    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
4972    /// Duration of the recording in seconds.
4973    #[prost(int32, tag="4")]
4974    pub duration_seconds: i32,
4975    /// Activity score (0.0–1.0).
4976    #[prost(float, tag="5")]
4977    pub activity_score: f32,
4978}
4979/// Request to list session recordings.
4980#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4981pub struct ListSessionRecordingsRequest {
4982    /// Optional: filter recordings by campaign ID (mapped to analytics property filter).
4983    /// Constraints: UUID format (36 characters).
4984    #[prost(string, tag="1")]
4985    pub campaign_id: ::prost::alloc::string::String,
4986    /// Optional: start of the time range filter (inclusive).
4987    #[prost(message, optional, tag="2")]
4988    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
4989    /// Optional: end of the time range filter (inclusive).
4990    #[prost(message, optional, tag="3")]
4991    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
4992    /// Pagination parameters.
4993    #[prost(message, optional, tag="4")]
4994    pub pagination: ::core::option::Option<Pagination>,
4995}
4996/// Response containing a page of session recordings.
4997#[derive(Clone, PartialEq, ::prost::Message)]
4998pub struct ListSessionRecordingsResponse {
4999    /// List of session recordings in this page.
5000    #[prost(message, repeated, tag="1")]
5001    pub recordings: ::prost::alloc::vec::Vec<SessionRecording>,
5002    /// Pagination metadata for fetching subsequent pages.
5003    #[prost(message, optional, tag="2")]
5004    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5005}
5006/// Request to fetch rrweb snapshot events for a recording.
5007#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5008pub struct GetSessionSnapshotsRequest {
5009    /// Recording ID from the analytics provider.
5010    /// Constraints: Max length 200 characters.
5011    #[prost(string, tag="1")]
5012    pub recording_id: ::prost::alloc::string::String,
5013}
5014/// Response containing rrweb snapshot events.
5015#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5016pub struct GetSessionSnapshotsResponse {
5017    /// JSON-encoded array of rrweb eventWithTime objects.
5018    /// Clients parse this JSON to feed into rrweb-player.
5019    #[prost(string, tag="1")]
5020    pub snapshot_data: ::prost::alloc::string::String,
5021}
5022// ─── Messages ───────────────────────────────────────────────────────────────
5023
5024/// Request to list all roles in the caller's organization.
5025#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5026pub struct ListRolesRequest {
5027}
5028/// Response containing the organization's roles.
5029#[derive(Clone, PartialEq, ::prost::Message)]
5030pub struct ListRolesResponse {
5031    /// All roles in the organization, including their permission sets.
5032    #[prost(message, repeated, tag="1")]
5033    pub roles: ::prost::alloc::vec::Vec<Role>,
5034}
5035/// Request to create a new role in the caller's organization.
5036#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5037pub struct CreateRoleRequest {
5038    /// Display name for the role (e.g. "Team Lead"). Required.
5039    /// A slug is auto-generated from the name.
5040    #[prost(string, tag="1")]
5041    pub name: ::prost::alloc::string::String,
5042    /// Initial permission set for the role.
5043    /// PERMISSION_UNSPECIFIED values are rejected.
5044    #[prost(enumeration="Permission", repeated, tag="2")]
5045    pub permissions: ::prost::alloc::vec::Vec<i32>,
5046}
5047/// Response after creating a role.
5048#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5049pub struct CreateRoleResponse {
5050    /// The newly created role with its generated slug and permission set.
5051    #[prost(message, optional, tag="1")]
5052    pub role: ::core::option::Option<Role>,
5053}
5054/// Request to update a role's name and/or permissions.
5055#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5056pub struct UpdateRoleRequest {
5057    /// ID of the role to update. Required.
5058    #[prost(string, tag="1")]
5059    pub role_id: ::prost::alloc::string::String,
5060    /// New display name. If empty, the name is not changed.
5061    #[prost(string, tag="2")]
5062    pub name: ::prost::alloc::string::String,
5063    /// New permission set (replaces existing permissions entirely).
5064    /// If empty, permissions are not changed.
5065    /// PERMISSION_UNSPECIFIED values are rejected.
5066    #[prost(enumeration="Permission", repeated, tag="3")]
5067    pub permissions: ::prost::alloc::vec::Vec<i32>,
5068}
5069/// Response after updating a role.
5070#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5071pub struct UpdateRoleResponse {
5072    /// The updated role.
5073    #[prost(message, optional, tag="1")]
5074    pub role: ::core::option::Option<Role>,
5075}
5076/// Request to delete a role.
5077#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5078pub struct DeleteRoleRequest {
5079    /// ID of the role to delete. Required.
5080    #[prost(string, tag="1")]
5081    pub role_id: ::prost::alloc::string::String,
5082}
5083/// Response after deleting a role.
5084#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5085pub struct DeleteRoleResponse {
5086}
5087// ─── Messages ───────────────────────────────────────────────────────────────
5088
5089/// Custom SAML attribute name overrides for identity providers that use
5090/// non-standard attribute names. When provided, these override the
5091/// auto-detected values from the metadata URL host.
5092#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5093pub struct SamlAttributeNames {
5094    /// SAML attribute name for the user's email address.
5095    #[prost(string, tag="1")]
5096    pub email: ::prost::alloc::string::String,
5097    /// SAML attribute name for the user's first name.
5098    #[prost(string, tag="2")]
5099    pub given_name: ::prost::alloc::string::String,
5100    /// SAML attribute name for the user's last name.
5101    #[prost(string, tag="3")]
5102    pub family_name: ::prost::alloc::string::String,
5103}
5104/// An SSO identity provider configured for an organization.
5105#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5106pub struct SsoProvider {
5107    /// Unique identifier for the provider.
5108    #[prost(string, tag="1")]
5109    pub id: ::prost::alloc::string::String,
5110    /// Email domain that triggers this SSO provider (e.g. "acme.com").
5111    /// Constraints: Max length 253 characters (RFC 1035).
5112    #[prost(string, tag="2")]
5113    pub domain: ::prost::alloc::string::String,
5114    /// Type of identity provider.
5115    #[prost(enumeration="SsoProviderType", tag="3")]
5116    pub r#type: i32,
5117    /// SAML metadata URL or OIDC discovery URL.
5118    /// Constraints: Max length 2048 characters. HTTPS required.
5119    #[prost(string, tag="4")]
5120    pub metadata_url: ::prost::alloc::string::String,
5121    /// Name of the identity provider (used for signInWithRedirect).
5122    /// Set by the API when the IdP is created.
5123    #[prost(string, tag="5")]
5124    pub idp_provider_name: ::prost::alloc::string::String,
5125    /// Timestamp when the provider was created.
5126    #[prost(message, optional, tag="6")]
5127    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5128    /// Timestamp when the provider was last updated.
5129    #[prost(message, optional, tag="7")]
5130    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5131    /// Optional custom SAML attribute name overrides.
5132    #[prost(message, optional, tag="8")]
5133    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
5134}
5135/// Request to check if an email domain has SSO configured.
5136/// This RPC is pre-authentication — no JWT required.
5137#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5138pub struct CheckSsoByDomainRequest {
5139    /// Email address to check. The domain part is extracted.
5140    /// Constraints: Max length 254 characters (RFC 5321).
5141    #[prost(string, tag="1")]
5142    pub email: ::prost::alloc::string::String,
5143}
5144/// Response for SSO domain check.
5145#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5146pub struct CheckSsoByDomainResponse {
5147    /// Whether SSO is enabled for the email's domain.
5148    #[prost(bool, tag="1")]
5149    pub sso_enabled: bool,
5150    /// Identity provider name for signInWithRedirect.
5151    /// Empty if sso_enabled is false.
5152    #[prost(string, tag="2")]
5153    pub provider_name: ::prost::alloc::string::String,
5154}
5155/// Request to create an SSO provider for the organization.
5156#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5157pub struct CreateSsoProviderRequest {
5158    /// Email domain to associate (e.g. "acme.com").
5159    /// Constraints: Max length 253 characters (RFC 1035).
5160    #[prost(string, tag="1")]
5161    pub domain: ::prost::alloc::string::String,
5162    /// Type of identity provider.
5163    #[prost(enumeration="SsoProviderType", tag="2")]
5164    pub r#type: i32,
5165    /// SAML metadata URL or OIDC discovery URL.
5166    /// Constraints: Max length 2048 characters. HTTPS required.
5167    #[prost(string, tag="3")]
5168    pub metadata_url: ::prost::alloc::string::String,
5169    /// Optional custom SAML attribute name overrides.
5170    /// When omitted, attribute names are auto-detected from the metadata URL.
5171    #[prost(message, optional, tag="4")]
5172    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
5173}
5174/// Response after creating an SSO provider.
5175#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5176pub struct CreateSsoProviderResponse {
5177    /// The newly created SSO provider.
5178    #[prost(message, optional, tag="1")]
5179    pub provider: ::core::option::Option<SsoProvider>,
5180}
5181/// Request to get the SSO provider for the organization.
5182/// Returns the provider if one is configured, or empty if not.
5183#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5184pub struct GetSsoProviderRequest {
5185}
5186/// Response containing the organization's SSO provider.
5187#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5188pub struct GetSsoProviderResponse {
5189    /// The organization's SSO provider, or null if not configured.
5190    #[prost(message, optional, tag="1")]
5191    pub provider: ::core::option::Option<SsoProvider>,
5192}
5193/// Request to delete the organization's SSO provider.
5194#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5195pub struct DeleteSsoProviderRequest {
5196    /// ID of the provider to delete.
5197    #[prost(string, tag="1")]
5198    pub provider_id: ::prost::alloc::string::String,
5199}
5200/// Response after deleting an SSO provider.
5201#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5202pub struct DeleteSsoProviderResponse {
5203}
5204// ─── Enums ──────────────────────────────────────────────────────────────────
5205
5206/// Type of SSO identity provider.
5207#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
5208#[repr(i32)]
5209pub enum SsoProviderType {
5210    /// Default value; not a valid type.
5211    Unspecified = 0,
5212    /// SAML 2.0 identity provider (e.g. Okta, Azure AD).
5213    Saml = 1,
5214    /// OpenID Connect identity provider (e.g. Google Workspace, Auth0).
5215    Oidc = 2,
5216}
5217impl SsoProviderType {
5218    /// String value of the enum field names used in the ProtoBuf definition.
5219    ///
5220    /// The values are not transformed in any way and thus are considered stable
5221    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
5222    pub fn as_str_name(&self) -> &'static str {
5223        match self {
5224            Self::Unspecified => "SSO_PROVIDER_TYPE_UNSPECIFIED",
5225            Self::Saml => "SSO_PROVIDER_TYPE_SAML",
5226            Self::Oidc => "SSO_PROVIDER_TYPE_OIDC",
5227        }
5228    }
5229    /// Creates an enum from field names used in the ProtoBuf definition.
5230    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
5231        match value {
5232            "SSO_PROVIDER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
5233            "SSO_PROVIDER_TYPE_SAML" => Some(Self::Saml),
5234            "SSO_PROVIDER_TYPE_OIDC" => Some(Self::Oidc),
5235            _ => None,
5236        }
5237    }
5238}
5239// ─── Messages ───────────────────────────────────────────────────────────────
5240
5241/// An organizational unit within an organization (e.g. department, division).
5242/// Teams represent the organizational structure and can serve as sender identity
5243/// in campaigns.
5244#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5245pub struct Team {
5246    /// Unique identifier for the team.
5247    #[prost(string, tag="1")]
5248    pub id: ::prost::alloc::string::String,
5249    /// Human-readable display name (unique within the organization).
5250    /// Constraints: Max length 200 characters.
5251    #[prost(string, tag="2")]
5252    pub name: ::prost::alloc::string::String,
5253    /// Optional description of the team's purpose.
5254    /// Constraints: Max length 1000 characters.
5255    #[prost(string, tag="3")]
5256    pub description: ::prost::alloc::string::String,
5257    /// Number of users currently in the team.
5258    #[prost(int32, tag="4")]
5259    pub member_count: i32,
5260    /// Timestamp when the team was created.
5261    #[prost(message, optional, tag="5")]
5262    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5263    /// Timestamp when the team was last updated.
5264    #[prost(message, optional, tag="6")]
5265    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5266    /// Whether this is the organization's default team (cannot be deleted or renamed).
5267    #[prost(bool, tag="7")]
5268    pub is_default: bool,
5269    /// ID of the user who created this team. Empty for system-seeded defaults.
5270    #[prost(string, tag="8")]
5271    pub created_by: ::prost::alloc::string::String,
5272}
5273/// Request to create a new team.
5274#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5275pub struct CreateTeamRequest {
5276    /// Display name for the team. Required.
5277    /// Constraints: Max length 200 characters.
5278    #[prost(string, tag="1")]
5279    pub name: ::prost::alloc::string::String,
5280    /// Optional description.
5281    /// Constraints: Max length 1000 characters.
5282    #[prost(string, tag="2")]
5283    pub description: ::prost::alloc::string::String,
5284}
5285/// Response after creating a team.
5286#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5287pub struct CreateTeamResponse {
5288    /// The newly created team.
5289    #[prost(message, optional, tag="1")]
5290    pub team: ::core::option::Option<Team>,
5291}
5292/// Request to retrieve a team by ID.
5293#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5294pub struct GetTeamRequest {
5295    /// ID of the team to retrieve. Required.
5296    #[prost(string, tag="1")]
5297    pub team_id: ::prost::alloc::string::String,
5298}
5299/// Response containing the requested team.
5300#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5301pub struct GetTeamResponse {
5302    /// The requested team.
5303    #[prost(message, optional, tag="1")]
5304    pub team: ::core::option::Option<Team>,
5305}
5306/// Request to list teams in the organization with pagination.
5307#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5308pub struct ListTeamsRequest {
5309    /// Pagination parameters.
5310    #[prost(message, optional, tag="1")]
5311    pub pagination: ::core::option::Option<Pagination>,
5312}
5313/// Response containing a page of teams.
5314#[derive(Clone, PartialEq, ::prost::Message)]
5315pub struct ListTeamsResponse {
5316    /// Teams in this page.
5317    #[prost(message, repeated, tag="1")]
5318    pub teams: ::prost::alloc::vec::Vec<Team>,
5319    /// Pagination metadata for fetching subsequent pages.
5320    #[prost(message, optional, tag="2")]
5321    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5322}
5323/// Request to update a team's name and/or description.
5324#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5325pub struct UpdateTeamRequest {
5326    /// ID of the team to update. Required.
5327    #[prost(string, tag="1")]
5328    pub team_id: ::prost::alloc::string::String,
5329    /// New display name. If empty, the name is not changed.
5330    /// Default teams cannot be renamed.
5331    /// Constraints: Max length 200 characters.
5332    #[prost(string, tag="2")]
5333    pub name: ::prost::alloc::string::String,
5334    /// New description. If empty, the description is not changed.
5335    /// Constraints: Max length 1000 characters.
5336    #[prost(string, tag="3")]
5337    pub description: ::prost::alloc::string::String,
5338}
5339/// Response after updating a team.
5340#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5341pub struct UpdateTeamResponse {
5342    /// The updated team.
5343    #[prost(message, optional, tag="1")]
5344    pub team: ::core::option::Option<Team>,
5345}
5346/// Request to delete a team.
5347#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5348pub struct DeleteTeamRequest {
5349    /// ID of the team to delete. Required.
5350    /// Default teams cannot be deleted.
5351    #[prost(string, tag="1")]
5352    pub team_id: ::prost::alloc::string::String,
5353}
5354/// Response after deleting a team.
5355#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5356pub struct DeleteTeamResponse {
5357}
5358/// Request to add users to a team.
5359#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5360pub struct AddTeamMembersRequest {
5361    /// ID of the team to add members to. Required.
5362    #[prost(string, tag="1")]
5363    pub team_id: ::prost::alloc::string::String,
5364    /// IDs of users to add. Must belong to the same organization.
5365    /// Adding an existing member is a no-op (idempotent).
5366    /// Constraints: Max 100 user IDs per request.
5367    #[prost(string, repeated, tag="2")]
5368    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
5369}
5370/// Response after adding team members.
5371#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5372pub struct AddTeamMembersResponse {
5373    /// The team with updated member_count.
5374    #[prost(message, optional, tag="1")]
5375    pub team: ::core::option::Option<Team>,
5376}
5377/// Request to remove users from a team.
5378#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5379pub struct RemoveTeamMembersRequest {
5380    /// ID of the team to remove members from. Required.
5381    #[prost(string, tag="1")]
5382    pub team_id: ::prost::alloc::string::String,
5383    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
5384    /// Constraints: Max 100 user IDs per request.
5385    #[prost(string, repeated, tag="2")]
5386    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
5387}
5388/// Response after removing team members.
5389#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5390pub struct RemoveTeamMembersResponse {
5391    /// The team with updated member_count.
5392    #[prost(message, optional, tag="1")]
5393    pub team: ::core::option::Option<Team>,
5394}
5395/// Request to list members of a team with pagination.
5396#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5397pub struct ListTeamMembersRequest {
5398    /// ID of the team whose members to list. Required.
5399    #[prost(string, tag="1")]
5400    pub team_id: ::prost::alloc::string::String,
5401    /// Pagination parameters.
5402    #[prost(message, optional, tag="2")]
5403    pub pagination: ::core::option::Option<Pagination>,
5404}
5405/// Response containing a page of team members.
5406#[derive(Clone, PartialEq, ::prost::Message)]
5407pub struct ListTeamMembersResponse {
5408    /// Users in this page.
5409    #[prost(message, repeated, tag="1")]
5410    pub users: ::prost::alloc::vec::Vec<User>,
5411    /// Pagination metadata for fetching subsequent pages.
5412    #[prost(message, optional, tag="2")]
5413    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5414}
5415// ─── Messages ───────────────────────────────────────────────────────────────
5416
5417/// A variable placeholder within a template that gets substituted during rendering.
5418#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5419pub struct TemplateVariable {
5420    /// Variable name used in the template body (e.g. "employee_name").
5421    /// Constraints: Max length 100 characters.
5422    #[prost(string, tag="1")]
5423    pub name: ::prost::alloc::string::String,
5424    /// Human-readable description of what this variable represents.
5425    /// Constraints: Max length 500 characters.
5426    #[prost(string, tag="2")]
5427    pub description: ::prost::alloc::string::String,
5428    /// Whether this variable must be provided during rendering.
5429    #[prost(bool, tag="3")]
5430    pub required: bool,
5431    /// Where this variable's value comes from (profile attribute or campaign config).
5432    #[prost(enumeration="TemplateVariableSource", tag="4")]
5433    pub source: i32,
5434    /// Fallback value used when the source does not provide a value.
5435    /// Constraints: Max length 1000 characters.
5436    #[prost(string, tag="5")]
5437    pub default_value: ::prost::alloc::string::String,
5438    /// When true, this variable's rendered value is masked in session replay
5439    /// and heatmap screenshots. Org admin controls per variable.
5440    #[prost(bool, tag="6")]
5441    pub pii: bool,
5442}
5443/// A versioned message template with variable placeholders.
5444/// Templates are append-only — updates create new versions.
5445#[derive(Clone, PartialEq, ::prost::Message)]
5446pub struct Template {
5447    /// Unique identifier for the template.
5448    #[prost(string, tag="1")]
5449    pub id: ::prost::alloc::string::String,
5450    /// Human-readable template name (admin-facing label).
5451    /// Constraints: Max length 200 characters.
5452    #[prost(string, tag="2")]
5453    pub name: ::prost::alloc::string::String,
5454    /// Template body with {{variable}} placeholders for substitution.
5455    /// Constraints: Max length 50000 characters.
5456    #[prost(string, tag="3")]
5457    pub body: ::prost::alloc::string::String,
5458    /// Variables that can be substituted into the template body.
5459    #[prost(message, repeated, tag="4")]
5460    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
5461    /// Version number (auto-incremented on each update).
5462    #[prost(int32, tag="5")]
5463    pub version: i32,
5464    /// Timestamp when this version was created.
5465    #[prost(message, optional, tag="6")]
5466    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5467    /// Timestamp of the most recent update (same as created_at for the latest version).
5468    #[prost(message, optional, tag="7")]
5469    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5470    /// User-facing title shown as the message subject to recipients.
5471    /// Serves as the default title; campaigns can override it.
5472    /// Constraints: Max length 200 characters.
5473    #[prost(string, tag="8")]
5474    pub title: ::prost::alloc::string::String,
5475    /// Content format of this template (markdown, rich, HTML).
5476    /// UNSPECIFIED is treated as MARKDOWN for backward compatibility.
5477    #[prost(enumeration="TemplateType", tag="9")]
5478    pub r#type: i32,
5479    /// Language of the template body content (e.g., "en", "es", "ja").
5480    /// Defaults to the org's default_locale, falling back to "en".
5481    /// Translations are created as locale variants of this source.
5482    #[prost(string, tag="10")]
5483    pub source_locale: ::prost::alloc::string::String,
5484}
5485/// A locale-specific translation of a template's title and body.
5486/// Translations are created per template version and go through a review workflow.
5487#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5488pub struct TemplateTranslation {
5489    /// Unique identifier for this translation.
5490    #[prost(string, tag="1")]
5491    pub id: ::prost::alloc::string::String,
5492    /// ID of the source template.
5493    #[prost(string, tag="2")]
5494    pub template_id: ::prost::alloc::string::String,
5495    /// Version of the source template this translation is for.
5496    #[prost(int32, tag="3")]
5497    pub version: i32,
5498    /// Target locale (e.g., "es", "pt-BR", "zh", "ja").
5499    #[prost(string, tag="4")]
5500    pub locale: ::prost::alloc::string::String,
5501    /// Translated title.
5502    /// Constraints: Max length 200 characters.
5503    #[prost(string, tag="5")]
5504    pub title: ::prost::alloc::string::String,
5505    /// Translated body content with {{variable}} placeholders preserved.
5506    /// Constraints: Max length 50000 characters.
5507    #[prost(string, tag="6")]
5508    pub body: ::prost::alloc::string::String,
5509    /// Current review status.
5510    #[prost(enumeration="TranslationStatus", tag="7")]
5511    pub status: i32,
5512    /// Who created this translation ("ai:bedrock", "ai:deepl", or user UUID).
5513    #[prost(string, tag="8")]
5514    pub translated_by: ::prost::alloc::string::String,
5515    /// User who approved the translation. Empty until approved.
5516    #[prost(string, tag="9")]
5517    pub reviewed_by: ::prost::alloc::string::String,
5518    /// When the translation was approved.
5519    #[prost(message, optional, tag="10")]
5520    pub reviewed_at: ::core::option::Option<::prost_types::Timestamp>,
5521    /// When the translation was created.
5522    #[prost(message, optional, tag="11")]
5523    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5524}
5525/// Request to create a new template.
5526#[derive(Clone, PartialEq, ::prost::Message)]
5527pub struct CreateTemplateRequest {
5528    /// Human-readable template name (admin-facing label).
5529    /// Constraints: Max length 200 characters.
5530    #[prost(string, tag="1")]
5531    pub name: ::prost::alloc::string::String,
5532    /// Template body with {{variable}} placeholders.
5533    /// Constraints: Max length 50000 characters.
5534    #[prost(string, tag="2")]
5535    pub body: ::prost::alloc::string::String,
5536    /// Variables available for substitution in the body.
5537    #[prost(message, repeated, tag="3")]
5538    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
5539    /// User-facing title shown as the message subject to recipients.
5540    /// Constraints: Max length 200 characters.
5541    #[prost(string, tag="4")]
5542    pub title: ::prost::alloc::string::String,
5543    /// Content format of the template. Defaults to MARKDOWN if unspecified.
5544    #[prost(enumeration="TemplateType", tag="5")]
5545    pub r#type: i32,
5546    /// Language of the template body content. Defaults to org's default_locale.
5547    /// Valid values: en, es, pt-BR, zh, ja.
5548    #[prost(string, tag="6")]
5549    pub source_locale: ::prost::alloc::string::String,
5550}
5551/// Response after creating a template.
5552#[derive(Clone, PartialEq, ::prost::Message)]
5553pub struct CreateTemplateResponse {
5554    /// The newly created template (version 1).
5555    #[prost(message, optional, tag="1")]
5556    pub template: ::core::option::Option<Template>,
5557}
5558/// Request to update a template, creating a new version.
5559#[derive(Clone, PartialEq, ::prost::Message)]
5560pub struct UpdateTemplateRequest {
5561    /// ID of the template to update.
5562    #[prost(string, tag="1")]
5563    pub template_id: ::prost::alloc::string::String,
5564    /// New template body with {{variable}} placeholders.
5565    /// Constraints: Max length 50000 characters.
5566    #[prost(string, tag="2")]
5567    pub body: ::prost::alloc::string::String,
5568    /// Updated variables for substitution.
5569    #[prost(message, repeated, tag="3")]
5570    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
5571}
5572/// Response after updating a template.
5573#[derive(Clone, PartialEq, ::prost::Message)]
5574pub struct UpdateTemplateResponse {
5575    /// The updated template with incremented version number.
5576    #[prost(message, optional, tag="1")]
5577    pub template: ::core::option::Option<Template>,
5578}
5579/// Request to retrieve a specific template version.
5580#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5581pub struct GetTemplateRequest {
5582    /// ID of the template to retrieve.
5583    #[prost(string, tag="1")]
5584    pub template_id: ::prost::alloc::string::String,
5585    /// Version to retrieve. 0 returns the latest version.
5586    #[prost(int32, tag="2")]
5587    pub version: i32,
5588}
5589/// Response containing the requested template.
5590#[derive(Clone, PartialEq, ::prost::Message)]
5591pub struct GetTemplateResponse {
5592    /// The requested template.
5593    #[prost(message, optional, tag="1")]
5594    pub template: ::core::option::Option<Template>,
5595}
5596/// Request to list templates with pagination.
5597#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5598pub struct ListTemplatesRequest {
5599    /// Pagination parameters.
5600    #[prost(message, optional, tag="1")]
5601    pub pagination: ::core::option::Option<Pagination>,
5602    /// Filter by template type. UNSPECIFIED returns all templates.
5603    #[prost(enumeration="TemplateType", tag="2")]
5604    pub r#type: i32,
5605}
5606/// Response containing a page of templates.
5607#[derive(Clone, PartialEq, ::prost::Message)]
5608pub struct ListTemplatesResponse {
5609    /// List of templates in this page (latest version of each).
5610    #[prost(message, repeated, tag="1")]
5611    pub templates: ::prost::alloc::vec::Vec<Template>,
5612    /// Pagination metadata for fetching subsequent pages.
5613    #[prost(message, optional, tag="2")]
5614    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5615}
5616/// Request to create a translation for a template.
5617#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5618pub struct CreateTemplateTranslationRequest {
5619    /// ID of the template to translate.
5620    #[prost(string, tag="1")]
5621    pub template_id: ::prost::alloc::string::String,
5622    /// Version of the template to translate.
5623    #[prost(int32, tag="2")]
5624    pub version: i32,
5625    /// Target locale.
5626    #[prost(string, tag="3")]
5627    pub locale: ::prost::alloc::string::String,
5628    /// Translated title.
5629    #[prost(string, tag="4")]
5630    pub title: ::prost::alloc::string::String,
5631    /// Translated body content.
5632    #[prost(string, tag="5")]
5633    pub body: ::prost::alloc::string::String,
5634    /// Who created this translation ("ai:bedrock" or user UUID).
5635    #[prost(string, tag="6")]
5636    pub translated_by: ::prost::alloc::string::String,
5637    /// Initial status (typically DRAFT or AI_TRANSLATED).
5638    #[prost(enumeration="TranslationStatus", tag="7")]
5639    pub status: i32,
5640}
5641/// Response after creating a template translation.
5642#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5643pub struct CreateTemplateTranslationResponse {
5644    /// The created translation.
5645    #[prost(message, optional, tag="1")]
5646    pub translation: ::core::option::Option<TemplateTranslation>,
5647}
5648/// Request to update an existing template translation.
5649#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5650pub struct UpdateTemplateTranslationRequest {
5651    /// ID of the translation to update.
5652    #[prost(string, tag="1")]
5653    pub translation_id: ::prost::alloc::string::String,
5654    /// Updated title. Empty leaves unchanged.
5655    #[prost(string, tag="2")]
5656    pub title: ::prost::alloc::string::String,
5657    /// Updated body. Empty leaves unchanged.
5658    #[prost(string, tag="3")]
5659    pub body: ::prost::alloc::string::String,
5660    /// Updated status.
5661    #[prost(enumeration="TranslationStatus", tag="4")]
5662    pub status: i32,
5663}
5664/// Response after updating a template translation.
5665#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5666pub struct UpdateTemplateTranslationResponse {
5667    /// The updated translation.
5668    #[prost(message, optional, tag="1")]
5669    pub translation: ::core::option::Option<TemplateTranslation>,
5670}
5671/// Request to list translations for a template version.
5672#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5673pub struct ListTemplateTranslationsRequest {
5674    /// ID of the template.
5675    #[prost(string, tag="1")]
5676    pub template_id: ::prost::alloc::string::String,
5677    /// Version of the template. 0 returns translations for the latest version.
5678    #[prost(int32, tag="2")]
5679    pub version: i32,
5680}
5681/// Response containing all translations for a template version.
5682#[derive(Clone, PartialEq, ::prost::Message)]
5683pub struct ListTemplateTranslationsResponse {
5684    /// Translations for the requested template version.
5685    #[prost(message, repeated, tag="1")]
5686    pub translations: ::prost::alloc::vec::Vec<TemplateTranslation>,
5687}
5688/// Request to approve a template translation.
5689#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5690pub struct ApproveTemplateTranslationRequest {
5691    /// ID of the translation to approve.
5692    #[prost(string, tag="1")]
5693    pub translation_id: ::prost::alloc::string::String,
5694}
5695/// Response after approving a template translation.
5696#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5697pub struct ApproveTemplateTranslationResponse {
5698    /// The approved translation (status: APPROVED, reviewed_by and reviewed_at set).
5699    #[prost(message, optional, tag="1")]
5700    pub translation: ::core::option::Option<TemplateTranslation>,
5701}
5702// ─── Enums ──────────────────────────────────────────────────────────────────
5703
5704/// Content format of a template, determining which editor and renderer to use.
5705#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
5706#[repr(i32)]
5707pub enum TemplateType {
5708    /// Default value; treated as MARKDOWN for backward compatibility.
5709    Unspecified = 0,
5710    /// Markdown with {{variable}} placeholders.
5711    Markdown = 1,
5712    /// Rich text format (reserved for future use).
5713    Rich = 2,
5714    /// Raw HTML format (reserved for future use).
5715    Html = 3,
5716}
5717impl TemplateType {
5718    /// String value of the enum field names used in the ProtoBuf definition.
5719    ///
5720    /// The values are not transformed in any way and thus are considered stable
5721    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
5722    pub fn as_str_name(&self) -> &'static str {
5723        match self {
5724            Self::Unspecified => "TEMPLATE_TYPE_UNSPECIFIED",
5725            Self::Markdown => "TEMPLATE_TYPE_MARKDOWN",
5726            Self::Rich => "TEMPLATE_TYPE_RICH",
5727            Self::Html => "TEMPLATE_TYPE_HTML",
5728        }
5729    }
5730    /// Creates an enum from field names used in the ProtoBuf definition.
5731    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
5732        match value {
5733            "TEMPLATE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
5734            "TEMPLATE_TYPE_MARKDOWN" => Some(Self::Markdown),
5735            "TEMPLATE_TYPE_RICH" => Some(Self::Rich),
5736            "TEMPLATE_TYPE_HTML" => Some(Self::Html),
5737            _ => None,
5738        }
5739    }
5740}
5741/// Source from which a template variable's value is resolved at render time.
5742#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
5743#[repr(i32)]
5744pub enum TemplateVariableSource {
5745    /// Default value; treated as CUSTOM for backward compatibility.
5746    Unspecified = 0,
5747    /// Auto-resolved from the target user's profile attributes.
5748    Profile = 1,
5749    /// Provided manually in the campaign or workflow step configuration.
5750    Custom = 2,
5751}
5752impl TemplateVariableSource {
5753    /// String value of the enum field names used in the ProtoBuf definition.
5754    ///
5755    /// The values are not transformed in any way and thus are considered stable
5756    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
5757    pub fn as_str_name(&self) -> &'static str {
5758        match self {
5759            Self::Unspecified => "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED",
5760            Self::Profile => "TEMPLATE_VARIABLE_SOURCE_PROFILE",
5761            Self::Custom => "TEMPLATE_VARIABLE_SOURCE_CUSTOM",
5762        }
5763    }
5764    /// Creates an enum from field names used in the ProtoBuf definition.
5765    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
5766        match value {
5767            "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
5768            "TEMPLATE_VARIABLE_SOURCE_PROFILE" => Some(Self::Profile),
5769            "TEMPLATE_VARIABLE_SOURCE_CUSTOM" => Some(Self::Custom),
5770            _ => None,
5771        }
5772    }
5773}
5774/// Review status of a template translation.
5775#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
5776#[repr(i32)]
5777pub enum TranslationStatus {
5778    Unspecified = 0,
5779    /// Translation draft, not yet reviewed.
5780    Draft = 1,
5781    /// Translation generated by AI, pending human review.
5782    AiTranslated = 2,
5783    /// Translation is being reviewed by a human.
5784    InReview = 3,
5785    /// Translation has been approved for use.
5786    Approved = 4,
5787}
5788impl TranslationStatus {
5789    /// String value of the enum field names used in the ProtoBuf definition.
5790    ///
5791    /// The values are not transformed in any way and thus are considered stable
5792    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
5793    pub fn as_str_name(&self) -> &'static str {
5794        match self {
5795            Self::Unspecified => "TRANSLATION_STATUS_UNSPECIFIED",
5796            Self::Draft => "TRANSLATION_STATUS_DRAFT",
5797            Self::AiTranslated => "TRANSLATION_STATUS_AI_TRANSLATED",
5798            Self::InReview => "TRANSLATION_STATUS_IN_REVIEW",
5799            Self::Approved => "TRANSLATION_STATUS_APPROVED",
5800        }
5801    }
5802    /// Creates an enum from field names used in the ProtoBuf definition.
5803    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
5804        match value {
5805            "TRANSLATION_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
5806            "TRANSLATION_STATUS_DRAFT" => Some(Self::Draft),
5807            "TRANSLATION_STATUS_AI_TRANSLATED" => Some(Self::AiTranslated),
5808            "TRANSLATION_STATUS_IN_REVIEW" => Some(Self::InReview),
5809            "TRANSLATION_STATUS_APPROVED" => Some(Self::Approved),
5810            _ => None,
5811        }
5812    }
5813}
5814// ─── Messages ───────────────────────────────────────────────────────────────
5815
5816/// Decoded deeplink-token payload. Populated by ValidateDeeplinkToken
5817/// only when validation succeeds.
5818#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5819pub struct DeeplinkTokenPayload {
5820    /// Campaign UUID the deeplink targets. The native app uses this for the
5821    /// authenticated GetCampaign follow-up post-recipient-auth.
5822    #[prost(string, tag="1")]
5823    pub campaign_id: ::prost::alloc::string::String,
5824    /// Recipient UUID the token authorizes. The token does not authenticate
5825    /// the recipient (that's the auth flow's job); it authorizes "this
5826    /// deeplink path is for this recipient" so the native app can refuse
5827    /// to render a token whose embedded recipient mismatches the signed-in
5828    /// user.
5829    #[prost(string, tag="2")]
5830    pub recipient_user_id: ::prost::alloc::string::String,
5831    /// Step kind the deeplink targets — REMINDER vs ESCALATION. Lets the
5832    /// native app pick the right campaign-card variant before the auth
5833    /// gate.
5834    #[prost(enumeration="ChannelStepKind", tag="3")]
5835    pub step_kind: i32,
5836    /// Expiry the token carries. Validation rejects tokens past this time
5837    /// even if the signature checks out.
5838    #[prost(message, optional, tag="4")]
5839    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5840}
5841#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5842pub struct SignDeeplinkTokenRequest {
5843    /// Campaign whose deeplink this token authorizes. Constraints: required,
5844    /// must be a UUID and exist within the caller's organization.
5845    #[prost(string, tag="1")]
5846    pub campaign_id: ::prost::alloc::string::String,
5847    /// Recipient the token authorizes. Constraints: required, must be a UUID
5848    /// and a member of the campaign's audience.
5849    #[prost(string, tag="2")]
5850    pub recipient_user_id: ::prost::alloc::string::String,
5851    /// Step kind the deeplink targets. Required.
5852    #[prost(enumeration="ChannelStepKind", tag="3")]
5853    pub step_kind: i32,
5854    /// Token lifetime in seconds from now. Constraints: required, must be
5855    /// in (0, 30 * 24 * 3600] (1 second to 30 days). 30 days matches the
5856    /// platform's outer bound on actionable campaign lifetimes; longer
5857    /// tokens are not signed.
5858    #[prost(int64, tag="4")]
5859    pub ttl_seconds: i64,
5860}
5861#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5862pub struct SignDeeplinkTokenResponse {
5863    /// The signed token, ready to URL-embed in
5864    /// links.pidgr.com/c/{short_code}?t={token}. Format: base64url-encoded
5865    /// payload (JSON) + base64url-encoded HMAC-SHA256 trailer, joined by
5866    /// a single dot. Implementation detail — clients SHOULD NOT parse or
5867    /// mutate the token; they pass it back to ValidateDeeplinkToken.
5868    #[prost(string, tag="1")]
5869    pub token: ::prost::alloc::string::String,
5870    /// The expiry the token carries. Echoed back so clients don't need to
5871    /// redo the time-math the caller passed in via ttl_seconds.
5872    #[prost(message, optional, tag="2")]
5873    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5874    /// The platform key version used to sign. Clients MAY record for
5875    /// telemetry but SHOULD NOT branch logic on it — the platform manages
5876    /// overlap windows during rotation transparently.
5877    #[prost(int32, tag="3")]
5878    pub key_version: i32,
5879}
5880#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5881pub struct ValidateDeeplinkTokenRequest {
5882    /// The token bytes from the deeplink URL's `t` query parameter.
5883    /// Constraints: required, non-empty.
5884    #[prost(string, tag="1")]
5885    pub token: ::prost::alloc::string::String,
5886    /// Campaign UUID embedded in the URL path (translated from the
5887    /// short-code by the native app via CampaignService.GetCampaignByShortCode).
5888    /// Validation rejects when the token's embedded campaign_id does not
5889    /// match — defense against replay attacks that swap the short-code
5890    /// path component while reusing a signed token from a different
5891    /// campaign.
5892    #[prost(string, tag="2")]
5893    pub campaign_id: ::prost::alloc::string::String,
5894}
5895#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5896pub struct ValidateDeeplinkTokenResponse {
5897    /// True when signature + expiry both check out under any active or
5898    /// overlap-window key version.
5899    #[prost(bool, tag="1")]
5900    pub valid: bool,
5901    /// Reason validation failed. Set only when valid=false; UNSPECIFIED
5902    /// when valid=true. The native app uses this to drive UX (silent retry
5903    /// vs. "this link expired" message vs. "this link looks tampered").
5904    #[prost(enumeration="ValidationFailureReason", tag="2")]
5905    pub failure_reason: i32,
5906    /// Decoded payload. Populated only when valid=true. The native app
5907    /// SHOULD compare payload.recipient_user_id against the signed-in user
5908    /// and refuse to render the campaign card on mismatch.
5909    #[prost(message, optional, tag="3")]
5910    pub payload: ::core::option::Option<DeeplinkTokenPayload>,
5911}
5912// ─── Enums ──────────────────────────────────────────────────────────────────
5913
5914/// Reason a deeplink-token validation failed. Empty when valid=true.
5915#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
5916#[repr(i32)]
5917pub enum ValidationFailureReason {
5918    Unspecified = 0,
5919    /// Token bytes parsed but the HMAC signature did not verify under any
5920    /// active or overlap-window key version.
5921    InvalidSignature = 1,
5922    /// Token signature verified but its embedded expiry has passed.
5923    Expired = 2,
5924    /// Signature would have verified, but the key version that signed the
5925    /// token is past the rotation overlap window and has been hard-deleted.
5926    /// This means the token is older than the platform's retention bound
5927    /// (rotation cadence + overlap window) — operationally equivalent to
5928    /// EXPIRED but distinguishable for telemetry.
5929    KeyRetired = 3,
5930    /// Token bytes could not be parsed at all (not base64url, wrong length,
5931    /// missing payload separator, etc.). Indicates a tampered or
5932    /// truncated URL.
5933    Malformed = 4,
5934}
5935impl ValidationFailureReason {
5936    /// String value of the enum field names used in the ProtoBuf definition.
5937    ///
5938    /// The values are not transformed in any way and thus are considered stable
5939    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
5940    pub fn as_str_name(&self) -> &'static str {
5941        match self {
5942            Self::Unspecified => "VALIDATION_FAILURE_REASON_UNSPECIFIED",
5943            Self::InvalidSignature => "VALIDATION_FAILURE_REASON_INVALID_SIGNATURE",
5944            Self::Expired => "VALIDATION_FAILURE_REASON_EXPIRED",
5945            Self::KeyRetired => "VALIDATION_FAILURE_REASON_KEY_RETIRED",
5946            Self::Malformed => "VALIDATION_FAILURE_REASON_MALFORMED",
5947        }
5948    }
5949    /// Creates an enum from field names used in the ProtoBuf definition.
5950    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
5951        match value {
5952            "VALIDATION_FAILURE_REASON_UNSPECIFIED" => Some(Self::Unspecified),
5953            "VALIDATION_FAILURE_REASON_INVALID_SIGNATURE" => Some(Self::InvalidSignature),
5954            "VALIDATION_FAILURE_REASON_EXPIRED" => Some(Self::Expired),
5955            "VALIDATION_FAILURE_REASON_KEY_RETIRED" => Some(Self::KeyRetired),
5956            "VALIDATION_FAILURE_REASON_MALFORMED" => Some(Self::Malformed),
5957            _ => None,
5958        }
5959    }
5960}
5961include!("pidgr.v1.tonic.rs");
5962// @@protoc_insertion_point(module)