Skip to main content

pidgr_proto/pidgr/v1/
pidgr.v1.rs

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