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