Skip to main content

pidgr_proto/pidgr/v1/
pidgr.v1.rs

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