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}
1461impl AuditEventType {
1462    /// String value of the enum field names used in the ProtoBuf definition.
1463    ///
1464    /// The values are not transformed in any way and thus are considered stable
1465    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1466    pub fn as_str_name(&self) -> &'static str {
1467        match self {
1468            Self::Unspecified => "AUDIT_EVENT_TYPE_UNSPECIFIED",
1469            Self::CampaignCreated => "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED",
1470            Self::MessageSent => "AUDIT_EVENT_TYPE_MESSAGE_SENT",
1471            Self::MessageOpened => "AUDIT_EVENT_TYPE_MESSAGE_OPENED",
1472            Self::AckRegistered => "AUDIT_EVENT_TYPE_ACK_REGISTERED",
1473            Self::EscalationExecuted => "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED",
1474            Self::CampaignStarted => "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED",
1475            Self::CampaignCancelled => "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED",
1476            Self::CampaignUpdated => "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED",
1477            Self::UserInvited => "AUDIT_EVENT_TYPE_USER_INVITED",
1478            Self::UserDeactivated => "AUDIT_EVENT_TYPE_USER_DEACTIVATED",
1479            Self::UserReactivated => "AUDIT_EVENT_TYPE_USER_REACTIVATED",
1480            Self::RoleChanged => "AUDIT_EVENT_TYPE_ROLE_CHANGED",
1481            Self::InviteRevoked => "AUDIT_EVENT_TYPE_INVITE_REVOKED",
1482            Self::ProfileUpdated => "AUDIT_EVENT_TYPE_PROFILE_UPDATED",
1483            Self::SettingsUpdated => "AUDIT_EVENT_TYPE_SETTINGS_UPDATED",
1484            Self::PasskeyEnrolled => "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED",
1485            Self::DataExportRequested => "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED",
1486            Self::DataDeletionRequested => "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED",
1487            Self::DataRectified => "AUDIT_EVENT_TYPE_DATA_RECTIFIED",
1488            Self::ProcessingRestricted => "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED",
1489            Self::DeletionCancelled => "AUDIT_EVENT_TYPE_DELETION_CANCELLED",
1490            Self::DeletionImmediate => "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE",
1491            Self::SsoConfigured => "AUDIT_EVENT_TYPE_SSO_CONFIGURED",
1492            Self::SsoProviderCreated => "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED",
1493            Self::SsoProviderDeleted => "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED",
1494            Self::OrgUpdated => "AUDIT_EVENT_TYPE_ORG_UPDATED",
1495            Self::RoleCreated => "AUDIT_EVENT_TYPE_ROLE_CREATED",
1496            Self::RoleUpdated => "AUDIT_EVENT_TYPE_ROLE_UPDATED",
1497            Self::RoleDeleted => "AUDIT_EVENT_TYPE_ROLE_DELETED",
1498            Self::TemplateCreated => "AUDIT_EVENT_TYPE_TEMPLATE_CREATED",
1499            Self::TemplateUpdated => "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED",
1500            Self::ApiKeyCreated => "AUDIT_EVENT_TYPE_API_KEY_CREATED",
1501            Self::ApiKeyRevoked => "AUDIT_EVENT_TYPE_API_KEY_REVOKED",
1502            Self::InviteLinkCreated => "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED",
1503            Self::InviteLinkRevoked => "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED",
1504            Self::GroupCreated => "AUDIT_EVENT_TYPE_GROUP_CREATED",
1505            Self::GroupUpdated => "AUDIT_EVENT_TYPE_GROUP_UPDATED",
1506            Self::GroupDeleted => "AUDIT_EVENT_TYPE_GROUP_DELETED",
1507            Self::GroupMembersAdded => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED",
1508            Self::GroupMembersRemoved => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED",
1509            Self::TeamCreated => "AUDIT_EVENT_TYPE_TEAM_CREATED",
1510            Self::TeamUpdated => "AUDIT_EVENT_TYPE_TEAM_UPDATED",
1511            Self::TeamDeleted => "AUDIT_EVENT_TYPE_TEAM_DELETED",
1512            Self::TeamMembersAdded => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED",
1513            Self::TeamMembersRemoved => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED",
1514            Self::ScimUserProvisioned => "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED",
1515            Self::ScimUserDeprovisioned => "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED",
1516            Self::ScimUserUpdated => "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED",
1517            Self::TranslationCreated => "AUDIT_EVENT_TYPE_TRANSLATION_CREATED",
1518            Self::TranslationApproved => "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED",
1519            Self::SandboxCreated => "AUDIT_EVENT_TYPE_SANDBOX_CREATED",
1520            Self::SandboxExpired => "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED",
1521            Self::AiPredictionLogged => "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED",
1522        }
1523    }
1524    /// Creates an enum from field names used in the ProtoBuf definition.
1525    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1526        match value {
1527            "AUDIT_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
1528            "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED" => Some(Self::CampaignCreated),
1529            "AUDIT_EVENT_TYPE_MESSAGE_SENT" => Some(Self::MessageSent),
1530            "AUDIT_EVENT_TYPE_MESSAGE_OPENED" => Some(Self::MessageOpened),
1531            "AUDIT_EVENT_TYPE_ACK_REGISTERED" => Some(Self::AckRegistered),
1532            "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED" => Some(Self::EscalationExecuted),
1533            "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED" => Some(Self::CampaignStarted),
1534            "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED" => Some(Self::CampaignCancelled),
1535            "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED" => Some(Self::CampaignUpdated),
1536            "AUDIT_EVENT_TYPE_USER_INVITED" => Some(Self::UserInvited),
1537            "AUDIT_EVENT_TYPE_USER_DEACTIVATED" => Some(Self::UserDeactivated),
1538            "AUDIT_EVENT_TYPE_USER_REACTIVATED" => Some(Self::UserReactivated),
1539            "AUDIT_EVENT_TYPE_ROLE_CHANGED" => Some(Self::RoleChanged),
1540            "AUDIT_EVENT_TYPE_INVITE_REVOKED" => Some(Self::InviteRevoked),
1541            "AUDIT_EVENT_TYPE_PROFILE_UPDATED" => Some(Self::ProfileUpdated),
1542            "AUDIT_EVENT_TYPE_SETTINGS_UPDATED" => Some(Self::SettingsUpdated),
1543            "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED" => Some(Self::PasskeyEnrolled),
1544            "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED" => Some(Self::DataExportRequested),
1545            "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED" => Some(Self::DataDeletionRequested),
1546            "AUDIT_EVENT_TYPE_DATA_RECTIFIED" => Some(Self::DataRectified),
1547            "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED" => Some(Self::ProcessingRestricted),
1548            "AUDIT_EVENT_TYPE_DELETION_CANCELLED" => Some(Self::DeletionCancelled),
1549            "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE" => Some(Self::DeletionImmediate),
1550            "AUDIT_EVENT_TYPE_SSO_CONFIGURED" => Some(Self::SsoConfigured),
1551            "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED" => Some(Self::SsoProviderCreated),
1552            "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED" => Some(Self::SsoProviderDeleted),
1553            "AUDIT_EVENT_TYPE_ORG_UPDATED" => Some(Self::OrgUpdated),
1554            "AUDIT_EVENT_TYPE_ROLE_CREATED" => Some(Self::RoleCreated),
1555            "AUDIT_EVENT_TYPE_ROLE_UPDATED" => Some(Self::RoleUpdated),
1556            "AUDIT_EVENT_TYPE_ROLE_DELETED" => Some(Self::RoleDeleted),
1557            "AUDIT_EVENT_TYPE_TEMPLATE_CREATED" => Some(Self::TemplateCreated),
1558            "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED" => Some(Self::TemplateUpdated),
1559            "AUDIT_EVENT_TYPE_API_KEY_CREATED" => Some(Self::ApiKeyCreated),
1560            "AUDIT_EVENT_TYPE_API_KEY_REVOKED" => Some(Self::ApiKeyRevoked),
1561            "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED" => Some(Self::InviteLinkCreated),
1562            "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED" => Some(Self::InviteLinkRevoked),
1563            "AUDIT_EVENT_TYPE_GROUP_CREATED" => Some(Self::GroupCreated),
1564            "AUDIT_EVENT_TYPE_GROUP_UPDATED" => Some(Self::GroupUpdated),
1565            "AUDIT_EVENT_TYPE_GROUP_DELETED" => Some(Self::GroupDeleted),
1566            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED" => Some(Self::GroupMembersAdded),
1567            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED" => Some(Self::GroupMembersRemoved),
1568            "AUDIT_EVENT_TYPE_TEAM_CREATED" => Some(Self::TeamCreated),
1569            "AUDIT_EVENT_TYPE_TEAM_UPDATED" => Some(Self::TeamUpdated),
1570            "AUDIT_EVENT_TYPE_TEAM_DELETED" => Some(Self::TeamDeleted),
1571            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED" => Some(Self::TeamMembersAdded),
1572            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED" => Some(Self::TeamMembersRemoved),
1573            "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED" => Some(Self::ScimUserProvisioned),
1574            "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED" => Some(Self::ScimUserDeprovisioned),
1575            "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED" => Some(Self::ScimUserUpdated),
1576            "AUDIT_EVENT_TYPE_TRANSLATION_CREATED" => Some(Self::TranslationCreated),
1577            "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED" => Some(Self::TranslationApproved),
1578            "AUDIT_EVENT_TYPE_SANDBOX_CREATED" => Some(Self::SandboxCreated),
1579            "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED" => Some(Self::SandboxExpired),
1580            "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED" => Some(Self::AiPredictionLogged),
1581            _ => None,
1582        }
1583    }
1584}
1585/// Format for audit trail export.
1586#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1587#[repr(i32)]
1588pub enum AuditExportFormat {
1589    /// Default value; should not be used explicitly.
1590    Unspecified = 0,
1591    /// Comma-separated values.
1592    Csv = 1,
1593    /// JSON lines format.
1594    Json = 2,
1595    /// Apache Parquet columnar format.
1596    Parquet = 3,
1597}
1598impl AuditExportFormat {
1599    /// String value of the enum field names used in the ProtoBuf definition.
1600    ///
1601    /// The values are not transformed in any way and thus are considered stable
1602    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1603    pub fn as_str_name(&self) -> &'static str {
1604        match self {
1605            Self::Unspecified => "AUDIT_EXPORT_FORMAT_UNSPECIFIED",
1606            Self::Csv => "AUDIT_EXPORT_FORMAT_CSV",
1607            Self::Json => "AUDIT_EXPORT_FORMAT_JSON",
1608            Self::Parquet => "AUDIT_EXPORT_FORMAT_PARQUET",
1609        }
1610    }
1611    /// Creates an enum from field names used in the ProtoBuf definition.
1612    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1613        match value {
1614            "AUDIT_EXPORT_FORMAT_UNSPECIFIED" => Some(Self::Unspecified),
1615            "AUDIT_EXPORT_FORMAT_CSV" => Some(Self::Csv),
1616            "AUDIT_EXPORT_FORMAT_JSON" => Some(Self::Json),
1617            "AUDIT_EXPORT_FORMAT_PARQUET" => Some(Self::Parquet),
1618            _ => None,
1619        }
1620    }
1621}
1622// ─── Messages ───────────────────────────────────────────────────────────────
1623
1624/// A campaign that delivers structured messages to a set of recipients
1625/// and tracks their engagement through a workflow.
1626#[derive(Clone, PartialEq, ::prost::Message)]
1627pub struct Campaign {
1628    /// Unique identifier for the campaign.
1629    /// Constraints: UUID format (36 characters).
1630    #[prost(string, tag="1")]
1631    pub id: ::prost::alloc::string::String,
1632    /// Human-readable campaign name.
1633    /// Constraints: Max length 200 characters.
1634    #[prost(string, tag="2")]
1635    pub name: ::prost::alloc::string::String,
1636    /// ID of the template used to render messages.
1637    /// Constraints: UUID format (36 characters).
1638    #[prost(string, tag="3")]
1639    pub template_id: ::prost::alloc::string::String,
1640    /// Pinned version of the template used for this campaign.
1641    #[prost(int32, tag="4")]
1642    pub template_version: i32,
1643    /// Object storage reference to the audience snapshot taken at campaign creation.
1644    #[prost(string, tag="5")]
1645    pub audience_snapshot_ref: ::prost::alloc::string::String,
1646    /// Current lifecycle status of the campaign.
1647    #[prost(enumeration="CampaignStatus", tag="6")]
1648    pub status: i32,
1649    /// Workflow DAG that drives the campaign's automation logic.
1650    #[prost(message, optional, tag="7")]
1651    pub workflow: ::core::option::Option<WorkflowDefinition>,
1652    /// Total number of recipients in the audience snapshot.
1653    #[prost(int32, tag="8")]
1654    pub total_recipients: i32,
1655    /// Number of recipients who completed the required action.
1656    #[prost(int32, tag="9")]
1657    pub action_completed_count: i32,
1658    /// Number of recipients who did not act before the deadline.
1659    #[prost(int32, tag="10")]
1660    pub missed_count: i32,
1661    /// Timestamp when the campaign was created.
1662    #[prost(message, optional, tag="11")]
1663    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1664    /// Timestamp when the campaign was started (workflow execution began).
1665    #[prost(message, optional, tag="12")]
1666    pub started_at: ::core::option::Option<::prost_types::Timestamp>,
1667    /// Timestamp when the campaign finished (completed, failed, or cancelled).
1668    #[prost(message, optional, tag="13")]
1669    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1670    /// Display name of the sender shown to recipients (e.g. "HR Team").
1671    /// Constraints: Max length 200 characters.
1672    #[prost(string, tag="14")]
1673    pub sender_name: ::prost::alloc::string::String,
1674    /// Optional user-facing title override. If set, takes precedence over the template title.
1675    /// Constraints: Max length 200 characters.
1676    #[prost(string, tag="15")]
1677    pub title: ::prost::alloc::string::String,
1678    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
1679    #[prost(bool, tag="16")]
1680    pub critical: bool,
1681    /// Optional locale override for all recipients in this campaign.
1682    /// When set, all recipients receive the campaign in this locale regardless of
1683    /// their preferred_locale. Empty means per-recipient locale resolution.
1684    /// Valid values: en, es, pt-BR, zh, ja.
1685    #[prost(string, tag="17")]
1686    pub default_locale: ::prost::alloc::string::String,
1687    /// Whether the campaign deadline waits for users without registered devices.
1688    /// When true, NO_DEVICE users remain in pending_count and can acknowledge
1689    /// via inbox after installing the app. Default false preserves current behavior.
1690    #[prost(bool, tag="18")]
1691    pub wait_for_enrollment: bool,
1692}
1693/// A single audience member with optional per-user template variables.
1694#[derive(Clone, PartialEq, ::prost::Message)]
1695pub struct AudienceMember {
1696    /// User ID (UUID).
1697    #[prost(string, tag="1")]
1698    pub user_id: ::prost::alloc::string::String,
1699    /// Template variable values for this user (e.g. {"name": "Alice"}).
1700    #[prost(map="string, string", tag="2")]
1701    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1702}
1703/// Request to create a new campaign.
1704#[derive(Clone, PartialEq, ::prost::Message)]
1705pub struct CreateCampaignRequest {
1706    /// Human-readable campaign name (admin-facing label).
1707    /// Constraints: Max length 200 characters.
1708    #[prost(string, tag="1")]
1709    pub name: ::prost::alloc::string::String,
1710    /// ID of the template to use for rendering messages.
1711    /// Constraints: UUID format (36 characters).
1712    #[prost(string, tag="2")]
1713    pub template_id: ::prost::alloc::string::String,
1714    /// Version of the template to pin for this campaign.
1715    #[prost(int32, tag="3")]
1716    pub template_version: i32,
1717    /// List of user IDs that form the campaign audience.
1718    /// Constraints: Max 100000 items.
1719    #[prost(string, repeated, tag="4")]
1720    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1721    /// Workflow DAG defining the campaign's automation steps.
1722    #[prost(message, optional, tag="5")]
1723    pub workflow: ::core::option::Option<WorkflowDefinition>,
1724    /// Display name of the sender shown to recipients (e.g. "HR Team").
1725    /// Constraints: Max length 200 characters.
1726    #[prost(string, tag="6")]
1727    pub sender_name: ::prost::alloc::string::String,
1728    /// Optional user-facing title override. If empty, the template title is used.
1729    /// Constraints: Max length 200 characters.
1730    #[prost(string, tag="7")]
1731    pub title: ::prost::alloc::string::String,
1732    /// Rich audience with per-user template variables.
1733    /// When set, takes precedence over user_ids.
1734    /// Constraints: Max 100000 items.
1735    #[prost(message, repeated, tag="8")]
1736    pub audience: ::prost::alloc::vec::Vec<AudienceMember>,
1737    /// Whether to include users with processing_restricted=true in the audience.
1738    /// Default false: restricted users are excluded. Set true only with Art. 18(2) legal basis.
1739    #[prost(bool, tag="9")]
1740    pub include_restricted: bool,
1741    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
1742    #[prost(bool, tag="10")]
1743    pub critical: bool,
1744    /// Optional locale override for all recipients.
1745    #[prost(string, tag="11")]
1746    pub default_locale: ::prost::alloc::string::String,
1747    /// Whether the campaign deadline should wait for users without registered devices.
1748    /// When true, NO_DEVICE users are not decremented from pending_count,
1749    /// allowing them to acknowledge via inbox after installing the app.
1750    #[prost(bool, tag="12")]
1751    pub wait_for_enrollment: bool,
1752}
1753/// Response after creating a campaign.
1754#[derive(Clone, PartialEq, ::prost::Message)]
1755pub struct CreateCampaignResponse {
1756    /// The newly created campaign.
1757    #[prost(message, optional, tag="1")]
1758    pub campaign: ::core::option::Option<Campaign>,
1759}
1760/// Request to start a campaign's workflow execution.
1761#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1762pub struct StartCampaignRequest {
1763    /// ID of the campaign to start.
1764    /// Constraints: UUID format (36 characters).
1765    #[prost(string, tag="1")]
1766    pub campaign_id: ::prost::alloc::string::String,
1767}
1768/// Response after starting a campaign.
1769#[derive(Clone, PartialEq, ::prost::Message)]
1770pub struct StartCampaignResponse {
1771    /// The campaign with updated status.
1772    #[prost(message, optional, tag="1")]
1773    pub campaign: ::core::option::Option<Campaign>,
1774}
1775/// Request to retrieve a single campaign by ID.
1776#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1777pub struct GetCampaignRequest {
1778    /// ID of the campaign to retrieve.
1779    /// Constraints: UUID format (36 characters).
1780    #[prost(string, tag="1")]
1781    pub campaign_id: ::prost::alloc::string::String,
1782}
1783/// Response containing the requested campaign.
1784#[derive(Clone, PartialEq, ::prost::Message)]
1785pub struct GetCampaignResponse {
1786    /// The requested campaign.
1787    #[prost(message, optional, tag="1")]
1788    pub campaign: ::core::option::Option<Campaign>,
1789}
1790/// Request to list campaigns with pagination.
1791#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1792pub struct ListCampaignsRequest {
1793    /// Pagination parameters.
1794    #[prost(message, optional, tag="1")]
1795    pub pagination: ::core::option::Option<Pagination>,
1796}
1797/// Response containing a page of campaigns.
1798#[derive(Clone, PartialEq, ::prost::Message)]
1799pub struct ListCampaignsResponse {
1800    /// List of campaigns in this page.
1801    #[prost(message, repeated, tag="1")]
1802    pub campaigns: ::prost::alloc::vec::Vec<Campaign>,
1803    /// Pagination metadata for fetching subsequent pages.
1804    #[prost(message, optional, tag="2")]
1805    pub pagination_meta: ::core::option::Option<PaginationMeta>,
1806}
1807/// Request to cancel a running campaign.
1808#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1809pub struct CancelCampaignRequest {
1810    /// ID of the campaign to cancel.
1811    /// Constraints: UUID format (36 characters).
1812    #[prost(string, tag="1")]
1813    pub campaign_id: ::prost::alloc::string::String,
1814}
1815/// Response after cancelling a campaign.
1816#[derive(Clone, PartialEq, ::prost::Message)]
1817pub struct CancelCampaignResponse {
1818    /// The campaign with updated status (CANCELLED).
1819    #[prost(message, optional, tag="1")]
1820    pub campaign: ::core::option::Option<Campaign>,
1821}
1822/// Request to update a draft campaign (status must be CREATED).
1823/// Only non-empty/non-zero fields are updated; omitted fields remain unchanged.
1824#[derive(Clone, PartialEq, ::prost::Message)]
1825pub struct UpdateCampaignRequest {
1826    /// ID of the campaign to update.
1827    /// Constraints: UUID format (36 characters).
1828    #[prost(string, tag="1")]
1829    pub campaign_id: ::prost::alloc::string::String,
1830    /// Updated campaign name. Empty string means no change.
1831    /// Constraints: Max length 200 characters.
1832    #[prost(string, tag="2")]
1833    pub name: ::prost::alloc::string::String,
1834    /// Updated sender display name. Empty string means no change.
1835    /// Constraints: Max length 200 characters.
1836    #[prost(string, tag="3")]
1837    pub sender_name: ::prost::alloc::string::String,
1838    /// Updated title override. Empty string means no change.
1839    /// Constraints: Max length 200 characters.
1840    #[prost(string, tag="4")]
1841    pub title: ::prost::alloc::string::String,
1842    /// Updated template ID. Empty string means no change.
1843    /// Constraints: UUID format (36 characters).
1844    #[prost(string, tag="5")]
1845    pub template_id: ::prost::alloc::string::String,
1846    /// Updated template version. Zero means no change.
1847    #[prost(int32, tag="6")]
1848    pub template_version: i32,
1849    /// Updated workflow DAG. Null/omitted means no change.
1850    #[prost(message, optional, tag="7")]
1851    pub workflow: ::core::option::Option<WorkflowDefinition>,
1852}
1853/// Response after updating a campaign.
1854#[derive(Clone, PartialEq, ::prost::Message)]
1855pub struct UpdateCampaignResponse {
1856    /// The campaign with updated fields.
1857    #[prost(message, optional, tag="1")]
1858    pub campaign: ::core::option::Option<Campaign>,
1859}
1860/// A single delivery record tracking message delivery to one recipient.
1861#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1862pub struct Delivery {
1863    /// Unique identifier for this delivery.
1864    /// Constraints: UUID format (36 characters).
1865    #[prost(string, tag="1")]
1866    pub id: ::prost::alloc::string::String,
1867    /// ID of the recipient user.
1868    /// Constraints: UUID format (36 characters).
1869    #[prost(string, tag="2")]
1870    pub user_id: ::prost::alloc::string::String,
1871    /// ID of the campaign this delivery belongs to.
1872    /// Constraints: UUID format (36 characters).
1873    #[prost(string, tag="3")]
1874    pub campaign_id: ::prost::alloc::string::String,
1875    /// Current delivery status.
1876    #[prost(enumeration="DeliveryStatus", tag="4")]
1877    pub status: i32,
1878    /// Timestamp when the message was delivered to the device.
1879    #[prost(message, optional, tag="5")]
1880    pub delivered_at: ::core::option::Option<::prost_types::Timestamp>,
1881    /// Timestamp when the recipient read the message.
1882    #[prost(message, optional, tag="6")]
1883    pub read_at: ::core::option::Option<::prost_types::Timestamp>,
1884    /// Timestamp when the recipient performed the required action.
1885    #[prost(message, optional, tag="7")]
1886    pub acted_at: ::core::option::Option<::prost_types::Timestamp>,
1887    /// Email address of the recipient, populated from the users table on read.
1888    #[prost(string, tag="8")]
1889    pub recipient_email: ::prost::alloc::string::String,
1890    /// Discriminator distinguishing primary recipient deliveries from
1891    /// deliveries generated by downstream workflow steps.
1892    #[prost(enumeration="delivery::Kind", tag="12")]
1893    pub kind: i32,
1894    /// For non-primary deliveries, the UUID of the originating delivery this
1895    /// row was derived from. Empty for primary deliveries.
1896    /// Constraints: UUID format (36 characters) when set.
1897    #[prost(string, tag="13")]
1898    pub parent_delivery_id: ::prost::alloc::string::String,
1899    /// The locale this delivery's body was actually rendered in after fallback
1900    /// resolution (recipient preference, campaign override, template default).
1901    /// Valid values: en, es, pt-BR, zh, ja.
1902    #[prost(string, tag="14")]
1903    pub rendered_locale: ::prost::alloc::string::String,
1904}
1905/// Nested message and enum types in `Delivery`.
1906pub mod delivery {
1907    /// Discriminator describing what produced this delivery row.
1908    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1909    #[repr(i32)]
1910    pub enum Kind {
1911        /// Default value; not a valid kind.
1912        Unspecified = 0,
1913        /// Delivery generated for an audience recipient at campaign start.
1914        Primary = 1,
1915        /// Delivery generated by an escalation step targeting a non-audience user.
1916        Escalation = 2,
1917    }
1918    impl Kind {
1919        /// String value of the enum field names used in the ProtoBuf definition.
1920        ///
1921        /// The values are not transformed in any way and thus are considered stable
1922        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1923        pub fn as_str_name(&self) -> &'static str {
1924            match self {
1925                Self::Unspecified => "KIND_UNSPECIFIED",
1926                Self::Primary => "KIND_PRIMARY",
1927                Self::Escalation => "KIND_ESCALATION",
1928            }
1929        }
1930        /// Creates an enum from field names used in the ProtoBuf definition.
1931        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1932            match value {
1933                "KIND_UNSPECIFIED" => Some(Self::Unspecified),
1934                "KIND_PRIMARY" => Some(Self::Primary),
1935                "KIND_ESCALATION" => Some(Self::Escalation),
1936                _ => None,
1937            }
1938        }
1939    }
1940}
1941/// Request to list deliveries for a campaign with optional status filtering.
1942#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1943pub struct ListDeliveriesRequest {
1944    /// ID of the campaign to list deliveries for.
1945    /// Constraints: UUID format (36 characters).
1946    #[prost(string, tag="1")]
1947    pub campaign_id: ::prost::alloc::string::String,
1948    /// Optional filter by delivery status. UNSPECIFIED returns all.
1949    #[prost(enumeration="DeliveryStatus", tag="2")]
1950    pub status_filter: i32,
1951    /// Pagination parameters.
1952    #[prost(message, optional, tag="3")]
1953    pub pagination: ::core::option::Option<Pagination>,
1954}
1955/// Response containing a page of delivery records.
1956#[derive(Clone, PartialEq, ::prost::Message)]
1957pub struct ListDeliveriesResponse {
1958    /// List of deliveries in this page.
1959    #[prost(message, repeated, tag="1")]
1960    pub deliveries: ::prost::alloc::vec::Vec<Delivery>,
1961    /// Pagination metadata for fetching subsequent pages.
1962    #[prost(message, optional, tag="2")]
1963    pub pagination_meta: ::core::option::Option<PaginationMeta>,
1964}
1965// ─── Messages ───────────────────────────────────────────────────────────────
1966
1967/// A registered device that can receive push notifications.
1968/// INTERNAL: This message is for server-side use only. Use DeviceSummary for API responses.
1969#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1970pub struct Device {
1971    /// Unique identifier for this device.
1972    /// Constraints: UUID format (36 characters).
1973    #[prost(string, tag="1")]
1974    pub device_id: ::prost::alloc::string::String,
1975    /// ID of the user who owns this device.
1976    /// Constraints: UUID format (36 characters).
1977    #[prost(string, tag="2")]
1978    pub user_id: ::prost::alloc::string::String,
1979    /// Mobile platform (iOS or Android).
1980    #[prost(enumeration="Platform", tag="3")]
1981    pub platform: i32,
1982    /// Push token used to send notifications to this device.
1983    #[prost(string, tag="4")]
1984    pub push_token: ::prost::alloc::string::String,
1985    /// Whether the device is currently active and eligible for push delivery.
1986    #[prost(bool, tag="5")]
1987    pub active: bool,
1988    /// Timestamp of the last activity from this device.
1989    #[prost(message, optional, tag="6")]
1990    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
1991    /// Timestamp when the device was first registered.
1992    #[prost(message, optional, tag="7")]
1993    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1994}
1995/// A device summary safe for API responses — excludes sensitive push_token.
1996#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1997pub struct DeviceSummary {
1998    /// Unique identifier for this device.
1999    #[prost(string, tag="1")]
2000    pub device_id: ::prost::alloc::string::String,
2001    /// ID of the user who owns this device.
2002    #[prost(string, tag="2")]
2003    pub user_id: ::prost::alloc::string::String,
2004    /// Mobile platform (iOS or Android).
2005    #[prost(enumeration="Platform", tag="3")]
2006    pub platform: i32,
2007    /// Whether the device is currently active and eligible for push delivery.
2008    #[prost(bool, tag="4")]
2009    pub active: bool,
2010    /// Timestamp of the last activity from this device.
2011    #[prost(message, optional, tag="5")]
2012    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
2013    /// Timestamp when the device was first registered.
2014    #[prost(message, optional, tag="6")]
2015    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2016}
2017/// Request to register a device for push notifications.
2018#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2019pub struct RegisterRequest {
2020    /// Client-generated unique device identifier.
2021    /// Constraints: UUID format (36 characters).
2022    #[prost(string, tag="1")]
2023    pub device_id: ::prost::alloc::string::String,
2024    /// Mobile platform of the device.
2025    #[prost(enumeration="Platform", tag="2")]
2026    pub platform: i32,
2027    /// Push token obtained from the push notification provider on the client.
2028    /// Constraints: Max length 4096 characters.
2029    #[prost(string, tag="3")]
2030    pub push_token: ::prost::alloc::string::String,
2031}
2032/// Response after registering a device.
2033#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2034pub struct RegisterResponse {
2035    /// The registered device summary (excludes push_token).
2036    #[prost(message, optional, tag="1")]
2037    pub device: ::core::option::Option<DeviceSummary>,
2038}
2039/// Request to deactivate a device, stopping push notifications.
2040#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2041pub struct DeactivateRequest {
2042    /// ID of the device to deactivate.
2043    /// Constraints: UUID format (36 characters).
2044    #[prost(string, tag="1")]
2045    pub device_id: ::prost::alloc::string::String,
2046}
2047/// Response after deactivating a device.
2048#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2049pub struct DeactivateResponse {
2050    /// Whether the device was successfully deactivated.
2051    #[prost(bool, tag="1")]
2052    pub success: bool,
2053}
2054/// Request to list all devices for the authenticated user.
2055#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2056pub struct ListDevicesRequest {
2057}
2058/// Response containing all devices for the user.
2059#[derive(Clone, PartialEq, ::prost::Message)]
2060pub struct ListDevicesResponse {
2061    /// List of devices registered to the authenticated user.
2062    #[prost(message, repeated, tag="1")]
2063    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
2064}
2065/// Request to list devices for a specific member (admin use).
2066#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2067pub struct ListMemberDevicesRequest {
2068    /// ID of the user whose devices to list.
2069    /// Constraints: UUID format (36 characters).
2070    #[prost(string, tag="1")]
2071    pub user_id: ::prost::alloc::string::String,
2072}
2073/// Response containing all devices for the specified member.
2074#[derive(Clone, PartialEq, ::prost::Message)]
2075pub struct ListMemberDevicesResponse {
2076    /// List of devices registered to the specified user.
2077    #[prost(message, repeated, tag="1")]
2078    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
2079}
2080// ─── Messages ───────────────────────────────────────────────────────────────
2081
2082/// User-configurable platform settings that apply across all clients.
2083/// All fields use their UNSPECIFIED/zero value to mean "no change" in updates.
2084#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2085pub struct UserSettings {
2086    /// Preferred color scheme for the UI.
2087    #[prost(enumeration="ThemePreference", tag="1")]
2088    pub theme_preference: i32,
2089    /// User's preferred language for the UI and push notifications.
2090    /// Empty string means "use organization default" or "auto-detect".
2091    /// Valid values: en, es, pt-BR, zh, ja.
2092    #[prost(string, tag="2")]
2093    pub preferred_locale: ::prost::alloc::string::String,
2094}
2095/// Structured profile attributes for a user within an organization.
2096/// Populated through admin invitation, mobile onboarding, or SSO attribute sync.
2097#[derive(Clone, PartialEq, ::prost::Message)]
2098pub struct UserProfile {
2099    /// User's given name.
2100    /// Constraints: Max length 200 characters.
2101    #[prost(string, tag="1")]
2102    pub first_name: ::prost::alloc::string::String,
2103    /// User's family name.
2104    /// Constraints: Max length 200 characters.
2105    #[prost(string, tag="2")]
2106    pub last_name: ::prost::alloc::string::String,
2107    /// Department or team within the organization.
2108    /// Constraints: Max length 200 characters.
2109    #[prost(string, tag="3")]
2110    pub department: ::prost::alloc::string::String,
2111    /// Job title.
2112    /// Constraints: Max length 200 characters.
2113    #[prost(string, tag="4")]
2114    pub title: ::prost::alloc::string::String,
2115    /// Phone number.
2116    /// Constraints: Max length 200 characters.
2117    #[prost(string, tag="5")]
2118    pub phone: ::prost::alloc::string::String,
2119    /// Office or geographic location.
2120    /// Constraints: Max length 200 characters.
2121    #[prost(string, tag="6")]
2122    pub location: ::prost::alloc::string::String,
2123    /// Organization-specific employee identifier.
2124    /// Constraints: Max length 200 characters.
2125    #[prost(string, tag="7")]
2126    pub employee_id: ::prost::alloc::string::String,
2127    /// Display name of the user's direct manager.
2128    /// Constraints: Max length 200 characters.
2129    #[prost(string, tag="8")]
2130    pub manager_name: ::prost::alloc::string::String,
2131    /// Employment start date in ISO 8601 format (YYYY-MM-DD).
2132    /// Constraints: Max length 200 characters.
2133    #[prost(string, tag="9")]
2134    pub start_date: ::prost::alloc::string::String,
2135    /// Organization-defined custom attributes for fields not covered by the fixed schema.
2136    /// Constraints: Max 50 entries. Key max length 100 characters, value max length 1000 characters.
2137    #[prost(map="string, string", tag="10")]
2138    pub custom_attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
2139    /// UUID of the user's direct manager within the same organization.
2140    /// Populated from SCIM enterprise extension (manager.value), manual admin
2141    /// assignment, or SSO attribute mapping. Empty if not set.
2142    #[prost(string, tag="11")]
2143    pub manager_id: ::prost::alloc::string::String,
2144}
2145/// A user within an organization.
2146#[derive(Clone, PartialEq, ::prost::Message)]
2147pub struct User {
2148    /// Unique identifier for the user (internal platform UUID, not identity provider subject ID).
2149    #[prost(string, tag="1")]
2150    pub id: ::prost::alloc::string::String,
2151    /// User's email address.
2152    /// Constraints: Max length 254 characters (RFC 5321).
2153    #[prost(string, tag="2")]
2154    pub email: ::prost::alloc::string::String,
2155    /// User's display name.
2156    /// Constraints: Max length 200 characters.
2157    #[prost(string, tag="3")]
2158    pub name: ::prost::alloc::string::String,
2159    /// Current account status.
2160    #[prost(enumeration="UserStatus", tag="5")]
2161    pub status: i32,
2162    /// Timestamp when the user was created.
2163    #[prost(message, optional, tag="6")]
2164    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2165    /// The user's role with its permission set.
2166    #[prost(message, optional, tag="7")]
2167    pub role: ::core::option::Option<Role>,
2168    /// ID of the user's role (for assignment operations).
2169    #[prost(string, tag="8")]
2170    pub role_id: ::prost::alloc::string::String,
2171    /// Structured profile attributes (department, title, etc.).
2172    /// May be empty if the user has not completed their profile.
2173    #[prost(message, optional, tag="9")]
2174    pub profile: ::core::option::Option<UserProfile>,
2175    /// Whether data processing is restricted for this user (GDPR Art. 18).
2176    /// When true, the user is excluded from campaign audiences by default.
2177    #[prost(bool, tag="10")]
2178    pub processing_restricted: bool,
2179    /// Data governance region override. Empty string means "inherit from org default".
2180    /// Valid values: EU, LATAM, BR, APAC, US.
2181    #[prost(string, tag="11")]
2182    pub data_governance_region: ::prost::alloc::string::String,
2183}
2184// ─── Enums ──────────────────────────────────────────────────────────────────
2185
2186/// Lifecycle status of a user account.
2187#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2188#[repr(i32)]
2189pub enum UserStatus {
2190    /// Default value; not a valid status.
2191    Unspecified = 0,
2192    /// User has been invited but has not completed onboarding.
2193    Invited = 1,
2194    /// User is active and can receive messages.
2195    Active = 2,
2196    /// User has been deactivated and will not receive messages.
2197    Deactivated = 3,
2198}
2199impl UserStatus {
2200    /// String value of the enum field names used in the ProtoBuf definition.
2201    ///
2202    /// The values are not transformed in any way and thus are considered stable
2203    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2204    pub fn as_str_name(&self) -> &'static str {
2205        match self {
2206            Self::Unspecified => "USER_STATUS_UNSPECIFIED",
2207            Self::Invited => "USER_STATUS_INVITED",
2208            Self::Active => "USER_STATUS_ACTIVE",
2209            Self::Deactivated => "USER_STATUS_DEACTIVATED",
2210        }
2211    }
2212    /// Creates an enum from field names used in the ProtoBuf definition.
2213    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2214        match value {
2215            "USER_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
2216            "USER_STATUS_INVITED" => Some(Self::Invited),
2217            "USER_STATUS_ACTIVE" => Some(Self::Active),
2218            "USER_STATUS_DEACTIVATED" => Some(Self::Deactivated),
2219            _ => None,
2220        }
2221    }
2222}
2223/// User's preferred color scheme.
2224#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2225#[repr(i32)]
2226pub enum ThemePreference {
2227    /// Default value; treated as SYSTEM when reading, "no change" when updating.
2228    Unspecified = 0,
2229    /// Always use light mode regardless of system setting.
2230    Light = 1,
2231    /// Always use dark mode regardless of system setting.
2232    Dark = 2,
2233    /// Follow the operating system or browser preference.
2234    System = 3,
2235}
2236impl ThemePreference {
2237    /// String value of the enum field names used in the ProtoBuf definition.
2238    ///
2239    /// The values are not transformed in any way and thus are considered stable
2240    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2241    pub fn as_str_name(&self) -> &'static str {
2242        match self {
2243            Self::Unspecified => "THEME_PREFERENCE_UNSPECIFIED",
2244            Self::Light => "THEME_PREFERENCE_LIGHT",
2245            Self::Dark => "THEME_PREFERENCE_DARK",
2246            Self::System => "THEME_PREFERENCE_SYSTEM",
2247        }
2248    }
2249    /// Creates an enum from field names used in the ProtoBuf definition.
2250    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2251        match value {
2252            "THEME_PREFERENCE_UNSPECIFIED" => Some(Self::Unspecified),
2253            "THEME_PREFERENCE_LIGHT" => Some(Self::Light),
2254            "THEME_PREFERENCE_DARK" => Some(Self::Dark),
2255            "THEME_PREFERENCE_SYSTEM" => Some(Self::System),
2256            _ => None,
2257        }
2258    }
2259}
2260// ─── Messages ───────────────────────────────────────────────────────────────
2261
2262/// A named collection of users within an organization, used for campaign
2263/// audience targeting (recipient groups).
2264#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2265pub struct Group {
2266    /// Unique identifier for the group.
2267    #[prost(string, tag="1")]
2268    pub id: ::prost::alloc::string::String,
2269    /// Human-readable display name (unique within the organization).
2270    /// Constraints: Max length 200 characters.
2271    #[prost(string, tag="2")]
2272    pub name: ::prost::alloc::string::String,
2273    /// Optional description of the group's purpose.
2274    /// Constraints: Max length 1000 characters.
2275    #[prost(string, tag="3")]
2276    pub description: ::prost::alloc::string::String,
2277    /// Number of users currently in the group.
2278    #[prost(int32, tag="4")]
2279    pub member_count: i32,
2280    /// Timestamp when the group was created.
2281    #[prost(message, optional, tag="5")]
2282    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2283    /// Timestamp when the group was last updated.
2284    #[prost(message, optional, tag="6")]
2285    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
2286    /// Whether this is the organization's default group (cannot be deleted or renamed).
2287    #[prost(bool, tag="7")]
2288    pub is_default: bool,
2289    /// ID of the user who created this group. Empty for system-seeded defaults.
2290    #[prost(string, tag="8")]
2291    pub created_by: ::prost::alloc::string::String,
2292}
2293/// Request to create a new group.
2294#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2295pub struct CreateGroupRequest {
2296    /// Display name for the group. Required.
2297    /// Constraints: Max length 200 characters.
2298    #[prost(string, tag="1")]
2299    pub name: ::prost::alloc::string::String,
2300    /// Optional description.
2301    /// Constraints: Max length 1000 characters.
2302    #[prost(string, tag="2")]
2303    pub description: ::prost::alloc::string::String,
2304}
2305/// Response after creating a group.
2306#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2307pub struct CreateGroupResponse {
2308    /// The newly created group.
2309    #[prost(message, optional, tag="1")]
2310    pub group: ::core::option::Option<Group>,
2311}
2312/// Request to retrieve a group by ID.
2313#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2314pub struct GetGroupRequest {
2315    /// ID of the group to retrieve. Required.
2316    #[prost(string, tag="1")]
2317    pub group_id: ::prost::alloc::string::String,
2318}
2319/// Response containing the requested group.
2320#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2321pub struct GetGroupResponse {
2322    /// The requested group.
2323    #[prost(message, optional, tag="1")]
2324    pub group: ::core::option::Option<Group>,
2325}
2326/// Request to list groups in the organization with pagination.
2327#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2328pub struct ListGroupsRequest {
2329    /// Pagination parameters.
2330    #[prost(message, optional, tag="1")]
2331    pub pagination: ::core::option::Option<Pagination>,
2332}
2333/// Response containing a page of groups.
2334#[derive(Clone, PartialEq, ::prost::Message)]
2335pub struct ListGroupsResponse {
2336    /// Groups in this page.
2337    #[prost(message, repeated, tag="1")]
2338    pub groups: ::prost::alloc::vec::Vec<Group>,
2339    /// Pagination metadata for fetching subsequent pages.
2340    #[prost(message, optional, tag="2")]
2341    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2342}
2343/// Request to update a group's name and/or description.
2344#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2345pub struct UpdateGroupRequest {
2346    /// ID of the group to update. Required.
2347    #[prost(string, tag="1")]
2348    pub group_id: ::prost::alloc::string::String,
2349    /// New display name. If empty, the name is not changed.
2350    /// Default groups cannot be renamed.
2351    /// Constraints: Max length 200 characters.
2352    #[prost(string, tag="2")]
2353    pub name: ::prost::alloc::string::String,
2354    /// New description. If empty, the description is not changed.
2355    /// Constraints: Max length 1000 characters.
2356    #[prost(string, tag="3")]
2357    pub description: ::prost::alloc::string::String,
2358}
2359/// Response after updating a group.
2360#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2361pub struct UpdateGroupResponse {
2362    /// The updated group.
2363    #[prost(message, optional, tag="1")]
2364    pub group: ::core::option::Option<Group>,
2365}
2366/// Request to delete a group.
2367#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2368pub struct DeleteGroupRequest {
2369    /// ID of the group to delete. Required.
2370    /// Default groups cannot be deleted.
2371    #[prost(string, tag="1")]
2372    pub group_id: ::prost::alloc::string::String,
2373}
2374/// Response after deleting a group.
2375#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2376pub struct DeleteGroupResponse {
2377}
2378/// Request to add users to a group.
2379#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2380pub struct AddGroupMembersRequest {
2381    /// ID of the group to add members to. Required.
2382    #[prost(string, tag="1")]
2383    pub group_id: ::prost::alloc::string::String,
2384    /// IDs of users to add. Must belong to the same organization.
2385    /// Adding an existing member is a no-op (idempotent).
2386    /// Constraints: Max 100 user IDs per request.
2387    #[prost(string, repeated, tag="2")]
2388    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2389}
2390/// Response after adding group members.
2391#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2392pub struct AddGroupMembersResponse {
2393    /// The group with updated member_count.
2394    #[prost(message, optional, tag="1")]
2395    pub group: ::core::option::Option<Group>,
2396}
2397/// Request to remove users from a group.
2398#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2399pub struct RemoveGroupMembersRequest {
2400    /// ID of the group to remove members from. Required.
2401    #[prost(string, tag="1")]
2402    pub group_id: ::prost::alloc::string::String,
2403    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
2404    /// Constraints: Max 100 user IDs per request.
2405    #[prost(string, repeated, tag="2")]
2406    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2407}
2408/// Response after removing group members.
2409#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2410pub struct RemoveGroupMembersResponse {
2411    /// The group with updated member_count.
2412    #[prost(message, optional, tag="1")]
2413    pub group: ::core::option::Option<Group>,
2414}
2415/// Request to list members of a group with pagination.
2416#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2417pub struct ListGroupMembersRequest {
2418    /// ID of the group whose members to list. Required.
2419    #[prost(string, tag="1")]
2420    pub group_id: ::prost::alloc::string::String,
2421    /// Pagination parameters.
2422    #[prost(message, optional, tag="2")]
2423    pub pagination: ::core::option::Option<Pagination>,
2424}
2425/// Response containing a page of group members.
2426#[derive(Clone, PartialEq, ::prost::Message)]
2427pub struct ListGroupMembersResponse {
2428    /// Users in this page.
2429    #[prost(message, repeated, tag="1")]
2430    pub users: ::prost::alloc::vec::Vec<User>,
2431    /// Pagination metadata for fetching subsequent pages.
2432    #[prost(message, optional, tag="2")]
2433    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2434}
2435/// A group membership entry for batch lookups.
2436#[derive(Clone, PartialEq, ::prost::Message)]
2437pub struct UserGroupMembership {
2438    /// ID of the user.
2439    #[prost(string, tag="1")]
2440    pub user_id: ::prost::alloc::string::String,
2441    /// Groups the user belongs to.
2442    #[prost(message, repeated, tag="2")]
2443    pub groups: ::prost::alloc::vec::Vec<Group>,
2444}
2445/// Request to get group memberships for a batch of users.
2446#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2447pub struct GetUserGroupMembershipsRequest {
2448    /// IDs of users to look up. Required.
2449    /// Constraints: Max 200 user IDs per request.
2450    #[prost(string, repeated, tag="1")]
2451    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2452}
2453/// Response containing group memberships for the requested users.
2454#[derive(Clone, PartialEq, ::prost::Message)]
2455pub struct GetUserGroupMembershipsResponse {
2456    /// Group memberships per user. Only users with at least one group are included.
2457    #[prost(message, repeated, tag="1")]
2458    pub memberships: ::prost::alloc::vec::Vec<UserGroupMembership>,
2459}
2460// ─── Messages ───────────────────────────────────────────────────────────────
2461
2462/// A single touch event captured from the mobile app.
2463#[derive(Clone, PartialEq, ::prost::Message)]
2464pub struct TouchEvent {
2465    /// Screen name from React Navigation route.
2466    /// Constraints: Max length 200 characters.
2467    #[prost(string, tag="1")]
2468    pub screen_name: ::prost::alloc::string::String,
2469    /// Horizontal coordinate as a percentage of screen width (0.0–1.0).
2470    /// Constraints: Range 0.0 to 1.0 inclusive.
2471    #[prost(float, tag="2")]
2472    pub x_pct: f32,
2473    /// Vertical coordinate as a percentage of screen height (0.0–1.0).
2474    /// Constraints: Range 0.0 to 1.0 inclusive.
2475    #[prost(float, tag="3")]
2476    pub y_pct: f32,
2477    /// Type of touch event.
2478    #[prost(enumeration="TouchEventType", tag="4")]
2479    pub event_type: i32,
2480    /// Screen width in device pixels at the time of capture.
2481    #[prost(int32, tag="5")]
2482    pub screen_width: i32,
2483    /// Screen height in device pixels at the time of capture.
2484    #[prost(int32, tag="6")]
2485    pub screen_height: i32,
2486    /// Client-side timestamp when the touch occurred.
2487    #[prost(message, optional, tag="7")]
2488    pub client_timestamp: ::core::option::Option<::prost_types::Timestamp>,
2489    /// Campaign ID if the touch occurred during a campaign message view.
2490    /// Empty string for organic (non-campaign) navigation.
2491    #[prost(string, tag="8")]
2492    pub campaign_id: ::prost::alloc::string::String,
2493}
2494/// Request to ingest a batch of touch events from the mobile app.
2495#[derive(Clone, PartialEq, ::prost::Message)]
2496pub struct IngestTouchEventsRequest {
2497    /// Batch of touch events to ingest.
2498    /// Constraints: Max 100 events per batch.
2499    #[prost(message, repeated, tag="1")]
2500    pub events: ::prost::alloc::vec::Vec<TouchEvent>,
2501}
2502/// Response after ingesting touch events.
2503#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2504pub struct IngestTouchEventsResponse {
2505    /// Number of events successfully ingested.
2506    #[prost(int32, tag="1")]
2507    pub ingested_count: i32,
2508}
2509/// A single aggregated data point in a heatmap grid cell.
2510#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2511pub struct HeatmapDataPoint {
2512    /// Grid cell horizontal center as a percentage (0.0–1.0).
2513    #[prost(float, tag="1")]
2514    pub x_pct: f32,
2515    /// Grid cell vertical center as a percentage (0.0–1.0).
2516    #[prost(float, tag="2")]
2517    pub y_pct: f32,
2518    /// Aggregated value for this cell (count, median, or z-score depending on mode).
2519    #[prost(float, tag="3")]
2520    pub value: f32,
2521}
2522/// Request to query aggregated heatmap data for a screen.
2523#[derive(Clone, PartialEq, ::prost::Message)]
2524pub struct QueryHeatmapDataRequest {
2525    /// Screen name to query.
2526    /// Constraints: Max length 200 characters.
2527    #[prost(string, tag="1")]
2528    pub screen_name: ::prost::alloc::string::String,
2529    /// Start of the time range filter (inclusive).
2530    #[prost(message, optional, tag="2")]
2531    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
2532    /// End of the time range filter (inclusive).
2533    #[prost(message, optional, tag="3")]
2534    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
2535    /// Optional: filter by campaign ID.
2536    /// Constraints: UUID format (36 characters).
2537    #[prost(string, tag="4")]
2538    pub campaign_id: ::prost::alloc::string::String,
2539    /// Grid resolution for coordinate rounding. Default: 0.02 (50×50 grid).
2540    /// Constraints: Range 0.005 to 0.1.
2541    #[prost(float, tag="6")]
2542    pub grid_resolution: f32,
2543    /// Aggregation mode (TOTAL or MEDIAN).
2544    #[prost(enumeration="HeatmapMode", tag="7")]
2545    pub mode: i32,
2546    /// Optional: filter by event types. Empty list means all types.
2547    #[prost(enumeration="TouchEventType", repeated, tag="8")]
2548    pub event_types: ::prost::alloc::vec::Vec<i32>,
2549}
2550/// Response containing aggregated heatmap data.
2551#[derive(Clone, PartialEq, ::prost::Message)]
2552pub struct QueryHeatmapDataResponse {
2553    /// Aggregated data points for heatmap rendering.
2554    #[prost(message, repeated, tag="1")]
2555    pub data_points: ::prost::alloc::vec::Vec<HeatmapDataPoint>,
2556    /// URL to a mobile-captured screenshot for this screen, if available.
2557    /// Empty string when no screenshot exists.
2558    #[prost(string, tag="3")]
2559    pub screenshot_url: ::prost::alloc::string::String,
2560    /// Whether per-cohort bucket breakdowns are available (k >= 5).
2561    #[prost(bool, tag="4")]
2562    pub cohort_enabled: bool,
2563}
2564/// Request to upload a screenshot captured from the mobile app.
2565#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2566pub struct UploadScreenshotRequest {
2567    /// Screen name matching React Navigation route (e.g. "MessageDetail::<campaign_uuid>").
2568    /// Constraints: Max length 200 characters.
2569    #[prost(string, tag="1")]
2570    pub screen_name: ::prost::alloc::string::String,
2571    /// App version that captured the screenshot (e.g. "1.15.0").
2572    #[prost(string, tag="2")]
2573    pub app_version: ::prost::alloc::string::String,
2574    /// PNG image data.
2575    /// Constraints: Max 512KB.
2576    #[prost(bytes="vec", tag="3")]
2577    pub image_data: ::prost::alloc::vec::Vec<u8>,
2578}
2579/// Response after uploading a screenshot.
2580#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2581pub struct UploadScreenshotResponse {
2582    /// S3 URL where the screenshot was stored.
2583    #[prost(string, tag="1")]
2584    pub url: ::prost::alloc::string::String,
2585}
2586/// A screen screenshot stored as a static asset.
2587#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2588pub struct ScreenScreenshot {
2589    /// Screen name matching React Navigation route.
2590    #[prost(string, tag="1")]
2591    pub screen_name: ::prost::alloc::string::String,
2592    /// S3 URL to the screenshot image.
2593    #[prost(string, tag="2")]
2594    pub url: ::prost::alloc::string::String,
2595    /// App version this screenshot corresponds to.
2596    #[prost(string, tag="3")]
2597    pub app_version: ::prost::alloc::string::String,
2598}
2599/// Request to list available screen screenshots.
2600#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2601pub struct ListScreenshotsRequest {
2602}
2603/// Response containing available screen screenshots.
2604#[derive(Clone, PartialEq, ::prost::Message)]
2605pub struct ListScreenshotsResponse {
2606    /// Available screen screenshots with their URLs and versions.
2607    #[prost(message, repeated, tag="1")]
2608    pub screenshots: ::prost::alloc::vec::Vec<ScreenScreenshot>,
2609}
2610// ─── Enums ──────────────────────────────────────────────────────────────────
2611
2612/// Type of touch event captured on the mobile app.
2613#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2614#[repr(i32)]
2615pub enum TouchEventType {
2616    /// Default value; not a valid event type.
2617    Unspecified = 0,
2618    /// A single tap on the screen.
2619    Tap = 1,
2620    /// A long press (held for 500ms+).
2621    LongPress = 2,
2622    /// A periodic scroll position sample (viewport midpoint every 2s).
2623    Scroll = 3,
2624    /// The user tapped an action button (e.g. "Acknowledge").
2625    ActionClick = 4,
2626}
2627impl TouchEventType {
2628    /// String value of the enum field names used in the ProtoBuf definition.
2629    ///
2630    /// The values are not transformed in any way and thus are considered stable
2631    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2632    pub fn as_str_name(&self) -> &'static str {
2633        match self {
2634            Self::Unspecified => "TOUCH_EVENT_TYPE_UNSPECIFIED",
2635            Self::Tap => "TOUCH_EVENT_TYPE_TAP",
2636            Self::LongPress => "TOUCH_EVENT_TYPE_LONG_PRESS",
2637            Self::Scroll => "TOUCH_EVENT_TYPE_SCROLL",
2638            Self::ActionClick => "TOUCH_EVENT_TYPE_ACTION_CLICK",
2639        }
2640    }
2641    /// Creates an enum from field names used in the ProtoBuf definition.
2642    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2643        match value {
2644            "TOUCH_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2645            "TOUCH_EVENT_TYPE_TAP" => Some(Self::Tap),
2646            "TOUCH_EVENT_TYPE_LONG_PRESS" => Some(Self::LongPress),
2647            "TOUCH_EVENT_TYPE_SCROLL" => Some(Self::Scroll),
2648            "TOUCH_EVENT_TYPE_ACTION_CLICK" => Some(Self::ActionClick),
2649            _ => None,
2650        }
2651    }
2652}
2653/// Aggregation mode for heatmap data queries.
2654#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2655#[repr(i32)]
2656pub enum HeatmapMode {
2657    /// Default value; not a valid mode.
2658    Unspecified = 0,
2659    /// Sum of all cohort buckets' touches per grid cell (default).
2660    Total = 1,
2661    /// Median touch count per grid cell across cohort buckets.
2662    Median = 2,
2663}
2664impl HeatmapMode {
2665    /// String value of the enum field names used in the ProtoBuf definition.
2666    ///
2667    /// The values are not transformed in any way and thus are considered stable
2668    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2669    pub fn as_str_name(&self) -> &'static str {
2670        match self {
2671            Self::Unspecified => "HEATMAP_MODE_UNSPECIFIED",
2672            Self::Total => "HEATMAP_MODE_TOTAL",
2673            Self::Median => "HEATMAP_MODE_MEDIAN",
2674        }
2675    }
2676    /// Creates an enum from field names used in the ProtoBuf definition.
2677    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2678        match value {
2679            "HEATMAP_MODE_UNSPECIFIED" => Some(Self::Unspecified),
2680            "HEATMAP_MODE_TOTAL" => Some(Self::Total),
2681            "HEATMAP_MODE_MEDIAN" => Some(Self::Median),
2682            _ => None,
2683        }
2684    }
2685}
2686// ─── Messages ───────────────────────────────────────────────────────────────
2687
2688/// A single entry in a user's inbox, combining a message with its delivery state.
2689#[derive(Clone, PartialEq, ::prost::Message)]
2690pub struct InboxEntry {
2691    /// ID of the delivery record for this inbox entry.
2692    /// Constraints: UUID format (36 characters).
2693    #[prost(string, tag="1")]
2694    pub delivery_id: ::prost::alloc::string::String,
2695    /// The fully rendered message content.
2696    #[prost(message, optional, tag="2")]
2697    pub message: ::core::option::Option<Message>,
2698    /// Current delivery status (e.g. DELIVERED, ACKNOWLEDGED).
2699    #[prost(enumeration="DeliveryStatus", tag="3")]
2700    pub status: i32,
2701    /// Whether the user has read this message.
2702    #[prost(bool, tag="4")]
2703    pub read: bool,
2704    /// Timestamp when the message was received in the inbox.
2705    #[prost(message, optional, tag="5")]
2706    pub received_at: ::core::option::Option<::prost_types::Timestamp>,
2707    /// Discriminator: PRIMARY for normal deliveries, ESCALATION for delivery-grade
2708    /// escalations. Mirrors Delivery.kind so inbox-sync clients can branch on the
2709    /// same dimension as listDeliveries clients.
2710    #[prost(enumeration="delivery::Kind", tag="6")]
2711    pub kind: i32,
2712    /// For ESCALATION entries, the UUID of the unacked delivery that triggered this
2713    /// entry. Empty for PRIMARY entries.
2714    #[prost(string, tag="7")]
2715    pub parent_delivery_id: ::prost::alloc::string::String,
2716    /// The locale the body actually rendered in after fallback resolution. Empty
2717    /// for legacy/PRIMARY entries.
2718    #[prost(string, tag="8")]
2719    pub rendered_locale: ::prost::alloc::string::String,
2720}
2721/// Request to sync inbox entries since a given timestamp.
2722#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2723pub struct SyncRequest {
2724    /// Fetch entries newer than this timestamp. Omit for initial sync.
2725    #[prost(message, optional, tag="1")]
2726    pub since: ::core::option::Option<::prost_types::Timestamp>,
2727    /// Maximum number of entries to return.
2728    /// Constraints: Valid range 1 to 200.
2729    #[prost(int32, tag="2")]
2730    pub limit: i32,
2731}
2732/// Response containing synced inbox entries.
2733#[derive(Clone, PartialEq, ::prost::Message)]
2734pub struct SyncResponse {
2735    /// Inbox entries newer than the requested timestamp.
2736    #[prost(message, repeated, tag="1")]
2737    pub entries: ::prost::alloc::vec::Vec<InboxEntry>,
2738    /// Cursor timestamp to use for the next sync call.
2739    #[prost(message, optional, tag="2")]
2740    pub next_since: ::core::option::Option<::prost_types::Timestamp>,
2741}
2742/// Request to mark a message as read.
2743#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2744pub struct MarkReadRequest {
2745    /// ID of the delivery to mark as read.
2746    /// Constraints: UUID format (36 characters).
2747    #[prost(string, tag="1")]
2748    pub delivery_id: ::prost::alloc::string::String,
2749}
2750/// Response after marking a message as read.
2751#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2752pub struct MarkReadResponse {
2753    /// Whether the read status was successfully updated.
2754    #[prost(bool, tag="1")]
2755    pub success: bool,
2756}
2757/// Request to retrieve a single message by delivery ID.
2758#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2759pub struct GetMessageRequest {
2760    /// ID of the delivery to retrieve.
2761    /// Constraints: UUID format (36 characters).
2762    #[prost(string, tag="1")]
2763    pub delivery_id: ::prost::alloc::string::String,
2764}
2765/// Response containing the requested inbox entry.
2766#[derive(Clone, PartialEq, ::prost::Message)]
2767pub struct GetMessageResponse {
2768    /// The inbox entry for the requested delivery.
2769    #[prost(message, optional, tag="1")]
2770    pub entry: ::core::option::Option<InboxEntry>,
2771}
2772// ─── Messages ───────────────────────────────────────────────────────────────
2773
2774/// A behavioral archetype describing a cohort pattern (never an individual).
2775/// Derived from k-anonymized, DP-noised behavioral feature vectors.
2776#[derive(Clone, PartialEq, ::prost::Message)]
2777pub struct Archetype {
2778    /// Human-readable label (e.g., "Swift Acknowledger", "Thorough Reader").
2779    #[prost(string, tag="1")]
2780    pub label: ::prost::alloc::string::String,
2781    /// Description of the behavioral pattern this archetype represents.
2782    #[prost(string, tag="2")]
2783    pub description: ::prost::alloc::string::String,
2784    /// Proportion of the group that belongs to this archetype (0.0-1.0).
2785    #[prost(float, tag="3")]
2786    pub percentage: f32,
2787    /// Centroid of the behavioral feature vector for this archetype.
2788    /// Keys are stable dimension names from the feature extractor
2789    /// vocabulary (e.g., "tap_density", "engagement_depth",
2790    /// "scroll_velocity_p50", "idle_gap_p75"). Single-letter keys are
2791    /// reserved for backward compatibility with pre-v0.64 servers and
2792    /// SHALL be ignored by clients.
2793    #[prost(map="string, double", tag="4")]
2794    pub feature_centroid: ::std::collections::HashMap<::prost::alloc::string::String, f64>,
2795    /// Per-dimension distribution of the archetype's members. Lets the
2796    /// admin render percentile bands instead of single-point centroids.
2797    /// Absent until at least k members exist in the cluster. Keys mirror
2798    /// `feature_centroid` keys.
2799    #[prost(map="string, message", tag="5")]
2800    pub feature_breakdown: ::std::collections::HashMap<::prost::alloc::string::String, DimensionStats>,
2801    /// Tap density heatmap aggregated across sessions for this
2802    /// archetype. Cohort-level only — never per-session timing.
2803    /// Absent when fewer than k sessions have tap data.
2804    #[prost(message, optional, tag="6")]
2805    pub tap_heatmap: ::core::option::Option<TapHeatmap>,
2806    /// Forecast of cluster share at fixed horizons (7/14/30/90 days).
2807    /// Absent during cold start before historical clustering runs exist
2808    /// to extrapolate from.
2809    #[prost(message, optional, tag="7")]
2810    pub forecast: ::core::option::Option<ArchetypeForecast>,
2811    /// Sessions that sit at the median and quartiles of the archetype's
2812    /// centroid distance, ranked by distance. Bounded at three entries.
2813    /// Absent until at least 50 sessions have been scored.
2814    /// Sessions can come from any client that emits to ReplayService —
2815    /// mobile (iOS, Android) or desktop (macOS, Windows, Linux).
2816    #[prost(message, repeated, tag="8")]
2817    pub exemplar_sessions: ::prost::alloc::vec::Vec<ExemplarSession>,
2818    /// Per-screen dwell time distribution, derived from session replay.
2819    /// Absent when fewer than k sessions per screen exist.
2820    #[prost(message, optional, tag="9")]
2821    pub screen_dwell: ::core::option::Option<ScreenDwell>,
2822    /// End-to-end response latencies (push delivered → read → ack) for
2823    /// members of this archetype, as percentiles. Absent until at least
2824    /// k campaign deliveries have been recorded for this archetype.
2825    #[prost(message, optional, tag="10")]
2826    pub response_timeline: ::core::option::Option<ResponseTimeline>,
2827}
2828/// Per-dimension distribution stats for one feature dimension within
2829/// an archetype's cohort. All values are in the same units as
2830/// `Archetype.feature_centroid`. Used to render percentile bands on
2831/// the admin's behavioral profile panel.
2832#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2833pub struct DimensionStats {
2834    /// Centroid value (same as Archetype.feature_centroid\[key\]).
2835    #[prost(double, tag="1")]
2836    pub centroid: f64,
2837    /// 25th percentile across the archetype's members.
2838    #[prost(double, tag="2")]
2839    pub p25: f64,
2840    /// Median across the archetype's members.
2841    #[prost(double, tag="3")]
2842    pub p50: f64,
2843    /// 75th percentile across the archetype's members.
2844    #[prost(double, tag="4")]
2845    pub p75: f64,
2846    /// Median across the entire group (all archetypes), included so the
2847    /// admin can render "this archetype is X% above group median".
2848    #[prost(double, tag="5")]
2849    pub group_p50: f64,
2850}
2851/// A density grid of tap activity for one archetype, normalized to
2852/// \[0.0, 1.0\] where 1.0 is the hottest cell in the cohort. Cohort-
2853/// level only.
2854#[derive(Clone, PartialEq, ::prost::Message)]
2855pub struct TapHeatmap {
2856    /// Width of the density grid in cells.
2857    #[prost(int32, tag="1")]
2858    pub width: i32,
2859    /// Height of the density grid in cells.
2860    #[prost(int32, tag="2")]
2861    pub height: i32,
2862    /// Row-major density values, length must equal width*height. All in
2863    /// \[0.0, 1.0\].
2864    #[prost(double, repeated, tag="3")]
2865    pub values: ::prost::alloc::vec::Vec<f64>,
2866    /// Number of sessions aggregated. Always >= MinFeatureVectorsForClustering
2867    /// when the field is present.
2868    #[prost(int32, tag="4")]
2869    pub session_count: i32,
2870    /// Optional per-event-type breakdown. When present, the writer
2871    /// SHALL emit one entry for each event type in the source data
2872    /// (TAP, LONG_PRESS, SCROLL, ACTION_CLICK).
2873    #[prost(message, repeated, tag="5")]
2874    pub layers: ::prost::alloc::vec::Vec<TapHeatmapLayer>,
2875}
2876/// One per-event-type layer of a TapHeatmap.
2877#[derive(Clone, PartialEq, ::prost::Message)]
2878pub struct TapHeatmapLayer {
2879    /// Event type this layer represents (e.g., "TAP", "LONG_PRESS",
2880    /// "SCROLL", "ACTION_CLICK").
2881    #[prost(string, tag="1")]
2882    pub event_type: ::prost::alloc::string::String,
2883    /// Row-major density values, same dimensions as the parent
2884    /// TapHeatmap. Independently normalized to \[0.0, 1.0\].
2885    #[prost(double, repeated, tag="2")]
2886    pub values: ::prost::alloc::vec::Vec<f64>,
2887}
2888/// Predicted cluster share at fixed horizons with confidence bands.
2889#[derive(Clone, PartialEq, ::prost::Message)]
2890pub struct ArchetypeForecast {
2891    /// Horizons in increasing days. Always one entry each for 7, 14,
2892    /// 30, and 90 days when the field is present.
2893    #[prost(message, repeated, tag="1")]
2894    pub horizons: ::prost::alloc::vec::Vec<ForecastHorizon>,
2895}
2896/// Predicted share at one horizon with a 90% prediction interval.
2897#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2898pub struct ForecastHorizon {
2899    /// Horizon length in days (one of: 7, 14, 30, 90).
2900    #[prost(int32, tag="1")]
2901    pub days: i32,
2902    /// Predicted fraction of the group falling in this archetype at the
2903    /// horizon (0.0-1.0).
2904    #[prost(double, tag="2")]
2905    pub predicted_share: f64,
2906    /// 5th-percentile lower bound of the prediction interval.
2907    #[prost(double, tag="3")]
2908    pub lower: f64,
2909    /// 95th-percentile upper bound of the prediction interval.
2910    #[prost(double, tag="4")]
2911    pub upper: f64,
2912    /// Confidence in this horizon's prediction.
2913    #[prost(enumeration="ConfidenceLevel", tag="5")]
2914    pub confidence: i32,
2915}
2916/// Pointer to a representative session for one archetype, ranked by
2917/// distance to the archetype centroid.
2918#[derive(Clone, PartialEq, ::prost::Message)]
2919pub struct ExemplarSession {
2920    /// Session recording ID retrievable via ReplayService for the same
2921    /// org. Linkable from the admin regardless of originating platform.
2922    #[prost(string, tag="1")]
2923    pub session_id: ::prost::alloc::string::String,
2924    /// Quantile rank within the archetype: 25, 50, or 75. The writer
2925    /// emits at most one session per rank.
2926    #[prost(int32, tag="2")]
2927    pub rank: i32,
2928    /// L2 distance from the session's feature vector to the centroid.
2929    #[prost(double, tag="3")]
2930    pub distance: f64,
2931    /// Optional duration metadata for quick admin labelling.
2932    #[prost(int32, tag="4")]
2933    pub duration_seconds: i32,
2934    /// Optional platform identifier from the vocabulary
2935    /// {"ios", "android", "macos", "windows", "linux"}. The admin
2936    /// renders unknown values verbatim for forward compatibility.
2937    #[prost(string, tag="5")]
2938    pub platform: ::prost::alloc::string::String,
2939}
2940/// Per-screen dwell distribution within an archetype. Lets the admin
2941/// surface "this archetype lingers 8.2s on the Message Detail screen
2942/// vs 0.4s on the Inbox list".
2943#[derive(Clone, PartialEq, ::prost::Message)]
2944pub struct ScreenDwell {
2945    /// One entry per screen. Screens with fewer than k members in the
2946    /// archetype are dropped from the list (not marked as absent).
2947    #[prost(message, repeated, tag="1")]
2948    pub entries: ::prost::alloc::vec::Vec<ScreenDwellEntry>,
2949}
2950#[derive(Clone, PartialEq, ::prost::Message)]
2951pub struct ScreenDwellEntry {
2952    /// Stable screen identifier (e.g., "MessageDetail", "Inbox",
2953    /// "ProfileSettings"). Sourced from the same screen_name vocabulary
2954    /// used by heatmap_cells.
2955    #[prost(string, tag="1")]
2956    pub screen_name: ::prost::alloc::string::String,
2957    /// Median dwell time in seconds for this archetype on this screen.
2958    #[prost(double, tag="2")]
2959    pub median_seconds: f64,
2960    /// 75th-percentile dwell time in seconds.
2961    #[prost(double, tag="3")]
2962    pub p75_seconds: f64,
2963    /// Number of distinct sessions aggregated for this screen.
2964    #[prost(int32, tag="4")]
2965    pub session_count: i32,
2966}
2967/// End-to-end response latencies for members of one archetype, in
2968/// seconds. Each percentile is computed across all qualifying campaign
2969/// deliveries for the archetype's members within the rolling window.
2970#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2971pub struct ResponseTimeline {
2972    /// Time from `delivered_at` to `read_at`, in seconds.
2973    #[prost(message, optional, tag="1")]
2974    pub read_after_delivered: ::core::option::Option<LatencyPercentiles>,
2975    /// Time from `read_at` to `acknowledged_at`, in seconds. Only
2976    /// includes deliveries that were both read and acknowledged.
2977    #[prost(message, optional, tag="2")]
2978    pub ack_after_read: ::core::option::Option<LatencyPercentiles>,
2979    /// End-to-end time from `delivered_at` to `acknowledged_at`, in
2980    /// seconds. Only includes deliveries that were acknowledged.
2981    #[prost(message, optional, tag="3")]
2982    pub ack_after_delivered: ::core::option::Option<LatencyPercentiles>,
2983    /// Number of deliveries the timeline is computed over.
2984    #[prost(int32, tag="4")]
2985    pub delivery_count: i32,
2986}
2987/// Latency distribution stats. Values are in seconds.
2988#[derive(Clone, Copy, PartialEq, ::prost::Message)]
2989pub struct LatencyPercentiles {
2990    #[prost(double, tag="1")]
2991    pub p50: f64,
2992    #[prost(double, tag="2")]
2993    pub p75: f64,
2994    #[prost(double, tag="3")]
2995    pub p95: f64,
2996}
2997/// A cohort-level prediction for campaign acknowledgment rate.
2998/// Never targets or scores individuals — always represents an audience aggregate.
2999#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3000pub struct CohortPrediction {
3001    /// Predicted ACK rate for the audience (0.0-1.0).
3002    #[prost(float, tag="1")]
3003    pub predicted_ack_rate: f32,
3004    /// Lower bound of the confidence interval.
3005    #[prost(float, tag="2")]
3006    pub confidence_low: f32,
3007    /// Upper bound of the confidence interval.
3008    #[prost(float, tag="3")]
3009    pub confidence_high: f32,
3010    /// Confidence level based on available data volume.
3011    #[prost(enumeration="ConfidenceLevel", tag="4")]
3012    pub confidence_level: i32,
3013    /// Number of anonymous data points used for this prediction.
3014    #[prost(int32, tag="5")]
3015    pub data_point_count: i32,
3016}
3017/// Advisory information for campaign configuration, combining predictions and archetypes.
3018#[derive(Clone, PartialEq, ::prost::Message)]
3019pub struct CampaignAdvisory {
3020    /// Cohort-level ACK prediction for the target audience.
3021    #[prost(message, optional, tag="1")]
3022    pub predicted_ack: ::core::option::Option<CohortPrediction>,
3023    /// Suggested escalation delay in minutes based on historical cohort patterns.
3024    /// 0 if insufficient data.
3025    #[prost(int32, tag="2")]
3026    pub suggested_escalation_delay_minutes: i32,
3027    /// Behavioral archetypes for the target audience.
3028    #[prost(message, repeated, tag="3")]
3029    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
3030}
3031/// Request to retrieve behavioral archetypes for a group.
3032#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3033pub struct GetGroupArchetypesRequest {
3034    /// ID of the group to query archetypes for. Required.
3035    #[prost(string, tag="1")]
3036    pub group_id: ::prost::alloc::string::String,
3037}
3038/// Response containing behavioral archetypes for a group.
3039#[derive(Clone, PartialEq, ::prost::Message)]
3040pub struct GetGroupArchetypesResponse {
3041    /// Behavioral archetypes for the group (empty if insufficient data).
3042    #[prost(message, repeated, tag="1")]
3043    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
3044    /// Number of anonymous feature vectors used for clustering.
3045    #[prost(int32, tag="2")]
3046    pub data_point_count: i32,
3047    /// Why `archetypes` looks the way it does. Lets the UI render a
3048    /// distinct empty-state affordance for "never trained" vs
3049    /// "below threshold" vs "no clusters" vs "ready". See PipelineState.
3050    #[prost(enumeration="PipelineState", tag="3")]
3051    pub pipeline_state: i32,
3052}
3053/// Request to predict cohort-level ACK rate for a campaign configuration.
3054#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3055pub struct PredictCampaignAckRequest {
3056    /// ID of the target audience group. Required.
3057    #[prost(string, tag="1")]
3058    pub group_id: ::prost::alloc::string::String,
3059    /// Template type (optional, for prediction refinement).
3060    #[prost(string, tag="2")]
3061    pub template_type: ::prost::alloc::string::String,
3062    /// Number of workflow steps (optional, for prediction refinement).
3063    #[prost(int32, tag="3")]
3064    pub workflow_step_count: i32,
3065}
3066/// Response containing a cohort-level ACK prediction.
3067#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3068pub struct PredictCampaignAckResponse {
3069    /// Cohort-level prediction.
3070    #[prost(message, optional, tag="1")]
3071    pub prediction: ::core::option::Option<CohortPrediction>,
3072}
3073/// Request for campaign configuration advisory.
3074#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3075pub struct GetCampaignAdvisoryRequest {
3076    /// ID of the target audience group. Required.
3077    #[prost(string, tag="1")]
3078    pub group_id: ::prost::alloc::string::String,
3079    /// Template ID (optional, for advisory context).
3080    #[prost(string, tag="2")]
3081    pub template_id: ::prost::alloc::string::String,
3082    /// Template version (optional).
3083    #[prost(int32, tag="3")]
3084    pub template_version: i32,
3085    /// Number of workflow steps (optional).
3086    #[prost(int32, tag="4")]
3087    pub workflow_step_count: i32,
3088}
3089/// Response containing campaign advisory information.
3090#[derive(Clone, PartialEq, ::prost::Message)]
3091pub struct GetCampaignAdvisoryResponse {
3092    /// Campaign advisory with prediction, suggested escalation, and archetypes.
3093    #[prost(message, optional, tag="1")]
3094    pub advisory: ::core::option::Option<CampaignAdvisory>,
3095}
3096/// Request to generate an AI narrative for a group's insights.
3097#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3098pub struct GetInsightNarrativeRequest {
3099    /// ID of the group to generate a narrative for. Required.
3100    #[prost(string, tag="1")]
3101    pub group_id: ::prost::alloc::string::String,
3102    /// Name of the prompt template to use (e.g., "campaign-advisory", "archetype-explanation").
3103    #[prost(string, tag="2")]
3104    pub prompt_name: ::prost::alloc::string::String,
3105}
3106/// Response containing an AI-generated narrative.
3107#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3108pub struct GetInsightNarrativeResponse {
3109    /// AI-generated narrative text (Markdown formatted).
3110    #[prost(string, tag="1")]
3111    pub narrative: ::prost::alloc::string::String,
3112    /// Timestamp when the narrative was generated.
3113    #[prost(message, optional, tag="2")]
3114    pub generated_at: ::core::option::Option<::prost_types::Timestamp>,
3115    /// Model identifier used for generation.
3116    #[prost(string, tag="3")]
3117    pub model_id: ::prost::alloc::string::String,
3118}
3119/// Request to manually trigger the ML training pipeline.
3120/// Empty — organization is extracted from the JWT.
3121#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3122pub struct TriggerMlPipelineRequest {
3123}
3124/// Response after triggering the ML pipeline.
3125#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3126pub struct TriggerMlPipelineResponse {
3127    /// Remaining manual retrains allowed this month.
3128    #[prost(int32, tag="1")]
3129    pub remaining_this_month: i32,
3130    /// Timestamp of the last successful training (null if never trained).
3131    #[prost(message, optional, tag="2")]
3132    pub last_trained_at: ::core::option::Option<::prost_types::Timestamp>,
3133}
3134/// Request to manually retrigger archetype clustering for a single group
3135/// without rerunning the full SageMaker training pipeline. Reuses the
3136/// already-deployed clustering model.
3137#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3138pub struct TriggerArchetypeClusteringRequest {
3139    /// Group to recluster. Org is extracted from the JWT.
3140    #[prost(string, tag="1")]
3141    pub group_id: ::prost::alloc::string::String,
3142}
3143/// Response after triggering archetype clustering for one group.
3144#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3145pub struct TriggerArchetypeClusteringResponse {
3146    /// Temporal workflow id — useful for client-side dedupe + operator
3147    /// debugging via the Temporal UI.
3148    #[prost(string, tag="1")]
3149    pub workflow_id: ::prost::alloc::string::String,
3150    /// Remaining manual retrains allowed this month. Shares the same
3151    /// monthly counter as TriggerMLPipeline (ml_manual_limit_monthly).
3152    #[prost(int32, tag="2")]
3153    pub remaining_this_month: i32,
3154    /// Timestamp of the last successful archetype clustering for this
3155    /// (org, group), null if never clustered.
3156    #[prost(message, optional, tag="3")]
3157    pub last_clustered_at: ::core::option::Option<::prost_types::Timestamp>,
3158}
3159// ─── Enums ──────────────────────────────────────────────────────────────────
3160
3161/// Confidence level for cohort-level predictions, based on available data volume.
3162#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3163#[repr(i32)]
3164pub enum ConfidenceLevel {
3165    Unspecified = 0,
3166    /// Fewer than 50 campaigns — predictions based on heuristics/industry benchmarks.
3167    Low = 1,
3168    /// 50-200 campaigns — basic clustering available, wide confidence intervals.
3169    Medium = 2,
3170    /// 200+ campaigns — full ML pipeline, narrow confidence intervals.
3171    High = 3,
3172}
3173impl ConfidenceLevel {
3174    /// String value of the enum field names used in the ProtoBuf definition.
3175    ///
3176    /// The values are not transformed in any way and thus are considered stable
3177    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3178    pub fn as_str_name(&self) -> &'static str {
3179        match self {
3180            Self::Unspecified => "CONFIDENCE_LEVEL_UNSPECIFIED",
3181            Self::Low => "CONFIDENCE_LEVEL_LOW",
3182            Self::Medium => "CONFIDENCE_LEVEL_MEDIUM",
3183            Self::High => "CONFIDENCE_LEVEL_HIGH",
3184        }
3185    }
3186    /// Creates an enum from field names used in the ProtoBuf definition.
3187    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3188        match value {
3189            "CONFIDENCE_LEVEL_UNSPECIFIED" => Some(Self::Unspecified),
3190            "CONFIDENCE_LEVEL_LOW" => Some(Self::Low),
3191            "CONFIDENCE_LEVEL_MEDIUM" => Some(Self::Medium),
3192            "CONFIDENCE_LEVEL_HIGH" => Some(Self::High),
3193            _ => None,
3194        }
3195    }
3196}
3197/// Pipeline state for a group's archetypes. Lets the admin UI render
3198/// distinct empty-state affordances ("run clustering" vs "need N more
3199/// sessions" vs "pipeline ran but audience was too homogeneous") instead
3200/// of treating every empty archetype list the same. Populated by
3201/// InsightsService.GetGroupArchetypes.
3202#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3203#[repr(i32)]
3204pub enum PipelineState {
3205    Unspecified = 0,
3206    /// The ML pipeline has never fired for this org. Archetypes are
3207    /// empty because nothing ran, not because of data shape.
3208    NeverRun = 1,
3209    /// The pipeline ran but the group had fewer than the k-anonymization
3210    /// minimum feature vectors (50), so clustering was skipped. UI
3211    /// renders "keep running campaigns" affordance.
3212    BelowThreshold = 2,
3213    /// The pipeline ran with enough vectors but the clustering provider
3214    /// returned zero clusters — typically means the audience is too
3215    /// homogeneous to separate into distinct archetypes.
3216    NoClusters = 3,
3217    /// Archetypes are populated and ready to render.
3218    Ready = 4,
3219}
3220impl PipelineState {
3221    /// String value of the enum field names used in the ProtoBuf definition.
3222    ///
3223    /// The values are not transformed in any way and thus are considered stable
3224    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3225    pub fn as_str_name(&self) -> &'static str {
3226        match self {
3227            Self::Unspecified => "PIPELINE_STATE_UNSPECIFIED",
3228            Self::NeverRun => "PIPELINE_STATE_NEVER_RUN",
3229            Self::BelowThreshold => "PIPELINE_STATE_BELOW_THRESHOLD",
3230            Self::NoClusters => "PIPELINE_STATE_NO_CLUSTERS",
3231            Self::Ready => "PIPELINE_STATE_READY",
3232        }
3233    }
3234    /// Creates an enum from field names used in the ProtoBuf definition.
3235    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3236        match value {
3237            "PIPELINE_STATE_UNSPECIFIED" => Some(Self::Unspecified),
3238            "PIPELINE_STATE_NEVER_RUN" => Some(Self::NeverRun),
3239            "PIPELINE_STATE_BELOW_THRESHOLD" => Some(Self::BelowThreshold),
3240            "PIPELINE_STATE_NO_CLUSTERS" => Some(Self::NoClusters),
3241            "PIPELINE_STATE_READY" => Some(Self::Ready),
3242            _ => None,
3243        }
3244    }
3245}
3246// ─── Messages ───────────────────────────────────────────────────────────────
3247
3248/// A shareable invite link that allows users to self-join an organization.
3249/// Links carry a role assignment and optional usage/expiry constraints.
3250#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3251pub struct InviteLink {
3252    /// Unique identifier for the invite link.
3253    #[prost(string, tag="1")]
3254    pub id: ::prost::alloc::string::String,
3255    /// Cryptographically random base64url-encoded token (43 characters).
3256    #[prost(string, tag="2")]
3257    pub token: ::prost::alloc::string::String,
3258    /// ID of the role assigned to users who redeem this link.
3259    #[prost(string, tag="3")]
3260    pub role_id: ::prost::alloc::string::String,
3261    /// Maximum number of times this link can be redeemed.
3262    /// 0 means unlimited.
3263    #[prost(int32, tag="4")]
3264    pub max_uses: i32,
3265    /// Number of times this link has been redeemed.
3266    #[prost(int32, tag="5")]
3267    pub use_count: i32,
3268    /// When the link expires. Empty if no expiry.
3269    #[prost(message, optional, tag="6")]
3270    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
3271    /// When the link was revoked. Empty if not revoked.
3272    #[prost(message, optional, tag="7")]
3273    pub revoked_at: ::core::option::Option<::prost_types::Timestamp>,
3274    /// ID of the admin who created the link.
3275    #[prost(string, tag="8")]
3276    pub created_by: ::prost::alloc::string::String,
3277    /// When the link was created.
3278    #[prost(message, optional, tag="9")]
3279    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3280    /// Data governance region assigned to users who redeem this link. Empty means inherit from org default.
3281    /// Valid values: EU, LATAM, BR, APAC, US.
3282    #[prost(string, tag="10")]
3283    pub data_governance_region: ::prost::alloc::string::String,
3284}
3285/// Request to create a new invite link for the organization.
3286#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3287pub struct CreateInviteLinkRequest {
3288    /// ID of the role to assign. Defaults to the organization's employee role if empty.
3289    #[prost(string, tag="1")]
3290    pub role_id: ::prost::alloc::string::String,
3291    /// Maximum number of redemptions. 0 means unlimited.
3292    #[prost(int32, tag="2")]
3293    pub max_uses: i32,
3294    /// Number of hours until the link expires. 0 means no expiry.
3295    /// Constraints: Valid range 0 to 8760 (1 year).
3296    #[prost(int32, tag="3")]
3297    pub expires_in_hours: i32,
3298    /// Optional data governance region. Users who redeem this link inherit this region. Empty means inherit from org default.
3299    /// Valid values: EU, LATAM, BR, APAC, US.
3300    #[prost(string, tag="4")]
3301    pub data_governance_region: ::prost::alloc::string::String,
3302}
3303/// Response after creating an invite link.
3304#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3305pub struct CreateInviteLinkResponse {
3306    /// The newly created invite link.
3307    #[prost(message, optional, tag="1")]
3308    pub invite_link: ::core::option::Option<InviteLink>,
3309    /// Full URL for sharing (e.g. "<https://app.pidgr.com/join?token=<TOKEN>">).
3310    #[prost(string, tag="2")]
3311    pub url: ::prost::alloc::string::String,
3312}
3313/// Request to list all invite links for the organization.
3314#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3315pub struct ListInviteLinksRequest {
3316}
3317/// Response containing all invite links for the organization.
3318#[derive(Clone, PartialEq, ::prost::Message)]
3319pub struct ListInviteLinksResponse {
3320    /// All invite links (active, expired, maxed-out, and revoked), ordered by creation date descending.
3321    #[prost(message, repeated, tag="1")]
3322    pub invite_links: ::prost::alloc::vec::Vec<InviteLink>,
3323}
3324/// Request to revoke an invite link.
3325#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3326pub struct RevokeInviteLinkRequest {
3327    /// ID of the invite link to revoke. Required.
3328    #[prost(string, tag="1")]
3329    pub invite_link_id: ::prost::alloc::string::String,
3330}
3331/// Response after revoking an invite link.
3332#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3333pub struct RevokeInviteLinkResponse {
3334}
3335/// Request to redeem an invite link (authenticated — email extracted from JWT).
3336#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3337pub struct RedeemInviteLinkRequest {
3338    /// The invite link token from the URL query parameter.
3339    #[prost(string, tag="1")]
3340    pub token: ::prost::alloc::string::String,
3341}
3342/// Response after redeeming an invite link.
3343#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3344pub struct RedeemInviteLinkResponse {
3345    /// Name of the organization the user was added to.
3346    #[prost(string, tag="1")]
3347    pub organization_name: ::prost::alloc::string::String,
3348}
3349/// Request to validate an invite link and provision a user account if needed (unauthenticated).
3350#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3351pub struct ValidateInviteLinkRequest {
3352    /// The invite link token from the URL query parameter.
3353    #[prost(string, tag="1")]
3354    pub token: ::prost::alloc::string::String,
3355    /// Email address of the user joining the organization.
3356    /// Constraints: Max length 254 characters (RFC 5321).
3357    #[prost(string, tag="2")]
3358    pub email: ::prost::alloc::string::String,
3359}
3360/// Response after validating an invite link.
3361#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3362pub struct ValidateInviteLinkResponse {
3363    /// Name of the organization the invite link belongs to.
3364    #[prost(string, tag="1")]
3365    pub organization_name: ::prost::alloc::string::String,
3366}
3367// ─── Messages ───────────────────────────────────────────────────────────────
3368
3369/// Request to invite a new user to the organization.
3370#[derive(Clone, PartialEq, ::prost::Message)]
3371pub struct InviteUserRequest {
3372    /// Email address to send the invitation to.
3373    /// Constraints: Max length 254 characters (RFC 5321).
3374    #[prost(string, tag="1")]
3375    pub email: ::prost::alloc::string::String,
3376    /// Display name for the invited user.
3377    /// Constraints: Max length 200 characters.
3378    #[prost(string, tag="2")]
3379    pub name: ::prost::alloc::string::String,
3380    /// ID of the role to assign. Defaults to the organization's employee role if empty.
3381    #[prost(string, tag="4")]
3382    pub role_id: ::prost::alloc::string::String,
3383    /// Optional profile attributes to pre-fill at invitation time.
3384    #[prost(message, optional, tag="5")]
3385    pub profile: ::core::option::Option<UserProfile>,
3386    /// Optional data governance region for the invited user. Empty means inherit from org default.
3387    /// Valid values: EU, LATAM, BR, APAC, US.
3388    #[prost(string, tag="6")]
3389    pub data_governance_region: ::prost::alloc::string::String,
3390}
3391/// Response after inviting a user.
3392#[derive(Clone, PartialEq, ::prost::Message)]
3393pub struct InviteUserResponse {
3394    /// The newly created user (status: INVITED).
3395    #[prost(message, optional, tag="1")]
3396    pub user: ::core::option::Option<User>,
3397}
3398/// Request to retrieve a user by ID.
3399#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3400pub struct GetUserRequest {
3401    /// ID of the user to retrieve.
3402    #[prost(string, tag="1")]
3403    pub user_id: ::prost::alloc::string::String,
3404}
3405/// Response containing the requested user.
3406#[derive(Clone, PartialEq, ::prost::Message)]
3407pub struct GetUserResponse {
3408    /// The requested user.
3409    #[prost(message, optional, tag="1")]
3410    pub user: ::core::option::Option<User>,
3411}
3412/// Request to list users in the organization with pagination.
3413#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3414pub struct ListUsersRequest {
3415    /// Pagination parameters.
3416    #[prost(message, optional, tag="1")]
3417    pub pagination: ::core::option::Option<Pagination>,
3418}
3419/// Response containing a page of users.
3420#[derive(Clone, PartialEq, ::prost::Message)]
3421pub struct ListUsersResponse {
3422    /// List of users in this page.
3423    #[prost(message, repeated, tag="1")]
3424    pub users: ::prost::alloc::vec::Vec<User>,
3425    /// Pagination metadata for fetching subsequent pages.
3426    #[prost(message, optional, tag="2")]
3427    pub pagination_meta: ::core::option::Option<PaginationMeta>,
3428}
3429/// Request to change a user's role within the organization.
3430#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3431pub struct UpdateUserRoleRequest {
3432    /// ID of the user whose role to update.
3433    #[prost(string, tag="1")]
3434    pub user_id: ::prost::alloc::string::String,
3435    /// ID of the new role to assign.
3436    #[prost(string, tag="2")]
3437    pub role_id: ::prost::alloc::string::String,
3438}
3439/// Response after updating a user's role.
3440#[derive(Clone, PartialEq, ::prost::Message)]
3441pub struct UpdateUserRoleResponse {
3442    /// The updated user with the new role.
3443    #[prost(message, optional, tag="1")]
3444    pub user: ::core::option::Option<User>,
3445}
3446/// Request to deactivate a user within the organization.
3447#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3448pub struct DeactivateUserRequest {
3449    /// ID of the user to deactivate.
3450    #[prost(string, tag="1")]
3451    pub user_id: ::prost::alloc::string::String,
3452}
3453/// Response after deactivating a user.
3454#[derive(Clone, PartialEq, ::prost::Message)]
3455pub struct DeactivateUserResponse {
3456    /// The deactivated user (status: DEACTIVATED).
3457    #[prost(message, optional, tag="1")]
3458    pub user: ::core::option::Option<User>,
3459}
3460/// Request to reactivate a deactivated user.
3461#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3462pub struct ReactivateUserRequest {
3463    /// ID of the user to reactivate.
3464    #[prost(string, tag="1")]
3465    pub user_id: ::prost::alloc::string::String,
3466}
3467/// Response after reactivating a user.
3468#[derive(Clone, PartialEq, ::prost::Message)]
3469pub struct ReactivateUserResponse {
3470    /// The reactivated user (status: INVITED).
3471    #[prost(message, optional, tag="1")]
3472    pub user: ::core::option::Option<User>,
3473}
3474/// Request to revoke an invitation for a user who has not yet registered.
3475#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3476pub struct RevokeInviteRequest {
3477    /// ID of the invited user to remove.
3478    /// Constraints: UUID format (36 characters).
3479    #[prost(string, tag="1")]
3480    pub user_id: ::prost::alloc::string::String,
3481}
3482/// Response after revoking an invitation. Empty on success.
3483#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3484pub struct RevokeInviteResponse {
3485}
3486/// Request to update a user's profile attributes.
3487#[derive(Clone, PartialEq, ::prost::Message)]
3488pub struct UpdateUserProfileRequest {
3489    /// ID of the user whose profile to update.
3490    /// Empty or matching the caller's own ID allows self-update without PERMISSION_MEMBERS_MANAGE.
3491    #[prost(string, tag="1")]
3492    pub user_id: ::prost::alloc::string::String,
3493    /// Profile attributes to set. All provided fields overwrite existing values.
3494    #[prost(message, optional, tag="2")]
3495    pub profile: ::core::option::Option<UserProfile>,
3496}
3497/// Response after updating a user's profile.
3498#[derive(Clone, PartialEq, ::prost::Message)]
3499pub struct UpdateUserProfileResponse {
3500    /// The updated user with the new profile.
3501    #[prost(message, optional, tag="1")]
3502    pub user: ::core::option::Option<User>,
3503}
3504/// Request to retrieve the caller's platform settings.
3505#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3506pub struct GetUserSettingsRequest {
3507}
3508/// Response containing the caller's platform settings.
3509#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3510pub struct GetUserSettingsResponse {
3511    /// Current settings. Fields at their default value indicate the platform default.
3512    #[prost(message, optional, tag="1")]
3513    pub settings: ::core::option::Option<UserSettings>,
3514}
3515/// Request to update the caller's platform settings.
3516#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3517pub struct UpdateUserSettingsRequest {
3518    /// Settings to update. Only fields with non-default (non-UNSPECIFIED) values
3519    /// are applied; default-valued fields are left unchanged.
3520    #[prost(message, optional, tag="1")]
3521    pub settings: ::core::option::Option<UserSettings>,
3522}
3523/// Response after updating the caller's platform settings.
3524#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3525pub struct UpdateUserSettingsResponse {
3526    /// The full settings after the update.
3527    #[prost(message, optional, tag="1")]
3528    pub settings: ::core::option::Option<UserSettings>,
3529}
3530/// Request to invite multiple users to the organization in a single call.
3531#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3532pub struct BulkInviteUsersRequest {
3533    /// Email addresses to invite.
3534    /// Constraints: Min 1, max 100 emails. Duplicates are deduplicated before processing.
3535    #[prost(string, repeated, tag="1")]
3536    pub emails: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3537    /// ID of the role to assign. Defaults to the organization's employee role if empty.
3538    #[prost(string, tag="2")]
3539    pub role_id: ::prost::alloc::string::String,
3540}
3541/// Per-email result within a bulk invite operation.
3542#[derive(Clone, PartialEq, ::prost::Message)]
3543pub struct BulkInviteResult {
3544    /// The email address that was processed.
3545    #[prost(string, tag="1")]
3546    pub email: ::prost::alloc::string::String,
3547    /// Whether the invitation succeeded.
3548    #[prost(bool, tag="2")]
3549    pub success: bool,
3550    /// Error message if the invitation failed (e.g. "user already exists").
3551    /// Empty on success.
3552    #[prost(string, tag="3")]
3553    pub error: ::prost::alloc::string::String,
3554    /// The created user. Only set on success.
3555    #[prost(message, optional, tag="4")]
3556    pub user: ::core::option::Option<User>,
3557}
3558/// Response after bulk inviting users.
3559#[derive(Clone, PartialEq, ::prost::Message)]
3560pub struct BulkInviteUsersResponse {
3561    /// Per-email results in the same order as the deduplicated input.
3562    #[prost(message, repeated, tag="1")]
3563    pub results: ::prost::alloc::vec::Vec<BulkInviteResult>,
3564    /// Number of users successfully invited.
3565    #[prost(int32, tag="2")]
3566    pub invited_count: i32,
3567    /// Number of emails that failed.
3568    #[prost(int32, tag="3")]
3569    pub failed_count: i32,
3570}
3571/// Request to confirm passkey enrollment after client-side WebAuthn registration.
3572/// The server verifies that the caller has at least one registered WebAuthn
3573/// credential before setting the enrollment attribute.
3574#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3575pub struct ConfirmPasskeyEnrollmentRequest {
3576}
3577/// Response after confirming passkey enrollment.
3578#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3579pub struct ConfirmPasskeyEnrollmentResponse {
3580    /// Whether enrollment was confirmed and the user attribute was updated.
3581    #[prost(bool, tag="1")]
3582    pub confirmed: bool,
3583}
3584/// Request to update a user's data governance region.
3585#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3586pub struct UpdateUserRegionRequest {
3587    /// ID of the user whose region to update. Required.
3588    #[prost(string, tag="1")]
3589    pub user_id: ::prost::alloc::string::String,
3590    /// New governance region, or empty to inherit from org default.
3591    /// Valid values: EU, LATAM, BR, APAC, US.
3592    #[prost(string, tag="2")]
3593    pub data_governance_region: ::prost::alloc::string::String,
3594}
3595/// Response after updating a user's governance region.
3596#[derive(Clone, PartialEq, ::prost::Message)]
3597pub struct UpdateUserRegionResponse {
3598    /// The updated user.
3599    #[prost(message, optional, tag="1")]
3600    pub user: ::core::option::Option<User>,
3601    /// Temporal workflow ID for the region migration, if a migration was triggered.
3602    /// Empty if the region didn't actually change.
3603    #[prost(string, tag="2")]
3604    pub migration_workflow_id: ::prost::alloc::string::String,
3605}
3606// ─── Messages ───────────────────────────────────────────────────────────────
3607
3608/// Maps an identity provider claim to a user profile field.
3609/// Used for automatic profile population when users authenticate via SSO/SAML.
3610#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3611pub struct SsoAttributeMapping {
3612    /// Claim name from the identity provider (e.g. "urn:oid:2.5.4.11", "given_name").
3613    /// Constraints: Max length 500 characters.
3614    #[prost(string, tag="1")]
3615    pub idp_claim: ::prost::alloc::string::String,
3616    /// Target UserProfile field name (e.g. "department", "first_name").
3617    /// For custom attributes, use "custom:" prefix (e.g. "custom:cost_center").
3618    /// Constraints: Max length 100 characters.
3619    #[prost(string, tag="2")]
3620    pub profile_field: ::prost::alloc::string::String,
3621}
3622/// An organization (tenant) in the Pidgr platform.
3623#[derive(Clone, PartialEq, ::prost::Message)]
3624pub struct Organization {
3625    /// Unique identifier for the organization.
3626    #[prost(string, tag="1")]
3627    pub id: ::prost::alloc::string::String,
3628    /// Organization display name.
3629    /// Constraints: Max length 200 characters.
3630    #[prost(string, tag="2")]
3631    pub name: ::prost::alloc::string::String,
3632    /// Default workflow used when campaigns don't specify one.
3633    #[prost(message, optional, tag="3")]
3634    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
3635    /// Timestamp when the organization was created.
3636    #[prost(message, optional, tag="4")]
3637    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3638    /// Industry vertical.
3639    #[prost(enumeration="Industry", tag="5")]
3640    pub industry: i32,
3641    /// Employee headcount range.
3642    #[prost(enumeration="CompanySize", tag="6")]
3643    pub company_size: i32,
3644    /// SSO identity provider claim-to-profile mappings.
3645    /// Empty when the organization does not use SSO.
3646    #[prost(message, repeated, tag="7")]
3647    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
3648    /// Default language for new users in this organization.
3649    /// Empty means no org default (users auto-detect from device/browser).
3650    /// Valid values: en, es, pt-BR, zh, ja.
3651    #[prost(string, tag="8")]
3652    pub default_locale: ::prost::alloc::string::String,
3653    /// Organization lifecycle type.
3654    #[prost(enumeration="OrgType", tag="9")]
3655    pub org_type: i32,
3656    /// Expiration time for sandbox organizations. Empty for standard orgs.
3657    #[prost(message, optional, tag="10")]
3658    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
3659    /// Data governance framework (EU, LATAM, BR, APAC, US).
3660    /// Determines legal framework, DPA template, and Bedrock endpoint routing.
3661    #[prost(string, tag="11")]
3662    pub data_governance_region: ::prost::alloc::string::String,
3663    /// AWS region for content storage (resolved from data_governance_region).
3664    /// e.g., "eu-west-1", "us-east-1".
3665    #[prost(string, tag="12")]
3666    pub data_content_region: ::prost::alloc::string::String,
3667    /// ─── ML pipeline settings ──────────────────────────────────────────────────
3668    /// Cold-start threshold: completed campaigns below this count trigger immediate
3669    /// retraining. At or above, the org is flagged for the weekly cron.
3670    /// Default 10, range 1-100.
3671    #[prost(int32, tag="13")]
3672    pub ml_retrain_cold_threshold: i32,
3673    /// Whether cancelled campaigns count toward the training counter. Default true.
3674    #[prost(bool, tag="14")]
3675    pub ml_cancelled_counts: bool,
3676    /// Monthly limit on manual retrain triggers. Default 3, range 0-10.
3677    #[prost(int32, tag="15")]
3678    pub ml_manual_limit_monthly: i32,
3679    /// Number of manual retrains used in the current month (resets monthly).
3680    #[prost(int32, tag="16")]
3681    pub ml_manual_retrains_used: i32,
3682    /// Whether the org is flagged for the next weekly cron run.
3683    #[prost(bool, tag="17")]
3684    pub ml_needs_retrain: bool,
3685    /// Campaigns completed since the last ML training run.
3686    #[prost(int32, tag="18")]
3687    pub campaigns_since_last_training: i32,
3688    /// Total campaigns completed across the organization lifetime.
3689    #[prost(int32, tag="19")]
3690    pub total_completed_campaigns: i32,
3691    /// Timestamp of the most recent successful ML training. Empty if never trained.
3692    #[prost(message, optional, tag="20")]
3693    pub last_ml_training_at: ::core::option::Option<::prost_types::Timestamp>,
3694}
3695/// Request to create a new organization.
3696/// JWT auth only — the authenticated caller becomes the initial admin. Additional
3697/// admins are added via CreateInviteLink after the org exists.
3698#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3699pub struct CreateOrganizationRequest {
3700    /// Name for the new organization.
3701    /// Constraints: Max length 200 characters.
3702    #[prost(string, tag="1")]
3703    pub name: ::prost::alloc::string::String,
3704    /// Industry vertical for the organization.
3705    #[prost(enumeration="Industry", tag="2")]
3706    pub industry: i32,
3707    /// Employee headcount range.
3708    #[prost(enumeration="CompanySize", tag="3")]
3709    pub company_size: i32,
3710    /// Access code required during early access.
3711    /// Format: PIDGR-XXXXXXXX (8 alphanumeric characters).
3712    #[prost(string, tag="4")]
3713    pub access_code: ::prost::alloc::string::String,
3714    /// Data governance framework. Defaults to "US" if omitted.
3715    /// Valid values: EU, LATAM, BR, APAC, US.
3716    #[prost(string, tag="5")]
3717    pub data_governance_region: ::prost::alloc::string::String,
3718}
3719/// Response after creating an organization.
3720#[derive(Clone, PartialEq, ::prost::Message)]
3721pub struct CreateOrganizationResponse {
3722    /// The newly created organization.
3723    #[prost(message, optional, tag="1")]
3724    pub organization: ::core::option::Option<Organization>,
3725    /// The admin user created for the organization.
3726    #[prost(message, optional, tag="2")]
3727    pub admin_user: ::core::option::Option<User>,
3728}
3729/// Request to retrieve the organization for the authenticated user.
3730#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3731pub struct GetOrganizationRequest {
3732}
3733/// Response containing the organization.
3734#[derive(Clone, PartialEq, ::prost::Message)]
3735pub struct GetOrganizationResponse {
3736    /// The organization the authenticated user belongs to.
3737    #[prost(message, optional, tag="1")]
3738    pub organization: ::core::option::Option<Organization>,
3739}
3740/// Request to update organization settings.
3741#[derive(Clone, PartialEq, ::prost::Message)]
3742pub struct UpdateOrganizationRequest {
3743    /// New organization name. Empty string leaves unchanged.
3744    /// Constraints: Max length 200 characters.
3745    #[prost(string, tag="1")]
3746    pub name: ::prost::alloc::string::String,
3747    /// New default workflow definition. Null leaves unchanged.
3748    #[prost(message, optional, tag="2")]
3749    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
3750    /// New industry vertical. UNSPECIFIED leaves unchanged.
3751    #[prost(enumeration="Industry", tag="3")]
3752    pub industry: i32,
3753    /// New employee headcount range. UNSPECIFIED leaves unchanged.
3754    #[prost(enumeration="CompanySize", tag="4")]
3755    pub company_size: i32,
3756    /// New default language for new users. Empty string leaves unchanged.
3757    /// Valid values: en, es, pt-BR, zh, ja.
3758    #[prost(string, tag="5")]
3759    pub default_locale: ::prost::alloc::string::String,
3760    /// New ML cold-start threshold. 0 leaves unchanged, otherwise must be in \[1, 100\].
3761    #[prost(int32, tag="6")]
3762    pub ml_retrain_cold_threshold: i32,
3763    /// New ML cancelled-counts flag. Uses google.protobuf.BoolValue-style semantics
3764    /// via optional to distinguish "not provided" from "set to false".
3765    #[prost(bool, optional, tag="7")]
3766    pub ml_cancelled_counts: ::core::option::Option<bool>,
3767    /// New ML monthly manual limit. Negative leaves unchanged, otherwise must be in \[0, 10\].
3768    /// Encoded as int32 with -1 meaning "leave unchanged".
3769    #[prost(int32, tag="8")]
3770    pub ml_manual_limit_monthly: i32,
3771}
3772/// Response after updating the organization.
3773#[derive(Clone, PartialEq, ::prost::Message)]
3774pub struct UpdateOrganizationResponse {
3775    /// The updated organization.
3776    #[prost(message, optional, tag="1")]
3777    pub organization: ::core::option::Option<Organization>,
3778}
3779/// Request to replace all SSO attribute mappings for the organization.
3780#[derive(Clone, PartialEq, ::prost::Message)]
3781pub struct UpdateSsoAttributeMappingsRequest {
3782    /// Complete list of SSO mappings (replaces all existing mappings).
3783    #[prost(message, repeated, tag="1")]
3784    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
3785}
3786/// Response after updating SSO attribute mappings.
3787#[derive(Clone, PartialEq, ::prost::Message)]
3788pub struct UpdateSsoAttributeMappingsResponse {
3789    /// The updated organization with the new SSO mappings.
3790    #[prost(message, optional, tag="1")]
3791    pub organization: ::core::option::Option<Organization>,
3792}
3793/// Request to rotate the analytics salt and optionally increase the bucket count.
3794#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3795pub struct RotateAnalyticsSaltRequest {
3796    /// New bucket count. Must be >= current bucket count. 0 means keep current.
3797    #[prost(int32, tag="1")]
3798    pub new_bucket_count: i32,
3799}
3800/// Response after rotating the analytics salt.
3801#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3802pub struct RotateAnalyticsSaltResponse {
3803    /// The new bucket count after rotation.
3804    #[prost(int32, tag="1")]
3805    pub bucket_count: i32,
3806}
3807/// Request to update the analytics epsilon (differential privacy parameter).
3808#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3809pub struct UpdateAnalyticsEpsilonRequest {
3810    /// New epsilon value. Must be in range \[0.5, 5.0\].
3811    #[prost(float, tag="1")]
3812    pub epsilon: f32,
3813}
3814/// Response after updating the analytics epsilon.
3815#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3816pub struct UpdateAnalyticsEpsilonResponse {
3817    /// The new epsilon value.
3818    #[prost(float, tag="1")]
3819    pub epsilon: f32,
3820}
3821/// Request to create a sandbox organization for testing.
3822#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3823pub struct CreateSandboxOrganizationRequest {
3824    /// Name for the sandbox organization.
3825    /// Constraints: Max length 200 characters.
3826    #[prost(string, tag="1")]
3827    pub name: ::prost::alloc::string::String,
3828    /// Required expiration time. Max 30 days from now for interactive callers;
3829    /// API-key callers may set shorter TTLs for ephemeral test sandboxes.
3830    #[prost(message, optional, tag="2")]
3831    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
3832    /// Data governance framework. Defaults to "US" if omitted.
3833    /// Valid values: EU, LATAM, BR, APAC, US.
3834    #[prost(string, tag="3")]
3835    pub data_governance_region: ::prost::alloc::string::String,
3836    /// Optional fixture to seed the sandbox with sample data (templates,
3837    /// workflows, historical campaigns). Empty string means no seeding.
3838    /// Must match an id returned by ListSandboxFixtures.
3839    #[prost(string, tag="4")]
3840    pub fixture_id: ::prost::alloc::string::String,
3841}
3842/// Response after creating a sandbox organization.
3843#[derive(Clone, PartialEq, ::prost::Message)]
3844pub struct CreateSandboxOrganizationResponse {
3845    /// The newly created sandbox organization (org_type: SANDBOX).
3846    #[prost(message, optional, tag="1")]
3847    pub organization: ::core::option::Option<Organization>,
3848    /// The admin user created for the sandbox.
3849    #[prost(message, optional, tag="2")]
3850    pub admin_user: ::core::option::Option<User>,
3851}
3852/// Request to delete a sandbox organization. Only callable for orgs with
3853/// org_type=SANDBOX. Allowed for super admins of the sandbox or the creator.
3854#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3855pub struct DeleteSandboxOrganizationRequest {
3856    /// ID of the sandbox organization to delete.
3857    #[prost(string, tag="1")]
3858    pub org_id: ::prost::alloc::string::String,
3859}
3860/// Response after requesting deletion. Deletion runs asynchronously via
3861/// the DeleteOrgWorkflow; a success response means the workflow started.
3862#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3863pub struct DeleteSandboxOrganizationResponse {
3864    /// ID of the Temporal workflow handling the deletion.
3865    #[prost(string, tag="1")]
3866    pub workflow_id: ::prost::alloc::string::String,
3867}
3868/// A seed fixture that can be applied when creating a sandbox organization.
3869#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3870pub struct SandboxFixture {
3871    /// Stable UUID for referencing this fixture.
3872    #[prost(string, tag="1")]
3873    pub id: ::prost::alloc::string::String,
3874    /// Display name for admin UI (e.g. "Sample data").
3875    #[prost(string, tag="2")]
3876    pub name: ::prost::alloc::string::String,
3877    /// Description shown alongside the fixture option in the UI.
3878    #[prost(string, tag="3")]
3879    pub description: ::prost::alloc::string::String,
3880    /// Exactly one fixture has is_default=true. Clients that show a simple
3881    /// "fill with sample data" checkbox send this fixture's id when checked.
3882    #[prost(bool, tag="4")]
3883    pub is_default: bool,
3884}
3885/// Request to list all sandbox fixtures available for seeding.
3886/// No parameters — catalog is the same for all callers.
3887#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3888pub struct ListSandboxFixturesRequest {
3889}
3890/// Response containing the sandbox fixture catalog.
3891#[derive(Clone, PartialEq, ::prost::Message)]
3892pub struct ListSandboxFixturesResponse {
3893    /// All registered fixtures, ordered by name.
3894    #[prost(message, repeated, tag="1")]
3895    pub fixtures: ::prost::alloc::vec::Vec<SandboxFixture>,
3896}
3897/// Request to list all organizations the authenticated user belongs to.
3898/// No parameters — user identity is extracted from the JWT sub claim.
3899#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3900pub struct ListUserOrganizationsRequest {
3901}
3902/// Response containing all organizations the authenticated user belongs to.
3903#[derive(Clone, PartialEq, ::prost::Message)]
3904pub struct ListUserOrganizationsResponse {
3905    /// Organizations the user belongs to, ordered by created_at ascending.
3906    /// Excludes expired sandbox organizations.
3907    #[prost(message, repeated, tag="1")]
3908    pub organizations: ::prost::alloc::vec::Vec<Organization>,
3909}
3910/// Request to list only the sandbox organizations the authenticated user
3911/// belongs to (i.e. orgs where org_type = SANDBOX, filtered from the full
3912/// membership set). No parameters — user identity is extracted from the JWT
3913/// sub claim.
3914#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3915pub struct ListUserSandboxesRequest {
3916}
3917/// Response containing the user's sandbox organizations.
3918#[derive(Clone, PartialEq, ::prost::Message)]
3919pub struct ListUserSandboxesResponse {
3920    /// Sandbox organizations the user belongs to, ordered by expires_at
3921    /// ascending (soonest-expiring first — matches the admin UI
3922    /// /organization/sandboxes ordering). Excludes already-expired sandboxes
3923    /// (those are pending cleanup by SandboxCleanupWorkflow).
3924    #[prost(message, repeated, tag="1")]
3925    pub sandboxes: ::prost::alloc::vec::Vec<Organization>,
3926}
3927// ─── Enums ───────────────────────────────────────────────────────────────────
3928
3929/// Industry vertical for an organization.
3930#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3931#[repr(i32)]
3932pub enum Industry {
3933    Unspecified = 0,
3934    Technology = 1,
3935    Finance = 2,
3936    Healthcare = 3,
3937    Education = 4,
3938    Retail = 5,
3939    Manufacturing = 6,
3940    Media = 7,
3941    Other = 8,
3942}
3943impl Industry {
3944    /// String value of the enum field names used in the ProtoBuf definition.
3945    ///
3946    /// The values are not transformed in any way and thus are considered stable
3947    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3948    pub fn as_str_name(&self) -> &'static str {
3949        match self {
3950            Self::Unspecified => "INDUSTRY_UNSPECIFIED",
3951            Self::Technology => "INDUSTRY_TECHNOLOGY",
3952            Self::Finance => "INDUSTRY_FINANCE",
3953            Self::Healthcare => "INDUSTRY_HEALTHCARE",
3954            Self::Education => "INDUSTRY_EDUCATION",
3955            Self::Retail => "INDUSTRY_RETAIL",
3956            Self::Manufacturing => "INDUSTRY_MANUFACTURING",
3957            Self::Media => "INDUSTRY_MEDIA",
3958            Self::Other => "INDUSTRY_OTHER",
3959        }
3960    }
3961    /// Creates an enum from field names used in the ProtoBuf definition.
3962    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3963        match value {
3964            "INDUSTRY_UNSPECIFIED" => Some(Self::Unspecified),
3965            "INDUSTRY_TECHNOLOGY" => Some(Self::Technology),
3966            "INDUSTRY_FINANCE" => Some(Self::Finance),
3967            "INDUSTRY_HEALTHCARE" => Some(Self::Healthcare),
3968            "INDUSTRY_EDUCATION" => Some(Self::Education),
3969            "INDUSTRY_RETAIL" => Some(Self::Retail),
3970            "INDUSTRY_MANUFACTURING" => Some(Self::Manufacturing),
3971            "INDUSTRY_MEDIA" => Some(Self::Media),
3972            "INDUSTRY_OTHER" => Some(Self::Other),
3973            _ => None,
3974        }
3975    }
3976}
3977/// Employee headcount range for an organization.
3978#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3979#[repr(i32)]
3980pub enum CompanySize {
3981    Unspecified = 0,
3982    CompanySize1200 = 1,
3983    CompanySize200500 = 2,
3984    CompanySize5001000 = 3,
3985    CompanySize10005000 = 4,
3986    CompanySize5000Plus = 5,
3987}
3988impl CompanySize {
3989    /// String value of the enum field names used in the ProtoBuf definition.
3990    ///
3991    /// The values are not transformed in any way and thus are considered stable
3992    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3993    pub fn as_str_name(&self) -> &'static str {
3994        match self {
3995            Self::Unspecified => "COMPANY_SIZE_UNSPECIFIED",
3996            Self::CompanySize1200 => "COMPANY_SIZE_1_200",
3997            Self::CompanySize200500 => "COMPANY_SIZE_200_500",
3998            Self::CompanySize5001000 => "COMPANY_SIZE_500_1000",
3999            Self::CompanySize10005000 => "COMPANY_SIZE_1000_5000",
4000            Self::CompanySize5000Plus => "COMPANY_SIZE_5000_PLUS",
4001        }
4002    }
4003    /// Creates an enum from field names used in the ProtoBuf definition.
4004    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4005        match value {
4006            "COMPANY_SIZE_UNSPECIFIED" => Some(Self::Unspecified),
4007            "COMPANY_SIZE_1_200" => Some(Self::CompanySize1200),
4008            "COMPANY_SIZE_200_500" => Some(Self::CompanySize200500),
4009            "COMPANY_SIZE_500_1000" => Some(Self::CompanySize5001000),
4010            "COMPANY_SIZE_1000_5000" => Some(Self::CompanySize10005000),
4011            "COMPANY_SIZE_5000_PLUS" => Some(Self::CompanySize5000Plus),
4012            _ => None,
4013        }
4014    }
4015}
4016/// Classification of an organization's lifecycle type.
4017#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4018#[repr(i32)]
4019pub enum OrgType {
4020    Unspecified = 0,
4021    Standard = 1,
4022    Sandbox = 2,
4023    /// Reserved for platform operations. At most one per deployment, seeded
4024    /// by migration. Cannot be created via CreateOrganization.
4025    Staff = 3,
4026}
4027impl OrgType {
4028    /// String value of the enum field names used in the ProtoBuf definition.
4029    ///
4030    /// The values are not transformed in any way and thus are considered stable
4031    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4032    pub fn as_str_name(&self) -> &'static str {
4033        match self {
4034            Self::Unspecified => "ORG_TYPE_UNSPECIFIED",
4035            Self::Standard => "ORG_TYPE_STANDARD",
4036            Self::Sandbox => "ORG_TYPE_SANDBOX",
4037            Self::Staff => "ORG_TYPE_STAFF",
4038        }
4039    }
4040    /// Creates an enum from field names used in the ProtoBuf definition.
4041    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4042        match value {
4043            "ORG_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
4044            "ORG_TYPE_STANDARD" => Some(Self::Standard),
4045            "ORG_TYPE_SANDBOX" => Some(Self::Sandbox),
4046            "ORG_TYPE_STAFF" => Some(Self::Staff),
4047            _ => None,
4048        }
4049    }
4050}
4051// ─── Messages ───────────────────────────────────────────────────────────────
4052
4053/// Per-user rendering context containing variable substitutions.
4054#[derive(Clone, PartialEq, ::prost::Message)]
4055pub struct UserRenderContext {
4056    /// ID of the user being rendered for.
4057    #[prost(string, tag="1")]
4058    pub user_id: ::prost::alloc::string::String,
4059    /// Variable name-value pairs to substitute into the template.
4060    /// Constraints: Max 100 entries. Key max length 100 characters, value max length 10000 characters.
4061    #[prost(map="string, string", tag="2")]
4062    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
4063}
4064/// Request to render a template for a batch of users.
4065#[derive(Clone, PartialEq, ::prost::Message)]
4066pub struct RenderBatchRequest {
4067    /// ID of the template to render.
4068    #[prost(string, tag="1")]
4069    pub template_id: ::prost::alloc::string::String,
4070    /// Version of the template to render.
4071    #[prost(int32, tag="2")]
4072    pub version: i32,
4073    /// Per-user rendering contexts with variable substitutions.
4074    /// Constraints: Max 10000 users per batch.
4075    #[prost(message, repeated, tag="3")]
4076    pub users: ::prost::alloc::vec::Vec<UserRenderContext>,
4077}
4078/// Streamed response for each user's rendered message.
4079/// One response is emitted per user in the batch.
4080#[derive(Clone, PartialEq, ::prost::Message)]
4081pub struct RenderBatchResponse {
4082    /// ID of the user this result is for.
4083    #[prost(string, tag="1")]
4084    pub user_id: ::prost::alloc::string::String,
4085    /// The rendered message (set on success).
4086    #[prost(message, optional, tag="2")]
4087    pub message: ::core::option::Option<Message>,
4088    /// Error message if rendering failed for this user (empty on success).
4089    #[prost(string, tag="3")]
4090    pub error: ::prost::alloc::string::String,
4091}
4092// ─── Messages ───────────────────────────────────────────────────────────────
4093
4094/// A session recording summary from the analytics provider.
4095/// Anonymous: no user identifiers are included.
4096#[derive(Clone, PartialEq, ::prost::Message)]
4097pub struct SessionRecording {
4098    /// Recording ID from the analytics provider.
4099    #[prost(string, tag="1")]
4100    pub id: ::prost::alloc::string::String,
4101    /// Timestamp when the recording started.
4102    #[prost(message, optional, tag="2")]
4103    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
4104    /// Timestamp when the recording ended.
4105    #[prost(message, optional, tag="3")]
4106    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
4107    /// Duration of the recording in seconds.
4108    #[prost(int32, tag="4")]
4109    pub duration_seconds: i32,
4110    /// Activity score (0.0–1.0).
4111    #[prost(float, tag="5")]
4112    pub activity_score: f32,
4113}
4114/// Request to list session recordings.
4115#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4116pub struct ListSessionRecordingsRequest {
4117    /// Optional: filter recordings by campaign ID (mapped to analytics property filter).
4118    /// Constraints: UUID format (36 characters).
4119    #[prost(string, tag="1")]
4120    pub campaign_id: ::prost::alloc::string::String,
4121    /// Optional: start of the time range filter (inclusive).
4122    #[prost(message, optional, tag="2")]
4123    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
4124    /// Optional: end of the time range filter (inclusive).
4125    #[prost(message, optional, tag="3")]
4126    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
4127    /// Pagination parameters.
4128    #[prost(message, optional, tag="4")]
4129    pub pagination: ::core::option::Option<Pagination>,
4130}
4131/// Response containing a page of session recordings.
4132#[derive(Clone, PartialEq, ::prost::Message)]
4133pub struct ListSessionRecordingsResponse {
4134    /// List of session recordings in this page.
4135    #[prost(message, repeated, tag="1")]
4136    pub recordings: ::prost::alloc::vec::Vec<SessionRecording>,
4137    /// Pagination metadata for fetching subsequent pages.
4138    #[prost(message, optional, tag="2")]
4139    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4140}
4141/// Request to fetch rrweb snapshot events for a recording.
4142#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4143pub struct GetSessionSnapshotsRequest {
4144    /// Recording ID from the analytics provider.
4145    /// Constraints: Max length 200 characters.
4146    #[prost(string, tag="1")]
4147    pub recording_id: ::prost::alloc::string::String,
4148}
4149/// Response containing rrweb snapshot events.
4150#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4151pub struct GetSessionSnapshotsResponse {
4152    /// JSON-encoded array of rrweb eventWithTime objects.
4153    /// Clients parse this JSON to feed into rrweb-player.
4154    #[prost(string, tag="1")]
4155    pub snapshot_data: ::prost::alloc::string::String,
4156}
4157// ─── Messages ───────────────────────────────────────────────────────────────
4158
4159/// Request to list all roles in the caller's organization.
4160#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4161pub struct ListRolesRequest {
4162}
4163/// Response containing the organization's roles.
4164#[derive(Clone, PartialEq, ::prost::Message)]
4165pub struct ListRolesResponse {
4166    /// All roles in the organization, including their permission sets.
4167    #[prost(message, repeated, tag="1")]
4168    pub roles: ::prost::alloc::vec::Vec<Role>,
4169}
4170/// Request to create a new role in the caller's organization.
4171#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4172pub struct CreateRoleRequest {
4173    /// Display name for the role (e.g. "Team Lead"). Required.
4174    /// A slug is auto-generated from the name.
4175    #[prost(string, tag="1")]
4176    pub name: ::prost::alloc::string::String,
4177    /// Initial permission set for the role.
4178    /// PERMISSION_UNSPECIFIED values are rejected.
4179    #[prost(enumeration="Permission", repeated, tag="2")]
4180    pub permissions: ::prost::alloc::vec::Vec<i32>,
4181}
4182/// Response after creating a role.
4183#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4184pub struct CreateRoleResponse {
4185    /// The newly created role with its generated slug and permission set.
4186    #[prost(message, optional, tag="1")]
4187    pub role: ::core::option::Option<Role>,
4188}
4189/// Request to update a role's name and/or permissions.
4190#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4191pub struct UpdateRoleRequest {
4192    /// ID of the role to update. Required.
4193    #[prost(string, tag="1")]
4194    pub role_id: ::prost::alloc::string::String,
4195    /// New display name. If empty, the name is not changed.
4196    #[prost(string, tag="2")]
4197    pub name: ::prost::alloc::string::String,
4198    /// New permission set (replaces existing permissions entirely).
4199    /// If empty, permissions are not changed.
4200    /// PERMISSION_UNSPECIFIED values are rejected.
4201    #[prost(enumeration="Permission", repeated, tag="3")]
4202    pub permissions: ::prost::alloc::vec::Vec<i32>,
4203}
4204/// Response after updating a role.
4205#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4206pub struct UpdateRoleResponse {
4207    /// The updated role.
4208    #[prost(message, optional, tag="1")]
4209    pub role: ::core::option::Option<Role>,
4210}
4211/// Request to delete a role.
4212#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4213pub struct DeleteRoleRequest {
4214    /// ID of the role to delete. Required.
4215    #[prost(string, tag="1")]
4216    pub role_id: ::prost::alloc::string::String,
4217}
4218/// Response after deleting a role.
4219#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4220pub struct DeleteRoleResponse {
4221}
4222// ─── Messages ───────────────────────────────────────────────────────────────
4223
4224/// Custom SAML attribute name overrides for identity providers that use
4225/// non-standard attribute names. When provided, these override the
4226/// auto-detected values from the metadata URL host.
4227#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4228pub struct SamlAttributeNames {
4229    /// SAML attribute name for the user's email address.
4230    #[prost(string, tag="1")]
4231    pub email: ::prost::alloc::string::String,
4232    /// SAML attribute name for the user's first name.
4233    #[prost(string, tag="2")]
4234    pub given_name: ::prost::alloc::string::String,
4235    /// SAML attribute name for the user's last name.
4236    #[prost(string, tag="3")]
4237    pub family_name: ::prost::alloc::string::String,
4238}
4239/// An SSO identity provider configured for an organization.
4240#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4241pub struct SsoProvider {
4242    /// Unique identifier for the provider.
4243    #[prost(string, tag="1")]
4244    pub id: ::prost::alloc::string::String,
4245    /// Email domain that triggers this SSO provider (e.g. "acme.com").
4246    /// Constraints: Max length 253 characters (RFC 1035).
4247    #[prost(string, tag="2")]
4248    pub domain: ::prost::alloc::string::String,
4249    /// Type of identity provider.
4250    #[prost(enumeration="SsoProviderType", tag="3")]
4251    pub r#type: i32,
4252    /// SAML metadata URL or OIDC discovery URL.
4253    /// Constraints: Max length 2048 characters. HTTPS required.
4254    #[prost(string, tag="4")]
4255    pub metadata_url: ::prost::alloc::string::String,
4256    /// Name of the identity provider (used for signInWithRedirect).
4257    /// Set by the API when the IdP is created.
4258    #[prost(string, tag="5")]
4259    pub idp_provider_name: ::prost::alloc::string::String,
4260    /// Timestamp when the provider was created.
4261    #[prost(message, optional, tag="6")]
4262    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4263    /// Timestamp when the provider was last updated.
4264    #[prost(message, optional, tag="7")]
4265    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4266    /// Optional custom SAML attribute name overrides.
4267    #[prost(message, optional, tag="8")]
4268    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
4269}
4270/// Request to check if an email domain has SSO configured.
4271/// This RPC is pre-authentication — no JWT required.
4272#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4273pub struct CheckSsoByDomainRequest {
4274    /// Email address to check. The domain part is extracted.
4275    /// Constraints: Max length 254 characters (RFC 5321).
4276    #[prost(string, tag="1")]
4277    pub email: ::prost::alloc::string::String,
4278}
4279/// Response for SSO domain check.
4280#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4281pub struct CheckSsoByDomainResponse {
4282    /// Whether SSO is enabled for the email's domain.
4283    #[prost(bool, tag="1")]
4284    pub sso_enabled: bool,
4285    /// Identity provider name for signInWithRedirect.
4286    /// Empty if sso_enabled is false.
4287    #[prost(string, tag="2")]
4288    pub provider_name: ::prost::alloc::string::String,
4289}
4290/// Request to create an SSO provider for the organization.
4291#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4292pub struct CreateSsoProviderRequest {
4293    /// Email domain to associate (e.g. "acme.com").
4294    /// Constraints: Max length 253 characters (RFC 1035).
4295    #[prost(string, tag="1")]
4296    pub domain: ::prost::alloc::string::String,
4297    /// Type of identity provider.
4298    #[prost(enumeration="SsoProviderType", tag="2")]
4299    pub r#type: i32,
4300    /// SAML metadata URL or OIDC discovery URL.
4301    /// Constraints: Max length 2048 characters. HTTPS required.
4302    #[prost(string, tag="3")]
4303    pub metadata_url: ::prost::alloc::string::String,
4304    /// Optional custom SAML attribute name overrides.
4305    /// When omitted, attribute names are auto-detected from the metadata URL.
4306    #[prost(message, optional, tag="4")]
4307    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
4308}
4309/// Response after creating an SSO provider.
4310#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4311pub struct CreateSsoProviderResponse {
4312    /// The newly created SSO provider.
4313    #[prost(message, optional, tag="1")]
4314    pub provider: ::core::option::Option<SsoProvider>,
4315}
4316/// Request to get the SSO provider for the organization.
4317/// Returns the provider if one is configured, or empty if not.
4318#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4319pub struct GetSsoProviderRequest {
4320}
4321/// Response containing the organization's SSO provider.
4322#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4323pub struct GetSsoProviderResponse {
4324    /// The organization's SSO provider, or null if not configured.
4325    #[prost(message, optional, tag="1")]
4326    pub provider: ::core::option::Option<SsoProvider>,
4327}
4328/// Request to delete the organization's SSO provider.
4329#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4330pub struct DeleteSsoProviderRequest {
4331    /// ID of the provider to delete.
4332    #[prost(string, tag="1")]
4333    pub provider_id: ::prost::alloc::string::String,
4334}
4335/// Response after deleting an SSO provider.
4336#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4337pub struct DeleteSsoProviderResponse {
4338}
4339// ─── Enums ──────────────────────────────────────────────────────────────────
4340
4341/// Type of SSO identity provider.
4342#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4343#[repr(i32)]
4344pub enum SsoProviderType {
4345    /// Default value; not a valid type.
4346    Unspecified = 0,
4347    /// SAML 2.0 identity provider (e.g. Okta, Azure AD).
4348    Saml = 1,
4349    /// OpenID Connect identity provider (e.g. Google Workspace, Auth0).
4350    Oidc = 2,
4351}
4352impl SsoProviderType {
4353    /// String value of the enum field names used in the ProtoBuf definition.
4354    ///
4355    /// The values are not transformed in any way and thus are considered stable
4356    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4357    pub fn as_str_name(&self) -> &'static str {
4358        match self {
4359            Self::Unspecified => "SSO_PROVIDER_TYPE_UNSPECIFIED",
4360            Self::Saml => "SSO_PROVIDER_TYPE_SAML",
4361            Self::Oidc => "SSO_PROVIDER_TYPE_OIDC",
4362        }
4363    }
4364    /// Creates an enum from field names used in the ProtoBuf definition.
4365    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4366        match value {
4367            "SSO_PROVIDER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
4368            "SSO_PROVIDER_TYPE_SAML" => Some(Self::Saml),
4369            "SSO_PROVIDER_TYPE_OIDC" => Some(Self::Oidc),
4370            _ => None,
4371        }
4372    }
4373}
4374// ─── Messages ───────────────────────────────────────────────────────────────
4375
4376/// An organizational unit within an organization (e.g. department, division).
4377/// Teams represent the organizational structure and can serve as sender identity
4378/// in campaigns.
4379#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4380pub struct Team {
4381    /// Unique identifier for the team.
4382    #[prost(string, tag="1")]
4383    pub id: ::prost::alloc::string::String,
4384    /// Human-readable display name (unique within the organization).
4385    /// Constraints: Max length 200 characters.
4386    #[prost(string, tag="2")]
4387    pub name: ::prost::alloc::string::String,
4388    /// Optional description of the team's purpose.
4389    /// Constraints: Max length 1000 characters.
4390    #[prost(string, tag="3")]
4391    pub description: ::prost::alloc::string::String,
4392    /// Number of users currently in the team.
4393    #[prost(int32, tag="4")]
4394    pub member_count: i32,
4395    /// Timestamp when the team was created.
4396    #[prost(message, optional, tag="5")]
4397    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4398    /// Timestamp when the team was last updated.
4399    #[prost(message, optional, tag="6")]
4400    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4401    /// Whether this is the organization's default team (cannot be deleted or renamed).
4402    #[prost(bool, tag="7")]
4403    pub is_default: bool,
4404    /// ID of the user who created this team. Empty for system-seeded defaults.
4405    #[prost(string, tag="8")]
4406    pub created_by: ::prost::alloc::string::String,
4407}
4408/// Request to create a new team.
4409#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4410pub struct CreateTeamRequest {
4411    /// Display name for the team. Required.
4412    /// Constraints: Max length 200 characters.
4413    #[prost(string, tag="1")]
4414    pub name: ::prost::alloc::string::String,
4415    /// Optional description.
4416    /// Constraints: Max length 1000 characters.
4417    #[prost(string, tag="2")]
4418    pub description: ::prost::alloc::string::String,
4419}
4420/// Response after creating a team.
4421#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4422pub struct CreateTeamResponse {
4423    /// The newly created team.
4424    #[prost(message, optional, tag="1")]
4425    pub team: ::core::option::Option<Team>,
4426}
4427/// Request to retrieve a team by ID.
4428#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4429pub struct GetTeamRequest {
4430    /// ID of the team to retrieve. Required.
4431    #[prost(string, tag="1")]
4432    pub team_id: ::prost::alloc::string::String,
4433}
4434/// Response containing the requested team.
4435#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4436pub struct GetTeamResponse {
4437    /// The requested team.
4438    #[prost(message, optional, tag="1")]
4439    pub team: ::core::option::Option<Team>,
4440}
4441/// Request to list teams in the organization with pagination.
4442#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4443pub struct ListTeamsRequest {
4444    /// Pagination parameters.
4445    #[prost(message, optional, tag="1")]
4446    pub pagination: ::core::option::Option<Pagination>,
4447}
4448/// Response containing a page of teams.
4449#[derive(Clone, PartialEq, ::prost::Message)]
4450pub struct ListTeamsResponse {
4451    /// Teams in this page.
4452    #[prost(message, repeated, tag="1")]
4453    pub teams: ::prost::alloc::vec::Vec<Team>,
4454    /// Pagination metadata for fetching subsequent pages.
4455    #[prost(message, optional, tag="2")]
4456    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4457}
4458/// Request to update a team's name and/or description.
4459#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4460pub struct UpdateTeamRequest {
4461    /// ID of the team to update. Required.
4462    #[prost(string, tag="1")]
4463    pub team_id: ::prost::alloc::string::String,
4464    /// New display name. If empty, the name is not changed.
4465    /// Default teams cannot be renamed.
4466    /// Constraints: Max length 200 characters.
4467    #[prost(string, tag="2")]
4468    pub name: ::prost::alloc::string::String,
4469    /// New description. If empty, the description is not changed.
4470    /// Constraints: Max length 1000 characters.
4471    #[prost(string, tag="3")]
4472    pub description: ::prost::alloc::string::String,
4473}
4474/// Response after updating a team.
4475#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4476pub struct UpdateTeamResponse {
4477    /// The updated team.
4478    #[prost(message, optional, tag="1")]
4479    pub team: ::core::option::Option<Team>,
4480}
4481/// Request to delete a team.
4482#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4483pub struct DeleteTeamRequest {
4484    /// ID of the team to delete. Required.
4485    /// Default teams cannot be deleted.
4486    #[prost(string, tag="1")]
4487    pub team_id: ::prost::alloc::string::String,
4488}
4489/// Response after deleting a team.
4490#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4491pub struct DeleteTeamResponse {
4492}
4493/// Request to add users to a team.
4494#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4495pub struct AddTeamMembersRequest {
4496    /// ID of the team to add members to. Required.
4497    #[prost(string, tag="1")]
4498    pub team_id: ::prost::alloc::string::String,
4499    /// IDs of users to add. Must belong to the same organization.
4500    /// Adding an existing member is a no-op (idempotent).
4501    /// Constraints: Max 100 user IDs per request.
4502    #[prost(string, repeated, tag="2")]
4503    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4504}
4505/// Response after adding team members.
4506#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4507pub struct AddTeamMembersResponse {
4508    /// The team with updated member_count.
4509    #[prost(message, optional, tag="1")]
4510    pub team: ::core::option::Option<Team>,
4511}
4512/// Request to remove users from a team.
4513#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4514pub struct RemoveTeamMembersRequest {
4515    /// ID of the team to remove members from. Required.
4516    #[prost(string, tag="1")]
4517    pub team_id: ::prost::alloc::string::String,
4518    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
4519    /// Constraints: Max 100 user IDs per request.
4520    #[prost(string, repeated, tag="2")]
4521    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4522}
4523/// Response after removing team members.
4524#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4525pub struct RemoveTeamMembersResponse {
4526    /// The team with updated member_count.
4527    #[prost(message, optional, tag="1")]
4528    pub team: ::core::option::Option<Team>,
4529}
4530/// Request to list members of a team with pagination.
4531#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4532pub struct ListTeamMembersRequest {
4533    /// ID of the team whose members to list. Required.
4534    #[prost(string, tag="1")]
4535    pub team_id: ::prost::alloc::string::String,
4536    /// Pagination parameters.
4537    #[prost(message, optional, tag="2")]
4538    pub pagination: ::core::option::Option<Pagination>,
4539}
4540/// Response containing a page of team members.
4541#[derive(Clone, PartialEq, ::prost::Message)]
4542pub struct ListTeamMembersResponse {
4543    /// Users in this page.
4544    #[prost(message, repeated, tag="1")]
4545    pub users: ::prost::alloc::vec::Vec<User>,
4546    /// Pagination metadata for fetching subsequent pages.
4547    #[prost(message, optional, tag="2")]
4548    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4549}
4550// ─── Messages ───────────────────────────────────────────────────────────────
4551
4552/// A variable placeholder within a template that gets substituted during rendering.
4553#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4554pub struct TemplateVariable {
4555    /// Variable name used in the template body (e.g. "employee_name").
4556    /// Constraints: Max length 100 characters.
4557    #[prost(string, tag="1")]
4558    pub name: ::prost::alloc::string::String,
4559    /// Human-readable description of what this variable represents.
4560    /// Constraints: Max length 500 characters.
4561    #[prost(string, tag="2")]
4562    pub description: ::prost::alloc::string::String,
4563    /// Whether this variable must be provided during rendering.
4564    #[prost(bool, tag="3")]
4565    pub required: bool,
4566    /// Where this variable's value comes from (profile attribute or campaign config).
4567    #[prost(enumeration="TemplateVariableSource", tag="4")]
4568    pub source: i32,
4569    /// Fallback value used when the source does not provide a value.
4570    /// Constraints: Max length 1000 characters.
4571    #[prost(string, tag="5")]
4572    pub default_value: ::prost::alloc::string::String,
4573    /// When true, this variable's rendered value is masked in session replay
4574    /// and heatmap screenshots. Org admin controls per variable.
4575    #[prost(bool, tag="6")]
4576    pub pii: bool,
4577}
4578/// A versioned message template with variable placeholders.
4579/// Templates are append-only — updates create new versions.
4580#[derive(Clone, PartialEq, ::prost::Message)]
4581pub struct Template {
4582    /// Unique identifier for the template.
4583    #[prost(string, tag="1")]
4584    pub id: ::prost::alloc::string::String,
4585    /// Human-readable template name (admin-facing label).
4586    /// Constraints: Max length 200 characters.
4587    #[prost(string, tag="2")]
4588    pub name: ::prost::alloc::string::String,
4589    /// Template body with {{variable}} placeholders for substitution.
4590    /// Constraints: Max length 50000 characters.
4591    #[prost(string, tag="3")]
4592    pub body: ::prost::alloc::string::String,
4593    /// Variables that can be substituted into the template body.
4594    #[prost(message, repeated, tag="4")]
4595    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
4596    /// Version number (auto-incremented on each update).
4597    #[prost(int32, tag="5")]
4598    pub version: i32,
4599    /// Timestamp when this version was created.
4600    #[prost(message, optional, tag="6")]
4601    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4602    /// Timestamp of the most recent update (same as created_at for the latest version).
4603    #[prost(message, optional, tag="7")]
4604    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4605    /// User-facing title shown as the message subject to recipients.
4606    /// Serves as the default title; campaigns can override it.
4607    /// Constraints: Max length 200 characters.
4608    #[prost(string, tag="8")]
4609    pub title: ::prost::alloc::string::String,
4610    /// Content format of this template (markdown, rich, HTML).
4611    /// UNSPECIFIED is treated as MARKDOWN for backward compatibility.
4612    #[prost(enumeration="TemplateType", tag="9")]
4613    pub r#type: i32,
4614    /// Language of the template body content (e.g., "en", "es", "ja").
4615    /// Defaults to the org's default_locale, falling back to "en".
4616    /// Translations are created as locale variants of this source.
4617    #[prost(string, tag="10")]
4618    pub source_locale: ::prost::alloc::string::String,
4619}
4620/// A locale-specific translation of a template's title and body.
4621/// Translations are created per template version and go through a review workflow.
4622#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4623pub struct TemplateTranslation {
4624    /// Unique identifier for this translation.
4625    #[prost(string, tag="1")]
4626    pub id: ::prost::alloc::string::String,
4627    /// ID of the source template.
4628    #[prost(string, tag="2")]
4629    pub template_id: ::prost::alloc::string::String,
4630    /// Version of the source template this translation is for.
4631    #[prost(int32, tag="3")]
4632    pub version: i32,
4633    /// Target locale (e.g., "es", "pt-BR", "zh", "ja").
4634    #[prost(string, tag="4")]
4635    pub locale: ::prost::alloc::string::String,
4636    /// Translated title.
4637    /// Constraints: Max length 200 characters.
4638    #[prost(string, tag="5")]
4639    pub title: ::prost::alloc::string::String,
4640    /// Translated body content with {{variable}} placeholders preserved.
4641    /// Constraints: Max length 50000 characters.
4642    #[prost(string, tag="6")]
4643    pub body: ::prost::alloc::string::String,
4644    /// Current review status.
4645    #[prost(enumeration="TranslationStatus", tag="7")]
4646    pub status: i32,
4647    /// Who created this translation ("ai:bedrock", "ai:deepl", or user UUID).
4648    #[prost(string, tag="8")]
4649    pub translated_by: ::prost::alloc::string::String,
4650    /// User who approved the translation. Empty until approved.
4651    #[prost(string, tag="9")]
4652    pub reviewed_by: ::prost::alloc::string::String,
4653    /// When the translation was approved.
4654    #[prost(message, optional, tag="10")]
4655    pub reviewed_at: ::core::option::Option<::prost_types::Timestamp>,
4656    /// When the translation was created.
4657    #[prost(message, optional, tag="11")]
4658    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4659}
4660/// Request to create a new template.
4661#[derive(Clone, PartialEq, ::prost::Message)]
4662pub struct CreateTemplateRequest {
4663    /// Human-readable template name (admin-facing label).
4664    /// Constraints: Max length 200 characters.
4665    #[prost(string, tag="1")]
4666    pub name: ::prost::alloc::string::String,
4667    /// Template body with {{variable}} placeholders.
4668    /// Constraints: Max length 50000 characters.
4669    #[prost(string, tag="2")]
4670    pub body: ::prost::alloc::string::String,
4671    /// Variables available for substitution in the body.
4672    #[prost(message, repeated, tag="3")]
4673    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
4674    /// User-facing title shown as the message subject to recipients.
4675    /// Constraints: Max length 200 characters.
4676    #[prost(string, tag="4")]
4677    pub title: ::prost::alloc::string::String,
4678    /// Content format of the template. Defaults to MARKDOWN if unspecified.
4679    #[prost(enumeration="TemplateType", tag="5")]
4680    pub r#type: i32,
4681    /// Language of the template body content. Defaults to org's default_locale.
4682    /// Valid values: en, es, pt-BR, zh, ja.
4683    #[prost(string, tag="6")]
4684    pub source_locale: ::prost::alloc::string::String,
4685}
4686/// Response after creating a template.
4687#[derive(Clone, PartialEq, ::prost::Message)]
4688pub struct CreateTemplateResponse {
4689    /// The newly created template (version 1).
4690    #[prost(message, optional, tag="1")]
4691    pub template: ::core::option::Option<Template>,
4692}
4693/// Request to update a template, creating a new version.
4694#[derive(Clone, PartialEq, ::prost::Message)]
4695pub struct UpdateTemplateRequest {
4696    /// ID of the template to update.
4697    #[prost(string, tag="1")]
4698    pub template_id: ::prost::alloc::string::String,
4699    /// New template body with {{variable}} placeholders.
4700    /// Constraints: Max length 50000 characters.
4701    #[prost(string, tag="2")]
4702    pub body: ::prost::alloc::string::String,
4703    /// Updated variables for substitution.
4704    #[prost(message, repeated, tag="3")]
4705    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
4706}
4707/// Response after updating a template.
4708#[derive(Clone, PartialEq, ::prost::Message)]
4709pub struct UpdateTemplateResponse {
4710    /// The updated template with incremented version number.
4711    #[prost(message, optional, tag="1")]
4712    pub template: ::core::option::Option<Template>,
4713}
4714/// Request to retrieve a specific template version.
4715#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4716pub struct GetTemplateRequest {
4717    /// ID of the template to retrieve.
4718    #[prost(string, tag="1")]
4719    pub template_id: ::prost::alloc::string::String,
4720    /// Version to retrieve. 0 returns the latest version.
4721    #[prost(int32, tag="2")]
4722    pub version: i32,
4723}
4724/// Response containing the requested template.
4725#[derive(Clone, PartialEq, ::prost::Message)]
4726pub struct GetTemplateResponse {
4727    /// The requested template.
4728    #[prost(message, optional, tag="1")]
4729    pub template: ::core::option::Option<Template>,
4730}
4731/// Request to list templates with pagination.
4732#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4733pub struct ListTemplatesRequest {
4734    /// Pagination parameters.
4735    #[prost(message, optional, tag="1")]
4736    pub pagination: ::core::option::Option<Pagination>,
4737    /// Filter by template type. UNSPECIFIED returns all templates.
4738    #[prost(enumeration="TemplateType", tag="2")]
4739    pub r#type: i32,
4740}
4741/// Response containing a page of templates.
4742#[derive(Clone, PartialEq, ::prost::Message)]
4743pub struct ListTemplatesResponse {
4744    /// List of templates in this page (latest version of each).
4745    #[prost(message, repeated, tag="1")]
4746    pub templates: ::prost::alloc::vec::Vec<Template>,
4747    /// Pagination metadata for fetching subsequent pages.
4748    #[prost(message, optional, tag="2")]
4749    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4750}
4751/// Request to create a translation for a template.
4752#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4753pub struct CreateTemplateTranslationRequest {
4754    /// ID of the template to translate.
4755    #[prost(string, tag="1")]
4756    pub template_id: ::prost::alloc::string::String,
4757    /// Version of the template to translate.
4758    #[prost(int32, tag="2")]
4759    pub version: i32,
4760    /// Target locale.
4761    #[prost(string, tag="3")]
4762    pub locale: ::prost::alloc::string::String,
4763    /// Translated title.
4764    #[prost(string, tag="4")]
4765    pub title: ::prost::alloc::string::String,
4766    /// Translated body content.
4767    #[prost(string, tag="5")]
4768    pub body: ::prost::alloc::string::String,
4769    /// Who created this translation ("ai:bedrock" or user UUID).
4770    #[prost(string, tag="6")]
4771    pub translated_by: ::prost::alloc::string::String,
4772    /// Initial status (typically DRAFT or AI_TRANSLATED).
4773    #[prost(enumeration="TranslationStatus", tag="7")]
4774    pub status: i32,
4775}
4776/// Response after creating a template translation.
4777#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4778pub struct CreateTemplateTranslationResponse {
4779    /// The created translation.
4780    #[prost(message, optional, tag="1")]
4781    pub translation: ::core::option::Option<TemplateTranslation>,
4782}
4783/// Request to update an existing template translation.
4784#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4785pub struct UpdateTemplateTranslationRequest {
4786    /// ID of the translation to update.
4787    #[prost(string, tag="1")]
4788    pub translation_id: ::prost::alloc::string::String,
4789    /// Updated title. Empty leaves unchanged.
4790    #[prost(string, tag="2")]
4791    pub title: ::prost::alloc::string::String,
4792    /// Updated body. Empty leaves unchanged.
4793    #[prost(string, tag="3")]
4794    pub body: ::prost::alloc::string::String,
4795    /// Updated status.
4796    #[prost(enumeration="TranslationStatus", tag="4")]
4797    pub status: i32,
4798}
4799/// Response after updating a template translation.
4800#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4801pub struct UpdateTemplateTranslationResponse {
4802    /// The updated translation.
4803    #[prost(message, optional, tag="1")]
4804    pub translation: ::core::option::Option<TemplateTranslation>,
4805}
4806/// Request to list translations for a template version.
4807#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4808pub struct ListTemplateTranslationsRequest {
4809    /// ID of the template.
4810    #[prost(string, tag="1")]
4811    pub template_id: ::prost::alloc::string::String,
4812    /// Version of the template. 0 returns translations for the latest version.
4813    #[prost(int32, tag="2")]
4814    pub version: i32,
4815}
4816/// Response containing all translations for a template version.
4817#[derive(Clone, PartialEq, ::prost::Message)]
4818pub struct ListTemplateTranslationsResponse {
4819    /// Translations for the requested template version.
4820    #[prost(message, repeated, tag="1")]
4821    pub translations: ::prost::alloc::vec::Vec<TemplateTranslation>,
4822}
4823/// Request to approve a template translation.
4824#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4825pub struct ApproveTemplateTranslationRequest {
4826    /// ID of the translation to approve.
4827    #[prost(string, tag="1")]
4828    pub translation_id: ::prost::alloc::string::String,
4829}
4830/// Response after approving a template translation.
4831#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4832pub struct ApproveTemplateTranslationResponse {
4833    /// The approved translation (status: APPROVED, reviewed_by and reviewed_at set).
4834    #[prost(message, optional, tag="1")]
4835    pub translation: ::core::option::Option<TemplateTranslation>,
4836}
4837// ─── Enums ──────────────────────────────────────────────────────────────────
4838
4839/// Content format of a template, determining which editor and renderer to use.
4840#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4841#[repr(i32)]
4842pub enum TemplateType {
4843    /// Default value; treated as MARKDOWN for backward compatibility.
4844    Unspecified = 0,
4845    /// Markdown with {{variable}} placeholders.
4846    Markdown = 1,
4847    /// Rich text format (reserved for future use).
4848    Rich = 2,
4849    /// Raw HTML format (reserved for future use).
4850    Html = 3,
4851}
4852impl TemplateType {
4853    /// String value of the enum field names used in the ProtoBuf definition.
4854    ///
4855    /// The values are not transformed in any way and thus are considered stable
4856    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4857    pub fn as_str_name(&self) -> &'static str {
4858        match self {
4859            Self::Unspecified => "TEMPLATE_TYPE_UNSPECIFIED",
4860            Self::Markdown => "TEMPLATE_TYPE_MARKDOWN",
4861            Self::Rich => "TEMPLATE_TYPE_RICH",
4862            Self::Html => "TEMPLATE_TYPE_HTML",
4863        }
4864    }
4865    /// Creates an enum from field names used in the ProtoBuf definition.
4866    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4867        match value {
4868            "TEMPLATE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
4869            "TEMPLATE_TYPE_MARKDOWN" => Some(Self::Markdown),
4870            "TEMPLATE_TYPE_RICH" => Some(Self::Rich),
4871            "TEMPLATE_TYPE_HTML" => Some(Self::Html),
4872            _ => None,
4873        }
4874    }
4875}
4876/// Source from which a template variable's value is resolved at render time.
4877#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4878#[repr(i32)]
4879pub enum TemplateVariableSource {
4880    /// Default value; treated as CUSTOM for backward compatibility.
4881    Unspecified = 0,
4882    /// Auto-resolved from the target user's profile attributes.
4883    Profile = 1,
4884    /// Provided manually in the campaign or workflow step configuration.
4885    Custom = 2,
4886}
4887impl TemplateVariableSource {
4888    /// String value of the enum field names used in the ProtoBuf definition.
4889    ///
4890    /// The values are not transformed in any way and thus are considered stable
4891    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4892    pub fn as_str_name(&self) -> &'static str {
4893        match self {
4894            Self::Unspecified => "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED",
4895            Self::Profile => "TEMPLATE_VARIABLE_SOURCE_PROFILE",
4896            Self::Custom => "TEMPLATE_VARIABLE_SOURCE_CUSTOM",
4897        }
4898    }
4899    /// Creates an enum from field names used in the ProtoBuf definition.
4900    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4901        match value {
4902            "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
4903            "TEMPLATE_VARIABLE_SOURCE_PROFILE" => Some(Self::Profile),
4904            "TEMPLATE_VARIABLE_SOURCE_CUSTOM" => Some(Self::Custom),
4905            _ => None,
4906        }
4907    }
4908}
4909/// Review status of a template translation.
4910#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4911#[repr(i32)]
4912pub enum TranslationStatus {
4913    Unspecified = 0,
4914    /// Translation draft, not yet reviewed.
4915    Draft = 1,
4916    /// Translation generated by AI, pending human review.
4917    AiTranslated = 2,
4918    /// Translation is being reviewed by a human.
4919    InReview = 3,
4920    /// Translation has been approved for use.
4921    Approved = 4,
4922}
4923impl TranslationStatus {
4924    /// String value of the enum field names used in the ProtoBuf definition.
4925    ///
4926    /// The values are not transformed in any way and thus are considered stable
4927    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4928    pub fn as_str_name(&self) -> &'static str {
4929        match self {
4930            Self::Unspecified => "TRANSLATION_STATUS_UNSPECIFIED",
4931            Self::Draft => "TRANSLATION_STATUS_DRAFT",
4932            Self::AiTranslated => "TRANSLATION_STATUS_AI_TRANSLATED",
4933            Self::InReview => "TRANSLATION_STATUS_IN_REVIEW",
4934            Self::Approved => "TRANSLATION_STATUS_APPROVED",
4935        }
4936    }
4937    /// Creates an enum from field names used in the ProtoBuf definition.
4938    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4939        match value {
4940            "TRANSLATION_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
4941            "TRANSLATION_STATUS_DRAFT" => Some(Self::Draft),
4942            "TRANSLATION_STATUS_AI_TRANSLATED" => Some(Self::AiTranslated),
4943            "TRANSLATION_STATUS_IN_REVIEW" => Some(Self::InReview),
4944            "TRANSLATION_STATUS_APPROVED" => Some(Self::Approved),
4945            _ => None,
4946        }
4947    }
4948}
4949include!("pidgr.v1.tonic.rs");
4950// @@protoc_insertion_point(module)