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