Skip to main content

pidgr_proto/pidgr/v1/
pidgr.v1.rs

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