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