Skip to main content

pidgr_proto/pidgr/v1/
pidgr.v1.rs

1// @generated
2// This file is @generated by prost-build.
3// ─── Messages ───────────────────────────────────────────────────────────────
4
5/// Request to submit a user action on a delivered message.
6#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7pub struct SubmitActionRequest {
8    /// ID of the delivery the user is acting on.
9    /// Constraints: UUID format (36 characters).
10    #[prost(string, tag="1")]
11    pub delivery_id: ::prost::alloc::string::String,
12    /// ID of the action being performed (matches MessageAction.id).
13    /// Constraints: Max length 100 characters.
14    #[prost(string, tag="2")]
15    pub action_id: ::prost::alloc::string::String,
16    /// Optional action-specific payload (e.g. poll response data). Empty for ACK.
17    /// Constraints: Max size 10000 bytes.
18    #[prost(bytes="vec", tag="3")]
19    pub payload: ::prost::alloc::vec::Vec<u8>,
20}
21/// Response after submitting an action.
22#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
23pub struct SubmitActionResponse {
24    /// Whether the action was successfully recorded and forwarded to the workflow.
25    #[prost(bool, tag="1")]
26    pub success: bool,
27}
28// ─── Messages ───────────────────────────────────────────────────────────────
29
30/// A single channel dispatch event for the audit trail. Append-only; the
31/// receiver enforces idempotency on terminal states via a partial unique index
32/// on (campaign_id, recipient_user_id, channel, step_kind).
33#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
34pub struct ChannelEvent {
35    #[prost(string, tag="1")]
36    pub org_id: ::prost::alloc::string::String,
37    #[prost(string, tag="2")]
38    pub campaign_id: ::prost::alloc::string::String,
39    #[prost(string, tag="3")]
40    pub recipient_user_id: ::prost::alloc::string::String,
41    #[prost(enumeration="ChannelName", tag="4")]
42    pub channel: i32,
43    #[prost(enumeration="ChannelStepKind", tag="5")]
44    pub step_kind: i32,
45    #[prost(enumeration="ChannelEventStatus", tag="6")]
46    pub status: i32,
47    /// Set only when status = SKIPPED. UNSPECIFIED in all other cases.
48    #[prost(enumeration="ChannelSkipReason", tag="7")]
49    pub skip_reason: i32,
50    /// Provider's identifier for this dispatch. Empty for SKIPPED events.
51    #[prost(string, tag="8")]
52    pub provider_message_id: ::prost::alloc::string::String,
53    /// Cost in micros (1/1000000 of a USD). Zero for absorbed channels.
54    /// Negative is invalid.
55    #[prost(int64, tag="9")]
56    pub cost_micros: i64,
57    /// Free-form provider error payload on FAILED. JSON-encoded; opaque to
58    /// the platform.
59    #[prost(string, tag="10")]
60    pub metadata_json: ::prost::alloc::string::String,
61    #[prost(message, optional, tag="11")]
62    pub occurred_at: ::core::option::Option<::prost_types::Timestamp>,
63}
64#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
65pub struct RecordChannelEventRequest {
66    #[prost(message, optional, tag="1")]
67    pub event: ::core::option::Option<ChannelEvent>,
68}
69#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
70pub struct RecordChannelEventResponse {
71    /// True if the row was inserted. False if rejected as a duplicate of an
72    /// existing terminal-state row.
73    #[prost(bool, tag="1")]
74    pub accepted: bool,
75    /// "duplicate" when accepted=false and the partial unique index rejected
76    /// the insert. Empty when accepted=true.
77    #[prost(string, tag="2")]
78    pub reason: ::prost::alloc::string::String,
79}
80#[derive(Clone, PartialEq, ::prost::Message)]
81pub struct RecordChannelEventBatchRequest {
82    #[prost(message, repeated, tag="1")]
83    pub events: ::prost::alloc::vec::Vec<ChannelEvent>,
84}
85/// Per-event result inside a batch. Order matches the request's events list.
86#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
87pub struct RecordChannelEventBatchResult {
88    #[prost(bool, tag="1")]
89    pub accepted: bool,
90    #[prost(string, tag="2")]
91    pub reason: ::prost::alloc::string::String,
92}
93#[derive(Clone, PartialEq, ::prost::Message)]
94pub struct RecordChannelEventBatchResponse {
95    #[prost(message, repeated, tag="1")]
96    pub results: ::prost::alloc::vec::Vec<RecordChannelEventBatchResult>,
97}
98// ─── Enums ──────────────────────────────────────────────────────────────────
99
100/// Third-party notification channel for reminder + escalation dispatch.
101///
102/// Push is intentionally NOT in this enum. Push is the primary channel; it
103/// always fires alongside any third-party channels. The third-party channels
104/// here are additive. Channels carry only a deeplink notification — message
105/// content stays in the platform.
106#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
107#[repr(i32)]
108pub enum ChannelName {
109    Unspecified = 0,
110    Email = 1,
111    Webhook = 2,
112    Telegram = 3,
113    Slack = 4,
114    Sms = 5,
115    Whatsapp = 6,
116    MicrosoftTeams = 7,
117    Line = 8,
118    GoogleChat = 9,
119}
120impl ChannelName {
121    /// String value of the enum field names used in the ProtoBuf definition.
122    ///
123    /// The values are not transformed in any way and thus are considered stable
124    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
125    pub fn as_str_name(&self) -> &'static str {
126        match self {
127            Self::Unspecified => "CHANNEL_NAME_UNSPECIFIED",
128            Self::Email => "CHANNEL_NAME_EMAIL",
129            Self::Webhook => "CHANNEL_NAME_WEBHOOK",
130            Self::Telegram => "CHANNEL_NAME_TELEGRAM",
131            Self::Slack => "CHANNEL_NAME_SLACK",
132            Self::Sms => "CHANNEL_NAME_SMS",
133            Self::Whatsapp => "CHANNEL_NAME_WHATSAPP",
134            Self::MicrosoftTeams => "CHANNEL_NAME_MICROSOFT_TEAMS",
135            Self::Line => "CHANNEL_NAME_LINE",
136            Self::GoogleChat => "CHANNEL_NAME_GOOGLE_CHAT",
137        }
138    }
139    /// Creates an enum from field names used in the ProtoBuf definition.
140    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
141        match value {
142            "CHANNEL_NAME_UNSPECIFIED" => Some(Self::Unspecified),
143            "CHANNEL_NAME_EMAIL" => Some(Self::Email),
144            "CHANNEL_NAME_WEBHOOK" => Some(Self::Webhook),
145            "CHANNEL_NAME_TELEGRAM" => Some(Self::Telegram),
146            "CHANNEL_NAME_SLACK" => Some(Self::Slack),
147            "CHANNEL_NAME_SMS" => Some(Self::Sms),
148            "CHANNEL_NAME_WHATSAPP" => Some(Self::Whatsapp),
149            "CHANNEL_NAME_MICROSOFT_TEAMS" => Some(Self::MicrosoftTeams),
150            "CHANNEL_NAME_LINE" => Some(Self::Line),
151            "CHANNEL_NAME_GOOGLE_CHAT" => Some(Self::GoogleChat),
152            _ => None,
153        }
154    }
155}
156/// Workflow step kind that triggered the channel dispatch. Different step
157/// kinds for the same (campaign, recipient, channel) tuple are treated as
158/// distinct dispatch events for idempotency purposes.
159#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
160#[repr(i32)]
161pub enum ChannelStepKind {
162    Unspecified = 0,
163    Reminder = 1,
164    Escalation = 2,
165}
166impl ChannelStepKind {
167    /// String value of the enum field names used in the ProtoBuf definition.
168    ///
169    /// The values are not transformed in any way and thus are considered stable
170    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
171    pub fn as_str_name(&self) -> &'static str {
172        match self {
173            Self::Unspecified => "CHANNEL_STEP_KIND_UNSPECIFIED",
174            Self::Reminder => "CHANNEL_STEP_KIND_REMINDER",
175            Self::Escalation => "CHANNEL_STEP_KIND_ESCALATION",
176        }
177    }
178    /// Creates an enum from field names used in the ProtoBuf definition.
179    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
180        match value {
181            "CHANNEL_STEP_KIND_UNSPECIFIED" => Some(Self::Unspecified),
182            "CHANNEL_STEP_KIND_REMINDER" => Some(Self::Reminder),
183            "CHANNEL_STEP_KIND_ESCALATION" => Some(Self::Escalation),
184            _ => None,
185        }
186    }
187}
188/// Status of a channel dispatch attempt. The table is append-only — each state
189/// transition (e.g. SENT → DELIVERED via provider webhook) is its own row keyed
190/// off provider_message_id, not an UPDATE.
191#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
192#[repr(i32)]
193pub enum ChannelEventStatus {
194    Unspecified = 0,
195    Sent = 1,
196    Delivered = 2,
197    Opened = 3,
198    Clicked = 4,
199    Bounced = 5,
200    Failed = 6,
201    Skipped = 7,
202}
203impl ChannelEventStatus {
204    /// String value of the enum field names used in the ProtoBuf definition.
205    ///
206    /// The values are not transformed in any way and thus are considered stable
207    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
208    pub fn as_str_name(&self) -> &'static str {
209        match self {
210            Self::Unspecified => "CHANNEL_EVENT_STATUS_UNSPECIFIED",
211            Self::Sent => "CHANNEL_EVENT_STATUS_SENT",
212            Self::Delivered => "CHANNEL_EVENT_STATUS_DELIVERED",
213            Self::Opened => "CHANNEL_EVENT_STATUS_OPENED",
214            Self::Clicked => "CHANNEL_EVENT_STATUS_CLICKED",
215            Self::Bounced => "CHANNEL_EVENT_STATUS_BOUNCED",
216            Self::Failed => "CHANNEL_EVENT_STATUS_FAILED",
217            Self::Skipped => "CHANNEL_EVENT_STATUS_SKIPPED",
218        }
219    }
220    /// Creates an enum from field names used in the ProtoBuf definition.
221    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
222        match value {
223            "CHANNEL_EVENT_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
224            "CHANNEL_EVENT_STATUS_SENT" => Some(Self::Sent),
225            "CHANNEL_EVENT_STATUS_DELIVERED" => Some(Self::Delivered),
226            "CHANNEL_EVENT_STATUS_OPENED" => Some(Self::Opened),
227            "CHANNEL_EVENT_STATUS_CLICKED" => Some(Self::Clicked),
228            "CHANNEL_EVENT_STATUS_BOUNCED" => Some(Self::Bounced),
229            "CHANNEL_EVENT_STATUS_FAILED" => Some(Self::Failed),
230            "CHANNEL_EVENT_STATUS_SKIPPED" => Some(Self::Skipped),
231            _ => None,
232        }
233    }
234}
235/// Reason a dispatch was SKIPPED rather than attempted. Set when status is
236/// CHANNEL_EVENT_STATUS_SKIPPED; UNSPECIFIED otherwise.
237#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
238#[repr(i32)]
239pub enum ChannelSkipReason {
240    Unspecified = 0,
241    OptedOut = 1,
242    RegionBlocked = 2,
243    CostCapExceeded = 3,
244    NoIdentifier = 4,
245    OrgSuspended = 5,
246}
247impl ChannelSkipReason {
248    /// String value of the enum field names used in the ProtoBuf definition.
249    ///
250    /// The values are not transformed in any way and thus are considered stable
251    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
252    pub fn as_str_name(&self) -> &'static str {
253        match self {
254            Self::Unspecified => "CHANNEL_SKIP_REASON_UNSPECIFIED",
255            Self::OptedOut => "CHANNEL_SKIP_REASON_OPTED_OUT",
256            Self::RegionBlocked => "CHANNEL_SKIP_REASON_REGION_BLOCKED",
257            Self::CostCapExceeded => "CHANNEL_SKIP_REASON_COST_CAP_EXCEEDED",
258            Self::NoIdentifier => "CHANNEL_SKIP_REASON_NO_IDENTIFIER",
259            Self::OrgSuspended => "CHANNEL_SKIP_REASON_ORG_SUSPENDED",
260        }
261    }
262    /// Creates an enum from field names used in the ProtoBuf definition.
263    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
264        match value {
265            "CHANNEL_SKIP_REASON_UNSPECIFIED" => Some(Self::Unspecified),
266            "CHANNEL_SKIP_REASON_OPTED_OUT" => Some(Self::OptedOut),
267            "CHANNEL_SKIP_REASON_REGION_BLOCKED" => Some(Self::RegionBlocked),
268            "CHANNEL_SKIP_REASON_COST_CAP_EXCEEDED" => Some(Self::CostCapExceeded),
269            "CHANNEL_SKIP_REASON_NO_IDENTIFIER" => Some(Self::NoIdentifier),
270            "CHANNEL_SKIP_REASON_ORG_SUSPENDED" => Some(Self::OrgSuspended),
271            _ => None,
272        }
273    }
274}
275/// A named role within an organization with a set of permissions.
276#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
277pub struct Role {
278    /// Unique identifier for the role.
279    #[prost(string, tag="1")]
280    pub id: ::prost::alloc::string::String,
281    /// URL-safe slug (unique within the organization, e.g. "admin", "manager").
282    #[prost(string, tag="2")]
283    pub slug: ::prost::alloc::string::String,
284    /// Human-readable display name.
285    #[prost(string, tag="3")]
286    pub name: ::prost::alloc::string::String,
287    /// Whether this role was seeded by the system on organization creation.
288    #[prost(bool, tag="4")]
289    pub is_default: bool,
290    /// Permissions granted to users with this role.
291    #[prost(enumeration="Permission", repeated, tag="5")]
292    pub permissions: ::prost::alloc::vec::Vec<i32>,
293    /// Whether this role is system-managed and immutable (e.g. super_admin).
294    #[prost(bool, tag="6")]
295    pub is_system: bool,
296}
297// ─── Pagination ─────────────────────────────────────────────────────────────
298
299/// Cursor-based pagination parameters for list requests.
300#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
301pub struct Pagination {
302    /// Maximum number of items to return per page.
303    #[prost(int32, tag="1")]
304    pub page_size: i32,
305    /// Opaque token from a previous response to fetch the next page.
306    #[prost(string, tag="2")]
307    pub page_token: ::prost::alloc::string::String,
308}
309/// Pagination metadata returned alongside list responses.
310#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
311pub struct PaginationMeta {
312    /// Token to pass in the next request to get the following page. Empty if no more pages.
313    #[prost(string, tag="1")]
314    pub next_page_token: ::prost::alloc::string::String,
315    /// Total number of items matching the query (across all pages).
316    #[prost(int32, tag="2")]
317    pub total_count: i32,
318}
319// ─── Message & Action Model ─────────────────────────────────────────────────
320
321/// An action button attached to a message that a recipient can interact with.
322#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
323pub struct MessageAction {
324    /// Unique identifier for this action within the message.
325    #[prost(string, tag="1")]
326    pub id: ::prost::alloc::string::String,
327    /// The type of action (e.g. ACK).
328    #[prost(enumeration="ActionType", tag="2")]
329    pub r#type: i32,
330    /// Display label shown to the recipient (e.g. "Got it").
331    /// Constraints: Max length 50 characters.
332    #[prost(string, tag="3")]
333    pub label: ::prost::alloc::string::String,
334}
335/// Canonical message type used across rendering, inbox, and delivery.
336/// Represents the fully rendered content delivered to a recipient.
337#[derive(Clone, PartialEq, ::prost::Message)]
338pub struct Message {
339    /// SHA-256 hash of the rendered content, used as a content-addressable ID.
340    #[prost(string, tag="1")]
341    pub content_id: ::prost::alloc::string::String,
342    /// ID of the campaign this message belongs to.
343    #[prost(string, tag="2")]
344    pub campaign_id: ::prost::alloc::string::String,
345    /// Display name of the sender (e.g. organization or campaign name).
346    /// Constraints: Max length 200 characters.
347    #[prost(string, tag="3")]
348    pub sender_name: ::prost::alloc::string::String,
349    /// Short one-line summary shown in notification banners.
350    /// Constraints: Max length 500 characters.
351    #[prost(string, tag="4")]
352    pub summary: ::prost::alloc::string::String,
353    /// Preview text shown in inbox list views.
354    /// Constraints: Max length 500 characters.
355    #[prost(string, tag="5")]
356    pub preview: ::prost::alloc::string::String,
357    /// Full message body content.
358    /// Constraints: Max length 100000 characters.
359    #[prost(string, tag="6")]
360    pub body: ::prost::alloc::string::String,
361    /// Whether this message requires immediate attention from the recipient.
362    #[prost(bool, tag="7")]
363    pub critical: bool,
364    /// Actions available to the recipient (e.g. acknowledge button).
365    #[prost(message, repeated, tag="8")]
366    pub actions: ::prost::alloc::vec::Vec<MessageAction>,
367    /// Timestamp when the message was created.
368    #[prost(message, optional, tag="9")]
369    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
370    /// User-facing title of the message (resolved from campaign or template).
371    /// Constraints: Max length 200 characters.
372    #[prost(string, tag="10")]
373    pub title: ::prost::alloc::string::String,
374}
375// ─── Workflow Definition Model ──────────────────────────────────────────────
376
377/// A data-driven workflow represented as a directed acyclic graph (DAG) of steps.
378/// Defines the automation logic for a campaign's lifecycle.
379/// Backend MUST validate the graph is a DAG (no cycles) before execution.
380#[derive(Clone, PartialEq, ::prost::Message)]
381pub struct WorkflowDefinition {
382    /// Ordered list of steps in the workflow DAG.
383    /// Constraints: Max 100 steps. Backend MUST validate the graph is a DAG (no cycles).
384    #[prost(message, repeated, tag="1")]
385    pub steps: ::prost::alloc::vec::Vec<WorkflowStep>,
386}
387/// A single step in a workflow DAG with typed configuration and transitions.
388#[derive(Clone, PartialEq, ::prost::Message)]
389pub struct WorkflowStep {
390    /// Unique identifier for this step within the workflow.
391    #[prost(string, tag="1")]
392    pub id: ::prost::alloc::string::String,
393    /// The type of operation this step performs.
394    #[prost(enumeration="StepType", tag="2")]
395    pub r#type: i32,
396    /// Map of outcome labels to the next step ID (e.g. "completed" -> "step_3").
397    /// Constraints: Max 10 transitions per step.
398    #[prost(map="string, string", tag="7")]
399    pub transitions: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
400    /// Step-specific configuration — exactly one must be set, matching the type.
401    #[prost(oneof="workflow_step::Config", tags="3, 4, 5, 6, 8")]
402    pub config: ::core::option::Option<workflow_step::Config>,
403}
404/// Nested message and enum types in `WorkflowStep`.
405pub mod workflow_step {
406    /// Step-specific configuration — exactly one must be set, matching the type.
407    #[derive(Clone, PartialEq, ::prost::Oneof)]
408    pub enum Config {
409        /// Configuration for SEND_NOTIFICATION steps.
410        #[prost(message, tag="3")]
411        SendNotification(super::SendNotificationConfig),
412        /// Configuration for DEADLINE_CHECK steps.
413        #[prost(message, tag="4")]
414        DeadlineCheck(super::DeadlineCheckConfig),
415        /// Configuration for SEND_REMINDER steps.
416        #[prost(message, tag="5")]
417        SendReminder(super::SendReminderConfig),
418        /// Configuration for CALL_WEBHOOK steps.
419        #[prost(message, tag="6")]
420        CallWebhook(super::CallWebhookConfig),
421        /// Configuration for STEP_TYPE_ESCALATE steps.
422        #[prost(message, tag="8")]
423        EscalateConfig(super::EscalateConfig),
424    }
425}
426/// Configuration for a step that sends the initial push notification.
427#[derive(Clone, PartialEq, ::prost::Message)]
428pub struct SendNotificationConfig {
429    /// Notification delivery type (e.g. "push").
430    /// Constraints: Accepted values: "push". Max length 50 characters.
431    #[prost(string, tag="1")]
432    pub r#type: ::prost::alloc::string::String,
433    /// ID of the template to use for this step's notification.
434    /// Empty falls back to campaign-level template_id.
435    /// Constraints: Max length 36 characters (UUID).
436    #[prost(string, tag="2")]
437    pub template_id: ::prost::alloc::string::String,
438    /// Pinned template version for this step.
439    /// 0 falls back to campaign-level template_version.
440    #[prost(int32, tag="3")]
441    pub template_version: i32,
442    /// Display label for the action button (e.g. "Acknowledge", "Got it").
443    /// Constraints: Max length 50 characters.
444    #[prost(string, tag="4")]
445    pub action_label: ::prost::alloc::string::String,
446    /// Action type for this step's message button.
447    #[prost(enumeration="ActionType", tag="5")]
448    pub action_type: i32,
449    /// Values for custom-sourced template variables specific to this step.
450    /// Constraints: Max 100 entries. Key max length 100 characters, value max length 10000 characters.
451    #[prost(map="string, string", tag="6")]
452    pub custom_variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
453}
454/// Configuration for a deadline-based timer step that sleeps for a configured
455/// delay before proceeding. Acknowledgments happen independently at the delivery
456/// level and are evaluated by subsequent steps (e.g. SEND_REMINDER).
457#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
458pub struct DeadlineCheckConfig {
459    /// Duration string for the deadline delay (e.g. "120h", "72h").
460    /// Constraints: Valid range 1m to 8760h (1 year).
461    #[prost(string, tag="1")]
462    pub delay: ::prost::alloc::string::String,
463}
464/// Configuration for a step that sends a one-time reminder to non-responsive recipients.
465#[derive(Clone, PartialEq, ::prost::Message)]
466pub struct SendReminderConfig {
467    /// Reminder delivery type (e.g. "push").
468    /// Constraints: Accepted values: "push". Max length 50 characters.
469    #[prost(string, tag="1")]
470    pub r#type: ::prost::alloc::string::String,
471    /// Additional third-party channels to dispatch the reminder through
472    /// alongside the primary push notification. Empty = push-only behaviour
473    /// (the platform's historical default; no surprise for existing
474    /// workflows). Each entry produces an independent dispatch attempt
475    /// recorded in `channel_events`; per-org configuration in
476    /// pidgr-integrations decides which channels are eligible at runtime.
477    #[prost(enumeration="ChannelName", repeated, tag="4")]
478    pub third_party_channels: ::prost::alloc::vec::Vec<i32>,
479    /// Third parties to loop in when this reminder fires. Each resolved
480    /// target receives a passive inbox delivery (no action button) plus a
481    /// fan-out via the same `third_party_channels` list as the employee
482    /// reminder. The delivery auto-dismisses when the original recipient
483    /// acknowledges the campaign.
484    ///
485    /// Each entry reuses the existing `EscalationTarget` shape
486    /// (USER / GROUP / MANAGER / ROLE). When `type` is MANAGER, `target_id`
487    /// is empty and is resolved at runtime from the original recipient's
488    /// `manager_id`. Self-targets (resolved user_id == original recipient)
489    /// are dropped at dispatch time.
490    /// Constraints: Max 5 entries.
491    #[prost(message, repeated, tag="5")]
492    pub notify_targets: ::prost::alloc::vec::Vec<EscalationTarget>,
493}
494/// Configuration for a step that calls an external webhook.
495#[derive(Clone, PartialEq, ::prost::Message)]
496pub struct CallWebhookConfig {
497    /// Human-readable name for this webhook (for logging/display).
498    /// Constraints: Max length 200 characters.
499    #[prost(string, tag="1")]
500    pub name: ::prost::alloc::string::String,
501    /// URL to POST campaign context to.
502    /// Constraints: Max length 2048 characters.
503    /// Security: HTTPS required in production. Backend MUST reject private,
504    /// loopback, and link-local addresses to prevent SSRF attacks.
505    #[prost(string, tag="2")]
506    pub url: ::prost::alloc::string::String,
507    /// Additional HTTP headers to include in the webhook request.
508    /// Constraints: Max 20 entries. Key max length 200 characters, value max length 2000 characters.
509    #[prost(map="string, string", tag="3")]
510    pub headers: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
511}
512/// A target for escalation — who should be notified when escalation fires.
513#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
514pub struct EscalationTarget {
515    /// Type of target.
516    #[prost(enumeration="EscalationTargetType", tag="1")]
517    pub r#type: i32,
518    /// ID of the target (user_id, group_id, or role_id).
519    /// Empty for MANAGER type (resolved at runtime from recipient's manager_id).
520    #[prost(string, tag="2")]
521    pub target_id: ::prost::alloc::string::String,
522}
523/// Configuration for an escalation step in the workflow DAG.
524#[derive(Clone, PartialEq, ::prost::Message)]
525pub struct EscalateConfig {
526    /// Condition that triggers escalation.
527    #[prost(enumeration="EscalationCondition", tag="1")]
528    pub condition: i32,
529    /// Targets to notify when escalation fires.
530    #[prost(message, repeated, tag="2")]
531    pub targets: ::prost::alloc::vec::Vec<EscalationTarget>,
532    /// Number of times to repeat this escalation before moving to the next step.
533    /// Constraints: Max 5.
534    #[prost(int32, tag="3")]
535    pub repeat_count: i32,
536    /// Minutes between repeat attempts.
537    #[prost(int32, tag="4")]
538    pub repeat_interval_minutes: i32,
539    /// Behavior mode for this escalation. UNSPECIFIED is normalized to DELIVER.
540    #[prost(enumeration="EscalateMode", tag="5")]
541    pub mode: i32,
542    /// Additional third-party channels to dispatch the escalation through
543    /// alongside the primary push / delivery side effect. Empty = no
544    /// third-party fan-out (existing behaviour). Each entry produces an
545    /// independent dispatch attempt recorded in `channel_events`. ALERT_ONLY
546    /// and DELIVER modes both support third-party fan-out — the channel
547    /// adapters render the alert content from the campaign + a
548    /// mode-aware copy variant.
549    #[prost(enumeration="ChannelName", repeated, tag="6")]
550    pub third_party_channels: ::prost::alloc::vec::Vec<i32>,
551}
552// ─── Status Enums ───────────────────────────────────────────────────────────
553
554/// Lifecycle status of a campaign.
555#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
556#[repr(i32)]
557pub enum CampaignStatus {
558    /// Default value; not a valid status.
559    Unspecified = 0,
560    /// Campaign has been created but not yet started.
561    Created = 1,
562    /// Campaign is actively delivering messages and processing actions.
563    Running = 2,
564    /// All recipients have been processed; campaign is finished.
565    Completed = 3,
566    /// Campaign terminated due to an unrecoverable error.
567    Failed = 4,
568    /// Campaign was manually cancelled before completion.
569    Cancelled = 5,
570}
571impl CampaignStatus {
572    /// String value of the enum field names used in the ProtoBuf definition.
573    ///
574    /// The values are not transformed in any way and thus are considered stable
575    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
576    pub fn as_str_name(&self) -> &'static str {
577        match self {
578            Self::Unspecified => "CAMPAIGN_STATUS_UNSPECIFIED",
579            Self::Created => "CAMPAIGN_STATUS_CREATED",
580            Self::Running => "CAMPAIGN_STATUS_RUNNING",
581            Self::Completed => "CAMPAIGN_STATUS_COMPLETED",
582            Self::Failed => "CAMPAIGN_STATUS_FAILED",
583            Self::Cancelled => "CAMPAIGN_STATUS_CANCELLED",
584        }
585    }
586    /// Creates an enum from field names used in the ProtoBuf definition.
587    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
588        match value {
589            "CAMPAIGN_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
590            "CAMPAIGN_STATUS_CREATED" => Some(Self::Created),
591            "CAMPAIGN_STATUS_RUNNING" => Some(Self::Running),
592            "CAMPAIGN_STATUS_COMPLETED" => Some(Self::Completed),
593            "CAMPAIGN_STATUS_FAILED" => Some(Self::Failed),
594            "CAMPAIGN_STATUS_CANCELLED" => Some(Self::Cancelled),
595            _ => None,
596        }
597    }
598}
599/// Delivery status for a single message sent to a recipient.
600#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
601#[repr(i32)]
602pub enum DeliveryStatus {
603    /// Default value; not a valid status.
604    Unspecified = 0,
605    /// Message is queued but has not been sent yet.
606    Pending = 1,
607    /// Push notification was sent to the delivery provider.
608    Sent = 2,
609    /// Message was confirmed delivered to the device.
610    Delivered = 3,
611    /// Recipient completed the required action (e.g. acknowledged).
612    Acknowledged = 4,
613    /// Recipient did not act before the deadline.
614    Missed = 5,
615    /// Recipient has no registered device; delivery was skipped.
616    NoDevice = 6,
617    /// Delivery failed due to a provider or system error.
618    Failed = 7,
619}
620impl DeliveryStatus {
621    /// String value of the enum field names used in the ProtoBuf definition.
622    ///
623    /// The values are not transformed in any way and thus are considered stable
624    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
625    pub fn as_str_name(&self) -> &'static str {
626        match self {
627            Self::Unspecified => "DELIVERY_STATUS_UNSPECIFIED",
628            Self::Pending => "DELIVERY_STATUS_PENDING",
629            Self::Sent => "DELIVERY_STATUS_SENT",
630            Self::Delivered => "DELIVERY_STATUS_DELIVERED",
631            Self::Acknowledged => "DELIVERY_STATUS_ACKNOWLEDGED",
632            Self::Missed => "DELIVERY_STATUS_MISSED",
633            Self::NoDevice => "DELIVERY_STATUS_NO_DEVICE",
634            Self::Failed => "DELIVERY_STATUS_FAILED",
635        }
636    }
637    /// Creates an enum from field names used in the ProtoBuf definition.
638    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
639        match value {
640            "DELIVERY_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
641            "DELIVERY_STATUS_PENDING" => Some(Self::Pending),
642            "DELIVERY_STATUS_SENT" => Some(Self::Sent),
643            "DELIVERY_STATUS_DELIVERED" => Some(Self::Delivered),
644            "DELIVERY_STATUS_ACKNOWLEDGED" => Some(Self::Acknowledged),
645            "DELIVERY_STATUS_MISSED" => Some(Self::Missed),
646            "DELIVERY_STATUS_NO_DEVICE" => Some(Self::NoDevice),
647            "DELIVERY_STATUS_FAILED" => Some(Self::Failed),
648            _ => None,
649        }
650    }
651}
652/// Mobile platform for device registration.
653#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
654#[repr(i32)]
655pub enum Platform {
656    /// Default value; not a valid platform.
657    Unspecified = 0,
658    /// Apple iOS.
659    Ios = 1,
660    /// Google Android.
661    Android = 2,
662}
663impl Platform {
664    /// String value of the enum field names used in the ProtoBuf definition.
665    ///
666    /// The values are not transformed in any way and thus are considered stable
667    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
668    pub fn as_str_name(&self) -> &'static str {
669        match self {
670            Self::Unspecified => "PLATFORM_UNSPECIFIED",
671            Self::Ios => "PLATFORM_IOS",
672            Self::Android => "PLATFORM_ANDROID",
673        }
674    }
675    /// Creates an enum from field names used in the ProtoBuf definition.
676    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
677        match value {
678            "PLATFORM_UNSPECIFIED" => Some(Self::Unspecified),
679            "PLATFORM_IOS" => Some(Self::Ios),
680            "PLATFORM_ANDROID" => Some(Self::Android),
681            _ => None,
682        }
683    }
684}
685/// Granular permission for authorization checks.
686/// Stored in the database as enum names (e.g. "PERMISSION_ORG_READ").
687/// New values MUST be appended with the next sequential number; existing values
688/// MUST NOT be renumbered or removed (enforced by buf breaking).
689#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
690#[repr(i32)]
691pub enum Permission {
692    /// Default value; not a valid permission.
693    Unspecified = 0,
694    /// View organization settings.
695    OrgRead = 1,
696    /// Modify organization settings.
697    OrgWrite = 2,
698    /// View organization members.
699    MembersRead = 3,
700    /// Invite new users to the organization.
701    MembersInvite = 4,
702    /// Change user roles, deactivate users.
703    MembersManage = 5,
704    /// View campaigns and deliveries.
705    CampaignsRead = 6,
706    /// Create and edit campaigns.
707    CampaignsWrite = 7,
708    /// Start campaign execution.
709    CampaignsStart = 8,
710    /// View templates.
711    TemplatesRead = 9,
712    /// Create and edit templates.
713    TemplatesWrite = 10,
714    /// View inbox messages and deliveries.
715    InboxRead = 11,
716    /// Submit actions on deliveries.
717    InboxAct = 12,
718    /// View all groups in the organization.
719    GroupsAllRead = 13,
720    /// Create, edit, delete groups the caller created, manage own group membership.
721    GroupsWrite = 14,
722    /// Create, edit, delete any group in the organization, manage any group membership.
723    GroupsAllWrite = 15,
724    /// View all teams (organizational units) in the organization.
725    TeamsAllRead = 16,
726    /// Create, edit, delete teams the caller created, manage own team membership.
727    TeamsWrite = 17,
728    /// Create, edit, delete any team in the organization, manage any team membership.
729    TeamsAllWrite = 18,
730    /// View privacy requests (exports, deletions) for the organization.
731    PrivacyRead = 19,
732    /// Schedule deletions, export user data, restrict processing.
733    PrivacyWrite = 20,
734    /// View audit trail events for the organization.
735    AuditRead = 21,
736    /// Review and approve template translations.
737    TemplatesReview = 22,
738    /// Cross-organization read access for platform-level support operations.
739    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
740    PlatformSupport = 23,
741    /// Manage platform access codes (generation, listing, revocation).
742    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
743    PlatformAccessCodes = 24,
744    /// Provision and manage organizations at the platform level.
745    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
746    PlatformProvision = 25,
747    /// Take abuse-response actions against organizations (suspend, revoke, quota overrides).
748    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
749    PlatformAbuseResponse = 26,
750    /// Write subprocessor and compliance records at the platform level.
751    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
752    PlatformComplianceWrite = 27,
753    /// Create synthetic (flagged) data on any org: seed resources and simulate
754    /// campaign outcomes. Assignable only to roles within an ORG_TYPE_STAFF organization.
755    PlatformSynthetic = 28,
756    /// Dispatch notifications to third-party channels (Slack, Telegram, webhook, etc.).
757    ChannelsDispatch = 29,
758    /// Create, update, or remove a member's third-party channel reachability.
759    ReachabilityWrite = 30,
760    /// Triage security incidents (list, classify, mark-notified) at the platform level.
761    /// Assignable only to roles within an ORG_TYPE_STAFF organization.
762    PlatformIncidents = 31,
763}
764impl Permission {
765    /// String value of the enum field names used in the ProtoBuf definition.
766    ///
767    /// The values are not transformed in any way and thus are considered stable
768    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
769    pub fn as_str_name(&self) -> &'static str {
770        match self {
771            Self::Unspecified => "PERMISSION_UNSPECIFIED",
772            Self::OrgRead => "PERMISSION_ORG_READ",
773            Self::OrgWrite => "PERMISSION_ORG_WRITE",
774            Self::MembersRead => "PERMISSION_MEMBERS_READ",
775            Self::MembersInvite => "PERMISSION_MEMBERS_INVITE",
776            Self::MembersManage => "PERMISSION_MEMBERS_MANAGE",
777            Self::CampaignsRead => "PERMISSION_CAMPAIGNS_READ",
778            Self::CampaignsWrite => "PERMISSION_CAMPAIGNS_WRITE",
779            Self::CampaignsStart => "PERMISSION_CAMPAIGNS_START",
780            Self::TemplatesRead => "PERMISSION_TEMPLATES_READ",
781            Self::TemplatesWrite => "PERMISSION_TEMPLATES_WRITE",
782            Self::InboxRead => "PERMISSION_INBOX_READ",
783            Self::InboxAct => "PERMISSION_INBOX_ACT",
784            Self::GroupsAllRead => "PERMISSION_GROUPS_ALL_READ",
785            Self::GroupsWrite => "PERMISSION_GROUPS_WRITE",
786            Self::GroupsAllWrite => "PERMISSION_GROUPS_ALL_WRITE",
787            Self::TeamsAllRead => "PERMISSION_TEAMS_ALL_READ",
788            Self::TeamsWrite => "PERMISSION_TEAMS_WRITE",
789            Self::TeamsAllWrite => "PERMISSION_TEAMS_ALL_WRITE",
790            Self::PrivacyRead => "PERMISSION_PRIVACY_READ",
791            Self::PrivacyWrite => "PERMISSION_PRIVACY_WRITE",
792            Self::AuditRead => "PERMISSION_AUDIT_READ",
793            Self::TemplatesReview => "PERMISSION_TEMPLATES_REVIEW",
794            Self::PlatformSupport => "PERMISSION_PLATFORM_SUPPORT",
795            Self::PlatformAccessCodes => "PERMISSION_PLATFORM_ACCESS_CODES",
796            Self::PlatformProvision => "PERMISSION_PLATFORM_PROVISION",
797            Self::PlatformAbuseResponse => "PERMISSION_PLATFORM_ABUSE_RESPONSE",
798            Self::PlatformComplianceWrite => "PERMISSION_PLATFORM_COMPLIANCE_WRITE",
799            Self::PlatformSynthetic => "PERMISSION_PLATFORM_SYNTHETIC",
800            Self::ChannelsDispatch => "PERMISSION_CHANNELS_DISPATCH",
801            Self::ReachabilityWrite => "PERMISSION_REACHABILITY_WRITE",
802            Self::PlatformIncidents => "PERMISSION_PLATFORM_INCIDENTS",
803        }
804    }
805    /// Creates an enum from field names used in the ProtoBuf definition.
806    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
807        match value {
808            "PERMISSION_UNSPECIFIED" => Some(Self::Unspecified),
809            "PERMISSION_ORG_READ" => Some(Self::OrgRead),
810            "PERMISSION_ORG_WRITE" => Some(Self::OrgWrite),
811            "PERMISSION_MEMBERS_READ" => Some(Self::MembersRead),
812            "PERMISSION_MEMBERS_INVITE" => Some(Self::MembersInvite),
813            "PERMISSION_MEMBERS_MANAGE" => Some(Self::MembersManage),
814            "PERMISSION_CAMPAIGNS_READ" => Some(Self::CampaignsRead),
815            "PERMISSION_CAMPAIGNS_WRITE" => Some(Self::CampaignsWrite),
816            "PERMISSION_CAMPAIGNS_START" => Some(Self::CampaignsStart),
817            "PERMISSION_TEMPLATES_READ" => Some(Self::TemplatesRead),
818            "PERMISSION_TEMPLATES_WRITE" => Some(Self::TemplatesWrite),
819            "PERMISSION_INBOX_READ" => Some(Self::InboxRead),
820            "PERMISSION_INBOX_ACT" => Some(Self::InboxAct),
821            "PERMISSION_GROUPS_ALL_READ" => Some(Self::GroupsAllRead),
822            "PERMISSION_GROUPS_WRITE" => Some(Self::GroupsWrite),
823            "PERMISSION_GROUPS_ALL_WRITE" => Some(Self::GroupsAllWrite),
824            "PERMISSION_TEAMS_ALL_READ" => Some(Self::TeamsAllRead),
825            "PERMISSION_TEAMS_WRITE" => Some(Self::TeamsWrite),
826            "PERMISSION_TEAMS_ALL_WRITE" => Some(Self::TeamsAllWrite),
827            "PERMISSION_PRIVACY_READ" => Some(Self::PrivacyRead),
828            "PERMISSION_PRIVACY_WRITE" => Some(Self::PrivacyWrite),
829            "PERMISSION_AUDIT_READ" => Some(Self::AuditRead),
830            "PERMISSION_TEMPLATES_REVIEW" => Some(Self::TemplatesReview),
831            "PERMISSION_PLATFORM_SUPPORT" => Some(Self::PlatformSupport),
832            "PERMISSION_PLATFORM_ACCESS_CODES" => Some(Self::PlatformAccessCodes),
833            "PERMISSION_PLATFORM_PROVISION" => Some(Self::PlatformProvision),
834            "PERMISSION_PLATFORM_ABUSE_RESPONSE" => Some(Self::PlatformAbuseResponse),
835            "PERMISSION_PLATFORM_COMPLIANCE_WRITE" => Some(Self::PlatformComplianceWrite),
836            "PERMISSION_PLATFORM_SYNTHETIC" => Some(Self::PlatformSynthetic),
837            "PERMISSION_CHANNELS_DISPATCH" => Some(Self::ChannelsDispatch),
838            "PERMISSION_REACHABILITY_WRITE" => Some(Self::ReachabilityWrite),
839            "PERMISSION_PLATFORM_INCIDENTS" => Some(Self::PlatformIncidents),
840            _ => None,
841        }
842    }
843}
844/// Type of action a recipient can perform on a message.
845#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
846#[repr(i32)]
847pub enum ActionType {
848    /// Default value; not a valid action type.
849    Unspecified = 0,
850    /// Simple acknowledgment — recipient confirms they received the message.
851    Ack = 1,
852}
853impl ActionType {
854    /// String value of the enum field names used in the ProtoBuf definition.
855    ///
856    /// The values are not transformed in any way and thus are considered stable
857    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
858    pub fn as_str_name(&self) -> &'static str {
859        match self {
860            Self::Unspecified => "ACTION_TYPE_UNSPECIFIED",
861            Self::Ack => "ACTION_TYPE_ACK",
862        }
863    }
864    /// Creates an enum from field names used in the ProtoBuf definition.
865    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
866        match value {
867            "ACTION_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
868            "ACTION_TYPE_ACK" => Some(Self::Ack),
869            _ => None,
870        }
871    }
872}
873/// Type of step within a workflow definition DAG.
874#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
875#[repr(i32)]
876pub enum StepType {
877    /// Default value; not a valid step type.
878    Unspecified = 0,
879    /// Send the initial push notification to all recipients.
880    SendNotification = 1,
881    /// Sleep for a configurable deadline, then proceed to the next step.
882    DeadlineCheck = 2,
883    /// Send a follow-up reminder to recipients who have not acted.
884    SendReminder = 3,
885    /// Call an external webhook with campaign context.
886    CallWebhook = 4,
887    /// Mark unacknowledged deliveries (SENT/DELIVERED) as MISSED. No config required.
888    MarkMissed = 5,
889    /// Escalate unacknowledged deliveries to configured targets.
890    Escalate = 6,
891}
892impl StepType {
893    /// String value of the enum field names used in the ProtoBuf definition.
894    ///
895    /// The values are not transformed in any way and thus are considered stable
896    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
897    pub fn as_str_name(&self) -> &'static str {
898        match self {
899            Self::Unspecified => "STEP_TYPE_UNSPECIFIED",
900            Self::SendNotification => "STEP_TYPE_SEND_NOTIFICATION",
901            Self::DeadlineCheck => "STEP_TYPE_DEADLINE_CHECK",
902            Self::SendReminder => "STEP_TYPE_SEND_REMINDER",
903            Self::CallWebhook => "STEP_TYPE_CALL_WEBHOOK",
904            Self::MarkMissed => "STEP_TYPE_MARK_MISSED",
905            Self::Escalate => "STEP_TYPE_ESCALATE",
906        }
907    }
908    /// Creates an enum from field names used in the ProtoBuf definition.
909    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
910        match value {
911            "STEP_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
912            "STEP_TYPE_SEND_NOTIFICATION" => Some(Self::SendNotification),
913            "STEP_TYPE_DEADLINE_CHECK" => Some(Self::DeadlineCheck),
914            "STEP_TYPE_SEND_REMINDER" => Some(Self::SendReminder),
915            "STEP_TYPE_CALL_WEBHOOK" => Some(Self::CallWebhook),
916            "STEP_TYPE_MARK_MISSED" => Some(Self::MarkMissed),
917            "STEP_TYPE_ESCALATE" => Some(Self::Escalate),
918            _ => None,
919        }
920    }
921}
922/// Condition that must be met for an escalation to fire.
923#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
924#[repr(i32)]
925pub enum EscalationCondition {
926    Unspecified = 0,
927    /// Escalate if the delivery has not been acknowledged.
928    IfNotAcked = 1,
929    /// Escalate if the campaign is still open (even if some deliveries are acknowledged).
930    IfNotClosed = 2,
931}
932impl EscalationCondition {
933    /// String value of the enum field names used in the ProtoBuf definition.
934    ///
935    /// The values are not transformed in any way and thus are considered stable
936    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
937    pub fn as_str_name(&self) -> &'static str {
938        match self {
939            Self::Unspecified => "ESCALATION_CONDITION_UNSPECIFIED",
940            Self::IfNotAcked => "ESCALATION_CONDITION_IF_NOT_ACKED",
941            Self::IfNotClosed => "ESCALATION_CONDITION_IF_NOT_CLOSED",
942        }
943    }
944    /// Creates an enum from field names used in the ProtoBuf definition.
945    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
946        match value {
947            "ESCALATION_CONDITION_UNSPECIFIED" => Some(Self::Unspecified),
948            "ESCALATION_CONDITION_IF_NOT_ACKED" => Some(Self::IfNotAcked),
949            "ESCALATION_CONDITION_IF_NOT_CLOSED" => Some(Self::IfNotClosed),
950            _ => None,
951        }
952    }
953}
954/// Type of escalation target.
955#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
956#[repr(i32)]
957pub enum EscalationTargetType {
958    Unspecified = 0,
959    /// Escalate to a specific user by ID.
960    User = 1,
961    /// Escalate to all members of a group.
962    Group = 2,
963    /// Escalate to the recipient's direct manager (resolved from manager_id at runtime).
964    Manager = 3,
965    /// Escalate to all users with a specific role in the org.
966    Role = 4,
967}
968impl EscalationTargetType {
969    /// String value of the enum field names used in the ProtoBuf definition.
970    ///
971    /// The values are not transformed in any way and thus are considered stable
972    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
973    pub fn as_str_name(&self) -> &'static str {
974        match self {
975            Self::Unspecified => "ESCALATION_TARGET_TYPE_UNSPECIFIED",
976            Self::User => "ESCALATION_TARGET_TYPE_USER",
977            Self::Group => "ESCALATION_TARGET_TYPE_GROUP",
978            Self::Manager => "ESCALATION_TARGET_TYPE_MANAGER",
979            Self::Role => "ESCALATION_TARGET_TYPE_ROLE",
980        }
981    }
982    /// Creates an enum from field names used in the ProtoBuf definition.
983    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
984        match value {
985            "ESCALATION_TARGET_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
986            "ESCALATION_TARGET_TYPE_USER" => Some(Self::User),
987            "ESCALATION_TARGET_TYPE_GROUP" => Some(Self::Group),
988            "ESCALATION_TARGET_TYPE_MANAGER" => Some(Self::Manager),
989            "ESCALATION_TARGET_TYPE_ROLE" => Some(Self::Role),
990            _ => None,
991        }
992    }
993}
994/// Behavior mode controlling what an escalation produces for its targets.
995#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
996#[repr(i32)]
997pub enum EscalateMode {
998    /// Default value; servers normalize this to ESCALATE_MODE_DELIVER.
999    Unspecified = 0,
1000    /// Targets receive a delivery for the campaign just like primary recipients.
1001    Deliver = 1,
1002    /// Targets receive an out-of-band alert only; no delivery is created.
1003    AlertOnly = 2,
1004}
1005impl EscalateMode {
1006    /// String value of the enum field names used in the ProtoBuf definition.
1007    ///
1008    /// The values are not transformed in any way and thus are considered stable
1009    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1010    pub fn as_str_name(&self) -> &'static str {
1011        match self {
1012            Self::Unspecified => "ESCALATE_MODE_UNSPECIFIED",
1013            Self::Deliver => "ESCALATE_MODE_DELIVER",
1014            Self::AlertOnly => "ESCALATE_MODE_ALERT_ONLY",
1015        }
1016    }
1017    /// Creates an enum from field names used in the ProtoBuf definition.
1018    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1019        match value {
1020            "ESCALATE_MODE_UNSPECIFIED" => Some(Self::Unspecified),
1021            "ESCALATE_MODE_DELIVER" => Some(Self::Deliver),
1022            "ESCALATE_MODE_ALERT_ONLY" => Some(Self::AlertOnly),
1023            _ => None,
1024        }
1025    }
1026}
1027// ─── Messages ───────────────────────────────────────────────────────────────
1028
1029/// A scoped API key for programmatic access (MCP agents, service integrations).
1030#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1031pub struct ApiKey {
1032    /// Unique identifier.
1033    #[prost(string, tag="1")]
1034    pub id: ::prost::alloc::string::String,
1035    /// Human-friendly label (e.g. "MCP Production", "CI Pipeline").
1036    #[prost(string, tag="2")]
1037    pub name: ::prost::alloc::string::String,
1038    /// Displayable prefix of the key (e.g. "pidgr_k_abc12345").
1039    /// Used for identification — the full key is only returned on creation.
1040    #[prost(string, tag="3")]
1041    pub key_prefix: ::prost::alloc::string::String,
1042    /// Permissions granted to this key.
1043    #[prost(enumeration="Permission", repeated, tag="4")]
1044    pub permissions: ::prost::alloc::vec::Vec<i32>,
1045    /// When the key was created.
1046    #[prost(message, optional, tag="5")]
1047    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1048    /// Last time the key was used to authenticate a request. Empty if never used.
1049    #[prost(message, optional, tag="6")]
1050    pub last_used_at: ::core::option::Option<::prost_types::Timestamp>,
1051    /// When the key expires. Empty means no expiration.
1052    #[prost(message, optional, tag="7")]
1053    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
1054    /// Type of this key (API key or SCIM token).
1055    /// Defaults to KEY_TYPE_API_KEY for existing keys.
1056    #[prost(enumeration="KeyType", tag="8")]
1057    pub key_type: i32,
1058}
1059/// Request to create a new API key.
1060#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1061pub struct CreateApiKeyRequest {
1062    /// Human-friendly label. Required, max 200 characters.
1063    #[prost(string, tag="1")]
1064    pub name: ::prost::alloc::string::String,
1065    /// Permissions to grant. Required, at least one.
1066    /// PERMISSION_UNSPECIFIED values are rejected.
1067    #[prost(enumeration="Permission", repeated, tag="2")]
1068    pub permissions: ::prost::alloc::vec::Vec<i32>,
1069    /// Optional expiration time. If omitted, the key does not expire.
1070    #[prost(message, optional, tag="3")]
1071    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
1072    /// Type of key to create. Defaults to KEY_TYPE_API_KEY.
1073    /// SCIM tokens use the "pidgr_scim_" prefix instead of "pidgr_k_".
1074    #[prost(enumeration="KeyType", tag="4")]
1075    pub key_type: i32,
1076}
1077/// Response after creating an API key.
1078/// IMPORTANT: The full key is only returned here — it cannot be retrieved later.
1079#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1080pub struct CreateApiKeyResponse {
1081    /// The created API key metadata.
1082    #[prost(message, optional, tag="1")]
1083    pub api_key: ::core::option::Option<ApiKey>,
1084    /// The full secret key value (e.g. "pidgr_k_abc12345...").
1085    /// Store this securely — it is not retrievable after this response.
1086    #[prost(string, tag="2")]
1087    pub key: ::prost::alloc::string::String,
1088}
1089/// Request to list all API keys in the caller's organization.
1090#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1091pub struct ListApiKeysRequest {
1092    /// Optional filter by key type. Unspecified returns all keys.
1093    #[prost(enumeration="KeyType", tag="1")]
1094    pub key_type: i32,
1095}
1096/// Response containing the organization's API keys.
1097#[derive(Clone, PartialEq, ::prost::Message)]
1098pub struct ListApiKeysResponse {
1099    /// All active (non-revoked) API keys. Full key values are not included.
1100    #[prost(message, repeated, tag="1")]
1101    pub api_keys: ::prost::alloc::vec::Vec<ApiKey>,
1102}
1103/// Request to revoke an API key.
1104#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1105pub struct RevokeApiKeyRequest {
1106    /// ID of the API key to revoke. Required.
1107    #[prost(string, tag="1")]
1108    pub api_key_id: ::prost::alloc::string::String,
1109}
1110/// Response after revoking an API key.
1111#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1112pub struct RevokeApiKeyResponse {
1113}
1114// ─── Enums ──────────────────────────────────────────────────────────────────
1115
1116/// Type of API key, distinguishing platform keys from SCIM provisioning tokens.
1117#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1118#[repr(i32)]
1119pub enum KeyType {
1120    Unspecified = 0,
1121    ApiKey = 1,
1122    ScimToken = 2,
1123}
1124impl KeyType {
1125    /// String value of the enum field names used in the ProtoBuf definition.
1126    ///
1127    /// The values are not transformed in any way and thus are considered stable
1128    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1129    pub fn as_str_name(&self) -> &'static str {
1130        match self {
1131            Self::Unspecified => "KEY_TYPE_UNSPECIFIED",
1132            Self::ApiKey => "KEY_TYPE_API_KEY",
1133            Self::ScimToken => "KEY_TYPE_SCIM_TOKEN",
1134        }
1135    }
1136    /// Creates an enum from field names used in the ProtoBuf definition.
1137    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1138        match value {
1139            "KEY_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
1140            "KEY_TYPE_API_KEY" => Some(Self::ApiKey),
1141            "KEY_TYPE_SCIM_TOKEN" => Some(Self::ScimToken),
1142            _ => None,
1143        }
1144    }
1145}
1146// ─── Messages ───────────────────────────────────────────────────────────────
1147
1148/// Request to export all personal data associated with a user.
1149/// Auth: Requires JWT. Callable by the user themselves or an org admin.
1150#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1151pub struct ExportUserDataRequest {
1152    /// Internal user ID whose data is being exported.
1153    /// Constraints: UUID format (36 characters).
1154    #[prost(string, tag="1")]
1155    pub user_id: ::prost::alloc::string::String,
1156}
1157/// Response containing the export status and download location.
1158#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1159pub struct ExportUserDataResponse {
1160    /// Current status of the export request.
1161    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1162    pub status: i32,
1163    /// Pre-signed S3 URL to download the exported data (ZIP format).
1164    /// Only populated when status is COMPLETED.
1165    #[prost(string, tag="2")]
1166    pub result_url: ::prost::alloc::string::String,
1167    /// Unique identifier for this export request.
1168    /// Constraints: UUID format (36 characters).
1169    #[prost(string, tag="3")]
1170    pub export_id: ::prost::alloc::string::String,
1171}
1172/// Request to export all data associated with the calling organization
1173/// (GDPR Art. 20 data portability at the org level). The organization is
1174/// extracted from the JWT — it is never in the request message.
1175/// Auth: Requires JWT. Org admin only.
1176#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1177pub struct ExportOrgDataRequest {
1178}
1179/// Response containing the org export status and download location.
1180/// The export workflow assembles org configuration, users, campaigns,
1181/// deliveries, and audit events into an encrypted bundle delivered via a
1182/// pre-signed S3 URL.
1183#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1184pub struct ExportOrgDataResponse {
1185    /// Current status of the export request.
1186    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1187    pub status: i32,
1188    /// Pre-signed S3 URL to download the exported bundle (encrypted ZIP).
1189    /// Only populated when status is COMPLETED.
1190    #[prost(string, tag="2")]
1191    pub result_url: ::prost::alloc::string::String,
1192    /// Unique identifier for this export request.
1193    /// Constraints: UUID format (36 characters).
1194    #[prost(string, tag="3")]
1195    pub export_id: ::prost::alloc::string::String,
1196}
1197/// Request to delete or anonymize all personal data associated with a user.
1198/// Auth: Requires JWT. Admin only.
1199#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1200pub struct DeleteUserDataRequest {
1201    /// Internal user ID whose data is being deleted.
1202    /// Constraints: UUID format (36 characters).
1203    #[prost(string, tag="1")]
1204    pub user_id: ::prost::alloc::string::String,
1205    /// When true, PII is replaced with placeholders instead of hard-deleted.
1206    /// This preserves audit trail integrity while removing personal data.
1207    #[prost(bool, tag="2")]
1208    pub anonymize: bool,
1209}
1210/// Response confirming the deletion request.
1211#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1212pub struct DeleteUserDataResponse {
1213    /// Current status of the deletion request.
1214    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1215    pub status: i32,
1216    /// Timestamp when deletion was completed (or scheduled).
1217    /// Only populated when status is COMPLETED.
1218    #[prost(message, optional, tag="2")]
1219    pub deleted_at: ::core::option::Option<::prost_types::Timestamp>,
1220    /// Unique identifier for this deletion request.
1221    #[prost(string, tag="3")]
1222    pub request_id: ::prost::alloc::string::String,
1223}
1224/// Request to list privacy requests for the organization.
1225/// Auth: Requires JWT. Admin only.
1226#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1227pub struct ListPrivacyRequestsRequest {
1228    /// Maximum number of results per page.
1229    /// Constraints: 1–100, default 25.
1230    #[prost(int32, tag="1")]
1231    pub page_size: i32,
1232    /// Continuation token from a previous response.
1233    #[prost(string, tag="2")]
1234    pub page_token: ::prost::alloc::string::String,
1235    /// Filter by request type (export, delete, rectify, restrict). Empty = all.
1236    #[prost(string, tag="3")]
1237    pub request_type: ::prost::alloc::string::String,
1238    /// Filter by status. UNSPECIFIED = all.
1239    #[prost(enumeration="PrivacyRequestStatus", tag="4")]
1240    pub status: i32,
1241}
1242/// Response containing privacy requests.
1243#[derive(Clone, PartialEq, ::prost::Message)]
1244pub struct ListPrivacyRequestsResponse {
1245    /// The privacy requests matching the filters.
1246    #[prost(message, repeated, tag="1")]
1247    pub requests: ::prost::alloc::vec::Vec<PrivacyRequest>,
1248    /// Token for the next page. Empty if no more results.
1249    #[prost(string, tag="2")]
1250    pub next_page_token: ::prost::alloc::string::String,
1251}
1252/// A privacy request record.
1253#[derive(Clone, PartialEq, ::prost::Message)]
1254pub struct PrivacyRequest {
1255    /// Unique identifier.
1256    #[prost(string, tag="1")]
1257    pub id: ::prost::alloc::string::String,
1258    /// The user this request applies to.
1259    #[prost(string, tag="2")]
1260    pub user_id: ::prost::alloc::string::String,
1261    /// Email of the target user.
1262    #[prost(string, tag="3")]
1263    pub user_email: ::prost::alloc::string::String,
1264    /// Type of request (export, delete, rectify, restrict).
1265    #[prost(string, tag="4")]
1266    pub request_type: ::prost::alloc::string::String,
1267    /// Current status.
1268    #[prost(enumeration="PrivacyRequestStatus", tag="5")]
1269    pub status: i32,
1270    /// Whether to anonymize (true) or hard-delete (false). Only for delete requests.
1271    #[prost(bool, tag="6")]
1272    pub anonymize: bool,
1273    /// Email of the admin who initiated this request.
1274    #[prost(string, tag="7")]
1275    pub requested_by_email: ::prost::alloc::string::String,
1276    /// When the request was created.
1277    #[prost(message, optional, tag="8")]
1278    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1279    /// When the request was completed (if applicable).
1280    #[prost(message, optional, tag="9")]
1281    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1282    /// Additional metadata (JSON).
1283    #[prost(map="string, string", tag="10")]
1284    pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1285}
1286/// Request to cancel a pending deletion.
1287/// Auth: Requires JWT. Admin only.
1288#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1289pub struct CancelDeletionRequest {
1290    /// The privacy request ID to cancel.
1291    #[prost(string, tag="1")]
1292    pub request_id: ::prost::alloc::string::String,
1293    /// Admin must type the target user's email to confirm.
1294    #[prost(string, tag="2")]
1295    pub confirmation_email: ::prost::alloc::string::String,
1296}
1297/// Response confirming the cancellation.
1298#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1299pub struct CancelDeletionResponse {
1300    /// Updated status (should be FAILED with reason cancelled).
1301    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1302    pub status: i32,
1303}
1304/// Request to skip the grace period and delete immediately.
1305/// Auth: Requires JWT. Admin only.
1306#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1307pub struct ImmediateDeleteRequest {
1308    /// The privacy request ID to expedite.
1309    #[prost(string, tag="1")]
1310    pub request_id: ::prost::alloc::string::String,
1311    /// Admin must type the target user's email to confirm.
1312    #[prost(string, tag="2")]
1313    pub confirmation_email: ::prost::alloc::string::String,
1314}
1315/// Response confirming the immediate deletion was triggered.
1316#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1317pub struct ImmediateDeleteResponse {
1318    /// Updated status (should be PROCESSING).
1319    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1320    pub status: i32,
1321}
1322/// Request to correct personal data for a user.
1323/// Auth: Requires JWT. Callable by the user themselves or an org admin.
1324#[derive(Clone, PartialEq, ::prost::Message)]
1325pub struct RectifyUserDataRequest {
1326    /// Internal user ID whose data is being corrected.
1327    /// Constraints: UUID format (36 characters).
1328    #[prost(string, tag="1")]
1329    pub user_id: ::prost::alloc::string::String,
1330    /// Map of field names to corrected values.
1331    /// Corrections are propagated to all stored locations.
1332    /// Constraints: Max 50 corrections per request.
1333    #[prost(map="string, string", tag="2")]
1334    pub corrections: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1335}
1336/// Response listing which fields were successfully corrected.
1337#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1338pub struct RectifyUserDataResponse {
1339    /// Names of fields that were rectified.
1340    #[prost(string, repeated, tag="1")]
1341    pub rectified_fields: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1342}
1343/// Request to restrict or unrestrict processing for a user.
1344/// Auth: Requires JWT. Admin only.
1345#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1346pub struct RestrictProcessingRequest {
1347    /// Internal user ID whose processing is being restricted.
1348    /// Constraints: UUID format (36 characters).
1349    #[prost(string, tag="1")]
1350    pub user_id: ::prost::alloc::string::String,
1351    /// When true, processing is restricted. When false, restriction is lifted.
1352    #[prost(bool, tag="2")]
1353    pub restricted: bool,
1354}
1355/// Response confirming the processing restriction status.
1356#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1357pub struct RestrictProcessingResponse {
1358    /// Current restriction status.
1359    #[prost(bool, tag="1")]
1360    pub restricted: bool,
1361    /// Timestamp when the restriction was applied or removed.
1362    #[prost(message, optional, tag="2")]
1363    pub restricted_at: ::core::option::Option<::prost_types::Timestamp>,
1364}
1365/// Request to confirm whether personal data exists for a user.
1366/// LGPD-specific: confirmação de existência (Art. 18, I).
1367/// Auth: Requires JWT. Admin only.
1368#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1369pub struct GetDataExistenceConfirmationRequest {
1370    /// Internal user ID to check.
1371    /// Constraints: UUID format (36 characters).
1372    #[prost(string, tag="1")]
1373    pub user_id: ::prost::alloc::string::String,
1374}
1375/// Response confirming data existence and listing data categories.
1376#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1377pub struct GetDataExistenceConfirmationResponse {
1378    /// Whether any personal data exists for this user.
1379    #[prost(bool, tag="1")]
1380    pub exists: bool,
1381    /// Categories of data stored (e.g., "profile", "deliveries", "analytics").
1382    #[prost(string, repeated, tag="2")]
1383    pub data_categories: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1384}
1385/// Request to list the calling user's own privacy requests.
1386/// Auth: Requires JWT. No admin permission required — returns only the caller's requests.
1387#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1388pub struct ListMyPrivacyRequestsRequest {
1389    /// Maximum number of results per page.
1390    /// Constraints: 1–100, default 25.
1391    #[prost(int32, tag="1")]
1392    pub page_size: i32,
1393    /// Continuation token from a previous response.
1394    #[prost(string, tag="2")]
1395    pub page_token: ::prost::alloc::string::String,
1396    /// Filter by request type (export, rectify). Empty = all.
1397    #[prost(string, tag="3")]
1398    pub request_type: ::prost::alloc::string::String,
1399    /// Filter by status. UNSPECIFIED = all.
1400    #[prost(enumeration="PrivacyRequestStatus", tag="4")]
1401    pub status: i32,
1402}
1403/// Response containing the calling user's privacy requests.
1404#[derive(Clone, PartialEq, ::prost::Message)]
1405pub struct ListMyPrivacyRequestsResponse {
1406    /// The privacy requests belonging to the calling user.
1407    #[prost(message, repeated, tag="1")]
1408    pub requests: ::prost::alloc::vec::Vec<PrivacyRequest>,
1409    /// Token for the next page. Empty if no more results.
1410    #[prost(string, tag="2")]
1411    pub next_page_token: ::prost::alloc::string::String,
1412}
1413/// A security incident that touched the calling organization. Org-facing
1414/// read-only subset of the staff-side incident record — internal triage
1415/// fields (detector signal, classifier identity, evidence pointers) are
1416/// intentionally not exposed.
1417#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1418pub struct OrgSecurityIncident {
1419    /// Unique identifier for the incident.
1420    /// Constraints: UUID format (36 characters).
1421    #[prost(string, tag="1")]
1422    pub id: ::prost::alloc::string::String,
1423    /// When the observability platform detected the incident. The canonical
1424    /// anchor for the 72-hour GDPR Art. 33 notification clock.
1425    #[prost(message, optional, tag="2")]
1426    pub detected_at: ::core::option::Option<::prost_types::Timestamp>,
1427    /// Detector-assigned severity.
1428    #[prost(enumeration="SecurityIncidentSeverity", tag="3")]
1429    pub severity: i32,
1430    /// Legal classification verdict. PENDING until staff triage completes.
1431    #[prost(enumeration="SecurityIncidentClassification", tag="4")]
1432    pub classification: i32,
1433    /// When the regulator was notified. Empty if no notification was required
1434    /// or it has not happened yet.
1435    #[prost(message, optional, tag="5")]
1436    pub notified_at: ::core::option::Option<::prost_types::Timestamp>,
1437    /// When the incident was resolved. Empty while still open.
1438    #[prost(message, optional, tag="6")]
1439    pub resolved_at: ::core::option::Option<::prost_types::Timestamp>,
1440}
1441/// Request to list security incidents that touched the calling organization.
1442/// The organization is extracted from the JWT — it is never in the request.
1443/// Auth: Requires JWT. Admin only.
1444#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1445pub struct ListOrgSecurityIncidentsRequest {
1446    /// Maximum number of results per page.
1447    /// Constraints: 1–100, default 25.
1448    #[prost(int32, tag="1")]
1449    pub page_size: i32,
1450    /// Continuation token from a previous response.
1451    #[prost(string, tag="2")]
1452    pub page_token: ::prost::alloc::string::String,
1453}
1454/// Response containing the organization's security incident feed.
1455#[derive(Clone, PartialEq, ::prost::Message)]
1456pub struct ListOrgSecurityIncidentsResponse {
1457    /// Incidents that touched the organization, ordered by detected_at
1458    /// descending (newest first).
1459    #[prost(message, repeated, tag="1")]
1460    pub incidents: ::prost::alloc::vec::Vec<OrgSecurityIncident>,
1461    /// Token for the next page. Empty if no more results.
1462    #[prost(string, tag="2")]
1463    pub next_page_token: ::prost::alloc::string::String,
1464}
1465// ─── Enums ──────────────────────────────────────────────────────────────────
1466
1467/// Status of a privacy request (export, delete, rectify, restrict).
1468#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1469#[repr(i32)]
1470pub enum PrivacyRequestStatus {
1471    /// Default value; should not be used explicitly.
1472    Unspecified = 0,
1473    /// Request has been created but not yet started.
1474    Pending = 1,
1475    /// Request is currently being processed.
1476    Processing = 2,
1477    /// Request completed successfully.
1478    Completed = 3,
1479    /// Request failed during processing.
1480    Failed = 4,
1481}
1482impl PrivacyRequestStatus {
1483    /// String value of the enum field names used in the ProtoBuf definition.
1484    ///
1485    /// The values are not transformed in any way and thus are considered stable
1486    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1487    pub fn as_str_name(&self) -> &'static str {
1488        match self {
1489            Self::Unspecified => "PRIVACY_REQUEST_STATUS_UNSPECIFIED",
1490            Self::Pending => "PRIVACY_REQUEST_STATUS_PENDING",
1491            Self::Processing => "PRIVACY_REQUEST_STATUS_PROCESSING",
1492            Self::Completed => "PRIVACY_REQUEST_STATUS_COMPLETED",
1493            Self::Failed => "PRIVACY_REQUEST_STATUS_FAILED",
1494        }
1495    }
1496    /// Creates an enum from field names used in the ProtoBuf definition.
1497    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1498        match value {
1499            "PRIVACY_REQUEST_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
1500            "PRIVACY_REQUEST_STATUS_PENDING" => Some(Self::Pending),
1501            "PRIVACY_REQUEST_STATUS_PROCESSING" => Some(Self::Processing),
1502            "PRIVACY_REQUEST_STATUS_COMPLETED" => Some(Self::Completed),
1503            "PRIVACY_REQUEST_STATUS_FAILED" => Some(Self::Failed),
1504            _ => None,
1505        }
1506    }
1507}
1508/// Detector-assigned severity of a security incident. Mirrors the staff-side
1509/// incident taxonomy; the org feed exposes the same values read-only.
1510#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1511#[repr(i32)]
1512pub enum SecurityIncidentSeverity {
1513    /// Default value; should not be used explicitly.
1514    Unspecified = 0,
1515    /// Informational signal; no action expected.
1516    Info = 1,
1517    /// Anomalous signal under investigation.
1518    Warn = 2,
1519    /// Confirmed or suspected breach-grade signal.
1520    Breach = 3,
1521}
1522impl SecurityIncidentSeverity {
1523    /// String value of the enum field names used in the ProtoBuf definition.
1524    ///
1525    /// The values are not transformed in any way and thus are considered stable
1526    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1527    pub fn as_str_name(&self) -> &'static str {
1528        match self {
1529            Self::Unspecified => "SECURITY_INCIDENT_SEVERITY_UNSPECIFIED",
1530            Self::Info => "SECURITY_INCIDENT_SEVERITY_INFO",
1531            Self::Warn => "SECURITY_INCIDENT_SEVERITY_WARN",
1532            Self::Breach => "SECURITY_INCIDENT_SEVERITY_BREACH",
1533        }
1534    }
1535    /// Creates an enum from field names used in the ProtoBuf definition.
1536    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1537        match value {
1538            "SECURITY_INCIDENT_SEVERITY_UNSPECIFIED" => Some(Self::Unspecified),
1539            "SECURITY_INCIDENT_SEVERITY_INFO" => Some(Self::Info),
1540            "SECURITY_INCIDENT_SEVERITY_WARN" => Some(Self::Warn),
1541            "SECURITY_INCIDENT_SEVERITY_BREACH" => Some(Self::Breach),
1542            _ => None,
1543        }
1544    }
1545}
1546/// Legal classification verdict recorded by platform staff during triage.
1547/// Mirrors the staff-side incident taxonomy; immutable once set.
1548#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1549#[repr(i32)]
1550pub enum SecurityIncidentClassification {
1551    /// Default value; should not be used explicitly.
1552    Unspecified = 0,
1553    /// Queued for triage; no verdict recorded yet.
1554    Pending = 1,
1555    /// Triage concluded the incident is not a breach.
1556    NotBreach = 2,
1557    /// Operational incident with no personal data involved.
1558    OperationalOnly = 10,
1559    /// Personal data breach (GDPR Art. 33 notification clock running).
1560    PersonalDataBreach = 11,
1561    /// Personal data breach with high risk to data subjects (GDPR Art. 34).
1562    PersonalDataBreachHighRisk = 12,
1563}
1564impl SecurityIncidentClassification {
1565    /// String value of the enum field names used in the ProtoBuf definition.
1566    ///
1567    /// The values are not transformed in any way and thus are considered stable
1568    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1569    pub fn as_str_name(&self) -> &'static str {
1570        match self {
1571            Self::Unspecified => "SECURITY_INCIDENT_CLASSIFICATION_UNSPECIFIED",
1572            Self::Pending => "SECURITY_INCIDENT_CLASSIFICATION_PENDING",
1573            Self::NotBreach => "SECURITY_INCIDENT_CLASSIFICATION_NOT_BREACH",
1574            Self::OperationalOnly => "SECURITY_INCIDENT_CLASSIFICATION_OPERATIONAL_ONLY",
1575            Self::PersonalDataBreach => "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH",
1576            Self::PersonalDataBreachHighRisk => "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH_HIGH_RISK",
1577        }
1578    }
1579    /// Creates an enum from field names used in the ProtoBuf definition.
1580    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1581        match value {
1582            "SECURITY_INCIDENT_CLASSIFICATION_UNSPECIFIED" => Some(Self::Unspecified),
1583            "SECURITY_INCIDENT_CLASSIFICATION_PENDING" => Some(Self::Pending),
1584            "SECURITY_INCIDENT_CLASSIFICATION_NOT_BREACH" => Some(Self::NotBreach),
1585            "SECURITY_INCIDENT_CLASSIFICATION_OPERATIONAL_ONLY" => Some(Self::OperationalOnly),
1586            "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH" => Some(Self::PersonalDataBreach),
1587            "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH_HIGH_RISK" => Some(Self::PersonalDataBreachHighRisk),
1588            _ => None,
1589        }
1590    }
1591}
1592// ─── Messages ───────────────────────────────────────────────────────────────
1593
1594/// An immutable audit event capturing a significant platform action.
1595/// Audit events are append-only — they cannot be updated or deleted.
1596#[derive(Clone, PartialEq, ::prost::Message)]
1597pub struct AuditEvent {
1598    /// Unique identifier for this audit event.
1599    /// Constraints: UUID format (36 characters).
1600    #[prost(string, tag="1")]
1601    pub id: ::prost::alloc::string::String,
1602    /// Organization in which the event occurred.
1603    /// Constraints: UUID format (36 characters).
1604    #[prost(string, tag="2")]
1605    pub org_id: ::prost::alloc::string::String,
1606    /// User who performed the action. Empty for system-initiated events.
1607    /// Constraints: UUID format (36 characters) when present.
1608    #[prost(string, tag="3")]
1609    pub actor_id: ::prost::alloc::string::String,
1610    /// Type of action that was performed.
1611    #[prost(enumeration="AuditEventType", tag="4")]
1612    pub event_type: i32,
1613    /// Type of entity affected (e.g., "campaign", "user", "template").
1614    /// Constraints: Max length 50 characters.
1615    #[prost(string, tag="5")]
1616    pub entity_type: ::prost::alloc::string::String,
1617    /// Identifier of the entity affected.
1618    /// Constraints: UUID format (36 characters).
1619    #[prost(string, tag="6")]
1620    pub entity_id: ::prost::alloc::string::String,
1621    /// Additional context about the event (e.g., old/new values for changes).
1622    /// Constraints: Max 20 key-value pairs, keys max 50 chars, values max 500 chars.
1623    #[prost(map="string, string", tag="7")]
1624    pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1625    /// True when this event is synthetic (artificially injected) data — used for
1626    /// demos, sandbox testing, or issue reproduction — rather than the record of
1627    /// a real user action.
1628    #[prost(bool, tag="8")]
1629    pub synthetic: bool,
1630    /// Classification of this event: MANAGEMENT for principal-initiated actions
1631    /// on the organization's configuration or operation, SYSTEM for high-volume
1632    /// data-plane events emitted during processing. The server derives the class
1633    /// from the event type, so events are never unclassified.
1634    #[prost(enumeration="AuditEventClass", tag="11")]
1635    pub event_class: i32,
1636    /// Timestamp when the event was recorded.
1637    #[prost(message, optional, tag="10")]
1638    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1639}
1640/// Request to list audit events with optional filters.
1641/// Auth: Requires JWT. Admin only.
1642#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1643pub struct ListAuditEventsRequest {
1644    /// Pagination token from a previous response.
1645    #[prost(string, tag="1")]
1646    pub page_token: ::prost::alloc::string::String,
1647    /// Maximum number of events to return.
1648    /// Constraints: Min 1, max 100. Default 50.
1649    #[prost(int32, tag="2")]
1650    pub page_size: i32,
1651    /// Optional filter: only return events of this type.
1652    #[prost(enumeration="AuditEventType", tag="3")]
1653    pub event_type: i32,
1654    /// Optional filter: only return events by this actor.
1655    /// Constraints: UUID format (36 characters).
1656    #[prost(string, tag="4")]
1657    pub actor_id: ::prost::alloc::string::String,
1658    /// Optional filter: events after this timestamp (inclusive).
1659    #[prost(message, optional, tag="5")]
1660    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
1661    /// Optional filter: events before this timestamp (exclusive).
1662    #[prost(message, optional, tag="6")]
1663    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
1664    /// Optional filter: only return events in these classes.
1665    /// Empty means no filtering — events of all classes are returned. Because
1666    /// classification is derived from the event type, a non-empty filter also
1667    /// covers events recorded before classification existed.
1668    #[prost(enumeration="AuditEventClass", repeated, tag="7")]
1669    pub event_classes: ::prost::alloc::vec::Vec<i32>,
1670}
1671/// Response containing a paginated list of audit events.
1672#[derive(Clone, PartialEq, ::prost::Message)]
1673pub struct ListAuditEventsResponse {
1674    /// Audit events matching the request filters.
1675    #[prost(message, repeated, tag="1")]
1676    pub events: ::prost::alloc::vec::Vec<AuditEvent>,
1677    /// Token for fetching the next page. Empty when no more events.
1678    #[prost(string, tag="2")]
1679    pub next_page_token: ::prost::alloc::string::String,
1680}
1681/// Request to export the audit trail to S3 in a specified format.
1682/// Auth: Requires JWT. Admin only.
1683#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1684pub struct ExportAuditTrailRequest {
1685    /// Export format.
1686    #[prost(enumeration="AuditExportFormat", tag="1")]
1687    pub format: i32,
1688    /// Optional: export events after this timestamp.
1689    #[prost(message, optional, tag="2")]
1690    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
1691    /// Optional: export events before this timestamp.
1692    #[prost(message, optional, tag="3")]
1693    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
1694}
1695/// Response containing the export download URL.
1696#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1697pub struct ExportAuditTrailResponse {
1698    /// Pre-signed S3 URL to download the exported audit trail.
1699    /// Only populated when status is COMPLETED.
1700    #[prost(string, tag="1")]
1701    pub export_url: ::prost::alloc::string::String,
1702    /// Current status of the export request.
1703    #[prost(enumeration="PrivacyRequestStatus", tag="2")]
1704    pub status: i32,
1705}
1706/// A persistent record of an audit trail export request.
1707#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1708pub struct AuditExport {
1709    /// Unique identifier.
1710    #[prost(string, tag="1")]
1711    pub id: ::prost::alloc::string::String,
1712    /// Export format (csv, json).
1713    #[prost(string, tag="2")]
1714    pub format: ::prost::alloc::string::String,
1715    /// Current status.
1716    #[prost(enumeration="PrivacyRequestStatus", tag="3")]
1717    pub status: i32,
1718    /// Pre-signed download URL. Only populated when status is COMPLETED.
1719    #[prost(string, tag="4")]
1720    pub result_url: ::prost::alloc::string::String,
1721    /// Error message if the export failed.
1722    #[prost(string, tag="5")]
1723    pub error_message: ::prost::alloc::string::String,
1724    /// Email of the admin who requested the export.
1725    #[prost(string, tag="6")]
1726    pub requested_by_email: ::prost::alloc::string::String,
1727    /// When the export was requested.
1728    #[prost(message, optional, tag="7")]
1729    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1730    /// When the export completed (if applicable).
1731    #[prost(message, optional, tag="8")]
1732    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1733}
1734/// Request to list audit export history.
1735/// Auth: Requires JWT. Admin only.
1736#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1737pub struct ListAuditExportsRequest {
1738}
1739/// Response containing the list of audit exports.
1740#[derive(Clone, PartialEq, ::prost::Message)]
1741pub struct ListAuditExportsResponse {
1742    /// Audit export records, newest first.
1743    #[prost(message, repeated, tag="1")]
1744    pub exports: ::prost::alloc::vec::Vec<AuditExport>,
1745}
1746/// Request to append a single audit event from an internal service.
1747///
1748/// Auth: INTERNAL-mTLS ONLY. Unlike the read-side RPCs which authenticate
1749/// via Cognito JWT and infer `org_id` from the caller's claim, this RPC is
1750/// invoked by sibling services (e.g. pidgr-integrations) over the internal
1751/// mTLS mesh and therefore carries `org_id` in the request payload. The
1752/// server MUST reject any caller presenting only a JWT.
1753#[derive(Clone, PartialEq, ::prost::Message)]
1754pub struct AppendRequest {
1755    /// String form of the event type. Sibling services use a stable string
1756    /// identifier (e.g. "REACHABILITY_UPSERT", "REACHABILITY_REMOVE") so a
1757    /// new event type does not require a coordinated proto release across
1758    /// every internal service before it can be recorded. The audit server
1759    /// is responsible for mapping the string into its internal taxonomy.
1760    #[prost(string, tag="1")]
1761    pub event_type: ::prost::alloc::string::String,
1762    /// Organization in which the event occurred. UUID.
1763    #[prost(string, tag="2")]
1764    pub org_id: ::prost::alloc::string::String,
1765    /// User the audit event is about, if applicable. UUID. Unset when the
1766    /// event is not subject-bound (e.g. an org-wide policy change).
1767    #[prost(string, optional, tag="3")]
1768    pub subject_user_id: ::core::option::Option<::prost::alloc::string::String>,
1769    /// Actor who initiated the action, if any. UUID. Unset for system-initiated
1770    /// or sibling-service-initiated events.
1771    #[prost(string, optional, tag="4")]
1772    pub actor_id: ::core::option::Option<::prost::alloc::string::String>,
1773    /// Structured event-specific payload. Used in lieu of the rigid
1774    /// `map<string, string> metadata` on `AuditEvent` so sibling services
1775    /// can record nested objects (e.g. a `prefetch_signals` block) without
1776    /// string-encoding every value. Servers SHOULD redact PII before persist
1777    /// and MUST NOT log this field at INFO or above. Sensitive cryptographic
1778    /// material (plaintext identifiers, envelope ciphertext, raw HMAC keys)
1779    /// MUST NOT be placed here.
1780    #[prost(message, optional, tag="5")]
1781    pub details: ::core::option::Option<::prost_types::Struct>,
1782}
1783#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1784pub struct AppendResponse {
1785    /// Server-assigned audit event identifier (UUID).
1786    #[prost(string, tag="1")]
1787    pub event_id: ::prost::alloc::string::String,
1788}
1789// ─── Enums ──────────────────────────────────────────────────────────────────
1790
1791/// Type of auditable platform action.
1792#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1793#[repr(i32)]
1794pub enum AuditEventType {
1795    /// Default value; should not be used explicitly.
1796    Unspecified = 0,
1797    /// ── Campaign lifecycle ───────────────────────────────────────────────────
1798    /// A campaign was created.
1799    CampaignCreated = 1,
1800    /// A message was sent to a recipient.
1801    MessageSent = 2,
1802    /// A message was opened by a recipient.
1803    MessageOpened = 3,
1804    /// A recipient acknowledged a campaign.
1805    AckRegistered = 4,
1806    /// An escalation was triggered by the workflow.
1807    EscalationExecuted = 5,
1808    /// A campaign was started.
1809    CampaignStarted = 12,
1810    /// A campaign was cancelled.
1811    CampaignCancelled = 13,
1812    /// A campaign was updated.
1813    CampaignUpdated = 14,
1814    /// ── User lifecycle ───────────────────────────────────────────────────────
1815    /// A user was invited to the organization.
1816    UserInvited = 6,
1817    /// A user was deactivated.
1818    UserDeactivated = 7,
1819    /// A user was reactivated.
1820    UserReactivated = 15,
1821    /// A user's role was changed (assigned to a different role).
1822    RoleChanged = 10,
1823    /// A user's invite was revoked.
1824    InviteRevoked = 16,
1825    /// A user's profile was updated.
1826    ProfileUpdated = 17,
1827    /// A user's settings were updated.
1828    SettingsUpdated = 18,
1829    /// A user enrolled a passkey.
1830    PasskeyEnrolled = 19,
1831    /// ── GDPR / Privacy ──────────────────────────────────────────────────────
1832    /// A data export was requested (GDPR Art. 15).
1833    DataExportRequested = 8,
1834    /// A data deletion was requested (GDPR Art. 17).
1835    DataDeletionRequested = 9,
1836    /// User data was rectified (GDPR Art. 16).
1837    DataRectified = 20,
1838    /// Data processing was restricted (GDPR Art. 18).
1839    ProcessingRestricted = 21,
1840    /// A scheduled deletion was cancelled.
1841    DeletionCancelled = 22,
1842    /// An immediate deletion was executed.
1843    DeletionImmediate = 23,
1844    /// ── Organization / SSO ───────────────────────────────────────────────────
1845    /// An SSO provider was configured.
1846    SsoConfigured = 11,
1847    /// An SSO provider was created.
1848    SsoProviderCreated = 24,
1849    /// An SSO provider was deleted.
1850    SsoProviderDeleted = 25,
1851    /// Organization settings were updated.
1852    OrgUpdated = 26,
1853    /// ── Roles ────────────────────────────────────────────────────────────────
1854    /// A role was created.
1855    RoleCreated = 27,
1856    /// A role's name or permissions were updated.
1857    RoleUpdated = 28,
1858    /// A role was deleted.
1859    RoleDeleted = 29,
1860    /// ── Templates ────────────────────────────────────────────────────────────
1861    /// A template was created.
1862    TemplateCreated = 30,
1863    /// A template was updated.
1864    TemplateUpdated = 31,
1865    /// ── API Keys ─────────────────────────────────────────────────────────────
1866    /// An API key was created.
1867    ApiKeyCreated = 32,
1868    /// An API key was revoked.
1869    ApiKeyRevoked = 33,
1870    /// ── Invite Links ─────────────────────────────────────────────────────────
1871    /// An invite link was created.
1872    InviteLinkCreated = 34,
1873    /// An invite link was revoked.
1874    InviteLinkRevoked = 35,
1875    /// ── Groups ───────────────────────────────────────────────────────────────
1876    /// A group was created.
1877    GroupCreated = 36,
1878    /// A group was updated.
1879    GroupUpdated = 37,
1880    /// A group was deleted.
1881    GroupDeleted = 38,
1882    /// Members were added to a group.
1883    GroupMembersAdded = 39,
1884    /// Members were removed from a group.
1885    GroupMembersRemoved = 40,
1886    /// ── Teams ────────────────────────────────────────────────────────────────
1887    /// A team was created.
1888    TeamCreated = 41,
1889    /// A team was updated.
1890    TeamUpdated = 42,
1891    /// A team was deleted.
1892    TeamDeleted = 43,
1893    /// Members were added to a team.
1894    TeamMembersAdded = 44,
1895    /// Members were removed from a team.
1896    TeamMembersRemoved = 45,
1897    /// ── SCIM Provisioning ───────────────────────────────────────────────────
1898    /// A user was provisioned via SCIM.
1899    ScimUserProvisioned = 46,
1900    /// A user was deprovisioned via SCIM.
1901    ScimUserDeprovisioned = 47,
1902    /// A user was updated via SCIM.
1903    ScimUserUpdated = 48,
1904    /// ── Translations ────────────────────────────────────────────────────────
1905    /// A template translation was created.
1906    TranslationCreated = 49,
1907    /// A template translation was approved.
1908    TranslationApproved = 50,
1909    /// ── Sandbox Orgs ────────────────────────────────────────────────────────
1910    /// A sandbox organization was created.
1911    SandboxCreated = 51,
1912    /// A sandbox organization expired and was deleted.
1913    SandboxExpired = 52,
1914    /// ── AI/Insights ─────────────────────────────────────────────────────────
1915    /// An AI prediction was served and logged (EU AI Act Art. 12).
1916    AiPredictionLogged = 53,
1917    /// The ML pipeline (archetype clustering + enrichment) was manually triggered.
1918    MlPipelineTriggered = 54,
1919    /// Per-group archetype clustering was manually triggered.
1920    ArchetypeClusteringTriggered = 55,
1921    /// ── Org lifecycle ───────────────────────────────────────────────────────
1922    /// An organization was created.
1923    OrgCreated = 56,
1924    /// An organization was deleted (sandbox cleanup or manual deletion).
1925    OrgDeleted = 57,
1926    /// ── Reachability registry (pidgr-integrations) ──────────────────────────
1927    /// A reachability identifier (email, phone, Slack ID, etc.) was upserted.
1928    /// GDPR-relevant per Chikorita audit classification.
1929    ReachabilityUpsert = 58,
1930    /// A reachability identifier was removed. GDPR Art. 17 "right to erasure"
1931    /// event; written BEFORE the registry row is deleted per Recital 30.
1932    ReachabilityRemove = 59,
1933    /// ── KMS envelope encryption ─────────────────────────────────────────────
1934    /// A payload was envelope-encrypted with a KMS-managed key.
1935    KmsEncrypt = 60,
1936    /// A payload was decrypted with a KMS-managed key.
1937    KmsDecrypt = 61,
1938}
1939impl AuditEventType {
1940    /// String value of the enum field names used in the ProtoBuf definition.
1941    ///
1942    /// The values are not transformed in any way and thus are considered stable
1943    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1944    pub fn as_str_name(&self) -> &'static str {
1945        match self {
1946            Self::Unspecified => "AUDIT_EVENT_TYPE_UNSPECIFIED",
1947            Self::CampaignCreated => "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED",
1948            Self::MessageSent => "AUDIT_EVENT_TYPE_MESSAGE_SENT",
1949            Self::MessageOpened => "AUDIT_EVENT_TYPE_MESSAGE_OPENED",
1950            Self::AckRegistered => "AUDIT_EVENT_TYPE_ACK_REGISTERED",
1951            Self::EscalationExecuted => "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED",
1952            Self::CampaignStarted => "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED",
1953            Self::CampaignCancelled => "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED",
1954            Self::CampaignUpdated => "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED",
1955            Self::UserInvited => "AUDIT_EVENT_TYPE_USER_INVITED",
1956            Self::UserDeactivated => "AUDIT_EVENT_TYPE_USER_DEACTIVATED",
1957            Self::UserReactivated => "AUDIT_EVENT_TYPE_USER_REACTIVATED",
1958            Self::RoleChanged => "AUDIT_EVENT_TYPE_ROLE_CHANGED",
1959            Self::InviteRevoked => "AUDIT_EVENT_TYPE_INVITE_REVOKED",
1960            Self::ProfileUpdated => "AUDIT_EVENT_TYPE_PROFILE_UPDATED",
1961            Self::SettingsUpdated => "AUDIT_EVENT_TYPE_SETTINGS_UPDATED",
1962            Self::PasskeyEnrolled => "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED",
1963            Self::DataExportRequested => "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED",
1964            Self::DataDeletionRequested => "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED",
1965            Self::DataRectified => "AUDIT_EVENT_TYPE_DATA_RECTIFIED",
1966            Self::ProcessingRestricted => "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED",
1967            Self::DeletionCancelled => "AUDIT_EVENT_TYPE_DELETION_CANCELLED",
1968            Self::DeletionImmediate => "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE",
1969            Self::SsoConfigured => "AUDIT_EVENT_TYPE_SSO_CONFIGURED",
1970            Self::SsoProviderCreated => "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED",
1971            Self::SsoProviderDeleted => "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED",
1972            Self::OrgUpdated => "AUDIT_EVENT_TYPE_ORG_UPDATED",
1973            Self::RoleCreated => "AUDIT_EVENT_TYPE_ROLE_CREATED",
1974            Self::RoleUpdated => "AUDIT_EVENT_TYPE_ROLE_UPDATED",
1975            Self::RoleDeleted => "AUDIT_EVENT_TYPE_ROLE_DELETED",
1976            Self::TemplateCreated => "AUDIT_EVENT_TYPE_TEMPLATE_CREATED",
1977            Self::TemplateUpdated => "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED",
1978            Self::ApiKeyCreated => "AUDIT_EVENT_TYPE_API_KEY_CREATED",
1979            Self::ApiKeyRevoked => "AUDIT_EVENT_TYPE_API_KEY_REVOKED",
1980            Self::InviteLinkCreated => "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED",
1981            Self::InviteLinkRevoked => "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED",
1982            Self::GroupCreated => "AUDIT_EVENT_TYPE_GROUP_CREATED",
1983            Self::GroupUpdated => "AUDIT_EVENT_TYPE_GROUP_UPDATED",
1984            Self::GroupDeleted => "AUDIT_EVENT_TYPE_GROUP_DELETED",
1985            Self::GroupMembersAdded => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED",
1986            Self::GroupMembersRemoved => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED",
1987            Self::TeamCreated => "AUDIT_EVENT_TYPE_TEAM_CREATED",
1988            Self::TeamUpdated => "AUDIT_EVENT_TYPE_TEAM_UPDATED",
1989            Self::TeamDeleted => "AUDIT_EVENT_TYPE_TEAM_DELETED",
1990            Self::TeamMembersAdded => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED",
1991            Self::TeamMembersRemoved => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED",
1992            Self::ScimUserProvisioned => "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED",
1993            Self::ScimUserDeprovisioned => "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED",
1994            Self::ScimUserUpdated => "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED",
1995            Self::TranslationCreated => "AUDIT_EVENT_TYPE_TRANSLATION_CREATED",
1996            Self::TranslationApproved => "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED",
1997            Self::SandboxCreated => "AUDIT_EVENT_TYPE_SANDBOX_CREATED",
1998            Self::SandboxExpired => "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED",
1999            Self::AiPredictionLogged => "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED",
2000            Self::MlPipelineTriggered => "AUDIT_EVENT_TYPE_ML_PIPELINE_TRIGGERED",
2001            Self::ArchetypeClusteringTriggered => "AUDIT_EVENT_TYPE_ARCHETYPE_CLUSTERING_TRIGGERED",
2002            Self::OrgCreated => "AUDIT_EVENT_TYPE_ORG_CREATED",
2003            Self::OrgDeleted => "AUDIT_EVENT_TYPE_ORG_DELETED",
2004            Self::ReachabilityUpsert => "AUDIT_EVENT_TYPE_REACHABILITY_UPSERT",
2005            Self::ReachabilityRemove => "AUDIT_EVENT_TYPE_REACHABILITY_REMOVE",
2006            Self::KmsEncrypt => "AUDIT_EVENT_TYPE_KMS_ENCRYPT",
2007            Self::KmsDecrypt => "AUDIT_EVENT_TYPE_KMS_DECRYPT",
2008        }
2009    }
2010    /// Creates an enum from field names used in the ProtoBuf definition.
2011    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2012        match value {
2013            "AUDIT_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2014            "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED" => Some(Self::CampaignCreated),
2015            "AUDIT_EVENT_TYPE_MESSAGE_SENT" => Some(Self::MessageSent),
2016            "AUDIT_EVENT_TYPE_MESSAGE_OPENED" => Some(Self::MessageOpened),
2017            "AUDIT_EVENT_TYPE_ACK_REGISTERED" => Some(Self::AckRegistered),
2018            "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED" => Some(Self::EscalationExecuted),
2019            "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED" => Some(Self::CampaignStarted),
2020            "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED" => Some(Self::CampaignCancelled),
2021            "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED" => Some(Self::CampaignUpdated),
2022            "AUDIT_EVENT_TYPE_USER_INVITED" => Some(Self::UserInvited),
2023            "AUDIT_EVENT_TYPE_USER_DEACTIVATED" => Some(Self::UserDeactivated),
2024            "AUDIT_EVENT_TYPE_USER_REACTIVATED" => Some(Self::UserReactivated),
2025            "AUDIT_EVENT_TYPE_ROLE_CHANGED" => Some(Self::RoleChanged),
2026            "AUDIT_EVENT_TYPE_INVITE_REVOKED" => Some(Self::InviteRevoked),
2027            "AUDIT_EVENT_TYPE_PROFILE_UPDATED" => Some(Self::ProfileUpdated),
2028            "AUDIT_EVENT_TYPE_SETTINGS_UPDATED" => Some(Self::SettingsUpdated),
2029            "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED" => Some(Self::PasskeyEnrolled),
2030            "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED" => Some(Self::DataExportRequested),
2031            "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED" => Some(Self::DataDeletionRequested),
2032            "AUDIT_EVENT_TYPE_DATA_RECTIFIED" => Some(Self::DataRectified),
2033            "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED" => Some(Self::ProcessingRestricted),
2034            "AUDIT_EVENT_TYPE_DELETION_CANCELLED" => Some(Self::DeletionCancelled),
2035            "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE" => Some(Self::DeletionImmediate),
2036            "AUDIT_EVENT_TYPE_SSO_CONFIGURED" => Some(Self::SsoConfigured),
2037            "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED" => Some(Self::SsoProviderCreated),
2038            "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED" => Some(Self::SsoProviderDeleted),
2039            "AUDIT_EVENT_TYPE_ORG_UPDATED" => Some(Self::OrgUpdated),
2040            "AUDIT_EVENT_TYPE_ROLE_CREATED" => Some(Self::RoleCreated),
2041            "AUDIT_EVENT_TYPE_ROLE_UPDATED" => Some(Self::RoleUpdated),
2042            "AUDIT_EVENT_TYPE_ROLE_DELETED" => Some(Self::RoleDeleted),
2043            "AUDIT_EVENT_TYPE_TEMPLATE_CREATED" => Some(Self::TemplateCreated),
2044            "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED" => Some(Self::TemplateUpdated),
2045            "AUDIT_EVENT_TYPE_API_KEY_CREATED" => Some(Self::ApiKeyCreated),
2046            "AUDIT_EVENT_TYPE_API_KEY_REVOKED" => Some(Self::ApiKeyRevoked),
2047            "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED" => Some(Self::InviteLinkCreated),
2048            "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED" => Some(Self::InviteLinkRevoked),
2049            "AUDIT_EVENT_TYPE_GROUP_CREATED" => Some(Self::GroupCreated),
2050            "AUDIT_EVENT_TYPE_GROUP_UPDATED" => Some(Self::GroupUpdated),
2051            "AUDIT_EVENT_TYPE_GROUP_DELETED" => Some(Self::GroupDeleted),
2052            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED" => Some(Self::GroupMembersAdded),
2053            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED" => Some(Self::GroupMembersRemoved),
2054            "AUDIT_EVENT_TYPE_TEAM_CREATED" => Some(Self::TeamCreated),
2055            "AUDIT_EVENT_TYPE_TEAM_UPDATED" => Some(Self::TeamUpdated),
2056            "AUDIT_EVENT_TYPE_TEAM_DELETED" => Some(Self::TeamDeleted),
2057            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED" => Some(Self::TeamMembersAdded),
2058            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED" => Some(Self::TeamMembersRemoved),
2059            "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED" => Some(Self::ScimUserProvisioned),
2060            "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED" => Some(Self::ScimUserDeprovisioned),
2061            "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED" => Some(Self::ScimUserUpdated),
2062            "AUDIT_EVENT_TYPE_TRANSLATION_CREATED" => Some(Self::TranslationCreated),
2063            "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED" => Some(Self::TranslationApproved),
2064            "AUDIT_EVENT_TYPE_SANDBOX_CREATED" => Some(Self::SandboxCreated),
2065            "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED" => Some(Self::SandboxExpired),
2066            "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED" => Some(Self::AiPredictionLogged),
2067            "AUDIT_EVENT_TYPE_ML_PIPELINE_TRIGGERED" => Some(Self::MlPipelineTriggered),
2068            "AUDIT_EVENT_TYPE_ARCHETYPE_CLUSTERING_TRIGGERED" => Some(Self::ArchetypeClusteringTriggered),
2069            "AUDIT_EVENT_TYPE_ORG_CREATED" => Some(Self::OrgCreated),
2070            "AUDIT_EVENT_TYPE_ORG_DELETED" => Some(Self::OrgDeleted),
2071            "AUDIT_EVENT_TYPE_REACHABILITY_UPSERT" => Some(Self::ReachabilityUpsert),
2072            "AUDIT_EVENT_TYPE_REACHABILITY_REMOVE" => Some(Self::ReachabilityRemove),
2073            "AUDIT_EVENT_TYPE_KMS_ENCRYPT" => Some(Self::KmsEncrypt),
2074            "AUDIT_EVENT_TYPE_KMS_DECRYPT" => Some(Self::KmsDecrypt),
2075            _ => None,
2076        }
2077    }
2078}
2079/// Classification of an audit event by origin and volume profile, separating
2080/// management actions (human-initiated configuration changes) from high-volume
2081/// system events emitted automatically during processing.
2082#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2083#[repr(i32)]
2084pub enum AuditEventClass {
2085    /// Default value; should not be used explicitly.
2086    Unspecified = 0,
2087    /// An action initiated by a principal against the organization's
2088    /// configuration or operation (e.g. creating a campaign, changing a role).
2089    Management = 1,
2090    /// A high-volume data-plane event emitted by the system during processing
2091    /// (e.g. per-payload encryption or decryption).
2092    System = 2,
2093}
2094impl AuditEventClass {
2095    /// String value of the enum field names used in the ProtoBuf definition.
2096    ///
2097    /// The values are not transformed in any way and thus are considered stable
2098    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2099    pub fn as_str_name(&self) -> &'static str {
2100        match self {
2101            Self::Unspecified => "AUDIT_EVENT_CLASS_UNSPECIFIED",
2102            Self::Management => "AUDIT_EVENT_CLASS_MANAGEMENT",
2103            Self::System => "AUDIT_EVENT_CLASS_SYSTEM",
2104        }
2105    }
2106    /// Creates an enum from field names used in the ProtoBuf definition.
2107    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2108        match value {
2109            "AUDIT_EVENT_CLASS_UNSPECIFIED" => Some(Self::Unspecified),
2110            "AUDIT_EVENT_CLASS_MANAGEMENT" => Some(Self::Management),
2111            "AUDIT_EVENT_CLASS_SYSTEM" => Some(Self::System),
2112            _ => None,
2113        }
2114    }
2115}
2116/// Format for audit trail export.
2117#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2118#[repr(i32)]
2119pub enum AuditExportFormat {
2120    /// Default value; should not be used explicitly.
2121    Unspecified = 0,
2122    /// Comma-separated values.
2123    Csv = 1,
2124    /// JSON lines format.
2125    Json = 2,
2126    /// Apache Parquet columnar format.
2127    Parquet = 3,
2128}
2129impl AuditExportFormat {
2130    /// String value of the enum field names used in the ProtoBuf definition.
2131    ///
2132    /// The values are not transformed in any way and thus are considered stable
2133    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2134    pub fn as_str_name(&self) -> &'static str {
2135        match self {
2136            Self::Unspecified => "AUDIT_EXPORT_FORMAT_UNSPECIFIED",
2137            Self::Csv => "AUDIT_EXPORT_FORMAT_CSV",
2138            Self::Json => "AUDIT_EXPORT_FORMAT_JSON",
2139            Self::Parquet => "AUDIT_EXPORT_FORMAT_PARQUET",
2140        }
2141    }
2142    /// Creates an enum from field names used in the ProtoBuf definition.
2143    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2144        match value {
2145            "AUDIT_EXPORT_FORMAT_UNSPECIFIED" => Some(Self::Unspecified),
2146            "AUDIT_EXPORT_FORMAT_CSV" => Some(Self::Csv),
2147            "AUDIT_EXPORT_FORMAT_JSON" => Some(Self::Json),
2148            "AUDIT_EXPORT_FORMAT_PARQUET" => Some(Self::Parquet),
2149            _ => None,
2150        }
2151    }
2152}
2153// ─── Messages ─────────────────────────────────────────────────────────────────
2154
2155/// Request to resolve the effective permission set for one principal.
2156#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2157pub struct ResolvePrincipalPermissionsRequest {
2158    /// UUID of the subject whose permissions are being resolved (user or
2159    /// principal identifier).
2160    #[prost(string, tag="1")]
2161    pub subject: ::prost::alloc::string::String,
2162    /// Organization the resolution is scoped to.
2163    #[prost(string, tag="2")]
2164    pub org_id: ::prost::alloc::string::String,
2165    /// Kind of principal identified by `subject`.
2166    #[prost(enumeration="PrincipalType", tag="3")]
2167    pub principal_type: i32,
2168}
2169/// Effective permissions resolved for the requested principal.
2170#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2171pub struct ResolvePrincipalPermissionsResponse {
2172    /// Flattened, deduplicated set of permissions granted to the principal in
2173    /// the requested organization. Empty when the principal has no grants.
2174    #[prost(enumeration="Permission", repeated, tag="1")]
2175    pub permissions: ::prost::alloc::vec::Vec<i32>,
2176}
2177/// Request to check the current suspension state of one organization.
2178#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2179pub struct CheckOrgSuspendedRequest {
2180    /// Organization whose suspension state is being checked.
2181    #[prost(string, tag="1")]
2182    pub org_id: ::prost::alloc::string::String,
2183}
2184/// Current suspension state of the requested organization.
2185#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2186pub struct CheckOrgSuspendedResponse {
2187    /// True when the organization is currently suspended.
2188    #[prost(bool, tag="1")]
2189    pub suspended: bool,
2190}
2191// ─── Enums ──────────────────────────────────────────────────────────────────
2192
2193/// Kind of principal whose permissions are being resolved.
2194#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2195#[repr(i32)]
2196pub enum PrincipalType {
2197    Unspecified = 0,
2198    /// An end user identified by their user UUID, scoped to one organization.
2199    User = 1,
2200    /// An organization acting as its own principal (e.g. a service identity
2201    /// operating on behalf of the whole org rather than a member).
2202    Org = 2,
2203    /// A platform staff principal whose permissions derive from a role within
2204    /// the ORG_TYPE_STAFF organization.
2205    Staff = 3,
2206}
2207impl PrincipalType {
2208    /// String value of the enum field names used in the ProtoBuf definition.
2209    ///
2210    /// The values are not transformed in any way and thus are considered stable
2211    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2212    pub fn as_str_name(&self) -> &'static str {
2213        match self {
2214            Self::Unspecified => "PRINCIPAL_TYPE_UNSPECIFIED",
2215            Self::User => "PRINCIPAL_TYPE_USER",
2216            Self::Org => "PRINCIPAL_TYPE_ORG",
2217            Self::Staff => "PRINCIPAL_TYPE_STAFF",
2218        }
2219    }
2220    /// Creates an enum from field names used in the ProtoBuf definition.
2221    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2222        match value {
2223            "PRINCIPAL_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2224            "PRINCIPAL_TYPE_USER" => Some(Self::User),
2225            "PRINCIPAL_TYPE_ORG" => Some(Self::Org),
2226            "PRINCIPAL_TYPE_STAFF" => Some(Self::Staff),
2227            _ => None,
2228        }
2229    }
2230}
2231// ─── Messages ───────────────────────────────────────────────────────────────
2232
2233/// A campaign that delivers structured messages to a set of recipients
2234/// and tracks their engagement through a workflow.
2235#[derive(Clone, PartialEq, ::prost::Message)]
2236pub struct Campaign {
2237    /// Unique identifier for the campaign.
2238    /// Constraints: UUID format (36 characters).
2239    #[prost(string, tag="1")]
2240    pub id: ::prost::alloc::string::String,
2241    /// Human-readable campaign name.
2242    /// Constraints: Max length 200 characters.
2243    #[prost(string, tag="2")]
2244    pub name: ::prost::alloc::string::String,
2245    /// ID of the template used to render messages.
2246    /// Constraints: UUID format (36 characters).
2247    #[prost(string, tag="3")]
2248    pub template_id: ::prost::alloc::string::String,
2249    /// Pinned version of the template used for this campaign.
2250    #[prost(int32, tag="4")]
2251    pub template_version: i32,
2252    /// Object storage reference to the audience snapshot taken at campaign creation.
2253    #[prost(string, tag="5")]
2254    pub audience_snapshot_ref: ::prost::alloc::string::String,
2255    /// Current lifecycle status of the campaign.
2256    #[prost(enumeration="CampaignStatus", tag="6")]
2257    pub status: i32,
2258    /// Workflow DAG that drives the campaign's automation logic.
2259    #[prost(message, optional, tag="7")]
2260    pub workflow: ::core::option::Option<WorkflowDefinition>,
2261    /// Total number of recipients in the audience snapshot.
2262    #[prost(int32, tag="8")]
2263    pub total_recipients: i32,
2264    /// Number of recipients who completed the required action.
2265    #[prost(int32, tag="9")]
2266    pub action_completed_count: i32,
2267    /// Number of recipients who did not act before the deadline.
2268    #[prost(int32, tag="10")]
2269    pub missed_count: i32,
2270    /// Timestamp when the campaign was created.
2271    #[prost(message, optional, tag="11")]
2272    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2273    /// Timestamp when the campaign was started (workflow execution began).
2274    #[prost(message, optional, tag="12")]
2275    pub started_at: ::core::option::Option<::prost_types::Timestamp>,
2276    /// Timestamp when the campaign finished (completed, failed, or cancelled).
2277    #[prost(message, optional, tag="13")]
2278    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
2279    /// Display name of the sender shown to recipients (e.g. "HR Team").
2280    /// Constraints: Max length 200 characters.
2281    #[prost(string, tag="14")]
2282    pub sender_name: ::prost::alloc::string::String,
2283    /// Optional user-facing title override. If set, takes precedence over the template title.
2284    /// Constraints: Max length 200 characters.
2285    #[prost(string, tag="15")]
2286    pub title: ::prost::alloc::string::String,
2287    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
2288    #[prost(bool, tag="16")]
2289    pub critical: bool,
2290    /// Optional locale override for all recipients in this campaign.
2291    /// When set, all recipients receive the campaign in this locale regardless of
2292    /// their preferred_locale. Empty means per-recipient locale resolution.
2293    /// Valid values: en, es, pt-BR, zh, ja.
2294    #[prost(string, tag="17")]
2295    pub default_locale: ::prost::alloc::string::String,
2296    /// Whether the campaign deadline waits for users without registered devices.
2297    /// When true, NO_DEVICE users remain in pending_count and can acknowledge
2298    /// via inbox after installing the app. Default false preserves current behavior.
2299    #[prost(bool, tag="18")]
2300    pub wait_for_enrollment: bool,
2301    /// Optional. Set when the campaign was created from a Compass archetype CTA.
2302    /// Drives post-campaign archetype-response analytics.
2303    #[prost(message, optional, tag="19")]
2304    pub originating_archetype: ::core::option::Option<CampaignOriginatingArchetype>,
2305    /// True when this campaign contains synthetic (artificially injected) data —
2306    /// created or populated for demos, sandbox testing, or issue reproduction.
2307    #[prost(bool, tag="20")]
2308    pub synthetic: bool,
2309    /// Number of recipients frozen in the audience snapshot at creation time.
2310    /// Unlike total_recipients (which counts deliveries and is 0 until the
2311    /// campaign starts), this is known as soon as the campaign exists.
2312    /// 0 when the campaign predates snapshot-size tracking.
2313    #[prost(int32, tag="21")]
2314    pub audience_snapshot_size: i32,
2315    /// Number of members currently eligible for this campaign's audience,
2316    /// computed at read time. Compare with audience_snapshot_size to see how far
2317    /// the frozen audience has drifted from the present membership.
2318    #[prost(int32, tag="22")]
2319    pub current_audience_size: i32,
2320    /// True when the frozen audience no longer covers the current eligible
2321    /// membership (current_audience_size > audience_snapshot_size). Clients
2322    /// should surface this before the campaign is started: recipients added
2323    /// after creation are NOT reached unless the campaign is recreated.
2324    #[prost(bool, tag="23")]
2325    pub audience_snapshot_stale: bool,
2326    /// Live execution position of the campaign's workflow. Unset until the
2327    /// campaign starts and after it reaches a terminal state. Distinct from
2328    /// per-recipient delivery state: this reports which workflow step the
2329    /// engine is executing (or waiting on), independent of whether any
2330    /// recipient has acted.
2331    #[prost(message, optional, tag="24")]
2332    pub workflow_progress: ::core::option::Option<CampaignWorkflowProgress>,
2333    /// Objectives this campaign serves, as declared at creation or linked
2334    /// afterwards. Empty is allowed and carries no penalty: a campaign
2335    /// with no declared objective behaves exactly like one that predates
2336    /// objectives entirely.
2337    #[prost(string, repeated, tag="25")]
2338    pub objective_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2339}
2340/// Live execution position of a running campaign's workflow, recorded by
2341/// the campaign worker as steps transition. Lets clients render true
2342/// engine progress (e.g. "waiting on a deadline until T") instead of
2343/// inferring it from recipient delivery activity, which never observes
2344/// timer-only steps.
2345#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2346pub struct CampaignWorkflowProgress {
2347    /// Workflow-definition step id (WorkflowStep.id) currently executing or
2348    /// being waited on.
2349    #[prost(string, tag="1")]
2350    pub current_step_id: ::prost::alloc::string::String,
2351    /// When the workflow entered the current step.
2352    #[prost(message, optional, tag="2")]
2353    pub step_entered_at: ::core::option::Option<::prost_types::Timestamp>,
2354    /// For timer-backed steps (e.g. deadline checks): when the pending timer
2355    /// fires. Unset for steps that complete without waiting.
2356    #[prost(message, optional, tag="3")]
2357    pub next_wake_at: ::core::option::Option<::prost_types::Timestamp>,
2358}
2359/// Identifies the archetype that motivated the creation of a campaign.
2360/// The audience is NOT filtered by archetype membership — this is metadata
2361/// about the campaign's authoring intent only. See OpenSpec change
2362/// archetype-targeted-campaign-cta.
2363#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2364pub struct CampaignOriginatingArchetype {
2365    /// UUID of the group whose archetype set the label belongs to.
2366    #[prost(string, tag="1")]
2367    pub group_id: ::prost::alloc::string::String,
2368    /// Stable archetype label (e.g., "Swift Acknowledger"). Labels are stable
2369    /// across clustering retrains; archetype IDs are not.
2370    #[prost(string, tag="2")]
2371    pub archetype_label: ::prost::alloc::string::String,
2372}
2373/// A single audience member with optional per-user template variables.
2374#[derive(Clone, PartialEq, ::prost::Message)]
2375pub struct AudienceMember {
2376    /// User ID (UUID).
2377    #[prost(string, tag="1")]
2378    pub user_id: ::prost::alloc::string::String,
2379    /// Template variable values for this user (e.g. {"name": "Alice"}).
2380    #[prost(map="string, string", tag="2")]
2381    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
2382}
2383/// Request to create a new campaign.
2384#[derive(Clone, PartialEq, ::prost::Message)]
2385pub struct CreateCampaignRequest {
2386    /// Human-readable campaign name (admin-facing label).
2387    /// Constraints: Max length 200 characters.
2388    #[prost(string, tag="1")]
2389    pub name: ::prost::alloc::string::String,
2390    /// ID of the template to use for rendering messages.
2391    /// Constraints: UUID format (36 characters).
2392    #[prost(string, tag="2")]
2393    pub template_id: ::prost::alloc::string::String,
2394    /// Version of the template to pin for this campaign.
2395    #[prost(int32, tag="3")]
2396    pub template_version: i32,
2397    /// List of user IDs that form the campaign audience.
2398    /// Constraints: Max 100000 items.
2399    #[prost(string, repeated, tag="4")]
2400    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2401    /// Workflow DAG defining the campaign's automation steps.
2402    /// Required: CreateCampaign rejects a request with no workflow
2403    /// (INVALID_ARGUMENT) and does not substitute a default. The definition
2404    /// MUST validate as an acyclic graph of well-formed steps.
2405    #[prost(message, optional, tag="5")]
2406    pub workflow: ::core::option::Option<WorkflowDefinition>,
2407    /// Display name of the sender shown to recipients (e.g. "HR Team").
2408    /// Constraints: Max length 200 characters.
2409    #[prost(string, tag="6")]
2410    pub sender_name: ::prost::alloc::string::String,
2411    /// Optional user-facing title override. If empty, the template title is used.
2412    /// Constraints: Max length 200 characters.
2413    #[prost(string, tag="7")]
2414    pub title: ::prost::alloc::string::String,
2415    /// Rich audience with per-user template variables.
2416    /// When set, takes precedence over user_ids.
2417    /// Constraints: Max 100000 items.
2418    #[prost(message, repeated, tag="8")]
2419    pub audience: ::prost::alloc::vec::Vec<AudienceMember>,
2420    /// Whether to include users with processing_restricted=true in the audience.
2421    /// Default false: restricted users are excluded. Set true only with Art. 18(2) legal basis.
2422    #[prost(bool, tag="9")]
2423    pub include_restricted: bool,
2424    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
2425    #[prost(bool, tag="10")]
2426    pub critical: bool,
2427    /// Optional locale override for all recipients.
2428    #[prost(string, tag="11")]
2429    pub default_locale: ::prost::alloc::string::String,
2430    /// Whether the campaign deadline should wait for users without registered devices.
2431    /// When true, NO_DEVICE users are not decremented from pending_count,
2432    /// allowing them to acknowledge via inbox after installing the app.
2433    #[prost(bool, tag="12")]
2434    pub wait_for_enrollment: bool,
2435    /// Optional. Set when the campaign is created from a Compass archetype CTA.
2436    /// The server validates the caller has access to group_id and that
2437    /// archetype_label exists in the group's current archetype set; cross-org
2438    /// group_id returns PERMISSION_DENIED, unknown label returns NOT_FOUND.
2439    #[prost(message, optional, tag="13")]
2440    pub originating_archetype: ::core::option::Option<CampaignOriginatingArchetype>,
2441    /// Objectives this campaign serves. Declaring the objective at
2442    /// creation is the point at which a response rate stops being the
2443    /// result and becomes evidence about something the organization was
2444    /// trying to achieve. Empty is allowed and changes nothing about how
2445    /// the campaign runs. Unknown or cross-org IDs return NOT_FOUND.
2446    #[prost(string, repeated, tag="14")]
2447    pub objective_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2448}
2449/// Response after creating a campaign.
2450#[derive(Clone, PartialEq, ::prost::Message)]
2451pub struct CreateCampaignResponse {
2452    /// The newly created campaign.
2453    #[prost(message, optional, tag="1")]
2454    pub campaign: ::core::option::Option<Campaign>,
2455}
2456/// Request to start a campaign's workflow execution.
2457#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2458pub struct StartCampaignRequest {
2459    /// ID of the campaign to start.
2460    /// Constraints: UUID format (36 characters).
2461    #[prost(string, tag="1")]
2462    pub campaign_id: ::prost::alloc::string::String,
2463}
2464/// Response after starting a campaign.
2465#[derive(Clone, PartialEq, ::prost::Message)]
2466pub struct StartCampaignResponse {
2467    /// The campaign with updated status.
2468    #[prost(message, optional, tag="1")]
2469    pub campaign: ::core::option::Option<Campaign>,
2470}
2471/// Request to retrieve a single campaign by ID.
2472#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2473pub struct GetCampaignRequest {
2474    /// ID of the campaign to retrieve.
2475    /// Constraints: UUID format (36 characters).
2476    #[prost(string, tag="1")]
2477    pub campaign_id: ::prost::alloc::string::String,
2478}
2479/// Response containing the requested campaign.
2480#[derive(Clone, PartialEq, ::prost::Message)]
2481pub struct GetCampaignResponse {
2482    /// The requested campaign.
2483    #[prost(message, optional, tag="1")]
2484    pub campaign: ::core::option::Option<Campaign>,
2485}
2486/// Request to list campaigns with pagination.
2487#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2488pub struct ListCampaignsRequest {
2489    /// Pagination parameters.
2490    #[prost(message, optional, tag="1")]
2491    pub pagination: ::core::option::Option<Pagination>,
2492}
2493/// Response containing a page of campaigns.
2494#[derive(Clone, PartialEq, ::prost::Message)]
2495pub struct ListCampaignsResponse {
2496    /// List of campaigns in this page.
2497    #[prost(message, repeated, tag="1")]
2498    pub campaigns: ::prost::alloc::vec::Vec<Campaign>,
2499    /// Pagination metadata for fetching subsequent pages.
2500    #[prost(message, optional, tag="2")]
2501    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2502}
2503/// Request to cancel a running campaign.
2504#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2505pub struct CancelCampaignRequest {
2506    /// ID of the campaign to cancel.
2507    /// Constraints: UUID format (36 characters).
2508    #[prost(string, tag="1")]
2509    pub campaign_id: ::prost::alloc::string::String,
2510}
2511/// Response after cancelling a campaign.
2512#[derive(Clone, PartialEq, ::prost::Message)]
2513pub struct CancelCampaignResponse {
2514    /// The campaign with updated status (CANCELLED).
2515    #[prost(message, optional, tag="1")]
2516    pub campaign: ::core::option::Option<Campaign>,
2517}
2518/// Request to update a draft campaign (status must be CREATED).
2519/// Only non-empty/non-zero fields are updated; omitted fields remain unchanged.
2520#[derive(Clone, PartialEq, ::prost::Message)]
2521pub struct UpdateCampaignRequest {
2522    /// ID of the campaign to update.
2523    /// Constraints: UUID format (36 characters).
2524    #[prost(string, tag="1")]
2525    pub campaign_id: ::prost::alloc::string::String,
2526    /// Updated campaign name. Empty string means no change.
2527    /// Constraints: Max length 200 characters.
2528    #[prost(string, tag="2")]
2529    pub name: ::prost::alloc::string::String,
2530    /// Updated sender display name. Empty string means no change.
2531    /// Constraints: Max length 200 characters.
2532    #[prost(string, tag="3")]
2533    pub sender_name: ::prost::alloc::string::String,
2534    /// Updated title override. Empty string means no change.
2535    /// Constraints: Max length 200 characters.
2536    #[prost(string, tag="4")]
2537    pub title: ::prost::alloc::string::String,
2538    /// Updated template ID. Empty string means no change.
2539    /// Constraints: UUID format (36 characters).
2540    #[prost(string, tag="5")]
2541    pub template_id: ::prost::alloc::string::String,
2542    /// Updated template version. Zero means no change.
2543    #[prost(int32, tag="6")]
2544    pub template_version: i32,
2545    /// Updated workflow DAG. Null/omitted means no change.
2546    #[prost(message, optional, tag="7")]
2547    pub workflow: ::core::option::Option<WorkflowDefinition>,
2548    /// Replaces the campaign's frozen audience snapshot. Omitted means no
2549    /// change; PRESENT means replace — including with an empty member list
2550    /// (a campaign with no recipients is a valid state). The wrapper message
2551    /// exists exactly for that presence distinction, which a bare repeated
2552    /// field cannot express. Only valid while the campaign is in CREATED
2553    /// status; the server rejects the replacement once the campaign has
2554    /// started, since deliveries were already created from the old snapshot.
2555    #[prost(message, optional, tag="8")]
2556    pub audience_replacement: ::core::option::Option<AudienceReplacement>,
2557}
2558/// A full replacement for a campaign's frozen audience. Presence of this
2559/// message (not its member count) signals the replace intent.
2560#[derive(Clone, PartialEq, ::prost::Message)]
2561pub struct AudienceReplacement {
2562    /// The new complete audience. Replaces the previous snapshot wholesale.
2563    #[prost(message, repeated, tag="1")]
2564    pub members: ::prost::alloc::vec::Vec<AudienceMember>,
2565}
2566/// Response after updating a campaign.
2567#[derive(Clone, PartialEq, ::prost::Message)]
2568pub struct UpdateCampaignResponse {
2569    /// The campaign with updated fields.
2570    #[prost(message, optional, tag="1")]
2571    pub campaign: ::core::option::Option<Campaign>,
2572}
2573/// Request to read a campaign's frozen audience snapshot.
2574#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2575pub struct GetCampaignAudienceRequest {
2576    /// ID of the campaign whose audience to read.
2577    /// Constraints: UUID format (36 characters).
2578    #[prost(string, tag="1")]
2579    pub campaign_id: ::prost::alloc::string::String,
2580}
2581/// One member of a campaign's frozen audience, enriched with the identity
2582/// fields a client needs to render the member without further lookups.
2583#[derive(Clone, PartialEq, ::prost::Message)]
2584pub struct CampaignAudienceEntry {
2585    /// The frozen audience row exactly as it will be delivered to: user id
2586    /// plus per-user template variables.
2587    #[prost(message, optional, tag="1")]
2588    pub member: ::core::option::Option<AudienceMember>,
2589    /// The member's email at read time. Empty when the user no longer
2590    /// resolves (deactivated or erased since the audience was frozen).
2591    #[prost(string, tag="2")]
2592    pub email: ::prost::alloc::string::String,
2593    /// The member's display name at read time. Empty when unresolvable.
2594    #[prost(string, tag="3")]
2595    pub display_name: ::prost::alloc::string::String,
2596    /// False when the user is no longer an active or invited member of the
2597    /// organization — a frozen recipient that would not be reachable today.
2598    #[prost(bool, tag="4")]
2599    pub active: bool,
2600}
2601/// A campaign's frozen audience. Empty when the campaign has no audience
2602/// snapshot (legacy campaigns predating snapshot tracking) or the snapshot
2603/// is empty.
2604#[derive(Clone, PartialEq, ::prost::Message)]
2605pub struct GetCampaignAudienceResponse {
2606    /// The frozen audience, enriched per entry.
2607    #[prost(message, repeated, tag="1")]
2608    pub entries: ::prost::alloc::vec::Vec<CampaignAudienceEntry>,
2609}
2610/// A single delivery record tracking message delivery to one recipient.
2611/// Out-of-band context attached to a delivery beyond its canonical
2612/// recipient + status + content payload. Optional; fields are populated
2613/// per delivery kind. Currently only REMINDER_FYI children carry values,
2614/// to snapshot context from the parent delivery so clients can render
2615/// without fetching additional resources.
2616#[derive(Clone, PartialEq, ::prost::Message)]
2617pub struct DeliveryMetadata {
2618    /// REMINDER_FYI: the rendered Message payload from the parent delivery,
2619    /// used to render the blockquoted "Original message" panel on the
2620    /// notify-target's inbox card.
2621    #[prost(message, optional, tag="1")]
2622    pub original_message: ::core::option::Option<Message>,
2623    /// REMINDER_FYI: display name of the original recipient (the employee
2624    /// who hasn't responded). Used to interpolate the FYI title and banner.
2625    #[prost(string, tag="2")]
2626    pub original_recipient_name: ::prost::alloc::string::String,
2627    /// REMINDER_FYI: campaign title, denormalized so the notify-target's
2628    /// client can render without a separate campaign lookup.
2629    #[prost(string, tag="3")]
2630    pub campaign_title: ::prost::alloc::string::String,
2631    /// REMINDER_FYI: when the parent reminder step fired, used to render
2632    /// the "fired X ago" footer on the FYI card.
2633    #[prost(message, optional, tag="4")]
2634    pub reminder_fired_at: ::core::option::Option<::prost_types::Timestamp>,
2635}
2636#[derive(Clone, PartialEq, ::prost::Message)]
2637pub struct Delivery {
2638    /// Unique identifier for this delivery.
2639    /// Constraints: UUID format (36 characters).
2640    #[prost(string, tag="1")]
2641    pub id: ::prost::alloc::string::String,
2642    /// ID of the recipient user.
2643    /// Constraints: UUID format (36 characters).
2644    #[prost(string, tag="2")]
2645    pub user_id: ::prost::alloc::string::String,
2646    /// ID of the campaign this delivery belongs to.
2647    /// Constraints: UUID format (36 characters).
2648    #[prost(string, tag="3")]
2649    pub campaign_id: ::prost::alloc::string::String,
2650    /// Current delivery status.
2651    #[prost(enumeration="DeliveryStatus", tag="4")]
2652    pub status: i32,
2653    /// Timestamp when the message was delivered to the device.
2654    #[prost(message, optional, tag="5")]
2655    pub delivered_at: ::core::option::Option<::prost_types::Timestamp>,
2656    /// Timestamp when the recipient read the message.
2657    #[prost(message, optional, tag="6")]
2658    pub read_at: ::core::option::Option<::prost_types::Timestamp>,
2659    /// Timestamp when the recipient performed the required action.
2660    #[prost(message, optional, tag="7")]
2661    pub acted_at: ::core::option::Option<::prost_types::Timestamp>,
2662    /// Email address of the recipient, populated from the users table on read.
2663    #[prost(string, tag="8")]
2664    pub recipient_email: ::prost::alloc::string::String,
2665    /// Discriminator distinguishing primary recipient deliveries from
2666    /// deliveries generated by downstream workflow steps.
2667    #[prost(enumeration="delivery::Kind", tag="12")]
2668    pub kind: i32,
2669    /// For non-primary deliveries, the UUID of the originating delivery this
2670    /// row was derived from. Empty for primary deliveries.
2671    /// Constraints: UUID format (36 characters) when set.
2672    #[prost(string, tag="13")]
2673    pub parent_delivery_id: ::prost::alloc::string::String,
2674    /// The locale this delivery's body was actually rendered in after fallback
2675    /// resolution (recipient preference, campaign override, template default).
2676    /// Valid values: en, es, pt-BR, zh, ja.
2677    #[prost(string, tag="14")]
2678    pub rendered_locale: ::prost::alloc::string::String,
2679    /// Optional out-of-band context. See `DeliveryMetadata` for which
2680    /// delivery kinds populate which fields. Empty for legacy / PRIMARY
2681    /// deliveries.
2682    #[prost(message, optional, tag="15")]
2683    pub metadata: ::core::option::Option<DeliveryMetadata>,
2684    /// True when this delivery's outcome is synthetic (artificially injected)
2685    /// data rather than the result of a real delivery and user response.
2686    #[prost(bool, tag="9")]
2687    pub synthetic: bool,
2688}
2689/// Nested message and enum types in `Delivery`.
2690pub mod delivery {
2691    /// Discriminator describing what produced this delivery row.
2692    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2693    #[repr(i32)]
2694    pub enum Kind {
2695        /// Default value; not a valid kind.
2696        Unspecified = 0,
2697        /// Delivery generated for an audience recipient at campaign start.
2698        Primary = 1,
2699        /// Delivery generated by an escalation step targeting a non-audience user.
2700        Escalation = 2,
2701        /// Passive heads-up delivery generated when a reminder step fans out to
2702        /// its `notify_targets`. Carries no action button; auto-dismisses when
2703        /// the parent delivery is acknowledged. See
2704        /// `SendReminderConfig.notify_targets`.
2705        ReminderFyi = 3,
2706    }
2707    impl Kind {
2708        /// String value of the enum field names used in the ProtoBuf definition.
2709        ///
2710        /// The values are not transformed in any way and thus are considered stable
2711        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2712        pub fn as_str_name(&self) -> &'static str {
2713            match self {
2714                Self::Unspecified => "KIND_UNSPECIFIED",
2715                Self::Primary => "KIND_PRIMARY",
2716                Self::Escalation => "KIND_ESCALATION",
2717                Self::ReminderFyi => "KIND_REMINDER_FYI",
2718            }
2719        }
2720        /// Creates an enum from field names used in the ProtoBuf definition.
2721        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2722            match value {
2723                "KIND_UNSPECIFIED" => Some(Self::Unspecified),
2724                "KIND_PRIMARY" => Some(Self::Primary),
2725                "KIND_ESCALATION" => Some(Self::Escalation),
2726                "KIND_REMINDER_FYI" => Some(Self::ReminderFyi),
2727                _ => None,
2728            }
2729        }
2730    }
2731}
2732/// Request to list deliveries for a campaign with optional status filtering.
2733#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2734pub struct ListDeliveriesRequest {
2735    /// ID of the campaign to list deliveries for.
2736    /// Constraints: UUID format (36 characters).
2737    #[prost(string, tag="1")]
2738    pub campaign_id: ::prost::alloc::string::String,
2739    /// Optional filter by delivery status. UNSPECIFIED returns all.
2740    #[prost(enumeration="DeliveryStatus", tag="2")]
2741    pub status_filter: i32,
2742    /// Pagination parameters.
2743    #[prost(message, optional, tag="3")]
2744    pub pagination: ::core::option::Option<Pagination>,
2745}
2746/// Response containing a page of delivery records.
2747#[derive(Clone, PartialEq, ::prost::Message)]
2748pub struct ListDeliveriesResponse {
2749    /// List of deliveries in this page.
2750    #[prost(message, repeated, tag="1")]
2751    pub deliveries: ::prost::alloc::vec::Vec<Delivery>,
2752    /// Pagination metadata for fetching subsequent pages.
2753    #[prost(message, optional, tag="2")]
2754    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2755}
2756/// Request to compute the archetype-tendency-shift surface for a campaign:
2757/// how each archetype's share of the originating group has moved between
2758/// the snapshot closest to campaign-creation time and the most recent
2759/// snapshot. Only valid for campaigns whose originating_archetype is set.
2760#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2761pub struct GetCampaignArchetypeBreakdownRequest {
2762    /// ID of the campaign to break down.
2763    /// Constraints: UUID format (36 characters).
2764    #[prost(string, tag="1")]
2765    pub campaign_id: ::prost::alloc::string::String,
2766}
2767/// Movement in one archetype's share of the originating group between the
2768/// "before" and "after" archetype-clustering snapshots. Cohort-level only;
2769/// no joining to user identity. The `is_origin` row is the archetype the
2770/// campaign was authored for.
2771#[derive(Clone, PartialEq, ::prost::Message)]
2772pub struct ArchetypeShareShift {
2773    /// Stable archetype label, e.g. "Swift Acknowledger".
2774    #[prost(string, tag="1")]
2775    pub label: ::prost::alloc::string::String,
2776    /// Archetype's share of the group at the snapshot closest to (but not
2777    /// after) the campaign's created_at. Range 0.0 – 1.0.
2778    #[prost(double, tag="2")]
2779    pub share_before: f64,
2780    /// Archetype's share of the group at the most recent snapshot. Range
2781    /// 0.0 – 1.0. Equals share_before when no clustering has run since.
2782    #[prost(double, tag="3")]
2783    pub share_after: f64,
2784    /// True when this row's label matches the campaign's
2785    /// originating_archetype.archetype_label.
2786    #[prost(bool, tag="4")]
2787    pub is_origin: bool,
2788    /// Count of email DELIVERED events recorded for this archetype's members
2789    /// across the campaign window. Denominator for both open-rate fields.
2790    #[prost(uint64, tag="5")]
2791    pub email_delivered_count: u64,
2792    /// Open rate excluding events flagged as Apple-MPP prefetches
2793    /// (prefetch_suspected=true). Range 0.0 – 1.0.
2794    #[prost(double, tag="6")]
2795    pub email_open_rate_real: f64,
2796    /// Open rate including all OPENED events, prefetches included.
2797    /// Range 0.0 – 1.0.
2798    #[prost(double, tag="7")]
2799    pub email_open_rate_raw: f64,
2800}
2801/// Response containing per-archetype share shifts. The admin renders
2802/// these as a comparison table — origin row marked, others as peers, so
2803/// the admin can tell campaign-coincident drift apart from background
2804/// drift across the rest of the group.
2805#[derive(Clone, PartialEq, ::prost::Message)]
2806pub struct GetCampaignArchetypeBreakdownResponse {
2807    /// One entry per archetype in the originating group. Empty when
2808    /// insufficient_history is true.
2809    #[prost(message, repeated, tag="1")]
2810    pub shifts: ::prost::alloc::vec::Vec<ArchetypeShareShift>,
2811    /// When the "before" sample was taken (closest snapshot at or before
2812    /// campaign creation).
2813    #[prost(message, optional, tag="2")]
2814    pub before_snapshot_at: ::core::option::Option<::prost_types::Timestamp>,
2815    /// When the "after" sample was taken (most recent snapshot).
2816    #[prost(message, optional, tag="3")]
2817    pub after_snapshot_at: ::core::option::Option<::prost_types::Timestamp>,
2818    /// True when fewer than two clustering snapshots exist for the group,
2819    /// so no shift can be computed yet. Admin renders an "awaiting next
2820    /// clustering cycle" empty state.
2821    #[prost(bool, tag="4")]
2822    pub insufficient_history: bool,
2823}
2824// ─── Short-code messages ────────────────────────────────────────────────────
2825
2826/// Request to resolve a campaign's short-code, lazily generating one on
2827/// first call. Used by internal-service callers (the dispatch layer)
2828/// when assembling a third-party-channel deeplink:
2829/// `links.pidgr.com/c/{short_code}?t={token}`.
2830#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2831pub struct ResolveOrCreateShortCodeRequest {
2832    /// The campaign whose short-code is being resolved.
2833    /// Constraints: Required, must be a UUID and exist within the caller's organization.
2834    #[prost(string, tag="1")]
2835    pub campaign_id: ::prost::alloc::string::String,
2836}
2837/// Response carrying the resolved short-code. The same campaign always
2838/// resolves to the same code for its lifetime; the value is safe to
2839/// cache by the caller.
2840#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2841pub struct ResolveOrCreateShortCodeResponse {
2842    /// 8-character base62 short-code stable for the campaign's lifetime.
2843    #[prost(string, tag="1")]
2844    pub short_code: ::prost::alloc::string::String,
2845}
2846/// Request to look up a campaign by its public short-code. Called by the
2847/// native app when the recipient taps a third-party-channel deeplink and
2848/// the URL handler needs to route to the right campaign card. Designed to
2849/// be safe to call without authentication — the response carries no PII
2850/// and only enough context for the app to route correctly and show org
2851/// branding before the auth gate.
2852#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2853pub struct GetCampaignByShortCodeRequest {
2854    /// The 8-character short-code from the deeplink path.
2855    /// Constraints: Required, exactly 8 base62 characters.
2856    #[prost(string, tag="1")]
2857    pub short_code: ::prost::alloc::string::String,
2858}
2859/// Response carrying the minimum metadata the native app needs to route
2860/// the deeplink. Subject is the campaign's title text (already visible
2861/// in the recipient's inbox after dispatch — no new PII exposure). Body
2862/// content, audience size, delivery status and any other operational
2863/// fields are NOT included; the app fetches those via authenticated
2864/// `GetCampaign` after the recipient signs in.
2865#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2866pub struct GetCampaignByShortCodeResponse {
2867    /// Campaign UUID — the app uses this for the authenticated `GetCampaign`
2868    /// follow-up after the deeplink token validates.
2869    #[prost(string, tag="1")]
2870    pub campaign_id: ::prost::alloc::string::String,
2871    /// Organization UUID owning the campaign — lets the app pick the
2872    /// correct SSO / sign-in flow when the recipient is logged out.
2873    #[prost(string, tag="2")]
2874    pub org_id: ::prost::alloc::string::String,
2875    /// Display name of the organization for sign-in branding ("Sign in to
2876    /// Acme Inc to view this campaign"). Public information; the
2877    /// organization's profile already exposes it elsewhere.
2878    #[prost(string, tag="3")]
2879    pub organization_name: ::prost::alloc::string::String,
2880    /// Campaign subject (title). Same string the recipient already saw in
2881    /// their inbox; included so the deeplink interstitial can show
2882    /// "Acme Inc — All-hands Q3" before the auth gate.
2883    #[prost(string, tag="4")]
2884    pub subject: ::prost::alloc::string::String,
2885}
2886// ─── Messages ───────────────────────────────────────────────────────────────
2887
2888/// A registered device that can receive push notifications.
2889/// INTERNAL: This message is for server-side use only. Use DeviceSummary for API responses.
2890#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2891pub struct Device {
2892    /// Unique identifier for this device.
2893    /// Constraints: UUID format (36 characters).
2894    #[prost(string, tag="1")]
2895    pub device_id: ::prost::alloc::string::String,
2896    /// ID of the user who owns this device.
2897    /// Constraints: UUID format (36 characters).
2898    #[prost(string, tag="2")]
2899    pub user_id: ::prost::alloc::string::String,
2900    /// Mobile platform (iOS or Android).
2901    #[prost(enumeration="Platform", tag="3")]
2902    pub platform: i32,
2903    /// Push token used to send notifications to this device.
2904    #[prost(string, tag="4")]
2905    pub push_token: ::prost::alloc::string::String,
2906    /// Whether the device is currently active and eligible for push delivery.
2907    #[prost(bool, tag="5")]
2908    pub active: bool,
2909    /// Timestamp of the last activity from this device.
2910    #[prost(message, optional, tag="6")]
2911    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
2912    /// Timestamp when the device was first registered.
2913    #[prost(message, optional, tag="7")]
2914    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2915}
2916/// A device summary safe for API responses — excludes sensitive push_token.
2917#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2918pub struct DeviceSummary {
2919    /// Unique identifier for this device.
2920    #[prost(string, tag="1")]
2921    pub device_id: ::prost::alloc::string::String,
2922    /// ID of the user who owns this device.
2923    #[prost(string, tag="2")]
2924    pub user_id: ::prost::alloc::string::String,
2925    /// Mobile platform (iOS or Android).
2926    #[prost(enumeration="Platform", tag="3")]
2927    pub platform: i32,
2928    /// Whether the device is currently active and eligible for push delivery.
2929    #[prost(bool, tag="4")]
2930    pub active: bool,
2931    /// Timestamp of the last activity from this device.
2932    #[prost(message, optional, tag="5")]
2933    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
2934    /// Timestamp when the device was first registered.
2935    #[prost(message, optional, tag="6")]
2936    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2937}
2938/// Request to register a device for push notifications.
2939#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2940pub struct RegisterRequest {
2941    /// Client-generated unique device identifier.
2942    /// Constraints: UUID format (36 characters).
2943    #[prost(string, tag="1")]
2944    pub device_id: ::prost::alloc::string::String,
2945    /// Mobile platform of the device.
2946    #[prost(enumeration="Platform", tag="2")]
2947    pub platform: i32,
2948    /// Push token obtained from the push notification provider on the client.
2949    /// Constraints: Max length 4096 characters.
2950    #[prost(string, tag="3")]
2951    pub push_token: ::prost::alloc::string::String,
2952}
2953/// Response after registering a device.
2954#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2955pub struct RegisterResponse {
2956    /// The registered device summary (excludes push_token).
2957    #[prost(message, optional, tag="1")]
2958    pub device: ::core::option::Option<DeviceSummary>,
2959}
2960/// Request to deactivate a device, stopping push notifications.
2961#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2962pub struct DeactivateRequest {
2963    /// ID of the device to deactivate.
2964    /// Constraints: UUID format (36 characters).
2965    #[prost(string, tag="1")]
2966    pub device_id: ::prost::alloc::string::String,
2967}
2968/// Response after deactivating a device.
2969#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2970pub struct DeactivateResponse {
2971    /// Whether the device was successfully deactivated.
2972    #[prost(bool, tag="1")]
2973    pub success: bool,
2974}
2975/// Request to list all devices for the authenticated user.
2976#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2977pub struct ListDevicesRequest {
2978}
2979/// Response containing all devices for the user.
2980#[derive(Clone, PartialEq, ::prost::Message)]
2981pub struct ListDevicesResponse {
2982    /// List of devices registered to the authenticated user.
2983    #[prost(message, repeated, tag="1")]
2984    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
2985}
2986/// Request to list devices for a specific member (admin use).
2987#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2988pub struct ListMemberDevicesRequest {
2989    /// ID of the user whose devices to list.
2990    /// Constraints: UUID format (36 characters).
2991    #[prost(string, tag="1")]
2992    pub user_id: ::prost::alloc::string::String,
2993}
2994/// Response containing all devices for the specified member.
2995#[derive(Clone, PartialEq, ::prost::Message)]
2996pub struct ListMemberDevicesResponse {
2997    /// List of devices registered to the specified user.
2998    #[prost(message, repeated, tag="1")]
2999    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
3000}
3001// ─── Messages ───────────────────────────────────────────────────────────────
3002
3003/// User-configurable platform settings that apply across all clients.
3004/// All fields use their UNSPECIFIED/zero value to mean "no change" in updates.
3005#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3006pub struct UserSettings {
3007    /// Preferred color scheme for the UI.
3008    #[prost(enumeration="ThemePreference", tag="1")]
3009    pub theme_preference: i32,
3010    /// User's preferred language for the UI and push notifications.
3011    /// Empty string means "use organization default" or "auto-detect".
3012    /// Valid values: en, es, pt-BR, zh, ja.
3013    #[prost(string, tag="2")]
3014    pub preferred_locale: ::prost::alloc::string::String,
3015}
3016/// Structured profile attributes for a user within an organization.
3017/// Populated through admin invitation, mobile onboarding, or SSO attribute sync.
3018#[derive(Clone, PartialEq, ::prost::Message)]
3019pub struct UserProfile {
3020    /// User's given name.
3021    /// Constraints: Max length 200 characters.
3022    #[prost(string, tag="1")]
3023    pub first_name: ::prost::alloc::string::String,
3024    /// User's family name.
3025    /// Constraints: Max length 200 characters.
3026    #[prost(string, tag="2")]
3027    pub last_name: ::prost::alloc::string::String,
3028    /// Department or team within the organization.
3029    /// Constraints: Max length 200 characters.
3030    #[prost(string, tag="3")]
3031    pub department: ::prost::alloc::string::String,
3032    /// Job title.
3033    /// Constraints: Max length 200 characters.
3034    #[prost(string, tag="4")]
3035    pub title: ::prost::alloc::string::String,
3036    /// Phone number.
3037    /// Constraints: Max length 200 characters.
3038    #[prost(string, tag="5")]
3039    pub phone: ::prost::alloc::string::String,
3040    /// Office or geographic location.
3041    /// Constraints: Max length 200 characters.
3042    #[prost(string, tag="6")]
3043    pub location: ::prost::alloc::string::String,
3044    /// Organization-specific employee identifier.
3045    /// Constraints: Max length 200 characters.
3046    #[prost(string, tag="7")]
3047    pub employee_id: ::prost::alloc::string::String,
3048    /// Display name of the user's direct manager.
3049    /// Constraints: Max length 200 characters.
3050    #[prost(string, tag="8")]
3051    pub manager_name: ::prost::alloc::string::String,
3052    /// Employment start date in ISO 8601 format (YYYY-MM-DD).
3053    /// Constraints: Max length 200 characters.
3054    #[prost(string, tag="9")]
3055    pub start_date: ::prost::alloc::string::String,
3056    /// Organization-defined custom attributes for fields not covered by the fixed schema.
3057    /// Constraints: Max 50 entries. Key max length 100 characters, value max length 1000 characters.
3058    #[prost(map="string, string", tag="10")]
3059    pub custom_attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
3060    /// UUID of the user's direct manager within the same organization.
3061    /// Populated from SCIM enterprise extension (manager.value), manual admin
3062    /// assignment, or SSO attribute mapping. Empty if not set.
3063    #[prost(string, tag="11")]
3064    pub manager_id: ::prost::alloc::string::String,
3065}
3066/// A user within an organization.
3067#[derive(Clone, PartialEq, ::prost::Message)]
3068pub struct User {
3069    /// Unique identifier for the user (internal platform UUID, not identity provider subject ID).
3070    #[prost(string, tag="1")]
3071    pub id: ::prost::alloc::string::String,
3072    /// User's email address.
3073    /// Constraints: Max length 254 characters (RFC 5321).
3074    #[prost(string, tag="2")]
3075    pub email: ::prost::alloc::string::String,
3076    /// User's display name.
3077    /// Constraints: Max length 200 characters.
3078    #[prost(string, tag="3")]
3079    pub name: ::prost::alloc::string::String,
3080    /// Current account status.
3081    #[prost(enumeration="UserStatus", tag="5")]
3082    pub status: i32,
3083    /// Timestamp when the user was created.
3084    #[prost(message, optional, tag="6")]
3085    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3086    /// The user's role with its permission set.
3087    #[prost(message, optional, tag="7")]
3088    pub role: ::core::option::Option<Role>,
3089    /// ID of the user's role (for assignment operations).
3090    #[prost(string, tag="8")]
3091    pub role_id: ::prost::alloc::string::String,
3092    /// Structured profile attributes (department, title, etc.).
3093    /// May be empty if the user has not completed their profile.
3094    #[prost(message, optional, tag="9")]
3095    pub profile: ::core::option::Option<UserProfile>,
3096    /// Whether data processing is restricted for this user (GDPR Art. 18).
3097    /// When true, the user is excluded from campaign audiences by default.
3098    #[prost(bool, tag="10")]
3099    pub processing_restricted: bool,
3100    /// Data governance region override. Empty string means "inherit from org default".
3101    /// Valid values: EU, LATAM, BR, APAC, US.
3102    #[prost(string, tag="11")]
3103    pub data_governance_region: ::prost::alloc::string::String,
3104}
3105// ─── Enums ──────────────────────────────────────────────────────────────────
3106
3107/// Lifecycle status of a user account.
3108#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3109#[repr(i32)]
3110pub enum UserStatus {
3111    /// Default value; not a valid status.
3112    Unspecified = 0,
3113    /// User has been invited but has not completed onboarding.
3114    Invited = 1,
3115    /// User is active and can receive messages.
3116    Active = 2,
3117    /// User has been deactivated and will not receive messages.
3118    Deactivated = 3,
3119}
3120impl UserStatus {
3121    /// String value of the enum field names used in the ProtoBuf definition.
3122    ///
3123    /// The values are not transformed in any way and thus are considered stable
3124    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3125    pub fn as_str_name(&self) -> &'static str {
3126        match self {
3127            Self::Unspecified => "USER_STATUS_UNSPECIFIED",
3128            Self::Invited => "USER_STATUS_INVITED",
3129            Self::Active => "USER_STATUS_ACTIVE",
3130            Self::Deactivated => "USER_STATUS_DEACTIVATED",
3131        }
3132    }
3133    /// Creates an enum from field names used in the ProtoBuf definition.
3134    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3135        match value {
3136            "USER_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
3137            "USER_STATUS_INVITED" => Some(Self::Invited),
3138            "USER_STATUS_ACTIVE" => Some(Self::Active),
3139            "USER_STATUS_DEACTIVATED" => Some(Self::Deactivated),
3140            _ => None,
3141        }
3142    }
3143}
3144/// User's preferred color scheme.
3145#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3146#[repr(i32)]
3147pub enum ThemePreference {
3148    /// Default value; treated as SYSTEM when reading, "no change" when updating.
3149    Unspecified = 0,
3150    /// Always use light mode regardless of system setting.
3151    Light = 1,
3152    /// Always use dark mode regardless of system setting.
3153    Dark = 2,
3154    /// Follow the operating system or browser preference.
3155    System = 3,
3156}
3157impl ThemePreference {
3158    /// String value of the enum field names used in the ProtoBuf definition.
3159    ///
3160    /// The values are not transformed in any way and thus are considered stable
3161    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3162    pub fn as_str_name(&self) -> &'static str {
3163        match self {
3164            Self::Unspecified => "THEME_PREFERENCE_UNSPECIFIED",
3165            Self::Light => "THEME_PREFERENCE_LIGHT",
3166            Self::Dark => "THEME_PREFERENCE_DARK",
3167            Self::System => "THEME_PREFERENCE_SYSTEM",
3168        }
3169    }
3170    /// Creates an enum from field names used in the ProtoBuf definition.
3171    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3172        match value {
3173            "THEME_PREFERENCE_UNSPECIFIED" => Some(Self::Unspecified),
3174            "THEME_PREFERENCE_LIGHT" => Some(Self::Light),
3175            "THEME_PREFERENCE_DARK" => Some(Self::Dark),
3176            "THEME_PREFERENCE_SYSTEM" => Some(Self::System),
3177            _ => None,
3178        }
3179    }
3180}
3181// ─── Messages ───────────────────────────────────────────────────────────────
3182
3183/// A named collection of users within an organization, used for campaign
3184/// audience targeting (recipient groups).
3185#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3186pub struct Group {
3187    /// Unique identifier for the group.
3188    #[prost(string, tag="1")]
3189    pub id: ::prost::alloc::string::String,
3190    /// Human-readable display name (unique within the organization).
3191    /// Constraints: Max length 200 characters.
3192    #[prost(string, tag="2")]
3193    pub name: ::prost::alloc::string::String,
3194    /// Optional description of the group's purpose.
3195    /// Constraints: Max length 1000 characters.
3196    #[prost(string, tag="3")]
3197    pub description: ::prost::alloc::string::String,
3198    /// Number of users currently in the group.
3199    #[prost(int32, tag="4")]
3200    pub member_count: i32,
3201    /// Timestamp when the group was created.
3202    #[prost(message, optional, tag="5")]
3203    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3204    /// Timestamp when the group was last updated.
3205    #[prost(message, optional, tag="6")]
3206    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
3207    /// Whether this is the organization's default group (cannot be deleted or renamed).
3208    #[prost(bool, tag="7")]
3209    pub is_default: bool,
3210    /// ID of the user who created this group. Empty for system-seeded defaults.
3211    #[prost(string, tag="8")]
3212    pub created_by: ::prost::alloc::string::String,
3213}
3214/// Request to create a new group.
3215#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3216pub struct CreateGroupRequest {
3217    /// Display name for the group. Required.
3218    /// Constraints: Max length 200 characters.
3219    #[prost(string, tag="1")]
3220    pub name: ::prost::alloc::string::String,
3221    /// Optional description.
3222    /// Constraints: Max length 1000 characters.
3223    #[prost(string, tag="2")]
3224    pub description: ::prost::alloc::string::String,
3225}
3226/// Response after creating a group.
3227#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3228pub struct CreateGroupResponse {
3229    /// The newly created group.
3230    #[prost(message, optional, tag="1")]
3231    pub group: ::core::option::Option<Group>,
3232}
3233/// Request to retrieve a group by ID.
3234#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3235pub struct GetGroupRequest {
3236    /// ID of the group to retrieve. Required.
3237    #[prost(string, tag="1")]
3238    pub group_id: ::prost::alloc::string::String,
3239}
3240/// Response containing the requested group.
3241#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3242pub struct GetGroupResponse {
3243    /// The requested group.
3244    #[prost(message, optional, tag="1")]
3245    pub group: ::core::option::Option<Group>,
3246}
3247/// Request to list groups in the organization with pagination.
3248#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3249pub struct ListGroupsRequest {
3250    /// Pagination parameters.
3251    #[prost(message, optional, tag="1")]
3252    pub pagination: ::core::option::Option<Pagination>,
3253}
3254/// Response containing a page of groups.
3255#[derive(Clone, PartialEq, ::prost::Message)]
3256pub struct ListGroupsResponse {
3257    /// Groups in this page.
3258    #[prost(message, repeated, tag="1")]
3259    pub groups: ::prost::alloc::vec::Vec<Group>,
3260    /// Pagination metadata for fetching subsequent pages.
3261    #[prost(message, optional, tag="2")]
3262    pub pagination_meta: ::core::option::Option<PaginationMeta>,
3263}
3264/// Request to update a group's name and/or description.
3265#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3266pub struct UpdateGroupRequest {
3267    /// ID of the group to update. Required.
3268    #[prost(string, tag="1")]
3269    pub group_id: ::prost::alloc::string::String,
3270    /// New display name. If empty, the name is not changed.
3271    /// Default groups cannot be renamed.
3272    /// Constraints: Max length 200 characters.
3273    #[prost(string, tag="2")]
3274    pub name: ::prost::alloc::string::String,
3275    /// New description. If empty, the description is not changed.
3276    /// Constraints: Max length 1000 characters.
3277    #[prost(string, tag="3")]
3278    pub description: ::prost::alloc::string::String,
3279}
3280/// Response after updating a group.
3281#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3282pub struct UpdateGroupResponse {
3283    /// The updated group.
3284    #[prost(message, optional, tag="1")]
3285    pub group: ::core::option::Option<Group>,
3286}
3287/// Request to delete a group.
3288#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3289pub struct DeleteGroupRequest {
3290    /// ID of the group to delete. Required.
3291    /// Default groups cannot be deleted.
3292    #[prost(string, tag="1")]
3293    pub group_id: ::prost::alloc::string::String,
3294}
3295/// Response after deleting a group.
3296#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3297pub struct DeleteGroupResponse {
3298}
3299/// Request to add users to a group.
3300#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3301pub struct AddGroupMembersRequest {
3302    /// ID of the group to add members to. Required.
3303    #[prost(string, tag="1")]
3304    pub group_id: ::prost::alloc::string::String,
3305    /// IDs of users to add. Must belong to the same organization.
3306    /// Adding an existing member is a no-op (idempotent).
3307    /// Constraints: Max 100 user IDs per request.
3308    #[prost(string, repeated, tag="2")]
3309    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3310}
3311/// Response after adding group members.
3312#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3313pub struct AddGroupMembersResponse {
3314    /// The group with updated member_count.
3315    #[prost(message, optional, tag="1")]
3316    pub group: ::core::option::Option<Group>,
3317}
3318/// Request to remove users from a group.
3319#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3320pub struct RemoveGroupMembersRequest {
3321    /// ID of the group to remove members from. Required.
3322    #[prost(string, tag="1")]
3323    pub group_id: ::prost::alloc::string::String,
3324    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
3325    /// Constraints: Max 100 user IDs per request.
3326    #[prost(string, repeated, tag="2")]
3327    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3328}
3329/// Response after removing group members.
3330#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3331pub struct RemoveGroupMembersResponse {
3332    /// The group with updated member_count.
3333    #[prost(message, optional, tag="1")]
3334    pub group: ::core::option::Option<Group>,
3335}
3336/// Request to list members of a group with pagination.
3337#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3338pub struct ListGroupMembersRequest {
3339    /// ID of the group whose members to list. Required.
3340    #[prost(string, tag="1")]
3341    pub group_id: ::prost::alloc::string::String,
3342    /// Pagination parameters.
3343    #[prost(message, optional, tag="2")]
3344    pub pagination: ::core::option::Option<Pagination>,
3345}
3346/// Response containing a page of group members.
3347#[derive(Clone, PartialEq, ::prost::Message)]
3348pub struct ListGroupMembersResponse {
3349    /// Users in this page.
3350    #[prost(message, repeated, tag="1")]
3351    pub users: ::prost::alloc::vec::Vec<User>,
3352    /// Pagination metadata for fetching subsequent pages.
3353    #[prost(message, optional, tag="2")]
3354    pub pagination_meta: ::core::option::Option<PaginationMeta>,
3355}
3356/// A group membership entry for batch lookups.
3357#[derive(Clone, PartialEq, ::prost::Message)]
3358pub struct UserGroupMembership {
3359    /// ID of the user.
3360    #[prost(string, tag="1")]
3361    pub user_id: ::prost::alloc::string::String,
3362    /// Groups the user belongs to.
3363    #[prost(message, repeated, tag="2")]
3364    pub groups: ::prost::alloc::vec::Vec<Group>,
3365}
3366/// Request to get group memberships for a batch of users.
3367#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3368pub struct GetUserGroupMembershipsRequest {
3369    /// IDs of users to look up. Required.
3370    /// Constraints: Max 200 user IDs per request.
3371    #[prost(string, repeated, tag="1")]
3372    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3373}
3374/// Response containing group memberships for the requested users.
3375#[derive(Clone, PartialEq, ::prost::Message)]
3376pub struct GetUserGroupMembershipsResponse {
3377    /// Group memberships per user. Only users with at least one group are included.
3378    #[prost(message, repeated, tag="1")]
3379    pub memberships: ::prost::alloc::vec::Vec<UserGroupMembership>,
3380}
3381// ─── Messages ───────────────────────────────────────────────────────────────
3382
3383/// A single touch event captured from the mobile app.
3384#[derive(Clone, PartialEq, ::prost::Message)]
3385pub struct TouchEvent {
3386    /// Screen name from React Navigation route.
3387    /// Constraints: Max length 200 characters.
3388    #[prost(string, tag="1")]
3389    pub screen_name: ::prost::alloc::string::String,
3390    /// Horizontal coordinate as a percentage of screen width (0.0–1.0).
3391    /// Constraints: Range 0.0 to 1.0 inclusive.
3392    #[prost(float, tag="2")]
3393    pub x_pct: f32,
3394    /// Vertical coordinate as a percentage of screen height (0.0–1.0).
3395    /// Constraints: Range 0.0 to 1.0 inclusive.
3396    #[prost(float, tag="3")]
3397    pub y_pct: f32,
3398    /// Type of touch event.
3399    #[prost(enumeration="TouchEventType", tag="4")]
3400    pub event_type: i32,
3401    /// Screen width in device pixels at the time of capture.
3402    #[prost(int32, tag="5")]
3403    pub screen_width: i32,
3404    /// Screen height in device pixels at the time of capture.
3405    #[prost(int32, tag="6")]
3406    pub screen_height: i32,
3407    /// Client-side timestamp when the touch occurred.
3408    #[prost(message, optional, tag="7")]
3409    pub client_timestamp: ::core::option::Option<::prost_types::Timestamp>,
3410    /// Campaign ID if the touch occurred during a campaign message view.
3411    /// Empty string for organic (non-campaign) navigation.
3412    #[prost(string, tag="8")]
3413    pub campaign_id: ::prost::alloc::string::String,
3414}
3415/// Request to ingest a batch of touch events from the mobile app.
3416#[derive(Clone, PartialEq, ::prost::Message)]
3417pub struct IngestTouchEventsRequest {
3418    /// Batch of touch events to ingest.
3419    /// Constraints: Max 100 events per batch.
3420    #[prost(message, repeated, tag="1")]
3421    pub events: ::prost::alloc::vec::Vec<TouchEvent>,
3422}
3423/// Response after ingesting touch events.
3424#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3425pub struct IngestTouchEventsResponse {
3426    /// Number of events successfully ingested.
3427    #[prost(int32, tag="1")]
3428    pub ingested_count: i32,
3429}
3430/// A single aggregated data point in a heatmap grid cell.
3431#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3432pub struct HeatmapDataPoint {
3433    /// Grid cell horizontal center as a percentage (0.0–1.0).
3434    #[prost(float, tag="1")]
3435    pub x_pct: f32,
3436    /// Grid cell vertical center as a percentage (0.0–1.0).
3437    #[prost(float, tag="2")]
3438    pub y_pct: f32,
3439    /// Aggregated value for this cell (count, median, or z-score depending on mode).
3440    #[prost(float, tag="3")]
3441    pub value: f32,
3442}
3443/// Request to query aggregated heatmap data for a screen.
3444#[derive(Clone, PartialEq, ::prost::Message)]
3445pub struct QueryHeatmapDataRequest {
3446    /// Screen name to query.
3447    /// Constraints: Max length 200 characters.
3448    #[prost(string, tag="1")]
3449    pub screen_name: ::prost::alloc::string::String,
3450    /// Start of the time range filter (inclusive).
3451    #[prost(message, optional, tag="2")]
3452    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
3453    /// End of the time range filter (inclusive).
3454    #[prost(message, optional, tag="3")]
3455    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
3456    /// Optional: filter by campaign ID.
3457    /// Constraints: UUID format (36 characters).
3458    #[prost(string, tag="4")]
3459    pub campaign_id: ::prost::alloc::string::String,
3460    /// Grid resolution for coordinate rounding. Default: 0.02 (50×50 grid).
3461    /// Constraints: Range 0.005 to 0.1.
3462    #[prost(float, tag="6")]
3463    pub grid_resolution: f32,
3464    /// Aggregation mode (TOTAL or MEDIAN).
3465    #[prost(enumeration="HeatmapMode", tag="7")]
3466    pub mode: i32,
3467    /// Optional: filter by event types. Empty list means all types.
3468    #[prost(enumeration="TouchEventType", repeated, tag="8")]
3469    pub event_types: ::prost::alloc::vec::Vec<i32>,
3470}
3471/// Response containing aggregated heatmap data.
3472#[derive(Clone, PartialEq, ::prost::Message)]
3473pub struct QueryHeatmapDataResponse {
3474    /// Aggregated data points for heatmap rendering.
3475    #[prost(message, repeated, tag="1")]
3476    pub data_points: ::prost::alloc::vec::Vec<HeatmapDataPoint>,
3477    /// URL to a mobile-captured screenshot for this screen, if available.
3478    /// Empty string when no screenshot exists.
3479    #[prost(string, tag="3")]
3480    pub screenshot_url: ::prost::alloc::string::String,
3481    /// Whether per-cohort bucket breakdowns are available (k >= 5).
3482    #[prost(bool, tag="4")]
3483    pub cohort_enabled: bool,
3484}
3485/// Request to upload a screenshot captured from the mobile app.
3486#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3487pub struct UploadScreenshotRequest {
3488    /// Screen name matching React Navigation route (e.g. "MessageDetail::<campaign_uuid>").
3489    /// Constraints: Max length 200 characters.
3490    #[prost(string, tag="1")]
3491    pub screen_name: ::prost::alloc::string::String,
3492    /// App version that captured the screenshot (e.g. "1.15.0").
3493    #[prost(string, tag="2")]
3494    pub app_version: ::prost::alloc::string::String,
3495    /// PNG image data.
3496    /// Constraints: Max 512KB.
3497    #[prost(bytes="vec", tag="3")]
3498    pub image_data: ::prost::alloc::vec::Vec<u8>,
3499}
3500/// Response after uploading a screenshot.
3501#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3502pub struct UploadScreenshotResponse {
3503    /// S3 URL where the screenshot was stored.
3504    #[prost(string, tag="1")]
3505    pub url: ::prost::alloc::string::String,
3506}
3507/// A screen screenshot stored as a static asset.
3508#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3509pub struct ScreenScreenshot {
3510    /// Screen name matching React Navigation route.
3511    #[prost(string, tag="1")]
3512    pub screen_name: ::prost::alloc::string::String,
3513    /// S3 URL to the screenshot image.
3514    #[prost(string, tag="2")]
3515    pub url: ::prost::alloc::string::String,
3516    /// App version this screenshot corresponds to.
3517    #[prost(string, tag="3")]
3518    pub app_version: ::prost::alloc::string::String,
3519}
3520/// Request to list available screen screenshots.
3521#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3522pub struct ListScreenshotsRequest {
3523}
3524/// Response containing available screen screenshots.
3525#[derive(Clone, PartialEq, ::prost::Message)]
3526pub struct ListScreenshotsResponse {
3527    /// Available screen screenshots with their URLs and versions.
3528    #[prost(message, repeated, tag="1")]
3529    pub screenshots: ::prost::alloc::vec::Vec<ScreenScreenshot>,
3530}
3531// ─── Enums ──────────────────────────────────────────────────────────────────
3532
3533/// Type of touch event captured on the mobile app.
3534#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3535#[repr(i32)]
3536pub enum TouchEventType {
3537    /// Default value; not a valid event type.
3538    Unspecified = 0,
3539    /// A single tap on the screen.
3540    Tap = 1,
3541    /// A long press (held for 500ms+).
3542    LongPress = 2,
3543    /// A periodic scroll position sample (viewport midpoint every 2s).
3544    Scroll = 3,
3545    /// The user tapped an action button (e.g. "Acknowledge").
3546    ActionClick = 4,
3547}
3548impl TouchEventType {
3549    /// String value of the enum field names used in the ProtoBuf definition.
3550    ///
3551    /// The values are not transformed in any way and thus are considered stable
3552    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3553    pub fn as_str_name(&self) -> &'static str {
3554        match self {
3555            Self::Unspecified => "TOUCH_EVENT_TYPE_UNSPECIFIED",
3556            Self::Tap => "TOUCH_EVENT_TYPE_TAP",
3557            Self::LongPress => "TOUCH_EVENT_TYPE_LONG_PRESS",
3558            Self::Scroll => "TOUCH_EVENT_TYPE_SCROLL",
3559            Self::ActionClick => "TOUCH_EVENT_TYPE_ACTION_CLICK",
3560        }
3561    }
3562    /// Creates an enum from field names used in the ProtoBuf definition.
3563    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3564        match value {
3565            "TOUCH_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
3566            "TOUCH_EVENT_TYPE_TAP" => Some(Self::Tap),
3567            "TOUCH_EVENT_TYPE_LONG_PRESS" => Some(Self::LongPress),
3568            "TOUCH_EVENT_TYPE_SCROLL" => Some(Self::Scroll),
3569            "TOUCH_EVENT_TYPE_ACTION_CLICK" => Some(Self::ActionClick),
3570            _ => None,
3571        }
3572    }
3573}
3574/// Aggregation mode for heatmap data queries.
3575#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3576#[repr(i32)]
3577pub enum HeatmapMode {
3578    /// Default value; not a valid mode.
3579    Unspecified = 0,
3580    /// Sum of all cohort buckets' touches per grid cell (default).
3581    Total = 1,
3582    /// Median touch count per grid cell across cohort buckets.
3583    Median = 2,
3584}
3585impl HeatmapMode {
3586    /// String value of the enum field names used in the ProtoBuf definition.
3587    ///
3588    /// The values are not transformed in any way and thus are considered stable
3589    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3590    pub fn as_str_name(&self) -> &'static str {
3591        match self {
3592            Self::Unspecified => "HEATMAP_MODE_UNSPECIFIED",
3593            Self::Total => "HEATMAP_MODE_TOTAL",
3594            Self::Median => "HEATMAP_MODE_MEDIAN",
3595        }
3596    }
3597    /// Creates an enum from field names used in the ProtoBuf definition.
3598    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3599        match value {
3600            "HEATMAP_MODE_UNSPECIFIED" => Some(Self::Unspecified),
3601            "HEATMAP_MODE_TOTAL" => Some(Self::Total),
3602            "HEATMAP_MODE_MEDIAN" => Some(Self::Median),
3603            _ => None,
3604        }
3605    }
3606}
3607// ─── Messages ───────────────────────────────────────────────────────────────
3608
3609/// A single entry in a user's inbox, combining a message with its delivery state.
3610#[derive(Clone, PartialEq, ::prost::Message)]
3611pub struct InboxEntry {
3612    /// ID of the delivery record for this inbox entry.
3613    /// Constraints: UUID format (36 characters).
3614    #[prost(string, tag="1")]
3615    pub delivery_id: ::prost::alloc::string::String,
3616    /// The fully rendered message content.
3617    #[prost(message, optional, tag="2")]
3618    pub message: ::core::option::Option<Message>,
3619    /// Current delivery status (e.g. DELIVERED, ACKNOWLEDGED).
3620    #[prost(enumeration="DeliveryStatus", tag="3")]
3621    pub status: i32,
3622    /// Whether the user has read this message.
3623    #[prost(bool, tag="4")]
3624    pub read: bool,
3625    /// Timestamp when the message was received in the inbox.
3626    #[prost(message, optional, tag="5")]
3627    pub received_at: ::core::option::Option<::prost_types::Timestamp>,
3628    /// Discriminator: PRIMARY for normal deliveries, ESCALATION for delivery-grade
3629    /// escalations. Mirrors Delivery.kind so inbox-sync clients can branch on the
3630    /// same dimension as listDeliveries clients.
3631    #[prost(enumeration="delivery::Kind", tag="6")]
3632    pub kind: i32,
3633    /// For ESCALATION entries, the UUID of the unacked delivery that triggered this
3634    /// entry. Empty for PRIMARY entries.
3635    #[prost(string, tag="7")]
3636    pub parent_delivery_id: ::prost::alloc::string::String,
3637    /// The locale the body actually rendered in after fallback resolution. Empty
3638    /// for legacy/PRIMARY entries.
3639    #[prost(string, tag="8")]
3640    pub rendered_locale: ::prost::alloc::string::String,
3641    /// Optional out-of-band context mirrored from the underlying delivery.
3642    /// See `DeliveryMetadata` for which delivery kinds populate which fields.
3643    /// Empty for PRIMARY entries.
3644    #[prost(message, optional, tag="9")]
3645    pub metadata: ::core::option::Option<DeliveryMetadata>,
3646}
3647/// Request to sync inbox entries since a given timestamp.
3648#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3649pub struct SyncRequest {
3650    /// Fetch entries newer than this timestamp. Omit for initial sync.
3651    #[prost(message, optional, tag="1")]
3652    pub since: ::core::option::Option<::prost_types::Timestamp>,
3653    /// Maximum number of entries to return.
3654    /// Constraints: Valid range 1 to 200.
3655    #[prost(int32, tag="2")]
3656    pub limit: i32,
3657}
3658/// Response containing synced inbox entries.
3659#[derive(Clone, PartialEq, ::prost::Message)]
3660pub struct SyncResponse {
3661    /// Inbox entries newer than the requested timestamp.
3662    #[prost(message, repeated, tag="1")]
3663    pub entries: ::prost::alloc::vec::Vec<InboxEntry>,
3664    /// Cursor timestamp to use for the next sync call.
3665    #[prost(message, optional, tag="2")]
3666    pub next_since: ::core::option::Option<::prost_types::Timestamp>,
3667}
3668/// Request to mark a message as read.
3669#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3670pub struct MarkReadRequest {
3671    /// ID of the delivery to mark as read.
3672    /// Constraints: UUID format (36 characters).
3673    #[prost(string, tag="1")]
3674    pub delivery_id: ::prost::alloc::string::String,
3675}
3676/// Response after marking a message as read.
3677#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3678pub struct MarkReadResponse {
3679    /// Whether the read status was successfully updated.
3680    #[prost(bool, tag="1")]
3681    pub success: bool,
3682}
3683/// Request to retrieve a single message by delivery ID.
3684#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3685pub struct GetMessageRequest {
3686    /// ID of the delivery to retrieve.
3687    /// Constraints: UUID format (36 characters).
3688    #[prost(string, tag="1")]
3689    pub delivery_id: ::prost::alloc::string::String,
3690}
3691/// Response containing the requested inbox entry.
3692#[derive(Clone, PartialEq, ::prost::Message)]
3693pub struct GetMessageResponse {
3694    /// The inbox entry for the requested delivery.
3695    #[prost(message, optional, tag="1")]
3696    pub entry: ::core::option::Option<InboxEntry>,
3697}
3698// ─── Messages ───────────────────────────────────────────────────────────────
3699
3700/// A behavioral archetype describing a cohort pattern (never an individual).
3701/// Derived from k-anonymized, DP-noised behavioral feature vectors.
3702#[derive(Clone, PartialEq, ::prost::Message)]
3703pub struct Archetype {
3704    /// Human-readable label (e.g., "Swift Acknowledger", "Thorough Reader").
3705    #[prost(string, tag="1")]
3706    pub label: ::prost::alloc::string::String,
3707    /// Description of the behavioral pattern this archetype represents.
3708    #[prost(string, tag="2")]
3709    pub description: ::prost::alloc::string::String,
3710    /// Proportion of the group that belongs to this archetype (0.0-1.0).
3711    #[prost(float, tag="3")]
3712    pub percentage: f32,
3713    /// Centroid of the behavioral feature vector for this archetype.
3714    /// Keys are stable dimension names from the feature extractor
3715    /// vocabulary (e.g., "tap_density", "engagement_depth",
3716    /// "scroll_velocity_p50", "idle_gap_p75"). Single-letter keys are
3717    /// reserved for backward compatibility with pre-v0.64 servers and
3718    /// SHALL be ignored by clients.
3719    #[prost(map="string, double", tag="4")]
3720    pub feature_centroid: ::std::collections::HashMap<::prost::alloc::string::String, f64>,
3721    /// Per-dimension distribution of the archetype's members. Lets the
3722    /// admin render percentile bands instead of single-point centroids.
3723    /// Absent until at least k members exist in the cluster. Keys mirror
3724    /// `feature_centroid` keys.
3725    #[prost(map="string, message", tag="5")]
3726    pub feature_breakdown: ::std::collections::HashMap<::prost::alloc::string::String, DimensionStats>,
3727    /// Tap density heatmap aggregated across sessions for this
3728    /// archetype. Cohort-level only — never per-session timing.
3729    /// Absent when fewer than k sessions have tap data.
3730    #[prost(message, optional, tag="6")]
3731    pub tap_heatmap: ::core::option::Option<TapHeatmap>,
3732    /// Forecast of cluster share at fixed horizons (7/14/30/90 days).
3733    /// Absent during cold start before historical clustering runs exist
3734    /// to extrapolate from.
3735    #[prost(message, optional, tag="7")]
3736    pub forecast: ::core::option::Option<ArchetypeForecast>,
3737    /// Sessions that sit at the median and quartiles of the archetype's
3738    /// centroid distance, ranked by distance. Bounded at three entries.
3739    /// Absent until at least 50 sessions have been scored.
3740    /// Sessions can come from any client that emits to ReplayService —
3741    /// mobile (iOS, Android) or desktop (macOS, Windows, Linux).
3742    #[prost(message, repeated, tag="8")]
3743    pub exemplar_sessions: ::prost::alloc::vec::Vec<ExemplarSession>,
3744    /// Per-screen dwell time distribution, derived from session replay.
3745    /// Absent when fewer than k sessions per screen exist.
3746    #[prost(message, optional, tag="9")]
3747    pub screen_dwell: ::core::option::Option<ScreenDwell>,
3748    /// End-to-end response latencies (push delivered → read → ack) for
3749    /// members of this archetype, as percentiles. Absent until at least
3750    /// k campaign deliveries have been recorded for this archetype.
3751    #[prost(message, optional, tag="10")]
3752    pub response_timeline: ::core::option::Option<ResponseTimeline>,
3753    /// Where this archetype came from. UNSPECIFIED on responses from
3754    /// pre-v0.81 servers; clients SHOULD treat UNSPECIFIED as ML for
3755    /// backward compatibility (provisional output is always labelled).
3756    #[prost(enumeration="ArchetypeSource", tag="11")]
3757    pub source: i32,
3758}
3759/// Per-dimension distribution stats for one feature dimension within
3760/// an archetype's cohort. All values are in the same units as
3761/// `Archetype.feature_centroid`. Used to render percentile bands on
3762/// the admin's behavioral profile panel.
3763#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3764pub struct DimensionStats {
3765    /// Centroid value (same as Archetype.feature_centroid\[key\]).
3766    #[prost(double, tag="1")]
3767    pub centroid: f64,
3768    /// 25th percentile across the archetype's members.
3769    #[prost(double, tag="2")]
3770    pub p25: f64,
3771    /// Median across the archetype's members.
3772    #[prost(double, tag="3")]
3773    pub p50: f64,
3774    /// 75th percentile across the archetype's members.
3775    #[prost(double, tag="4")]
3776    pub p75: f64,
3777    /// Median across the entire group (all archetypes), included so the
3778    /// admin can render "this archetype is X% above group median".
3779    #[prost(double, tag="5")]
3780    pub group_p50: f64,
3781}
3782/// A density grid of tap activity for one archetype, normalized to
3783/// \[0.0, 1.0\] where 1.0 is the hottest cell in the cohort. Cohort-
3784/// level only.
3785#[derive(Clone, PartialEq, ::prost::Message)]
3786pub struct TapHeatmap {
3787    /// Width of the density grid in cells.
3788    #[prost(int32, tag="1")]
3789    pub width: i32,
3790    /// Height of the density grid in cells.
3791    #[prost(int32, tag="2")]
3792    pub height: i32,
3793    /// Row-major density values, length must equal width*height. All in
3794    /// \[0.0, 1.0\].
3795    #[prost(double, repeated, tag="3")]
3796    pub values: ::prost::alloc::vec::Vec<f64>,
3797    /// Number of sessions aggregated. Always >= MinFeatureVectorsForClustering
3798    /// when the field is present.
3799    #[prost(int32, tag="4")]
3800    pub session_count: i32,
3801    /// Optional per-event-type breakdown. When present, the writer
3802    /// SHALL emit one entry for each event type in the source data
3803    /// (TAP, LONG_PRESS, SCROLL, ACTION_CLICK).
3804    #[prost(message, repeated, tag="5")]
3805    pub layers: ::prost::alloc::vec::Vec<TapHeatmapLayer>,
3806}
3807/// One per-event-type layer of a TapHeatmap.
3808#[derive(Clone, PartialEq, ::prost::Message)]
3809pub struct TapHeatmapLayer {
3810    /// Event type this layer represents (e.g., "TAP", "LONG_PRESS",
3811    /// "SCROLL", "ACTION_CLICK").
3812    #[prost(string, tag="1")]
3813    pub event_type: ::prost::alloc::string::String,
3814    /// Row-major density values, same dimensions as the parent
3815    /// TapHeatmap. Independently normalized to \[0.0, 1.0\].
3816    #[prost(double, repeated, tag="2")]
3817    pub values: ::prost::alloc::vec::Vec<f64>,
3818}
3819/// Predicted cluster share at fixed horizons with confidence bands.
3820#[derive(Clone, PartialEq, ::prost::Message)]
3821pub struct ArchetypeForecast {
3822    /// Horizons in increasing days. Always one entry each for 7, 14,
3823    /// 30, and 90 days when the field is present.
3824    #[prost(message, repeated, tag="1")]
3825    pub horizons: ::prost::alloc::vec::Vec<ForecastHorizon>,
3826}
3827/// Predicted share at one horizon with a 90% prediction interval.
3828#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3829pub struct ForecastHorizon {
3830    /// Horizon length in days (one of: 7, 14, 30, 90).
3831    #[prost(int32, tag="1")]
3832    pub days: i32,
3833    /// Predicted fraction of the group falling in this archetype at the
3834    /// horizon (0.0-1.0).
3835    #[prost(double, tag="2")]
3836    pub predicted_share: f64,
3837    /// 5th-percentile lower bound of the prediction interval.
3838    #[prost(double, tag="3")]
3839    pub lower: f64,
3840    /// 95th-percentile upper bound of the prediction interval.
3841    #[prost(double, tag="4")]
3842    pub upper: f64,
3843    /// Confidence in this horizon's prediction.
3844    #[prost(enumeration="ConfidenceLevel", tag="5")]
3845    pub confidence: i32,
3846}
3847/// Pointer to a representative session for one archetype, ranked by
3848/// distance to the archetype centroid.
3849#[derive(Clone, PartialEq, ::prost::Message)]
3850pub struct ExemplarSession {
3851    /// Session recording ID retrievable via ReplayService for the same
3852    /// org. Linkable from the admin regardless of originating platform.
3853    #[prost(string, tag="1")]
3854    pub session_id: ::prost::alloc::string::String,
3855    /// Quantile rank within the archetype: 25, 50, or 75. The writer
3856    /// emits at most one session per rank.
3857    #[prost(int32, tag="2")]
3858    pub rank: i32,
3859    /// L2 distance from the session's feature vector to the centroid.
3860    #[prost(double, tag="3")]
3861    pub distance: f64,
3862    /// Optional duration metadata for quick admin labelling.
3863    #[prost(int32, tag="4")]
3864    pub duration_seconds: i32,
3865    /// Optional platform identifier from the vocabulary
3866    /// {"ios", "android", "macos", "windows", "linux"}. The admin
3867    /// renders unknown values verbatim for forward compatibility.
3868    #[prost(string, tag="5")]
3869    pub platform: ::prost::alloc::string::String,
3870}
3871/// Per-screen dwell distribution within an archetype. Lets the admin
3872/// surface "this archetype lingers 8.2s on the Message Detail screen
3873/// vs 0.4s on the Inbox list".
3874#[derive(Clone, PartialEq, ::prost::Message)]
3875pub struct ScreenDwell {
3876    /// One entry per screen. Screens with fewer than k members in the
3877    /// archetype are dropped from the list (not marked as absent).
3878    #[prost(message, repeated, tag="1")]
3879    pub entries: ::prost::alloc::vec::Vec<ScreenDwellEntry>,
3880}
3881#[derive(Clone, PartialEq, ::prost::Message)]
3882pub struct ScreenDwellEntry {
3883    /// Stable screen identifier (e.g., "MessageDetail", "Inbox",
3884    /// "ProfileSettings"). Sourced from the same screen_name vocabulary
3885    /// used by heatmap_cells.
3886    #[prost(string, tag="1")]
3887    pub screen_name: ::prost::alloc::string::String,
3888    /// Median dwell time in seconds for this archetype on this screen.
3889    #[prost(double, tag="2")]
3890    pub median_seconds: f64,
3891    /// 75th-percentile dwell time in seconds.
3892    #[prost(double, tag="3")]
3893    pub p75_seconds: f64,
3894    /// Number of distinct sessions aggregated for this screen.
3895    #[prost(int32, tag="4")]
3896    pub session_count: i32,
3897}
3898/// End-to-end response latencies for members of one archetype, in
3899/// seconds. Each percentile is computed across all qualifying campaign
3900/// deliveries for the archetype's members within the rolling window.
3901#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3902pub struct ResponseTimeline {
3903    /// Time from `delivered_at` to `read_at`, in seconds.
3904    #[prost(message, optional, tag="1")]
3905    pub read_after_delivered: ::core::option::Option<LatencyPercentiles>,
3906    /// Time from `read_at` to `acknowledged_at`, in seconds. Only
3907    /// includes deliveries that were both read and acknowledged.
3908    #[prost(message, optional, tag="2")]
3909    pub ack_after_read: ::core::option::Option<LatencyPercentiles>,
3910    /// End-to-end time from `delivered_at` to `acknowledged_at`, in
3911    /// seconds. Only includes deliveries that were acknowledged.
3912    #[prost(message, optional, tag="3")]
3913    pub ack_after_delivered: ::core::option::Option<LatencyPercentiles>,
3914    /// Number of deliveries the timeline is computed over.
3915    #[prost(int32, tag="4")]
3916    pub delivery_count: i32,
3917}
3918/// Latency distribution stats. Values are in seconds.
3919#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3920pub struct LatencyPercentiles {
3921    #[prost(double, tag="1")]
3922    pub p50: f64,
3923    #[prost(double, tag="2")]
3924    pub p75: f64,
3925    #[prost(double, tag="3")]
3926    pub p95: f64,
3927}
3928/// A cohort-level prediction for campaign acknowledgment rate.
3929/// Never targets or scores individuals — always represents an audience aggregate.
3930#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3931pub struct CohortPrediction {
3932    /// Predicted ACK rate for the audience (0.0-1.0).
3933    #[prost(float, tag="1")]
3934    pub predicted_ack_rate: f32,
3935    /// Lower bound of the confidence interval.
3936    #[prost(float, tag="2")]
3937    pub confidence_low: f32,
3938    /// Upper bound of the confidence interval.
3939    #[prost(float, tag="3")]
3940    pub confidence_high: f32,
3941    /// Confidence level based on available data volume.
3942    #[prost(enumeration="ConfidenceLevel", tag="4")]
3943    pub confidence_level: i32,
3944    /// Number of anonymous data points used for this prediction.
3945    #[prost(int32, tag="5")]
3946    pub data_point_count: i32,
3947}
3948/// Advisory information for campaign configuration, combining predictions and archetypes.
3949#[derive(Clone, PartialEq, ::prost::Message)]
3950pub struct CampaignAdvisory {
3951    /// Cohort-level ACK prediction for the target audience.
3952    #[prost(message, optional, tag="1")]
3953    pub predicted_ack: ::core::option::Option<CohortPrediction>,
3954    /// Suggested escalation delay in minutes based on historical cohort patterns.
3955    /// 0 if insufficient data.
3956    #[prost(int32, tag="2")]
3957    pub suggested_escalation_delay_minutes: i32,
3958    /// Behavioral archetypes for the target audience.
3959    #[prost(message, repeated, tag="3")]
3960    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
3961}
3962/// Request to retrieve behavioral archetypes for a group.
3963#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3964pub struct GetGroupArchetypesRequest {
3965    /// ID of the group to query archetypes for. Required.
3966    #[prost(string, tag="1")]
3967    pub group_id: ::prost::alloc::string::String,
3968}
3969/// Response containing behavioral archetypes for a group.
3970#[derive(Clone, PartialEq, ::prost::Message)]
3971pub struct GetGroupArchetypesResponse {
3972    /// Behavioral archetypes for the group (empty if insufficient data).
3973    #[prost(message, repeated, tag="1")]
3974    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
3975    /// Number of anonymous feature vectors used for clustering.
3976    #[prost(int32, tag="2")]
3977    pub data_point_count: i32,
3978    /// Why `archetypes` looks the way it does. Lets the UI render a
3979    /// distinct empty-state affordance for "never trained" vs
3980    /// "below threshold" vs "no clusters" vs "ready". See PipelineState.
3981    #[prost(enumeration="PipelineState", tag="3")]
3982    pub pipeline_state: i32,
3983    /// Confidence in the returned archetypes, derived from available data
3984    /// volume. Always CONFIDENCE_LEVEL_LOW when provisional archetypes
3985    /// are returned — clients use this plus `Archetype.source` to render
3986    /// the low-confidence disclaimer.
3987    #[prost(enumeration="ConfidenceLevel", tag="4")]
3988    pub confidence_level: i32,
3989}
3990/// Request to predict cohort-level ACK rate for a campaign configuration.
3991#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3992pub struct PredictCampaignAckRequest {
3993    /// ID of the target audience group. Required.
3994    #[prost(string, tag="1")]
3995    pub group_id: ::prost::alloc::string::String,
3996    /// Template type (optional, for prediction refinement).
3997    #[prost(string, tag="2")]
3998    pub template_type: ::prost::alloc::string::String,
3999    /// Number of workflow steps (optional, for prediction refinement).
4000    #[prost(int32, tag="3")]
4001    pub workflow_step_count: i32,
4002}
4003/// Response containing a cohort-level ACK prediction.
4004#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4005pub struct PredictCampaignAckResponse {
4006    /// Cohort-level prediction.
4007    #[prost(message, optional, tag="1")]
4008    pub prediction: ::core::option::Option<CohortPrediction>,
4009}
4010/// Request for campaign configuration advisory.
4011#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4012pub struct GetCampaignAdvisoryRequest {
4013    /// ID of the target audience group. Required.
4014    #[prost(string, tag="1")]
4015    pub group_id: ::prost::alloc::string::String,
4016    /// Template ID (optional, for advisory context).
4017    #[prost(string, tag="2")]
4018    pub template_id: ::prost::alloc::string::String,
4019    /// Template version (optional).
4020    #[prost(int32, tag="3")]
4021    pub template_version: i32,
4022    /// Number of workflow steps (optional).
4023    #[prost(int32, tag="4")]
4024    pub workflow_step_count: i32,
4025}
4026/// Response containing campaign advisory information.
4027#[derive(Clone, PartialEq, ::prost::Message)]
4028pub struct GetCampaignAdvisoryResponse {
4029    /// Campaign advisory with prediction, suggested escalation, and archetypes.
4030    #[prost(message, optional, tag="1")]
4031    pub advisory: ::core::option::Option<CampaignAdvisory>,
4032}
4033/// Request to generate an AI narrative for a group's insights.
4034#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4035pub struct GetInsightNarrativeRequest {
4036    /// ID of the group to generate a narrative for. Required.
4037    #[prost(string, tag="1")]
4038    pub group_id: ::prost::alloc::string::String,
4039    /// Name of the prompt template to use (e.g., "campaign-advisory", "archetype-explanation").
4040    #[prost(string, tag="2")]
4041    pub prompt_name: ::prost::alloc::string::String,
4042}
4043/// Response containing an AI-generated narrative.
4044#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4045pub struct GetInsightNarrativeResponse {
4046    /// AI-generated narrative text (Markdown formatted).
4047    #[prost(string, tag="1")]
4048    pub narrative: ::prost::alloc::string::String,
4049    /// Timestamp when the narrative was generated.
4050    #[prost(message, optional, tag="2")]
4051    pub generated_at: ::core::option::Option<::prost_types::Timestamp>,
4052    /// Model identifier used for generation.
4053    #[prost(string, tag="3")]
4054    pub model_id: ::prost::alloc::string::String,
4055}
4056/// Request to manually trigger the ML training pipeline.
4057/// Empty — organization is extracted from the JWT.
4058#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4059pub struct TriggerMlPipelineRequest {
4060}
4061/// Response after triggering the ML pipeline.
4062#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4063pub struct TriggerMlPipelineResponse {
4064    /// Remaining manual retrains allowed this month.
4065    #[prost(int32, tag="1")]
4066    pub remaining_this_month: i32,
4067    /// Timestamp of the last successful training (null if never trained).
4068    #[prost(message, optional, tag="2")]
4069    pub last_trained_at: ::core::option::Option<::prost_types::Timestamp>,
4070}
4071/// Request to manually retrigger archetype clustering for a single group
4072/// without rerunning the full SageMaker training pipeline. Reuses the
4073/// already-deployed clustering model.
4074#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4075pub struct TriggerArchetypeClusteringRequest {
4076    /// Group to recluster. Org is extracted from the JWT.
4077    #[prost(string, tag="1")]
4078    pub group_id: ::prost::alloc::string::String,
4079}
4080/// Response after triggering archetype clustering for one group.
4081#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4082pub struct TriggerArchetypeClusteringResponse {
4083    /// Temporal workflow id — useful for client-side dedupe + operator
4084    /// debugging via the Temporal UI.
4085    #[prost(string, tag="1")]
4086    pub workflow_id: ::prost::alloc::string::String,
4087    /// Remaining manual retrains allowed this month. Shares the same
4088    /// monthly counter as TriggerMLPipeline (ml_manual_limit_monthly).
4089    #[prost(int32, tag="2")]
4090    pub remaining_this_month: i32,
4091    /// Timestamp of the last successful archetype clustering for this
4092    /// (org, group), null if never clustered.
4093    #[prost(message, optional, tag="3")]
4094    pub last_clustered_at: ::core::option::Option<::prost_types::Timestamp>,
4095}
4096/// Request to draft a campaign body for a given archetype using Bedrock.
4097/// Used by the Compass "Target this archetype in a new campaign" CTA to
4098/// pre-fill the campaign creation wizard's body field.
4099#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4100pub struct GenerateCampaignBodyDraftRequest {
4101    /// UUID of the source group whose archetype set the label belongs to.
4102    #[prost(string, tag="1")]
4103    pub group_id: ::prost::alloc::string::String,
4104    /// Stable archetype label, e.g. "Swift Acknowledger".
4105    #[prost(string, tag="2")]
4106    pub archetype_label: ::prost::alloc::string::String,
4107    /// Lane-recommended action copy passed through from the admin (e.g.
4108    /// "Simplify the call-to-action"). Used as a tone hint for the prompt.
4109    #[prost(string, tag="3")]
4110    pub lane_action: ::prost::alloc::string::String,
4111}
4112/// Response containing the generated draft body in Markdown.
4113#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4114pub struct GenerateCampaignBodyDraftResponse {
4115    /// Draft Markdown body, 3-5 sentences. Authored as if written for the
4116    /// recipient — does not mention the archetype name.
4117    #[prost(string, tag="1")]
4118    pub body_markdown: ::prost::alloc::string::String,
4119}
4120/// Share of an organization's campaigns exercising one lever.
4121#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4122pub struct LeverShare {
4123    #[prost(enumeration="Lever", tag="1")]
4124    pub lever: i32,
4125    #[prost(int32, tag="2")]
4126    pub count: i32,
4127    /// Fraction of classified campaigns, 0..1.
4128    #[prost(float, tag="3")]
4129    pub share: f32,
4130    /// Where the majority of this lever's classifications came from.
4131    /// Consumers use this together with `avg_confidence` to present
4132    /// rule-derived mixes as estimates rather than model-grade
4133    /// classifications.
4134    #[prost(enumeration="LeverSource", tag="4")]
4135    pub dominant_source: i32,
4136    /// Mean classifier confidence across the campaigns counted here, 0..1.
4137    #[prost(float, tag="5")]
4138    pub avg_confidence: f32,
4139}
4140/// How much messaging lands on a single person over the observed window.
4141#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4142pub struct RecipientLoad {
4143    #[prost(float, tag="1")]
4144    pub median_per_week: f32,
4145    #[prost(float, tag="2")]
4146    pub p90_per_week: f32,
4147    #[prost(int32, tag="3")]
4148    pub users_reached: i32,
4149    #[prost(int32, tag="4")]
4150    pub window_days: i32,
4151    /// Median number of distinct senders reaching one recipient within
4152    /// the same window.
4153    #[prost(float, tag="5")]
4154    pub median_distinct_senders: f32,
4155    /// 90th-percentile number of distinct senders reaching one recipient
4156    /// within the same window.
4157    #[prost(float, tag="6")]
4158    pub p90_distinct_senders: f32,
4159    /// Median number of distinct channels one recipient is reached on
4160    /// within the same window.
4161    #[prost(float, tag="7")]
4162    pub median_distinct_channels: f32,
4163    /// 90th-percentile number of distinct channels one recipient is
4164    /// reached on within the same window.
4165    #[prost(float, tag="8")]
4166    pub p90_distinct_channels: f32,
4167}
4168#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4169pub struct GetOrgCommunicationProfileRequest {
4170}
4171#[derive(Clone, PartialEq, ::prost::Message)]
4172pub struct GetOrgCommunicationProfileResponse {
4173    #[prost(message, repeated, tag="1")]
4174    pub lever_mix: ::prost::alloc::vec::Vec<LeverShare>,
4175    #[prost(message, optional, tag="2")]
4176    pub load: ::core::option::Option<RecipientLoad>,
4177    #[prost(int32, tag="3")]
4178    pub campaigns_analyzed: i32,
4179    /// Fraction of active objectives that have at least one indicator
4180    /// whose evidence comes from outside the product, 0..1.
4181    ///
4182    /// It says how much the rest of the board is worth: an objective
4183    /// observed only through what people answered inside the app has
4184    /// evidence that they said they did it, not evidence that the work
4185    /// changed.
4186    ///
4187    /// Absent when `active_objectives` is zero, because a fraction with no
4188    /// denominator has no value and a present 0.0 would be
4189    /// indistinguishable from genuine coverage of none — opposite facts
4190    /// with opposite consequences. The two counts below travel with it as
4191    /// the second half of the same guarantee.
4192    #[prost(float, optional, tag="4")]
4193    pub evidence_coverage: ::core::option::Option<f32>,
4194    /// Numerator of `evidence_coverage`: active objectives with at least
4195    /// one indicator sourced outside the product.
4196    #[prost(int32, tag="5")]
4197    pub objectives_with_external_evidence: i32,
4198    /// Denominator of `evidence_coverage`: active objectives. Zero means
4199    /// the organization has declared none, which is a supported way to use
4200    /// the product and not an incomplete setup.
4201    #[prost(int32, tag="6")]
4202    pub active_objectives: i32,
4203    /// Median number of days since the organization's indicators were last
4204    /// revised, measured from each indicator's last update.
4205    ///
4206    /// Indicators are rarely revisited when the strategy they serve moves
4207    /// on, and this is the plainest measurable form of that: an ageing
4208    /// median means the board is describing an older intent than the
4209    /// objectives do.
4210    ///
4211    /// Absent when the organization has no indicators. An age of zero
4212    /// would claim they were all just reviewed.
4213    #[prost(int64, optional, tag="7")]
4214    pub median_indicator_review_age_days: ::core::option::Option<i64>,
4215}
4216/// One observation in a diagnosis.
4217///
4218/// Every finding carries the records it was derived from. That is not
4219/// decoration: a statement about an organization that cannot be traced
4220/// back to the campaigns, objectives and indicators that produced it is
4221/// indistinguishable from an opinion, and the reader has no way to
4222/// disagree with it on the facts. At least one of the three reference
4223/// lists is always non-empty.
4224#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4225pub struct DiagnosisFinding {
4226    /// Unique identifier for the finding, stable within the diagnosis.
4227    /// Lets a surface show a finding once at the level where it can be
4228    /// acted on instead of repeating it as a loose warning elsewhere.
4229    #[prost(string, tag="1")]
4230    pub id: ::prost::alloc::string::String,
4231    /// Which pattern produced it.
4232    #[prost(enumeration="DiagnosisFindingKind", tag="2")]
4233    pub kind: i32,
4234    /// What was observed, in the organization's own terms. Plain language
4235    /// and free of the vocabulary of the framework the pattern comes from.
4236    #[prost(string, tag="3")]
4237    pub detail: ::prost::alloc::string::String,
4238    /// Campaigns the finding was derived from.
4239    #[prost(string, repeated, tag="4")]
4240    pub campaign_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4241    /// Objectives the finding was derived from.
4242    #[prost(string, repeated, tag="5")]
4243    pub objective_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4244    /// Indicators the finding was derived from.
4245    #[prost(string, repeated, tag="6")]
4246    pub indicator_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4247    /// True when a model wrote `detail`. A model only ever phrases a
4248    /// finding that was already established from the records above; it
4249    /// never decides that there is one. Consumers use this the way they
4250    /// use lever provenance — to present a phrasing as a phrasing.
4251    #[prost(bool, tag="7")]
4252    pub model_assisted: bool,
4253}
4254/// The organization-level metrics as they stood when a diagnosis was
4255/// produced, stored with it.
4256///
4257/// Kept rather than recomputed because two of the four cannot be
4258/// recovered afterwards. Evidence coverage and the indicator review age
4259/// are read off the objectives and indicators as they are configured at
4260/// that moment, and configuration has no history: an objective archived
4261/// or an indicator revised next month silently rewrites what last
4262/// month's answer would have been. A diagnosis stored without its
4263/// snapshot therefore loses the comparison permanently, and the
4264/// comparison is most of why the diagnosis is stored at all.
4265///
4266/// Fields carry presence on the same terms as the profile response they
4267/// mirror: absent means there was nothing to measure, never zero.
4268#[derive(Clone, PartialEq, ::prost::Message)]
4269pub struct OrgMetricsSnapshot {
4270    /// Distribution of the classified history across control mechanisms.
4271    #[prost(message, repeated, tag="1")]
4272    pub lever_mix: ::prost::alloc::vec::Vec<LeverShare>,
4273    /// How much messaging landed on one person over the observed window.
4274    #[prost(message, optional, tag="2")]
4275    pub load: ::core::option::Option<RecipientLoad>,
4276    /// Fraction of active objectives with at least one indicator sourced
4277    /// outside the product, 0..1. Absent when there were no active
4278    /// objectives.
4279    #[prost(float, optional, tag="3")]
4280    pub evidence_coverage: ::core::option::Option<f32>,
4281    /// Numerator of `evidence_coverage` at generation time.
4282    #[prost(int32, tag="4")]
4283    pub objectives_with_external_evidence: i32,
4284    /// Denominator of `evidence_coverage` at generation time.
4285    #[prost(int32, tag="5")]
4286    pub active_objectives: i32,
4287    /// Median days since the organization's indicators were last revised.
4288    /// Absent when there were no indicators.
4289    #[prost(int64, optional, tag="6")]
4290    pub median_indicator_review_age_days: ::core::option::Option<i64>,
4291}
4292/// A dated, stored reading of the organization's own measurement system:
4293/// what it has declared it wants, how it observes it, and what it has
4294/// actually been communicating.
4295///
4296/// Stored rather than computed on request because the useful statements
4297/// are comparisons — that the mix of messages moved over a quarter, that
4298/// three objectives still have no outcome evidence months later — and a
4299/// stateless query cannot make them. It is also the only shape in which a
4300/// recurring review has something to review.
4301#[derive(Clone, PartialEq, ::prost::Message)]
4302pub struct OrgDiagnosis {
4303    /// Unique identifier for this run.
4304    #[prost(string, tag="1")]
4305    pub id: ::prost::alloc::string::String,
4306    /// When the run was produced.
4307    #[prost(message, optional, tag="2")]
4308    pub generated_at: ::core::option::Option<::prost_types::Timestamp>,
4309    /// What the run found. Empty when the configuration and the history
4310    /// gave nothing to say, which is a real result: a system that always
4311    /// has an opinion stops being read.
4312    #[prost(message, repeated, tag="3")]
4313    pub findings: ::prost::alloc::vec::Vec<DiagnosisFinding>,
4314    /// The previous run, when there is one. What changed between the two
4315    /// is the part of a diagnosis that no single run can carry.
4316    #[prost(string, tag="4")]
4317    pub previous_diagnosis_id: ::prost::alloc::string::String,
4318    /// Objectives read by the run.
4319    #[prost(int32, tag="5")]
4320    pub objectives_analyzed: i32,
4321    /// Campaigns read by the run.
4322    #[prost(int32, tag="6")]
4323    pub campaigns_analyzed: i32,
4324    /// The metrics as they stood at generation time. What moved between
4325    /// two runs is the part of a diagnosis that no single run can state,
4326    /// and this is what makes it recoverable later.
4327    #[prost(message, optional, tag="7")]
4328    pub metrics: ::core::option::Option<OrgMetricsSnapshot>,
4329}
4330/// Request for a stored organization diagnosis.
4331#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4332pub struct GetOrgDiagnosisRequest {
4333    /// Retrieve a specific run. Empty returns the most recent one.
4334    /// An id that does not exist returns NOT_FOUND.
4335    #[prost(string, tag="1")]
4336    pub diagnosis_id: ::prost::alloc::string::String,
4337}
4338/// Response containing an organization diagnosis.
4339#[derive(Clone, PartialEq, ::prost::Message)]
4340pub struct GetOrgDiagnosisResponse {
4341    /// The diagnosis. Absent when no run has ever been produced for the
4342    /// organization — a run needs declared objectives to have anything to
4343    /// read, and does not happen without them. Absence is presented as
4344    /// absence, never as a diagnosis with no findings, which would say
4345    /// something quite different.
4346    #[prost(message, optional, tag="1")]
4347    pub diagnosis: ::core::option::Option<OrgDiagnosis>,
4348}
4349/// Request to list an organization's diagnoses with pagination.
4350#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4351pub struct ListOrgDiagnosesRequest {
4352    /// Pagination parameters.
4353    #[prost(message, optional, tag="1")]
4354    pub pagination: ::core::option::Option<Pagination>,
4355}
4356/// Response containing a page of diagnoses.
4357#[derive(Clone, PartialEq, ::prost::Message)]
4358pub struct ListOrgDiagnosesResponse {
4359    /// Diagnoses in this page, newest first. Each carries its own metrics
4360    /// snapshot, so a page is enough to plot how the organization's
4361    /// measurement system moved without walking the chain of previous
4362    /// runs one fetch at a time.
4363    #[prost(message, repeated, tag="1")]
4364    pub diagnoses: ::prost::alloc::vec::Vec<OrgDiagnosis>,
4365    /// Pagination metadata for fetching subsequent pages.
4366    #[prost(message, optional, tag="2")]
4367    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4368}
4369/// Request to run a diagnosis now.
4370/// Empty — organization is extracted from the JWT.
4371#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4372pub struct TriggerOrgDiagnosisRequest {
4373}
4374/// Response after triggering a diagnosis run.
4375#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4376pub struct TriggerOrgDiagnosisResponse {
4377    /// Remaining manual runs allowed this month.
4378    #[prost(int32, tag="1")]
4379    pub remaining_this_month: i32,
4380    /// Timestamp of the last diagnosis produced, null if never run.
4381    #[prost(message, optional, tag="2")]
4382    pub last_generated_at: ::core::option::Option<::prost_types::Timestamp>,
4383}
4384// ─── Enums ──────────────────────────────────────────────────────────────────
4385
4386/// Confidence level for cohort-level predictions, based on available data volume.
4387#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4388#[repr(i32)]
4389pub enum ConfidenceLevel {
4390    Unspecified = 0,
4391    /// Fewer than 50 campaigns — predictions based on heuristics/industry benchmarks.
4392    Low = 1,
4393    /// 50-200 campaigns — basic clustering available, wide confidence intervals.
4394    Medium = 2,
4395    /// 200+ campaigns — full ML pipeline, narrow confidence intervals.
4396    High = 3,
4397}
4398impl ConfidenceLevel {
4399    /// String value of the enum field names used in the ProtoBuf definition.
4400    ///
4401    /// The values are not transformed in any way and thus are considered stable
4402    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4403    pub fn as_str_name(&self) -> &'static str {
4404        match self {
4405            Self::Unspecified => "CONFIDENCE_LEVEL_UNSPECIFIED",
4406            Self::Low => "CONFIDENCE_LEVEL_LOW",
4407            Self::Medium => "CONFIDENCE_LEVEL_MEDIUM",
4408            Self::High => "CONFIDENCE_LEVEL_HIGH",
4409        }
4410    }
4411    /// Creates an enum from field names used in the ProtoBuf definition.
4412    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4413        match value {
4414            "CONFIDENCE_LEVEL_UNSPECIFIED" => Some(Self::Unspecified),
4415            "CONFIDENCE_LEVEL_LOW" => Some(Self::Low),
4416            "CONFIDENCE_LEVEL_MEDIUM" => Some(Self::Medium),
4417            "CONFIDENCE_LEVEL_HIGH" => Some(Self::High),
4418            _ => None,
4419        }
4420    }
4421}
4422/// Pipeline state for a group's archetypes. Lets the admin UI render
4423/// distinct empty-state affordances ("run clustering" vs "need N more
4424/// sessions" vs "pipeline ran but audience was too homogeneous") instead
4425/// of treating every empty archetype list the same. Populated by
4426/// InsightsService.GetGroupArchetypes.
4427#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4428#[repr(i32)]
4429pub enum PipelineState {
4430    Unspecified = 0,
4431    /// The ML pipeline has never fired for this org. Archetypes are
4432    /// empty because nothing ran, not because of data shape.
4433    NeverRun = 1,
4434    /// The pipeline ran but the group had fewer than the k-anonymization
4435    /// minimum feature vectors (50), so clustering was skipped. UI
4436    /// renders "keep running campaigns" affordance.
4437    BelowThreshold = 2,
4438    /// The pipeline ran with enough vectors but the clustering provider
4439    /// returned zero clusters — typically means the audience is too
4440    /// homogeneous to separate into distinct archetypes.
4441    NoClusters = 3,
4442    /// Archetypes are populated and ready to render.
4443    Ready = 4,
4444}
4445impl PipelineState {
4446    /// String value of the enum field names used in the ProtoBuf definition.
4447    ///
4448    /// The values are not transformed in any way and thus are considered stable
4449    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4450    pub fn as_str_name(&self) -> &'static str {
4451        match self {
4452            Self::Unspecified => "PIPELINE_STATE_UNSPECIFIED",
4453            Self::NeverRun => "PIPELINE_STATE_NEVER_RUN",
4454            Self::BelowThreshold => "PIPELINE_STATE_BELOW_THRESHOLD",
4455            Self::NoClusters => "PIPELINE_STATE_NO_CLUSTERS",
4456            Self::Ready => "PIPELINE_STATE_READY",
4457        }
4458    }
4459    /// Creates an enum from field names used in the ProtoBuf definition.
4460    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4461        match value {
4462            "PIPELINE_STATE_UNSPECIFIED" => Some(Self::Unspecified),
4463            "PIPELINE_STATE_NEVER_RUN" => Some(Self::NeverRun),
4464            "PIPELINE_STATE_BELOW_THRESHOLD" => Some(Self::BelowThreshold),
4465            "PIPELINE_STATE_NO_CLUSTERS" => Some(Self::NoClusters),
4466            "PIPELINE_STATE_READY" => Some(Self::Ready),
4467            _ => None,
4468        }
4469    }
4470}
4471/// Where an archetype came from. Lets clients distinguish trained ML
4472/// clustering output from low-confidence provisional output generated
4473/// for sandboxes and opted-in organizations before enough engagement
4474/// data exists. Clients MUST render a low-confidence disclaimer for
4475/// PROVISIONAL archetypes.
4476#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4477#[repr(i32)]
4478pub enum ArchetypeSource {
4479    Unspecified = 0,
4480    /// Produced by the trained ML clustering pipeline (k-anonymized,
4481    /// DP-noised behavioral feature vectors).
4482    Ml = 1,
4483    /// Rule-based provisional output derived from coarse delivery/read/
4484    /// ack activity (or a stable starter distribution for sandboxes with
4485    /// no activity). Low confidence, never written to the ML artifact
4486    /// path, and always superseded by ML output once available.
4487    Provisional = 2,
4488}
4489impl ArchetypeSource {
4490    /// String value of the enum field names used in the ProtoBuf definition.
4491    ///
4492    /// The values are not transformed in any way and thus are considered stable
4493    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4494    pub fn as_str_name(&self) -> &'static str {
4495        match self {
4496            Self::Unspecified => "ARCHETYPE_SOURCE_UNSPECIFIED",
4497            Self::Ml => "ARCHETYPE_SOURCE_ML",
4498            Self::Provisional => "ARCHETYPE_SOURCE_PROVISIONAL",
4499        }
4500    }
4501    /// Creates an enum from field names used in the ProtoBuf definition.
4502    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4503        match value {
4504            "ARCHETYPE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
4505            "ARCHETYPE_SOURCE_ML" => Some(Self::Ml),
4506            "ARCHETYPE_SOURCE_PROVISIONAL" => Some(Self::Provisional),
4507            _ => None,
4508        }
4509    }
4510}
4511/// Which control mechanism a message exercises. Names are technical; clients
4512/// render plain-language labels from their own catalog.
4513#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4514#[repr(i32)]
4515pub enum Lever {
4516    Unspecified = 0,
4517    Boundaries = 1,
4518    Diagnostic = 2,
4519    Beliefs = 3,
4520    Interactive = 4,
4521}
4522impl Lever {
4523    /// String value of the enum field names used in the ProtoBuf definition.
4524    ///
4525    /// The values are not transformed in any way and thus are considered stable
4526    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4527    pub fn as_str_name(&self) -> &'static str {
4528        match self {
4529            Self::Unspecified => "LEVER_UNSPECIFIED",
4530            Self::Boundaries => "LEVER_BOUNDARIES",
4531            Self::Diagnostic => "LEVER_DIAGNOSTIC",
4532            Self::Beliefs => "LEVER_BELIEFS",
4533            Self::Interactive => "LEVER_INTERACTIVE",
4534        }
4535    }
4536    /// Creates an enum from field names used in the ProtoBuf definition.
4537    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4538        match value {
4539            "LEVER_UNSPECIFIED" => Some(Self::Unspecified),
4540            "LEVER_BOUNDARIES" => Some(Self::Boundaries),
4541            "LEVER_DIAGNOSTIC" => Some(Self::Diagnostic),
4542            "LEVER_BELIEFS" => Some(Self::Beliefs),
4543            "LEVER_INTERACTIVE" => Some(Self::Interactive),
4544            _ => None,
4545        }
4546    }
4547}
4548/// How a lever classification was produced.
4549#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4550#[repr(i32)]
4551pub enum LeverSource {
4552    Unspecified = 0,
4553    /// Produced by a trained classification model.
4554    Model = 1,
4555    /// Produced by deterministic rules over campaign metadata.
4556    Rules = 2,
4557}
4558impl LeverSource {
4559    /// String value of the enum field names used in the ProtoBuf definition.
4560    ///
4561    /// The values are not transformed in any way and thus are considered stable
4562    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4563    pub fn as_str_name(&self) -> &'static str {
4564        match self {
4565            Self::Unspecified => "LEVER_SOURCE_UNSPECIFIED",
4566            Self::Model => "LEVER_SOURCE_MODEL",
4567            Self::Rules => "LEVER_SOURCE_RULES",
4568        }
4569    }
4570    /// Creates an enum from field names used in the ProtoBuf definition.
4571    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4572        match value {
4573            "LEVER_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
4574            "LEVER_SOURCE_MODEL" => Some(Self::Model),
4575            "LEVER_SOURCE_RULES" => Some(Self::Rules),
4576            _ => None,
4577        }
4578    }
4579}
4580/// Which pattern a finding came from. The scope a pattern is entitled to
4581/// speak at is fixed per kind and not a separate field: mutual exclusivity
4582/// and lever mix are properties of the whole declared set, board size and
4583/// drift are properties of one objective, and encouraged behaviour is a
4584/// property of one indicator. Evaluating any of them at another scope is a
4585/// category error rather than a partial view.
4586#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4587#[repr(i32)]
4588pub enum DiagnosisFindingKind {
4589    Unspecified = 0,
4590    /// An indicator whose evidence source structurally fails one of the
4591    /// qualities a measure needs, and the behaviour that tends to follow.
4592    PerverseConductRisk = 1,
4593    /// The organization's messages concentrate in some control mechanisms
4594    /// and leave others unused, with the consequences the missing ones
4595    /// would have covered.
4596    LeverImbalance = 2,
4597    /// The declared objectives overlap each other or leave gaps, so the
4598    /// set does not partition what the organization is trying to hold
4599    /// true.
4600    NonExclusiveSet = 3,
4601    /// An objective carries more indicators than anyone reads, or several
4602    /// that measure the same thing by different routes.
4603    InflatedBoard = 4,
4604    /// An objective's wording changed and none of its indicators was
4605    /// revisited afterwards.
4606    ObjectiveIndicatorDrift = 5,
4607}
4608impl DiagnosisFindingKind {
4609    /// String value of the enum field names used in the ProtoBuf definition.
4610    ///
4611    /// The values are not transformed in any way and thus are considered stable
4612    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4613    pub fn as_str_name(&self) -> &'static str {
4614        match self {
4615            Self::Unspecified => "DIAGNOSIS_FINDING_KIND_UNSPECIFIED",
4616            Self::PerverseConductRisk => "DIAGNOSIS_FINDING_KIND_PERVERSE_CONDUCT_RISK",
4617            Self::LeverImbalance => "DIAGNOSIS_FINDING_KIND_LEVER_IMBALANCE",
4618            Self::NonExclusiveSet => "DIAGNOSIS_FINDING_KIND_NON_EXCLUSIVE_SET",
4619            Self::InflatedBoard => "DIAGNOSIS_FINDING_KIND_INFLATED_BOARD",
4620            Self::ObjectiveIndicatorDrift => "DIAGNOSIS_FINDING_KIND_OBJECTIVE_INDICATOR_DRIFT",
4621        }
4622    }
4623    /// Creates an enum from field names used in the ProtoBuf definition.
4624    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4625        match value {
4626            "DIAGNOSIS_FINDING_KIND_UNSPECIFIED" => Some(Self::Unspecified),
4627            "DIAGNOSIS_FINDING_KIND_PERVERSE_CONDUCT_RISK" => Some(Self::PerverseConductRisk),
4628            "DIAGNOSIS_FINDING_KIND_LEVER_IMBALANCE" => Some(Self::LeverImbalance),
4629            "DIAGNOSIS_FINDING_KIND_NON_EXCLUSIVE_SET" => Some(Self::NonExclusiveSet),
4630            "DIAGNOSIS_FINDING_KIND_INFLATED_BOARD" => Some(Self::InflatedBoard),
4631            "DIAGNOSIS_FINDING_KIND_OBJECTIVE_INDICATOR_DRIFT" => Some(Self::ObjectiveIndicatorDrift),
4632            _ => None,
4633        }
4634    }
4635}
4636// ─── Messages ───────────────────────────────────────────────────────────────
4637
4638/// A single reachability registry row, returned by `GetReachability` and
4639/// `ListReachabilityForUser`. The plaintext identifier and envelope ciphertext
4640/// are NEVER returned over the wire — only metadata. The dispatch worker reads
4641/// the plaintext directly from the database and decrypts via KMS.
4642#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4643pub struct Reachability {
4644    /// Server-assigned row identifier (UUID).
4645    #[prost(string, tag="1")]
4646    pub id: ::prost::alloc::string::String,
4647    /// Organization that owns this reachability entry.
4648    #[prost(string, tag="2")]
4649    pub org_id: ::prost::alloc::string::String,
4650    /// User this reachability entry is for.
4651    #[prost(string, tag="3")]
4652    pub user_id: ::prost::alloc::string::String,
4653    /// Channel for which this entry stores a contact identifier.
4654    #[prost(enumeration="ChannelName", tag="4")]
4655    pub channel: i32,
4656    /// When the row was first written.
4657    #[prost(message, optional, tag="5")]
4658    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4659    /// When the row was last upserted.
4660    #[prost(message, optional, tag="6")]
4661    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4662    /// Optional AWS region identifier (e.g. "eu-west-1") this user's data must
4663    /// remain in for GDPR/residency reasons. Unset means "no constraint."
4664    /// Enforcement happens at dispatch time, not write time.
4665    #[prost(string, optional, tag="7")]
4666    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
4667}
4668/// Per-(org, channel) region allowlist used by the dispatch worker to enforce
4669/// data-residency policy. An empty `allowed_regions` list means "no policy
4670/// configured" — NOT "no regions allowed."
4671#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4672pub struct RegionPolicy {
4673    #[prost(string, tag="1")]
4674    pub org_id: ::prost::alloc::string::String,
4675    #[prost(enumeration="ChannelName", tag="2")]
4676    pub channel: i32,
4677    /// AWS region identifiers (e.g. "eu-west-1", "us-east-1"). Empty list ==
4678    /// "no policy configured" — the dispatch worker SHALL NOT block on empty.
4679    #[prost(string, repeated, tag="3")]
4680    pub allowed_regions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4681    #[prost(message, optional, tag="4")]
4682    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4683}
4684// ─── Enums ──────────────────────────────────────────────────────────────────
4685
4686/// Terminal status of a single dispatch attempt as returned by the worker-mode
4687/// `DispatchToChannel` RPC. Distinct from the richer `ChannelEventStatus` in
4688/// `channel_events.proto`, which models the audit-trail row for every state
4689/// transition (SENT → DELIVERED → OPENED → …). DispatchStatus is the immediate
4690/// outcome of one worker call.
4691#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4692#[repr(i32)]
4693pub enum DispatchStatus {
4694    /// Default value; should not be used explicitly.
4695    Unspecified = 0,
4696    /// The adapter accepted the message for delivery (provider returned success).
4697    Sent = 1,
4698    /// The adapter returned a terminal error (e.g. recipient blocked, domain not
4699    /// verified). Retries SHALL NOT be attempted; consult `failure_reason`.
4700    Failed = 2,
4701    /// An existing `(dispatch_id, SENT)` row was found by the idempotency guard
4702    /// before the adapter was called; the prior receipt was returned without a
4703    /// second provider call.
4704    Deduped = 3,
4705}
4706impl DispatchStatus {
4707    /// String value of the enum field names used in the ProtoBuf definition.
4708    ///
4709    /// The values are not transformed in any way and thus are considered stable
4710    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4711    pub fn as_str_name(&self) -> &'static str {
4712        match self {
4713            Self::Unspecified => "DISPATCH_STATUS_UNSPECIFIED",
4714            Self::Sent => "DISPATCH_STATUS_SENT",
4715            Self::Failed => "DISPATCH_STATUS_FAILED",
4716            Self::Deduped => "DISPATCH_STATUS_DEDUPED",
4717        }
4718    }
4719    /// Creates an enum from field names used in the ProtoBuf definition.
4720    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4721        match value {
4722            "DISPATCH_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
4723            "DISPATCH_STATUS_SENT" => Some(Self::Sent),
4724            "DISPATCH_STATUS_FAILED" => Some(Self::Failed),
4725            "DISPATCH_STATUS_DEDUPED" => Some(Self::Deduped),
4726            _ => None,
4727        }
4728    }
4729}
4730// ─── DispatchToChannel ──────────────────────────────────────────────────────
4731
4732/// Worker-mode entry point invoked by the Temporal worker for one recipient.
4733/// Idempotent on `dispatch_id`: if a `(dispatch_id, SENT)` row already exists
4734/// in `channel_dispatches`, the worker SHALL return DISPATCH_STATUS_DEDUPED
4735/// without re-invoking the channel adapter.
4736#[derive(Clone, PartialEq, ::prost::Message)]
4737pub struct DispatchToChannelRequest {
4738    /// Idempotency key. Must be stable across retries from pidgr-api side.
4739    #[prost(string, tag="1")]
4740    pub dispatch_id: ::prost::alloc::string::String,
4741    #[prost(string, tag="2")]
4742    pub org_id: ::prost::alloc::string::String,
4743    #[prost(string, tag="3")]
4744    pub user_id: ::prost::alloc::string::String,
4745    /// Which channel adapter to invoke (EMAIL is the Wave 1 implementation).
4746    #[prost(enumeration="ChannelName", tag="4")]
4747    pub channel: i32,
4748    /// Template to render before dispatch.
4749    #[prost(string, tag="5")]
4750    pub template_id: ::prost::alloc::string::String,
4751    /// Per-recipient template variables.
4752    #[prost(map="string, string", tag="6")]
4753    pub template_vars: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
4754    /// BCP-47 locale used to select the template translation.
4755    #[prost(string, tag="7")]
4756    pub locale: ::prost::alloc::string::String,
4757    /// Optional AWS region the worker MUST dispatch from (typically copied from
4758    /// the recipient's reachability row). Unset means "no constraint."
4759    #[prost(string, optional, tag="8")]
4760    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
4761}
4762#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4763pub struct DispatchToChannelResponse {
4764    /// Echoes back the request's `dispatch_id`.
4765    #[prost(string, tag="1")]
4766    pub dispatch_id: ::prost::alloc::string::String,
4767    /// Terminal outcome of this call.
4768    #[prost(enumeration="DispatchStatus", tag="2")]
4769    pub status: i32,
4770    /// Human-readable failure reason; set only when `status` is
4771    /// DISPATCH_STATUS_FAILED.
4772    #[prost(string, optional, tag="3")]
4773    pub failure_reason: ::core::option::Option<::prost::alloc::string::String>,
4774}
4775// ─── UpsertReachability ─────────────────────────────────────────────────────
4776
4777/// Records a recipient identifier for a (user, channel) tuple. The plaintext
4778/// identifier is column-level KMS-encrypted on insert and never logged or
4779/// returned. The server computes the org-scoped HMAC lookup hash so opt-out
4780/// webhooks can find the row without decrypt.
4781#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4782pub struct UpsertReachabilityRequest {
4783    #[prost(string, tag="1")]
4784    pub org_id: ::prost::alloc::string::String,
4785    #[prost(string, tag="2")]
4786    pub user_id: ::prost::alloc::string::String,
4787    #[prost(enumeration="ChannelName", tag="3")]
4788    pub channel: i32,
4789    /// The plaintext identifier (email address, phone number, Slack user ID,
4790    /// Telegram chat ID, etc.). Encrypted at rest server-side. Servers MUST NOT
4791    /// log this field. Clients SHOULD treat this message as sensitive.
4792    #[prost(string, tag="4")]
4793    pub identifier_plaintext: ::prost::alloc::string::String,
4794    /// Optional AWS region this user's data must remain in (e.g. "eu-west-1").
4795    /// Recorded but NOT enforced at write time; enforcement is at dispatch.
4796    #[prost(string, optional, tag="5")]
4797    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
4798}
4799#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4800pub struct UpsertReachabilityResponse {
4801    /// The metadata for the upserted row. Plaintext identifier and envelope
4802    /// ciphertext are intentionally absent.
4803    #[prost(message, optional, tag="1")]
4804    pub reachability: ::core::option::Option<Reachability>,
4805}
4806// ─── RemoveReachability ─────────────────────────────────────────────────────
4807
4808/// Idempotent removal. GDPR Recital 30 audit row is appended via internal-mTLS
4809/// BEFORE the registry row is deleted (see AuditService.Append). If no row
4810/// existed, `removed = false` and no audit row is emitted.
4811#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4812pub struct RemoveReachabilityRequest {
4813    #[prost(string, tag="1")]
4814    pub org_id: ::prost::alloc::string::String,
4815    #[prost(string, tag="2")]
4816    pub user_id: ::prost::alloc::string::String,
4817    #[prost(enumeration="ChannelName", tag="3")]
4818    pub channel: i32,
4819}
4820#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4821pub struct RemoveReachabilityResponse {
4822    /// True if a row was deleted. False if no row existed for the tuple
4823    /// (idempotent success).
4824    #[prost(bool, tag="1")]
4825    pub removed: bool,
4826}
4827// ─── GetReachability ────────────────────────────────────────────────────────
4828
4829/// Returns the reachability metadata for a single (user, channel) tuple.
4830/// Returns NOT_FOUND if no row exists.
4831#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4832pub struct GetReachabilityRequest {
4833    #[prost(string, tag="1")]
4834    pub org_id: ::prost::alloc::string::String,
4835    #[prost(string, tag="2")]
4836    pub user_id: ::prost::alloc::string::String,
4837    #[prost(enumeration="ChannelName", tag="3")]
4838    pub channel: i32,
4839}
4840#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4841pub struct GetReachabilityResponse {
4842    /// Plaintext identifier and envelope ciphertext are intentionally absent.
4843    #[prost(message, optional, tag="1")]
4844    pub reachability: ::core::option::Option<Reachability>,
4845}
4846// ─── ListReachabilityForUser ────────────────────────────────────────────────
4847
4848/// Returns one Reachability entry per channel configured for a (org, user)
4849/// pair. Used by the admin-side per-user matrix view. Plaintext identifiers
4850/// and envelope ciphertext are intentionally absent — the admin UI only needs
4851/// to know which channels are configured.
4852#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4853pub struct ListReachabilityForUserRequest {
4854    #[prost(string, tag="1")]
4855    pub org_id: ::prost::alloc::string::String,
4856    #[prost(string, tag="2")]
4857    pub user_id: ::prost::alloc::string::String,
4858}
4859#[derive(Clone, PartialEq, ::prost::Message)]
4860pub struct ListReachabilityForUserResponse {
4861    /// One entry per channel that has a row for the (org_id, user_id) pair.
4862    #[prost(message, repeated, tag="1")]
4863    pub reachabilities: ::prost::alloc::vec::Vec<Reachability>,
4864}
4865// ─── GetRegionPolicy / SetRegionPolicy ──────────────────────────────────────
4866
4867#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4868pub struct GetRegionPolicyRequest {
4869    #[prost(string, tag="1")]
4870    pub org_id: ::prost::alloc::string::String,
4871    #[prost(enumeration="ChannelName", tag="2")]
4872    pub channel: i32,
4873}
4874#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4875pub struct GetRegionPolicyResponse {
4876    /// Always populated. Empty `allowed_regions` means "no policy configured"
4877    /// — NOT "no regions allowed."
4878    #[prost(message, optional, tag="1")]
4879    pub policy: ::core::option::Option<RegionPolicy>,
4880}
4881/// Admin-only upsert. Empty `allowed_regions` clears the policy.
4882#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4883pub struct SetRegionPolicyRequest {
4884    #[prost(string, tag="1")]
4885    pub org_id: ::prost::alloc::string::String,
4886    #[prost(enumeration="ChannelName", tag="2")]
4887    pub channel: i32,
4888    /// AWS region identifiers (e.g. "eu-west-1"). Empty list == "no policy."
4889    #[prost(string, repeated, tag="3")]
4890    pub allowed_regions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4891}
4892#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4893pub struct SetRegionPolicyResponse {
4894    #[prost(message, optional, tag="1")]
4895    pub policy: ::core::option::Option<RegionPolicy>,
4896}
4897// ─── GetCostCapPolicy / SetCostCapPolicy ────────────────────────────────────
4898
4899/// Get the cost-cap state for the current calendar-month period (UTC). When
4900/// no row exists for `(org_id, channel, period_yyyymm)`, the server returns
4901/// the channel default cap from server config
4902/// (`COST_CAP_DEFAULT_${CHANNEL}_MICROS`) with `used_micros = 0`.
4903#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4904pub struct GetCostCapPolicyRequest {
4905    #[prost(string, tag="1")]
4906    pub org_id: ::prost::alloc::string::String,
4907    #[prost(enumeration="ChannelName", tag="2")]
4908    pub channel: i32,
4909}
4910#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4911pub struct GetCostCapPolicyResponse {
4912    #[prost(string, tag="1")]
4913    pub org_id: ::prost::alloc::string::String,
4914    #[prost(enumeration="ChannelName", tag="2")]
4915    pub channel: i32,
4916    /// Current period's cap in micros (1/1_000_000 of a USD).
4917    #[prost(int64, tag="3")]
4918    pub cap_micros: i64,
4919    /// Current period's accumulated spend in micros.
4920    #[prost(int64, tag="4")]
4921    pub used_micros: i64,
4922    /// Calendar-month period in integer YYYYMM form (e.g. 202605 for May 2026).
4923    #[prost(int32, tag="5")]
4924    pub period_yyyymm: i32,
4925}
4926/// Admin-only upsert of the cap for the current calendar-month period. Future
4927/// periods inherit the most recent SetCostCapPolicy value until the next call.
4928#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4929pub struct SetCostCapPolicyRequest {
4930    #[prost(string, tag="1")]
4931    pub org_id: ::prost::alloc::string::String,
4932    #[prost(enumeration="ChannelName", tag="2")]
4933    pub channel: i32,
4934    #[prost(int64, tag="3")]
4935    pub cap_micros: i64,
4936}
4937#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4938pub struct SetCostCapPolicyResponse {
4939    #[prost(string, tag="1")]
4940    pub org_id: ::prost::alloc::string::String,
4941    #[prost(enumeration="ChannelName", tag="2")]
4942    pub channel: i32,
4943    #[prost(int64, tag="3")]
4944    pub cap_micros: i64,
4945    #[prost(int64, tag="4")]
4946    pub used_micros: i64,
4947    #[prost(int32, tag="5")]
4948    pub period_yyyymm: i32,
4949}
4950// ─── GetOrgWebhookConfig / SetOrgWebhookConfig ──────────────────────────────
4951
4952/// Get the org's generic-webhook channel configuration. The shared secret is
4953/// write-only and never returned — `has_secret` reports whether one is set.
4954#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4955pub struct GetOrgWebhookConfigRequest {
4956    #[prost(string, tag="1")]
4957    pub org_id: ::prost::alloc::string::String,
4958}
4959#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4960pub struct GetOrgWebhookConfigResponse {
4961    #[prost(string, tag="1")]
4962    pub org_id: ::prost::alloc::string::String,
4963    /// Destination URL Pidgr POSTs notification events to. Empty when no
4964    /// configuration exists.
4965    #[prost(string, tag="2")]
4966    pub url: ::prost::alloc::string::String,
4967    /// Whether dispatch via the WEBHOOK channel is enabled for the org.
4968    #[prost(bool, tag="3")]
4969    pub enabled: bool,
4970    /// Whether a signing secret is currently configured. The secret itself is
4971    /// never returned.
4972    #[prost(bool, tag="4")]
4973    pub has_secret: bool,
4974    #[prost(message, optional, tag="5")]
4975    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4976    #[prost(message, optional, tag="6")]
4977    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4978}
4979/// Admin-only upsert of the org's generic-webhook configuration. The server
4980/// validates the URL (https-only, public addresses only) before persisting,
4981/// and envelope-encrypts the secret at rest. Setting a new `secret` rotates
4982/// it; leaving `secret` unset keeps the existing one.
4983#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4984pub struct SetOrgWebhookConfigRequest {
4985    #[prost(string, tag="1")]
4986    pub org_id: ::prost::alloc::string::String,
4987    /// Destination URL. Constraints: https scheme; non-private, non-loopback
4988    /// host. Validation failures return `invalid_argument`.
4989    #[prost(string, tag="2")]
4990    pub url: ::prost::alloc::string::String,
4991    #[prost(bool, tag="3")]
4992    pub enabled: bool,
4993    /// Shared secret used for the `X-Pidgr-Signature` HMAC-SHA256 header.
4994    /// Write-only. Unset keeps the current secret; set rotates it.
4995    /// Constraints: 16–256 bytes when set.
4996    #[prost(string, optional, tag="4")]
4997    pub secret: ::core::option::Option<::prost::alloc::string::String>,
4998}
4999#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5000pub struct SetOrgWebhookConfigResponse {
5001    #[prost(string, tag="1")]
5002    pub org_id: ::prost::alloc::string::String,
5003    #[prost(string, tag="2")]
5004    pub url: ::prost::alloc::string::String,
5005    #[prost(bool, tag="3")]
5006    pub enabled: bool,
5007    #[prost(bool, tag="4")]
5008    pub has_secret: bool,
5009    #[prost(message, optional, tag="5")]
5010    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5011    #[prost(message, optional, tag="6")]
5012    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5013}
5014// ─── CreateChannelConnectLink ───────────────────────────────────────────────
5015
5016/// Mints a short-lived, HMAC-signed opt-in link a user follows to bind a
5017/// third-party channel to their (org, user). Only follow-style channels are
5018/// accepted: CHANNEL_NAME_TELEGRAM (bot-follow), CHANNEL_NAME_SLACK (OAuth),
5019/// CHANNEL_NAME_LINE (follow-code). Any other channel is rejected server-side
5020/// with `invalid_argument`. Wraps the pidgr-api `internal/linktoken` minter.
5021#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5022pub struct CreateChannelConnectLinkRequest {
5023    #[prost(string, tag="1")]
5024    pub org_id: ::prost::alloc::string::String,
5025    /// Internal user UUID; resolved via UserResolver on the server. The minted
5026    /// token binds the resulting channel identifier to this (org, user).
5027    #[prost(string, tag="2")]
5028    pub user_id: ::prost::alloc::string::String,
5029    /// Channel to connect. Constraints: must be one of CHANNEL_NAME_TELEGRAM,
5030    /// CHANNEL_NAME_SLACK, CHANNEL_NAME_LINE. Other values return
5031    /// `invalid_argument`.
5032    #[prost(enumeration="ChannelName", tag="3")]
5033    pub channel: i32,
5034}
5035#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5036pub struct CreateChannelConnectLinkResponse {
5037    /// The deep link the client renders for the user to follow (e.g. a
5038    /// Telegram bot-follow URL, Slack OAuth authorize URL, or LINE follow URL).
5039    #[prost(string, tag="1")]
5040    pub connect_url: ::prost::alloc::string::String,
5041    /// The raw 64-char base64url opt-in token embedded in `connect_url`,
5042    /// surfaced separately so clients can render it as a QR code or copy
5043    /// button. Implementation detail — clients SHOULD NOT parse or mutate it.
5044    #[prost(string, tag="2")]
5045    pub token: ::prost::alloc::string::String,
5046    /// When the minted token expires. After this time the link no longer
5047    /// binds and the user must request a fresh one.
5048    #[prost(message, optional, tag="3")]
5049    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5050}
5051// ─── CreateSlackWorkspaceInstallAuthorization ───────────────────────────────
5052
5053/// Mints a short-lived, HMAC-signed token authorizing a Slack WORKSPACE
5054/// install into the caller's AUTHORIZED org. The admin passes the token to the
5055/// pidgr-integrations install-start endpoint, which verifies it and installs
5056/// into the org the token binds — not the caller's JWT home org. This is the
5057/// workspace-install analogue of CreateChannelConnectLink (which binds the
5058/// per-user link flow): without it, a multi-org admin who selects a non-home
5059/// org still installs the bot into their home org, because the install-start
5060/// endpoint has no Cognito-sub→internal-id resolver of its own and falls back
5061/// to the JWT org claim.
5062#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5063pub struct CreateSlackWorkspaceInstallAuthorizationRequest {
5064    /// Must equal the caller's authorized org (auth.OrgID) — cross-org minting is
5065    /// rejected with permission_denied.
5066    #[prost(string, tag="1")]
5067    pub org_id: ::prost::alloc::string::String,
5068}
5069#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5070pub struct CreateSlackWorkspaceInstallAuthorizationResponse {
5071    /// The opaque HMAC token the client passes as the `token` query parameter to
5072    /// the integrations `/webhooks/slack/oauth/install/start` endpoint. It binds
5073    /// the authorized (org, internal user id) and an expiry. Implementation
5074    /// detail — clients SHOULD NOT parse or mutate it.
5075    #[prost(string, tag="1")]
5076    pub token: ::prost::alloc::string::String,
5077    /// When the minted token expires. After this the admin must request a fresh
5078    /// one before starting the install.
5079    #[prost(message, optional, tag="2")]
5080    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5081}
5082// ─── Messages ───────────────────────────────────────────────────────────────
5083
5084/// A shareable invite link that allows users to self-join an organization.
5085/// Links carry a role assignment and optional usage/expiry constraints.
5086#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5087pub struct InviteLink {
5088    /// Unique identifier for the invite link.
5089    #[prost(string, tag="1")]
5090    pub id: ::prost::alloc::string::String,
5091    /// Cryptographically random base64url-encoded token (43 characters).
5092    #[prost(string, tag="2")]
5093    pub token: ::prost::alloc::string::String,
5094    /// ID of the role assigned to users who redeem this link.
5095    #[prost(string, tag="3")]
5096    pub role_id: ::prost::alloc::string::String,
5097    /// Maximum number of times this link can be redeemed.
5098    /// 0 means unlimited.
5099    #[prost(int32, tag="4")]
5100    pub max_uses: i32,
5101    /// Number of times this link has been redeemed.
5102    #[prost(int32, tag="5")]
5103    pub use_count: i32,
5104    /// When the link expires. Empty if no expiry.
5105    #[prost(message, optional, tag="6")]
5106    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5107    /// When the link was revoked. Empty if not revoked.
5108    #[prost(message, optional, tag="7")]
5109    pub revoked_at: ::core::option::Option<::prost_types::Timestamp>,
5110    /// ID of the admin who created the link.
5111    #[prost(string, tag="8")]
5112    pub created_by: ::prost::alloc::string::String,
5113    /// When the link was created.
5114    #[prost(message, optional, tag="9")]
5115    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5116    /// Data governance region assigned to users who redeem this link. Empty means inherit from org default.
5117    /// Valid values: EU, LATAM, BR, APAC, US.
5118    #[prost(string, tag="10")]
5119    pub data_governance_region: ::prost::alloc::string::String,
5120}
5121/// Request to create a new invite link for the organization.
5122#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5123pub struct CreateInviteLinkRequest {
5124    /// ID of the role to assign. Defaults to the organization's employee role if empty.
5125    #[prost(string, tag="1")]
5126    pub role_id: ::prost::alloc::string::String,
5127    /// Maximum number of redemptions. 0 means unlimited.
5128    #[prost(int32, tag="2")]
5129    pub max_uses: i32,
5130    /// Number of hours until the link expires. 0 means no expiry.
5131    /// Constraints: Valid range 0 to 8760 (1 year).
5132    #[prost(int32, tag="3")]
5133    pub expires_in_hours: i32,
5134    /// Optional data governance region. Users who redeem this link inherit this region. Empty means inherit from org default.
5135    /// Valid values: EU, LATAM, BR, APAC, US.
5136    #[prost(string, tag="4")]
5137    pub data_governance_region: ::prost::alloc::string::String,
5138}
5139/// Response after creating an invite link.
5140#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5141pub struct CreateInviteLinkResponse {
5142    /// The newly created invite link.
5143    #[prost(message, optional, tag="1")]
5144    pub invite_link: ::core::option::Option<InviteLink>,
5145    /// Full URL for sharing (e.g. "<https://app.pidgr.com/join?token=<TOKEN>">).
5146    #[prost(string, tag="2")]
5147    pub url: ::prost::alloc::string::String,
5148}
5149/// Request to list all invite links for the organization.
5150#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5151pub struct ListInviteLinksRequest {
5152}
5153/// Response containing all invite links for the organization.
5154#[derive(Clone, PartialEq, ::prost::Message)]
5155pub struct ListInviteLinksResponse {
5156    /// All invite links (active, expired, maxed-out, and revoked), ordered by creation date descending.
5157    #[prost(message, repeated, tag="1")]
5158    pub invite_links: ::prost::alloc::vec::Vec<InviteLink>,
5159}
5160/// Request to revoke an invite link.
5161#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5162pub struct RevokeInviteLinkRequest {
5163    /// ID of the invite link to revoke. Required.
5164    #[prost(string, tag="1")]
5165    pub invite_link_id: ::prost::alloc::string::String,
5166}
5167/// Response after revoking an invite link.
5168#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5169pub struct RevokeInviteLinkResponse {
5170}
5171/// Request to redeem an invite link (authenticated — email extracted from JWT).
5172#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5173pub struct RedeemInviteLinkRequest {
5174    /// The invite link token from the URL query parameter.
5175    #[prost(string, tag="1")]
5176    pub token: ::prost::alloc::string::String,
5177}
5178/// Response after redeeming an invite link.
5179#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5180pub struct RedeemInviteLinkResponse {
5181    /// Name of the organization the user was added to.
5182    #[prost(string, tag="1")]
5183    pub organization_name: ::prost::alloc::string::String,
5184}
5185/// Request to validate an invite link and provision a user account if needed (unauthenticated).
5186#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5187pub struct ValidateInviteLinkRequest {
5188    /// The invite link token from the URL query parameter.
5189    #[prost(string, tag="1")]
5190    pub token: ::prost::alloc::string::String,
5191    /// Email address of the user joining the organization.
5192    /// Constraints: Max length 254 characters (RFC 5321).
5193    #[prost(string, tag="2")]
5194    pub email: ::prost::alloc::string::String,
5195}
5196/// Response after validating an invite link.
5197#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5198pub struct ValidateInviteLinkResponse {
5199    /// Name of the organization the invite link belongs to.
5200    #[prost(string, tag="1")]
5201    pub organization_name: ::prost::alloc::string::String,
5202}
5203// ─── Messages ───────────────────────────────────────────────────────────────
5204
5205/// Request to invite a new user to the organization.
5206#[derive(Clone, PartialEq, ::prost::Message)]
5207pub struct InviteUserRequest {
5208    /// Email address to send the invitation to.
5209    /// Constraints: Max length 254 characters (RFC 5321).
5210    #[prost(string, tag="1")]
5211    pub email: ::prost::alloc::string::String,
5212    /// Display name for the invited user.
5213    /// Constraints: Max length 200 characters.
5214    #[prost(string, tag="2")]
5215    pub name: ::prost::alloc::string::String,
5216    /// ID of the role to assign. Defaults to the organization's employee role if empty.
5217    #[prost(string, tag="4")]
5218    pub role_id: ::prost::alloc::string::String,
5219    /// Optional profile attributes to pre-fill at invitation time.
5220    #[prost(message, optional, tag="5")]
5221    pub profile: ::core::option::Option<UserProfile>,
5222    /// Optional data governance region for the invited user. Empty means inherit from org default.
5223    /// Valid values: EU, LATAM, BR, APAC, US.
5224    #[prost(string, tag="6")]
5225    pub data_governance_region: ::prost::alloc::string::String,
5226}
5227/// Response after inviting a user.
5228#[derive(Clone, PartialEq, ::prost::Message)]
5229pub struct InviteUserResponse {
5230    /// The newly created user (status: INVITED).
5231    #[prost(message, optional, tag="1")]
5232    pub user: ::core::option::Option<User>,
5233}
5234/// Request to retrieve a user by ID.
5235#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5236pub struct GetUserRequest {
5237    /// ID of the user to retrieve.
5238    #[prost(string, tag="1")]
5239    pub user_id: ::prost::alloc::string::String,
5240}
5241/// Response containing the requested user.
5242#[derive(Clone, PartialEq, ::prost::Message)]
5243pub struct GetUserResponse {
5244    /// The requested user.
5245    #[prost(message, optional, tag="1")]
5246    pub user: ::core::option::Option<User>,
5247}
5248/// Request to list users in the organization with pagination.
5249#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5250pub struct ListUsersRequest {
5251    /// Pagination parameters.
5252    #[prost(message, optional, tag="1")]
5253    pub pagination: ::core::option::Option<Pagination>,
5254}
5255/// Response containing a page of users.
5256#[derive(Clone, PartialEq, ::prost::Message)]
5257pub struct ListUsersResponse {
5258    /// List of users in this page.
5259    #[prost(message, repeated, tag="1")]
5260    pub users: ::prost::alloc::vec::Vec<User>,
5261    /// Pagination metadata for fetching subsequent pages.
5262    #[prost(message, optional, tag="2")]
5263    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5264}
5265/// Request to change a user's role within the organization.
5266#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5267pub struct UpdateUserRoleRequest {
5268    /// ID of the user whose role to update.
5269    #[prost(string, tag="1")]
5270    pub user_id: ::prost::alloc::string::String,
5271    /// ID of the new role to assign.
5272    #[prost(string, tag="2")]
5273    pub role_id: ::prost::alloc::string::String,
5274}
5275/// Response after updating a user's role.
5276#[derive(Clone, PartialEq, ::prost::Message)]
5277pub struct UpdateUserRoleResponse {
5278    /// The updated user with the new role.
5279    #[prost(message, optional, tag="1")]
5280    pub user: ::core::option::Option<User>,
5281}
5282/// Request to deactivate a user within the organization.
5283#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5284pub struct DeactivateUserRequest {
5285    /// ID of the user to deactivate.
5286    #[prost(string, tag="1")]
5287    pub user_id: ::prost::alloc::string::String,
5288}
5289/// Response after deactivating a user.
5290#[derive(Clone, PartialEq, ::prost::Message)]
5291pub struct DeactivateUserResponse {
5292    /// The deactivated user (status: DEACTIVATED).
5293    #[prost(message, optional, tag="1")]
5294    pub user: ::core::option::Option<User>,
5295}
5296/// Request to reactivate a deactivated user.
5297#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5298pub struct ReactivateUserRequest {
5299    /// ID of the user to reactivate.
5300    #[prost(string, tag="1")]
5301    pub user_id: ::prost::alloc::string::String,
5302}
5303/// Response after reactivating a user.
5304#[derive(Clone, PartialEq, ::prost::Message)]
5305pub struct ReactivateUserResponse {
5306    /// The reactivated user (status: INVITED).
5307    #[prost(message, optional, tag="1")]
5308    pub user: ::core::option::Option<User>,
5309}
5310/// Request to revoke an invitation for a user who has not yet registered.
5311#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5312pub struct RevokeInviteRequest {
5313    /// ID of the invited user to remove.
5314    /// Constraints: UUID format (36 characters).
5315    #[prost(string, tag="1")]
5316    pub user_id: ::prost::alloc::string::String,
5317}
5318/// Response after revoking an invitation. Empty on success.
5319#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5320pub struct RevokeInviteResponse {
5321}
5322/// Request to update a user's profile attributes.
5323#[derive(Clone, PartialEq, ::prost::Message)]
5324pub struct UpdateUserProfileRequest {
5325    /// ID of the user whose profile to update.
5326    /// Empty or matching the caller's own ID allows self-update without PERMISSION_MEMBERS_MANAGE.
5327    #[prost(string, tag="1")]
5328    pub user_id: ::prost::alloc::string::String,
5329    /// Profile attributes to set. All provided fields overwrite existing values.
5330    #[prost(message, optional, tag="2")]
5331    pub profile: ::core::option::Option<UserProfile>,
5332}
5333/// Response after updating a user's profile.
5334#[derive(Clone, PartialEq, ::prost::Message)]
5335pub struct UpdateUserProfileResponse {
5336    /// The updated user with the new profile.
5337    #[prost(message, optional, tag="1")]
5338    pub user: ::core::option::Option<User>,
5339}
5340/// Request to retrieve the caller's platform settings.
5341#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5342pub struct GetUserSettingsRequest {
5343}
5344/// Response containing the caller's platform settings.
5345#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5346pub struct GetUserSettingsResponse {
5347    /// Current settings. Fields at their default value indicate the platform default.
5348    #[prost(message, optional, tag="1")]
5349    pub settings: ::core::option::Option<UserSettings>,
5350}
5351/// Request to update the caller's platform settings.
5352#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5353pub struct UpdateUserSettingsRequest {
5354    /// Settings to update. Only fields with non-default (non-UNSPECIFIED) values
5355    /// are applied; default-valued fields are left unchanged.
5356    #[prost(message, optional, tag="1")]
5357    pub settings: ::core::option::Option<UserSettings>,
5358}
5359/// Response after updating the caller's platform settings.
5360#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5361pub struct UpdateUserSettingsResponse {
5362    /// The full settings after the update.
5363    #[prost(message, optional, tag="1")]
5364    pub settings: ::core::option::Option<UserSettings>,
5365}
5366/// Request to invite multiple users to the organization in a single call.
5367#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5368pub struct BulkInviteUsersRequest {
5369    /// Email addresses to invite.
5370    /// Constraints: Min 1, max 100 emails. Duplicates are deduplicated before processing.
5371    #[prost(string, repeated, tag="1")]
5372    pub emails: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
5373    /// ID of the role to assign. Defaults to the organization's employee role if empty.
5374    #[prost(string, tag="2")]
5375    pub role_id: ::prost::alloc::string::String,
5376}
5377/// Per-email result within a bulk invite operation.
5378#[derive(Clone, PartialEq, ::prost::Message)]
5379pub struct BulkInviteResult {
5380    /// The email address that was processed.
5381    #[prost(string, tag="1")]
5382    pub email: ::prost::alloc::string::String,
5383    /// Whether the invitation succeeded.
5384    #[prost(bool, tag="2")]
5385    pub success: bool,
5386    /// Error message if the invitation failed (e.g. "user already exists").
5387    /// Empty on success.
5388    #[prost(string, tag="3")]
5389    pub error: ::prost::alloc::string::String,
5390    /// The created user. Only set on success.
5391    #[prost(message, optional, tag="4")]
5392    pub user: ::core::option::Option<User>,
5393}
5394/// Response after bulk inviting users.
5395#[derive(Clone, PartialEq, ::prost::Message)]
5396pub struct BulkInviteUsersResponse {
5397    /// Per-email results in the same order as the deduplicated input.
5398    #[prost(message, repeated, tag="1")]
5399    pub results: ::prost::alloc::vec::Vec<BulkInviteResult>,
5400    /// Number of users successfully invited.
5401    #[prost(int32, tag="2")]
5402    pub invited_count: i32,
5403    /// Number of emails that failed.
5404    #[prost(int32, tag="3")]
5405    pub failed_count: i32,
5406}
5407/// Request to confirm passkey enrollment after client-side WebAuthn registration.
5408/// The server verifies that the caller has at least one registered WebAuthn
5409/// credential before setting the enrollment attribute.
5410#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5411pub struct ConfirmPasskeyEnrollmentRequest {
5412}
5413/// Response after confirming passkey enrollment.
5414#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5415pub struct ConfirmPasskeyEnrollmentResponse {
5416    /// Whether enrollment was confirmed and the user attribute was updated.
5417    #[prost(bool, tag="1")]
5418    pub confirmed: bool,
5419}
5420/// Request to update a user's data governance region.
5421#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5422pub struct UpdateUserRegionRequest {
5423    /// ID of the user whose region to update. Required.
5424    #[prost(string, tag="1")]
5425    pub user_id: ::prost::alloc::string::String,
5426    /// New governance region, or empty to inherit from org default.
5427    /// Valid values: EU, LATAM, BR, APAC, US.
5428    #[prost(string, tag="2")]
5429    pub data_governance_region: ::prost::alloc::string::String,
5430}
5431/// Response after updating a user's governance region.
5432#[derive(Clone, PartialEq, ::prost::Message)]
5433pub struct UpdateUserRegionResponse {
5434    /// The updated user.
5435    #[prost(message, optional, tag="1")]
5436    pub user: ::core::option::Option<User>,
5437    /// Temporal workflow ID for the region migration, if a migration was triggered.
5438    /// Empty if the region didn't actually change.
5439    #[prost(string, tag="2")]
5440    pub migration_workflow_id: ::prost::alloc::string::String,
5441}
5442// ─── Messages ───────────────────────────────────────────────────────────────
5443
5444/// A qualitative statement of a state the organization wants to hold
5445/// true. Owned by the organization, never by a single campaign. Content
5446/// is always authored by the organization; the contract only carries
5447/// structure.
5448#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5449pub struct Objective {
5450    /// Unique identifier for the objective.
5451    #[prost(string, tag="1")]
5452    pub id: ::prost::alloc::string::String,
5453    /// Whether this is a standing objective or a time-bounded initiative.
5454    #[prost(enumeration="ObjectiveKind", tag="2")]
5455    pub kind: i32,
5456    /// The statement itself. Required.
5457    /// Constraints: Max length 300 characters.
5458    #[prost(string, tag="3")]
5459    pub title: ::prost::alloc::string::String,
5460    /// Longer explanation of what the statement means and does not mean.
5461    /// Constraints: Max length 4000 characters.
5462    #[prost(string, tag="4")]
5463    pub description: ::prost::alloc::string::String,
5464    /// ID of the user accountable for the objective. Optional.
5465    #[prost(string, tag="5")]
5466    pub owner_user_id: ::prost::alloc::string::String,
5467    /// Lifecycle state.
5468    #[prost(enumeration="ObjectiveState", tag="6")]
5469    pub state: i32,
5470    /// For an initiative, the standing objective it contributes to. Empty
5471    /// when the initiative stands alone, and always empty for
5472    /// OBJECTIVE_KIND_OBJECTIVE.
5473    #[prost(string, tag="7")]
5474    pub parent_objective_id: ::prost::alloc::string::String,
5475    /// For an initiative, the date it is expected to end. Unset for a
5476    /// standing objective, which by definition does not have one.
5477    #[prost(message, optional, tag="8")]
5478    pub ends_at: ::core::option::Option<::prost_types::Timestamp>,
5479    /// Number of indicators currently attached.
5480    #[prost(int32, tag="9")]
5481    pub indicator_count: i32,
5482    /// Timestamp when the objective was created.
5483    #[prost(message, optional, tag="10")]
5484    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5485    /// Timestamp when the objective was last updated.
5486    #[prost(message, optional, tag="11")]
5487    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5488}
5489/// A form problem found in an objective's wording, returned alongside the
5490/// stored objective. Never blocks the write.
5491#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5492pub struct ObjectiveAdvisory {
5493    /// Which form problem was detected.
5494    #[prost(enumeration="ObjectiveWritingIssue", tag="1")]
5495    pub issue: i32,
5496    /// Plain-language explanation of what was detected and why it matters.
5497    #[prost(string, tag="2")]
5498    pub detail: ::prost::alloc::string::String,
5499    /// A rewrite the author can accept or ignore. May be empty when no
5500    /// rewrite could be produced.
5501    #[prost(string, tag="3")]
5502    pub suggested_rewrite: ::prost::alloc::string::String,
5503}
5504/// Something the author should know before relying on a verification
5505/// campaign as an indicator's evidence, returned alongside the stored
5506/// indicator. Never blocks the write.
5507///
5508/// Asking a verifier about a unit rather than about each of its members
5509/// is what keeps a stored answer from being one person's judgement of
5510/// another. That protection is a function of size: below a handful of
5511/// people, a statement about the unit is in practice a statement about
5512/// each member, and the distinction reconstructs itself. The platform
5513/// responds by putting the question to the level above instead, and where
5514/// there is no level above, the objective simply gets no evidence by this
5515/// route.
5516///
5517/// The notice states that consequence to the admin, who is the one who
5518/// can change the shape of the question or decide it is acceptable. It is
5519/// deliberately not a warning shown to the verifier at the moment of
5520/// answering: that would claim a safeguard that does not exist, and would
5521/// ask one person to accept a risk that runs to somebody else.
5522#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5523pub struct VerificationSetupNotice {
5524    /// What follows from the current configuration, in plain language.
5525    #[prost(string, tag="1")]
5526    pub detail: ::prost::alloc::string::String,
5527    /// How many of the units this derivation would reach are smaller than
5528    /// the floor.
5529    #[prost(int32, tag="2")]
5530    pub units_below_floor: i32,
5531    /// The size at or above which a unit is asked about on its own.
5532    #[prost(int32, tag="3")]
5533    pub unit_floor: i32,
5534}
5535/// A declared way of observing whether an objective holds. Several per
5536/// objective is the intended shape: indicators are individually
5537/// incomplete and are meant to compensate for one another.
5538#[derive(Clone, PartialEq, ::prost::Message)]
5539pub struct Indicator {
5540    /// Unique identifier for the indicator.
5541    #[prost(string, tag="1")]
5542    pub id: ::prost::alloc::string::String,
5543    /// Objective this indicator hangs from.
5544    #[prost(string, tag="2")]
5545    pub objective_id: ::prost::alloc::string::String,
5546    /// Short name for the indicator. Required.
5547    /// Constraints: Max length 200 characters.
5548    #[prost(string, tag="3")]
5549    pub name: ::prost::alloc::string::String,
5550    /// Unit the readings are expressed in (e.g. "percent", "days",
5551    /// "incidents"). Free text so that existing measures can be carried
5552    /// over unchanged.
5553    /// Constraints: Max length 50 characters.
5554    #[prost(string, tag="4")]
5555    pub unit: ::prost::alloc::string::String,
5556    /// Which direction of movement is the desired one.
5557    #[prost(enumeration="IndicatorDirection", tag="5")]
5558    pub direction: i32,
5559    /// How often a reading is expected.
5560    #[prost(enumeration="IndicatorFrequency", tag="6")]
5561    pub frequency: i32,
5562    /// ID of the user accountable for the indicator. Optional.
5563    #[prost(string, tag="7")]
5564    pub owner_user_id: ::prost::alloc::string::String,
5565    /// Where readings come from. Required.
5566    #[prost(message, optional, tag="8")]
5567    pub evidence_source: ::core::option::Option<EvidenceSource>,
5568    /// Why this indicator was chosen over the alternatives.
5569    /// Constraints: Max length 2000 characters.
5570    #[prost(string, tag="9")]
5571    pub rationale: ::prost::alloc::string::String,
5572    /// What the indicator is meant to say about the objective.
5573    /// Constraints: Max length 2000 characters.
5574    #[prost(string, tag="10")]
5575    pub strategic_meaning: ::prost::alloc::string::String,
5576    /// How a reading should be read, including what it does not cover.
5577    /// Constraints: Max length 2000 characters.
5578    #[prost(string, tag="11")]
5579    pub interpretation_guidance: ::prost::alloc::string::String,
5580    /// The behaviour this indicator could encourage if it were optimized
5581    /// on its own. Pre-filled by the server where a structural weakness in
5582    /// the evidence source implies one, always editable, never required.
5583    /// Constraints: Max length 2000 characters.
5584    #[prost(string, tag="12")]
5585    pub perverse_behavior_note: ::prost::alloc::string::String,
5586    /// Whether any reading has ever corroborated this indicator.
5587    #[prost(enumeration="IndicatorVerificationState", tag="13")]
5588    pub verification_state: i32,
5589    /// Timestamp when the indicator was created.
5590    #[prost(message, optional, tag="14")]
5591    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5592    /// Timestamp when the indicator was last updated.
5593    #[prost(message, optional, tag="15")]
5594    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5595    /// The value the organization is aiming for, expressed in `unit` and
5596    /// read together with `direction`. Absent when no target has been set.
5597    ///
5598    /// Targets live here rather than inside the objective's wording, and
5599    /// they sit at the routine tier of change: revising a target is
5600    /// expected housekeeping, unlike rewriting the objective it serves.
5601    #[prost(double, optional, tag="16")]
5602    pub target: ::core::option::Option<f64>,
5603}
5604/// Where an indicator's readings come from, plus the structural facts
5605/// that follow from that choice. The facts are descriptive, not a score:
5606/// they state what the configuration implies so the reader can judge it,
5607/// and are never combined into a single rating.
5608#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5609pub struct EvidenceSource {
5610    /// Which adapter produces the readings.
5611    #[prost(enumeration="EvidenceSourceKind", tag="1")]
5612    pub kind: i32,
5613    /// True when whoever reports the reading is also whoever the reading
5614    /// is about. Self-reported readings can be negotiated rather than
5615    /// produced.
5616    #[prost(bool, tag="2")]
5617    pub reporter_is_subject: bool,
5618    /// Whether the source observes the whole population or a sample.
5619    #[prost(enumeration="EvidenceCoverage", tag="3")]
5620    pub coverage: i32,
5621    /// True when a party other than the reporter could check the reading
5622    /// against an independent record.
5623    #[prost(bool, tag="4")]
5624    pub third_party_verifiable: bool,
5625    /// Adapter-specific configuration. Must match `kind`.
5626    #[prost(oneof="evidence_source::Detail", tags="5, 6, 7, 8")]
5627    pub detail: ::core::option::Option<evidence_source::Detail>,
5628}
5629/// Nested message and enum types in `EvidenceSource`.
5630pub mod evidence_source {
5631    /// Adapter-specific configuration. Must match `kind`.
5632    #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)]
5633    pub enum Detail {
5634        #[prost(message, tag="5")]
5635        InApp(super::InAppEvidence),
5636        #[prost(message, tag="6")]
5637        VerificationCampaign(super::VerificationCampaignEvidence),
5638        #[prost(message, tag="7")]
5639        Webhook(super::WebhookEvidence),
5640        #[prost(message, tag="8")]
5641        ManualEntry(super::ManualEntryEvidence),
5642    }
5643}
5644/// Configuration for readings produced inside the product by the
5645/// audience of the message itself.
5646#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5647pub struct InAppEvidence {
5648    /// Which response counts as a reading. ActionType currently defines
5649    /// only ACK; poll answers, go-to confirmations and attestations become
5650    /// expressible here once message actions land in common.proto.
5651    #[prost(enumeration="ActionType", tag="1")]
5652    pub action_type: i32,
5653}
5654/// Configuration for readings produced by a deferred follow-up message
5655/// sent to someone other than the audience.
5656#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5657pub struct VerificationCampaignEvidence {
5658    /// How the recipients of the follow-up are derived from the audience
5659    /// being verified. Kinds other than the ones enumerated are rejected
5660    /// with UNIMPLEMENTED.
5661    #[prost(enumeration="VerifierDerivation", tag="1")]
5662    pub verifier_derivation: i32,
5663    /// Days to wait after the original message before the follow-up is
5664    /// sent.
5665    #[prost(int32, tag="2")]
5666    pub delay_days: i32,
5667    /// Template used for the follow-up. Optional; a default is used when
5668    /// empty.
5669    #[prost(string, tag="3")]
5670    pub template_id: ::prost::alloc::string::String,
5671}
5672/// Configuration for readings the organization pushes from one of its
5673/// own systems.
5674#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5675pub struct WebhookEvidence {
5676    /// Name of the system the readings come from. Required for this
5677    /// adapter.
5678    /// Constraints: Max length 200 characters.
5679    #[prost(string, tag="1")]
5680    pub system_name: ::prost::alloc::string::String,
5681    /// How the reading is produced in that system, in the organization's
5682    /// own words.
5683    /// Constraints: Max length 2000 characters.
5684    #[prost(string, tag="2")]
5685    pub description: ::prost::alloc::string::String,
5686}
5687/// Configuration for readings entered by hand or imported from a
5688/// spreadsheet. There is no originating system to name — a person is the
5689/// source.
5690#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5691pub struct ManualEntryEvidence {
5692    /// How the reading is arrived at before it is entered, in the
5693    /// organization's own words.
5694    /// Constraints: Max length 2000 characters.
5695    #[prost(string, tag="1")]
5696    pub description: ::prost::alloc::string::String,
5697}
5698/// Declares which objective a campaign serves. The link is what turns a
5699/// campaign's response rate from a result in itself into evidence about
5700/// something the organization was trying to achieve.
5701#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5702pub struct CampaignObjectiveLink {
5703    /// Campaign that serves the objective.
5704    #[prost(string, tag="1")]
5705    pub campaign_id: ::prost::alloc::string::String,
5706    /// Objective the campaign serves.
5707    #[prost(string, tag="2")]
5708    pub objective_id: ::prost::alloc::string::String,
5709    /// How the link came to be.
5710    #[prost(enumeration="LinkOrigin", tag="3")]
5711    pub origin: i32,
5712    /// Timestamp when the link was recorded.
5713    #[prost(message, optional, tag="4")]
5714    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5715}
5716/// Request to create an objective.
5717#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5718pub struct CreateObjectiveRequest {
5719    /// The statement. Required.
5720    /// Constraints: Max length 300 characters.
5721    #[prost(string, tag="1")]
5722    pub title: ::prost::alloc::string::String,
5723    /// Longer explanation. Optional.
5724    /// Constraints: Max length 4000 characters.
5725    #[prost(string, tag="2")]
5726    pub description: ::prost::alloc::string::String,
5727    /// Accountable user. Optional.
5728    #[prost(string, tag="3")]
5729    pub owner_user_id: ::prost::alloc::string::String,
5730    /// Standing objective or time-bounded initiative. Defaults to
5731    /// OBJECTIVE_KIND_OBJECTIVE when unspecified.
5732    #[prost(enumeration="ObjectiveKind", tag="4")]
5733    pub kind: i32,
5734    /// For an initiative, the standing objective it contributes to.
5735    /// Optional; must be empty for a standing objective.
5736    #[prost(string, tag="5")]
5737    pub parent_objective_id: ::prost::alloc::string::String,
5738    /// For an initiative, its expected end. Must be unset for a standing
5739    /// objective.
5740    #[prost(message, optional, tag="6")]
5741    pub ends_at: ::core::option::Option<::prost_types::Timestamp>,
5742    /// Initial lifecycle state. Defaults to OBJECTIVE_STATE_DRAFT when
5743    /// unspecified. OBJECTIVE_STATE_ARCHIVED is rejected.
5744    #[prost(enumeration="ObjectiveState", tag="7")]
5745    pub state: i32,
5746}
5747/// Response after creating an objective.
5748#[derive(Clone, PartialEq, ::prost::Message)]
5749pub struct CreateObjectiveResponse {
5750    /// The newly created objective. Always present, including when
5751    /// advisories were raised.
5752    #[prost(message, optional, tag="1")]
5753    pub objective: ::core::option::Option<Objective>,
5754    /// Form problems found in the wording. Advisory only — the objective
5755    /// was stored regardless.
5756    #[prost(message, repeated, tag="2")]
5757    pub advisories: ::prost::alloc::vec::Vec<ObjectiveAdvisory>,
5758}
5759/// Request to update an objective.
5760///
5761/// Every mutable field carries explicit presence and they all follow one
5762/// rule: a field left absent leaves the stored value untouched, and a
5763/// field that is present replaces it — including when the value sent is
5764/// empty. Clearing a field is therefore expressible, which matters for
5765/// text an author wants gone rather than merely reworded.
5766#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5767pub struct UpdateObjectiveRequest {
5768    /// ID of the objective to update. Required.
5769    #[prost(string, tag="1")]
5770    pub objective_id: ::prost::alloc::string::String,
5771    /// New statement.
5772    /// Constraints: Max length 300 characters.
5773    #[prost(string, optional, tag="2")]
5774    pub title: ::core::option::Option<::prost::alloc::string::String>,
5775    /// New explanation.
5776    /// Constraints: Max length 4000 characters.
5777    #[prost(string, optional, tag="3")]
5778    pub description: ::core::option::Option<::prost::alloc::string::String>,
5779    /// New accountable user. Present and empty detaches the owner.
5780    #[prost(string, optional, tag="4")]
5781    pub owner_user_id: ::core::option::Option<::prost::alloc::string::String>,
5782    /// New lifecycle state. Archiving an objective is done here, by
5783    /// sending OBJECTIVE_STATE_ARCHIVED.
5784    #[prost(enumeration="ObjectiveState", optional, tag="5")]
5785    pub state: ::core::option::Option<i32>,
5786    /// New expected end for an initiative. Reclassifying to
5787    /// OBJECTIVE_KIND_OBJECTIVE clears it regardless of what is sent here,
5788    /// since a standing objective has no end.
5789    #[prost(message, optional, tag="6")]
5790    pub ends_at: ::core::option::Option<::prost_types::Timestamp>,
5791    /// Reclassify between a standing objective and a time-bounded
5792    /// initiative, so that an OBJECTIVE_WRITING_ISSUE_PROJECT_FORM
5793    /// advisory can be acted on without recreating the entry.
5794    #[prost(enumeration="ObjectiveKind", optional, tag="7")]
5795    pub kind: ::core::option::Option<i32>,
5796    /// For an initiative, the standing objective it contributes to.
5797    /// Present and empty detaches it and leaves the initiative standing
5798    /// alone.
5799    #[prost(string, optional, tag="8")]
5800    pub parent_objective_id: ::core::option::Option<::prost::alloc::string::String>,
5801}
5802/// Response after updating an objective.
5803#[derive(Clone, PartialEq, ::prost::Message)]
5804pub struct UpdateObjectiveResponse {
5805    /// The updated objective.
5806    #[prost(message, optional, tag="1")]
5807    pub objective: ::core::option::Option<Objective>,
5808    /// Form problems found in the new wording. Advisory only — the update
5809    /// was applied regardless.
5810    #[prost(message, repeated, tag="2")]
5811    pub advisories: ::prost::alloc::vec::Vec<ObjectiveAdvisory>,
5812}
5813/// Request to retrieve one objective with its indicators.
5814#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5815pub struct GetObjectiveRequest {
5816    /// ID of the objective to retrieve. Required.
5817    #[prost(string, tag="1")]
5818    pub objective_id: ::prost::alloc::string::String,
5819}
5820/// Response containing the requested objective.
5821#[derive(Clone, PartialEq, ::prost::Message)]
5822pub struct GetObjectiveResponse {
5823    /// The requested objective.
5824    #[prost(message, optional, tag="1")]
5825    pub objective: ::core::option::Option<Objective>,
5826    /// Indicators attached to it, ordered by creation time.
5827    #[prost(message, repeated, tag="2")]
5828    pub indicators: ::prost::alloc::vec::Vec<Indicator>,
5829}
5830/// Request to list the organization's objectives with pagination.
5831#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5832pub struct ListObjectivesRequest {
5833    /// Pagination parameters.
5834    #[prost(message, optional, tag="1")]
5835    pub pagination: ::core::option::Option<Pagination>,
5836    /// Return only objectives in this state. Unspecified returns every
5837    /// state except OBJECTIVE_STATE_ARCHIVED.
5838    #[prost(enumeration="ObjectiveState", tag="2")]
5839    pub state: i32,
5840    /// Return only entries of this kind. Unspecified returns both kinds.
5841    #[prost(enumeration="ObjectiveKind", tag="3")]
5842    pub kind: i32,
5843}
5844/// Response containing a page of objectives.
5845#[derive(Clone, PartialEq, ::prost::Message)]
5846pub struct ListObjectivesResponse {
5847    /// Objectives in this page.
5848    #[prost(message, repeated, tag="1")]
5849    pub objectives: ::prost::alloc::vec::Vec<Objective>,
5850    /// Pagination metadata for fetching subsequent pages.
5851    #[prost(message, optional, tag="2")]
5852    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5853}
5854/// Request to attach an indicator to an objective.
5855#[derive(Clone, PartialEq, ::prost::Message)]
5856pub struct AddIndicatorRequest {
5857    /// Objective the indicator hangs from. Required.
5858    #[prost(string, tag="1")]
5859    pub objective_id: ::prost::alloc::string::String,
5860    /// Short name. Required.
5861    /// Constraints: Max length 200 characters.
5862    #[prost(string, tag="2")]
5863    pub name: ::prost::alloc::string::String,
5864    /// Unit the readings are expressed in. Optional.
5865    /// Constraints: Max length 50 characters.
5866    #[prost(string, tag="3")]
5867    pub unit: ::prost::alloc::string::String,
5868    /// Desired direction of movement.
5869    #[prost(enumeration="IndicatorDirection", tag="4")]
5870    pub direction: i32,
5871    /// Expected reading cadence.
5872    #[prost(enumeration="IndicatorFrequency", tag="5")]
5873    pub frequency: i32,
5874    /// Accountable user. Optional.
5875    #[prost(string, tag="6")]
5876    pub owner_user_id: ::prost::alloc::string::String,
5877    /// Where readings come from. Required.
5878    #[prost(message, optional, tag="7")]
5879    pub evidence_source: ::core::option::Option<EvidenceSource>,
5880    /// Why this indicator was chosen. Optional.
5881    /// Constraints: Max length 2000 characters.
5882    #[prost(string, tag="8")]
5883    pub rationale: ::prost::alloc::string::String,
5884    /// What it is meant to say about the objective. Optional.
5885    /// Constraints: Max length 2000 characters.
5886    #[prost(string, tag="9")]
5887    pub strategic_meaning: ::prost::alloc::string::String,
5888    /// How a reading should be read. Optional.
5889    /// Constraints: Max length 2000 characters.
5890    #[prost(string, tag="10")]
5891    pub interpretation_guidance: ::prost::alloc::string::String,
5892    /// Behaviour the indicator could encourage if optimized on its own.
5893    /// Optional; the server pre-fills it when left empty and the evidence
5894    /// source implies one.
5895    /// Constraints: Max length 2000 characters.
5896    #[prost(string, tag="11")]
5897    pub perverse_behavior_note: ::prost::alloc::string::String,
5898    /// The value being aimed for, expressed in `unit`. Optional.
5899    #[prost(double, optional, tag="12")]
5900    pub target: ::core::option::Option<f64>,
5901}
5902/// Response after attaching an indicator.
5903#[derive(Clone, PartialEq, ::prost::Message)]
5904pub struct AddIndicatorResponse {
5905    /// The newly created indicator.
5906    #[prost(message, optional, tag="1")]
5907    pub indicator: ::core::option::Option<Indicator>,
5908    /// What follows from declaring a verification campaign as the evidence
5909    /// source, given the shape of the organization. Empty for every other
5910    /// evidence kind, and empty when nothing follows. Advisory only — the
5911    /// indicator was stored regardless.
5912    #[prost(message, repeated, tag="2")]
5913    pub notices: ::prost::alloc::vec::Vec<VerificationSetupNotice>,
5914}
5915/// Request to update an indicator.
5916///
5917/// Every mutable field carries explicit presence and they all follow one
5918/// rule: a field left absent leaves the stored value untouched, and a
5919/// field that is present replaces it — including when the value sent is
5920/// empty. This is what lets an author delete server-pre-filled text such
5921/// as `perverse_behavior_note` instead of only overwriting it.
5922#[derive(Clone, PartialEq, ::prost::Message)]
5923pub struct UpdateIndicatorRequest {
5924    /// ID of the indicator to update. Required.
5925    #[prost(string, tag="1")]
5926    pub indicator_id: ::prost::alloc::string::String,
5927    /// New name.
5928    /// Constraints: Max length 200 characters.
5929    #[prost(string, optional, tag="2")]
5930    pub name: ::core::option::Option<::prost::alloc::string::String>,
5931    /// New unit.
5932    /// Constraints: Max length 50 characters.
5933    #[prost(string, optional, tag="3")]
5934    pub unit: ::core::option::Option<::prost::alloc::string::String>,
5935    /// New direction.
5936    #[prost(enumeration="IndicatorDirection", optional, tag="4")]
5937    pub direction: ::core::option::Option<i32>,
5938    /// New cadence.
5939    #[prost(enumeration="IndicatorFrequency", optional, tag="5")]
5940    pub frequency: ::core::option::Option<i32>,
5941    /// New accountable user. Present and empty detaches the owner.
5942    #[prost(string, optional, tag="6")]
5943    pub owner_user_id: ::core::option::Option<::prost::alloc::string::String>,
5944    /// New evidence source.
5945    #[prost(message, optional, tag="7")]
5946    pub evidence_source: ::core::option::Option<EvidenceSource>,
5947    /// New rationale.
5948    /// Constraints: Max length 2000 characters.
5949    #[prost(string, optional, tag="8")]
5950    pub rationale: ::core::option::Option<::prost::alloc::string::String>,
5951    /// New strategic meaning.
5952    /// Constraints: Max length 2000 characters.
5953    #[prost(string, optional, tag="9")]
5954    pub strategic_meaning: ::core::option::Option<::prost::alloc::string::String>,
5955    /// New interpretation guidance.
5956    /// Constraints: Max length 2000 characters.
5957    #[prost(string, optional, tag="10")]
5958    pub interpretation_guidance: ::core::option::Option<::prost::alloc::string::String>,
5959    /// New note on encouraged behaviour. Present and empty deletes the
5960    /// note, which is how an author rejects the server's pre-filled text.
5961    /// Constraints: Max length 2000 characters.
5962    #[prost(string, optional, tag="11")]
5963    pub perverse_behavior_note: ::core::option::Option<::prost::alloc::string::String>,
5964    /// New target.
5965    #[prost(double, optional, tag="12")]
5966    pub target: ::core::option::Option<f64>,
5967}
5968/// Response after updating an indicator.
5969#[derive(Clone, PartialEq, ::prost::Message)]
5970pub struct UpdateIndicatorResponse {
5971    /// The updated indicator. Notices are recomputed on every update, so
5972    /// an evidence source switched onto or off a verification campaign
5973    /// gets the current answer rather than the one from creation time.
5974    #[prost(message, optional, tag="1")]
5975    pub indicator: ::core::option::Option<Indicator>,
5976    /// What follows from the evidence source as it now stands. Advisory
5977    /// only — the update was applied regardless.
5978    #[prost(message, repeated, tag="2")]
5979    pub notices: ::prost::alloc::vec::Vec<VerificationSetupNotice>,
5980}
5981/// Request to detach an indicator from its objective.
5982#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5983pub struct RemoveIndicatorRequest {
5984    /// ID of the indicator to remove. Required.
5985    #[prost(string, tag="1")]
5986    pub indicator_id: ::prost::alloc::string::String,
5987}
5988/// Response after removing an indicator.
5989#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5990pub struct RemoveIndicatorResponse {
5991}
5992/// Request to declare that a campaign serves an objective.
5993#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5994pub struct LinkCampaignToObjectiveRequest {
5995    /// Campaign to link. Required.
5996    #[prost(string, tag="1")]
5997    pub campaign_id: ::prost::alloc::string::String,
5998    /// Objective the campaign serves. Required.
5999    #[prost(string, tag="2")]
6000    pub objective_id: ::prost::alloc::string::String,
6001    /// How the link came to be. Defaults to LINK_ORIGIN_DECLARED when
6002    /// unspecified.
6003    #[prost(enumeration="LinkOrigin", tag="3")]
6004    pub origin: i32,
6005}
6006/// Response after linking a campaign to an objective.
6007#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6008pub struct LinkCampaignToObjectiveResponse {
6009    /// The recorded link. Linking an already-linked pair is idempotent and
6010    /// returns the existing link.
6011    #[prost(message, optional, tag="1")]
6012    pub link: ::core::option::Option<CampaignObjectiveLink>,
6013}
6014/// Request to remove the declaration that a campaign serves an objective.
6015#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6016pub struct UnlinkCampaignFromObjectiveRequest {
6017    /// Campaign to unlink. Required.
6018    #[prost(string, tag="1")]
6019    pub campaign_id: ::prost::alloc::string::String,
6020    /// Objective to unlink it from. Required.
6021    #[prost(string, tag="2")]
6022    pub objective_id: ::prost::alloc::string::String,
6023}
6024/// Response after unlinking a campaign from an objective.
6025#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6026pub struct UnlinkCampaignFromObjectiveResponse {
6027}
6028/// Request to list campaign-to-objective links, from either end of the
6029/// relationship. Exactly one of `objective_id` and `campaign_id` must be
6030/// set; sending both, or neither, returns INVALID_ARGUMENT.
6031#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6032pub struct ListCampaignObjectiveLinksRequest {
6033    /// List the campaigns that serve this objective.
6034    #[prost(string, optional, tag="1")]
6035    pub objective_id: ::core::option::Option<::prost::alloc::string::String>,
6036    /// Pagination parameters.
6037    #[prost(message, optional, tag="2")]
6038    pub pagination: ::core::option::Option<Pagination>,
6039    /// List the objectives this campaign serves.
6040    #[prost(string, optional, tag="3")]
6041    pub campaign_id: ::core::option::Option<::prost::alloc::string::String>,
6042}
6043/// Response containing a page of campaign links.
6044#[derive(Clone, PartialEq, ::prost::Message)]
6045pub struct ListCampaignObjectiveLinksResponse {
6046    /// Links in this page, newest first.
6047    #[prost(message, repeated, tag="1")]
6048    pub links: ::prost::alloc::vec::Vec<CampaignObjectiveLink>,
6049    /// Pagination metadata for fetching subsequent pages.
6050    #[prost(message, optional, tag="2")]
6051    pub pagination_meta: ::core::option::Option<PaginationMeta>,
6052}
6053/// A candidate way of observing an objective, offered for a person to
6054/// accept, edit or throw away.
6055///
6056/// A suggestion is not an indicator and carries no identifier, because
6057/// nothing has been created. Proposing how an objective might be
6058/// observed is a bounded generative task and the platform is useful at
6059/// it; deciding that the proposed measure actually moves with the
6060/// objective is not something any model can settle, and only accumulated
6061/// readings can. Keeping the two apart is the point of this message
6062/// existing separately from Indicator.
6063#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6064pub struct IndicatorSuggestion {
6065    /// Proposed name for the indicator.
6066    #[prost(string, tag="1")]
6067    pub name: ::prost::alloc::string::String,
6068    /// Proposed unit the readings would be expressed in.
6069    #[prost(string, tag="2")]
6070    pub unit: ::prost::alloc::string::String,
6071    /// Proposed direction of desired movement.
6072    #[prost(enumeration="IndicatorDirection", tag="3")]
6073    pub direction: i32,
6074    /// Where readings would have to come from for this measure to exist.
6075    /// Part of the suggestion because a measure nobody can source is not a
6076    /// usable proposal.
6077    #[prost(enumeration="EvidenceSourceKind", tag="4")]
6078    pub evidence_source_kind: i32,
6079    /// Why this measure was proposed for this objective, in plain
6080    /// language, so the reader can reject it on the reasoning rather than
6081    /// on the wording.
6082    #[prost(string, tag="5")]
6083    pub rationale: ::prost::alloc::string::String,
6084}
6085/// Request for candidate indicators for a declared objective.
6086#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6087pub struct SuggestIndicatorsRequest {
6088    /// Objective to propose indicators for. Required.
6089    #[prost(string, tag="1")]
6090    pub objective_id: ::prost::alloc::string::String,
6091}
6092/// Response containing candidate indicators.
6093#[derive(Clone, PartialEq, ::prost::Message)]
6094pub struct SuggestIndicatorsResponse {
6095    /// Candidates, most relevant first. Never applied by the server —
6096    /// acting on one means calling AddIndicator with its contents, and the
6097    /// indicator that results is unverified like any other.
6098    ///
6099    /// Empty when no candidate could be produced, including when the
6100    /// organization has model-assisted features turned off. Suggestions
6101    /// are a convenience and nothing in the contract depends on them, so
6102    /// their absence is not an error.
6103    #[prost(message, repeated, tag="1")]
6104    pub suggestions: ::prost::alloc::vec::Vec<IndicatorSuggestion>,
6105}
6106// ─── Enums ──────────────────────────────────────────────────────────────────
6107
6108/// Lifecycle state of an objective.
6109#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6110#[repr(i32)]
6111pub enum ObjectiveState {
6112    Unspecified = 0,
6113    /// Being drafted. Not yet part of the organization's declared set and
6114    /// excluded from any analysis that reads the set as a whole.
6115    Draft = 1,
6116    /// Declared and in force.
6117    Active = 2,
6118    /// Withdrawn. Kept for history and for links already recorded against
6119    /// it, but no longer part of the declared set.
6120    Archived = 3,
6121}
6122impl ObjectiveState {
6123    /// String value of the enum field names used in the ProtoBuf definition.
6124    ///
6125    /// The values are not transformed in any way and thus are considered stable
6126    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6127    pub fn as_str_name(&self) -> &'static str {
6128        match self {
6129            Self::Unspecified => "OBJECTIVE_STATE_UNSPECIFIED",
6130            Self::Draft => "OBJECTIVE_STATE_DRAFT",
6131            Self::Active => "OBJECTIVE_STATE_ACTIVE",
6132            Self::Archived => "OBJECTIVE_STATE_ARCHIVED",
6133        }
6134    }
6135    /// Creates an enum from field names used in the ProtoBuf definition.
6136    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6137        match value {
6138            "OBJECTIVE_STATE_UNSPECIFIED" => Some(Self::Unspecified),
6139            "OBJECTIVE_STATE_DRAFT" => Some(Self::Draft),
6140            "OBJECTIVE_STATE_ACTIVE" => Some(Self::Active),
6141            "OBJECTIVE_STATE_ARCHIVED" => Some(Self::Archived),
6142            _ => None,
6143        }
6144    }
6145}
6146/// Whether the entry is a standing desired state or a time-bounded
6147/// effort. The distinction is structural, not cosmetic: analyses that
6148/// read the declared set as a whole (coverage, overlap, gaps) apply only
6149/// to standing objectives, because a time-bounded effort is expected to
6150/// end and would distort them.
6151#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6152#[repr(i32)]
6153pub enum ObjectiveKind {
6154    Unspecified = 0,
6155    /// A desired state with no end date, written as a condition rather
6156    /// than as a change or a target.
6157    Objective = 1,
6158    /// A time-bounded effort with an explicit end. May stand alone or hang
6159    /// off a standing objective.
6160    Initiative = 2,
6161}
6162impl ObjectiveKind {
6163    /// String value of the enum field names used in the ProtoBuf definition.
6164    ///
6165    /// The values are not transformed in any way and thus are considered stable
6166    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6167    pub fn as_str_name(&self) -> &'static str {
6168        match self {
6169            Self::Unspecified => "OBJECTIVE_KIND_UNSPECIFIED",
6170            Self::Objective => "OBJECTIVE_KIND_OBJECTIVE",
6171            Self::Initiative => "OBJECTIVE_KIND_INITIATIVE",
6172        }
6173    }
6174    /// Creates an enum from field names used in the ProtoBuf definition.
6175    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6176        match value {
6177            "OBJECTIVE_KIND_UNSPECIFIED" => Some(Self::Unspecified),
6178            "OBJECTIVE_KIND_OBJECTIVE" => Some(Self::Objective),
6179            "OBJECTIVE_KIND_INITIATIVE" => Some(Self::Initiative),
6180            _ => None,
6181        }
6182    }
6183}
6184/// A form problem detected in an objective's wording. Advisory only —
6185/// servers never reject a write because of one, and clients present the
6186/// finding alongside the suggested rewrite while still allowing the save.
6187#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6188#[repr(i32)]
6189pub enum ObjectiveWritingIssue {
6190    Unspecified = 0,
6191    /// Phrased as a change ("improve", "reduce", "increase") rather than
6192    /// as the state that should hold once the change has happened.
6193    ChangeVerb = 1,
6194    /// Carries a number, percentage or date inside the statement, which
6195    /// makes it a target rather than a state. Targets belong on
6196    /// indicators.
6197    EmbeddedTarget = 2,
6198    /// Phrased as a project ("launch", "roll out", "migrate"), which has
6199    /// an end and therefore describes an initiative rather than a
6200    /// standing objective.
6201    ProjectForm = 3,
6202}
6203impl ObjectiveWritingIssue {
6204    /// String value of the enum field names used in the ProtoBuf definition.
6205    ///
6206    /// The values are not transformed in any way and thus are considered stable
6207    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6208    pub fn as_str_name(&self) -> &'static str {
6209        match self {
6210            Self::Unspecified => "OBJECTIVE_WRITING_ISSUE_UNSPECIFIED",
6211            Self::ChangeVerb => "OBJECTIVE_WRITING_ISSUE_CHANGE_VERB",
6212            Self::EmbeddedTarget => "OBJECTIVE_WRITING_ISSUE_EMBEDDED_TARGET",
6213            Self::ProjectForm => "OBJECTIVE_WRITING_ISSUE_PROJECT_FORM",
6214        }
6215    }
6216    /// Creates an enum from field names used in the ProtoBuf definition.
6217    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6218        match value {
6219            "OBJECTIVE_WRITING_ISSUE_UNSPECIFIED" => Some(Self::Unspecified),
6220            "OBJECTIVE_WRITING_ISSUE_CHANGE_VERB" => Some(Self::ChangeVerb),
6221            "OBJECTIVE_WRITING_ISSUE_EMBEDDED_TARGET" => Some(Self::EmbeddedTarget),
6222            "OBJECTIVE_WRITING_ISSUE_PROJECT_FORM" => Some(Self::ProjectForm),
6223            _ => None,
6224        }
6225    }
6226}
6227/// Whether a higher or a lower reading of an indicator is the desired
6228/// direction.
6229#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6230#[repr(i32)]
6231pub enum IndicatorDirection {
6232    Unspecified = 0,
6233    HigherIsBetter = 1,
6234    LowerIsBetter = 2,
6235}
6236impl IndicatorDirection {
6237    /// String value of the enum field names used in the ProtoBuf definition.
6238    ///
6239    /// The values are not transformed in any way and thus are considered stable
6240    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6241    pub fn as_str_name(&self) -> &'static str {
6242        match self {
6243            Self::Unspecified => "INDICATOR_DIRECTION_UNSPECIFIED",
6244            Self::HigherIsBetter => "INDICATOR_DIRECTION_HIGHER_IS_BETTER",
6245            Self::LowerIsBetter => "INDICATOR_DIRECTION_LOWER_IS_BETTER",
6246        }
6247    }
6248    /// Creates an enum from field names used in the ProtoBuf definition.
6249    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6250        match value {
6251            "INDICATOR_DIRECTION_UNSPECIFIED" => Some(Self::Unspecified),
6252            "INDICATOR_DIRECTION_HIGHER_IS_BETTER" => Some(Self::HigherIsBetter),
6253            "INDICATOR_DIRECTION_LOWER_IS_BETTER" => Some(Self::LowerIsBetter),
6254            _ => None,
6255        }
6256    }
6257}
6258/// How often an indicator is expected to be read.
6259#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6260#[repr(i32)]
6261pub enum IndicatorFrequency {
6262    Unspecified = 0,
6263    Daily = 1,
6264    Weekly = 2,
6265    Monthly = 3,
6266    Quarterly = 4,
6267    Annually = 5,
6268    /// Read on demand, with no fixed cadence.
6269    AdHoc = 6,
6270}
6271impl IndicatorFrequency {
6272    /// String value of the enum field names used in the ProtoBuf definition.
6273    ///
6274    /// The values are not transformed in any way and thus are considered stable
6275    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6276    pub fn as_str_name(&self) -> &'static str {
6277        match self {
6278            Self::Unspecified => "INDICATOR_FREQUENCY_UNSPECIFIED",
6279            Self::Daily => "INDICATOR_FREQUENCY_DAILY",
6280            Self::Weekly => "INDICATOR_FREQUENCY_WEEKLY",
6281            Self::Monthly => "INDICATOR_FREQUENCY_MONTHLY",
6282            Self::Quarterly => "INDICATOR_FREQUENCY_QUARTERLY",
6283            Self::Annually => "INDICATOR_FREQUENCY_ANNUALLY",
6284            Self::AdHoc => "INDICATOR_FREQUENCY_AD_HOC",
6285        }
6286    }
6287    /// Creates an enum from field names used in the ProtoBuf definition.
6288    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6289        match value {
6290            "INDICATOR_FREQUENCY_UNSPECIFIED" => Some(Self::Unspecified),
6291            "INDICATOR_FREQUENCY_DAILY" => Some(Self::Daily),
6292            "INDICATOR_FREQUENCY_WEEKLY" => Some(Self::Weekly),
6293            "INDICATOR_FREQUENCY_MONTHLY" => Some(Self::Monthly),
6294            "INDICATOR_FREQUENCY_QUARTERLY" => Some(Self::Quarterly),
6295            "INDICATOR_FREQUENCY_ANNUALLY" => Some(Self::Annually),
6296            "INDICATOR_FREQUENCY_AD_HOC" => Some(Self::AdHoc),
6297            _ => None,
6298        }
6299    }
6300}
6301/// Where an indicator's readings come from. Each kind is an adapter over
6302/// the same contract; kinds that are not yet implemented are rejected
6303/// with UNIMPLEMENTED rather than silently accepted.
6304#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6305#[repr(i32)]
6306pub enum EvidenceSourceKind {
6307    Unspecified = 0,
6308    /// Signals produced inside the product by the audience of the message
6309    /// itself (acknowledgment, poll answer, and so on). Carries
6310    /// InAppEvidence.
6311    InApp = 1,
6312    /// A deferred follow-up message sent to someone other than the
6313    /// audience, whose answer is stored as a reading of this indicator.
6314    /// Carries VerificationCampaignEvidence.
6315    VerificationCampaign = 2,
6316    /// The organization pushes the operational fact from one of its own
6317    /// systems. Carries WebhookEvidence. Returns UNIMPLEMENTED until the
6318    /// adapter is built.
6319    Webhook = 3,
6320    /// Readings entered by hand or imported from a spreadsheet. Carries
6321    /// ManualEntryEvidence. Returns UNIMPLEMENTED until the adapter is
6322    /// built.
6323    ManualEntry = 4,
6324}
6325impl EvidenceSourceKind {
6326    /// String value of the enum field names used in the ProtoBuf definition.
6327    ///
6328    /// The values are not transformed in any way and thus are considered stable
6329    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6330    pub fn as_str_name(&self) -> &'static str {
6331        match self {
6332            Self::Unspecified => "EVIDENCE_SOURCE_KIND_UNSPECIFIED",
6333            Self::InApp => "EVIDENCE_SOURCE_KIND_IN_APP",
6334            Self::VerificationCampaign => "EVIDENCE_SOURCE_KIND_VERIFICATION_CAMPAIGN",
6335            Self::Webhook => "EVIDENCE_SOURCE_KIND_WEBHOOK",
6336            Self::ManualEntry => "EVIDENCE_SOURCE_KIND_MANUAL_ENTRY",
6337        }
6338    }
6339    /// Creates an enum from field names used in the ProtoBuf definition.
6340    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6341        match value {
6342            "EVIDENCE_SOURCE_KIND_UNSPECIFIED" => Some(Self::Unspecified),
6343            "EVIDENCE_SOURCE_KIND_IN_APP" => Some(Self::InApp),
6344            "EVIDENCE_SOURCE_KIND_VERIFICATION_CAMPAIGN" => Some(Self::VerificationCampaign),
6345            "EVIDENCE_SOURCE_KIND_WEBHOOK" => Some(Self::Webhook),
6346            "EVIDENCE_SOURCE_KIND_MANUAL_ENTRY" => Some(Self::ManualEntry),
6347            _ => None,
6348        }
6349    }
6350}
6351/// Whether an evidence source observes the whole population or a sample
6352/// of it.
6353#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6354#[repr(i32)]
6355pub enum EvidenceCoverage {
6356    Unspecified = 0,
6357    Full = 1,
6358    Sampled = 2,
6359}
6360impl EvidenceCoverage {
6361    /// String value of the enum field names used in the ProtoBuf definition.
6362    ///
6363    /// The values are not transformed in any way and thus are considered stable
6364    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6365    pub fn as_str_name(&self) -> &'static str {
6366        match self {
6367            Self::Unspecified => "EVIDENCE_COVERAGE_UNSPECIFIED",
6368            Self::Full => "EVIDENCE_COVERAGE_FULL",
6369            Self::Sampled => "EVIDENCE_COVERAGE_SAMPLED",
6370        }
6371    }
6372    /// Creates an enum from field names used in the ProtoBuf definition.
6373    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6374        match value {
6375            "EVIDENCE_COVERAGE_UNSPECIFIED" => Some(Self::Unspecified),
6376            "EVIDENCE_COVERAGE_FULL" => Some(Self::Full),
6377            "EVIDENCE_COVERAGE_SAMPLED" => Some(Self::Sampled),
6378            _ => None,
6379        }
6380    }
6381}
6382/// How the recipients of a verification message are derived from the
6383/// audience of the message being verified.
6384#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6385#[repr(i32)]
6386pub enum VerifierDerivation {
6387    Unspecified = 0,
6388    /// Each audience member's manager, deduplicated. Self-targets are
6389    /// dropped.
6390    Manager = 1,
6391}
6392impl VerifierDerivation {
6393    /// String value of the enum field names used in the ProtoBuf definition.
6394    ///
6395    /// The values are not transformed in any way and thus are considered stable
6396    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6397    pub fn as_str_name(&self) -> &'static str {
6398        match self {
6399            Self::Unspecified => "VERIFIER_DERIVATION_UNSPECIFIED",
6400            Self::Manager => "VERIFIER_DERIVATION_MANAGER",
6401        }
6402    }
6403    /// Creates an enum from field names used in the ProtoBuf definition.
6404    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6405        match value {
6406            "VERIFIER_DERIVATION_UNSPECIFIED" => Some(Self::Unspecified),
6407            "VERIFIER_DERIVATION_MANAGER" => Some(Self::Manager),
6408            _ => None,
6409        }
6410    }
6411}
6412/// Whether an indicator has ever been corroborated by evidence outside
6413/// of the declaration that created it.
6414///
6415/// Recording readings is not part of this service. An indicator becomes
6416/// verified when an IndicatorReading is stored against it, which the
6417/// platform does from campaign outcomes; no RPC defined here can move
6418/// the state, so every indicator created or updated via
6419/// ObjectivesService stays UNVERIFIED.
6420#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6421#[repr(i32)]
6422pub enum IndicatorVerificationState {
6423    Unspecified = 0,
6424    /// No corroborating reading has been recorded. This is the state of
6425    /// every newly created indicator, including one whose wording was
6426    /// suggested by a model: a suggestion is not evidence, and callers
6427    /// must not present an unverified indicator as one that is known to
6428    /// track its objective.
6429    Unverified = 1,
6430    /// At least one reading from the declared evidence source has been
6431    /// recorded against this indicator. The state says evidence exists,
6432    /// not that the evidence was favourable — an indicator corroborated by
6433    /// a negative reading is verified all the same.
6434    Verified = 2,
6435}
6436impl IndicatorVerificationState {
6437    /// String value of the enum field names used in the ProtoBuf definition.
6438    ///
6439    /// The values are not transformed in any way and thus are considered stable
6440    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6441    pub fn as_str_name(&self) -> &'static str {
6442        match self {
6443            Self::Unspecified => "INDICATOR_VERIFICATION_STATE_UNSPECIFIED",
6444            Self::Unverified => "INDICATOR_VERIFICATION_STATE_UNVERIFIED",
6445            Self::Verified => "INDICATOR_VERIFICATION_STATE_VERIFIED",
6446        }
6447    }
6448    /// Creates an enum from field names used in the ProtoBuf definition.
6449    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6450        match value {
6451            "INDICATOR_VERIFICATION_STATE_UNSPECIFIED" => Some(Self::Unspecified),
6452            "INDICATOR_VERIFICATION_STATE_UNVERIFIED" => Some(Self::Unverified),
6453            "INDICATOR_VERIFICATION_STATE_VERIFIED" => Some(Self::Verified),
6454            _ => None,
6455        }
6456    }
6457}
6458/// How a campaign came to be linked to an objective.
6459#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6460#[repr(i32)]
6461pub enum LinkOrigin {
6462    Unspecified = 0,
6463    /// Chosen explicitly by a person.
6464    Declared = 1,
6465    /// Proposed by the system from content similarity and confirmed by a
6466    /// person.
6467    Suggested = 2,
6468    /// Applied in bulk over historical campaigns when the objective set
6469    /// was first configured.
6470    Backfill = 3,
6471}
6472impl LinkOrigin {
6473    /// String value of the enum field names used in the ProtoBuf definition.
6474    ///
6475    /// The values are not transformed in any way and thus are considered stable
6476    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6477    pub fn as_str_name(&self) -> &'static str {
6478        match self {
6479            Self::Unspecified => "LINK_ORIGIN_UNSPECIFIED",
6480            Self::Declared => "LINK_ORIGIN_DECLARED",
6481            Self::Suggested => "LINK_ORIGIN_SUGGESTED",
6482            Self::Backfill => "LINK_ORIGIN_BACKFILL",
6483        }
6484    }
6485    /// Creates an enum from field names used in the ProtoBuf definition.
6486    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6487        match value {
6488            "LINK_ORIGIN_UNSPECIFIED" => Some(Self::Unspecified),
6489            "LINK_ORIGIN_DECLARED" => Some(Self::Declared),
6490            "LINK_ORIGIN_SUGGESTED" => Some(Self::Suggested),
6491            "LINK_ORIGIN_BACKFILL" => Some(Self::Backfill),
6492            _ => None,
6493        }
6494    }
6495}
6496// ─── Messages ───────────────────────────────────────────────────────────────
6497
6498/// A single non-retired pepper version. Returned by GetPeppers.
6499///
6500/// During a rotation overlap, multiple versions are returned — callers
6501/// (e.g. pidgr-integrations) compute lookup hashes under EVERY returned
6502/// version to write or match against `identifier_lookup_hash_v1` and
6503/// `identifier_lookup_hash_v2` on the reachability registry.
6504#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6505pub struct Pepper {
6506    /// Monotonically-increasing version number. Lower versions retire first.
6507    #[prost(int32, tag="1")]
6508    pub version: i32,
6509    /// Raw HMAC key material. Sensitive — callers MUST NOT log or persist
6510    /// this value to disk. In-memory caching keyed on (org_id, version) with
6511    /// a short TTL is permitted and expected.
6512    #[prost(bytes="vec", tag="2")]
6513    pub key_material: ::prost::alloc::vec::Vec<u8>,
6514}
6515/// Request to fetch the active (non-retired) peppers for one org/purpose.
6516///
6517/// Auth: internal-mTLS only. This RPC exposes raw cryptographic key material
6518/// and MUST NOT be reachable from the public ingress or from JWT-authenticated
6519/// clients. The server SHALL reject any caller whose mTLS identity is not on
6520/// the configured allowlist.
6521#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6522pub struct GetPeppersRequest {
6523    /// Organization whose peppers are requested.
6524    #[prost(string, tag="1")]
6525    pub org_id: ::prost::alloc::string::String,
6526    /// Purpose identifier scoping which key family to return. Use
6527    /// `"reachability_lookup"` for the pidgr-integrations registry lookup hash.
6528    #[prost(string, tag="2")]
6529    pub purpose: ::prost::alloc::string::String,
6530}
6531#[derive(Clone, PartialEq, ::prost::Message)]
6532pub struct GetPeppersResponse {
6533    /// All non-retired pepper versions for the (org_id, purpose) pair, in
6534    /// ascending version order. Typically exactly one entry; two during a
6535    /// rotation overlap window; zero only when no pepper has ever been
6536    /// generated for this (org, purpose).
6537    #[prost(message, repeated, tag="1")]
6538    pub peppers: ::prost::alloc::vec::Vec<Pepper>,
6539}
6540// ─── Messages ───────────────────────────────────────────────────────────────
6541
6542/// Maps an identity provider claim to a user profile field.
6543/// Used for automatic profile population when users authenticate via SSO/SAML.
6544#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6545pub struct SsoAttributeMapping {
6546    /// Claim name from the identity provider (e.g. "urn:oid:2.5.4.11", "given_name").
6547    /// Constraints: Max length 500 characters.
6548    #[prost(string, tag="1")]
6549    pub idp_claim: ::prost::alloc::string::String,
6550    /// Target UserProfile field name (e.g. "department", "first_name").
6551    /// For custom attributes, use "custom:" prefix (e.g. "custom:cost_center").
6552    /// Constraints: Max length 100 characters.
6553    #[prost(string, tag="2")]
6554    pub profile_field: ::prost::alloc::string::String,
6555}
6556/// An organization (tenant) in the Pidgr platform.
6557#[derive(Clone, PartialEq, ::prost::Message)]
6558pub struct Organization {
6559    /// Unique identifier for the organization.
6560    #[prost(string, tag="1")]
6561    pub id: ::prost::alloc::string::String,
6562    /// Organization display name.
6563    /// Constraints: Max length 200 characters.
6564    #[prost(string, tag="2")]
6565    pub name: ::prost::alloc::string::String,
6566    /// Default workflow used when campaigns don't specify one.
6567    #[prost(message, optional, tag="3")]
6568    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
6569    /// Timestamp when the organization was created.
6570    #[prost(message, optional, tag="4")]
6571    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
6572    /// Industry vertical.
6573    #[prost(enumeration="Industry", tag="5")]
6574    pub industry: i32,
6575    /// Employee headcount range.
6576    #[prost(enumeration="CompanySize", tag="6")]
6577    pub company_size: i32,
6578    /// SSO identity provider claim-to-profile mappings.
6579    /// Empty when the organization does not use SSO.
6580    #[prost(message, repeated, tag="7")]
6581    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
6582    /// Default language for new users in this organization.
6583    /// Empty means no org default (users auto-detect from device/browser).
6584    /// Valid values: en, es, pt-BR, zh, ja.
6585    #[prost(string, tag="8")]
6586    pub default_locale: ::prost::alloc::string::String,
6587    /// Organization lifecycle type.
6588    #[prost(enumeration="OrgType", tag="9")]
6589    pub org_type: i32,
6590    /// Expiration time for sandbox organizations. Empty for standard orgs.
6591    #[prost(message, optional, tag="10")]
6592    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
6593    /// Data governance framework (EU, LATAM, BR, APAC, US).
6594    /// Determines legal framework, DPA template, and Bedrock endpoint routing.
6595    #[prost(string, tag="11")]
6596    pub data_governance_region: ::prost::alloc::string::String,
6597    /// AWS region for content storage (resolved from data_governance_region).
6598    /// e.g., "eu-west-1", "us-east-1".
6599    #[prost(string, tag="12")]
6600    pub data_content_region: ::prost::alloc::string::String,
6601    /// ─── ML pipeline settings ──────────────────────────────────────────────────
6602    /// Cold-start threshold: completed campaigns below this count trigger immediate
6603    /// retraining. At or above, the org is flagged for the weekly cron.
6604    /// Default 10, range 1-100.
6605    #[prost(int32, tag="13")]
6606    pub ml_retrain_cold_threshold: i32,
6607    /// Whether cancelled campaigns count toward the training counter. Default true.
6608    #[prost(bool, tag="14")]
6609    pub ml_cancelled_counts: bool,
6610    /// Monthly limit on manual retrain triggers. Default 3, range 0-10.
6611    #[prost(int32, tag="15")]
6612    pub ml_manual_limit_monthly: i32,
6613    /// Number of manual retrains used in the current month (resets monthly).
6614    #[prost(int32, tag="16")]
6615    pub ml_manual_retrains_used: i32,
6616    /// Whether the org is flagged for the next weekly cron run.
6617    #[prost(bool, tag="17")]
6618    pub ml_needs_retrain: bool,
6619    /// Campaigns completed since the last ML training run.
6620    #[prost(int32, tag="18")]
6621    pub campaigns_since_last_training: i32,
6622    /// Total campaigns completed across the organization lifetime.
6623    #[prost(int32, tag="19")]
6624    pub total_completed_campaigns: i32,
6625    /// Timestamp of the most recent successful ML training. Empty if never trained.
6626    #[prost(message, optional, tag="20")]
6627    pub last_ml_training_at: ::core::option::Option<::prost_types::Timestamp>,
6628    /// Controls whether aggregate stats (campaign recipient/ack/missed counts)
6629    /// include synthetic data. Unset = default by org type: sandbox orgs include,
6630    /// standard orgs exclude. Derived intelligence (ML, analytics, attestation
6631    /// evidence) always excludes synthetic regardless of this setting.
6632    #[prost(bool, optional, tag="21")]
6633    pub include_synthetic_in_aggregates: ::core::option::Option<bool>,
6634    /// Whether the organization has opted into provisional (rule-based,
6635    /// low-confidence) archetypes for groups that don't yet have trained
6636    /// ML archetypes. Only meaningful for ORG_TYPE_STANDARD — sandbox
6637    /// organizations are always eligible regardless of this setting.
6638    /// Default false: production analytics stay conservative.
6639    #[prost(bool, tag="22")]
6640    pub provisional_archetypes_enabled: bool,
6641}
6642/// Request to create a new organization.
6643/// JWT auth only — the authenticated caller becomes the initial admin. Additional
6644/// admins are added via CreateInviteLink after the org exists.
6645#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6646pub struct CreateOrganizationRequest {
6647    /// Name for the new organization.
6648    /// Constraints: Max length 200 characters.
6649    #[prost(string, tag="1")]
6650    pub name: ::prost::alloc::string::String,
6651    /// Industry vertical for the organization.
6652    #[prost(enumeration="Industry", tag="2")]
6653    pub industry: i32,
6654    /// Employee headcount range.
6655    #[prost(enumeration="CompanySize", tag="3")]
6656    pub company_size: i32,
6657    /// Access code required during early access.
6658    /// Format: PIDGR-XXXXXXXX (8 alphanumeric characters).
6659    #[prost(string, tag="4")]
6660    pub access_code: ::prost::alloc::string::String,
6661    /// Data governance framework. Defaults to "US" if omitted.
6662    /// Valid values: EU, LATAM, BR, APAC, US.
6663    #[prost(string, tag="5")]
6664    pub data_governance_region: ::prost::alloc::string::String,
6665    /// Optional bootstrap fixture to seed the organization with starter data.
6666    /// Empty string means the default fixture.
6667    #[prost(string, tag="6")]
6668    pub fixture_id: ::prost::alloc::string::String,
6669}
6670/// Response after creating an organization.
6671#[derive(Clone, PartialEq, ::prost::Message)]
6672pub struct CreateOrganizationResponse {
6673    /// The newly created organization.
6674    #[prost(message, optional, tag="1")]
6675    pub organization: ::core::option::Option<Organization>,
6676    /// The admin user created for the organization.
6677    #[prost(message, optional, tag="2")]
6678    pub admin_user: ::core::option::Option<User>,
6679}
6680/// Request to retrieve the organization for the authenticated user.
6681#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6682pub struct GetOrganizationRequest {
6683}
6684/// Response containing the organization.
6685#[derive(Clone, PartialEq, ::prost::Message)]
6686pub struct GetOrganizationResponse {
6687    /// The organization the authenticated user belongs to.
6688    #[prost(message, optional, tag="1")]
6689    pub organization: ::core::option::Option<Organization>,
6690}
6691/// Request to update organization settings.
6692#[derive(Clone, PartialEq, ::prost::Message)]
6693pub struct UpdateOrganizationRequest {
6694    /// New organization name. Empty string leaves unchanged.
6695    /// Constraints: Max length 200 characters.
6696    #[prost(string, tag="1")]
6697    pub name: ::prost::alloc::string::String,
6698    /// New default workflow definition. Null leaves unchanged.
6699    #[prost(message, optional, tag="2")]
6700    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
6701    /// New industry vertical. UNSPECIFIED leaves unchanged.
6702    #[prost(enumeration="Industry", tag="3")]
6703    pub industry: i32,
6704    /// New employee headcount range. UNSPECIFIED leaves unchanged.
6705    #[prost(enumeration="CompanySize", tag="4")]
6706    pub company_size: i32,
6707    /// New default language for new users. Empty string leaves unchanged.
6708    /// Valid values: en, es, pt-BR, zh, ja.
6709    #[prost(string, tag="5")]
6710    pub default_locale: ::prost::alloc::string::String,
6711    /// New ML cold-start threshold. 0 leaves unchanged, otherwise must be in \[1, 100\].
6712    #[prost(int32, tag="6")]
6713    pub ml_retrain_cold_threshold: i32,
6714    /// New ML cancelled-counts flag. Uses google.protobuf.BoolValue-style semantics
6715    /// via optional to distinguish "not provided" from "set to false".
6716    #[prost(bool, optional, tag="7")]
6717    pub ml_cancelled_counts: ::core::option::Option<bool>,
6718    /// New ML monthly manual limit. Negative leaves unchanged, otherwise must be in \[0, 10\].
6719    /// Encoded as int32 with -1 meaning "leave unchanged".
6720    #[prost(int32, tag="8")]
6721    pub ml_manual_limit_monthly: i32,
6722    /// Set the synthetic-aggregates override; unset leaves it unchanged.
6723    #[prost(bool, optional, tag="9")]
6724    pub include_synthetic_in_aggregates: ::core::option::Option<bool>,
6725    /// New provisional-archetypes opt-in for standard organizations.
6726    /// Unset leaves unchanged. Rejected for sandbox organizations, which
6727    /// are always eligible automatically.
6728    #[prost(bool, optional, tag="10")]
6729    pub provisional_archetypes_enabled: ::core::option::Option<bool>,
6730}
6731/// Response after updating the organization.
6732#[derive(Clone, PartialEq, ::prost::Message)]
6733pub struct UpdateOrganizationResponse {
6734    /// The updated organization.
6735    #[prost(message, optional, tag="1")]
6736    pub organization: ::core::option::Option<Organization>,
6737}
6738/// Request to replace all SSO attribute mappings for the organization.
6739#[derive(Clone, PartialEq, ::prost::Message)]
6740pub struct UpdateSsoAttributeMappingsRequest {
6741    /// Complete list of SSO mappings (replaces all existing mappings).
6742    #[prost(message, repeated, tag="1")]
6743    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
6744}
6745/// Response after updating SSO attribute mappings.
6746#[derive(Clone, PartialEq, ::prost::Message)]
6747pub struct UpdateSsoAttributeMappingsResponse {
6748    /// The updated organization with the new SSO mappings.
6749    #[prost(message, optional, tag="1")]
6750    pub organization: ::core::option::Option<Organization>,
6751}
6752/// Request to rotate the analytics salt and optionally increase the bucket count.
6753#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6754pub struct RotateAnalyticsSaltRequest {
6755    /// New bucket count. Must be >= current bucket count. 0 means keep current.
6756    #[prost(int32, tag="1")]
6757    pub new_bucket_count: i32,
6758}
6759/// Response after rotating the analytics salt.
6760#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6761pub struct RotateAnalyticsSaltResponse {
6762    /// The new bucket count after rotation.
6763    #[prost(int32, tag="1")]
6764    pub bucket_count: i32,
6765}
6766/// Request to update the analytics epsilon (differential privacy parameter).
6767#[derive(Clone, Copy, PartialEq, ::prost::Message)]
6768pub struct UpdateAnalyticsEpsilonRequest {
6769    /// New epsilon value. Must be in range \[0.5, 5.0\].
6770    #[prost(float, tag="1")]
6771    pub epsilon: f32,
6772}
6773/// Response after updating the analytics epsilon.
6774#[derive(Clone, Copy, PartialEq, ::prost::Message)]
6775pub struct UpdateAnalyticsEpsilonResponse {
6776    /// The new epsilon value.
6777    #[prost(float, tag="1")]
6778    pub epsilon: f32,
6779}
6780/// Request to create a sandbox organization for testing.
6781#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6782pub struct CreateSandboxOrganizationRequest {
6783    /// Name for the sandbox organization.
6784    /// Constraints: Max length 200 characters.
6785    #[prost(string, tag="1")]
6786    pub name: ::prost::alloc::string::String,
6787    /// Required expiration time. Max 30 days from now for interactive callers;
6788    /// API-key callers may set shorter TTLs for ephemeral test sandboxes.
6789    #[prost(message, optional, tag="2")]
6790    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
6791    /// Data governance framework. Defaults to "US" if omitted.
6792    /// Valid values: EU, LATAM, BR, APAC, US.
6793    #[prost(string, tag="3")]
6794    pub data_governance_region: ::prost::alloc::string::String,
6795    /// Optional bootstrap fixture to seed the sandbox with starter data.
6796    /// Empty string means the default fixture.
6797    /// Must match an id returned by ListSandboxFixtures.
6798    #[prost(string, tag="4")]
6799    pub fixture_id: ::prost::alloc::string::String,
6800}
6801/// Response after creating a sandbox organization.
6802#[derive(Clone, PartialEq, ::prost::Message)]
6803pub struct CreateSandboxOrganizationResponse {
6804    /// The newly created sandbox organization (org_type: SANDBOX).
6805    #[prost(message, optional, tag="1")]
6806    pub organization: ::core::option::Option<Organization>,
6807    /// The admin user created for the sandbox.
6808    #[prost(message, optional, tag="2")]
6809    pub admin_user: ::core::option::Option<User>,
6810}
6811/// Request to delete a sandbox organization. Only callable for orgs with
6812/// org_type=SANDBOX. Allowed for super admins of the sandbox or the creator.
6813#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6814pub struct DeleteSandboxOrganizationRequest {
6815    /// ID of the sandbox organization to delete.
6816    #[prost(string, tag="1")]
6817    pub org_id: ::prost::alloc::string::String,
6818}
6819/// Response after requesting deletion. Deletion runs asynchronously via
6820/// the DeleteOrgWorkflow; a success response means the workflow started.
6821#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6822pub struct DeleteSandboxOrganizationResponse {
6823    /// ID of the Temporal workflow handling the deletion.
6824    #[prost(string, tag="1")]
6825    pub workflow_id: ::prost::alloc::string::String,
6826}
6827/// A bootstrap fixture that can be applied when creating a new organization.
6828#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6829pub struct SandboxFixture {
6830    /// Stable slug for referencing this fixture (e.g. "starter", "empty",
6831    /// "fintech", "sales"). Pass it back as the fixture_id on create.
6832    #[prost(string, tag="1")]
6833    pub id: ::prost::alloc::string::String,
6834    /// Display name for admin UI (e.g. "Starter").
6835    #[prost(string, tag="2")]
6836    pub name: ::prost::alloc::string::String,
6837    /// Description shown alongside the fixture option in the UI.
6838    #[prost(string, tag="3")]
6839    pub description: ::prost::alloc::string::String,
6840    /// Exactly one fixture has is_default=true. Clients that show a simple
6841    /// "seed initial data" control select this fixture's id by default.
6842    #[prost(bool, tag="4")]
6843    pub is_default: bool,
6844}
6845/// Request to list all bootstrap fixtures available for seeding.
6846/// No parameters — catalog is the same for all callers.
6847#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6848pub struct ListSandboxFixturesRequest {
6849}
6850/// Response containing the bootstrap fixture catalog.
6851#[derive(Clone, PartialEq, ::prost::Message)]
6852pub struct ListSandboxFixturesResponse {
6853    /// All registered fixtures, ordered by name.
6854    #[prost(message, repeated, tag="1")]
6855    pub fixtures: ::prost::alloc::vec::Vec<SandboxFixture>,
6856}
6857/// Request to list all organizations the authenticated user belongs to.
6858/// No parameters — user identity is extracted from the JWT sub claim.
6859#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6860pub struct ListUserOrganizationsRequest {
6861}
6862/// Response containing all organizations the authenticated user belongs to.
6863#[derive(Clone, PartialEq, ::prost::Message)]
6864pub struct ListUserOrganizationsResponse {
6865    /// Organizations the user belongs to, ordered by created_at ascending.
6866    /// Excludes expired sandbox organizations.
6867    #[prost(message, repeated, tag="1")]
6868    pub organizations: ::prost::alloc::vec::Vec<Organization>,
6869}
6870/// Request to list only the sandbox organizations the authenticated user
6871/// belongs to (i.e. orgs where org_type = SANDBOX, filtered from the full
6872/// membership set). No parameters — user identity is extracted from the JWT
6873/// sub claim.
6874#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6875pub struct ListUserSandboxesRequest {
6876}
6877/// Response containing the user's sandbox organizations.
6878#[derive(Clone, PartialEq, ::prost::Message)]
6879pub struct ListUserSandboxesResponse {
6880    /// Sandbox organizations the user belongs to, ordered by expires_at
6881    /// ascending (soonest-expiring first — matches the admin UI
6882    /// /organization/sandboxes ordering). Excludes already-expired sandboxes
6883    /// (those are pending cleanup by SandboxCleanupWorkflow).
6884    #[prost(message, repeated, tag="1")]
6885    pub sandboxes: ::prost::alloc::vec::Vec<Organization>,
6886}
6887/// A single org-level data-processing toggle with consent-trace metadata.
6888/// The metadata records who flipped the toggle last and when, so the admin
6889/// consent-trace UI can show a verifiable change trail.
6890#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6891pub struct OrgPrivacyToggle {
6892    /// Whether this category of processing is enabled for the organization.
6893    #[prost(bool, tag="1")]
6894    pub enabled: bool,
6895    /// Email of the admin who last changed this toggle.
6896    /// Empty if the toggle has never been changed from its default.
6897    #[prost(string, tag="2")]
6898    pub last_changed_by_email: ::prost::alloc::string::String,
6899    /// When this toggle was last changed.
6900    /// Empty if the toggle has never been changed from its default.
6901    #[prost(message, optional, tag="3")]
6902    pub last_changed_at: ::core::option::Option<::prost_types::Timestamp>,
6903}
6904/// Org-level data-processing settings (compliance consent surface).
6905/// Each toggle gates an entire category of processing for every user in
6906/// the organization.
6907#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6908pub struct OrgPrivacySettings {
6909    /// Gates ML archetype clustering and ACK predictions.
6910    #[prost(message, optional, tag="1")]
6911    pub ai_clustering: ::core::option::Option<OrgPrivacyToggle>,
6912    /// Gates behavioral analytics (session replay, heatmaps, dwell metrics).
6913    #[prost(message, optional, tag="2")]
6914    pub behavioral_analytics: ::core::option::Option<OrgPrivacyToggle>,
6915    /// Gates third-party notification channel dispatch (email, Slack, SMS, …).
6916    #[prost(message, optional, tag="3")]
6917    pub third_party_channels: ::core::option::Option<OrgPrivacyToggle>,
6918}
6919/// Request to retrieve the org-level privacy settings.
6920/// The organization is extracted from the JWT.
6921#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6922pub struct GetOrgPrivacySettingsRequest {
6923}
6924/// Response containing the org-level privacy settings with consent-trace
6925/// metadata for each toggle.
6926#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6927pub struct GetOrgPrivacySettingsResponse {
6928    /// The organization's current privacy settings.
6929    #[prost(message, optional, tag="1")]
6930    pub settings: ::core::option::Option<OrgPrivacySettings>,
6931}
6932/// Request to update org-level privacy settings. Only the provided fields
6933/// are changed; unset fields leave the corresponding toggle unchanged.
6934#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6935pub struct UpdateOrgPrivacySettingsRequest {
6936    /// Enable or disable ML archetype clustering and ACK predictions.
6937    /// Unset leaves unchanged.
6938    #[prost(bool, optional, tag="1")]
6939    pub ai_clustering_enabled: ::core::option::Option<bool>,
6940    /// Enable or disable behavioral analytics. Unset leaves unchanged.
6941    #[prost(bool, optional, tag="2")]
6942    pub behavioral_analytics_enabled: ::core::option::Option<bool>,
6943    /// Enable or disable third-party notification channels.
6944    /// Unset leaves unchanged.
6945    #[prost(bool, optional, tag="3")]
6946    pub third_party_channels_enabled: ::core::option::Option<bool>,
6947}
6948/// Response after updating org-level privacy settings.
6949#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6950pub struct UpdateOrgPrivacySettingsResponse {
6951    /// The organization's privacy settings after the update, with refreshed
6952    /// consent-trace metadata.
6953    #[prost(message, optional, tag="1")]
6954    pub settings: ::core::option::Option<OrgPrivacySettings>,
6955}
6956// ─── Enums ───────────────────────────────────────────────────────────────────
6957
6958/// Industry vertical for an organization.
6959#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6960#[repr(i32)]
6961pub enum Industry {
6962    Unspecified = 0,
6963    Technology = 1,
6964    Finance = 2,
6965    Healthcare = 3,
6966    Education = 4,
6967    Retail = 5,
6968    Manufacturing = 6,
6969    Media = 7,
6970    Other = 8,
6971}
6972impl Industry {
6973    /// String value of the enum field names used in the ProtoBuf definition.
6974    ///
6975    /// The values are not transformed in any way and thus are considered stable
6976    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6977    pub fn as_str_name(&self) -> &'static str {
6978        match self {
6979            Self::Unspecified => "INDUSTRY_UNSPECIFIED",
6980            Self::Technology => "INDUSTRY_TECHNOLOGY",
6981            Self::Finance => "INDUSTRY_FINANCE",
6982            Self::Healthcare => "INDUSTRY_HEALTHCARE",
6983            Self::Education => "INDUSTRY_EDUCATION",
6984            Self::Retail => "INDUSTRY_RETAIL",
6985            Self::Manufacturing => "INDUSTRY_MANUFACTURING",
6986            Self::Media => "INDUSTRY_MEDIA",
6987            Self::Other => "INDUSTRY_OTHER",
6988        }
6989    }
6990    /// Creates an enum from field names used in the ProtoBuf definition.
6991    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6992        match value {
6993            "INDUSTRY_UNSPECIFIED" => Some(Self::Unspecified),
6994            "INDUSTRY_TECHNOLOGY" => Some(Self::Technology),
6995            "INDUSTRY_FINANCE" => Some(Self::Finance),
6996            "INDUSTRY_HEALTHCARE" => Some(Self::Healthcare),
6997            "INDUSTRY_EDUCATION" => Some(Self::Education),
6998            "INDUSTRY_RETAIL" => Some(Self::Retail),
6999            "INDUSTRY_MANUFACTURING" => Some(Self::Manufacturing),
7000            "INDUSTRY_MEDIA" => Some(Self::Media),
7001            "INDUSTRY_OTHER" => Some(Self::Other),
7002            _ => None,
7003        }
7004    }
7005}
7006/// Employee headcount range for an organization.
7007#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7008#[repr(i32)]
7009pub enum CompanySize {
7010    Unspecified = 0,
7011    CompanySize1200 = 1,
7012    CompanySize200500 = 2,
7013    CompanySize5001000 = 3,
7014    CompanySize10005000 = 4,
7015    CompanySize5000Plus = 5,
7016}
7017impl CompanySize {
7018    /// String value of the enum field names used in the ProtoBuf definition.
7019    ///
7020    /// The values are not transformed in any way and thus are considered stable
7021    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7022    pub fn as_str_name(&self) -> &'static str {
7023        match self {
7024            Self::Unspecified => "COMPANY_SIZE_UNSPECIFIED",
7025            Self::CompanySize1200 => "COMPANY_SIZE_1_200",
7026            Self::CompanySize200500 => "COMPANY_SIZE_200_500",
7027            Self::CompanySize5001000 => "COMPANY_SIZE_500_1000",
7028            Self::CompanySize10005000 => "COMPANY_SIZE_1000_5000",
7029            Self::CompanySize5000Plus => "COMPANY_SIZE_5000_PLUS",
7030        }
7031    }
7032    /// Creates an enum from field names used in the ProtoBuf definition.
7033    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7034        match value {
7035            "COMPANY_SIZE_UNSPECIFIED" => Some(Self::Unspecified),
7036            "COMPANY_SIZE_1_200" => Some(Self::CompanySize1200),
7037            "COMPANY_SIZE_200_500" => Some(Self::CompanySize200500),
7038            "COMPANY_SIZE_500_1000" => Some(Self::CompanySize5001000),
7039            "COMPANY_SIZE_1000_5000" => Some(Self::CompanySize10005000),
7040            "COMPANY_SIZE_5000_PLUS" => Some(Self::CompanySize5000Plus),
7041            _ => None,
7042        }
7043    }
7044}
7045/// Classification of an organization's lifecycle type.
7046#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7047#[repr(i32)]
7048pub enum OrgType {
7049    Unspecified = 0,
7050    Standard = 1,
7051    Sandbox = 2,
7052    /// Reserved for platform operations. At most one per deployment, seeded
7053    /// by migration. Cannot be created via CreateOrganization.
7054    Staff = 3,
7055}
7056impl OrgType {
7057    /// String value of the enum field names used in the ProtoBuf definition.
7058    ///
7059    /// The values are not transformed in any way and thus are considered stable
7060    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7061    pub fn as_str_name(&self) -> &'static str {
7062        match self {
7063            Self::Unspecified => "ORG_TYPE_UNSPECIFIED",
7064            Self::Standard => "ORG_TYPE_STANDARD",
7065            Self::Sandbox => "ORG_TYPE_SANDBOX",
7066            Self::Staff => "ORG_TYPE_STAFF",
7067        }
7068    }
7069    /// Creates an enum from field names used in the ProtoBuf definition.
7070    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7071        match value {
7072            "ORG_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
7073            "ORG_TYPE_STANDARD" => Some(Self::Standard),
7074            "ORG_TYPE_SANDBOX" => Some(Self::Sandbox),
7075            "ORG_TYPE_STAFF" => Some(Self::Staff),
7076            _ => None,
7077        }
7078    }
7079}
7080// ─── Messages ───────────────────────────────────────────────────────────────
7081
7082/// Per-user rendering context containing variable substitutions.
7083#[derive(Clone, PartialEq, ::prost::Message)]
7084pub struct UserRenderContext {
7085    /// ID of the user being rendered for.
7086    #[prost(string, tag="1")]
7087    pub user_id: ::prost::alloc::string::String,
7088    /// Variable name-value pairs to substitute into the template.
7089    /// Constraints: Max 100 entries. Key max length 100 characters, value max length 10000 characters.
7090    #[prost(map="string, string", tag="2")]
7091    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
7092}
7093/// Request to render a template for a batch of users.
7094#[derive(Clone, PartialEq, ::prost::Message)]
7095pub struct RenderBatchRequest {
7096    /// ID of the template to render.
7097    #[prost(string, tag="1")]
7098    pub template_id: ::prost::alloc::string::String,
7099    /// Version of the template to render.
7100    #[prost(int32, tag="2")]
7101    pub version: i32,
7102    /// Per-user rendering contexts with variable substitutions.
7103    /// Constraints: Max 10000 users per batch.
7104    #[prost(message, repeated, tag="3")]
7105    pub users: ::prost::alloc::vec::Vec<UserRenderContext>,
7106}
7107/// Streamed response for each user's rendered message.
7108/// One response is emitted per user in the batch.
7109#[derive(Clone, PartialEq, ::prost::Message)]
7110pub struct RenderBatchResponse {
7111    /// ID of the user this result is for.
7112    #[prost(string, tag="1")]
7113    pub user_id: ::prost::alloc::string::String,
7114    /// The rendered message (set on success).
7115    #[prost(message, optional, tag="2")]
7116    pub message: ::core::option::Option<Message>,
7117    /// Error message if rendering failed for this user (empty on success).
7118    #[prost(string, tag="3")]
7119    pub error: ::prost::alloc::string::String,
7120}
7121// ─── Messages ───────────────────────────────────────────────────────────────
7122
7123/// A session recording summary from the analytics provider.
7124/// Anonymous: no user identifiers are included.
7125#[derive(Clone, PartialEq, ::prost::Message)]
7126pub struct SessionRecording {
7127    /// Recording ID from the analytics provider.
7128    #[prost(string, tag="1")]
7129    pub id: ::prost::alloc::string::String,
7130    /// Timestamp when the recording started.
7131    #[prost(message, optional, tag="2")]
7132    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
7133    /// Timestamp when the recording ended.
7134    #[prost(message, optional, tag="3")]
7135    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
7136    /// Duration of the recording in seconds.
7137    #[prost(int32, tag="4")]
7138    pub duration_seconds: i32,
7139    /// Activity score (0.0–1.0).
7140    #[prost(float, tag="5")]
7141    pub activity_score: f32,
7142}
7143/// Request to list session recordings.
7144#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7145pub struct ListSessionRecordingsRequest {
7146    /// Optional: filter recordings by campaign ID (mapped to analytics property filter).
7147    /// Constraints: UUID format (36 characters).
7148    #[prost(string, tag="1")]
7149    pub campaign_id: ::prost::alloc::string::String,
7150    /// Optional: start of the time range filter (inclusive).
7151    #[prost(message, optional, tag="2")]
7152    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
7153    /// Optional: end of the time range filter (inclusive).
7154    #[prost(message, optional, tag="3")]
7155    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
7156    /// Pagination parameters.
7157    #[prost(message, optional, tag="4")]
7158    pub pagination: ::core::option::Option<Pagination>,
7159}
7160/// Response containing a page of session recordings.
7161#[derive(Clone, PartialEq, ::prost::Message)]
7162pub struct ListSessionRecordingsResponse {
7163    /// List of session recordings in this page.
7164    #[prost(message, repeated, tag="1")]
7165    pub recordings: ::prost::alloc::vec::Vec<SessionRecording>,
7166    /// Pagination metadata for fetching subsequent pages.
7167    #[prost(message, optional, tag="2")]
7168    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7169}
7170/// Request to fetch rrweb snapshot events for a recording.
7171#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7172pub struct GetSessionSnapshotsRequest {
7173    /// Recording ID from the analytics provider.
7174    /// Constraints: Max length 200 characters.
7175    #[prost(string, tag="1")]
7176    pub recording_id: ::prost::alloc::string::String,
7177}
7178/// Response containing rrweb snapshot events.
7179#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7180pub struct GetSessionSnapshotsResponse {
7181    /// JSON-encoded array of rrweb eventWithTime objects.
7182    /// Clients parse this JSON to feed into rrweb-player.
7183    #[prost(string, tag="1")]
7184    pub snapshot_data: ::prost::alloc::string::String,
7185}
7186// ─── Messages ───────────────────────────────────────────────────────────────
7187
7188/// Request to list all roles in the caller's organization.
7189#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7190pub struct ListRolesRequest {
7191}
7192/// Response containing the organization's roles.
7193#[derive(Clone, PartialEq, ::prost::Message)]
7194pub struct ListRolesResponse {
7195    /// All roles in the organization, including their permission sets.
7196    #[prost(message, repeated, tag="1")]
7197    pub roles: ::prost::alloc::vec::Vec<Role>,
7198}
7199/// Request to create a new role in the caller's organization.
7200#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7201pub struct CreateRoleRequest {
7202    /// Display name for the role (e.g. "Team Lead"). Required.
7203    /// A slug is auto-generated from the name.
7204    #[prost(string, tag="1")]
7205    pub name: ::prost::alloc::string::String,
7206    /// Initial permission set for the role.
7207    /// PERMISSION_UNSPECIFIED values are rejected.
7208    #[prost(enumeration="Permission", repeated, tag="2")]
7209    pub permissions: ::prost::alloc::vec::Vec<i32>,
7210}
7211/// Response after creating a role.
7212#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7213pub struct CreateRoleResponse {
7214    /// The newly created role with its generated slug and permission set.
7215    #[prost(message, optional, tag="1")]
7216    pub role: ::core::option::Option<Role>,
7217}
7218/// Request to update a role's name and/or permissions.
7219#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7220pub struct UpdateRoleRequest {
7221    /// ID of the role to update. Required.
7222    #[prost(string, tag="1")]
7223    pub role_id: ::prost::alloc::string::String,
7224    /// New display name. If empty, the name is not changed.
7225    #[prost(string, tag="2")]
7226    pub name: ::prost::alloc::string::String,
7227    /// New permission set (replaces existing permissions entirely).
7228    /// If empty, permissions are not changed.
7229    /// PERMISSION_UNSPECIFIED values are rejected.
7230    #[prost(enumeration="Permission", repeated, tag="3")]
7231    pub permissions: ::prost::alloc::vec::Vec<i32>,
7232}
7233/// Response after updating a role.
7234#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7235pub struct UpdateRoleResponse {
7236    /// The updated role.
7237    #[prost(message, optional, tag="1")]
7238    pub role: ::core::option::Option<Role>,
7239}
7240/// Request to delete a role.
7241#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7242pub struct DeleteRoleRequest {
7243    /// ID of the role to delete. Required.
7244    #[prost(string, tag="1")]
7245    pub role_id: ::prost::alloc::string::String,
7246}
7247/// Response after deleting a role.
7248#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7249pub struct DeleteRoleResponse {
7250}
7251// ─── Messages ───────────────────────────────────────────────────────────────
7252
7253/// Custom SAML attribute name overrides for identity providers that use
7254/// non-standard attribute names. When provided, these override the
7255/// auto-detected values from the metadata URL host.
7256#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7257pub struct SamlAttributeNames {
7258    /// SAML attribute name for the user's email address.
7259    #[prost(string, tag="1")]
7260    pub email: ::prost::alloc::string::String,
7261    /// SAML attribute name for the user's first name.
7262    #[prost(string, tag="2")]
7263    pub given_name: ::prost::alloc::string::String,
7264    /// SAML attribute name for the user's last name.
7265    #[prost(string, tag="3")]
7266    pub family_name: ::prost::alloc::string::String,
7267}
7268/// An SSO identity provider configured for an organization.
7269#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7270pub struct SsoProvider {
7271    /// Unique identifier for the provider.
7272    #[prost(string, tag="1")]
7273    pub id: ::prost::alloc::string::String,
7274    /// Email domain that triggers this SSO provider (e.g. "acme.com").
7275    /// Constraints: Max length 253 characters (RFC 1035).
7276    #[prost(string, tag="2")]
7277    pub domain: ::prost::alloc::string::String,
7278    /// Type of identity provider.
7279    #[prost(enumeration="SsoProviderType", tag="3")]
7280    pub r#type: i32,
7281    /// SAML metadata URL or OIDC discovery URL.
7282    /// Constraints: Max length 2048 characters. HTTPS required.
7283    #[prost(string, tag="4")]
7284    pub metadata_url: ::prost::alloc::string::String,
7285    /// Name of the identity provider (used for signInWithRedirect).
7286    /// Set by the API when the IdP is created.
7287    #[prost(string, tag="5")]
7288    pub idp_provider_name: ::prost::alloc::string::String,
7289    /// Timestamp when the provider was created.
7290    #[prost(message, optional, tag="6")]
7291    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7292    /// Timestamp when the provider was last updated.
7293    #[prost(message, optional, tag="7")]
7294    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
7295    /// Optional custom SAML attribute name overrides.
7296    #[prost(message, optional, tag="8")]
7297    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
7298}
7299/// Request to check if an email domain has SSO configured.
7300/// This RPC is pre-authentication — no JWT required.
7301#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7302pub struct CheckSsoByDomainRequest {
7303    /// Email address to check. The domain part is extracted.
7304    /// Constraints: Max length 254 characters (RFC 5321).
7305    #[prost(string, tag="1")]
7306    pub email: ::prost::alloc::string::String,
7307}
7308/// Response for SSO domain check.
7309#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7310pub struct CheckSsoByDomainResponse {
7311    /// Whether SSO is enabled for the email's domain.
7312    #[prost(bool, tag="1")]
7313    pub sso_enabled: bool,
7314    /// Identity provider name for signInWithRedirect.
7315    /// Empty if sso_enabled is false.
7316    #[prost(string, tag="2")]
7317    pub provider_name: ::prost::alloc::string::String,
7318}
7319/// Request to create an SSO provider for the organization.
7320#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7321pub struct CreateSsoProviderRequest {
7322    /// Email domain to associate (e.g. "acme.com").
7323    /// Constraints: Max length 253 characters (RFC 1035).
7324    #[prost(string, tag="1")]
7325    pub domain: ::prost::alloc::string::String,
7326    /// Type of identity provider.
7327    #[prost(enumeration="SsoProviderType", tag="2")]
7328    pub r#type: i32,
7329    /// SAML metadata URL or OIDC discovery URL.
7330    /// Constraints: Max length 2048 characters. HTTPS required.
7331    #[prost(string, tag="3")]
7332    pub metadata_url: ::prost::alloc::string::String,
7333    /// Optional custom SAML attribute name overrides.
7334    /// When omitted, attribute names are auto-detected from the metadata URL.
7335    #[prost(message, optional, tag="4")]
7336    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
7337}
7338/// Response after creating an SSO provider.
7339#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7340pub struct CreateSsoProviderResponse {
7341    /// The newly created SSO provider.
7342    #[prost(message, optional, tag="1")]
7343    pub provider: ::core::option::Option<SsoProvider>,
7344}
7345/// Request to get the SSO provider for the organization.
7346/// Returns the provider if one is configured, or empty if not.
7347#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7348pub struct GetSsoProviderRequest {
7349}
7350/// Response containing the organization's SSO provider.
7351#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7352pub struct GetSsoProviderResponse {
7353    /// The organization's SSO provider, or null if not configured.
7354    #[prost(message, optional, tag="1")]
7355    pub provider: ::core::option::Option<SsoProvider>,
7356}
7357/// Request to delete the organization's SSO provider.
7358#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7359pub struct DeleteSsoProviderRequest {
7360    /// ID of the provider to delete.
7361    #[prost(string, tag="1")]
7362    pub provider_id: ::prost::alloc::string::String,
7363}
7364/// Response after deleting an SSO provider.
7365#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7366pub struct DeleteSsoProviderResponse {
7367}
7368// ─── Enums ──────────────────────────────────────────────────────────────────
7369
7370/// Type of SSO identity provider.
7371#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7372#[repr(i32)]
7373pub enum SsoProviderType {
7374    /// Default value; not a valid type.
7375    Unspecified = 0,
7376    /// SAML 2.0 identity provider (e.g. Okta, Azure AD).
7377    Saml = 1,
7378    /// OpenID Connect identity provider (e.g. Google Workspace, Auth0).
7379    Oidc = 2,
7380}
7381impl SsoProviderType {
7382    /// String value of the enum field names used in the ProtoBuf definition.
7383    ///
7384    /// The values are not transformed in any way and thus are considered stable
7385    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7386    pub fn as_str_name(&self) -> &'static str {
7387        match self {
7388            Self::Unspecified => "SSO_PROVIDER_TYPE_UNSPECIFIED",
7389            Self::Saml => "SSO_PROVIDER_TYPE_SAML",
7390            Self::Oidc => "SSO_PROVIDER_TYPE_OIDC",
7391        }
7392    }
7393    /// Creates an enum from field names used in the ProtoBuf definition.
7394    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7395        match value {
7396            "SSO_PROVIDER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
7397            "SSO_PROVIDER_TYPE_SAML" => Some(Self::Saml),
7398            "SSO_PROVIDER_TYPE_OIDC" => Some(Self::Oidc),
7399            _ => None,
7400        }
7401    }
7402}
7403// ─── Messages ───────────────────────────────────────────────────────────────
7404
7405/// An organizational unit within an organization (e.g. department, division).
7406/// Teams represent the organizational structure and can serve as sender identity
7407/// in campaigns.
7408#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7409pub struct Team {
7410    /// Unique identifier for the team.
7411    #[prost(string, tag="1")]
7412    pub id: ::prost::alloc::string::String,
7413    /// Human-readable display name (unique within the organization).
7414    /// Constraints: Max length 200 characters.
7415    #[prost(string, tag="2")]
7416    pub name: ::prost::alloc::string::String,
7417    /// Optional description of the team's purpose.
7418    /// Constraints: Max length 1000 characters.
7419    #[prost(string, tag="3")]
7420    pub description: ::prost::alloc::string::String,
7421    /// Number of users currently in the team.
7422    #[prost(int32, tag="4")]
7423    pub member_count: i32,
7424    /// Timestamp when the team was created.
7425    #[prost(message, optional, tag="5")]
7426    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7427    /// Timestamp when the team was last updated.
7428    #[prost(message, optional, tag="6")]
7429    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
7430    /// Whether this is the organization's default team (cannot be deleted or renamed).
7431    #[prost(bool, tag="7")]
7432    pub is_default: bool,
7433    /// ID of the user who created this team. Empty for system-seeded defaults.
7434    #[prost(string, tag="8")]
7435    pub created_by: ::prost::alloc::string::String,
7436}
7437/// Request to create a new team.
7438#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7439pub struct CreateTeamRequest {
7440    /// Display name for the team. Required.
7441    /// Constraints: Max length 200 characters.
7442    #[prost(string, tag="1")]
7443    pub name: ::prost::alloc::string::String,
7444    /// Optional description.
7445    /// Constraints: Max length 1000 characters.
7446    #[prost(string, tag="2")]
7447    pub description: ::prost::alloc::string::String,
7448}
7449/// Response after creating a team.
7450#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7451pub struct CreateTeamResponse {
7452    /// The newly created team.
7453    #[prost(message, optional, tag="1")]
7454    pub team: ::core::option::Option<Team>,
7455}
7456/// Request to retrieve a team by ID.
7457#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7458pub struct GetTeamRequest {
7459    /// ID of the team to retrieve. Required.
7460    #[prost(string, tag="1")]
7461    pub team_id: ::prost::alloc::string::String,
7462}
7463/// Response containing the requested team.
7464#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7465pub struct GetTeamResponse {
7466    /// The requested team.
7467    #[prost(message, optional, tag="1")]
7468    pub team: ::core::option::Option<Team>,
7469}
7470/// Request to list teams in the organization with pagination.
7471#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7472pub struct ListTeamsRequest {
7473    /// Pagination parameters.
7474    #[prost(message, optional, tag="1")]
7475    pub pagination: ::core::option::Option<Pagination>,
7476}
7477/// Response containing a page of teams.
7478#[derive(Clone, PartialEq, ::prost::Message)]
7479pub struct ListTeamsResponse {
7480    /// Teams in this page.
7481    #[prost(message, repeated, tag="1")]
7482    pub teams: ::prost::alloc::vec::Vec<Team>,
7483    /// Pagination metadata for fetching subsequent pages.
7484    #[prost(message, optional, tag="2")]
7485    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7486}
7487/// Request to update a team's name and/or description.
7488#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7489pub struct UpdateTeamRequest {
7490    /// ID of the team to update. Required.
7491    #[prost(string, tag="1")]
7492    pub team_id: ::prost::alloc::string::String,
7493    /// New display name. If empty, the name is not changed.
7494    /// Default teams cannot be renamed.
7495    /// Constraints: Max length 200 characters.
7496    #[prost(string, tag="2")]
7497    pub name: ::prost::alloc::string::String,
7498    /// New description. If empty, the description is not changed.
7499    /// Constraints: Max length 1000 characters.
7500    #[prost(string, tag="3")]
7501    pub description: ::prost::alloc::string::String,
7502}
7503/// Response after updating a team.
7504#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7505pub struct UpdateTeamResponse {
7506    /// The updated team.
7507    #[prost(message, optional, tag="1")]
7508    pub team: ::core::option::Option<Team>,
7509}
7510/// Request to delete a team.
7511#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7512pub struct DeleteTeamRequest {
7513    /// ID of the team to delete. Required.
7514    /// Default teams cannot be deleted.
7515    #[prost(string, tag="1")]
7516    pub team_id: ::prost::alloc::string::String,
7517}
7518/// Response after deleting a team.
7519#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7520pub struct DeleteTeamResponse {
7521}
7522/// Request to add users to a team.
7523#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7524pub struct AddTeamMembersRequest {
7525    /// ID of the team to add members to. Required.
7526    #[prost(string, tag="1")]
7527    pub team_id: ::prost::alloc::string::String,
7528    /// IDs of users to add. Must belong to the same organization.
7529    /// Adding an existing member is a no-op (idempotent).
7530    /// Constraints: Max 100 user IDs per request.
7531    #[prost(string, repeated, tag="2")]
7532    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
7533}
7534/// Response after adding team members.
7535#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7536pub struct AddTeamMembersResponse {
7537    /// The team with updated member_count.
7538    #[prost(message, optional, tag="1")]
7539    pub team: ::core::option::Option<Team>,
7540}
7541/// Request to remove users from a team.
7542#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7543pub struct RemoveTeamMembersRequest {
7544    /// ID of the team to remove members from. Required.
7545    #[prost(string, tag="1")]
7546    pub team_id: ::prost::alloc::string::String,
7547    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
7548    /// Constraints: Max 100 user IDs per request.
7549    #[prost(string, repeated, tag="2")]
7550    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
7551}
7552/// Response after removing team members.
7553#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7554pub struct RemoveTeamMembersResponse {
7555    /// The team with updated member_count.
7556    #[prost(message, optional, tag="1")]
7557    pub team: ::core::option::Option<Team>,
7558}
7559/// Request to list members of a team with pagination.
7560#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7561pub struct ListTeamMembersRequest {
7562    /// ID of the team whose members to list. Required.
7563    #[prost(string, tag="1")]
7564    pub team_id: ::prost::alloc::string::String,
7565    /// Pagination parameters.
7566    #[prost(message, optional, tag="2")]
7567    pub pagination: ::core::option::Option<Pagination>,
7568}
7569/// Response containing a page of team members.
7570#[derive(Clone, PartialEq, ::prost::Message)]
7571pub struct ListTeamMembersResponse {
7572    /// Users in this page.
7573    #[prost(message, repeated, tag="1")]
7574    pub users: ::prost::alloc::vec::Vec<User>,
7575    /// Pagination metadata for fetching subsequent pages.
7576    #[prost(message, optional, tag="2")]
7577    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7578}
7579// ─── Messages ───────────────────────────────────────────────────────────────
7580
7581/// A variable placeholder within a template that gets substituted during rendering.
7582#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7583pub struct TemplateVariable {
7584    /// Variable name used in the template body (e.g. "employee_name").
7585    /// Constraints: Max length 100 characters.
7586    #[prost(string, tag="1")]
7587    pub name: ::prost::alloc::string::String,
7588    /// Human-readable description of what this variable represents.
7589    /// Constraints: Max length 500 characters.
7590    #[prost(string, tag="2")]
7591    pub description: ::prost::alloc::string::String,
7592    /// Whether this variable must be provided during rendering.
7593    #[prost(bool, tag="3")]
7594    pub required: bool,
7595    /// Where this variable's value comes from (profile attribute or campaign config).
7596    #[prost(enumeration="TemplateVariableSource", tag="4")]
7597    pub source: i32,
7598    /// Fallback value used when the source does not provide a value.
7599    /// Constraints: Max length 1000 characters.
7600    #[prost(string, tag="5")]
7601    pub default_value: ::prost::alloc::string::String,
7602    /// When true, this variable's rendered value is masked in session replay
7603    /// and heatmap screenshots. Org admin controls per variable.
7604    #[prost(bool, tag="6")]
7605    pub pii: bool,
7606}
7607/// A versioned message template with variable placeholders.
7608/// Templates are append-only — updates create new versions.
7609#[derive(Clone, PartialEq, ::prost::Message)]
7610pub struct Template {
7611    /// Unique identifier for the template.
7612    #[prost(string, tag="1")]
7613    pub id: ::prost::alloc::string::String,
7614    /// Human-readable template name (admin-facing label).
7615    /// Constraints: Max length 200 characters.
7616    #[prost(string, tag="2")]
7617    pub name: ::prost::alloc::string::String,
7618    /// Template body with {{variable}} placeholders for substitution.
7619    /// Constraints: Max length 50000 characters.
7620    #[prost(string, tag="3")]
7621    pub body: ::prost::alloc::string::String,
7622    /// Variables that can be substituted into the template body.
7623    #[prost(message, repeated, tag="4")]
7624    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
7625    /// Version number (auto-incremented on each update).
7626    #[prost(int32, tag="5")]
7627    pub version: i32,
7628    /// Timestamp when this version was created.
7629    #[prost(message, optional, tag="6")]
7630    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7631    /// Timestamp of the most recent update (same as created_at for the latest version).
7632    #[prost(message, optional, tag="7")]
7633    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
7634    /// User-facing title shown as the message subject to recipients.
7635    /// Serves as the default title; campaigns can override it.
7636    /// Constraints: Max length 200 characters.
7637    #[prost(string, tag="8")]
7638    pub title: ::prost::alloc::string::String,
7639    /// Content format of this template (markdown, rich, HTML).
7640    /// UNSPECIFIED is treated as MARKDOWN for backward compatibility.
7641    #[prost(enumeration="TemplateType", tag="9")]
7642    pub r#type: i32,
7643    /// Language of the template body content (e.g., "en", "es", "ja").
7644    /// Defaults to the org's default_locale, falling back to "en".
7645    /// Translations are created as locale variants of this source.
7646    #[prost(string, tag="10")]
7647    pub source_locale: ::prost::alloc::string::String,
7648}
7649/// A locale-specific translation of a template's title and body.
7650/// Translations are created per template version and go through a review workflow.
7651#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7652pub struct TemplateTranslation {
7653    /// Unique identifier for this translation.
7654    #[prost(string, tag="1")]
7655    pub id: ::prost::alloc::string::String,
7656    /// ID of the source template.
7657    #[prost(string, tag="2")]
7658    pub template_id: ::prost::alloc::string::String,
7659    /// Version of the source template this translation is for.
7660    #[prost(int32, tag="3")]
7661    pub version: i32,
7662    /// Target locale (e.g., "es", "pt-BR", "zh", "ja").
7663    #[prost(string, tag="4")]
7664    pub locale: ::prost::alloc::string::String,
7665    /// Translated title.
7666    /// Constraints: Max length 200 characters.
7667    #[prost(string, tag="5")]
7668    pub title: ::prost::alloc::string::String,
7669    /// Translated body content with {{variable}} placeholders preserved.
7670    /// Constraints: Max length 50000 characters.
7671    #[prost(string, tag="6")]
7672    pub body: ::prost::alloc::string::String,
7673    /// Current review status.
7674    #[prost(enumeration="TranslationStatus", tag="7")]
7675    pub status: i32,
7676    /// Who created this translation ("ai:bedrock", "ai:deepl", or user UUID).
7677    #[prost(string, tag="8")]
7678    pub translated_by: ::prost::alloc::string::String,
7679    /// User who approved the translation. Empty until approved.
7680    #[prost(string, tag="9")]
7681    pub reviewed_by: ::prost::alloc::string::String,
7682    /// When the translation was approved.
7683    #[prost(message, optional, tag="10")]
7684    pub reviewed_at: ::core::option::Option<::prost_types::Timestamp>,
7685    /// When the translation was created.
7686    #[prost(message, optional, tag="11")]
7687    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7688}
7689/// Request to create a new template.
7690#[derive(Clone, PartialEq, ::prost::Message)]
7691pub struct CreateTemplateRequest {
7692    /// Human-readable template name (admin-facing label).
7693    /// Constraints: Max length 200 characters.
7694    #[prost(string, tag="1")]
7695    pub name: ::prost::alloc::string::String,
7696    /// Template body with {{variable}} placeholders.
7697    /// Constraints: Max length 50000 characters.
7698    #[prost(string, tag="2")]
7699    pub body: ::prost::alloc::string::String,
7700    /// Variables available for substitution in the body.
7701    #[prost(message, repeated, tag="3")]
7702    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
7703    /// User-facing title shown as the message subject to recipients.
7704    /// Constraints: Max length 200 characters.
7705    #[prost(string, tag="4")]
7706    pub title: ::prost::alloc::string::String,
7707    /// Content format of the template. Defaults to MARKDOWN if unspecified.
7708    #[prost(enumeration="TemplateType", tag="5")]
7709    pub r#type: i32,
7710    /// Language of the template body content. Defaults to org's default_locale.
7711    /// Valid values: en, es, pt-BR, zh, ja.
7712    #[prost(string, tag="6")]
7713    pub source_locale: ::prost::alloc::string::String,
7714}
7715/// Response after creating a template.
7716#[derive(Clone, PartialEq, ::prost::Message)]
7717pub struct CreateTemplateResponse {
7718    /// The newly created template (version 1).
7719    #[prost(message, optional, tag="1")]
7720    pub template: ::core::option::Option<Template>,
7721}
7722/// Request to update a template, creating a new version.
7723#[derive(Clone, PartialEq, ::prost::Message)]
7724pub struct UpdateTemplateRequest {
7725    /// ID of the template to update.
7726    #[prost(string, tag="1")]
7727    pub template_id: ::prost::alloc::string::String,
7728    /// New template body with {{variable}} placeholders.
7729    /// Constraints: Max length 50000 characters.
7730    #[prost(string, tag="2")]
7731    pub body: ::prost::alloc::string::String,
7732    /// Updated variables for substitution.
7733    #[prost(message, repeated, tag="3")]
7734    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
7735}
7736/// Response after updating a template.
7737#[derive(Clone, PartialEq, ::prost::Message)]
7738pub struct UpdateTemplateResponse {
7739    /// The updated template with incremented version number.
7740    #[prost(message, optional, tag="1")]
7741    pub template: ::core::option::Option<Template>,
7742}
7743/// Request to retrieve a specific template version.
7744#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7745pub struct GetTemplateRequest {
7746    /// ID of the template to retrieve.
7747    #[prost(string, tag="1")]
7748    pub template_id: ::prost::alloc::string::String,
7749    /// Version to retrieve. 0 returns the latest version.
7750    #[prost(int32, tag="2")]
7751    pub version: i32,
7752}
7753/// Response containing the requested template.
7754#[derive(Clone, PartialEq, ::prost::Message)]
7755pub struct GetTemplateResponse {
7756    /// The requested template.
7757    #[prost(message, optional, tag="1")]
7758    pub template: ::core::option::Option<Template>,
7759}
7760/// Request to list templates with pagination.
7761#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7762pub struct ListTemplatesRequest {
7763    /// Pagination parameters.
7764    #[prost(message, optional, tag="1")]
7765    pub pagination: ::core::option::Option<Pagination>,
7766    /// Filter by template type. UNSPECIFIED returns all templates.
7767    #[prost(enumeration="TemplateType", tag="2")]
7768    pub r#type: i32,
7769}
7770/// Response containing a page of templates.
7771#[derive(Clone, PartialEq, ::prost::Message)]
7772pub struct ListTemplatesResponse {
7773    /// List of templates in this page (latest version of each).
7774    #[prost(message, repeated, tag="1")]
7775    pub templates: ::prost::alloc::vec::Vec<Template>,
7776    /// Pagination metadata for fetching subsequent pages.
7777    #[prost(message, optional, tag="2")]
7778    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7779}
7780/// Request to create a translation for a template.
7781#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7782pub struct CreateTemplateTranslationRequest {
7783    /// ID of the template to translate.
7784    #[prost(string, tag="1")]
7785    pub template_id: ::prost::alloc::string::String,
7786    /// Version of the template to translate.
7787    #[prost(int32, tag="2")]
7788    pub version: i32,
7789    /// Target locale.
7790    #[prost(string, tag="3")]
7791    pub locale: ::prost::alloc::string::String,
7792    /// Translated title.
7793    #[prost(string, tag="4")]
7794    pub title: ::prost::alloc::string::String,
7795    /// Translated body content.
7796    #[prost(string, tag="5")]
7797    pub body: ::prost::alloc::string::String,
7798    /// Who created this translation ("ai:bedrock" or user UUID).
7799    #[prost(string, tag="6")]
7800    pub translated_by: ::prost::alloc::string::String,
7801    /// Initial status (typically DRAFT or AI_TRANSLATED).
7802    #[prost(enumeration="TranslationStatus", tag="7")]
7803    pub status: i32,
7804}
7805/// Response after creating a template translation.
7806#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7807pub struct CreateTemplateTranslationResponse {
7808    /// The created translation.
7809    #[prost(message, optional, tag="1")]
7810    pub translation: ::core::option::Option<TemplateTranslation>,
7811}
7812/// Request to update an existing template translation.
7813#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7814pub struct UpdateTemplateTranslationRequest {
7815    /// ID of the translation to update.
7816    #[prost(string, tag="1")]
7817    pub translation_id: ::prost::alloc::string::String,
7818    /// Updated title. Empty leaves unchanged.
7819    #[prost(string, tag="2")]
7820    pub title: ::prost::alloc::string::String,
7821    /// Updated body. Empty leaves unchanged.
7822    #[prost(string, tag="3")]
7823    pub body: ::prost::alloc::string::String,
7824    /// Updated status.
7825    #[prost(enumeration="TranslationStatus", tag="4")]
7826    pub status: i32,
7827}
7828/// Response after updating a template translation.
7829#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7830pub struct UpdateTemplateTranslationResponse {
7831    /// The updated translation.
7832    #[prost(message, optional, tag="1")]
7833    pub translation: ::core::option::Option<TemplateTranslation>,
7834}
7835/// Request to list translations for a template version.
7836#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7837pub struct ListTemplateTranslationsRequest {
7838    /// ID of the template.
7839    #[prost(string, tag="1")]
7840    pub template_id: ::prost::alloc::string::String,
7841    /// Version of the template. 0 returns translations for the latest version.
7842    #[prost(int32, tag="2")]
7843    pub version: i32,
7844}
7845/// Response containing all translations for a template version.
7846#[derive(Clone, PartialEq, ::prost::Message)]
7847pub struct ListTemplateTranslationsResponse {
7848    /// Translations for the requested template version.
7849    #[prost(message, repeated, tag="1")]
7850    pub translations: ::prost::alloc::vec::Vec<TemplateTranslation>,
7851}
7852/// Request to approve a template translation.
7853#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7854pub struct ApproveTemplateTranslationRequest {
7855    /// ID of the translation to approve.
7856    #[prost(string, tag="1")]
7857    pub translation_id: ::prost::alloc::string::String,
7858}
7859/// Response after approving a template translation.
7860#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7861pub struct ApproveTemplateTranslationResponse {
7862    /// The approved translation (status: APPROVED, reviewed_by and reviewed_at set).
7863    #[prost(message, optional, tag="1")]
7864    pub translation: ::core::option::Option<TemplateTranslation>,
7865}
7866// ─── Enums ──────────────────────────────────────────────────────────────────
7867
7868/// Content format of a template, determining which editor and renderer to use.
7869#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7870#[repr(i32)]
7871pub enum TemplateType {
7872    /// Default value; treated as MARKDOWN for backward compatibility.
7873    Unspecified = 0,
7874    /// Markdown with {{variable}} placeholders.
7875    Markdown = 1,
7876    /// Rich text format (reserved for future use).
7877    Rich = 2,
7878    /// Raw HTML format (reserved for future use).
7879    Html = 3,
7880}
7881impl TemplateType {
7882    /// String value of the enum field names used in the ProtoBuf definition.
7883    ///
7884    /// The values are not transformed in any way and thus are considered stable
7885    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7886    pub fn as_str_name(&self) -> &'static str {
7887        match self {
7888            Self::Unspecified => "TEMPLATE_TYPE_UNSPECIFIED",
7889            Self::Markdown => "TEMPLATE_TYPE_MARKDOWN",
7890            Self::Rich => "TEMPLATE_TYPE_RICH",
7891            Self::Html => "TEMPLATE_TYPE_HTML",
7892        }
7893    }
7894    /// Creates an enum from field names used in the ProtoBuf definition.
7895    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7896        match value {
7897            "TEMPLATE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
7898            "TEMPLATE_TYPE_MARKDOWN" => Some(Self::Markdown),
7899            "TEMPLATE_TYPE_RICH" => Some(Self::Rich),
7900            "TEMPLATE_TYPE_HTML" => Some(Self::Html),
7901            _ => None,
7902        }
7903    }
7904}
7905/// Source from which a template variable's value is resolved at render time.
7906#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7907#[repr(i32)]
7908pub enum TemplateVariableSource {
7909    /// Default value; treated as CUSTOM for backward compatibility.
7910    Unspecified = 0,
7911    /// Auto-resolved from the target user's profile attributes.
7912    Profile = 1,
7913    /// Provided manually in the campaign or workflow step configuration.
7914    Custom = 2,
7915}
7916impl TemplateVariableSource {
7917    /// String value of the enum field names used in the ProtoBuf definition.
7918    ///
7919    /// The values are not transformed in any way and thus are considered stable
7920    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7921    pub fn as_str_name(&self) -> &'static str {
7922        match self {
7923            Self::Unspecified => "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED",
7924            Self::Profile => "TEMPLATE_VARIABLE_SOURCE_PROFILE",
7925            Self::Custom => "TEMPLATE_VARIABLE_SOURCE_CUSTOM",
7926        }
7927    }
7928    /// Creates an enum from field names used in the ProtoBuf definition.
7929    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7930        match value {
7931            "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
7932            "TEMPLATE_VARIABLE_SOURCE_PROFILE" => Some(Self::Profile),
7933            "TEMPLATE_VARIABLE_SOURCE_CUSTOM" => Some(Self::Custom),
7934            _ => None,
7935        }
7936    }
7937}
7938/// Review status of a template translation.
7939#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7940#[repr(i32)]
7941pub enum TranslationStatus {
7942    Unspecified = 0,
7943    /// Translation draft, not yet reviewed.
7944    Draft = 1,
7945    /// Translation generated by AI, pending human review.
7946    AiTranslated = 2,
7947    /// Translation is being reviewed by a human.
7948    InReview = 3,
7949    /// Translation has been approved for use.
7950    Approved = 4,
7951}
7952impl TranslationStatus {
7953    /// String value of the enum field names used in the ProtoBuf definition.
7954    ///
7955    /// The values are not transformed in any way and thus are considered stable
7956    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7957    pub fn as_str_name(&self) -> &'static str {
7958        match self {
7959            Self::Unspecified => "TRANSLATION_STATUS_UNSPECIFIED",
7960            Self::Draft => "TRANSLATION_STATUS_DRAFT",
7961            Self::AiTranslated => "TRANSLATION_STATUS_AI_TRANSLATED",
7962            Self::InReview => "TRANSLATION_STATUS_IN_REVIEW",
7963            Self::Approved => "TRANSLATION_STATUS_APPROVED",
7964        }
7965    }
7966    /// Creates an enum from field names used in the ProtoBuf definition.
7967    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7968        match value {
7969            "TRANSLATION_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
7970            "TRANSLATION_STATUS_DRAFT" => Some(Self::Draft),
7971            "TRANSLATION_STATUS_AI_TRANSLATED" => Some(Self::AiTranslated),
7972            "TRANSLATION_STATUS_IN_REVIEW" => Some(Self::InReview),
7973            "TRANSLATION_STATUS_APPROVED" => Some(Self::Approved),
7974            _ => None,
7975        }
7976    }
7977}
7978// ─── Messages ───────────────────────────────────────────────────────────────
7979
7980/// Decoded deeplink-token payload. Populated by ValidateDeeplinkToken
7981/// only when validation succeeds.
7982#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7983pub struct DeeplinkTokenPayload {
7984    /// Campaign UUID the deeplink targets. The native app uses this for the
7985    /// authenticated GetCampaign follow-up post-recipient-auth.
7986    #[prost(string, tag="1")]
7987    pub campaign_id: ::prost::alloc::string::String,
7988    /// Recipient UUID the token authorizes. The token does not authenticate
7989    /// the recipient (that's the auth flow's job); it authorizes "this
7990    /// deeplink path is for this recipient" so the native app can refuse
7991    /// to render a token whose embedded recipient mismatches the signed-in
7992    /// user.
7993    #[prost(string, tag="2")]
7994    pub recipient_user_id: ::prost::alloc::string::String,
7995    /// Step kind the deeplink targets — REMINDER vs ESCALATION. Lets the
7996    /// native app pick the right campaign-card variant before the auth
7997    /// gate.
7998    #[prost(enumeration="ChannelStepKind", tag="3")]
7999    pub step_kind: i32,
8000    /// Expiry the token carries. Validation rejects tokens past this time
8001    /// even if the signature checks out.
8002    #[prost(message, optional, tag="4")]
8003    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
8004}
8005#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8006pub struct SignDeeplinkTokenRequest {
8007    /// Campaign whose deeplink this token authorizes. Constraints: required,
8008    /// must be a UUID and exist within the caller's organization.
8009    #[prost(string, tag="1")]
8010    pub campaign_id: ::prost::alloc::string::String,
8011    /// Recipient the token authorizes. Constraints: required, must be a UUID
8012    /// and a member of the campaign's audience.
8013    #[prost(string, tag="2")]
8014    pub recipient_user_id: ::prost::alloc::string::String,
8015    /// Step kind the deeplink targets. Required.
8016    #[prost(enumeration="ChannelStepKind", tag="3")]
8017    pub step_kind: i32,
8018    /// Token lifetime in seconds from now. Constraints: required, must be
8019    /// in (0, 30 * 24 * 3600] (1 second to 30 days). 30 days matches the
8020    /// platform's outer bound on actionable campaign lifetimes; longer
8021    /// tokens are not signed.
8022    #[prost(int64, tag="4")]
8023    pub ttl_seconds: i64,
8024}
8025#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8026pub struct SignDeeplinkTokenResponse {
8027    /// The signed token, ready to URL-embed in
8028    /// links.pidgr.com/c/{short_code}?t={token}. Format: base64url-encoded
8029    /// payload (JSON) + base64url-encoded HMAC-SHA256 trailer, joined by
8030    /// a single dot. Implementation detail — clients SHOULD NOT parse or
8031    /// mutate the token; they pass it back to ValidateDeeplinkToken.
8032    #[prost(string, tag="1")]
8033    pub token: ::prost::alloc::string::String,
8034    /// The expiry the token carries. Echoed back so clients don't need to
8035    /// redo the time-math the caller passed in via ttl_seconds.
8036    #[prost(message, optional, tag="2")]
8037    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
8038    /// The platform key version used to sign. Clients MAY record for
8039    /// telemetry but SHOULD NOT branch logic on it — the platform manages
8040    /// overlap windows during rotation transparently.
8041    #[prost(int32, tag="3")]
8042    pub key_version: i32,
8043}
8044#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8045pub struct ValidateDeeplinkTokenRequest {
8046    /// The token bytes from the deeplink URL's `t` query parameter.
8047    /// Constraints: required, non-empty.
8048    #[prost(string, tag="1")]
8049    pub token: ::prost::alloc::string::String,
8050    /// Campaign UUID embedded in the URL path (translated from the
8051    /// short-code by the native app via CampaignService.GetCampaignByShortCode).
8052    /// Validation rejects when the token's embedded campaign_id does not
8053    /// match — defense against replay attacks that swap the short-code
8054    /// path component while reusing a signed token from a different
8055    /// campaign.
8056    #[prost(string, tag="2")]
8057    pub campaign_id: ::prost::alloc::string::String,
8058}
8059#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8060pub struct ValidateDeeplinkTokenResponse {
8061    /// True when signature + expiry both check out under any active or
8062    /// overlap-window key version.
8063    #[prost(bool, tag="1")]
8064    pub valid: bool,
8065    /// Reason validation failed. Set only when valid=false; UNSPECIFIED
8066    /// when valid=true. The native app uses this to drive UX (silent retry
8067    /// vs. "this link expired" message vs. "this link looks tampered").
8068    #[prost(enumeration="ValidationFailureReason", tag="2")]
8069    pub failure_reason: i32,
8070    /// Decoded payload. Populated only when valid=true. The native app
8071    /// SHOULD compare payload.recipient_user_id against the signed-in user
8072    /// and refuse to render the campaign card on mismatch.
8073    #[prost(message, optional, tag="3")]
8074    pub payload: ::core::option::Option<DeeplinkTokenPayload>,
8075}
8076// ─── Enums ──────────────────────────────────────────────────────────────────
8077
8078/// Reason a deeplink-token validation failed. Empty when valid=true.
8079#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8080#[repr(i32)]
8081pub enum ValidationFailureReason {
8082    Unspecified = 0,
8083    /// Token bytes parsed but the HMAC signature did not verify under any
8084    /// active or overlap-window key version.
8085    InvalidSignature = 1,
8086    /// Token signature verified but its embedded expiry has passed.
8087    Expired = 2,
8088    /// Signature would have verified, but the key version that signed the
8089    /// token is past the rotation overlap window and has been hard-deleted.
8090    /// This means the token is older than the platform's retention bound
8091    /// (rotation cadence + overlap window) — operationally equivalent to
8092    /// EXPIRED but distinguishable for telemetry.
8093    KeyRetired = 3,
8094    /// Token bytes could not be parsed at all (not base64url, wrong length,
8095    /// missing payload separator, etc.). Indicates a tampered or
8096    /// truncated URL.
8097    Malformed = 4,
8098}
8099impl ValidationFailureReason {
8100    /// String value of the enum field names used in the ProtoBuf definition.
8101    ///
8102    /// The values are not transformed in any way and thus are considered stable
8103    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8104    pub fn as_str_name(&self) -> &'static str {
8105        match self {
8106            Self::Unspecified => "VALIDATION_FAILURE_REASON_UNSPECIFIED",
8107            Self::InvalidSignature => "VALIDATION_FAILURE_REASON_INVALID_SIGNATURE",
8108            Self::Expired => "VALIDATION_FAILURE_REASON_EXPIRED",
8109            Self::KeyRetired => "VALIDATION_FAILURE_REASON_KEY_RETIRED",
8110            Self::Malformed => "VALIDATION_FAILURE_REASON_MALFORMED",
8111        }
8112    }
8113    /// Creates an enum from field names used in the ProtoBuf definition.
8114    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8115        match value {
8116            "VALIDATION_FAILURE_REASON_UNSPECIFIED" => Some(Self::Unspecified),
8117            "VALIDATION_FAILURE_REASON_INVALID_SIGNATURE" => Some(Self::InvalidSignature),
8118            "VALIDATION_FAILURE_REASON_EXPIRED" => Some(Self::Expired),
8119            "VALIDATION_FAILURE_REASON_KEY_RETIRED" => Some(Self::KeyRetired),
8120            "VALIDATION_FAILURE_REASON_MALFORMED" => Some(Self::Malformed),
8121            _ => None,
8122        }
8123    }
8124}
8125// ─── Messages ───────────────────────────────────────────────────────────────
8126
8127/// One recorded observation of an indicator over a period.
8128///
8129/// A reading records what was reported and nothing else. Reading it
8130/// together with the response rate of the campaign it followed produces
8131/// an interpretation — for instance that a well-acknowledged message
8132/// nonetheless changed nothing, which says the gap was never one of
8133/// direction. That crossing is analysis and belongs to the diagnosis
8134/// layer; storing it here would make the record and its interpretation
8135/// impossible to tell apart, and would freeze one interpretation into
8136/// data that later analysis cannot revisit.
8137#[derive(Clone, PartialEq, ::prost::Message)]
8138pub struct IndicatorReading {
8139    /// Unique identifier for the reading.
8140    #[prost(string, tag="1")]
8141    pub id: ::prost::alloc::string::String,
8142    /// Indicator this reading was recorded against.
8143    #[prost(string, tag="2")]
8144    pub indicator_id: ::prost::alloc::string::String,
8145    /// Kind of source that produced it.
8146    #[prost(enumeration="ReadingSource", tag="3")]
8147    pub source: i32,
8148    /// What the reading says.
8149    #[prost(enumeration="ReadingOutcome", tag="4")]
8150    pub outcome: i32,
8151    /// Start of the period the reading covers.
8152    #[prost(message, optional, tag="5")]
8153    pub period_start: ::core::option::Option<::prost_types::Timestamp>,
8154    /// End of the period the reading covers.
8155    #[prost(message, optional, tag="6")]
8156    pub period_end: ::core::option::Option<::prost_types::Timestamp>,
8157    /// Verification run that produced it. Set only when `source` is
8158    /// READING_SOURCE_VERIFICATION_CAMPAIGN, and the way to check the
8159    /// reading: the run carries how many verifiers were asked and over
8160    /// what window, never who they were. The identities are deliberately
8161    /// not recorded, because the reading is about a unit and not about its
8162    /// members, and keeping the two apart is what stops a stored answer
8163    /// from becoming one person's judgement of another.
8164    #[prost(string, tag="7")]
8165    pub verification_run_id: ::prost::alloc::string::String,
8166    /// Campaign whose responses produced it. For an in-app reading this is
8167    /// the campaign the audience answered; for a verification reading it
8168    /// is the follow-up that was sent to the verifiers.
8169    #[prost(string, tag="8")]
8170    pub campaign_id: ::prost::alloc::string::String,
8171    /// How many responses fed this reading. For a verification reading the
8172    /// unit of count is the organizational unit that answered, not the
8173    /// person: the question is asked once per unit.
8174    ///
8175    /// Absent for a source that does not count responses at all, such as a
8176    /// figure pushed from another system. Absence and a count of none are
8177    /// different facts and the field carries presence so they stay
8178    /// different.
8179    #[prost(int32, optional, tag="9")]
8180    pub response_count: ::core::option::Option<i32>,
8181    /// How many responses were expected over the same period. Travels with
8182    /// `response_count` so that the reading carries its own denominator
8183    /// and can be judged without a second lookup, and carries presence for
8184    /// the same reason.
8185    #[prost(int32, optional, tag="10")]
8186    pub expected_response_count: ::core::option::Option<i32>,
8187    /// Timestamp when the reading was stored.
8188    #[prost(message, optional, tag="11")]
8189    pub recorded_at: ::core::option::Option<::prost_types::Timestamp>,
8190    /// The measured figure, expressed in the indicator's unit and read
8191    /// together with its direction and target.
8192    ///
8193    /// Present only for a source that produces a number: a figure pushed
8194    /// from one of the organization's own systems, or one entered by hand.
8195    /// A verification-campaign reading never carries one, because the
8196    /// question put to a verifier is whether the behaviour changed and an
8197    /// answer to that has no magnitude — deriving a figure from it would
8198    /// manufacture precision the answer does not contain. Absent for every
8199    /// source that has no number to report, which is not the same as a
8200    /// measurement of zero.
8201    #[prost(double, optional, tag="12")]
8202    pub value: ::core::option::Option<f64>,
8203}
8204/// A scheduled follow-up that asks whether the behaviour a campaign was
8205/// trying to change actually changed, and lands the answer on an
8206/// indicator.
8207///
8208/// The question is asked about an organizational unit, never about a
8209/// named person. A run therefore never produces a third party's judgement
8210/// of an individual, which is a category of data this contract does not
8211/// carry.
8212#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8213pub struct VerificationRun {
8214    /// Unique identifier for the run.
8215    #[prost(string, tag="1")]
8216    pub id: ::prost::alloc::string::String,
8217    /// Campaign whose effect is being verified.
8218    #[prost(string, tag="2")]
8219    pub campaign_id: ::prost::alloc::string::String,
8220    /// Indicator the answers are recorded against.
8221    #[prost(string, tag="3")]
8222    pub indicator_id: ::prost::alloc::string::String,
8223    /// Objective the indicator hangs from, carried here so a run can be
8224    /// listed and read at the objective level without resolving the
8225    /// indicator first.
8226    #[prost(string, tag="4")]
8227    pub objective_id: ::prost::alloc::string::String,
8228    /// Lifecycle state.
8229    #[prost(enumeration="VerificationRunState", tag="5")]
8230    pub state: i32,
8231    /// The follow-up campaign sent to the verifiers. Empty while the run
8232    /// is VERIFICATION_RUN_STATE_PENDING, because it does not exist yet.
8233    #[prost(string, tag="6")]
8234    pub verification_campaign_id: ::prost::alloc::string::String,
8235    /// When the follow-up is due, derived from the wait declared on the
8236    /// indicator's evidence source. Known from the moment the run is
8237    /// created.
8238    #[prost(message, optional, tag="7")]
8239    pub scheduled_for: ::core::option::Option<::prost_types::Timestamp>,
8240    /// When the follow-up actually went out and collection opened. Unset
8241    /// while the run is pending.
8242    #[prost(message, optional, tag="8")]
8243    pub window_start: ::core::option::Option<::prost_types::Timestamp>,
8244    /// When collection closed. Unset until the run is complete.
8245    #[prost(message, optional, tag="9")]
8246    pub window_end: ::core::option::Option<::prost_types::Timestamp>,
8247    /// How many verifiers the derivation resolved to, after dropping
8248    /// anyone who is inside the audience being measured and after any unit
8249    /// too small to be asked about on its own was folded into the level
8250    /// above it.
8251    #[prost(int32, tag="10")]
8252    pub verifier_count: i32,
8253    /// Reading this run produced. Empty until the run completes, and
8254    /// empty on a completed run that produced none — a run nobody answered
8255    /// leaves the indicator without evidence rather than with a zero.
8256    #[prost(string, tag="11")]
8257    pub reading_id: ::prost::alloc::string::String,
8258    /// Timestamp when the run was created.
8259    #[prost(message, optional, tag="12")]
8260    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
8261    /// Timestamp when the run was last updated.
8262    #[prost(message, optional, tag="13")]
8263    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
8264}
8265/// Request to schedule a verification run for a campaign and one of the
8266/// indicators it should move.
8267#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8268pub struct StartVerificationRunRequest {
8269    /// Campaign whose effect is to be verified. Required.
8270    #[prost(string, tag="1")]
8271    pub campaign_id: ::prost::alloc::string::String,
8272    /// Indicator the answers will be recorded against. Required. Its
8273    /// evidence source must be the verification-campaign kind; any other
8274    /// kind returns FAILED_PRECONDITION, because the wait, the verifier
8275    /// derivation and the follow-up template all come from that
8276    /// configuration and have nowhere else to come from.
8277    #[prost(string, tag="2")]
8278    pub indicator_id: ::prost::alloc::string::String,
8279}
8280/// Response after scheduling a verification run.
8281#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8282pub struct StartVerificationRunResponse {
8283    /// The scheduled run. Scheduling a run for a pair that already has one
8284    /// that has not completed is idempotent and returns the existing run.
8285    #[prost(message, optional, tag="1")]
8286    pub run: ::core::option::Option<VerificationRun>,
8287}
8288/// Request to retrieve one verification run.
8289#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8290pub struct GetVerificationRunRequest {
8291    /// ID of the run to retrieve. Required.
8292    #[prost(string, tag="1")]
8293    pub verification_run_id: ::prost::alloc::string::String,
8294}
8295/// Response containing the requested verification run.
8296#[derive(Clone, PartialEq, ::prost::Message)]
8297pub struct GetVerificationRunResponse {
8298    /// The requested run.
8299    #[prost(message, optional, tag="1")]
8300    pub run: ::core::option::Option<VerificationRun>,
8301    /// The reading it produced, when it produced one. Absent while the run
8302    /// is still open and absent on a completed run that collected nothing.
8303    #[prost(message, optional, tag="2")]
8304    pub reading: ::core::option::Option<IndicatorReading>,
8305}
8306/// Request to list verification runs. Exactly one of `objective_id`,
8307/// `indicator_id` and `campaign_id` must be set; sending more than one,
8308/// or none, returns INVALID_ARGUMENT.
8309#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8310pub struct ListVerificationRunsRequest {
8311    /// List the runs recorded against the indicators of this objective.
8312    #[prost(string, optional, tag="1")]
8313    pub objective_id: ::core::option::Option<::prost::alloc::string::String>,
8314    /// List the runs recorded against this indicator.
8315    #[prost(string, optional, tag="2")]
8316    pub indicator_id: ::core::option::Option<::prost::alloc::string::String>,
8317    /// List the runs verifying this campaign.
8318    #[prost(string, optional, tag="3")]
8319    pub campaign_id: ::core::option::Option<::prost::alloc::string::String>,
8320    /// Return only runs in this state. Unspecified returns every state.
8321    #[prost(enumeration="VerificationRunState", tag="4")]
8322    pub state: i32,
8323    /// Pagination parameters.
8324    #[prost(message, optional, tag="5")]
8325    pub pagination: ::core::option::Option<Pagination>,
8326}
8327/// Response containing a page of verification runs.
8328#[derive(Clone, PartialEq, ::prost::Message)]
8329pub struct ListVerificationRunsResponse {
8330    /// Runs in this page, newest first.
8331    #[prost(message, repeated, tag="1")]
8332    pub runs: ::prost::alloc::vec::Vec<VerificationRun>,
8333    /// Pagination metadata for fetching subsequent pages.
8334    #[prost(message, optional, tag="2")]
8335    pub pagination_meta: ::core::option::Option<PaginationMeta>,
8336}
8337/// Request to list the readings recorded against one indicator.
8338#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8339pub struct ListIndicatorReadingsRequest {
8340    /// Indicator whose readings to list. Required.
8341    #[prost(string, tag="1")]
8342    pub indicator_id: ::prost::alloc::string::String,
8343    /// Return only readings from this kind of source. Unspecified returns
8344    /// every kind.
8345    #[prost(enumeration="ReadingSource", tag="2")]
8346    pub source: i32,
8347    /// Pagination parameters.
8348    #[prost(message, optional, tag="3")]
8349    pub pagination: ::core::option::Option<Pagination>,
8350    /// Return only readings whose period ends at or after this instant.
8351    /// Unset leaves the range open at that end.
8352    #[prost(message, optional, tag="4")]
8353    pub period_start_after: ::core::option::Option<::prost_types::Timestamp>,
8354    /// Return only readings whose period starts at or before this instant.
8355    /// Unset leaves the range open at that end.
8356    #[prost(message, optional, tag="5")]
8357    pub period_end_before: ::core::option::Option<::prost_types::Timestamp>,
8358}
8359/// Response containing a page of readings.
8360#[derive(Clone, PartialEq, ::prost::Message)]
8361pub struct ListIndicatorReadingsResponse {
8362    /// Readings in this page, newest period first. An empty page means no
8363    /// reading exists for the filter, which is a statement about evidence
8364    /// and not about the indicator's value.
8365    #[prost(message, repeated, tag="1")]
8366    pub readings: ::prost::alloc::vec::Vec<IndicatorReading>,
8367    /// Pagination metadata for fetching subsequent pages.
8368    #[prost(message, optional, tag="2")]
8369    pub pagination_meta: ::core::option::Option<PaginationMeta>,
8370}
8371// ─── Enums ──────────────────────────────────────────────────────────────────
8372
8373/// Where a reading came from. One value per evidence adapter, so that a
8374/// reading can always be traced back to the kind of source that produced
8375/// it without consulting the indicator's current configuration — an
8376/// indicator's evidence source can be changed after readings exist, and
8377/// past readings keep saying how they were actually obtained.
8378#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8379#[repr(i32)]
8380pub enum ReadingSource {
8381    Unspecified = 0,
8382    /// Produced by responses from the audience of the message itself.
8383    InApp = 1,
8384    /// Produced by a deferred follow-up message asking someone other than
8385    /// the audience whether the behaviour changed.
8386    VerificationCampaign = 2,
8387    /// Pushed by the organization from one of its own systems.
8388    Webhook = 3,
8389    /// Entered by hand or imported from a spreadsheet.
8390    ManualEntry = 4,
8391}
8392impl ReadingSource {
8393    /// String value of the enum field names used in the ProtoBuf definition.
8394    ///
8395    /// The values are not transformed in any way and thus are considered stable
8396    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8397    pub fn as_str_name(&self) -> &'static str {
8398        match self {
8399            Self::Unspecified => "READING_SOURCE_UNSPECIFIED",
8400            Self::InApp => "READING_SOURCE_IN_APP",
8401            Self::VerificationCampaign => "READING_SOURCE_VERIFICATION_CAMPAIGN",
8402            Self::Webhook => "READING_SOURCE_WEBHOOK",
8403            Self::ManualEntry => "READING_SOURCE_MANUAL_ENTRY",
8404        }
8405    }
8406    /// Creates an enum from field names used in the ProtoBuf definition.
8407    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8408        match value {
8409            "READING_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
8410            "READING_SOURCE_IN_APP" => Some(Self::InApp),
8411            "READING_SOURCE_VERIFICATION_CAMPAIGN" => Some(Self::VerificationCampaign),
8412            "READING_SOURCE_WEBHOOK" => Some(Self::Webhook),
8413            "READING_SOURCE_MANUAL_ENTRY" => Some(Self::ManualEntry),
8414            _ => None,
8415        }
8416    }
8417}
8418/// What a reading says about the indicator it was recorded against.
8419/// Every reading carries one, whatever produced it, so that sources of
8420/// different shapes remain comparable on the only question the indicator
8421/// is there to answer.
8422///
8423/// For a verification-campaign reading this is the whole of it. A
8424/// verifier is asked whether the behaviour changed for a unit, not to
8425/// grade it, so a three-way judgement is all the answer contains and
8426/// anything finer would be invented; those readings therefore carry no
8427/// figure. A source that genuinely measures something — a system of the
8428/// organization's own, or a figure entered by hand — reports the number
8429/// in `value` in addition, and the outcome then says how that number
8430/// reads against the indicator's direction and target.
8431#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8432#[repr(i32)]
8433pub enum ReadingOutcome {
8434    Unspecified = 0,
8435    /// The behaviour the indicator describes was reported as happening.
8436    Positive = 1,
8437    /// The behaviour the indicator describes was reported as not
8438    /// happening. A negative reading is a finding, not a failure to
8439    /// collect.
8440    Negative = 2,
8441    /// Answers were collected but they do not support either reading —
8442    /// too few came back, or they disagreed.
8443    ///
8444    /// Distinct from no reading at all. When nobody answers, no reading is
8445    /// recorded and the indicator simply has no evidence for that period;
8446    /// silence is never stored as an outcome, and never as a zero.
8447    Insufficient = 3,
8448}
8449impl ReadingOutcome {
8450    /// String value of the enum field names used in the ProtoBuf definition.
8451    ///
8452    /// The values are not transformed in any way and thus are considered stable
8453    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8454    pub fn as_str_name(&self) -> &'static str {
8455        match self {
8456            Self::Unspecified => "READING_OUTCOME_UNSPECIFIED",
8457            Self::Positive => "READING_OUTCOME_POSITIVE",
8458            Self::Negative => "READING_OUTCOME_NEGATIVE",
8459            Self::Insufficient => "READING_OUTCOME_INSUFFICIENT",
8460        }
8461    }
8462    /// Creates an enum from field names used in the ProtoBuf definition.
8463    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8464        match value {
8465            "READING_OUTCOME_UNSPECIFIED" => Some(Self::Unspecified),
8466            "READING_OUTCOME_POSITIVE" => Some(Self::Positive),
8467            "READING_OUTCOME_NEGATIVE" => Some(Self::Negative),
8468            "READING_OUTCOME_INSUFFICIENT" => Some(Self::Insufficient),
8469            _ => None,
8470        }
8471    }
8472}
8473/// Lifecycle of a verification run.
8474#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8475#[repr(i32)]
8476pub enum VerificationRunState {
8477    Unspecified = 0,
8478    /// Scheduled. The wait after the original message has not elapsed and
8479    /// the follow-up has not been sent.
8480    Pending = 1,
8481    /// The follow-up has been sent and answers are being collected.
8482    Collecting = 2,
8483    /// Collection is closed. The run either produced a reading or produced
8484    /// none; both are terminal, and the second is not an error.
8485    Complete = 3,
8486}
8487impl VerificationRunState {
8488    /// String value of the enum field names used in the ProtoBuf definition.
8489    ///
8490    /// The values are not transformed in any way and thus are considered stable
8491    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8492    pub fn as_str_name(&self) -> &'static str {
8493        match self {
8494            Self::Unspecified => "VERIFICATION_RUN_STATE_UNSPECIFIED",
8495            Self::Pending => "VERIFICATION_RUN_STATE_PENDING",
8496            Self::Collecting => "VERIFICATION_RUN_STATE_COLLECTING",
8497            Self::Complete => "VERIFICATION_RUN_STATE_COMPLETE",
8498        }
8499    }
8500    /// Creates an enum from field names used in the ProtoBuf definition.
8501    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8502        match value {
8503            "VERIFICATION_RUN_STATE_UNSPECIFIED" => Some(Self::Unspecified),
8504            "VERIFICATION_RUN_STATE_PENDING" => Some(Self::Pending),
8505            "VERIFICATION_RUN_STATE_COLLECTING" => Some(Self::Collecting),
8506            "VERIFICATION_RUN_STATE_COMPLETE" => Some(Self::Complete),
8507            _ => None,
8508        }
8509    }
8510}
8511include!("pidgr.v1.tonic.rs");
8512// @@protoc_insertion_point(module)