Skip to main content

pidgr_proto/pidgr/v1/
pidgr.v1.rs

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