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