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/// The level of organizational unit a verification question is put at.
995///
996/// Verification asks somebody other than the audience whether the
997/// behaviour changed for a unit. Which unit that is has two sides pulling
998/// against each other.
999///
1000/// A size floor pushes the choice upward: below a handful of people, an
1001/// answer about the unit is in practice an answer about each of its
1002/// members, and the whole reason for asking about a unit rather than about
1003/// individuals disappears. Sensitivity pushes the choice downward: a
1004/// measure is only worth reading when whoever answers can influence what
1005/// is being asked about, and a question put far above the work stops
1006/// reflecting anybody's effort while still looking like a measurement. The
1007/// level worth choosing is the smallest one that clears the floor.
1008///
1009/// Which levels exist is a fact about the organization and only the
1010/// organization can state it. A reporting line is not a map of meaningful
1011/// units — units that report to the same place may do unrelated work — so
1012/// a level is never inferred from one. When no level satisfies both sides,
1013/// the honest outcome is that the indicator gets no evidence by this
1014/// route, and this enum makes that expressible instead of leaving it
1015/// looking like a question that was asked.
1016#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1017#[repr(i32)]
1018pub enum VerificationUnitLevel {
1019    /// No level chosen. On an indicator this means the organization's
1020    /// default applies; on the organization it means the platform default
1021    /// applies, which is VERIFICATION_UNIT_LEVEL_DERIVED_UNIT. Consumers
1022    /// MUST NOT present this value as a choice somebody made.
1023    Unspecified = 0,
1024    /// Ask at the unit the verifier derivation resolves to. The smallest
1025    /// level available, and therefore the one whose answers track the work
1026    /// most closely. The floor still applies here: a unit below it is not
1027    /// asked at this level and contributes nothing, so a reading covers only
1028    /// the units that cleared the floor and never every unit the derivation
1029    /// reached.
1030    DerivedUnit = 1,
1031    /// Ask at the wider unit the organization's declared structure places
1032    /// over the derived one. This is what rising above the floor looks like
1033    /// when the organization has somewhere to rise to, and the organization
1034    /// is the one that says so. The cost is paid in sensitivity: whoever
1035    /// answers is further from the work, and an answer covering a unit whose
1036    /// parts do unrelated things says less about any of them. Where the
1037    /// organization has declared no level above, or the wider unit is itself
1038    /// below the floor, no question is asked and no evidence is produced.
1039    EnclosingUnit = 2,
1040    /// Do not ask by this route at all. The indicator keeps whatever other
1041    /// evidence sources it has and simply gets none from verification. This
1042    /// is the outcome for an organization flat enough that no level clears
1043    /// the floor, and it is a decision rather than a failure: consumers MUST
1044    /// NOT show it as a collection that is pending, overdue or broken.
1045    None = 3,
1046}
1047impl VerificationUnitLevel {
1048    /// String value of the enum field names used in the ProtoBuf definition.
1049    ///
1050    /// The values are not transformed in any way and thus are considered stable
1051    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1052    pub fn as_str_name(&self) -> &'static str {
1053        match self {
1054            Self::Unspecified => "VERIFICATION_UNIT_LEVEL_UNSPECIFIED",
1055            Self::DerivedUnit => "VERIFICATION_UNIT_LEVEL_DERIVED_UNIT",
1056            Self::EnclosingUnit => "VERIFICATION_UNIT_LEVEL_ENCLOSING_UNIT",
1057            Self::None => "VERIFICATION_UNIT_LEVEL_NONE",
1058        }
1059    }
1060    /// Creates an enum from field names used in the ProtoBuf definition.
1061    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1062        match value {
1063            "VERIFICATION_UNIT_LEVEL_UNSPECIFIED" => Some(Self::Unspecified),
1064            "VERIFICATION_UNIT_LEVEL_DERIVED_UNIT" => Some(Self::DerivedUnit),
1065            "VERIFICATION_UNIT_LEVEL_ENCLOSING_UNIT" => Some(Self::EnclosingUnit),
1066            "VERIFICATION_UNIT_LEVEL_NONE" => Some(Self::None),
1067            _ => None,
1068        }
1069    }
1070}
1071/// Behavior mode controlling what an escalation produces for its targets.
1072#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1073#[repr(i32)]
1074pub enum EscalateMode {
1075    /// Default value; servers normalize this to ESCALATE_MODE_DELIVER.
1076    Unspecified = 0,
1077    /// Targets receive a delivery for the campaign just like primary recipients.
1078    Deliver = 1,
1079    /// Targets receive an out-of-band alert only; no delivery is created.
1080    AlertOnly = 2,
1081}
1082impl EscalateMode {
1083    /// String value of the enum field names used in the ProtoBuf definition.
1084    ///
1085    /// The values are not transformed in any way and thus are considered stable
1086    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1087    pub fn as_str_name(&self) -> &'static str {
1088        match self {
1089            Self::Unspecified => "ESCALATE_MODE_UNSPECIFIED",
1090            Self::Deliver => "ESCALATE_MODE_DELIVER",
1091            Self::AlertOnly => "ESCALATE_MODE_ALERT_ONLY",
1092        }
1093    }
1094    /// Creates an enum from field names used in the ProtoBuf definition.
1095    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1096        match value {
1097            "ESCALATE_MODE_UNSPECIFIED" => Some(Self::Unspecified),
1098            "ESCALATE_MODE_DELIVER" => Some(Self::Deliver),
1099            "ESCALATE_MODE_ALERT_ONLY" => Some(Self::AlertOnly),
1100            _ => None,
1101        }
1102    }
1103}
1104// ─── Messages ───────────────────────────────────────────────────────────────
1105
1106/// A scoped API key for programmatic access (MCP agents, service integrations).
1107#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1108pub struct ApiKey {
1109    /// Unique identifier.
1110    #[prost(string, tag="1")]
1111    pub id: ::prost::alloc::string::String,
1112    /// Human-friendly label (e.g. "MCP Production", "CI Pipeline").
1113    #[prost(string, tag="2")]
1114    pub name: ::prost::alloc::string::String,
1115    /// Displayable prefix of the key (e.g. "pidgr_k_abc12345").
1116    /// Used for identification — the full key is only returned on creation.
1117    #[prost(string, tag="3")]
1118    pub key_prefix: ::prost::alloc::string::String,
1119    /// Permissions granted to this key.
1120    #[prost(enumeration="Permission", repeated, tag="4")]
1121    pub permissions: ::prost::alloc::vec::Vec<i32>,
1122    /// When the key was created.
1123    #[prost(message, optional, tag="5")]
1124    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1125    /// Last time the key was used to authenticate a request. Empty if never used.
1126    #[prost(message, optional, tag="6")]
1127    pub last_used_at: ::core::option::Option<::prost_types::Timestamp>,
1128    /// When the key expires. Empty means no expiration.
1129    #[prost(message, optional, tag="7")]
1130    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
1131    /// Type of this key (API key or SCIM token).
1132    /// Defaults to KEY_TYPE_API_KEY for existing keys.
1133    #[prost(enumeration="KeyType", tag="8")]
1134    pub key_type: i32,
1135}
1136/// Request to create a new API key.
1137#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1138pub struct CreateApiKeyRequest {
1139    /// Human-friendly label. Required, max 200 characters.
1140    #[prost(string, tag="1")]
1141    pub name: ::prost::alloc::string::String,
1142    /// Permissions to grant. Required, at least one.
1143    /// PERMISSION_UNSPECIFIED values are rejected.
1144    #[prost(enumeration="Permission", repeated, tag="2")]
1145    pub permissions: ::prost::alloc::vec::Vec<i32>,
1146    /// Optional expiration time. If omitted, the key does not expire.
1147    #[prost(message, optional, tag="3")]
1148    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
1149    /// Type of key to create. Defaults to KEY_TYPE_API_KEY.
1150    /// SCIM tokens use the "pidgr_scim_" prefix instead of "pidgr_k_".
1151    #[prost(enumeration="KeyType", tag="4")]
1152    pub key_type: i32,
1153}
1154/// Response after creating an API key.
1155/// IMPORTANT: The full key is only returned here — it cannot be retrieved later.
1156#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1157pub struct CreateApiKeyResponse {
1158    /// The created API key metadata.
1159    #[prost(message, optional, tag="1")]
1160    pub api_key: ::core::option::Option<ApiKey>,
1161    /// The full secret key value (e.g. "pidgr_k_abc12345...").
1162    /// Store this securely — it is not retrievable after this response.
1163    #[prost(string, tag="2")]
1164    pub key: ::prost::alloc::string::String,
1165}
1166/// Request to list all API keys in the caller's organization.
1167#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1168pub struct ListApiKeysRequest {
1169    /// Optional filter by key type. Unspecified returns all keys.
1170    #[prost(enumeration="KeyType", tag="1")]
1171    pub key_type: i32,
1172}
1173/// Response containing the organization's API keys.
1174#[derive(Clone, PartialEq, ::prost::Message)]
1175pub struct ListApiKeysResponse {
1176    /// All active (non-revoked) API keys. Full key values are not included.
1177    #[prost(message, repeated, tag="1")]
1178    pub api_keys: ::prost::alloc::vec::Vec<ApiKey>,
1179}
1180/// Request to revoke an API key.
1181#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1182pub struct RevokeApiKeyRequest {
1183    /// ID of the API key to revoke. Required.
1184    #[prost(string, tag="1")]
1185    pub api_key_id: ::prost::alloc::string::String,
1186}
1187/// Response after revoking an API key.
1188#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1189pub struct RevokeApiKeyResponse {
1190}
1191// ─── Enums ──────────────────────────────────────────────────────────────────
1192
1193/// Type of API key, distinguishing platform keys from SCIM provisioning tokens.
1194#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1195#[repr(i32)]
1196pub enum KeyType {
1197    Unspecified = 0,
1198    ApiKey = 1,
1199    ScimToken = 2,
1200}
1201impl KeyType {
1202    /// String value of the enum field names used in the ProtoBuf definition.
1203    ///
1204    /// The values are not transformed in any way and thus are considered stable
1205    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1206    pub fn as_str_name(&self) -> &'static str {
1207        match self {
1208            Self::Unspecified => "KEY_TYPE_UNSPECIFIED",
1209            Self::ApiKey => "KEY_TYPE_API_KEY",
1210            Self::ScimToken => "KEY_TYPE_SCIM_TOKEN",
1211        }
1212    }
1213    /// Creates an enum from field names used in the ProtoBuf definition.
1214    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1215        match value {
1216            "KEY_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
1217            "KEY_TYPE_API_KEY" => Some(Self::ApiKey),
1218            "KEY_TYPE_SCIM_TOKEN" => Some(Self::ScimToken),
1219            _ => None,
1220        }
1221    }
1222}
1223// ─── Messages ───────────────────────────────────────────────────────────────
1224
1225/// Request to export all personal data associated with a user.
1226/// Auth: Requires JWT. Callable by the user themselves or an org admin.
1227#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1228pub struct ExportUserDataRequest {
1229    /// Internal user ID whose data is being exported.
1230    /// Constraints: UUID format (36 characters).
1231    #[prost(string, tag="1")]
1232    pub user_id: ::prost::alloc::string::String,
1233}
1234/// Response containing the export status and download location.
1235#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1236pub struct ExportUserDataResponse {
1237    /// Current status of the export request.
1238    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1239    pub status: i32,
1240    /// Pre-signed S3 URL to download the exported data (ZIP format).
1241    /// Only populated when status is COMPLETED.
1242    #[prost(string, tag="2")]
1243    pub result_url: ::prost::alloc::string::String,
1244    /// Unique identifier for this export request.
1245    /// Constraints: UUID format (36 characters).
1246    #[prost(string, tag="3")]
1247    pub export_id: ::prost::alloc::string::String,
1248}
1249/// Request to export all data associated with the calling organization
1250/// (GDPR Art. 20 data portability at the org level). The organization is
1251/// extracted from the JWT — it is never in the request message.
1252/// Auth: Requires JWT. Org admin only.
1253#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1254pub struct ExportOrgDataRequest {
1255}
1256/// Response containing the org export status and download location.
1257/// The export workflow assembles org configuration, users, campaigns,
1258/// deliveries, and audit events into an encrypted bundle delivered via a
1259/// pre-signed S3 URL.
1260#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1261pub struct ExportOrgDataResponse {
1262    /// Current status of the export request.
1263    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1264    pub status: i32,
1265    /// Pre-signed S3 URL to download the exported bundle (encrypted ZIP).
1266    /// Only populated when status is COMPLETED.
1267    #[prost(string, tag="2")]
1268    pub result_url: ::prost::alloc::string::String,
1269    /// Unique identifier for this export request.
1270    /// Constraints: UUID format (36 characters).
1271    #[prost(string, tag="3")]
1272    pub export_id: ::prost::alloc::string::String,
1273}
1274/// Request to delete or anonymize all personal data associated with a user.
1275/// Auth: Requires JWT. Admin only.
1276#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1277pub struct DeleteUserDataRequest {
1278    /// Internal user ID whose data is being deleted.
1279    /// Constraints: UUID format (36 characters).
1280    #[prost(string, tag="1")]
1281    pub user_id: ::prost::alloc::string::String,
1282    /// When true, PII is replaced with placeholders instead of hard-deleted.
1283    /// This preserves audit trail integrity while removing personal data.
1284    #[prost(bool, tag="2")]
1285    pub anonymize: bool,
1286}
1287/// Response confirming the deletion request.
1288#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1289pub struct DeleteUserDataResponse {
1290    /// Current status of the deletion request.
1291    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1292    pub status: i32,
1293    /// Timestamp when deletion was completed (or scheduled).
1294    /// Only populated when status is COMPLETED.
1295    #[prost(message, optional, tag="2")]
1296    pub deleted_at: ::core::option::Option<::prost_types::Timestamp>,
1297    /// Unique identifier for this deletion request.
1298    #[prost(string, tag="3")]
1299    pub request_id: ::prost::alloc::string::String,
1300}
1301/// Request to list privacy requests for the organization.
1302/// Auth: Requires JWT. Admin only.
1303#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1304pub struct ListPrivacyRequestsRequest {
1305    /// Maximum number of results per page.
1306    /// Constraints: 1–100, default 25.
1307    #[prost(int32, tag="1")]
1308    pub page_size: i32,
1309    /// Continuation token from a previous response.
1310    #[prost(string, tag="2")]
1311    pub page_token: ::prost::alloc::string::String,
1312    /// Filter by request type (export, delete, rectify, restrict). Empty = all.
1313    #[prost(string, tag="3")]
1314    pub request_type: ::prost::alloc::string::String,
1315    /// Filter by status. UNSPECIFIED = all.
1316    #[prost(enumeration="PrivacyRequestStatus", tag="4")]
1317    pub status: i32,
1318}
1319/// Response containing privacy requests.
1320#[derive(Clone, PartialEq, ::prost::Message)]
1321pub struct ListPrivacyRequestsResponse {
1322    /// The privacy requests matching the filters.
1323    #[prost(message, repeated, tag="1")]
1324    pub requests: ::prost::alloc::vec::Vec<PrivacyRequest>,
1325    /// Token for the next page. Empty if no more results.
1326    #[prost(string, tag="2")]
1327    pub next_page_token: ::prost::alloc::string::String,
1328}
1329/// A privacy request record.
1330#[derive(Clone, PartialEq, ::prost::Message)]
1331pub struct PrivacyRequest {
1332    /// Unique identifier.
1333    #[prost(string, tag="1")]
1334    pub id: ::prost::alloc::string::String,
1335    /// The user this request applies to.
1336    #[prost(string, tag="2")]
1337    pub user_id: ::prost::alloc::string::String,
1338    /// Email of the target user.
1339    #[prost(string, tag="3")]
1340    pub user_email: ::prost::alloc::string::String,
1341    /// Type of request (export, delete, rectify, restrict).
1342    #[prost(string, tag="4")]
1343    pub request_type: ::prost::alloc::string::String,
1344    /// Current status.
1345    #[prost(enumeration="PrivacyRequestStatus", tag="5")]
1346    pub status: i32,
1347    /// Whether to anonymize (true) or hard-delete (false). Only for delete requests.
1348    #[prost(bool, tag="6")]
1349    pub anonymize: bool,
1350    /// Email of the admin who initiated this request.
1351    #[prost(string, tag="7")]
1352    pub requested_by_email: ::prost::alloc::string::String,
1353    /// When the request was created.
1354    #[prost(message, optional, tag="8")]
1355    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1356    /// When the request was completed (if applicable).
1357    #[prost(message, optional, tag="9")]
1358    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1359    /// Additional metadata (JSON).
1360    #[prost(map="string, string", tag="10")]
1361    pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1362}
1363/// Request to cancel a pending deletion.
1364/// Auth: Requires JWT. Admin only.
1365#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1366pub struct CancelDeletionRequest {
1367    /// The privacy request ID to cancel.
1368    #[prost(string, tag="1")]
1369    pub request_id: ::prost::alloc::string::String,
1370    /// Admin must type the target user's email to confirm.
1371    #[prost(string, tag="2")]
1372    pub confirmation_email: ::prost::alloc::string::String,
1373}
1374/// Response confirming the cancellation.
1375#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1376pub struct CancelDeletionResponse {
1377    /// Updated status (should be FAILED with reason cancelled).
1378    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1379    pub status: i32,
1380}
1381/// Request to skip the grace period and delete immediately.
1382/// Auth: Requires JWT. Admin only.
1383#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1384pub struct ImmediateDeleteRequest {
1385    /// The privacy request ID to expedite.
1386    #[prost(string, tag="1")]
1387    pub request_id: ::prost::alloc::string::String,
1388    /// Admin must type the target user's email to confirm.
1389    #[prost(string, tag="2")]
1390    pub confirmation_email: ::prost::alloc::string::String,
1391}
1392/// Response confirming the immediate deletion was triggered.
1393#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1394pub struct ImmediateDeleteResponse {
1395    /// Updated status (should be PROCESSING).
1396    #[prost(enumeration="PrivacyRequestStatus", tag="1")]
1397    pub status: i32,
1398}
1399/// Request to correct personal data for a user.
1400/// Auth: Requires JWT. Callable by the user themselves or an org admin.
1401#[derive(Clone, PartialEq, ::prost::Message)]
1402pub struct RectifyUserDataRequest {
1403    /// Internal user ID whose data is being corrected.
1404    /// Constraints: UUID format (36 characters).
1405    #[prost(string, tag="1")]
1406    pub user_id: ::prost::alloc::string::String,
1407    /// Map of field names to corrected values.
1408    /// Corrections are propagated to all stored locations.
1409    /// Constraints: Max 50 corrections per request.
1410    #[prost(map="string, string", tag="2")]
1411    pub corrections: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1412}
1413/// Response listing which fields were successfully corrected.
1414#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1415pub struct RectifyUserDataResponse {
1416    /// Names of fields that were rectified.
1417    #[prost(string, repeated, tag="1")]
1418    pub rectified_fields: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1419}
1420/// Request to restrict or unrestrict processing for a user.
1421/// Auth: Requires JWT. Admin only.
1422#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1423pub struct RestrictProcessingRequest {
1424    /// Internal user ID whose processing is being restricted.
1425    /// Constraints: UUID format (36 characters).
1426    #[prost(string, tag="1")]
1427    pub user_id: ::prost::alloc::string::String,
1428    /// When true, processing is restricted. When false, restriction is lifted.
1429    #[prost(bool, tag="2")]
1430    pub restricted: bool,
1431}
1432/// Response confirming the processing restriction status.
1433#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1434pub struct RestrictProcessingResponse {
1435    /// Current restriction status.
1436    #[prost(bool, tag="1")]
1437    pub restricted: bool,
1438    /// Timestamp when the restriction was applied or removed.
1439    #[prost(message, optional, tag="2")]
1440    pub restricted_at: ::core::option::Option<::prost_types::Timestamp>,
1441}
1442/// Request to confirm whether personal data exists for a user.
1443/// LGPD-specific: confirmação de existência (Art. 18, I).
1444/// Auth: Requires JWT. Admin only.
1445#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1446pub struct GetDataExistenceConfirmationRequest {
1447    /// Internal user ID to check.
1448    /// Constraints: UUID format (36 characters).
1449    #[prost(string, tag="1")]
1450    pub user_id: ::prost::alloc::string::String,
1451}
1452/// Response confirming data existence and listing data categories.
1453#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1454pub struct GetDataExistenceConfirmationResponse {
1455    /// Whether any personal data exists for this user.
1456    #[prost(bool, tag="1")]
1457    pub exists: bool,
1458    /// Categories of data stored (e.g., "profile", "deliveries", "analytics").
1459    #[prost(string, repeated, tag="2")]
1460    pub data_categories: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1461}
1462/// Request to list the calling user's own privacy requests.
1463/// Auth: Requires JWT. No admin permission required — returns only the caller's requests.
1464#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1465pub struct ListMyPrivacyRequestsRequest {
1466    /// Maximum number of results per page.
1467    /// Constraints: 1–100, default 25.
1468    #[prost(int32, tag="1")]
1469    pub page_size: i32,
1470    /// Continuation token from a previous response.
1471    #[prost(string, tag="2")]
1472    pub page_token: ::prost::alloc::string::String,
1473    /// Filter by request type (export, rectify). Empty = all.
1474    #[prost(string, tag="3")]
1475    pub request_type: ::prost::alloc::string::String,
1476    /// Filter by status. UNSPECIFIED = all.
1477    #[prost(enumeration="PrivacyRequestStatus", tag="4")]
1478    pub status: i32,
1479}
1480/// Response containing the calling user's privacy requests.
1481#[derive(Clone, PartialEq, ::prost::Message)]
1482pub struct ListMyPrivacyRequestsResponse {
1483    /// The privacy requests belonging to the calling user.
1484    #[prost(message, repeated, tag="1")]
1485    pub requests: ::prost::alloc::vec::Vec<PrivacyRequest>,
1486    /// Token for the next page. Empty if no more results.
1487    #[prost(string, tag="2")]
1488    pub next_page_token: ::prost::alloc::string::String,
1489}
1490/// A security incident that touched the calling organization. Org-facing
1491/// read-only subset of the staff-side incident record — internal triage
1492/// fields (detector signal, classifier identity, evidence pointers) are
1493/// intentionally not exposed.
1494#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1495pub struct OrgSecurityIncident {
1496    /// Unique identifier for the incident.
1497    /// Constraints: UUID format (36 characters).
1498    #[prost(string, tag="1")]
1499    pub id: ::prost::alloc::string::String,
1500    /// When the observability platform detected the incident. The canonical
1501    /// anchor for the 72-hour GDPR Art. 33 notification clock.
1502    #[prost(message, optional, tag="2")]
1503    pub detected_at: ::core::option::Option<::prost_types::Timestamp>,
1504    /// Detector-assigned severity.
1505    #[prost(enumeration="SecurityIncidentSeverity", tag="3")]
1506    pub severity: i32,
1507    /// Legal classification verdict. PENDING until staff triage completes.
1508    #[prost(enumeration="SecurityIncidentClassification", tag="4")]
1509    pub classification: i32,
1510    /// When the regulator was notified. Empty if no notification was required
1511    /// or it has not happened yet.
1512    #[prost(message, optional, tag="5")]
1513    pub notified_at: ::core::option::Option<::prost_types::Timestamp>,
1514    /// When the incident was resolved. Empty while still open.
1515    #[prost(message, optional, tag="6")]
1516    pub resolved_at: ::core::option::Option<::prost_types::Timestamp>,
1517}
1518/// Request to list security incidents that touched the calling organization.
1519/// The organization is extracted from the JWT — it is never in the request.
1520/// Auth: Requires JWT. Admin only.
1521#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1522pub struct ListOrgSecurityIncidentsRequest {
1523    /// Maximum number of results per page.
1524    /// Constraints: 1–100, default 25.
1525    #[prost(int32, tag="1")]
1526    pub page_size: i32,
1527    /// Continuation token from a previous response.
1528    #[prost(string, tag="2")]
1529    pub page_token: ::prost::alloc::string::String,
1530}
1531/// Response containing the organization's security incident feed.
1532#[derive(Clone, PartialEq, ::prost::Message)]
1533pub struct ListOrgSecurityIncidentsResponse {
1534    /// Incidents that touched the organization, ordered by detected_at
1535    /// descending (newest first).
1536    #[prost(message, repeated, tag="1")]
1537    pub incidents: ::prost::alloc::vec::Vec<OrgSecurityIncident>,
1538    /// Token for the next page. Empty if no more results.
1539    #[prost(string, tag="2")]
1540    pub next_page_token: ::prost::alloc::string::String,
1541}
1542// ─── Enums ──────────────────────────────────────────────────────────────────
1543
1544/// Status of a privacy request (export, delete, rectify, restrict).
1545#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1546#[repr(i32)]
1547pub enum PrivacyRequestStatus {
1548    /// Default value; should not be used explicitly.
1549    Unspecified = 0,
1550    /// Request has been created but not yet started.
1551    Pending = 1,
1552    /// Request is currently being processed.
1553    Processing = 2,
1554    /// Request completed successfully.
1555    Completed = 3,
1556    /// Request failed during processing.
1557    Failed = 4,
1558}
1559impl PrivacyRequestStatus {
1560    /// String value of the enum field names used in the ProtoBuf definition.
1561    ///
1562    /// The values are not transformed in any way and thus are considered stable
1563    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1564    pub fn as_str_name(&self) -> &'static str {
1565        match self {
1566            Self::Unspecified => "PRIVACY_REQUEST_STATUS_UNSPECIFIED",
1567            Self::Pending => "PRIVACY_REQUEST_STATUS_PENDING",
1568            Self::Processing => "PRIVACY_REQUEST_STATUS_PROCESSING",
1569            Self::Completed => "PRIVACY_REQUEST_STATUS_COMPLETED",
1570            Self::Failed => "PRIVACY_REQUEST_STATUS_FAILED",
1571        }
1572    }
1573    /// Creates an enum from field names used in the ProtoBuf definition.
1574    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1575        match value {
1576            "PRIVACY_REQUEST_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
1577            "PRIVACY_REQUEST_STATUS_PENDING" => Some(Self::Pending),
1578            "PRIVACY_REQUEST_STATUS_PROCESSING" => Some(Self::Processing),
1579            "PRIVACY_REQUEST_STATUS_COMPLETED" => Some(Self::Completed),
1580            "PRIVACY_REQUEST_STATUS_FAILED" => Some(Self::Failed),
1581            _ => None,
1582        }
1583    }
1584}
1585/// Detector-assigned severity of a security incident. Mirrors the staff-side
1586/// incident taxonomy; the org feed exposes the same values read-only.
1587#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1588#[repr(i32)]
1589pub enum SecurityIncidentSeverity {
1590    /// Default value; should not be used explicitly.
1591    Unspecified = 0,
1592    /// Informational signal; no action expected.
1593    Info = 1,
1594    /// Anomalous signal under investigation.
1595    Warn = 2,
1596    /// Confirmed or suspected breach-grade signal.
1597    Breach = 3,
1598}
1599impl SecurityIncidentSeverity {
1600    /// String value of the enum field names used in the ProtoBuf definition.
1601    ///
1602    /// The values are not transformed in any way and thus are considered stable
1603    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1604    pub fn as_str_name(&self) -> &'static str {
1605        match self {
1606            Self::Unspecified => "SECURITY_INCIDENT_SEVERITY_UNSPECIFIED",
1607            Self::Info => "SECURITY_INCIDENT_SEVERITY_INFO",
1608            Self::Warn => "SECURITY_INCIDENT_SEVERITY_WARN",
1609            Self::Breach => "SECURITY_INCIDENT_SEVERITY_BREACH",
1610        }
1611    }
1612    /// Creates an enum from field names used in the ProtoBuf definition.
1613    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1614        match value {
1615            "SECURITY_INCIDENT_SEVERITY_UNSPECIFIED" => Some(Self::Unspecified),
1616            "SECURITY_INCIDENT_SEVERITY_INFO" => Some(Self::Info),
1617            "SECURITY_INCIDENT_SEVERITY_WARN" => Some(Self::Warn),
1618            "SECURITY_INCIDENT_SEVERITY_BREACH" => Some(Self::Breach),
1619            _ => None,
1620        }
1621    }
1622}
1623/// Legal classification verdict recorded by platform staff during triage.
1624/// Mirrors the staff-side incident taxonomy; immutable once set.
1625#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1626#[repr(i32)]
1627pub enum SecurityIncidentClassification {
1628    /// Default value; should not be used explicitly.
1629    Unspecified = 0,
1630    /// Queued for triage; no verdict recorded yet.
1631    Pending = 1,
1632    /// Triage concluded the incident is not a breach.
1633    NotBreach = 2,
1634    /// Operational incident with no personal data involved.
1635    OperationalOnly = 10,
1636    /// Personal data breach (GDPR Art. 33 notification clock running).
1637    PersonalDataBreach = 11,
1638    /// Personal data breach with high risk to data subjects (GDPR Art. 34).
1639    PersonalDataBreachHighRisk = 12,
1640}
1641impl SecurityIncidentClassification {
1642    /// String value of the enum field names used in the ProtoBuf definition.
1643    ///
1644    /// The values are not transformed in any way and thus are considered stable
1645    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1646    pub fn as_str_name(&self) -> &'static str {
1647        match self {
1648            Self::Unspecified => "SECURITY_INCIDENT_CLASSIFICATION_UNSPECIFIED",
1649            Self::Pending => "SECURITY_INCIDENT_CLASSIFICATION_PENDING",
1650            Self::NotBreach => "SECURITY_INCIDENT_CLASSIFICATION_NOT_BREACH",
1651            Self::OperationalOnly => "SECURITY_INCIDENT_CLASSIFICATION_OPERATIONAL_ONLY",
1652            Self::PersonalDataBreach => "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH",
1653            Self::PersonalDataBreachHighRisk => "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH_HIGH_RISK",
1654        }
1655    }
1656    /// Creates an enum from field names used in the ProtoBuf definition.
1657    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1658        match value {
1659            "SECURITY_INCIDENT_CLASSIFICATION_UNSPECIFIED" => Some(Self::Unspecified),
1660            "SECURITY_INCIDENT_CLASSIFICATION_PENDING" => Some(Self::Pending),
1661            "SECURITY_INCIDENT_CLASSIFICATION_NOT_BREACH" => Some(Self::NotBreach),
1662            "SECURITY_INCIDENT_CLASSIFICATION_OPERATIONAL_ONLY" => Some(Self::OperationalOnly),
1663            "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH" => Some(Self::PersonalDataBreach),
1664            "SECURITY_INCIDENT_CLASSIFICATION_PERSONAL_DATA_BREACH_HIGH_RISK" => Some(Self::PersonalDataBreachHighRisk),
1665            _ => None,
1666        }
1667    }
1668}
1669// ─── Messages ───────────────────────────────────────────────────────────────
1670
1671/// An immutable audit event capturing a significant platform action.
1672/// Audit events are append-only — they cannot be updated or deleted.
1673#[derive(Clone, PartialEq, ::prost::Message)]
1674pub struct AuditEvent {
1675    /// Unique identifier for this audit event.
1676    /// Constraints: UUID format (36 characters).
1677    #[prost(string, tag="1")]
1678    pub id: ::prost::alloc::string::String,
1679    /// Organization in which the event occurred.
1680    /// Constraints: UUID format (36 characters).
1681    #[prost(string, tag="2")]
1682    pub org_id: ::prost::alloc::string::String,
1683    /// User who performed the action. Empty for system-initiated events.
1684    /// Constraints: UUID format (36 characters) when present.
1685    #[prost(string, tag="3")]
1686    pub actor_id: ::prost::alloc::string::String,
1687    /// Type of action that was performed.
1688    #[prost(enumeration="AuditEventType", tag="4")]
1689    pub event_type: i32,
1690    /// Type of entity affected (e.g., "campaign", "user", "template").
1691    /// Constraints: Max length 50 characters.
1692    #[prost(string, tag="5")]
1693    pub entity_type: ::prost::alloc::string::String,
1694    /// Identifier of the entity affected.
1695    /// Constraints: UUID format (36 characters).
1696    #[prost(string, tag="6")]
1697    pub entity_id: ::prost::alloc::string::String,
1698    /// Additional context about the event (e.g., old/new values for changes).
1699    /// Constraints: Max 20 key-value pairs, keys max 50 chars, values max 500 chars.
1700    #[prost(map="string, string", tag="7")]
1701    pub metadata: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
1702    /// True when this event is synthetic (artificially injected) data — used for
1703    /// demos, sandbox testing, or issue reproduction — rather than the record of
1704    /// a real user action.
1705    #[prost(bool, tag="8")]
1706    pub synthetic: bool,
1707    /// Classification of this event: MANAGEMENT for principal-initiated actions
1708    /// on the organization's configuration or operation, SYSTEM for high-volume
1709    /// data-plane events emitted during processing. The server derives the class
1710    /// from the event type, so events are never unclassified.
1711    #[prost(enumeration="AuditEventClass", tag="11")]
1712    pub event_class: i32,
1713    /// Timestamp when the event was recorded.
1714    #[prost(message, optional, tag="10")]
1715    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1716}
1717/// Request to list audit events with optional filters.
1718/// Auth: Requires JWT. Admin only.
1719#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1720pub struct ListAuditEventsRequest {
1721    /// Pagination token from a previous response.
1722    #[prost(string, tag="1")]
1723    pub page_token: ::prost::alloc::string::String,
1724    /// Maximum number of events to return.
1725    /// Constraints: Min 1, max 100. Default 50.
1726    #[prost(int32, tag="2")]
1727    pub page_size: i32,
1728    /// Optional filter: only return events of this type.
1729    #[prost(enumeration="AuditEventType", tag="3")]
1730    pub event_type: i32,
1731    /// Optional filter: only return events by this actor.
1732    /// Constraints: UUID format (36 characters).
1733    #[prost(string, tag="4")]
1734    pub actor_id: ::prost::alloc::string::String,
1735    /// Optional filter: events after this timestamp (inclusive).
1736    #[prost(message, optional, tag="5")]
1737    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
1738    /// Optional filter: events before this timestamp (exclusive).
1739    #[prost(message, optional, tag="6")]
1740    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
1741    /// Optional filter: only return events in these classes.
1742    /// Empty means no filtering — events of all classes are returned. Because
1743    /// classification is derived from the event type, a non-empty filter also
1744    /// covers events recorded before classification existed.
1745    #[prost(enumeration="AuditEventClass", repeated, tag="7")]
1746    pub event_classes: ::prost::alloc::vec::Vec<i32>,
1747}
1748/// Response containing a paginated list of audit events.
1749#[derive(Clone, PartialEq, ::prost::Message)]
1750pub struct ListAuditEventsResponse {
1751    /// Audit events matching the request filters.
1752    #[prost(message, repeated, tag="1")]
1753    pub events: ::prost::alloc::vec::Vec<AuditEvent>,
1754    /// Token for fetching the next page. Empty when no more events.
1755    #[prost(string, tag="2")]
1756    pub next_page_token: ::prost::alloc::string::String,
1757}
1758/// Request to export the audit trail to S3 in a specified format.
1759/// Auth: Requires JWT. Admin only.
1760#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1761pub struct ExportAuditTrailRequest {
1762    /// Export format.
1763    #[prost(enumeration="AuditExportFormat", tag="1")]
1764    pub format: i32,
1765    /// Optional: export events after this timestamp.
1766    #[prost(message, optional, tag="2")]
1767    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
1768    /// Optional: export events before this timestamp.
1769    #[prost(message, optional, tag="3")]
1770    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
1771}
1772/// Response containing the export download URL.
1773#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1774pub struct ExportAuditTrailResponse {
1775    /// Pre-signed S3 URL to download the exported audit trail.
1776    /// Only populated when status is COMPLETED.
1777    #[prost(string, tag="1")]
1778    pub export_url: ::prost::alloc::string::String,
1779    /// Current status of the export request.
1780    #[prost(enumeration="PrivacyRequestStatus", tag="2")]
1781    pub status: i32,
1782}
1783/// A persistent record of an audit trail export request.
1784#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1785pub struct AuditExport {
1786    /// Unique identifier.
1787    #[prost(string, tag="1")]
1788    pub id: ::prost::alloc::string::String,
1789    /// Export format (csv, json).
1790    #[prost(string, tag="2")]
1791    pub format: ::prost::alloc::string::String,
1792    /// Current status.
1793    #[prost(enumeration="PrivacyRequestStatus", tag="3")]
1794    pub status: i32,
1795    /// Pre-signed download URL. Only populated when status is COMPLETED.
1796    #[prost(string, tag="4")]
1797    pub result_url: ::prost::alloc::string::String,
1798    /// Error message if the export failed.
1799    #[prost(string, tag="5")]
1800    pub error_message: ::prost::alloc::string::String,
1801    /// Email of the admin who requested the export.
1802    #[prost(string, tag="6")]
1803    pub requested_by_email: ::prost::alloc::string::String,
1804    /// When the export was requested.
1805    #[prost(message, optional, tag="7")]
1806    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
1807    /// When the export completed (if applicable).
1808    #[prost(message, optional, tag="8")]
1809    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
1810}
1811/// Request to list audit export history.
1812/// Auth: Requires JWT. Admin only.
1813#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
1814pub struct ListAuditExportsRequest {
1815}
1816/// Response containing the list of audit exports.
1817#[derive(Clone, PartialEq, ::prost::Message)]
1818pub struct ListAuditExportsResponse {
1819    /// Audit export records, newest first.
1820    #[prost(message, repeated, tag="1")]
1821    pub exports: ::prost::alloc::vec::Vec<AuditExport>,
1822}
1823/// Request to append a single audit event from an internal service.
1824///
1825/// Auth: INTERNAL-mTLS ONLY. Unlike the read-side RPCs which authenticate
1826/// via Cognito JWT and infer `org_id` from the caller's claim, this RPC is
1827/// invoked by sibling services (e.g. pidgr-integrations) over the internal
1828/// mTLS mesh and therefore carries `org_id` in the request payload. The
1829/// server MUST reject any caller presenting only a JWT.
1830#[derive(Clone, PartialEq, ::prost::Message)]
1831pub struct AppendRequest {
1832    /// String form of the event type. Sibling services use a stable string
1833    /// identifier (e.g. "REACHABILITY_UPSERT", "REACHABILITY_REMOVE") so a
1834    /// new event type does not require a coordinated proto release across
1835    /// every internal service before it can be recorded. The audit server
1836    /// is responsible for mapping the string into its internal taxonomy.
1837    #[prost(string, tag="1")]
1838    pub event_type: ::prost::alloc::string::String,
1839    /// Organization in which the event occurred. UUID.
1840    #[prost(string, tag="2")]
1841    pub org_id: ::prost::alloc::string::String,
1842    /// User the audit event is about, if applicable. UUID. Unset when the
1843    /// event is not subject-bound (e.g. an org-wide policy change).
1844    #[prost(string, optional, tag="3")]
1845    pub subject_user_id: ::core::option::Option<::prost::alloc::string::String>,
1846    /// Actor who initiated the action, if any. UUID. Unset for system-initiated
1847    /// or sibling-service-initiated events.
1848    #[prost(string, optional, tag="4")]
1849    pub actor_id: ::core::option::Option<::prost::alloc::string::String>,
1850    /// Structured event-specific payload. Used in lieu of the rigid
1851    /// `map<string, string> metadata` on `AuditEvent` so sibling services
1852    /// can record nested objects (e.g. a `prefetch_signals` block) without
1853    /// string-encoding every value. Servers SHOULD redact PII before persist
1854    /// and MUST NOT log this field at INFO or above. Sensitive cryptographic
1855    /// material (plaintext identifiers, envelope ciphertext, raw HMAC keys)
1856    /// MUST NOT be placed here.
1857    #[prost(message, optional, tag="5")]
1858    pub details: ::core::option::Option<::prost_types::Struct>,
1859}
1860#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
1861pub struct AppendResponse {
1862    /// Server-assigned audit event identifier (UUID).
1863    #[prost(string, tag="1")]
1864    pub event_id: ::prost::alloc::string::String,
1865}
1866// ─── Enums ──────────────────────────────────────────────────────────────────
1867
1868/// Type of auditable platform action.
1869#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
1870#[repr(i32)]
1871pub enum AuditEventType {
1872    /// Default value; should not be used explicitly.
1873    Unspecified = 0,
1874    /// ── Campaign lifecycle ───────────────────────────────────────────────────
1875    /// A campaign was created.
1876    CampaignCreated = 1,
1877    /// A message was sent to a recipient.
1878    MessageSent = 2,
1879    /// A message was opened by a recipient.
1880    MessageOpened = 3,
1881    /// A recipient acknowledged a campaign.
1882    AckRegistered = 4,
1883    /// An escalation was triggered by the workflow.
1884    EscalationExecuted = 5,
1885    /// A campaign was started.
1886    CampaignStarted = 12,
1887    /// A campaign was cancelled.
1888    CampaignCancelled = 13,
1889    /// A campaign was updated.
1890    CampaignUpdated = 14,
1891    /// ── User lifecycle ───────────────────────────────────────────────────────
1892    /// A user was invited to the organization.
1893    UserInvited = 6,
1894    /// A user was deactivated.
1895    UserDeactivated = 7,
1896    /// A user was reactivated.
1897    UserReactivated = 15,
1898    /// A user's role was changed (assigned to a different role).
1899    RoleChanged = 10,
1900    /// A user's invite was revoked.
1901    InviteRevoked = 16,
1902    /// A user's profile was updated.
1903    ProfileUpdated = 17,
1904    /// A user's settings were updated.
1905    SettingsUpdated = 18,
1906    /// A user enrolled a passkey.
1907    PasskeyEnrolled = 19,
1908    /// ── GDPR / Privacy ──────────────────────────────────────────────────────
1909    /// A data export was requested (GDPR Art. 15).
1910    DataExportRequested = 8,
1911    /// A data deletion was requested (GDPR Art. 17).
1912    DataDeletionRequested = 9,
1913    /// User data was rectified (GDPR Art. 16).
1914    DataRectified = 20,
1915    /// Data processing was restricted (GDPR Art. 18).
1916    ProcessingRestricted = 21,
1917    /// A scheduled deletion was cancelled.
1918    DeletionCancelled = 22,
1919    /// An immediate deletion was executed.
1920    DeletionImmediate = 23,
1921    /// ── Organization / SSO ───────────────────────────────────────────────────
1922    /// An SSO provider was configured.
1923    SsoConfigured = 11,
1924    /// An SSO provider was created.
1925    SsoProviderCreated = 24,
1926    /// An SSO provider was deleted.
1927    SsoProviderDeleted = 25,
1928    /// Organization settings were updated.
1929    OrgUpdated = 26,
1930    /// ── Roles ────────────────────────────────────────────────────────────────
1931    /// A role was created.
1932    RoleCreated = 27,
1933    /// A role's name or permissions were updated.
1934    RoleUpdated = 28,
1935    /// A role was deleted.
1936    RoleDeleted = 29,
1937    /// ── Templates ────────────────────────────────────────────────────────────
1938    /// A template was created.
1939    TemplateCreated = 30,
1940    /// A template was updated.
1941    TemplateUpdated = 31,
1942    /// ── API Keys ─────────────────────────────────────────────────────────────
1943    /// An API key was created.
1944    ApiKeyCreated = 32,
1945    /// An API key was revoked.
1946    ApiKeyRevoked = 33,
1947    /// ── Invite Links ─────────────────────────────────────────────────────────
1948    /// An invite link was created.
1949    InviteLinkCreated = 34,
1950    /// An invite link was revoked.
1951    InviteLinkRevoked = 35,
1952    /// ── Groups ───────────────────────────────────────────────────────────────
1953    /// A group was created.
1954    GroupCreated = 36,
1955    /// A group was updated.
1956    GroupUpdated = 37,
1957    /// A group was deleted.
1958    GroupDeleted = 38,
1959    /// Members were added to a group.
1960    GroupMembersAdded = 39,
1961    /// Members were removed from a group.
1962    GroupMembersRemoved = 40,
1963    /// ── Teams ────────────────────────────────────────────────────────────────
1964    /// A team was created.
1965    TeamCreated = 41,
1966    /// A team was updated.
1967    TeamUpdated = 42,
1968    /// A team was deleted.
1969    TeamDeleted = 43,
1970    /// Members were added to a team.
1971    TeamMembersAdded = 44,
1972    /// Members were removed from a team.
1973    TeamMembersRemoved = 45,
1974    /// ── SCIM Provisioning ───────────────────────────────────────────────────
1975    /// A user was provisioned via SCIM.
1976    ScimUserProvisioned = 46,
1977    /// A user was deprovisioned via SCIM.
1978    ScimUserDeprovisioned = 47,
1979    /// A user was updated via SCIM.
1980    ScimUserUpdated = 48,
1981    /// ── Translations ────────────────────────────────────────────────────────
1982    /// A template translation was created.
1983    TranslationCreated = 49,
1984    /// A template translation was approved.
1985    TranslationApproved = 50,
1986    /// ── Sandbox Orgs ────────────────────────────────────────────────────────
1987    /// A sandbox organization was created.
1988    SandboxCreated = 51,
1989    /// A sandbox organization expired and was deleted.
1990    SandboxExpired = 52,
1991    /// ── AI/Insights ─────────────────────────────────────────────────────────
1992    /// An AI prediction was served and logged (EU AI Act Art. 12).
1993    AiPredictionLogged = 53,
1994    /// The ML pipeline (archetype clustering + enrichment) was manually triggered.
1995    MlPipelineTriggered = 54,
1996    /// Per-group archetype clustering was manually triggered.
1997    ArchetypeClusteringTriggered = 55,
1998    /// ── Org lifecycle ───────────────────────────────────────────────────────
1999    /// An organization was created.
2000    OrgCreated = 56,
2001    /// An organization was deleted (sandbox cleanup or manual deletion).
2002    OrgDeleted = 57,
2003    /// ── Reachability registry (pidgr-integrations) ──────────────────────────
2004    /// A reachability identifier (email, phone, Slack ID, etc.) was upserted.
2005    /// GDPR-relevant per Chikorita audit classification.
2006    ReachabilityUpsert = 58,
2007    /// A reachability identifier was removed. GDPR Art. 17 "right to erasure"
2008    /// event; written BEFORE the registry row is deleted per Recital 30.
2009    ReachabilityRemove = 59,
2010    /// ── KMS envelope encryption ─────────────────────────────────────────────
2011    /// A payload was envelope-encrypted with a KMS-managed key.
2012    KmsEncrypt = 60,
2013    /// A payload was decrypted with a KMS-managed key.
2014    KmsDecrypt = 61,
2015}
2016impl AuditEventType {
2017    /// String value of the enum field names used in the ProtoBuf definition.
2018    ///
2019    /// The values are not transformed in any way and thus are considered stable
2020    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2021    pub fn as_str_name(&self) -> &'static str {
2022        match self {
2023            Self::Unspecified => "AUDIT_EVENT_TYPE_UNSPECIFIED",
2024            Self::CampaignCreated => "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED",
2025            Self::MessageSent => "AUDIT_EVENT_TYPE_MESSAGE_SENT",
2026            Self::MessageOpened => "AUDIT_EVENT_TYPE_MESSAGE_OPENED",
2027            Self::AckRegistered => "AUDIT_EVENT_TYPE_ACK_REGISTERED",
2028            Self::EscalationExecuted => "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED",
2029            Self::CampaignStarted => "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED",
2030            Self::CampaignCancelled => "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED",
2031            Self::CampaignUpdated => "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED",
2032            Self::UserInvited => "AUDIT_EVENT_TYPE_USER_INVITED",
2033            Self::UserDeactivated => "AUDIT_EVENT_TYPE_USER_DEACTIVATED",
2034            Self::UserReactivated => "AUDIT_EVENT_TYPE_USER_REACTIVATED",
2035            Self::RoleChanged => "AUDIT_EVENT_TYPE_ROLE_CHANGED",
2036            Self::InviteRevoked => "AUDIT_EVENT_TYPE_INVITE_REVOKED",
2037            Self::ProfileUpdated => "AUDIT_EVENT_TYPE_PROFILE_UPDATED",
2038            Self::SettingsUpdated => "AUDIT_EVENT_TYPE_SETTINGS_UPDATED",
2039            Self::PasskeyEnrolled => "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED",
2040            Self::DataExportRequested => "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED",
2041            Self::DataDeletionRequested => "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED",
2042            Self::DataRectified => "AUDIT_EVENT_TYPE_DATA_RECTIFIED",
2043            Self::ProcessingRestricted => "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED",
2044            Self::DeletionCancelled => "AUDIT_EVENT_TYPE_DELETION_CANCELLED",
2045            Self::DeletionImmediate => "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE",
2046            Self::SsoConfigured => "AUDIT_EVENT_TYPE_SSO_CONFIGURED",
2047            Self::SsoProviderCreated => "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED",
2048            Self::SsoProviderDeleted => "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED",
2049            Self::OrgUpdated => "AUDIT_EVENT_TYPE_ORG_UPDATED",
2050            Self::RoleCreated => "AUDIT_EVENT_TYPE_ROLE_CREATED",
2051            Self::RoleUpdated => "AUDIT_EVENT_TYPE_ROLE_UPDATED",
2052            Self::RoleDeleted => "AUDIT_EVENT_TYPE_ROLE_DELETED",
2053            Self::TemplateCreated => "AUDIT_EVENT_TYPE_TEMPLATE_CREATED",
2054            Self::TemplateUpdated => "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED",
2055            Self::ApiKeyCreated => "AUDIT_EVENT_TYPE_API_KEY_CREATED",
2056            Self::ApiKeyRevoked => "AUDIT_EVENT_TYPE_API_KEY_REVOKED",
2057            Self::InviteLinkCreated => "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED",
2058            Self::InviteLinkRevoked => "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED",
2059            Self::GroupCreated => "AUDIT_EVENT_TYPE_GROUP_CREATED",
2060            Self::GroupUpdated => "AUDIT_EVENT_TYPE_GROUP_UPDATED",
2061            Self::GroupDeleted => "AUDIT_EVENT_TYPE_GROUP_DELETED",
2062            Self::GroupMembersAdded => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED",
2063            Self::GroupMembersRemoved => "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED",
2064            Self::TeamCreated => "AUDIT_EVENT_TYPE_TEAM_CREATED",
2065            Self::TeamUpdated => "AUDIT_EVENT_TYPE_TEAM_UPDATED",
2066            Self::TeamDeleted => "AUDIT_EVENT_TYPE_TEAM_DELETED",
2067            Self::TeamMembersAdded => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED",
2068            Self::TeamMembersRemoved => "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED",
2069            Self::ScimUserProvisioned => "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED",
2070            Self::ScimUserDeprovisioned => "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED",
2071            Self::ScimUserUpdated => "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED",
2072            Self::TranslationCreated => "AUDIT_EVENT_TYPE_TRANSLATION_CREATED",
2073            Self::TranslationApproved => "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED",
2074            Self::SandboxCreated => "AUDIT_EVENT_TYPE_SANDBOX_CREATED",
2075            Self::SandboxExpired => "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED",
2076            Self::AiPredictionLogged => "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED",
2077            Self::MlPipelineTriggered => "AUDIT_EVENT_TYPE_ML_PIPELINE_TRIGGERED",
2078            Self::ArchetypeClusteringTriggered => "AUDIT_EVENT_TYPE_ARCHETYPE_CLUSTERING_TRIGGERED",
2079            Self::OrgCreated => "AUDIT_EVENT_TYPE_ORG_CREATED",
2080            Self::OrgDeleted => "AUDIT_EVENT_TYPE_ORG_DELETED",
2081            Self::ReachabilityUpsert => "AUDIT_EVENT_TYPE_REACHABILITY_UPSERT",
2082            Self::ReachabilityRemove => "AUDIT_EVENT_TYPE_REACHABILITY_REMOVE",
2083            Self::KmsEncrypt => "AUDIT_EVENT_TYPE_KMS_ENCRYPT",
2084            Self::KmsDecrypt => "AUDIT_EVENT_TYPE_KMS_DECRYPT",
2085        }
2086    }
2087    /// Creates an enum from field names used in the ProtoBuf definition.
2088    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2089        match value {
2090            "AUDIT_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2091            "AUDIT_EVENT_TYPE_CAMPAIGN_CREATED" => Some(Self::CampaignCreated),
2092            "AUDIT_EVENT_TYPE_MESSAGE_SENT" => Some(Self::MessageSent),
2093            "AUDIT_EVENT_TYPE_MESSAGE_OPENED" => Some(Self::MessageOpened),
2094            "AUDIT_EVENT_TYPE_ACK_REGISTERED" => Some(Self::AckRegistered),
2095            "AUDIT_EVENT_TYPE_ESCALATION_EXECUTED" => Some(Self::EscalationExecuted),
2096            "AUDIT_EVENT_TYPE_CAMPAIGN_STARTED" => Some(Self::CampaignStarted),
2097            "AUDIT_EVENT_TYPE_CAMPAIGN_CANCELLED" => Some(Self::CampaignCancelled),
2098            "AUDIT_EVENT_TYPE_CAMPAIGN_UPDATED" => Some(Self::CampaignUpdated),
2099            "AUDIT_EVENT_TYPE_USER_INVITED" => Some(Self::UserInvited),
2100            "AUDIT_EVENT_TYPE_USER_DEACTIVATED" => Some(Self::UserDeactivated),
2101            "AUDIT_EVENT_TYPE_USER_REACTIVATED" => Some(Self::UserReactivated),
2102            "AUDIT_EVENT_TYPE_ROLE_CHANGED" => Some(Self::RoleChanged),
2103            "AUDIT_EVENT_TYPE_INVITE_REVOKED" => Some(Self::InviteRevoked),
2104            "AUDIT_EVENT_TYPE_PROFILE_UPDATED" => Some(Self::ProfileUpdated),
2105            "AUDIT_EVENT_TYPE_SETTINGS_UPDATED" => Some(Self::SettingsUpdated),
2106            "AUDIT_EVENT_TYPE_PASSKEY_ENROLLED" => Some(Self::PasskeyEnrolled),
2107            "AUDIT_EVENT_TYPE_DATA_EXPORT_REQUESTED" => Some(Self::DataExportRequested),
2108            "AUDIT_EVENT_TYPE_DATA_DELETION_REQUESTED" => Some(Self::DataDeletionRequested),
2109            "AUDIT_EVENT_TYPE_DATA_RECTIFIED" => Some(Self::DataRectified),
2110            "AUDIT_EVENT_TYPE_PROCESSING_RESTRICTED" => Some(Self::ProcessingRestricted),
2111            "AUDIT_EVENT_TYPE_DELETION_CANCELLED" => Some(Self::DeletionCancelled),
2112            "AUDIT_EVENT_TYPE_DELETION_IMMEDIATE" => Some(Self::DeletionImmediate),
2113            "AUDIT_EVENT_TYPE_SSO_CONFIGURED" => Some(Self::SsoConfigured),
2114            "AUDIT_EVENT_TYPE_SSO_PROVIDER_CREATED" => Some(Self::SsoProviderCreated),
2115            "AUDIT_EVENT_TYPE_SSO_PROVIDER_DELETED" => Some(Self::SsoProviderDeleted),
2116            "AUDIT_EVENT_TYPE_ORG_UPDATED" => Some(Self::OrgUpdated),
2117            "AUDIT_EVENT_TYPE_ROLE_CREATED" => Some(Self::RoleCreated),
2118            "AUDIT_EVENT_TYPE_ROLE_UPDATED" => Some(Self::RoleUpdated),
2119            "AUDIT_EVENT_TYPE_ROLE_DELETED" => Some(Self::RoleDeleted),
2120            "AUDIT_EVENT_TYPE_TEMPLATE_CREATED" => Some(Self::TemplateCreated),
2121            "AUDIT_EVENT_TYPE_TEMPLATE_UPDATED" => Some(Self::TemplateUpdated),
2122            "AUDIT_EVENT_TYPE_API_KEY_CREATED" => Some(Self::ApiKeyCreated),
2123            "AUDIT_EVENT_TYPE_API_KEY_REVOKED" => Some(Self::ApiKeyRevoked),
2124            "AUDIT_EVENT_TYPE_INVITE_LINK_CREATED" => Some(Self::InviteLinkCreated),
2125            "AUDIT_EVENT_TYPE_INVITE_LINK_REVOKED" => Some(Self::InviteLinkRevoked),
2126            "AUDIT_EVENT_TYPE_GROUP_CREATED" => Some(Self::GroupCreated),
2127            "AUDIT_EVENT_TYPE_GROUP_UPDATED" => Some(Self::GroupUpdated),
2128            "AUDIT_EVENT_TYPE_GROUP_DELETED" => Some(Self::GroupDeleted),
2129            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_ADDED" => Some(Self::GroupMembersAdded),
2130            "AUDIT_EVENT_TYPE_GROUP_MEMBERS_REMOVED" => Some(Self::GroupMembersRemoved),
2131            "AUDIT_EVENT_TYPE_TEAM_CREATED" => Some(Self::TeamCreated),
2132            "AUDIT_EVENT_TYPE_TEAM_UPDATED" => Some(Self::TeamUpdated),
2133            "AUDIT_EVENT_TYPE_TEAM_DELETED" => Some(Self::TeamDeleted),
2134            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_ADDED" => Some(Self::TeamMembersAdded),
2135            "AUDIT_EVENT_TYPE_TEAM_MEMBERS_REMOVED" => Some(Self::TeamMembersRemoved),
2136            "AUDIT_EVENT_TYPE_SCIM_USER_PROVISIONED" => Some(Self::ScimUserProvisioned),
2137            "AUDIT_EVENT_TYPE_SCIM_USER_DEPROVISIONED" => Some(Self::ScimUserDeprovisioned),
2138            "AUDIT_EVENT_TYPE_SCIM_USER_UPDATED" => Some(Self::ScimUserUpdated),
2139            "AUDIT_EVENT_TYPE_TRANSLATION_CREATED" => Some(Self::TranslationCreated),
2140            "AUDIT_EVENT_TYPE_TRANSLATION_APPROVED" => Some(Self::TranslationApproved),
2141            "AUDIT_EVENT_TYPE_SANDBOX_CREATED" => Some(Self::SandboxCreated),
2142            "AUDIT_EVENT_TYPE_SANDBOX_EXPIRED" => Some(Self::SandboxExpired),
2143            "AUDIT_EVENT_TYPE_AI_PREDICTION_LOGGED" => Some(Self::AiPredictionLogged),
2144            "AUDIT_EVENT_TYPE_ML_PIPELINE_TRIGGERED" => Some(Self::MlPipelineTriggered),
2145            "AUDIT_EVENT_TYPE_ARCHETYPE_CLUSTERING_TRIGGERED" => Some(Self::ArchetypeClusteringTriggered),
2146            "AUDIT_EVENT_TYPE_ORG_CREATED" => Some(Self::OrgCreated),
2147            "AUDIT_EVENT_TYPE_ORG_DELETED" => Some(Self::OrgDeleted),
2148            "AUDIT_EVENT_TYPE_REACHABILITY_UPSERT" => Some(Self::ReachabilityUpsert),
2149            "AUDIT_EVENT_TYPE_REACHABILITY_REMOVE" => Some(Self::ReachabilityRemove),
2150            "AUDIT_EVENT_TYPE_KMS_ENCRYPT" => Some(Self::KmsEncrypt),
2151            "AUDIT_EVENT_TYPE_KMS_DECRYPT" => Some(Self::KmsDecrypt),
2152            _ => None,
2153        }
2154    }
2155}
2156/// Classification of an audit event by origin and volume profile, separating
2157/// management actions (human-initiated configuration changes) from high-volume
2158/// system events emitted automatically during processing.
2159#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2160#[repr(i32)]
2161pub enum AuditEventClass {
2162    /// Default value; should not be used explicitly.
2163    Unspecified = 0,
2164    /// An action initiated by a principal against the organization's
2165    /// configuration or operation (e.g. creating a campaign, changing a role).
2166    Management = 1,
2167    /// A high-volume data-plane event emitted by the system during processing
2168    /// (e.g. per-payload encryption or decryption).
2169    System = 2,
2170}
2171impl AuditEventClass {
2172    /// String value of the enum field names used in the ProtoBuf definition.
2173    ///
2174    /// The values are not transformed in any way and thus are considered stable
2175    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2176    pub fn as_str_name(&self) -> &'static str {
2177        match self {
2178            Self::Unspecified => "AUDIT_EVENT_CLASS_UNSPECIFIED",
2179            Self::Management => "AUDIT_EVENT_CLASS_MANAGEMENT",
2180            Self::System => "AUDIT_EVENT_CLASS_SYSTEM",
2181        }
2182    }
2183    /// Creates an enum from field names used in the ProtoBuf definition.
2184    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2185        match value {
2186            "AUDIT_EVENT_CLASS_UNSPECIFIED" => Some(Self::Unspecified),
2187            "AUDIT_EVENT_CLASS_MANAGEMENT" => Some(Self::Management),
2188            "AUDIT_EVENT_CLASS_SYSTEM" => Some(Self::System),
2189            _ => None,
2190        }
2191    }
2192}
2193/// Format for audit trail export.
2194#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2195#[repr(i32)]
2196pub enum AuditExportFormat {
2197    /// Default value; should not be used explicitly.
2198    Unspecified = 0,
2199    /// Comma-separated values.
2200    Csv = 1,
2201    /// JSON lines format.
2202    Json = 2,
2203    /// Apache Parquet columnar format.
2204    Parquet = 3,
2205}
2206impl AuditExportFormat {
2207    /// String value of the enum field names used in the ProtoBuf definition.
2208    ///
2209    /// The values are not transformed in any way and thus are considered stable
2210    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2211    pub fn as_str_name(&self) -> &'static str {
2212        match self {
2213            Self::Unspecified => "AUDIT_EXPORT_FORMAT_UNSPECIFIED",
2214            Self::Csv => "AUDIT_EXPORT_FORMAT_CSV",
2215            Self::Json => "AUDIT_EXPORT_FORMAT_JSON",
2216            Self::Parquet => "AUDIT_EXPORT_FORMAT_PARQUET",
2217        }
2218    }
2219    /// Creates an enum from field names used in the ProtoBuf definition.
2220    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2221        match value {
2222            "AUDIT_EXPORT_FORMAT_UNSPECIFIED" => Some(Self::Unspecified),
2223            "AUDIT_EXPORT_FORMAT_CSV" => Some(Self::Csv),
2224            "AUDIT_EXPORT_FORMAT_JSON" => Some(Self::Json),
2225            "AUDIT_EXPORT_FORMAT_PARQUET" => Some(Self::Parquet),
2226            _ => None,
2227        }
2228    }
2229}
2230// ─── Messages ─────────────────────────────────────────────────────────────────
2231
2232/// Request to resolve the effective permission set for one principal.
2233#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2234pub struct ResolvePrincipalPermissionsRequest {
2235    /// UUID of the subject whose permissions are being resolved (user or
2236    /// principal identifier).
2237    #[prost(string, tag="1")]
2238    pub subject: ::prost::alloc::string::String,
2239    /// Organization the resolution is scoped to.
2240    #[prost(string, tag="2")]
2241    pub org_id: ::prost::alloc::string::String,
2242    /// Kind of principal identified by `subject`.
2243    #[prost(enumeration="PrincipalType", tag="3")]
2244    pub principal_type: i32,
2245}
2246/// Effective permissions resolved for the requested principal.
2247#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2248pub struct ResolvePrincipalPermissionsResponse {
2249    /// Flattened, deduplicated set of permissions granted to the principal in
2250    /// the requested organization. Empty when the principal has no grants.
2251    #[prost(enumeration="Permission", repeated, tag="1")]
2252    pub permissions: ::prost::alloc::vec::Vec<i32>,
2253}
2254/// Request to check the current suspension state of one organization.
2255#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2256pub struct CheckOrgSuspendedRequest {
2257    /// Organization whose suspension state is being checked.
2258    #[prost(string, tag="1")]
2259    pub org_id: ::prost::alloc::string::String,
2260}
2261/// Current suspension state of the requested organization.
2262#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
2263pub struct CheckOrgSuspendedResponse {
2264    /// True when the organization is currently suspended.
2265    #[prost(bool, tag="1")]
2266    pub suspended: bool,
2267}
2268// ─── Enums ──────────────────────────────────────────────────────────────────
2269
2270/// Kind of principal whose permissions are being resolved.
2271#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2272#[repr(i32)]
2273pub enum PrincipalType {
2274    Unspecified = 0,
2275    /// An end user identified by their user UUID, scoped to one organization.
2276    User = 1,
2277    /// An organization acting as its own principal (e.g. a service identity
2278    /// operating on behalf of the whole org rather than a member).
2279    Org = 2,
2280    /// A platform staff principal whose permissions derive from a role within
2281    /// the ORG_TYPE_STAFF organization.
2282    Staff = 3,
2283}
2284impl PrincipalType {
2285    /// String value of the enum field names used in the ProtoBuf definition.
2286    ///
2287    /// The values are not transformed in any way and thus are considered stable
2288    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2289    pub fn as_str_name(&self) -> &'static str {
2290        match self {
2291            Self::Unspecified => "PRINCIPAL_TYPE_UNSPECIFIED",
2292            Self::User => "PRINCIPAL_TYPE_USER",
2293            Self::Org => "PRINCIPAL_TYPE_ORG",
2294            Self::Staff => "PRINCIPAL_TYPE_STAFF",
2295        }
2296    }
2297    /// Creates an enum from field names used in the ProtoBuf definition.
2298    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2299        match value {
2300            "PRINCIPAL_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2301            "PRINCIPAL_TYPE_USER" => Some(Self::User),
2302            "PRINCIPAL_TYPE_ORG" => Some(Self::Org),
2303            "PRINCIPAL_TYPE_STAFF" => Some(Self::Staff),
2304            _ => None,
2305        }
2306    }
2307}
2308// ─── Messages ───────────────────────────────────────────────────────────────
2309
2310/// A campaign that delivers structured messages to a set of recipients
2311/// and tracks their engagement through a workflow.
2312#[derive(Clone, PartialEq, ::prost::Message)]
2313pub struct Campaign {
2314    /// Unique identifier for the campaign.
2315    /// Constraints: UUID format (36 characters).
2316    #[prost(string, tag="1")]
2317    pub id: ::prost::alloc::string::String,
2318    /// Human-readable campaign name.
2319    /// Constraints: Max length 200 characters.
2320    #[prost(string, tag="2")]
2321    pub name: ::prost::alloc::string::String,
2322    /// ID of the template used to render messages.
2323    /// Constraints: UUID format (36 characters).
2324    #[prost(string, tag="3")]
2325    pub template_id: ::prost::alloc::string::String,
2326    /// Pinned version of the template used for this campaign.
2327    #[prost(int32, tag="4")]
2328    pub template_version: i32,
2329    /// Object storage reference to the audience snapshot taken at campaign creation.
2330    #[prost(string, tag="5")]
2331    pub audience_snapshot_ref: ::prost::alloc::string::String,
2332    /// Current lifecycle status of the campaign.
2333    #[prost(enumeration="CampaignStatus", tag="6")]
2334    pub status: i32,
2335    /// Workflow DAG that drives the campaign's automation logic.
2336    #[prost(message, optional, tag="7")]
2337    pub workflow: ::core::option::Option<WorkflowDefinition>,
2338    /// Total number of recipients in the audience snapshot.
2339    #[prost(int32, tag="8")]
2340    pub total_recipients: i32,
2341    /// Number of recipients who completed the required action.
2342    #[prost(int32, tag="9")]
2343    pub action_completed_count: i32,
2344    /// Number of recipients who did not act before the deadline.
2345    #[prost(int32, tag="10")]
2346    pub missed_count: i32,
2347    /// Timestamp when the campaign was created.
2348    #[prost(message, optional, tag="11")]
2349    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2350    /// Timestamp when the campaign was started (workflow execution began).
2351    #[prost(message, optional, tag="12")]
2352    pub started_at: ::core::option::Option<::prost_types::Timestamp>,
2353    /// Timestamp when the campaign finished (completed, failed, or cancelled).
2354    #[prost(message, optional, tag="13")]
2355    pub completed_at: ::core::option::Option<::prost_types::Timestamp>,
2356    /// Display name of the sender shown to recipients (e.g. "HR Team").
2357    /// Constraints: Max length 200 characters.
2358    #[prost(string, tag="14")]
2359    pub sender_name: ::prost::alloc::string::String,
2360    /// Optional user-facing title override. If set, takes precedence over the template title.
2361    /// Constraints: Max length 200 characters.
2362    #[prost(string, tag="15")]
2363    pub title: ::prost::alloc::string::String,
2364    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
2365    #[prost(bool, tag="16")]
2366    pub critical: bool,
2367    /// Optional locale override for all recipients in this campaign.
2368    /// When set, all recipients receive the campaign in this locale regardless of
2369    /// their preferred_locale. Empty means per-recipient locale resolution.
2370    /// Valid values: en, es, pt-BR, zh, ja.
2371    #[prost(string, tag="17")]
2372    pub default_locale: ::prost::alloc::string::String,
2373    /// Whether the campaign deadline waits for users without registered devices.
2374    /// When true, NO_DEVICE users remain in pending_count and can acknowledge
2375    /// via inbox after installing the app. Default false preserves current behavior.
2376    #[prost(bool, tag="18")]
2377    pub wait_for_enrollment: bool,
2378    /// Optional. Set when the campaign was created from a Compass archetype CTA.
2379    /// Drives post-campaign archetype-response analytics.
2380    #[prost(message, optional, tag="19")]
2381    pub originating_archetype: ::core::option::Option<CampaignOriginatingArchetype>,
2382    /// True when this campaign contains synthetic (artificially injected) data —
2383    /// created or populated for demos, sandbox testing, or issue reproduction.
2384    #[prost(bool, tag="20")]
2385    pub synthetic: bool,
2386    /// Number of recipients frozen in the audience snapshot at creation time.
2387    /// Unlike total_recipients (which counts deliveries and is 0 until the
2388    /// campaign starts), this is known as soon as the campaign exists.
2389    /// 0 when the campaign predates snapshot-size tracking.
2390    #[prost(int32, tag="21")]
2391    pub audience_snapshot_size: i32,
2392    /// Number of members currently eligible for this campaign's audience,
2393    /// computed at read time. Compare with audience_snapshot_size to see how far
2394    /// the frozen audience has drifted from the present membership.
2395    #[prost(int32, tag="22")]
2396    pub current_audience_size: i32,
2397    /// True when the frozen audience no longer covers the current eligible
2398    /// membership (current_audience_size > audience_snapshot_size). Clients
2399    /// should surface this before the campaign is started: recipients added
2400    /// after creation are NOT reached unless the campaign is recreated.
2401    #[prost(bool, tag="23")]
2402    pub audience_snapshot_stale: bool,
2403    /// Live execution position of the campaign's workflow. Unset until the
2404    /// campaign starts and after it reaches a terminal state. Distinct from
2405    /// per-recipient delivery state: this reports which workflow step the
2406    /// engine is executing (or waiting on), independent of whether any
2407    /// recipient has acted.
2408    #[prost(message, optional, tag="24")]
2409    pub workflow_progress: ::core::option::Option<CampaignWorkflowProgress>,
2410    /// Objectives this campaign serves, as declared at creation or linked
2411    /// afterwards. Empty is allowed and carries no penalty: a campaign
2412    /// with no declared objective behaves exactly like one that predates
2413    /// objectives entirely.
2414    #[prost(string, repeated, tag="25")]
2415    pub objective_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2416}
2417/// Live execution position of a running campaign's workflow, recorded by
2418/// the campaign worker as steps transition. Lets clients render true
2419/// engine progress (e.g. "waiting on a deadline until T") instead of
2420/// inferring it from recipient delivery activity, which never observes
2421/// timer-only steps.
2422#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2423pub struct CampaignWorkflowProgress {
2424    /// Workflow-definition step id (WorkflowStep.id) currently executing or
2425    /// being waited on.
2426    #[prost(string, tag="1")]
2427    pub current_step_id: ::prost::alloc::string::String,
2428    /// When the workflow entered the current step.
2429    #[prost(message, optional, tag="2")]
2430    pub step_entered_at: ::core::option::Option<::prost_types::Timestamp>,
2431    /// For timer-backed steps (e.g. deadline checks): when the pending timer
2432    /// fires. Unset for steps that complete without waiting.
2433    #[prost(message, optional, tag="3")]
2434    pub next_wake_at: ::core::option::Option<::prost_types::Timestamp>,
2435}
2436/// Identifies the archetype that motivated the creation of a campaign.
2437/// The audience is NOT filtered by archetype membership — this is metadata
2438/// about the campaign's authoring intent only. See OpenSpec change
2439/// archetype-targeted-campaign-cta.
2440#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2441pub struct CampaignOriginatingArchetype {
2442    /// UUID of the group whose archetype set the label belongs to.
2443    #[prost(string, tag="1")]
2444    pub group_id: ::prost::alloc::string::String,
2445    /// Stable archetype label (e.g., "Swift Acknowledger"). Labels are stable
2446    /// across clustering retrains; archetype IDs are not.
2447    #[prost(string, tag="2")]
2448    pub archetype_label: ::prost::alloc::string::String,
2449}
2450/// A single audience member with optional per-user template variables.
2451#[derive(Clone, PartialEq, ::prost::Message)]
2452pub struct AudienceMember {
2453    /// User ID (UUID).
2454    #[prost(string, tag="1")]
2455    pub user_id: ::prost::alloc::string::String,
2456    /// Template variable values for this user (e.g. {"name": "Alice"}).
2457    #[prost(map="string, string", tag="2")]
2458    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
2459}
2460/// Request to create a new campaign.
2461#[derive(Clone, PartialEq, ::prost::Message)]
2462pub struct CreateCampaignRequest {
2463    /// Human-readable campaign name (admin-facing label).
2464    /// Constraints: Max length 200 characters.
2465    #[prost(string, tag="1")]
2466    pub name: ::prost::alloc::string::String,
2467    /// ID of the template to use for rendering messages.
2468    /// Constraints: UUID format (36 characters).
2469    #[prost(string, tag="2")]
2470    pub template_id: ::prost::alloc::string::String,
2471    /// Version of the template to pin for this campaign.
2472    #[prost(int32, tag="3")]
2473    pub template_version: i32,
2474    /// List of user IDs that form the campaign audience.
2475    /// Constraints: Max 100000 items.
2476    #[prost(string, repeated, tag="4")]
2477    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2478    /// Workflow DAG defining the campaign's automation steps.
2479    /// Required: CreateCampaign rejects a request with no workflow
2480    /// (INVALID_ARGUMENT) and does not substitute a default. The definition
2481    /// MUST validate as an acyclic graph of well-formed steps.
2482    #[prost(message, optional, tag="5")]
2483    pub workflow: ::core::option::Option<WorkflowDefinition>,
2484    /// Display name of the sender shown to recipients (e.g. "HR Team").
2485    /// Constraints: Max length 200 characters.
2486    #[prost(string, tag="6")]
2487    pub sender_name: ::prost::alloc::string::String,
2488    /// Optional user-facing title override. If empty, the template title is used.
2489    /// Constraints: Max length 200 characters.
2490    #[prost(string, tag="7")]
2491    pub title: ::prost::alloc::string::String,
2492    /// Rich audience with per-user template variables.
2493    /// When set, takes precedence over user_ids.
2494    /// Constraints: Max 100000 items.
2495    #[prost(message, repeated, tag="8")]
2496    pub audience: ::prost::alloc::vec::Vec<AudienceMember>,
2497    /// Whether to include users with processing_restricted=true in the audience.
2498    /// Default false: restricted users are excluded. Set true only with Art. 18(2) legal basis.
2499    #[prost(bool, tag="9")]
2500    pub include_restricted: bool,
2501    /// Whether this campaign's notifications break through Do Not Disturb / Focus mode.
2502    #[prost(bool, tag="10")]
2503    pub critical: bool,
2504    /// Optional locale override for all recipients.
2505    #[prost(string, tag="11")]
2506    pub default_locale: ::prost::alloc::string::String,
2507    /// Whether the campaign deadline should wait for users without registered devices.
2508    /// When true, NO_DEVICE users are not decremented from pending_count,
2509    /// allowing them to acknowledge via inbox after installing the app.
2510    #[prost(bool, tag="12")]
2511    pub wait_for_enrollment: bool,
2512    /// Optional. Set when the campaign is created from a Compass archetype CTA.
2513    /// The server validates the caller has access to group_id and that
2514    /// archetype_label exists in the group's current archetype set; cross-org
2515    /// group_id returns PERMISSION_DENIED, unknown label returns NOT_FOUND.
2516    #[prost(message, optional, tag="13")]
2517    pub originating_archetype: ::core::option::Option<CampaignOriginatingArchetype>,
2518    /// Objectives this campaign serves. Declaring the objective at
2519    /// creation is the point at which a response rate stops being the
2520    /// result and becomes evidence about something the organization was
2521    /// trying to achieve. Empty is allowed and changes nothing about how
2522    /// the campaign runs. Unknown or cross-org IDs return NOT_FOUND.
2523    #[prost(string, repeated, tag="14")]
2524    pub objective_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2525}
2526/// Response after creating a campaign.
2527#[derive(Clone, PartialEq, ::prost::Message)]
2528pub struct CreateCampaignResponse {
2529    /// The newly created campaign.
2530    #[prost(message, optional, tag="1")]
2531    pub campaign: ::core::option::Option<Campaign>,
2532}
2533/// Request to start a campaign's workflow execution.
2534#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2535pub struct StartCampaignRequest {
2536    /// ID of the campaign to start.
2537    /// Constraints: UUID format (36 characters).
2538    #[prost(string, tag="1")]
2539    pub campaign_id: ::prost::alloc::string::String,
2540}
2541/// Response after starting a campaign.
2542#[derive(Clone, PartialEq, ::prost::Message)]
2543pub struct StartCampaignResponse {
2544    /// The campaign with updated status.
2545    #[prost(message, optional, tag="1")]
2546    pub campaign: ::core::option::Option<Campaign>,
2547}
2548/// Request to retrieve a single campaign by ID.
2549#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2550pub struct GetCampaignRequest {
2551    /// ID of the campaign to retrieve.
2552    /// Constraints: UUID format (36 characters).
2553    #[prost(string, tag="1")]
2554    pub campaign_id: ::prost::alloc::string::String,
2555}
2556/// Response containing the requested campaign.
2557#[derive(Clone, PartialEq, ::prost::Message)]
2558pub struct GetCampaignResponse {
2559    /// The requested campaign.
2560    #[prost(message, optional, tag="1")]
2561    pub campaign: ::core::option::Option<Campaign>,
2562}
2563/// Request to list campaigns with pagination.
2564#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2565pub struct ListCampaignsRequest {
2566    /// Pagination parameters.
2567    #[prost(message, optional, tag="1")]
2568    pub pagination: ::core::option::Option<Pagination>,
2569}
2570/// Response containing a page of campaigns.
2571#[derive(Clone, PartialEq, ::prost::Message)]
2572pub struct ListCampaignsResponse {
2573    /// List of campaigns in this page.
2574    #[prost(message, repeated, tag="1")]
2575    pub campaigns: ::prost::alloc::vec::Vec<Campaign>,
2576    /// Pagination metadata for fetching subsequent pages.
2577    #[prost(message, optional, tag="2")]
2578    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2579}
2580/// Request to cancel a running campaign.
2581#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2582pub struct CancelCampaignRequest {
2583    /// ID of the campaign to cancel.
2584    /// Constraints: UUID format (36 characters).
2585    #[prost(string, tag="1")]
2586    pub campaign_id: ::prost::alloc::string::String,
2587}
2588/// Response after cancelling a campaign.
2589#[derive(Clone, PartialEq, ::prost::Message)]
2590pub struct CancelCampaignResponse {
2591    /// The campaign with updated status (CANCELLED).
2592    #[prost(message, optional, tag="1")]
2593    pub campaign: ::core::option::Option<Campaign>,
2594}
2595/// Request to update a draft campaign (status must be CREATED).
2596/// Only non-empty/non-zero fields are updated; omitted fields remain unchanged.
2597#[derive(Clone, PartialEq, ::prost::Message)]
2598pub struct UpdateCampaignRequest {
2599    /// ID of the campaign to update.
2600    /// Constraints: UUID format (36 characters).
2601    #[prost(string, tag="1")]
2602    pub campaign_id: ::prost::alloc::string::String,
2603    /// Updated campaign name. Empty string means no change.
2604    /// Constraints: Max length 200 characters.
2605    #[prost(string, tag="2")]
2606    pub name: ::prost::alloc::string::String,
2607    /// Updated sender display name. Empty string means no change.
2608    /// Constraints: Max length 200 characters.
2609    #[prost(string, tag="3")]
2610    pub sender_name: ::prost::alloc::string::String,
2611    /// Updated title override. Empty string means no change.
2612    /// Constraints: Max length 200 characters.
2613    #[prost(string, tag="4")]
2614    pub title: ::prost::alloc::string::String,
2615    /// Updated template ID. Empty string means no change.
2616    /// Constraints: UUID format (36 characters).
2617    #[prost(string, tag="5")]
2618    pub template_id: ::prost::alloc::string::String,
2619    /// Updated template version. Zero means no change.
2620    #[prost(int32, tag="6")]
2621    pub template_version: i32,
2622    /// Updated workflow DAG. Null/omitted means no change.
2623    #[prost(message, optional, tag="7")]
2624    pub workflow: ::core::option::Option<WorkflowDefinition>,
2625    /// Replaces the campaign's frozen audience snapshot. Omitted means no
2626    /// change; PRESENT means replace — including with an empty member list
2627    /// (a campaign with no recipients is a valid state). The wrapper message
2628    /// exists exactly for that presence distinction, which a bare repeated
2629    /// field cannot express. Only valid while the campaign is in CREATED
2630    /// status; the server rejects the replacement once the campaign has
2631    /// started, since deliveries were already created from the old snapshot.
2632    #[prost(message, optional, tag="8")]
2633    pub audience_replacement: ::core::option::Option<AudienceReplacement>,
2634}
2635/// A full replacement for a campaign's frozen audience. Presence of this
2636/// message (not its member count) signals the replace intent.
2637#[derive(Clone, PartialEq, ::prost::Message)]
2638pub struct AudienceReplacement {
2639    /// The new complete audience. Replaces the previous snapshot wholesale.
2640    #[prost(message, repeated, tag="1")]
2641    pub members: ::prost::alloc::vec::Vec<AudienceMember>,
2642}
2643/// Response after updating a campaign.
2644#[derive(Clone, PartialEq, ::prost::Message)]
2645pub struct UpdateCampaignResponse {
2646    /// The campaign with updated fields.
2647    #[prost(message, optional, tag="1")]
2648    pub campaign: ::core::option::Option<Campaign>,
2649}
2650/// Request to read a campaign's frozen audience snapshot.
2651#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2652pub struct GetCampaignAudienceRequest {
2653    /// ID of the campaign whose audience to read.
2654    /// Constraints: UUID format (36 characters).
2655    #[prost(string, tag="1")]
2656    pub campaign_id: ::prost::alloc::string::String,
2657}
2658/// One member of a campaign's frozen audience, enriched with the identity
2659/// fields a client needs to render the member without further lookups.
2660#[derive(Clone, PartialEq, ::prost::Message)]
2661pub struct CampaignAudienceEntry {
2662    /// The frozen audience row exactly as it will be delivered to: user id
2663    /// plus per-user template variables.
2664    #[prost(message, optional, tag="1")]
2665    pub member: ::core::option::Option<AudienceMember>,
2666    /// The member's email at read time. Empty when the user no longer
2667    /// resolves (deactivated or erased since the audience was frozen).
2668    #[prost(string, tag="2")]
2669    pub email: ::prost::alloc::string::String,
2670    /// The member's display name at read time. Empty when unresolvable.
2671    #[prost(string, tag="3")]
2672    pub display_name: ::prost::alloc::string::String,
2673    /// False when the user is no longer an active or invited member of the
2674    /// organization — a frozen recipient that would not be reachable today.
2675    #[prost(bool, tag="4")]
2676    pub active: bool,
2677}
2678/// A campaign's frozen audience. Empty when the campaign has no audience
2679/// snapshot (legacy campaigns predating snapshot tracking) or the snapshot
2680/// is empty.
2681#[derive(Clone, PartialEq, ::prost::Message)]
2682pub struct GetCampaignAudienceResponse {
2683    /// The frozen audience, enriched per entry.
2684    #[prost(message, repeated, tag="1")]
2685    pub entries: ::prost::alloc::vec::Vec<CampaignAudienceEntry>,
2686}
2687/// A single delivery record tracking message delivery to one recipient.
2688/// Out-of-band context attached to a delivery beyond its canonical
2689/// recipient + status + content payload. Optional; fields are populated
2690/// per delivery kind. Currently only REMINDER_FYI children carry values,
2691/// to snapshot context from the parent delivery so clients can render
2692/// without fetching additional resources.
2693#[derive(Clone, PartialEq, ::prost::Message)]
2694pub struct DeliveryMetadata {
2695    /// REMINDER_FYI: the rendered Message payload from the parent delivery,
2696    /// used to render the blockquoted "Original message" panel on the
2697    /// notify-target's inbox card.
2698    #[prost(message, optional, tag="1")]
2699    pub original_message: ::core::option::Option<Message>,
2700    /// REMINDER_FYI: display name of the original recipient (the employee
2701    /// who hasn't responded). Used to interpolate the FYI title and banner.
2702    #[prost(string, tag="2")]
2703    pub original_recipient_name: ::prost::alloc::string::String,
2704    /// REMINDER_FYI: campaign title, denormalized so the notify-target's
2705    /// client can render without a separate campaign lookup.
2706    #[prost(string, tag="3")]
2707    pub campaign_title: ::prost::alloc::string::String,
2708    /// REMINDER_FYI: when the parent reminder step fired, used to render
2709    /// the "fired X ago" footer on the FYI card.
2710    #[prost(message, optional, tag="4")]
2711    pub reminder_fired_at: ::core::option::Option<::prost_types::Timestamp>,
2712}
2713#[derive(Clone, PartialEq, ::prost::Message)]
2714pub struct Delivery {
2715    /// Unique identifier for this delivery.
2716    /// Constraints: UUID format (36 characters).
2717    #[prost(string, tag="1")]
2718    pub id: ::prost::alloc::string::String,
2719    /// ID of the recipient user.
2720    /// Constraints: UUID format (36 characters).
2721    #[prost(string, tag="2")]
2722    pub user_id: ::prost::alloc::string::String,
2723    /// ID of the campaign this delivery belongs to.
2724    /// Constraints: UUID format (36 characters).
2725    #[prost(string, tag="3")]
2726    pub campaign_id: ::prost::alloc::string::String,
2727    /// Current delivery status.
2728    #[prost(enumeration="DeliveryStatus", tag="4")]
2729    pub status: i32,
2730    /// Timestamp when the message was delivered to the device.
2731    #[prost(message, optional, tag="5")]
2732    pub delivered_at: ::core::option::Option<::prost_types::Timestamp>,
2733    /// Timestamp when the recipient read the message.
2734    #[prost(message, optional, tag="6")]
2735    pub read_at: ::core::option::Option<::prost_types::Timestamp>,
2736    /// Timestamp when the recipient performed the required action.
2737    #[prost(message, optional, tag="7")]
2738    pub acted_at: ::core::option::Option<::prost_types::Timestamp>,
2739    /// Email address of the recipient, populated from the users table on read.
2740    #[prost(string, tag="8")]
2741    pub recipient_email: ::prost::alloc::string::String,
2742    /// Discriminator distinguishing primary recipient deliveries from
2743    /// deliveries generated by downstream workflow steps.
2744    #[prost(enumeration="delivery::Kind", tag="12")]
2745    pub kind: i32,
2746    /// For non-primary deliveries, the UUID of the originating delivery this
2747    /// row was derived from. Empty for primary deliveries.
2748    /// Constraints: UUID format (36 characters) when set.
2749    #[prost(string, tag="13")]
2750    pub parent_delivery_id: ::prost::alloc::string::String,
2751    /// The locale this delivery's body was actually rendered in after fallback
2752    /// resolution (recipient preference, campaign override, template default).
2753    /// Valid values: en, es, pt-BR, zh, ja.
2754    #[prost(string, tag="14")]
2755    pub rendered_locale: ::prost::alloc::string::String,
2756    /// Optional out-of-band context. See `DeliveryMetadata` for which
2757    /// delivery kinds populate which fields. Empty for legacy / PRIMARY
2758    /// deliveries.
2759    #[prost(message, optional, tag="15")]
2760    pub metadata: ::core::option::Option<DeliveryMetadata>,
2761    /// True when this delivery's outcome is synthetic (artificially injected)
2762    /// data rather than the result of a real delivery and user response.
2763    #[prost(bool, tag="9")]
2764    pub synthetic: bool,
2765}
2766/// Nested message and enum types in `Delivery`.
2767pub mod delivery {
2768    /// Discriminator describing what produced this delivery row.
2769    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2770    #[repr(i32)]
2771    pub enum Kind {
2772        /// Default value; not a valid kind.
2773        Unspecified = 0,
2774        /// Delivery generated for an audience recipient at campaign start.
2775        Primary = 1,
2776        /// Delivery generated by an escalation step targeting a non-audience user.
2777        Escalation = 2,
2778        /// Passive heads-up delivery generated when a reminder step fans out to
2779        /// its `notify_targets`. Carries no action button; auto-dismisses when
2780        /// the parent delivery is acknowledged. See
2781        /// `SendReminderConfig.notify_targets`.
2782        ReminderFyi = 3,
2783    }
2784    impl Kind {
2785        /// String value of the enum field names used in the ProtoBuf definition.
2786        ///
2787        /// The values are not transformed in any way and thus are considered stable
2788        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2789        pub fn as_str_name(&self) -> &'static str {
2790            match self {
2791                Self::Unspecified => "KIND_UNSPECIFIED",
2792                Self::Primary => "KIND_PRIMARY",
2793                Self::Escalation => "KIND_ESCALATION",
2794                Self::ReminderFyi => "KIND_REMINDER_FYI",
2795            }
2796        }
2797        /// Creates an enum from field names used in the ProtoBuf definition.
2798        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2799            match value {
2800                "KIND_UNSPECIFIED" => Some(Self::Unspecified),
2801                "KIND_PRIMARY" => Some(Self::Primary),
2802                "KIND_ESCALATION" => Some(Self::Escalation),
2803                "KIND_REMINDER_FYI" => Some(Self::ReminderFyi),
2804                _ => None,
2805            }
2806        }
2807    }
2808}
2809/// Request to list deliveries for a campaign with optional status filtering.
2810#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2811pub struct ListDeliveriesRequest {
2812    /// ID of the campaign to list deliveries for.
2813    /// Constraints: UUID format (36 characters).
2814    #[prost(string, tag="1")]
2815    pub campaign_id: ::prost::alloc::string::String,
2816    /// Optional filter by delivery status. UNSPECIFIED returns all.
2817    #[prost(enumeration="DeliveryStatus", tag="2")]
2818    pub status_filter: i32,
2819    /// Pagination parameters.
2820    #[prost(message, optional, tag="3")]
2821    pub pagination: ::core::option::Option<Pagination>,
2822}
2823/// Response containing a page of delivery records.
2824#[derive(Clone, PartialEq, ::prost::Message)]
2825pub struct ListDeliveriesResponse {
2826    /// List of deliveries in this page.
2827    #[prost(message, repeated, tag="1")]
2828    pub deliveries: ::prost::alloc::vec::Vec<Delivery>,
2829    /// Pagination metadata for fetching subsequent pages.
2830    #[prost(message, optional, tag="2")]
2831    pub pagination_meta: ::core::option::Option<PaginationMeta>,
2832}
2833/// Request to compute the archetype-tendency-shift surface for a campaign:
2834/// how each archetype's share of the originating group has moved between
2835/// the snapshot closest to campaign-creation time and the most recent
2836/// snapshot. Only valid for campaigns whose originating_archetype is set.
2837#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2838pub struct GetCampaignArchetypeBreakdownRequest {
2839    /// ID of the campaign to break down.
2840    /// Constraints: UUID format (36 characters).
2841    #[prost(string, tag="1")]
2842    pub campaign_id: ::prost::alloc::string::String,
2843}
2844/// Movement in one archetype's share of the originating group between the
2845/// "before" and "after" archetype-clustering snapshots. Cohort-level only;
2846/// no joining to user identity. The `is_origin` row is the archetype the
2847/// campaign was authored for.
2848#[derive(Clone, PartialEq, ::prost::Message)]
2849pub struct ArchetypeShareShift {
2850    /// Stable archetype label, e.g. "Swift Acknowledger".
2851    #[prost(string, tag="1")]
2852    pub label: ::prost::alloc::string::String,
2853    /// Archetype's share of the group at the snapshot closest to (but not
2854    /// after) the campaign's created_at. Range 0.0 – 1.0.
2855    #[prost(double, tag="2")]
2856    pub share_before: f64,
2857    /// Archetype's share of the group at the most recent snapshot. Range
2858    /// 0.0 – 1.0. Equals share_before when no clustering has run since.
2859    #[prost(double, tag="3")]
2860    pub share_after: f64,
2861    /// True when this row's label matches the campaign's
2862    /// originating_archetype.archetype_label.
2863    #[prost(bool, tag="4")]
2864    pub is_origin: bool,
2865    /// Count of email DELIVERED events recorded for this archetype's members
2866    /// across the campaign window. Denominator for both open-rate fields.
2867    #[prost(uint64, tag="5")]
2868    pub email_delivered_count: u64,
2869    /// Open rate excluding events flagged as Apple-MPP prefetches
2870    /// (prefetch_suspected=true). Range 0.0 – 1.0.
2871    #[prost(double, tag="6")]
2872    pub email_open_rate_real: f64,
2873    /// Open rate including all OPENED events, prefetches included.
2874    /// Range 0.0 – 1.0.
2875    #[prost(double, tag="7")]
2876    pub email_open_rate_raw: f64,
2877}
2878/// Response containing per-archetype share shifts. The admin renders
2879/// these as a comparison table — origin row marked, others as peers, so
2880/// the admin can tell campaign-coincident drift apart from background
2881/// drift across the rest of the group.
2882#[derive(Clone, PartialEq, ::prost::Message)]
2883pub struct GetCampaignArchetypeBreakdownResponse {
2884    /// One entry per archetype in the originating group. Empty when
2885    /// insufficient_history is true.
2886    #[prost(message, repeated, tag="1")]
2887    pub shifts: ::prost::alloc::vec::Vec<ArchetypeShareShift>,
2888    /// When the "before" sample was taken (closest snapshot at or before
2889    /// campaign creation).
2890    #[prost(message, optional, tag="2")]
2891    pub before_snapshot_at: ::core::option::Option<::prost_types::Timestamp>,
2892    /// When the "after" sample was taken (most recent snapshot).
2893    #[prost(message, optional, tag="3")]
2894    pub after_snapshot_at: ::core::option::Option<::prost_types::Timestamp>,
2895    /// True when fewer than two clustering snapshots exist for the group,
2896    /// so no shift can be computed yet. Admin renders an "awaiting next
2897    /// clustering cycle" empty state.
2898    #[prost(bool, tag="4")]
2899    pub insufficient_history: bool,
2900}
2901// ─── Short-code messages ────────────────────────────────────────────────────
2902
2903/// Request to resolve a campaign's short-code, lazily generating one on
2904/// first call. Used by internal-service callers (the dispatch layer)
2905/// when assembling a third-party-channel deeplink:
2906/// `links.pidgr.com/c/{short_code}?t={token}`.
2907#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2908pub struct ResolveOrCreateShortCodeRequest {
2909    /// The campaign whose short-code is being resolved.
2910    /// Constraints: Required, must be a UUID and exist within the caller's organization.
2911    #[prost(string, tag="1")]
2912    pub campaign_id: ::prost::alloc::string::String,
2913}
2914/// Response carrying the resolved short-code. The same campaign always
2915/// resolves to the same code for its lifetime; the value is safe to
2916/// cache by the caller.
2917#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2918pub struct ResolveOrCreateShortCodeResponse {
2919    /// 8-character base62 short-code stable for the campaign's lifetime.
2920    #[prost(string, tag="1")]
2921    pub short_code: ::prost::alloc::string::String,
2922}
2923/// Request to look up a campaign by its public short-code. Called by the
2924/// native app when the recipient taps a third-party-channel deeplink and
2925/// the URL handler needs to route to the right campaign card. Designed to
2926/// be safe to call without authentication — the response carries no PII
2927/// and only enough context for the app to route correctly and show org
2928/// branding before the auth gate.
2929#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2930pub struct GetCampaignByShortCodeRequest {
2931    /// The 8-character short-code from the deeplink path.
2932    /// Constraints: Required, exactly 8 base62 characters.
2933    #[prost(string, tag="1")]
2934    pub short_code: ::prost::alloc::string::String,
2935}
2936/// Response carrying the minimum metadata the native app needs to route
2937/// the deeplink. Subject is the campaign's title text (already visible
2938/// in the recipient's inbox after dispatch — no new PII exposure). Body
2939/// content, audience size, delivery status and any other operational
2940/// fields are NOT included; the app fetches those via authenticated
2941/// `GetCampaign` after the recipient signs in.
2942#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2943pub struct GetCampaignByShortCodeResponse {
2944    /// Campaign UUID — the app uses this for the authenticated `GetCampaign`
2945    /// follow-up after the deeplink token validates.
2946    #[prost(string, tag="1")]
2947    pub campaign_id: ::prost::alloc::string::String,
2948    /// Organization UUID owning the campaign — lets the app pick the
2949    /// correct SSO / sign-in flow when the recipient is logged out.
2950    #[prost(string, tag="2")]
2951    pub org_id: ::prost::alloc::string::String,
2952    /// Display name of the organization for sign-in branding ("Sign in to
2953    /// Acme Inc to view this campaign"). Public information; the
2954    /// organization's profile already exposes it elsewhere.
2955    #[prost(string, tag="3")]
2956    pub organization_name: ::prost::alloc::string::String,
2957    /// Campaign subject (title). Same string the recipient already saw in
2958    /// their inbox; included so the deeplink interstitial can show
2959    /// "Acme Inc — All-hands Q3" before the auth gate.
2960    #[prost(string, tag="4")]
2961    pub subject: ::prost::alloc::string::String,
2962}
2963// ─── Messages ───────────────────────────────────────────────────────────────
2964
2965/// A registered device that can receive push notifications.
2966/// INTERNAL: This message is for server-side use only. Use DeviceSummary for API responses.
2967#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2968pub struct Device {
2969    /// Unique identifier for this device.
2970    /// Constraints: UUID format (36 characters).
2971    #[prost(string, tag="1")]
2972    pub device_id: ::prost::alloc::string::String,
2973    /// ID of the user who owns this device.
2974    /// Constraints: UUID format (36 characters).
2975    #[prost(string, tag="2")]
2976    pub user_id: ::prost::alloc::string::String,
2977    /// Mobile platform (iOS or Android).
2978    #[prost(enumeration="Platform", tag="3")]
2979    pub platform: i32,
2980    /// Push token used to send notifications to this device.
2981    #[prost(string, tag="4")]
2982    pub push_token: ::prost::alloc::string::String,
2983    /// Whether the device is currently active and eligible for push delivery.
2984    #[prost(bool, tag="5")]
2985    pub active: bool,
2986    /// Timestamp of the last activity from this device.
2987    #[prost(message, optional, tag="6")]
2988    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
2989    /// Timestamp when the device was first registered.
2990    #[prost(message, optional, tag="7")]
2991    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
2992}
2993/// A device summary safe for API responses — excludes sensitive push_token.
2994#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
2995pub struct DeviceSummary {
2996    /// Unique identifier for this device.
2997    #[prost(string, tag="1")]
2998    pub device_id: ::prost::alloc::string::String,
2999    /// ID of the user who owns this device.
3000    #[prost(string, tag="2")]
3001    pub user_id: ::prost::alloc::string::String,
3002    /// Mobile platform (iOS or Android).
3003    #[prost(enumeration="Platform", tag="3")]
3004    pub platform: i32,
3005    /// Whether the device is currently active and eligible for push delivery.
3006    #[prost(bool, tag="4")]
3007    pub active: bool,
3008    /// Timestamp of the last activity from this device.
3009    #[prost(message, optional, tag="5")]
3010    pub last_seen: ::core::option::Option<::prost_types::Timestamp>,
3011    /// Timestamp when the device was first registered.
3012    #[prost(message, optional, tag="6")]
3013    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3014}
3015/// Request to register a device for push notifications.
3016#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3017pub struct RegisterRequest {
3018    /// Client-generated unique device identifier.
3019    /// Constraints: UUID format (36 characters).
3020    #[prost(string, tag="1")]
3021    pub device_id: ::prost::alloc::string::String,
3022    /// Mobile platform of the device.
3023    #[prost(enumeration="Platform", tag="2")]
3024    pub platform: i32,
3025    /// Push token obtained from the push notification provider on the client.
3026    /// Constraints: Max length 4096 characters.
3027    #[prost(string, tag="3")]
3028    pub push_token: ::prost::alloc::string::String,
3029}
3030/// Response after registering a device.
3031#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3032pub struct RegisterResponse {
3033    /// The registered device summary (excludes push_token).
3034    #[prost(message, optional, tag="1")]
3035    pub device: ::core::option::Option<DeviceSummary>,
3036}
3037/// Request to deactivate a device, stopping push notifications.
3038#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3039pub struct DeactivateRequest {
3040    /// ID of the device to deactivate.
3041    /// Constraints: UUID format (36 characters).
3042    #[prost(string, tag="1")]
3043    pub device_id: ::prost::alloc::string::String,
3044}
3045/// Response after deactivating a device.
3046#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3047pub struct DeactivateResponse {
3048    /// Whether the device was successfully deactivated.
3049    #[prost(bool, tag="1")]
3050    pub success: bool,
3051}
3052/// Request to list all devices for the authenticated user.
3053#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3054pub struct ListDevicesRequest {
3055}
3056/// Response containing all devices for the user.
3057#[derive(Clone, PartialEq, ::prost::Message)]
3058pub struct ListDevicesResponse {
3059    /// List of devices registered to the authenticated user.
3060    #[prost(message, repeated, tag="1")]
3061    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
3062}
3063/// Request to list devices for a specific member (admin use).
3064#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3065pub struct ListMemberDevicesRequest {
3066    /// ID of the user whose devices to list.
3067    /// Constraints: UUID format (36 characters).
3068    #[prost(string, tag="1")]
3069    pub user_id: ::prost::alloc::string::String,
3070}
3071/// Response containing all devices for the specified member.
3072#[derive(Clone, PartialEq, ::prost::Message)]
3073pub struct ListMemberDevicesResponse {
3074    /// List of devices registered to the specified user.
3075    #[prost(message, repeated, tag="1")]
3076    pub devices: ::prost::alloc::vec::Vec<DeviceSummary>,
3077}
3078// ─── Messages ───────────────────────────────────────────────────────────────
3079
3080/// User-configurable platform settings that apply across all clients.
3081/// All fields use their UNSPECIFIED/zero value to mean "no change" in updates.
3082#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3083pub struct UserSettings {
3084    /// Preferred color scheme for the UI.
3085    #[prost(enumeration="ThemePreference", tag="1")]
3086    pub theme_preference: i32,
3087    /// User's preferred language for the UI and push notifications.
3088    /// Empty string means "use organization default" or "auto-detect".
3089    /// Valid values: en, es, pt-BR, zh, ja.
3090    #[prost(string, tag="2")]
3091    pub preferred_locale: ::prost::alloc::string::String,
3092}
3093/// Structured profile attributes for a user within an organization.
3094/// Populated through admin invitation, mobile onboarding, or SSO attribute sync.
3095#[derive(Clone, PartialEq, ::prost::Message)]
3096pub struct UserProfile {
3097    /// User's given name.
3098    /// Constraints: Max length 200 characters.
3099    #[prost(string, tag="1")]
3100    pub first_name: ::prost::alloc::string::String,
3101    /// User's family name.
3102    /// Constraints: Max length 200 characters.
3103    #[prost(string, tag="2")]
3104    pub last_name: ::prost::alloc::string::String,
3105    /// Department or team within the organization.
3106    /// Constraints: Max length 200 characters.
3107    #[prost(string, tag="3")]
3108    pub department: ::prost::alloc::string::String,
3109    /// Job title.
3110    /// Constraints: Max length 200 characters.
3111    #[prost(string, tag="4")]
3112    pub title: ::prost::alloc::string::String,
3113    /// Phone number.
3114    /// Constraints: Max length 200 characters.
3115    #[prost(string, tag="5")]
3116    pub phone: ::prost::alloc::string::String,
3117    /// Office or geographic location.
3118    /// Constraints: Max length 200 characters.
3119    #[prost(string, tag="6")]
3120    pub location: ::prost::alloc::string::String,
3121    /// Organization-specific employee identifier.
3122    /// Constraints: Max length 200 characters.
3123    #[prost(string, tag="7")]
3124    pub employee_id: ::prost::alloc::string::String,
3125    /// Display name of the user's direct manager.
3126    /// Constraints: Max length 200 characters.
3127    #[prost(string, tag="8")]
3128    pub manager_name: ::prost::alloc::string::String,
3129    /// Employment start date in ISO 8601 format (YYYY-MM-DD).
3130    /// Constraints: Max length 200 characters.
3131    #[prost(string, tag="9")]
3132    pub start_date: ::prost::alloc::string::String,
3133    /// Organization-defined custom attributes for fields not covered by the fixed schema.
3134    /// Constraints: Max 50 entries. Key max length 100 characters, value max length 1000 characters.
3135    #[prost(map="string, string", tag="10")]
3136    pub custom_attributes: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
3137    /// UUID of the user's direct manager within the same organization.
3138    /// Populated from SCIM enterprise extension (manager.value), manual admin
3139    /// assignment, or SSO attribute mapping. Empty if not set.
3140    #[prost(string, tag="11")]
3141    pub manager_id: ::prost::alloc::string::String,
3142}
3143/// A user within an organization.
3144#[derive(Clone, PartialEq, ::prost::Message)]
3145pub struct User {
3146    /// Unique identifier for the user (internal platform UUID, not identity provider subject ID).
3147    #[prost(string, tag="1")]
3148    pub id: ::prost::alloc::string::String,
3149    /// User's email address.
3150    /// Constraints: Max length 254 characters (RFC 5321).
3151    #[prost(string, tag="2")]
3152    pub email: ::prost::alloc::string::String,
3153    /// User's display name.
3154    /// Constraints: Max length 200 characters.
3155    #[prost(string, tag="3")]
3156    pub name: ::prost::alloc::string::String,
3157    /// Current account status.
3158    #[prost(enumeration="UserStatus", tag="5")]
3159    pub status: i32,
3160    /// Timestamp when the user was created.
3161    #[prost(message, optional, tag="6")]
3162    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3163    /// The user's role with its permission set.
3164    #[prost(message, optional, tag="7")]
3165    pub role: ::core::option::Option<Role>,
3166    /// ID of the user's role (for assignment operations).
3167    #[prost(string, tag="8")]
3168    pub role_id: ::prost::alloc::string::String,
3169    /// Structured profile attributes (department, title, etc.).
3170    /// May be empty if the user has not completed their profile.
3171    #[prost(message, optional, tag="9")]
3172    pub profile: ::core::option::Option<UserProfile>,
3173    /// Whether data processing is restricted for this user (GDPR Art. 18).
3174    /// When true, the user is excluded from campaign audiences by default.
3175    #[prost(bool, tag="10")]
3176    pub processing_restricted: bool,
3177    /// Data governance region override. Empty string means "inherit from org default".
3178    /// Valid values: EU, LATAM, BR, APAC, US.
3179    #[prost(string, tag="11")]
3180    pub data_governance_region: ::prost::alloc::string::String,
3181}
3182// ─── Enums ──────────────────────────────────────────────────────────────────
3183
3184/// Lifecycle status of a user account.
3185#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3186#[repr(i32)]
3187pub enum UserStatus {
3188    /// Default value; not a valid status.
3189    Unspecified = 0,
3190    /// User has been invited but has not completed onboarding.
3191    Invited = 1,
3192    /// User is active and can receive messages.
3193    Active = 2,
3194    /// User has been deactivated and will not receive messages.
3195    Deactivated = 3,
3196}
3197impl UserStatus {
3198    /// String value of the enum field names used in the ProtoBuf definition.
3199    ///
3200    /// The values are not transformed in any way and thus are considered stable
3201    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3202    pub fn as_str_name(&self) -> &'static str {
3203        match self {
3204            Self::Unspecified => "USER_STATUS_UNSPECIFIED",
3205            Self::Invited => "USER_STATUS_INVITED",
3206            Self::Active => "USER_STATUS_ACTIVE",
3207            Self::Deactivated => "USER_STATUS_DEACTIVATED",
3208        }
3209    }
3210    /// Creates an enum from field names used in the ProtoBuf definition.
3211    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3212        match value {
3213            "USER_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
3214            "USER_STATUS_INVITED" => Some(Self::Invited),
3215            "USER_STATUS_ACTIVE" => Some(Self::Active),
3216            "USER_STATUS_DEACTIVATED" => Some(Self::Deactivated),
3217            _ => None,
3218        }
3219    }
3220}
3221/// User's preferred color scheme.
3222#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3223#[repr(i32)]
3224pub enum ThemePreference {
3225    /// Default value; treated as SYSTEM when reading, "no change" when updating.
3226    Unspecified = 0,
3227    /// Always use light mode regardless of system setting.
3228    Light = 1,
3229    /// Always use dark mode regardless of system setting.
3230    Dark = 2,
3231    /// Follow the operating system or browser preference.
3232    System = 3,
3233}
3234impl ThemePreference {
3235    /// String value of the enum field names used in the ProtoBuf definition.
3236    ///
3237    /// The values are not transformed in any way and thus are considered stable
3238    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3239    pub fn as_str_name(&self) -> &'static str {
3240        match self {
3241            Self::Unspecified => "THEME_PREFERENCE_UNSPECIFIED",
3242            Self::Light => "THEME_PREFERENCE_LIGHT",
3243            Self::Dark => "THEME_PREFERENCE_DARK",
3244            Self::System => "THEME_PREFERENCE_SYSTEM",
3245        }
3246    }
3247    /// Creates an enum from field names used in the ProtoBuf definition.
3248    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3249        match value {
3250            "THEME_PREFERENCE_UNSPECIFIED" => Some(Self::Unspecified),
3251            "THEME_PREFERENCE_LIGHT" => Some(Self::Light),
3252            "THEME_PREFERENCE_DARK" => Some(Self::Dark),
3253            "THEME_PREFERENCE_SYSTEM" => Some(Self::System),
3254            _ => None,
3255        }
3256    }
3257}
3258// ─── Messages ───────────────────────────────────────────────────────────────
3259
3260/// A named collection of users within an organization, used for campaign
3261/// audience targeting (recipient groups).
3262#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3263pub struct Group {
3264    /// Unique identifier for the group.
3265    #[prost(string, tag="1")]
3266    pub id: ::prost::alloc::string::String,
3267    /// Human-readable display name (unique within the organization).
3268    /// Constraints: Max length 200 characters.
3269    #[prost(string, tag="2")]
3270    pub name: ::prost::alloc::string::String,
3271    /// Optional description of the group's purpose.
3272    /// Constraints: Max length 1000 characters.
3273    #[prost(string, tag="3")]
3274    pub description: ::prost::alloc::string::String,
3275    /// Number of users currently in the group.
3276    #[prost(int32, tag="4")]
3277    pub member_count: i32,
3278    /// Timestamp when the group was created.
3279    #[prost(message, optional, tag="5")]
3280    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
3281    /// Timestamp when the group was last updated.
3282    #[prost(message, optional, tag="6")]
3283    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
3284    /// Whether this is the organization's default group (cannot be deleted or renamed).
3285    #[prost(bool, tag="7")]
3286    pub is_default: bool,
3287    /// ID of the user who created this group. Empty for system-seeded defaults.
3288    #[prost(string, tag="8")]
3289    pub created_by: ::prost::alloc::string::String,
3290}
3291/// Request to create a new group.
3292#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3293pub struct CreateGroupRequest {
3294    /// Display name for the group. Required.
3295    /// Constraints: Max length 200 characters.
3296    #[prost(string, tag="1")]
3297    pub name: ::prost::alloc::string::String,
3298    /// Optional description.
3299    /// Constraints: Max length 1000 characters.
3300    #[prost(string, tag="2")]
3301    pub description: ::prost::alloc::string::String,
3302}
3303/// Response after creating a group.
3304#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3305pub struct CreateGroupResponse {
3306    /// The newly created group.
3307    #[prost(message, optional, tag="1")]
3308    pub group: ::core::option::Option<Group>,
3309}
3310/// Request to retrieve a group by ID.
3311#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3312pub struct GetGroupRequest {
3313    /// ID of the group to retrieve. Required.
3314    #[prost(string, tag="1")]
3315    pub group_id: ::prost::alloc::string::String,
3316}
3317/// Response containing the requested group.
3318#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3319pub struct GetGroupResponse {
3320    /// The requested group.
3321    #[prost(message, optional, tag="1")]
3322    pub group: ::core::option::Option<Group>,
3323}
3324/// Request to list groups in the organization with pagination.
3325#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3326pub struct ListGroupsRequest {
3327    /// Pagination parameters.
3328    #[prost(message, optional, tag="1")]
3329    pub pagination: ::core::option::Option<Pagination>,
3330}
3331/// Response containing a page of groups.
3332#[derive(Clone, PartialEq, ::prost::Message)]
3333pub struct ListGroupsResponse {
3334    /// Groups in this page.
3335    #[prost(message, repeated, tag="1")]
3336    pub groups: ::prost::alloc::vec::Vec<Group>,
3337    /// Pagination metadata for fetching subsequent pages.
3338    #[prost(message, optional, tag="2")]
3339    pub pagination_meta: ::core::option::Option<PaginationMeta>,
3340}
3341/// Request to update a group's name and/or description.
3342#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3343pub struct UpdateGroupRequest {
3344    /// ID of the group to update. Required.
3345    #[prost(string, tag="1")]
3346    pub group_id: ::prost::alloc::string::String,
3347    /// New display name. If empty, the name is not changed.
3348    /// Default groups cannot be renamed.
3349    /// Constraints: Max length 200 characters.
3350    #[prost(string, tag="2")]
3351    pub name: ::prost::alloc::string::String,
3352    /// New description. If empty, the description is not changed.
3353    /// Constraints: Max length 1000 characters.
3354    #[prost(string, tag="3")]
3355    pub description: ::prost::alloc::string::String,
3356}
3357/// Response after updating a group.
3358#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3359pub struct UpdateGroupResponse {
3360    /// The updated group.
3361    #[prost(message, optional, tag="1")]
3362    pub group: ::core::option::Option<Group>,
3363}
3364/// Request to delete a group.
3365#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3366pub struct DeleteGroupRequest {
3367    /// ID of the group to delete. Required.
3368    /// Default groups cannot be deleted.
3369    #[prost(string, tag="1")]
3370    pub group_id: ::prost::alloc::string::String,
3371}
3372/// Response after deleting a group.
3373#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3374pub struct DeleteGroupResponse {
3375}
3376/// Request to add users to a group.
3377#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3378pub struct AddGroupMembersRequest {
3379    /// ID of the group to add members to. Required.
3380    #[prost(string, tag="1")]
3381    pub group_id: ::prost::alloc::string::String,
3382    /// IDs of users to add. Must belong to the same organization.
3383    /// Adding an existing member is a no-op (idempotent).
3384    /// Constraints: Max 100 user IDs per request.
3385    #[prost(string, repeated, tag="2")]
3386    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3387}
3388/// Response after adding group members.
3389#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3390pub struct AddGroupMembersResponse {
3391    /// The group with updated member_count.
3392    #[prost(message, optional, tag="1")]
3393    pub group: ::core::option::Option<Group>,
3394}
3395/// Request to remove users from a group.
3396#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3397pub struct RemoveGroupMembersRequest {
3398    /// ID of the group to remove members from. Required.
3399    #[prost(string, tag="1")]
3400    pub group_id: ::prost::alloc::string::String,
3401    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
3402    /// Constraints: Max 100 user IDs per request.
3403    #[prost(string, repeated, tag="2")]
3404    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3405}
3406/// Response after removing group members.
3407#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3408pub struct RemoveGroupMembersResponse {
3409    /// The group with updated member_count.
3410    #[prost(message, optional, tag="1")]
3411    pub group: ::core::option::Option<Group>,
3412}
3413/// Request to list members of a group with pagination.
3414#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3415pub struct ListGroupMembersRequest {
3416    /// ID of the group whose members to list. Required.
3417    #[prost(string, tag="1")]
3418    pub group_id: ::prost::alloc::string::String,
3419    /// Pagination parameters.
3420    #[prost(message, optional, tag="2")]
3421    pub pagination: ::core::option::Option<Pagination>,
3422}
3423/// Response containing a page of group members.
3424#[derive(Clone, PartialEq, ::prost::Message)]
3425pub struct ListGroupMembersResponse {
3426    /// Users in this page.
3427    #[prost(message, repeated, tag="1")]
3428    pub users: ::prost::alloc::vec::Vec<User>,
3429    /// Pagination metadata for fetching subsequent pages.
3430    #[prost(message, optional, tag="2")]
3431    pub pagination_meta: ::core::option::Option<PaginationMeta>,
3432}
3433/// A group membership entry for batch lookups.
3434#[derive(Clone, PartialEq, ::prost::Message)]
3435pub struct UserGroupMembership {
3436    /// ID of the user.
3437    #[prost(string, tag="1")]
3438    pub user_id: ::prost::alloc::string::String,
3439    /// Groups the user belongs to.
3440    #[prost(message, repeated, tag="2")]
3441    pub groups: ::prost::alloc::vec::Vec<Group>,
3442}
3443/// Request to get group memberships for a batch of users.
3444#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3445pub struct GetUserGroupMembershipsRequest {
3446    /// IDs of users to look up. Required.
3447    /// Constraints: Max 200 user IDs per request.
3448    #[prost(string, repeated, tag="1")]
3449    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
3450}
3451/// Response containing group memberships for the requested users.
3452#[derive(Clone, PartialEq, ::prost::Message)]
3453pub struct GetUserGroupMembershipsResponse {
3454    /// Group memberships per user. Only users with at least one group are included.
3455    #[prost(message, repeated, tag="1")]
3456    pub memberships: ::prost::alloc::vec::Vec<UserGroupMembership>,
3457}
3458// ─── Messages ───────────────────────────────────────────────────────────────
3459
3460/// A single touch event captured from the mobile app.
3461#[derive(Clone, PartialEq, ::prost::Message)]
3462pub struct TouchEvent {
3463    /// Screen name from React Navigation route.
3464    /// Constraints: Max length 200 characters.
3465    #[prost(string, tag="1")]
3466    pub screen_name: ::prost::alloc::string::String,
3467    /// Horizontal coordinate as a percentage of screen width (0.0–1.0).
3468    /// Constraints: Range 0.0 to 1.0 inclusive.
3469    #[prost(float, tag="2")]
3470    pub x_pct: f32,
3471    /// Vertical coordinate as a percentage of screen height (0.0–1.0).
3472    /// Constraints: Range 0.0 to 1.0 inclusive.
3473    #[prost(float, tag="3")]
3474    pub y_pct: f32,
3475    /// Type of touch event.
3476    #[prost(enumeration="TouchEventType", tag="4")]
3477    pub event_type: i32,
3478    /// Screen width in device pixels at the time of capture.
3479    #[prost(int32, tag="5")]
3480    pub screen_width: i32,
3481    /// Screen height in device pixels at the time of capture.
3482    #[prost(int32, tag="6")]
3483    pub screen_height: i32,
3484    /// Client-side timestamp when the touch occurred.
3485    #[prost(message, optional, tag="7")]
3486    pub client_timestamp: ::core::option::Option<::prost_types::Timestamp>,
3487    /// Campaign ID if the touch occurred during a campaign message view.
3488    /// Empty string for organic (non-campaign) navigation.
3489    #[prost(string, tag="8")]
3490    pub campaign_id: ::prost::alloc::string::String,
3491}
3492/// Request to ingest a batch of touch events from the mobile app.
3493#[derive(Clone, PartialEq, ::prost::Message)]
3494pub struct IngestTouchEventsRequest {
3495    /// Batch of touch events to ingest.
3496    /// Constraints: Max 100 events per batch.
3497    #[prost(message, repeated, tag="1")]
3498    pub events: ::prost::alloc::vec::Vec<TouchEvent>,
3499}
3500/// Response after ingesting touch events.
3501#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3502pub struct IngestTouchEventsResponse {
3503    /// Number of events successfully ingested.
3504    #[prost(int32, tag="1")]
3505    pub ingested_count: i32,
3506}
3507/// A single aggregated data point in a heatmap grid cell.
3508#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3509pub struct HeatmapDataPoint {
3510    /// Grid cell horizontal center as a percentage (0.0–1.0).
3511    #[prost(float, tag="1")]
3512    pub x_pct: f32,
3513    /// Grid cell vertical center as a percentage (0.0–1.0).
3514    #[prost(float, tag="2")]
3515    pub y_pct: f32,
3516    /// Aggregated value for this cell (count, median, or z-score depending on mode).
3517    #[prost(float, tag="3")]
3518    pub value: f32,
3519}
3520/// Request to query aggregated heatmap data for a screen.
3521#[derive(Clone, PartialEq, ::prost::Message)]
3522pub struct QueryHeatmapDataRequest {
3523    /// Screen name to query.
3524    /// Constraints: Max length 200 characters.
3525    #[prost(string, tag="1")]
3526    pub screen_name: ::prost::alloc::string::String,
3527    /// Start of the time range filter (inclusive).
3528    #[prost(message, optional, tag="2")]
3529    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
3530    /// End of the time range filter (inclusive).
3531    #[prost(message, optional, tag="3")]
3532    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
3533    /// Optional: filter by campaign ID.
3534    /// Constraints: UUID format (36 characters).
3535    #[prost(string, tag="4")]
3536    pub campaign_id: ::prost::alloc::string::String,
3537    /// Grid resolution for coordinate rounding. Default: 0.02 (50×50 grid).
3538    /// Constraints: Range 0.005 to 0.1.
3539    #[prost(float, tag="6")]
3540    pub grid_resolution: f32,
3541    /// Aggregation mode (TOTAL or MEDIAN).
3542    #[prost(enumeration="HeatmapMode", tag="7")]
3543    pub mode: i32,
3544    /// Optional: filter by event types. Empty list means all types.
3545    #[prost(enumeration="TouchEventType", repeated, tag="8")]
3546    pub event_types: ::prost::alloc::vec::Vec<i32>,
3547}
3548/// Response containing aggregated heatmap data.
3549#[derive(Clone, PartialEq, ::prost::Message)]
3550pub struct QueryHeatmapDataResponse {
3551    /// Aggregated data points for heatmap rendering.
3552    #[prost(message, repeated, tag="1")]
3553    pub data_points: ::prost::alloc::vec::Vec<HeatmapDataPoint>,
3554    /// URL to a mobile-captured screenshot for this screen, if available.
3555    /// Empty string when no screenshot exists.
3556    #[prost(string, tag="3")]
3557    pub screenshot_url: ::prost::alloc::string::String,
3558    /// Whether per-cohort bucket breakdowns are available (k >= 5).
3559    #[prost(bool, tag="4")]
3560    pub cohort_enabled: bool,
3561}
3562/// Request to upload a screenshot captured from the mobile app.
3563#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3564pub struct UploadScreenshotRequest {
3565    /// Screen name matching React Navigation route (e.g. "MessageDetail::<campaign_uuid>").
3566    /// Constraints: Max length 200 characters.
3567    #[prost(string, tag="1")]
3568    pub screen_name: ::prost::alloc::string::String,
3569    /// App version that captured the screenshot (e.g. "1.15.0").
3570    #[prost(string, tag="2")]
3571    pub app_version: ::prost::alloc::string::String,
3572    /// PNG image data.
3573    /// Constraints: Max 512KB.
3574    #[prost(bytes="vec", tag="3")]
3575    pub image_data: ::prost::alloc::vec::Vec<u8>,
3576}
3577/// Response after uploading a screenshot.
3578#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3579pub struct UploadScreenshotResponse {
3580    /// S3 URL where the screenshot was stored.
3581    #[prost(string, tag="1")]
3582    pub url: ::prost::alloc::string::String,
3583}
3584/// A screen screenshot stored as a static asset.
3585#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3586pub struct ScreenScreenshot {
3587    /// Screen name matching React Navigation route.
3588    #[prost(string, tag="1")]
3589    pub screen_name: ::prost::alloc::string::String,
3590    /// S3 URL to the screenshot image.
3591    #[prost(string, tag="2")]
3592    pub url: ::prost::alloc::string::String,
3593    /// App version this screenshot corresponds to.
3594    #[prost(string, tag="3")]
3595    pub app_version: ::prost::alloc::string::String,
3596}
3597/// Request to list available screen screenshots.
3598#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3599pub struct ListScreenshotsRequest {
3600}
3601/// Response containing available screen screenshots.
3602#[derive(Clone, PartialEq, ::prost::Message)]
3603pub struct ListScreenshotsResponse {
3604    /// Available screen screenshots with their URLs and versions.
3605    #[prost(message, repeated, tag="1")]
3606    pub screenshots: ::prost::alloc::vec::Vec<ScreenScreenshot>,
3607}
3608// ─── Enums ──────────────────────────────────────────────────────────────────
3609
3610/// Type of touch event captured on the mobile app.
3611#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3612#[repr(i32)]
3613pub enum TouchEventType {
3614    /// Default value; not a valid event type.
3615    Unspecified = 0,
3616    /// A single tap on the screen.
3617    Tap = 1,
3618    /// A long press (held for 500ms+).
3619    LongPress = 2,
3620    /// A periodic scroll position sample (viewport midpoint every 2s).
3621    Scroll = 3,
3622    /// The user tapped an action button (e.g. "Acknowledge").
3623    ActionClick = 4,
3624}
3625impl TouchEventType {
3626    /// String value of the enum field names used in the ProtoBuf definition.
3627    ///
3628    /// The values are not transformed in any way and thus are considered stable
3629    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3630    pub fn as_str_name(&self) -> &'static str {
3631        match self {
3632            Self::Unspecified => "TOUCH_EVENT_TYPE_UNSPECIFIED",
3633            Self::Tap => "TOUCH_EVENT_TYPE_TAP",
3634            Self::LongPress => "TOUCH_EVENT_TYPE_LONG_PRESS",
3635            Self::Scroll => "TOUCH_EVENT_TYPE_SCROLL",
3636            Self::ActionClick => "TOUCH_EVENT_TYPE_ACTION_CLICK",
3637        }
3638    }
3639    /// Creates an enum from field names used in the ProtoBuf definition.
3640    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3641        match value {
3642            "TOUCH_EVENT_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
3643            "TOUCH_EVENT_TYPE_TAP" => Some(Self::Tap),
3644            "TOUCH_EVENT_TYPE_LONG_PRESS" => Some(Self::LongPress),
3645            "TOUCH_EVENT_TYPE_SCROLL" => Some(Self::Scroll),
3646            "TOUCH_EVENT_TYPE_ACTION_CLICK" => Some(Self::ActionClick),
3647            _ => None,
3648        }
3649    }
3650}
3651/// Aggregation mode for heatmap data queries.
3652#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
3653#[repr(i32)]
3654pub enum HeatmapMode {
3655    /// Default value; not a valid mode.
3656    Unspecified = 0,
3657    /// Sum of all cohort buckets' touches per grid cell (default).
3658    Total = 1,
3659    /// Median touch count per grid cell across cohort buckets.
3660    Median = 2,
3661}
3662impl HeatmapMode {
3663    /// String value of the enum field names used in the ProtoBuf definition.
3664    ///
3665    /// The values are not transformed in any way and thus are considered stable
3666    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
3667    pub fn as_str_name(&self) -> &'static str {
3668        match self {
3669            Self::Unspecified => "HEATMAP_MODE_UNSPECIFIED",
3670            Self::Total => "HEATMAP_MODE_TOTAL",
3671            Self::Median => "HEATMAP_MODE_MEDIAN",
3672        }
3673    }
3674    /// Creates an enum from field names used in the ProtoBuf definition.
3675    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
3676        match value {
3677            "HEATMAP_MODE_UNSPECIFIED" => Some(Self::Unspecified),
3678            "HEATMAP_MODE_TOTAL" => Some(Self::Total),
3679            "HEATMAP_MODE_MEDIAN" => Some(Self::Median),
3680            _ => None,
3681        }
3682    }
3683}
3684// ─── Messages ───────────────────────────────────────────────────────────────
3685
3686/// A single entry in a user's inbox, combining a message with its delivery state.
3687#[derive(Clone, PartialEq, ::prost::Message)]
3688pub struct InboxEntry {
3689    /// ID of the delivery record for this inbox entry.
3690    /// Constraints: UUID format (36 characters).
3691    #[prost(string, tag="1")]
3692    pub delivery_id: ::prost::alloc::string::String,
3693    /// The fully rendered message content.
3694    #[prost(message, optional, tag="2")]
3695    pub message: ::core::option::Option<Message>,
3696    /// Current delivery status (e.g. DELIVERED, ACKNOWLEDGED).
3697    #[prost(enumeration="DeliveryStatus", tag="3")]
3698    pub status: i32,
3699    /// Whether the user has read this message.
3700    #[prost(bool, tag="4")]
3701    pub read: bool,
3702    /// Timestamp when the message was received in the inbox.
3703    #[prost(message, optional, tag="5")]
3704    pub received_at: ::core::option::Option<::prost_types::Timestamp>,
3705    /// Discriminator: PRIMARY for normal deliveries, ESCALATION for delivery-grade
3706    /// escalations. Mirrors Delivery.kind so inbox-sync clients can branch on the
3707    /// same dimension as listDeliveries clients.
3708    #[prost(enumeration="delivery::Kind", tag="6")]
3709    pub kind: i32,
3710    /// For ESCALATION entries, the UUID of the unacked delivery that triggered this
3711    /// entry. Empty for PRIMARY entries.
3712    #[prost(string, tag="7")]
3713    pub parent_delivery_id: ::prost::alloc::string::String,
3714    /// The locale the body actually rendered in after fallback resolution. Empty
3715    /// for legacy/PRIMARY entries.
3716    #[prost(string, tag="8")]
3717    pub rendered_locale: ::prost::alloc::string::String,
3718    /// Optional out-of-band context mirrored from the underlying delivery.
3719    /// See `DeliveryMetadata` for which delivery kinds populate which fields.
3720    /// Empty for PRIMARY entries.
3721    #[prost(message, optional, tag="9")]
3722    pub metadata: ::core::option::Option<DeliveryMetadata>,
3723}
3724/// Request to sync inbox entries since a given timestamp.
3725#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3726pub struct SyncRequest {
3727    /// Fetch entries newer than this timestamp. Omit for initial sync.
3728    #[prost(message, optional, tag="1")]
3729    pub since: ::core::option::Option<::prost_types::Timestamp>,
3730    /// Maximum number of entries to return.
3731    /// Constraints: Valid range 1 to 200.
3732    #[prost(int32, tag="2")]
3733    pub limit: i32,
3734}
3735/// Response containing synced inbox entries.
3736#[derive(Clone, PartialEq, ::prost::Message)]
3737pub struct SyncResponse {
3738    /// Inbox entries newer than the requested timestamp.
3739    #[prost(message, repeated, tag="1")]
3740    pub entries: ::prost::alloc::vec::Vec<InboxEntry>,
3741    /// Cursor timestamp to use for the next sync call.
3742    #[prost(message, optional, tag="2")]
3743    pub next_since: ::core::option::Option<::prost_types::Timestamp>,
3744}
3745/// Request to mark a message as read.
3746#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3747pub struct MarkReadRequest {
3748    /// ID of the delivery to mark as read.
3749    /// Constraints: UUID format (36 characters).
3750    #[prost(string, tag="1")]
3751    pub delivery_id: ::prost::alloc::string::String,
3752}
3753/// Response after marking a message as read.
3754#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
3755pub struct MarkReadResponse {
3756    /// Whether the read status was successfully updated.
3757    #[prost(bool, tag="1")]
3758    pub success: bool,
3759}
3760/// Request to retrieve a single message by delivery ID.
3761#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
3762pub struct GetMessageRequest {
3763    /// ID of the delivery to retrieve.
3764    /// Constraints: UUID format (36 characters).
3765    #[prost(string, tag="1")]
3766    pub delivery_id: ::prost::alloc::string::String,
3767}
3768/// Response containing the requested inbox entry.
3769#[derive(Clone, PartialEq, ::prost::Message)]
3770pub struct GetMessageResponse {
3771    /// The inbox entry for the requested delivery.
3772    #[prost(message, optional, tag="1")]
3773    pub entry: ::core::option::Option<InboxEntry>,
3774}
3775// ─── Messages ───────────────────────────────────────────────────────────────
3776
3777/// A behavioral archetype describing a cohort pattern (never an individual).
3778/// Derived from k-anonymized, DP-noised behavioral feature vectors.
3779#[derive(Clone, PartialEq, ::prost::Message)]
3780pub struct Archetype {
3781    /// Human-readable label (e.g., "Swift Acknowledger", "Thorough Reader").
3782    #[prost(string, tag="1")]
3783    pub label: ::prost::alloc::string::String,
3784    /// Description of the behavioral pattern this archetype represents.
3785    #[prost(string, tag="2")]
3786    pub description: ::prost::alloc::string::String,
3787    /// Proportion of the group that belongs to this archetype (0.0-1.0).
3788    #[prost(float, tag="3")]
3789    pub percentage: f32,
3790    /// Centroid of the behavioral feature vector for this archetype.
3791    /// Keys are stable dimension names from the feature extractor
3792    /// vocabulary (e.g., "tap_density", "engagement_depth",
3793    /// "scroll_velocity_p50", "idle_gap_p75"). Single-letter keys are
3794    /// reserved for backward compatibility with pre-v0.64 servers and
3795    /// SHALL be ignored by clients.
3796    #[prost(map="string, double", tag="4")]
3797    pub feature_centroid: ::std::collections::HashMap<::prost::alloc::string::String, f64>,
3798    /// Per-dimension distribution of the archetype's members. Lets the
3799    /// admin render percentile bands instead of single-point centroids.
3800    /// Absent until at least k members exist in the cluster. Keys mirror
3801    /// `feature_centroid` keys.
3802    #[prost(map="string, message", tag="5")]
3803    pub feature_breakdown: ::std::collections::HashMap<::prost::alloc::string::String, DimensionStats>,
3804    /// Tap density heatmap aggregated across sessions for this
3805    /// archetype. Cohort-level only — never per-session timing.
3806    /// Absent when fewer than k sessions have tap data.
3807    #[prost(message, optional, tag="6")]
3808    pub tap_heatmap: ::core::option::Option<TapHeatmap>,
3809    /// Forecast of cluster share at fixed horizons (7/14/30/90 days).
3810    /// Absent during cold start before historical clustering runs exist
3811    /// to extrapolate from.
3812    #[prost(message, optional, tag="7")]
3813    pub forecast: ::core::option::Option<ArchetypeForecast>,
3814    /// Sessions that sit at the median and quartiles of the archetype's
3815    /// centroid distance, ranked by distance. Bounded at three entries.
3816    /// Absent until at least 50 sessions have been scored.
3817    /// Sessions can come from any client that emits to ReplayService —
3818    /// mobile (iOS, Android) or desktop (macOS, Windows, Linux).
3819    #[prost(message, repeated, tag="8")]
3820    pub exemplar_sessions: ::prost::alloc::vec::Vec<ExemplarSession>,
3821    /// Per-screen dwell time distribution, derived from session replay.
3822    /// Absent when fewer than k sessions per screen exist.
3823    #[prost(message, optional, tag="9")]
3824    pub screen_dwell: ::core::option::Option<ScreenDwell>,
3825    /// End-to-end response latencies (push delivered → read → ack) for
3826    /// members of this archetype, as percentiles. Absent until at least
3827    /// k campaign deliveries have been recorded for this archetype.
3828    #[prost(message, optional, tag="10")]
3829    pub response_timeline: ::core::option::Option<ResponseTimeline>,
3830    /// Where this archetype came from. UNSPECIFIED on responses from
3831    /// pre-v0.81 servers; clients SHOULD treat UNSPECIFIED as ML for
3832    /// backward compatibility (provisional output is always labelled).
3833    #[prost(enumeration="ArchetypeSource", tag="11")]
3834    pub source: i32,
3835}
3836/// Per-dimension distribution stats for one feature dimension within
3837/// an archetype's cohort. All values are in the same units as
3838/// `Archetype.feature_centroid`. Used to render percentile bands on
3839/// the admin's behavioral profile panel.
3840#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3841pub struct DimensionStats {
3842    /// Centroid value (same as Archetype.feature_centroid\[key\]).
3843    #[prost(double, tag="1")]
3844    pub centroid: f64,
3845    /// 25th percentile across the archetype's members.
3846    #[prost(double, tag="2")]
3847    pub p25: f64,
3848    /// Median across the archetype's members.
3849    #[prost(double, tag="3")]
3850    pub p50: f64,
3851    /// 75th percentile across the archetype's members.
3852    #[prost(double, tag="4")]
3853    pub p75: f64,
3854    /// Median across the entire group (all archetypes), included so the
3855    /// admin can render "this archetype is X% above group median".
3856    #[prost(double, tag="5")]
3857    pub group_p50: f64,
3858}
3859/// A density grid of tap activity for one archetype, normalized to
3860/// \[0.0, 1.0\] where 1.0 is the hottest cell in the cohort. Cohort-
3861/// level only.
3862#[derive(Clone, PartialEq, ::prost::Message)]
3863pub struct TapHeatmap {
3864    /// Width of the density grid in cells.
3865    #[prost(int32, tag="1")]
3866    pub width: i32,
3867    /// Height of the density grid in cells.
3868    #[prost(int32, tag="2")]
3869    pub height: i32,
3870    /// Row-major density values, length must equal width*height. All in
3871    /// \[0.0, 1.0\].
3872    #[prost(double, repeated, tag="3")]
3873    pub values: ::prost::alloc::vec::Vec<f64>,
3874    /// Number of sessions aggregated. Always >= MinFeatureVectorsForClustering
3875    /// when the field is present.
3876    #[prost(int32, tag="4")]
3877    pub session_count: i32,
3878    /// Optional per-event-type breakdown. When present, the writer
3879    /// SHALL emit one entry for each event type in the source data
3880    /// (TAP, LONG_PRESS, SCROLL, ACTION_CLICK).
3881    #[prost(message, repeated, tag="5")]
3882    pub layers: ::prost::alloc::vec::Vec<TapHeatmapLayer>,
3883}
3884/// One per-event-type layer of a TapHeatmap.
3885#[derive(Clone, PartialEq, ::prost::Message)]
3886pub struct TapHeatmapLayer {
3887    /// Event type this layer represents (e.g., "TAP", "LONG_PRESS",
3888    /// "SCROLL", "ACTION_CLICK").
3889    #[prost(string, tag="1")]
3890    pub event_type: ::prost::alloc::string::String,
3891    /// Row-major density values, same dimensions as the parent
3892    /// TapHeatmap. Independently normalized to \[0.0, 1.0\].
3893    #[prost(double, repeated, tag="2")]
3894    pub values: ::prost::alloc::vec::Vec<f64>,
3895}
3896/// Predicted cluster share at fixed horizons with confidence bands.
3897#[derive(Clone, PartialEq, ::prost::Message)]
3898pub struct ArchetypeForecast {
3899    /// Horizons in increasing days. Always one entry each for 7, 14,
3900    /// 30, and 90 days when the field is present.
3901    #[prost(message, repeated, tag="1")]
3902    pub horizons: ::prost::alloc::vec::Vec<ForecastHorizon>,
3903}
3904/// Predicted share at one horizon with a 90% prediction interval.
3905#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3906pub struct ForecastHorizon {
3907    /// Horizon length in days (one of: 7, 14, 30, 90).
3908    #[prost(int32, tag="1")]
3909    pub days: i32,
3910    /// Predicted fraction of the group falling in this archetype at the
3911    /// horizon (0.0-1.0).
3912    #[prost(double, tag="2")]
3913    pub predicted_share: f64,
3914    /// 5th-percentile lower bound of the prediction interval.
3915    #[prost(double, tag="3")]
3916    pub lower: f64,
3917    /// 95th-percentile upper bound of the prediction interval.
3918    #[prost(double, tag="4")]
3919    pub upper: f64,
3920    /// Confidence in this horizon's prediction.
3921    #[prost(enumeration="ConfidenceLevel", tag="5")]
3922    pub confidence: i32,
3923}
3924/// Pointer to a representative session for one archetype, ranked by
3925/// distance to the archetype centroid.
3926#[derive(Clone, PartialEq, ::prost::Message)]
3927pub struct ExemplarSession {
3928    /// Session recording ID retrievable via ReplayService for the same
3929    /// org. Linkable from the admin regardless of originating platform.
3930    #[prost(string, tag="1")]
3931    pub session_id: ::prost::alloc::string::String,
3932    /// Quantile rank within the archetype: 25, 50, or 75. The writer
3933    /// emits at most one session per rank.
3934    #[prost(int32, tag="2")]
3935    pub rank: i32,
3936    /// L2 distance from the session's feature vector to the centroid.
3937    #[prost(double, tag="3")]
3938    pub distance: f64,
3939    /// Optional duration metadata for quick admin labelling.
3940    #[prost(int32, tag="4")]
3941    pub duration_seconds: i32,
3942    /// Optional platform identifier from the vocabulary
3943    /// {"ios", "android", "macos", "windows", "linux"}. The admin
3944    /// renders unknown values verbatim for forward compatibility.
3945    #[prost(string, tag="5")]
3946    pub platform: ::prost::alloc::string::String,
3947}
3948/// Per-screen dwell distribution within an archetype. Lets the admin
3949/// surface "this archetype lingers 8.2s on the Message Detail screen
3950/// vs 0.4s on the Inbox list".
3951#[derive(Clone, PartialEq, ::prost::Message)]
3952pub struct ScreenDwell {
3953    /// One entry per screen. Screens with fewer than k members in the
3954    /// archetype are dropped from the list (not marked as absent).
3955    #[prost(message, repeated, tag="1")]
3956    pub entries: ::prost::alloc::vec::Vec<ScreenDwellEntry>,
3957}
3958#[derive(Clone, PartialEq, ::prost::Message)]
3959pub struct ScreenDwellEntry {
3960    /// Stable screen identifier (e.g., "MessageDetail", "Inbox",
3961    /// "ProfileSettings"). Sourced from the same screen_name vocabulary
3962    /// used by heatmap_cells.
3963    #[prost(string, tag="1")]
3964    pub screen_name: ::prost::alloc::string::String,
3965    /// Median dwell time in seconds for this archetype on this screen.
3966    #[prost(double, tag="2")]
3967    pub median_seconds: f64,
3968    /// 75th-percentile dwell time in seconds.
3969    #[prost(double, tag="3")]
3970    pub p75_seconds: f64,
3971    /// Number of distinct sessions aggregated for this screen.
3972    #[prost(int32, tag="4")]
3973    pub session_count: i32,
3974}
3975/// End-to-end response latencies for members of one archetype, in
3976/// seconds. Each percentile is computed across all qualifying campaign
3977/// deliveries for the archetype's members within the rolling window.
3978#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3979pub struct ResponseTimeline {
3980    /// Time from `delivered_at` to `read_at`, in seconds.
3981    #[prost(message, optional, tag="1")]
3982    pub read_after_delivered: ::core::option::Option<LatencyPercentiles>,
3983    /// Time from `read_at` to `acknowledged_at`, in seconds. Only
3984    /// includes deliveries that were both read and acknowledged.
3985    #[prost(message, optional, tag="2")]
3986    pub ack_after_read: ::core::option::Option<LatencyPercentiles>,
3987    /// End-to-end time from `delivered_at` to `acknowledged_at`, in
3988    /// seconds. Only includes deliveries that were acknowledged.
3989    #[prost(message, optional, tag="3")]
3990    pub ack_after_delivered: ::core::option::Option<LatencyPercentiles>,
3991    /// Number of deliveries the timeline is computed over.
3992    #[prost(int32, tag="4")]
3993    pub delivery_count: i32,
3994}
3995/// Latency distribution stats. Values are in seconds.
3996#[derive(Clone, Copy, PartialEq, ::prost::Message)]
3997pub struct LatencyPercentiles {
3998    #[prost(double, tag="1")]
3999    pub p50: f64,
4000    #[prost(double, tag="2")]
4001    pub p75: f64,
4002    #[prost(double, tag="3")]
4003    pub p95: f64,
4004}
4005/// A cohort-level prediction for campaign acknowledgment rate.
4006/// Never targets or scores individuals — always represents an audience aggregate.
4007#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4008pub struct CohortPrediction {
4009    /// Predicted ACK rate for the audience (0.0-1.0).
4010    #[prost(float, tag="1")]
4011    pub predicted_ack_rate: f32,
4012    /// Lower bound of the confidence interval.
4013    #[prost(float, tag="2")]
4014    pub confidence_low: f32,
4015    /// Upper bound of the confidence interval.
4016    #[prost(float, tag="3")]
4017    pub confidence_high: f32,
4018    /// Confidence level based on available data volume.
4019    #[prost(enumeration="ConfidenceLevel", tag="4")]
4020    pub confidence_level: i32,
4021    /// Number of anonymous data points used for this prediction.
4022    #[prost(int32, tag="5")]
4023    pub data_point_count: i32,
4024}
4025/// Advisory information for campaign configuration, combining predictions and archetypes.
4026#[derive(Clone, PartialEq, ::prost::Message)]
4027pub struct CampaignAdvisory {
4028    /// Cohort-level ACK prediction for the target audience.
4029    #[prost(message, optional, tag="1")]
4030    pub predicted_ack: ::core::option::Option<CohortPrediction>,
4031    /// Suggested escalation delay in minutes based on historical cohort patterns.
4032    /// 0 if insufficient data.
4033    #[prost(int32, tag="2")]
4034    pub suggested_escalation_delay_minutes: i32,
4035    /// Behavioral archetypes for the target audience.
4036    #[prost(message, repeated, tag="3")]
4037    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
4038}
4039/// Request to retrieve behavioral archetypes for a group.
4040#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4041pub struct GetGroupArchetypesRequest {
4042    /// ID of the group to query archetypes for. Required.
4043    #[prost(string, tag="1")]
4044    pub group_id: ::prost::alloc::string::String,
4045}
4046/// Response containing behavioral archetypes for a group.
4047#[derive(Clone, PartialEq, ::prost::Message)]
4048pub struct GetGroupArchetypesResponse {
4049    /// Behavioral archetypes for the group (empty if insufficient data).
4050    #[prost(message, repeated, tag="1")]
4051    pub archetypes: ::prost::alloc::vec::Vec<Archetype>,
4052    /// Number of anonymous feature vectors used for clustering.
4053    #[prost(int32, tag="2")]
4054    pub data_point_count: i32,
4055    /// Why `archetypes` looks the way it does. Lets the UI render a
4056    /// distinct empty-state affordance for "never trained" vs
4057    /// "below threshold" vs "no clusters" vs "ready". See PipelineState.
4058    #[prost(enumeration="PipelineState", tag="3")]
4059    pub pipeline_state: i32,
4060    /// Confidence in the returned archetypes, derived from available data
4061    /// volume. Always CONFIDENCE_LEVEL_LOW when provisional archetypes
4062    /// are returned — clients use this plus `Archetype.source` to render
4063    /// the low-confidence disclaimer.
4064    #[prost(enumeration="ConfidenceLevel", tag="4")]
4065    pub confidence_level: i32,
4066}
4067/// Request to predict cohort-level ACK rate for a campaign configuration.
4068#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4069pub struct PredictCampaignAckRequest {
4070    /// ID of the target audience group. Required.
4071    #[prost(string, tag="1")]
4072    pub group_id: ::prost::alloc::string::String,
4073    /// Template type (optional, for prediction refinement).
4074    #[prost(string, tag="2")]
4075    pub template_type: ::prost::alloc::string::String,
4076    /// Number of workflow steps (optional, for prediction refinement).
4077    #[prost(int32, tag="3")]
4078    pub workflow_step_count: i32,
4079}
4080/// Response containing a cohort-level ACK prediction.
4081#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4082pub struct PredictCampaignAckResponse {
4083    /// Cohort-level prediction.
4084    #[prost(message, optional, tag="1")]
4085    pub prediction: ::core::option::Option<CohortPrediction>,
4086}
4087/// Request for campaign configuration advisory.
4088#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4089pub struct GetCampaignAdvisoryRequest {
4090    /// ID of the target audience group. Required.
4091    #[prost(string, tag="1")]
4092    pub group_id: ::prost::alloc::string::String,
4093    /// Template ID (optional, for advisory context).
4094    #[prost(string, tag="2")]
4095    pub template_id: ::prost::alloc::string::String,
4096    /// Template version (optional).
4097    #[prost(int32, tag="3")]
4098    pub template_version: i32,
4099    /// Number of workflow steps (optional).
4100    #[prost(int32, tag="4")]
4101    pub workflow_step_count: i32,
4102}
4103/// Response containing campaign advisory information.
4104#[derive(Clone, PartialEq, ::prost::Message)]
4105pub struct GetCampaignAdvisoryResponse {
4106    /// Campaign advisory with prediction, suggested escalation, and archetypes.
4107    #[prost(message, optional, tag="1")]
4108    pub advisory: ::core::option::Option<CampaignAdvisory>,
4109}
4110/// Request to generate an AI narrative for a group's insights.
4111#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4112pub struct GetInsightNarrativeRequest {
4113    /// ID of the group to generate a narrative for. Required.
4114    #[prost(string, tag="1")]
4115    pub group_id: ::prost::alloc::string::String,
4116    /// Name of the prompt template to use (e.g., "campaign-advisory", "archetype-explanation").
4117    #[prost(string, tag="2")]
4118    pub prompt_name: ::prost::alloc::string::String,
4119}
4120/// Response containing an AI-generated narrative.
4121#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4122pub struct GetInsightNarrativeResponse {
4123    /// AI-generated narrative text (Markdown formatted).
4124    #[prost(string, tag="1")]
4125    pub narrative: ::prost::alloc::string::String,
4126    /// Timestamp when the narrative was generated.
4127    #[prost(message, optional, tag="2")]
4128    pub generated_at: ::core::option::Option<::prost_types::Timestamp>,
4129    /// Model identifier used for generation.
4130    #[prost(string, tag="3")]
4131    pub model_id: ::prost::alloc::string::String,
4132}
4133/// Request to manually trigger the ML training pipeline.
4134/// Empty — organization is extracted from the JWT.
4135#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4136pub struct TriggerMlPipelineRequest {
4137}
4138/// Response after triggering the ML pipeline.
4139#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4140pub struct TriggerMlPipelineResponse {
4141    /// Remaining manual retrains allowed this month.
4142    #[prost(int32, tag="1")]
4143    pub remaining_this_month: i32,
4144    /// Timestamp of the last successful training (null if never trained).
4145    #[prost(message, optional, tag="2")]
4146    pub last_trained_at: ::core::option::Option<::prost_types::Timestamp>,
4147}
4148/// Request to manually retrigger archetype clustering for a single group
4149/// without rerunning the full SageMaker training pipeline. Reuses the
4150/// already-deployed clustering model.
4151#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4152pub struct TriggerArchetypeClusteringRequest {
4153    /// Group to recluster. Org is extracted from the JWT.
4154    #[prost(string, tag="1")]
4155    pub group_id: ::prost::alloc::string::String,
4156}
4157/// Response after triggering archetype clustering for one group.
4158#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4159pub struct TriggerArchetypeClusteringResponse {
4160    /// Temporal workflow id — useful for client-side dedupe + operator
4161    /// debugging via the Temporal UI.
4162    #[prost(string, tag="1")]
4163    pub workflow_id: ::prost::alloc::string::String,
4164    /// Remaining manual retrains allowed this month. Shares the same
4165    /// monthly counter as TriggerMLPipeline (ml_manual_limit_monthly).
4166    #[prost(int32, tag="2")]
4167    pub remaining_this_month: i32,
4168    /// Timestamp of the last successful archetype clustering for this
4169    /// (org, group), null if never clustered.
4170    #[prost(message, optional, tag="3")]
4171    pub last_clustered_at: ::core::option::Option<::prost_types::Timestamp>,
4172}
4173/// Request to draft a campaign body for a given archetype using Bedrock.
4174/// Used by the Compass "Target this archetype in a new campaign" CTA to
4175/// pre-fill the campaign creation wizard's body field.
4176#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4177pub struct GenerateCampaignBodyDraftRequest {
4178    /// UUID of the source group whose archetype set the label belongs to.
4179    #[prost(string, tag="1")]
4180    pub group_id: ::prost::alloc::string::String,
4181    /// Stable archetype label, e.g. "Swift Acknowledger".
4182    #[prost(string, tag="2")]
4183    pub archetype_label: ::prost::alloc::string::String,
4184    /// Lane-recommended action copy passed through from the admin (e.g.
4185    /// "Simplify the call-to-action"). Used as a tone hint for the prompt.
4186    #[prost(string, tag="3")]
4187    pub lane_action: ::prost::alloc::string::String,
4188}
4189/// Response containing the generated draft body in Markdown.
4190#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4191pub struct GenerateCampaignBodyDraftResponse {
4192    /// Draft Markdown body, 3-5 sentences. Authored as if written for the
4193    /// recipient — does not mention the archetype name.
4194    #[prost(string, tag="1")]
4195    pub body_markdown: ::prost::alloc::string::String,
4196}
4197/// Share of an organization's campaigns exercising one lever.
4198#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4199pub struct LeverShare {
4200    #[prost(enumeration="Lever", tag="1")]
4201    pub lever: i32,
4202    #[prost(int32, tag="2")]
4203    pub count: i32,
4204    /// Fraction of classified campaigns, 0..1.
4205    #[prost(float, tag="3")]
4206    pub share: f32,
4207    /// Where the majority of this lever's classifications came from.
4208    /// Consumers use this together with `avg_confidence` to present
4209    /// rule-derived mixes as estimates rather than model-grade
4210    /// classifications.
4211    #[prost(enumeration="LeverSource", tag="4")]
4212    pub dominant_source: i32,
4213    /// Mean classifier confidence across the campaigns counted here, 0..1.
4214    #[prost(float, tag="5")]
4215    pub avg_confidence: f32,
4216}
4217/// How much messaging lands on a single person over the observed window.
4218#[derive(Clone, Copy, PartialEq, ::prost::Message)]
4219pub struct RecipientLoad {
4220    #[prost(float, tag="1")]
4221    pub median_per_week: f32,
4222    #[prost(float, tag="2")]
4223    pub p90_per_week: f32,
4224    #[prost(int32, tag="3")]
4225    pub users_reached: i32,
4226    #[prost(int32, tag="4")]
4227    pub window_days: i32,
4228    /// Median number of distinct senders reaching one recipient within
4229    /// the same window.
4230    #[prost(float, tag="5")]
4231    pub median_distinct_senders: f32,
4232    /// 90th-percentile number of distinct senders reaching one recipient
4233    /// within the same window.
4234    #[prost(float, tag="6")]
4235    pub p90_distinct_senders: f32,
4236    /// Median number of distinct channels one recipient is reached on
4237    /// within the same window.
4238    #[prost(float, tag="7")]
4239    pub median_distinct_channels: f32,
4240    /// 90th-percentile number of distinct channels one recipient is
4241    /// reached on within the same window.
4242    #[prost(float, tag="8")]
4243    pub p90_distinct_channels: f32,
4244}
4245#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4246pub struct GetOrgCommunicationProfileRequest {
4247}
4248#[derive(Clone, PartialEq, ::prost::Message)]
4249pub struct GetOrgCommunicationProfileResponse {
4250    #[prost(message, repeated, tag="1")]
4251    pub lever_mix: ::prost::alloc::vec::Vec<LeverShare>,
4252    #[prost(message, optional, tag="2")]
4253    pub load: ::core::option::Option<RecipientLoad>,
4254    #[prost(int32, tag="3")]
4255    pub campaigns_analyzed: i32,
4256    /// Fraction of active objectives that have at least one indicator
4257    /// whose evidence comes from outside the product, 0..1.
4258    ///
4259    /// It says how much the rest of the board is worth: an objective
4260    /// observed only through what people answered inside the app has
4261    /// evidence that they said they did it, not evidence that the work
4262    /// changed.
4263    ///
4264    /// Absent when `active_objectives` is zero, because a fraction with no
4265    /// denominator has no value and a present 0.0 would be
4266    /// indistinguishable from genuine coverage of none — opposite facts
4267    /// with opposite consequences. The two counts below travel with it as
4268    /// the second half of the same guarantee.
4269    #[prost(float, optional, tag="4")]
4270    pub evidence_coverage: ::core::option::Option<f32>,
4271    /// Numerator of `evidence_coverage`: active objectives with at least
4272    /// one indicator sourced outside the product.
4273    #[prost(int32, tag="5")]
4274    pub objectives_with_external_evidence: i32,
4275    /// Denominator of `evidence_coverage`: active objectives. Zero means
4276    /// the organization has declared none, which is a supported way to use
4277    /// the product and not an incomplete setup.
4278    #[prost(int32, tag="6")]
4279    pub active_objectives: i32,
4280    /// Median number of days since the organization's indicators were last
4281    /// revised, measured from each indicator's last update.
4282    ///
4283    /// Indicators are rarely revisited when the strategy they serve moves
4284    /// on, and this is the plainest measurable form of that: an ageing
4285    /// median means the board is describing an older intent than the
4286    /// objectives do.
4287    ///
4288    /// Absent when the organization has no indicators. An age of zero
4289    /// would claim they were all just reviewed.
4290    #[prost(int64, optional, tag="7")]
4291    pub median_indicator_review_age_days: ::core::option::Option<i64>,
4292}
4293/// One observation in a diagnosis.
4294///
4295/// Every finding carries the records it was derived from. That is not
4296/// decoration: a statement about an organization that cannot be traced
4297/// back to the campaigns, objectives and indicators that produced it is
4298/// indistinguishable from an opinion, and the reader has no way to
4299/// disagree with it on the facts. At least one of the three reference
4300/// lists is always non-empty.
4301#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4302pub struct DiagnosisFinding {
4303    /// Unique identifier for the finding, stable within the diagnosis.
4304    /// Lets a surface show a finding once at the level where it can be
4305    /// acted on instead of repeating it as a loose warning elsewhere.
4306    #[prost(string, tag="1")]
4307    pub id: ::prost::alloc::string::String,
4308    /// Which pattern produced it.
4309    #[prost(enumeration="DiagnosisFindingKind", tag="2")]
4310    pub kind: i32,
4311    /// What was observed, in the organization's own terms. Plain language
4312    /// and free of the vocabulary of the framework the pattern comes from.
4313    #[prost(string, tag="3")]
4314    pub detail: ::prost::alloc::string::String,
4315    /// Campaigns the finding was derived from.
4316    #[prost(string, repeated, tag="4")]
4317    pub campaign_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4318    /// Objectives the finding was derived from.
4319    #[prost(string, repeated, tag="5")]
4320    pub objective_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4321    /// Indicators the finding was derived from.
4322    #[prost(string, repeated, tag="6")]
4323    pub indicator_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4324    /// True when a model wrote `detail`. A model only ever phrases a
4325    /// finding that was already established from the records above; it
4326    /// never decides that there is one. Consumers use this the way they
4327    /// use lever provenance — to present a phrasing as a phrasing.
4328    #[prost(bool, tag="7")]
4329    pub model_assisted: bool,
4330}
4331/// The organization-level metrics as they stood when a diagnosis was
4332/// produced, stored with it.
4333///
4334/// Kept rather than recomputed because two of the four cannot be
4335/// recovered afterwards. Evidence coverage and the indicator review age
4336/// are read off the objectives and indicators as they are configured at
4337/// that moment, and configuration has no history: an objective archived
4338/// or an indicator revised next month silently rewrites what last
4339/// month's answer would have been. A diagnosis stored without its
4340/// snapshot therefore loses the comparison permanently, and the
4341/// comparison is most of why the diagnosis is stored at all.
4342///
4343/// Fields carry presence on the same terms as the profile response they
4344/// mirror: absent means there was nothing to measure, never zero.
4345#[derive(Clone, PartialEq, ::prost::Message)]
4346pub struct OrgMetricsSnapshot {
4347    /// Distribution of the classified history across control mechanisms.
4348    #[prost(message, repeated, tag="1")]
4349    pub lever_mix: ::prost::alloc::vec::Vec<LeverShare>,
4350    /// How much messaging landed on one person over the observed window.
4351    #[prost(message, optional, tag="2")]
4352    pub load: ::core::option::Option<RecipientLoad>,
4353    /// Fraction of active objectives with at least one indicator sourced
4354    /// outside the product, 0..1. Absent when there were no active
4355    /// objectives.
4356    #[prost(float, optional, tag="3")]
4357    pub evidence_coverage: ::core::option::Option<f32>,
4358    /// Numerator of `evidence_coverage` at generation time.
4359    #[prost(int32, tag="4")]
4360    pub objectives_with_external_evidence: i32,
4361    /// Denominator of `evidence_coverage` at generation time.
4362    #[prost(int32, tag="5")]
4363    pub active_objectives: i32,
4364    /// Median days since the organization's indicators were last revised.
4365    /// Absent when there were no indicators.
4366    #[prost(int64, optional, tag="6")]
4367    pub median_indicator_review_age_days: ::core::option::Option<i64>,
4368}
4369/// A dated, stored reading of the organization's own measurement system:
4370/// what it has declared it wants, how it observes it, and what it has
4371/// actually been communicating.
4372///
4373/// Stored rather than computed on request because the useful statements
4374/// are comparisons — that the mix of messages moved over a quarter, that
4375/// three objectives still have no outcome evidence months later — and a
4376/// stateless query cannot make them. It is also the only shape in which a
4377/// recurring review has something to review.
4378#[derive(Clone, PartialEq, ::prost::Message)]
4379pub struct OrgDiagnosis {
4380    /// Unique identifier for this run.
4381    #[prost(string, tag="1")]
4382    pub id: ::prost::alloc::string::String,
4383    /// When the run was produced.
4384    #[prost(message, optional, tag="2")]
4385    pub generated_at: ::core::option::Option<::prost_types::Timestamp>,
4386    /// What the run found. Empty when the configuration and the history
4387    /// gave nothing to say, which is a real result: a system that always
4388    /// has an opinion stops being read. Empty carries that meaning only
4389    /// when `findings_evaluated` is true.
4390    #[prost(message, repeated, tag="3")]
4391    pub findings: ::prost::alloc::vec::Vec<DiagnosisFinding>,
4392    /// The previous run, when there is one. What changed between the two
4393    /// is the part of a diagnosis that no single run can carry.
4394    #[prost(string, tag="4")]
4395    pub previous_diagnosis_id: ::prost::alloc::string::String,
4396    /// Objectives read by the run.
4397    #[prost(int32, tag="5")]
4398    pub objectives_analyzed: i32,
4399    /// Campaigns read by the run.
4400    #[prost(int32, tag="6")]
4401    pub campaigns_analyzed: i32,
4402    /// The metrics as they stood at generation time. What moved between
4403    /// two runs is the part of a diagnosis that no single run can state,
4404    /// and this is what makes it recoverable later.
4405    #[prost(message, optional, tag="7")]
4406    pub metrics: ::core::option::Option<OrgMetricsSnapshot>,
4407    /// Whether the patterns that produce findings were evaluated for this
4408    /// diagnosis.
4409    ///
4410    /// A run freezes its metrics whether or not the interpretation half
4411    /// completes, because measurement cannot be recovered afterwards and
4412    /// interpretation can. When it did not complete, `findings` is empty
4413    /// for a reason that says nothing about the organization: nothing
4414    /// looked.
4415    ///
4416    /// An empty `findings` list is evidence that nothing was found only
4417    /// when this is true; otherwise it is evidence of nothing at all, and
4418    /// a consumer MUST NOT present it as a clean bill of health — no
4419    /// warnings shown, "no issues detected", a zero on a findings count,
4420    /// or a flat stretch in a findings-over-time series are all the same
4421    /// false claim.
4422    ///
4423    /// False is the safe default: a producer that does not set it is taken
4424    /// to have looked at nothing.
4425    #[prost(bool, tag="8")]
4426    pub findings_evaluated: bool,
4427}
4428/// Request for a stored organization diagnosis.
4429#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4430pub struct GetOrgDiagnosisRequest {
4431    /// Retrieve a specific run. Empty returns the most recent one.
4432    /// An id that does not exist returns NOT_FOUND.
4433    #[prost(string, tag="1")]
4434    pub diagnosis_id: ::prost::alloc::string::String,
4435}
4436/// Response containing an organization diagnosis.
4437#[derive(Clone, PartialEq, ::prost::Message)]
4438pub struct GetOrgDiagnosisResponse {
4439    /// The diagnosis. Absent when no run has ever been produced for the
4440    /// organization — a run needs declared objectives to have anything to
4441    /// read, and does not happen without them. Absence is presented as
4442    /// absence, never as a diagnosis with no findings, which would say
4443    /// something quite different.
4444    #[prost(message, optional, tag="1")]
4445    pub diagnosis: ::core::option::Option<OrgDiagnosis>,
4446}
4447/// Request to list an organization's diagnoses with pagination.
4448#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4449pub struct ListOrgDiagnosesRequest {
4450    /// Pagination parameters.
4451    #[prost(message, optional, tag="1")]
4452    pub pagination: ::core::option::Option<Pagination>,
4453}
4454/// Response containing a page of diagnoses.
4455#[derive(Clone, PartialEq, ::prost::Message)]
4456pub struct ListOrgDiagnosesResponse {
4457    /// Diagnoses in this page, newest first. Each carries its own metrics
4458    /// snapshot, so a page is enough to plot how the organization's
4459    /// measurement system moved without walking the chain of previous
4460    /// runs one fetch at a time.
4461    ///
4462    /// Entries whose `findings_evaluated` is false are not quiet months.
4463    /// Leave them out of any count or series built on findings, and say
4464    /// they were left out; kept in, the series reports when evaluation
4465    /// succeeded rather than how the organization moved.
4466    #[prost(message, repeated, tag="1")]
4467    pub diagnoses: ::prost::alloc::vec::Vec<OrgDiagnosis>,
4468    /// Pagination metadata for fetching subsequent pages.
4469    #[prost(message, optional, tag="2")]
4470    pub pagination_meta: ::core::option::Option<PaginationMeta>,
4471}
4472/// Request to run a diagnosis now.
4473/// Empty — organization is extracted from the JWT.
4474#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4475pub struct TriggerOrgDiagnosisRequest {
4476}
4477/// Response after triggering a diagnosis run.
4478#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4479pub struct TriggerOrgDiagnosisResponse {
4480    /// Remaining manual runs allowed this month.
4481    #[prost(int32, tag="1")]
4482    pub remaining_this_month: i32,
4483    /// Timestamp of the last diagnosis produced, null if never run.
4484    #[prost(message, optional, tag="2")]
4485    pub last_generated_at: ::core::option::Option<::prost_types::Timestamp>,
4486}
4487// ─── Enums ──────────────────────────────────────────────────────────────────
4488
4489/// Confidence level for cohort-level predictions, based on available data volume.
4490#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4491#[repr(i32)]
4492pub enum ConfidenceLevel {
4493    Unspecified = 0,
4494    /// Fewer than 50 campaigns — predictions based on heuristics/industry benchmarks.
4495    Low = 1,
4496    /// 50-200 campaigns — basic clustering available, wide confidence intervals.
4497    Medium = 2,
4498    /// 200+ campaigns — full ML pipeline, narrow confidence intervals.
4499    High = 3,
4500}
4501impl ConfidenceLevel {
4502    /// String value of the enum field names used in the ProtoBuf definition.
4503    ///
4504    /// The values are not transformed in any way and thus are considered stable
4505    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4506    pub fn as_str_name(&self) -> &'static str {
4507        match self {
4508            Self::Unspecified => "CONFIDENCE_LEVEL_UNSPECIFIED",
4509            Self::Low => "CONFIDENCE_LEVEL_LOW",
4510            Self::Medium => "CONFIDENCE_LEVEL_MEDIUM",
4511            Self::High => "CONFIDENCE_LEVEL_HIGH",
4512        }
4513    }
4514    /// Creates an enum from field names used in the ProtoBuf definition.
4515    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4516        match value {
4517            "CONFIDENCE_LEVEL_UNSPECIFIED" => Some(Self::Unspecified),
4518            "CONFIDENCE_LEVEL_LOW" => Some(Self::Low),
4519            "CONFIDENCE_LEVEL_MEDIUM" => Some(Self::Medium),
4520            "CONFIDENCE_LEVEL_HIGH" => Some(Self::High),
4521            _ => None,
4522        }
4523    }
4524}
4525/// Pipeline state for a group's archetypes. Lets the admin UI render
4526/// distinct empty-state affordances ("run clustering" vs "need N more
4527/// sessions" vs "pipeline ran but audience was too homogeneous") instead
4528/// of treating every empty archetype list the same. Populated by
4529/// InsightsService.GetGroupArchetypes.
4530#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4531#[repr(i32)]
4532pub enum PipelineState {
4533    Unspecified = 0,
4534    /// The ML pipeline has never fired for this org. Archetypes are
4535    /// empty because nothing ran, not because of data shape.
4536    NeverRun = 1,
4537    /// The pipeline ran but the group had fewer than the k-anonymization
4538    /// minimum feature vectors (50), so clustering was skipped. UI
4539    /// renders "keep running campaigns" affordance.
4540    BelowThreshold = 2,
4541    /// The pipeline ran with enough vectors but the clustering provider
4542    /// returned zero clusters — typically means the audience is too
4543    /// homogeneous to separate into distinct archetypes.
4544    NoClusters = 3,
4545    /// Archetypes are populated and ready to render.
4546    Ready = 4,
4547}
4548impl PipelineState {
4549    /// String value of the enum field names used in the ProtoBuf definition.
4550    ///
4551    /// The values are not transformed in any way and thus are considered stable
4552    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4553    pub fn as_str_name(&self) -> &'static str {
4554        match self {
4555            Self::Unspecified => "PIPELINE_STATE_UNSPECIFIED",
4556            Self::NeverRun => "PIPELINE_STATE_NEVER_RUN",
4557            Self::BelowThreshold => "PIPELINE_STATE_BELOW_THRESHOLD",
4558            Self::NoClusters => "PIPELINE_STATE_NO_CLUSTERS",
4559            Self::Ready => "PIPELINE_STATE_READY",
4560        }
4561    }
4562    /// Creates an enum from field names used in the ProtoBuf definition.
4563    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4564        match value {
4565            "PIPELINE_STATE_UNSPECIFIED" => Some(Self::Unspecified),
4566            "PIPELINE_STATE_NEVER_RUN" => Some(Self::NeverRun),
4567            "PIPELINE_STATE_BELOW_THRESHOLD" => Some(Self::BelowThreshold),
4568            "PIPELINE_STATE_NO_CLUSTERS" => Some(Self::NoClusters),
4569            "PIPELINE_STATE_READY" => Some(Self::Ready),
4570            _ => None,
4571        }
4572    }
4573}
4574/// Where an archetype came from. Lets clients distinguish trained ML
4575/// clustering output from low-confidence provisional output generated
4576/// for sandboxes and opted-in organizations before enough engagement
4577/// data exists. Clients MUST render a low-confidence disclaimer for
4578/// PROVISIONAL archetypes.
4579#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4580#[repr(i32)]
4581pub enum ArchetypeSource {
4582    Unspecified = 0,
4583    /// Produced by the trained ML clustering pipeline (k-anonymized,
4584    /// DP-noised behavioral feature vectors).
4585    Ml = 1,
4586    /// Rule-based provisional output derived from coarse delivery/read/
4587    /// ack activity (or a stable starter distribution for sandboxes with
4588    /// no activity). Low confidence, never written to the ML artifact
4589    /// path, and always superseded by ML output once available.
4590    Provisional = 2,
4591}
4592impl ArchetypeSource {
4593    /// String value of the enum field names used in the ProtoBuf definition.
4594    ///
4595    /// The values are not transformed in any way and thus are considered stable
4596    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4597    pub fn as_str_name(&self) -> &'static str {
4598        match self {
4599            Self::Unspecified => "ARCHETYPE_SOURCE_UNSPECIFIED",
4600            Self::Ml => "ARCHETYPE_SOURCE_ML",
4601            Self::Provisional => "ARCHETYPE_SOURCE_PROVISIONAL",
4602        }
4603    }
4604    /// Creates an enum from field names used in the ProtoBuf definition.
4605    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4606        match value {
4607            "ARCHETYPE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
4608            "ARCHETYPE_SOURCE_ML" => Some(Self::Ml),
4609            "ARCHETYPE_SOURCE_PROVISIONAL" => Some(Self::Provisional),
4610            _ => None,
4611        }
4612    }
4613}
4614/// Which control mechanism a message exercises. Names are technical; clients
4615/// render plain-language labels from their own catalog.
4616#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4617#[repr(i32)]
4618pub enum Lever {
4619    Unspecified = 0,
4620    Boundaries = 1,
4621    Diagnostic = 2,
4622    Beliefs = 3,
4623    Interactive = 4,
4624}
4625impl Lever {
4626    /// String value of the enum field names used in the ProtoBuf definition.
4627    ///
4628    /// The values are not transformed in any way and thus are considered stable
4629    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4630    pub fn as_str_name(&self) -> &'static str {
4631        match self {
4632            Self::Unspecified => "LEVER_UNSPECIFIED",
4633            Self::Boundaries => "LEVER_BOUNDARIES",
4634            Self::Diagnostic => "LEVER_DIAGNOSTIC",
4635            Self::Beliefs => "LEVER_BELIEFS",
4636            Self::Interactive => "LEVER_INTERACTIVE",
4637        }
4638    }
4639    /// Creates an enum from field names used in the ProtoBuf definition.
4640    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4641        match value {
4642            "LEVER_UNSPECIFIED" => Some(Self::Unspecified),
4643            "LEVER_BOUNDARIES" => Some(Self::Boundaries),
4644            "LEVER_DIAGNOSTIC" => Some(Self::Diagnostic),
4645            "LEVER_BELIEFS" => Some(Self::Beliefs),
4646            "LEVER_INTERACTIVE" => Some(Self::Interactive),
4647            _ => None,
4648        }
4649    }
4650}
4651/// How a lever classification was produced.
4652#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4653#[repr(i32)]
4654pub enum LeverSource {
4655    Unspecified = 0,
4656    /// Produced by a trained classification model.
4657    Model = 1,
4658    /// Produced by deterministic rules over campaign metadata.
4659    Rules = 2,
4660}
4661impl LeverSource {
4662    /// String value of the enum field names used in the ProtoBuf definition.
4663    ///
4664    /// The values are not transformed in any way and thus are considered stable
4665    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4666    pub fn as_str_name(&self) -> &'static str {
4667        match self {
4668            Self::Unspecified => "LEVER_SOURCE_UNSPECIFIED",
4669            Self::Model => "LEVER_SOURCE_MODEL",
4670            Self::Rules => "LEVER_SOURCE_RULES",
4671        }
4672    }
4673    /// Creates an enum from field names used in the ProtoBuf definition.
4674    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4675        match value {
4676            "LEVER_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
4677            "LEVER_SOURCE_MODEL" => Some(Self::Model),
4678            "LEVER_SOURCE_RULES" => Some(Self::Rules),
4679            _ => None,
4680        }
4681    }
4682}
4683/// Which pattern a finding came from. The scope a pattern is entitled to
4684/// speak at is fixed per kind and not a separate field: mutual exclusivity
4685/// and lever mix are properties of the whole declared set, board size and
4686/// drift are properties of one objective, and encouraged behaviour is a
4687/// property of one indicator. Evaluating any of them at another scope is a
4688/// category error rather than a partial view.
4689#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4690#[repr(i32)]
4691pub enum DiagnosisFindingKind {
4692    Unspecified = 0,
4693    /// An indicator whose evidence source structurally fails one of the
4694    /// qualities a measure needs, and the behaviour that tends to follow.
4695    PerverseConductRisk = 1,
4696    /// The organization's messages concentrate in some control mechanisms
4697    /// and leave others unused, with the consequences the missing ones
4698    /// would have covered.
4699    LeverImbalance = 2,
4700    /// The declared objectives overlap each other or leave gaps, so the
4701    /// set does not partition what the organization is trying to hold
4702    /// true.
4703    NonExclusiveSet = 3,
4704    /// An objective carries more indicators than anyone reads, or several
4705    /// that measure the same thing by different routes.
4706    InflatedBoard = 4,
4707    /// An objective's wording changed and none of its indicators was
4708    /// revisited afterwards.
4709    ObjectiveIndicatorDrift = 5,
4710}
4711impl DiagnosisFindingKind {
4712    /// String value of the enum field names used in the ProtoBuf definition.
4713    ///
4714    /// The values are not transformed in any way and thus are considered stable
4715    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4716    pub fn as_str_name(&self) -> &'static str {
4717        match self {
4718            Self::Unspecified => "DIAGNOSIS_FINDING_KIND_UNSPECIFIED",
4719            Self::PerverseConductRisk => "DIAGNOSIS_FINDING_KIND_PERVERSE_CONDUCT_RISK",
4720            Self::LeverImbalance => "DIAGNOSIS_FINDING_KIND_LEVER_IMBALANCE",
4721            Self::NonExclusiveSet => "DIAGNOSIS_FINDING_KIND_NON_EXCLUSIVE_SET",
4722            Self::InflatedBoard => "DIAGNOSIS_FINDING_KIND_INFLATED_BOARD",
4723            Self::ObjectiveIndicatorDrift => "DIAGNOSIS_FINDING_KIND_OBJECTIVE_INDICATOR_DRIFT",
4724        }
4725    }
4726    /// Creates an enum from field names used in the ProtoBuf definition.
4727    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4728        match value {
4729            "DIAGNOSIS_FINDING_KIND_UNSPECIFIED" => Some(Self::Unspecified),
4730            "DIAGNOSIS_FINDING_KIND_PERVERSE_CONDUCT_RISK" => Some(Self::PerverseConductRisk),
4731            "DIAGNOSIS_FINDING_KIND_LEVER_IMBALANCE" => Some(Self::LeverImbalance),
4732            "DIAGNOSIS_FINDING_KIND_NON_EXCLUSIVE_SET" => Some(Self::NonExclusiveSet),
4733            "DIAGNOSIS_FINDING_KIND_INFLATED_BOARD" => Some(Self::InflatedBoard),
4734            "DIAGNOSIS_FINDING_KIND_OBJECTIVE_INDICATOR_DRIFT" => Some(Self::ObjectiveIndicatorDrift),
4735            _ => None,
4736        }
4737    }
4738}
4739// ─── Messages ───────────────────────────────────────────────────────────────
4740
4741/// A single reachability registry row, returned by `GetReachability` and
4742/// `ListReachabilityForUser`. The plaintext identifier and envelope ciphertext
4743/// are NEVER returned over the wire — only metadata. The dispatch worker reads
4744/// the plaintext directly from the database and decrypts via KMS.
4745#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4746pub struct Reachability {
4747    /// Server-assigned row identifier (UUID).
4748    #[prost(string, tag="1")]
4749    pub id: ::prost::alloc::string::String,
4750    /// Organization that owns this reachability entry.
4751    #[prost(string, tag="2")]
4752    pub org_id: ::prost::alloc::string::String,
4753    /// User this reachability entry is for.
4754    #[prost(string, tag="3")]
4755    pub user_id: ::prost::alloc::string::String,
4756    /// Channel for which this entry stores a contact identifier.
4757    #[prost(enumeration="ChannelName", tag="4")]
4758    pub channel: i32,
4759    /// When the row was first written.
4760    #[prost(message, optional, tag="5")]
4761    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
4762    /// When the row was last upserted.
4763    #[prost(message, optional, tag="6")]
4764    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4765    /// Optional AWS region identifier (e.g. "eu-west-1") this user's data must
4766    /// remain in for GDPR/residency reasons. Unset means "no constraint."
4767    /// Enforcement happens at dispatch time, not write time.
4768    #[prost(string, optional, tag="7")]
4769    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
4770}
4771/// Per-(org, channel) region allowlist used by the dispatch worker to enforce
4772/// data-residency policy. An empty `allowed_regions` list means "no policy
4773/// configured" — NOT "no regions allowed."
4774#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4775pub struct RegionPolicy {
4776    #[prost(string, tag="1")]
4777    pub org_id: ::prost::alloc::string::String,
4778    #[prost(enumeration="ChannelName", tag="2")]
4779    pub channel: i32,
4780    /// AWS region identifiers (e.g. "eu-west-1", "us-east-1"). Empty list ==
4781    /// "no policy configured" — the dispatch worker SHALL NOT block on empty.
4782    #[prost(string, repeated, tag="3")]
4783    pub allowed_regions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4784    #[prost(message, optional, tag="4")]
4785    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
4786}
4787// ─── Enums ──────────────────────────────────────────────────────────────────
4788
4789/// Terminal status of a single dispatch attempt as returned by the worker-mode
4790/// `DispatchToChannel` RPC. Distinct from the richer `ChannelEventStatus` in
4791/// `channel_events.proto`, which models the audit-trail row for every state
4792/// transition (SENT → DELIVERED → OPENED → …). DispatchStatus is the immediate
4793/// outcome of one worker call.
4794#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
4795#[repr(i32)]
4796pub enum DispatchStatus {
4797    /// Default value; should not be used explicitly.
4798    Unspecified = 0,
4799    /// The adapter accepted the message for delivery (provider returned success).
4800    Sent = 1,
4801    /// The adapter returned a terminal error (e.g. recipient blocked, domain not
4802    /// verified). Retries SHALL NOT be attempted; consult `failure_reason`.
4803    Failed = 2,
4804    /// An existing `(dispatch_id, SENT)` row was found by the idempotency guard
4805    /// before the adapter was called; the prior receipt was returned without a
4806    /// second provider call.
4807    Deduped = 3,
4808}
4809impl DispatchStatus {
4810    /// String value of the enum field names used in the ProtoBuf definition.
4811    ///
4812    /// The values are not transformed in any way and thus are considered stable
4813    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
4814    pub fn as_str_name(&self) -> &'static str {
4815        match self {
4816            Self::Unspecified => "DISPATCH_STATUS_UNSPECIFIED",
4817            Self::Sent => "DISPATCH_STATUS_SENT",
4818            Self::Failed => "DISPATCH_STATUS_FAILED",
4819            Self::Deduped => "DISPATCH_STATUS_DEDUPED",
4820        }
4821    }
4822    /// Creates an enum from field names used in the ProtoBuf definition.
4823    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
4824        match value {
4825            "DISPATCH_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
4826            "DISPATCH_STATUS_SENT" => Some(Self::Sent),
4827            "DISPATCH_STATUS_FAILED" => Some(Self::Failed),
4828            "DISPATCH_STATUS_DEDUPED" => Some(Self::Deduped),
4829            _ => None,
4830        }
4831    }
4832}
4833// ─── DispatchToChannel ──────────────────────────────────────────────────────
4834
4835/// Worker-mode entry point invoked by the Temporal worker for one recipient.
4836/// Idempotent on `dispatch_id`: if a `(dispatch_id, SENT)` row already exists
4837/// in `channel_dispatches`, the worker SHALL return DISPATCH_STATUS_DEDUPED
4838/// without re-invoking the channel adapter.
4839#[derive(Clone, PartialEq, ::prost::Message)]
4840pub struct DispatchToChannelRequest {
4841    /// Idempotency key. Must be stable across retries from pidgr-api side.
4842    #[prost(string, tag="1")]
4843    pub dispatch_id: ::prost::alloc::string::String,
4844    #[prost(string, tag="2")]
4845    pub org_id: ::prost::alloc::string::String,
4846    #[prost(string, tag="3")]
4847    pub user_id: ::prost::alloc::string::String,
4848    /// Which channel adapter to invoke (EMAIL is the Wave 1 implementation).
4849    #[prost(enumeration="ChannelName", tag="4")]
4850    pub channel: i32,
4851    /// Template to render before dispatch.
4852    #[prost(string, tag="5")]
4853    pub template_id: ::prost::alloc::string::String,
4854    /// Per-recipient template variables.
4855    #[prost(map="string, string", tag="6")]
4856    pub template_vars: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
4857    /// BCP-47 locale used to select the template translation.
4858    #[prost(string, tag="7")]
4859    pub locale: ::prost::alloc::string::String,
4860    /// Optional AWS region the worker MUST dispatch from (typically copied from
4861    /// the recipient's reachability row). Unset means "no constraint."
4862    #[prost(string, optional, tag="8")]
4863    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
4864}
4865#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4866pub struct DispatchToChannelResponse {
4867    /// Echoes back the request's `dispatch_id`.
4868    #[prost(string, tag="1")]
4869    pub dispatch_id: ::prost::alloc::string::String,
4870    /// Terminal outcome of this call.
4871    #[prost(enumeration="DispatchStatus", tag="2")]
4872    pub status: i32,
4873    /// Human-readable failure reason; set only when `status` is
4874    /// DISPATCH_STATUS_FAILED.
4875    #[prost(string, optional, tag="3")]
4876    pub failure_reason: ::core::option::Option<::prost::alloc::string::String>,
4877}
4878// ─── UpsertReachability ─────────────────────────────────────────────────────
4879
4880/// Records a recipient identifier for a (user, channel) tuple. The plaintext
4881/// identifier is column-level KMS-encrypted on insert and never logged or
4882/// returned. The server computes the org-scoped HMAC lookup hash so opt-out
4883/// webhooks can find the row without decrypt.
4884#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4885pub struct UpsertReachabilityRequest {
4886    #[prost(string, tag="1")]
4887    pub org_id: ::prost::alloc::string::String,
4888    #[prost(string, tag="2")]
4889    pub user_id: ::prost::alloc::string::String,
4890    #[prost(enumeration="ChannelName", tag="3")]
4891    pub channel: i32,
4892    /// The plaintext identifier (email address, phone number, Slack user ID,
4893    /// Telegram chat ID, etc.). Encrypted at rest server-side. Servers MUST NOT
4894    /// log this field. Clients SHOULD treat this message as sensitive.
4895    #[prost(string, tag="4")]
4896    pub identifier_plaintext: ::prost::alloc::string::String,
4897    /// Optional AWS region this user's data must remain in (e.g. "eu-west-1").
4898    /// Recorded but NOT enforced at write time; enforcement is at dispatch.
4899    #[prost(string, optional, tag="5")]
4900    pub region_constraint: ::core::option::Option<::prost::alloc::string::String>,
4901}
4902#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4903pub struct UpsertReachabilityResponse {
4904    /// The metadata for the upserted row. Plaintext identifier and envelope
4905    /// ciphertext are intentionally absent.
4906    #[prost(message, optional, tag="1")]
4907    pub reachability: ::core::option::Option<Reachability>,
4908}
4909// ─── RemoveReachability ─────────────────────────────────────────────────────
4910
4911/// Idempotent removal. GDPR Recital 30 audit row is appended via internal-mTLS
4912/// BEFORE the registry row is deleted (see AuditService.Append). If no row
4913/// existed, `removed = false` and no audit row is emitted.
4914#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4915pub struct RemoveReachabilityRequest {
4916    #[prost(string, tag="1")]
4917    pub org_id: ::prost::alloc::string::String,
4918    #[prost(string, tag="2")]
4919    pub user_id: ::prost::alloc::string::String,
4920    #[prost(enumeration="ChannelName", tag="3")]
4921    pub channel: i32,
4922}
4923#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
4924pub struct RemoveReachabilityResponse {
4925    /// True if a row was deleted. False if no row existed for the tuple
4926    /// (idempotent success).
4927    #[prost(bool, tag="1")]
4928    pub removed: bool,
4929}
4930// ─── GetReachability ────────────────────────────────────────────────────────
4931
4932/// Returns the reachability metadata for a single (user, channel) tuple.
4933/// Returns NOT_FOUND if no row exists.
4934#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4935pub struct GetReachabilityRequest {
4936    #[prost(string, tag="1")]
4937    pub org_id: ::prost::alloc::string::String,
4938    #[prost(string, tag="2")]
4939    pub user_id: ::prost::alloc::string::String,
4940    #[prost(enumeration="ChannelName", tag="3")]
4941    pub channel: i32,
4942}
4943#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4944pub struct GetReachabilityResponse {
4945    /// Plaintext identifier and envelope ciphertext are intentionally absent.
4946    #[prost(message, optional, tag="1")]
4947    pub reachability: ::core::option::Option<Reachability>,
4948}
4949// ─── ListReachabilityForUser ────────────────────────────────────────────────
4950
4951/// Returns one Reachability entry per channel configured for a (org, user)
4952/// pair. Used by the admin-side per-user matrix view. Plaintext identifiers
4953/// and envelope ciphertext are intentionally absent — the admin UI only needs
4954/// to know which channels are configured.
4955#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4956pub struct ListReachabilityForUserRequest {
4957    #[prost(string, tag="1")]
4958    pub org_id: ::prost::alloc::string::String,
4959    #[prost(string, tag="2")]
4960    pub user_id: ::prost::alloc::string::String,
4961}
4962#[derive(Clone, PartialEq, ::prost::Message)]
4963pub struct ListReachabilityForUserResponse {
4964    /// One entry per channel that has a row for the (org_id, user_id) pair.
4965    #[prost(message, repeated, tag="1")]
4966    pub reachabilities: ::prost::alloc::vec::Vec<Reachability>,
4967}
4968// ─── GetRegionPolicy / SetRegionPolicy ──────────────────────────────────────
4969
4970#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4971pub struct GetRegionPolicyRequest {
4972    #[prost(string, tag="1")]
4973    pub org_id: ::prost::alloc::string::String,
4974    #[prost(enumeration="ChannelName", tag="2")]
4975    pub channel: i32,
4976}
4977#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4978pub struct GetRegionPolicyResponse {
4979    /// Always populated. Empty `allowed_regions` means "no policy configured"
4980    /// — NOT "no regions allowed."
4981    #[prost(message, optional, tag="1")]
4982    pub policy: ::core::option::Option<RegionPolicy>,
4983}
4984/// Admin-only upsert. Empty `allowed_regions` clears the policy.
4985#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4986pub struct SetRegionPolicyRequest {
4987    #[prost(string, tag="1")]
4988    pub org_id: ::prost::alloc::string::String,
4989    #[prost(enumeration="ChannelName", tag="2")]
4990    pub channel: i32,
4991    /// AWS region identifiers (e.g. "eu-west-1"). Empty list == "no policy."
4992    #[prost(string, repeated, tag="3")]
4993    pub allowed_regions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
4994}
4995#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
4996pub struct SetRegionPolicyResponse {
4997    #[prost(message, optional, tag="1")]
4998    pub policy: ::core::option::Option<RegionPolicy>,
4999}
5000// ─── GetCostCapPolicy / SetCostCapPolicy ────────────────────────────────────
5001
5002/// Get the cost-cap state for the current calendar-month period (UTC). When
5003/// no row exists for `(org_id, channel, period_yyyymm)`, the server returns
5004/// the channel default cap from server config
5005/// (`COST_CAP_DEFAULT_${CHANNEL}_MICROS`) with `used_micros = 0`.
5006#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5007pub struct GetCostCapPolicyRequest {
5008    #[prost(string, tag="1")]
5009    pub org_id: ::prost::alloc::string::String,
5010    #[prost(enumeration="ChannelName", tag="2")]
5011    pub channel: i32,
5012}
5013#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5014pub struct GetCostCapPolicyResponse {
5015    #[prost(string, tag="1")]
5016    pub org_id: ::prost::alloc::string::String,
5017    #[prost(enumeration="ChannelName", tag="2")]
5018    pub channel: i32,
5019    /// Current period's cap in micros (1/1_000_000 of a USD).
5020    #[prost(int64, tag="3")]
5021    pub cap_micros: i64,
5022    /// Current period's accumulated spend in micros.
5023    #[prost(int64, tag="4")]
5024    pub used_micros: i64,
5025    /// Calendar-month period in integer YYYYMM form (e.g. 202605 for May 2026).
5026    #[prost(int32, tag="5")]
5027    pub period_yyyymm: i32,
5028}
5029/// Admin-only upsert of the cap for the current calendar-month period. Future
5030/// periods inherit the most recent SetCostCapPolicy value until the next call.
5031#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5032pub struct SetCostCapPolicyRequest {
5033    #[prost(string, tag="1")]
5034    pub org_id: ::prost::alloc::string::String,
5035    #[prost(enumeration="ChannelName", tag="2")]
5036    pub channel: i32,
5037    #[prost(int64, tag="3")]
5038    pub cap_micros: i64,
5039}
5040#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5041pub struct SetCostCapPolicyResponse {
5042    #[prost(string, tag="1")]
5043    pub org_id: ::prost::alloc::string::String,
5044    #[prost(enumeration="ChannelName", tag="2")]
5045    pub channel: i32,
5046    #[prost(int64, tag="3")]
5047    pub cap_micros: i64,
5048    #[prost(int64, tag="4")]
5049    pub used_micros: i64,
5050    #[prost(int32, tag="5")]
5051    pub period_yyyymm: i32,
5052}
5053// ─── GetOrgWebhookConfig / SetOrgWebhookConfig ──────────────────────────────
5054
5055/// Get the org's generic-webhook channel configuration. The shared secret is
5056/// write-only and never returned — `has_secret` reports whether one is set.
5057#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5058pub struct GetOrgWebhookConfigRequest {
5059    #[prost(string, tag="1")]
5060    pub org_id: ::prost::alloc::string::String,
5061}
5062#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5063pub struct GetOrgWebhookConfigResponse {
5064    #[prost(string, tag="1")]
5065    pub org_id: ::prost::alloc::string::String,
5066    /// Destination URL Pidgr POSTs notification events to. Empty when no
5067    /// configuration exists.
5068    #[prost(string, tag="2")]
5069    pub url: ::prost::alloc::string::String,
5070    /// Whether dispatch via the WEBHOOK channel is enabled for the org.
5071    #[prost(bool, tag="3")]
5072    pub enabled: bool,
5073    /// Whether a signing secret is currently configured. The secret itself is
5074    /// never returned.
5075    #[prost(bool, tag="4")]
5076    pub has_secret: bool,
5077    #[prost(message, optional, tag="5")]
5078    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5079    #[prost(message, optional, tag="6")]
5080    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5081}
5082/// Admin-only upsert of the org's generic-webhook configuration. The server
5083/// validates the URL (https-only, public addresses only) before persisting,
5084/// and envelope-encrypts the secret at rest. Setting a new `secret` rotates
5085/// it; leaving `secret` unset keeps the existing one.
5086#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5087pub struct SetOrgWebhookConfigRequest {
5088    #[prost(string, tag="1")]
5089    pub org_id: ::prost::alloc::string::String,
5090    /// Destination URL. Constraints: https scheme; non-private, non-loopback
5091    /// host. Validation failures return `invalid_argument`.
5092    #[prost(string, tag="2")]
5093    pub url: ::prost::alloc::string::String,
5094    #[prost(bool, tag="3")]
5095    pub enabled: bool,
5096    /// Shared secret used for the `X-Pidgr-Signature` HMAC-SHA256 header.
5097    /// Write-only. Unset keeps the current secret; set rotates it.
5098    /// Constraints: 16–256 bytes when set.
5099    #[prost(string, optional, tag="4")]
5100    pub secret: ::core::option::Option<::prost::alloc::string::String>,
5101}
5102#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5103pub struct SetOrgWebhookConfigResponse {
5104    #[prost(string, tag="1")]
5105    pub org_id: ::prost::alloc::string::String,
5106    #[prost(string, tag="2")]
5107    pub url: ::prost::alloc::string::String,
5108    #[prost(bool, tag="3")]
5109    pub enabled: bool,
5110    #[prost(bool, tag="4")]
5111    pub has_secret: bool,
5112    #[prost(message, optional, tag="5")]
5113    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5114    #[prost(message, optional, tag="6")]
5115    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5116}
5117// ─── CreateChannelConnectLink ───────────────────────────────────────────────
5118
5119/// Mints a short-lived, HMAC-signed opt-in link a user follows to bind a
5120/// third-party channel to their (org, user). Only follow-style channels are
5121/// accepted: CHANNEL_NAME_TELEGRAM (bot-follow), CHANNEL_NAME_SLACK (OAuth),
5122/// CHANNEL_NAME_LINE (follow-code). Any other channel is rejected server-side
5123/// with `invalid_argument`. Wraps the pidgr-api `internal/linktoken` minter.
5124#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5125pub struct CreateChannelConnectLinkRequest {
5126    #[prost(string, tag="1")]
5127    pub org_id: ::prost::alloc::string::String,
5128    /// Internal user UUID; resolved via UserResolver on the server. The minted
5129    /// token binds the resulting channel identifier to this (org, user).
5130    #[prost(string, tag="2")]
5131    pub user_id: ::prost::alloc::string::String,
5132    /// Channel to connect. Constraints: must be one of CHANNEL_NAME_TELEGRAM,
5133    /// CHANNEL_NAME_SLACK, CHANNEL_NAME_LINE. Other values return
5134    /// `invalid_argument`.
5135    #[prost(enumeration="ChannelName", tag="3")]
5136    pub channel: i32,
5137}
5138#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5139pub struct CreateChannelConnectLinkResponse {
5140    /// The deep link the client renders for the user to follow (e.g. a
5141    /// Telegram bot-follow URL, Slack OAuth authorize URL, or LINE follow URL).
5142    #[prost(string, tag="1")]
5143    pub connect_url: ::prost::alloc::string::String,
5144    /// The raw 64-char base64url opt-in token embedded in `connect_url`,
5145    /// surfaced separately so clients can render it as a QR code or copy
5146    /// button. Implementation detail — clients SHOULD NOT parse or mutate it.
5147    #[prost(string, tag="2")]
5148    pub token: ::prost::alloc::string::String,
5149    /// When the minted token expires. After this time the link no longer
5150    /// binds and the user must request a fresh one.
5151    #[prost(message, optional, tag="3")]
5152    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5153}
5154// ─── CreateSlackWorkspaceInstallAuthorization ───────────────────────────────
5155
5156/// Mints a short-lived, HMAC-signed token authorizing a Slack WORKSPACE
5157/// install into the caller's AUTHORIZED org. The admin passes the token to the
5158/// pidgr-integrations install-start endpoint, which verifies it and installs
5159/// into the org the token binds — not the caller's JWT home org. This is the
5160/// workspace-install analogue of CreateChannelConnectLink (which binds the
5161/// per-user link flow): without it, a multi-org admin who selects a non-home
5162/// org still installs the bot into their home org, because the install-start
5163/// endpoint has no Cognito-sub→internal-id resolver of its own and falls back
5164/// to the JWT org claim.
5165#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5166pub struct CreateSlackWorkspaceInstallAuthorizationRequest {
5167    /// Must equal the caller's authorized org (auth.OrgID) — cross-org minting is
5168    /// rejected with permission_denied.
5169    #[prost(string, tag="1")]
5170    pub org_id: ::prost::alloc::string::String,
5171}
5172#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5173pub struct CreateSlackWorkspaceInstallAuthorizationResponse {
5174    /// The opaque HMAC token the client passes as the `token` query parameter to
5175    /// the integrations `/webhooks/slack/oauth/install/start` endpoint. It binds
5176    /// the authorized (org, internal user id) and an expiry. Implementation
5177    /// detail — clients SHOULD NOT parse or mutate it.
5178    #[prost(string, tag="1")]
5179    pub token: ::prost::alloc::string::String,
5180    /// When the minted token expires. After this the admin must request a fresh
5181    /// one before starting the install.
5182    #[prost(message, optional, tag="2")]
5183    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5184}
5185// ─── Messages ───────────────────────────────────────────────────────────────
5186
5187/// A shareable invite link that allows users to self-join an organization.
5188/// Links carry a role assignment and optional usage/expiry constraints.
5189#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5190pub struct InviteLink {
5191    /// Unique identifier for the invite link.
5192    #[prost(string, tag="1")]
5193    pub id: ::prost::alloc::string::String,
5194    /// Cryptographically random base64url-encoded token (43 characters).
5195    #[prost(string, tag="2")]
5196    pub token: ::prost::alloc::string::String,
5197    /// ID of the role assigned to users who redeem this link.
5198    #[prost(string, tag="3")]
5199    pub role_id: ::prost::alloc::string::String,
5200    /// Maximum number of times this link can be redeemed.
5201    /// 0 means unlimited.
5202    #[prost(int32, tag="4")]
5203    pub max_uses: i32,
5204    /// Number of times this link has been redeemed.
5205    #[prost(int32, tag="5")]
5206    pub use_count: i32,
5207    /// When the link expires. Empty if no expiry.
5208    #[prost(message, optional, tag="6")]
5209    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
5210    /// When the link was revoked. Empty if not revoked.
5211    #[prost(message, optional, tag="7")]
5212    pub revoked_at: ::core::option::Option<::prost_types::Timestamp>,
5213    /// ID of the admin who created the link.
5214    #[prost(string, tag="8")]
5215    pub created_by: ::prost::alloc::string::String,
5216    /// When the link was created.
5217    #[prost(message, optional, tag="9")]
5218    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5219    /// Data governance region assigned to users who redeem this link. Empty means inherit from org default.
5220    /// Valid values: EU, LATAM, BR, APAC, US.
5221    #[prost(string, tag="10")]
5222    pub data_governance_region: ::prost::alloc::string::String,
5223}
5224/// Request to create a new invite link for the organization.
5225#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5226pub struct CreateInviteLinkRequest {
5227    /// ID of the role to assign. Defaults to the organization's employee role if empty.
5228    #[prost(string, tag="1")]
5229    pub role_id: ::prost::alloc::string::String,
5230    /// Maximum number of redemptions. 0 means unlimited.
5231    #[prost(int32, tag="2")]
5232    pub max_uses: i32,
5233    /// Number of hours until the link expires. 0 means no expiry.
5234    /// Constraints: Valid range 0 to 8760 (1 year).
5235    #[prost(int32, tag="3")]
5236    pub expires_in_hours: i32,
5237    /// Optional data governance region. Users who redeem this link inherit this region. Empty means inherit from org default.
5238    /// Valid values: EU, LATAM, BR, APAC, US.
5239    #[prost(string, tag="4")]
5240    pub data_governance_region: ::prost::alloc::string::String,
5241}
5242/// Response after creating an invite link.
5243#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5244pub struct CreateInviteLinkResponse {
5245    /// The newly created invite link.
5246    #[prost(message, optional, tag="1")]
5247    pub invite_link: ::core::option::Option<InviteLink>,
5248    /// Full URL for sharing (e.g. "<https://app.pidgr.com/join?token=<TOKEN>">).
5249    #[prost(string, tag="2")]
5250    pub url: ::prost::alloc::string::String,
5251}
5252/// Request to list all invite links for the organization.
5253#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5254pub struct ListInviteLinksRequest {
5255}
5256/// Response containing all invite links for the organization.
5257#[derive(Clone, PartialEq, ::prost::Message)]
5258pub struct ListInviteLinksResponse {
5259    /// All invite links (active, expired, maxed-out, and revoked), ordered by creation date descending.
5260    #[prost(message, repeated, tag="1")]
5261    pub invite_links: ::prost::alloc::vec::Vec<InviteLink>,
5262}
5263/// Request to revoke an invite link.
5264#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5265pub struct RevokeInviteLinkRequest {
5266    /// ID of the invite link to revoke. Required.
5267    #[prost(string, tag="1")]
5268    pub invite_link_id: ::prost::alloc::string::String,
5269}
5270/// Response after revoking an invite link.
5271#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5272pub struct RevokeInviteLinkResponse {
5273}
5274/// Request to redeem an invite link (authenticated — email extracted from JWT).
5275#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5276pub struct RedeemInviteLinkRequest {
5277    /// The invite link token from the URL query parameter.
5278    #[prost(string, tag="1")]
5279    pub token: ::prost::alloc::string::String,
5280}
5281/// Response after redeeming an invite link.
5282#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5283pub struct RedeemInviteLinkResponse {
5284    /// Name of the organization the user was added to.
5285    #[prost(string, tag="1")]
5286    pub organization_name: ::prost::alloc::string::String,
5287}
5288/// Request to validate an invite link and provision a user account if needed (unauthenticated).
5289#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5290pub struct ValidateInviteLinkRequest {
5291    /// The invite link token from the URL query parameter.
5292    #[prost(string, tag="1")]
5293    pub token: ::prost::alloc::string::String,
5294    /// Email address of the user joining the organization.
5295    /// Constraints: Max length 254 characters (RFC 5321).
5296    #[prost(string, tag="2")]
5297    pub email: ::prost::alloc::string::String,
5298}
5299/// Response after validating an invite link.
5300#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5301pub struct ValidateInviteLinkResponse {
5302    /// Name of the organization the invite link belongs to.
5303    #[prost(string, tag="1")]
5304    pub organization_name: ::prost::alloc::string::String,
5305}
5306// ─── Messages ───────────────────────────────────────────────────────────────
5307
5308/// Request to invite a new user to the organization.
5309#[derive(Clone, PartialEq, ::prost::Message)]
5310pub struct InviteUserRequest {
5311    /// Email address to send the invitation to.
5312    /// Constraints: Max length 254 characters (RFC 5321).
5313    #[prost(string, tag="1")]
5314    pub email: ::prost::alloc::string::String,
5315    /// Display name for the invited user.
5316    /// Constraints: Max length 200 characters.
5317    #[prost(string, tag="2")]
5318    pub name: ::prost::alloc::string::String,
5319    /// ID of the role to assign. Defaults to the organization's employee role if empty.
5320    #[prost(string, tag="4")]
5321    pub role_id: ::prost::alloc::string::String,
5322    /// Optional profile attributes to pre-fill at invitation time.
5323    #[prost(message, optional, tag="5")]
5324    pub profile: ::core::option::Option<UserProfile>,
5325    /// Optional data governance region for the invited user. Empty means inherit from org default.
5326    /// Valid values: EU, LATAM, BR, APAC, US.
5327    #[prost(string, tag="6")]
5328    pub data_governance_region: ::prost::alloc::string::String,
5329}
5330/// Response after inviting a user.
5331#[derive(Clone, PartialEq, ::prost::Message)]
5332pub struct InviteUserResponse {
5333    /// The newly created user (status: INVITED).
5334    #[prost(message, optional, tag="1")]
5335    pub user: ::core::option::Option<User>,
5336}
5337/// Request to retrieve a user by ID.
5338#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5339pub struct GetUserRequest {
5340    /// ID of the user to retrieve.
5341    #[prost(string, tag="1")]
5342    pub user_id: ::prost::alloc::string::String,
5343}
5344/// Response containing the requested user.
5345#[derive(Clone, PartialEq, ::prost::Message)]
5346pub struct GetUserResponse {
5347    /// The requested user.
5348    #[prost(message, optional, tag="1")]
5349    pub user: ::core::option::Option<User>,
5350}
5351/// Request to list users in the organization with pagination.
5352#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5353pub struct ListUsersRequest {
5354    /// Pagination parameters.
5355    #[prost(message, optional, tag="1")]
5356    pub pagination: ::core::option::Option<Pagination>,
5357}
5358/// Response containing a page of users.
5359#[derive(Clone, PartialEq, ::prost::Message)]
5360pub struct ListUsersResponse {
5361    /// List of users in this page.
5362    #[prost(message, repeated, tag="1")]
5363    pub users: ::prost::alloc::vec::Vec<User>,
5364    /// Pagination metadata for fetching subsequent pages.
5365    #[prost(message, optional, tag="2")]
5366    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5367}
5368/// Request to change a user's role within the organization.
5369#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5370pub struct UpdateUserRoleRequest {
5371    /// ID of the user whose role to update.
5372    #[prost(string, tag="1")]
5373    pub user_id: ::prost::alloc::string::String,
5374    /// ID of the new role to assign.
5375    #[prost(string, tag="2")]
5376    pub role_id: ::prost::alloc::string::String,
5377}
5378/// Response after updating a user's role.
5379#[derive(Clone, PartialEq, ::prost::Message)]
5380pub struct UpdateUserRoleResponse {
5381    /// The updated user with the new role.
5382    #[prost(message, optional, tag="1")]
5383    pub user: ::core::option::Option<User>,
5384}
5385/// Request to deactivate a user within the organization.
5386#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5387pub struct DeactivateUserRequest {
5388    /// ID of the user to deactivate.
5389    #[prost(string, tag="1")]
5390    pub user_id: ::prost::alloc::string::String,
5391}
5392/// Response after deactivating a user.
5393#[derive(Clone, PartialEq, ::prost::Message)]
5394pub struct DeactivateUserResponse {
5395    /// The deactivated user (status: DEACTIVATED).
5396    #[prost(message, optional, tag="1")]
5397    pub user: ::core::option::Option<User>,
5398}
5399/// Request to reactivate a deactivated user.
5400#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5401pub struct ReactivateUserRequest {
5402    /// ID of the user to reactivate.
5403    #[prost(string, tag="1")]
5404    pub user_id: ::prost::alloc::string::String,
5405}
5406/// Response after reactivating a user.
5407#[derive(Clone, PartialEq, ::prost::Message)]
5408pub struct ReactivateUserResponse {
5409    /// The reactivated user (status: INVITED).
5410    #[prost(message, optional, tag="1")]
5411    pub user: ::core::option::Option<User>,
5412}
5413/// Request to revoke an invitation for a user who has not yet registered.
5414#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5415pub struct RevokeInviteRequest {
5416    /// ID of the invited user to remove.
5417    /// Constraints: UUID format (36 characters).
5418    #[prost(string, tag="1")]
5419    pub user_id: ::prost::alloc::string::String,
5420}
5421/// Response after revoking an invitation. Empty on success.
5422#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5423pub struct RevokeInviteResponse {
5424}
5425/// Request to update a user's profile attributes.
5426#[derive(Clone, PartialEq, ::prost::Message)]
5427pub struct UpdateUserProfileRequest {
5428    /// ID of the user whose profile to update.
5429    /// Empty or matching the caller's own ID allows self-update without PERMISSION_MEMBERS_MANAGE.
5430    #[prost(string, tag="1")]
5431    pub user_id: ::prost::alloc::string::String,
5432    /// Profile attributes to set. All provided fields overwrite existing values.
5433    #[prost(message, optional, tag="2")]
5434    pub profile: ::core::option::Option<UserProfile>,
5435}
5436/// Response after updating a user's profile.
5437#[derive(Clone, PartialEq, ::prost::Message)]
5438pub struct UpdateUserProfileResponse {
5439    /// The updated user with the new profile.
5440    #[prost(message, optional, tag="1")]
5441    pub user: ::core::option::Option<User>,
5442}
5443/// Request to retrieve the caller's platform settings.
5444#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5445pub struct GetUserSettingsRequest {
5446}
5447/// Response containing the caller's platform settings.
5448#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5449pub struct GetUserSettingsResponse {
5450    /// Current settings. Fields at their default value indicate the platform default.
5451    #[prost(message, optional, tag="1")]
5452    pub settings: ::core::option::Option<UserSettings>,
5453}
5454/// Request to update the caller's platform settings.
5455#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5456pub struct UpdateUserSettingsRequest {
5457    /// Settings to update. Only fields with non-default (non-UNSPECIFIED) values
5458    /// are applied; default-valued fields are left unchanged.
5459    #[prost(message, optional, tag="1")]
5460    pub settings: ::core::option::Option<UserSettings>,
5461}
5462/// Response after updating the caller's platform settings.
5463#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5464pub struct UpdateUserSettingsResponse {
5465    /// The full settings after the update.
5466    #[prost(message, optional, tag="1")]
5467    pub settings: ::core::option::Option<UserSettings>,
5468}
5469/// Request to invite multiple users to the organization in a single call.
5470#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5471pub struct BulkInviteUsersRequest {
5472    /// Email addresses to invite.
5473    /// Constraints: Min 1, max 100 emails. Duplicates are deduplicated before processing.
5474    #[prost(string, repeated, tag="1")]
5475    pub emails: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
5476    /// ID of the role to assign. Defaults to the organization's employee role if empty.
5477    #[prost(string, tag="2")]
5478    pub role_id: ::prost::alloc::string::String,
5479}
5480/// Per-email result within a bulk invite operation.
5481#[derive(Clone, PartialEq, ::prost::Message)]
5482pub struct BulkInviteResult {
5483    /// The email address that was processed.
5484    #[prost(string, tag="1")]
5485    pub email: ::prost::alloc::string::String,
5486    /// Whether the invitation succeeded.
5487    #[prost(bool, tag="2")]
5488    pub success: bool,
5489    /// Error message if the invitation failed (e.g. "user already exists").
5490    /// Empty on success.
5491    #[prost(string, tag="3")]
5492    pub error: ::prost::alloc::string::String,
5493    /// The created user. Only set on success.
5494    #[prost(message, optional, tag="4")]
5495    pub user: ::core::option::Option<User>,
5496}
5497/// Response after bulk inviting users.
5498#[derive(Clone, PartialEq, ::prost::Message)]
5499pub struct BulkInviteUsersResponse {
5500    /// Per-email results in the same order as the deduplicated input.
5501    #[prost(message, repeated, tag="1")]
5502    pub results: ::prost::alloc::vec::Vec<BulkInviteResult>,
5503    /// Number of users successfully invited.
5504    #[prost(int32, tag="2")]
5505    pub invited_count: i32,
5506    /// Number of emails that failed.
5507    #[prost(int32, tag="3")]
5508    pub failed_count: i32,
5509}
5510/// Request to confirm passkey enrollment after client-side WebAuthn registration.
5511/// The server verifies that the caller has at least one registered WebAuthn
5512/// credential before setting the enrollment attribute.
5513#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5514pub struct ConfirmPasskeyEnrollmentRequest {
5515}
5516/// Response after confirming passkey enrollment.
5517#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5518pub struct ConfirmPasskeyEnrollmentResponse {
5519    /// Whether enrollment was confirmed and the user attribute was updated.
5520    #[prost(bool, tag="1")]
5521    pub confirmed: bool,
5522}
5523/// Request to update a user's data governance region.
5524#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5525pub struct UpdateUserRegionRequest {
5526    /// ID of the user whose region to update. Required.
5527    #[prost(string, tag="1")]
5528    pub user_id: ::prost::alloc::string::String,
5529    /// New governance region, or empty to inherit from org default.
5530    /// Valid values: EU, LATAM, BR, APAC, US.
5531    #[prost(string, tag="2")]
5532    pub data_governance_region: ::prost::alloc::string::String,
5533}
5534/// Response after updating a user's governance region.
5535#[derive(Clone, PartialEq, ::prost::Message)]
5536pub struct UpdateUserRegionResponse {
5537    /// The updated user.
5538    #[prost(message, optional, tag="1")]
5539    pub user: ::core::option::Option<User>,
5540    /// Temporal workflow ID for the region migration, if a migration was triggered.
5541    /// Empty if the region didn't actually change.
5542    #[prost(string, tag="2")]
5543    pub migration_workflow_id: ::prost::alloc::string::String,
5544}
5545// ─── Messages ───────────────────────────────────────────────────────────────
5546
5547/// A qualitative statement of a state the organization wants to hold
5548/// true. Owned by the organization, never by a single campaign. Content
5549/// is always authored by the organization; the contract only carries
5550/// structure.
5551#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5552pub struct Objective {
5553    /// Unique identifier for the objective.
5554    #[prost(string, tag="1")]
5555    pub id: ::prost::alloc::string::String,
5556    /// Whether this is a standing objective or a time-bounded initiative.
5557    #[prost(enumeration="ObjectiveKind", tag="2")]
5558    pub kind: i32,
5559    /// The statement itself. Required.
5560    /// Constraints: Max length 300 characters.
5561    #[prost(string, tag="3")]
5562    pub title: ::prost::alloc::string::String,
5563    /// Longer explanation of what the statement means and does not mean.
5564    /// Constraints: Max length 4000 characters.
5565    #[prost(string, tag="4")]
5566    pub description: ::prost::alloc::string::String,
5567    /// ID of the user accountable for the objective. Optional.
5568    #[prost(string, tag="5")]
5569    pub owner_user_id: ::prost::alloc::string::String,
5570    /// Lifecycle state.
5571    #[prost(enumeration="ObjectiveState", tag="6")]
5572    pub state: i32,
5573    /// For an initiative, the standing objective it contributes to. Empty
5574    /// when the initiative stands alone, and always empty for
5575    /// OBJECTIVE_KIND_OBJECTIVE.
5576    #[prost(string, tag="7")]
5577    pub parent_objective_id: ::prost::alloc::string::String,
5578    /// For an initiative, the date it is expected to end. Unset for a
5579    /// standing objective, which by definition does not have one.
5580    #[prost(message, optional, tag="8")]
5581    pub ends_at: ::core::option::Option<::prost_types::Timestamp>,
5582    /// Number of indicators currently attached.
5583    #[prost(int32, tag="9")]
5584    pub indicator_count: i32,
5585    /// Timestamp when the objective was created.
5586    #[prost(message, optional, tag="10")]
5587    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5588    /// Timestamp when the objective was last updated.
5589    #[prost(message, optional, tag="11")]
5590    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5591}
5592/// A form problem found in an objective's wording, returned alongside the
5593/// stored objective. Never blocks the write.
5594#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5595pub struct ObjectiveAdvisory {
5596    /// Which form problem was detected.
5597    #[prost(enumeration="ObjectiveWritingIssue", tag="1")]
5598    pub issue: i32,
5599    /// Plain-language explanation of what was detected and why it matters.
5600    #[prost(string, tag="2")]
5601    pub detail: ::prost::alloc::string::String,
5602    /// A rewrite the author can accept or ignore. May be empty when no
5603    /// rewrite could be produced.
5604    #[prost(string, tag="3")]
5605    pub suggested_rewrite: ::prost::alloc::string::String,
5606}
5607/// Something the author should know before relying on a verification
5608/// campaign as an indicator's evidence, returned alongside the stored
5609/// indicator. Never blocks the write.
5610///
5611/// Asking a verifier about a unit rather than about each of its members
5612/// is what keeps a stored answer from being one person's judgement of
5613/// another. That protection is a function of size: below a handful of
5614/// people, a statement about the unit is in practice a statement about
5615/// each member, and the distinction reconstructs itself. The remedy is to
5616/// put the question at a wider level instead, and where there is no wider
5617/// level, to accept that the objective gets no evidence by this route.
5618///
5619/// The platform does not pick that level by itself. Which units are
5620/// meaningful is something only the organization can state, so the choice
5621/// is the organization's — defaulted organization-wide, overridable per
5622/// indicator — and this notice is what puts the facts in front of the
5623/// person making it, who is also the one who can decide the current shape
5624/// is acceptable. It is deliberately not a warning shown to the verifier
5625/// at the moment of answering: that would claim a safeguard that does not
5626/// exist, and would ask one person to accept a risk that runs to somebody
5627/// else.
5628#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5629pub struct VerificationSetupNotice {
5630    /// What follows from the current configuration, in plain language.
5631    #[prost(string, tag="1")]
5632    pub detail: ::prost::alloc::string::String,
5633    /// How many of the units this derivation would reach are smaller than
5634    /// the floor.
5635    #[prost(int32, tag="2")]
5636    pub units_below_floor: i32,
5637    /// The size at or above which a unit is asked about on its own.
5638    #[prost(int32, tag="3")]
5639    pub unit_floor: i32,
5640    /// The level the question would be put at as things stand, with the
5641    /// indicator's own selection already resolved against the
5642    /// organization's default. Stated outright so that a reader never has
5643    /// to guess whether an inherited default or an explicit choice is in
5644    /// force, and never has to fetch the organization to find out.
5645    #[prost(enumeration="VerificationUnitLevel", tag="4")]
5646    pub effective_unit_level: i32,
5647    /// The levels that would actually reach somebody in this organization,
5648    /// given the structure it has declared. A level absent from this list
5649    /// resolves to no question being asked at all, so offering it as a
5650    /// remedy would trade a visible problem for a silent one.
5651    #[prost(enumeration="VerificationUnitLevel", repeated, tag="5")]
5652    pub selectable_unit_levels: ::prost::alloc::vec::Vec<i32>,
5653}
5654/// A declared way of observing whether an objective holds. Several per
5655/// objective is the intended shape: indicators are individually
5656/// incomplete and are meant to compensate for one another.
5657#[derive(Clone, PartialEq, ::prost::Message)]
5658pub struct Indicator {
5659    /// Unique identifier for the indicator.
5660    #[prost(string, tag="1")]
5661    pub id: ::prost::alloc::string::String,
5662    /// Objective this indicator hangs from.
5663    #[prost(string, tag="2")]
5664    pub objective_id: ::prost::alloc::string::String,
5665    /// Short name for the indicator. Required.
5666    /// Constraints: Max length 200 characters.
5667    #[prost(string, tag="3")]
5668    pub name: ::prost::alloc::string::String,
5669    /// Unit the readings are expressed in (e.g. "percent", "days",
5670    /// "incidents"). Free text so that existing measures can be carried
5671    /// over unchanged.
5672    /// Constraints: Max length 50 characters.
5673    #[prost(string, tag="4")]
5674    pub unit: ::prost::alloc::string::String,
5675    /// Which direction of movement is the desired one.
5676    #[prost(enumeration="IndicatorDirection", tag="5")]
5677    pub direction: i32,
5678    /// How often a reading is expected.
5679    #[prost(enumeration="IndicatorFrequency", tag="6")]
5680    pub frequency: i32,
5681    /// ID of the user accountable for the indicator. Optional.
5682    #[prost(string, tag="7")]
5683    pub owner_user_id: ::prost::alloc::string::String,
5684    /// Where readings come from. Required.
5685    #[prost(message, optional, tag="8")]
5686    pub evidence_source: ::core::option::Option<EvidenceSource>,
5687    /// Why this indicator was chosen over the alternatives.
5688    /// Constraints: Max length 2000 characters.
5689    #[prost(string, tag="9")]
5690    pub rationale: ::prost::alloc::string::String,
5691    /// What the indicator is meant to say about the objective.
5692    /// Constraints: Max length 2000 characters.
5693    #[prost(string, tag="10")]
5694    pub strategic_meaning: ::prost::alloc::string::String,
5695    /// How a reading should be read, including what it does not cover.
5696    /// Constraints: Max length 2000 characters.
5697    #[prost(string, tag="11")]
5698    pub interpretation_guidance: ::prost::alloc::string::String,
5699    /// The behaviour this indicator could encourage if it were optimized
5700    /// on its own. Pre-filled by the server where a structural weakness in
5701    /// the evidence source implies one, always editable, never required.
5702    /// Constraints: Max length 2000 characters.
5703    #[prost(string, tag="12")]
5704    pub perverse_behavior_note: ::prost::alloc::string::String,
5705    /// Whether any reading has ever corroborated this indicator.
5706    #[prost(enumeration="IndicatorVerificationState", tag="13")]
5707    pub verification_state: i32,
5708    /// Timestamp when the indicator was created.
5709    #[prost(message, optional, tag="14")]
5710    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5711    /// Timestamp when the indicator was last updated.
5712    #[prost(message, optional, tag="15")]
5713    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
5714    /// The value the organization is aiming for, expressed in `unit` and
5715    /// read together with `direction`. Absent when no target has been set.
5716    ///
5717    /// Targets live here rather than inside the objective's wording, and
5718    /// they sit at the routine tier of change: revising a target is
5719    /// expected housekeeping, unlike rewriting the objective it serves.
5720    #[prost(double, optional, tag="16")]
5721    pub target: ::core::option::Option<f64>,
5722    /// The level of organizational unit a verification question about this
5723    /// indicator is put at.
5724    ///
5725    /// Unset is not a choice: it means this indicator follows the
5726    /// organization's default, and consumers MUST NOT render it as a level
5727    /// somebody selected. Any other value overrides the default for this
5728    /// indicator alone, which is what makes the field worth having — how
5729    /// close the respondent has to be to the work is a property of what is
5730    /// being measured, while the shape of the organization is not.
5731    ///
5732    /// Meaningful only while the evidence source is the
5733    /// verification-campaign kind, but kept across a switch to another kind
5734    /// so that switching back does not silently discard the selection.
5735    #[prost(enumeration="VerificationUnitLevel", tag="17")]
5736    pub verification_unit_level: i32,
5737}
5738/// Where an indicator's readings come from, plus the structural facts
5739/// that follow from that choice. The facts are descriptive, not a score:
5740/// they state what the configuration implies so the reader can judge it,
5741/// and are never combined into a single rating.
5742#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5743pub struct EvidenceSource {
5744    /// Which adapter produces the readings.
5745    #[prost(enumeration="EvidenceSourceKind", tag="1")]
5746    pub kind: i32,
5747    /// True when whoever reports the reading is also whoever the reading
5748    /// is about. Self-reported readings can be negotiated rather than
5749    /// produced.
5750    #[prost(bool, tag="2")]
5751    pub reporter_is_subject: bool,
5752    /// Whether the source observes the whole population or a sample.
5753    #[prost(enumeration="EvidenceCoverage", tag="3")]
5754    pub coverage: i32,
5755    /// True when a party other than the reporter could check the reading
5756    /// against an independent record.
5757    #[prost(bool, tag="4")]
5758    pub third_party_verifiable: bool,
5759    /// Adapter-specific configuration. Must match `kind`.
5760    #[prost(oneof="evidence_source::Detail", tags="5, 6, 7, 8")]
5761    pub detail: ::core::option::Option<evidence_source::Detail>,
5762}
5763/// Nested message and enum types in `EvidenceSource`.
5764pub mod evidence_source {
5765    /// Adapter-specific configuration. Must match `kind`.
5766    #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)]
5767    pub enum Detail {
5768        #[prost(message, tag="5")]
5769        InApp(super::InAppEvidence),
5770        #[prost(message, tag="6")]
5771        VerificationCampaign(super::VerificationCampaignEvidence),
5772        #[prost(message, tag="7")]
5773        Webhook(super::WebhookEvidence),
5774        #[prost(message, tag="8")]
5775        ManualEntry(super::ManualEntryEvidence),
5776    }
5777}
5778/// Configuration for readings produced inside the product by the
5779/// audience of the message itself.
5780#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
5781pub struct InAppEvidence {
5782    /// Which response counts as a reading. ActionType currently defines
5783    /// only ACK; poll answers, go-to confirmations and attestations become
5784    /// expressible here once message actions land in common.proto.
5785    #[prost(enumeration="ActionType", tag="1")]
5786    pub action_type: i32,
5787}
5788/// Configuration for readings produced by a deferred follow-up message
5789/// sent to someone other than the audience.
5790#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5791pub struct VerificationCampaignEvidence {
5792    /// How the recipients of the follow-up are derived from the audience
5793    /// being verified. Kinds other than the ones enumerated are rejected
5794    /// with UNIMPLEMENTED.
5795    #[prost(enumeration="VerifierDerivation", tag="1")]
5796    pub verifier_derivation: i32,
5797    /// Days to wait after the original message before the follow-up is
5798    /// sent.
5799    #[prost(int32, tag="2")]
5800    pub delay_days: i32,
5801    /// Template used for the follow-up. Optional; a default is used when
5802    /// empty.
5803    #[prost(string, tag="3")]
5804    pub template_id: ::prost::alloc::string::String,
5805}
5806/// Configuration for readings the organization pushes from one of its
5807/// own systems.
5808#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5809pub struct WebhookEvidence {
5810    /// Name of the system the readings come from. Required for this
5811    /// adapter.
5812    /// Constraints: Max length 200 characters.
5813    #[prost(string, tag="1")]
5814    pub system_name: ::prost::alloc::string::String,
5815    /// How the reading is produced in that system, in the organization's
5816    /// own words.
5817    /// Constraints: Max length 2000 characters.
5818    #[prost(string, tag="2")]
5819    pub description: ::prost::alloc::string::String,
5820}
5821/// Configuration for readings entered by hand or imported from a
5822/// spreadsheet. There is no originating system to name — a person is the
5823/// source.
5824#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5825pub struct ManualEntryEvidence {
5826    /// How the reading is arrived at before it is entered, in the
5827    /// organization's own words.
5828    /// Constraints: Max length 2000 characters.
5829    #[prost(string, tag="1")]
5830    pub description: ::prost::alloc::string::String,
5831}
5832/// Declares which objective a campaign serves. The link is what turns a
5833/// campaign's response rate from a result in itself into evidence about
5834/// something the organization was trying to achieve.
5835#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5836pub struct CampaignObjectiveLink {
5837    /// Campaign that serves the objective.
5838    #[prost(string, tag="1")]
5839    pub campaign_id: ::prost::alloc::string::String,
5840    /// Objective the campaign serves.
5841    #[prost(string, tag="2")]
5842    pub objective_id: ::prost::alloc::string::String,
5843    /// How the link came to be.
5844    #[prost(enumeration="LinkOrigin", tag="3")]
5845    pub origin: i32,
5846    /// Timestamp when the link was recorded.
5847    #[prost(message, optional, tag="4")]
5848    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
5849}
5850/// Request to create an objective.
5851#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5852pub struct CreateObjectiveRequest {
5853    /// The statement. Required.
5854    /// Constraints: Max length 300 characters.
5855    #[prost(string, tag="1")]
5856    pub title: ::prost::alloc::string::String,
5857    /// Longer explanation. Optional.
5858    /// Constraints: Max length 4000 characters.
5859    #[prost(string, tag="2")]
5860    pub description: ::prost::alloc::string::String,
5861    /// Accountable user. Optional.
5862    #[prost(string, tag="3")]
5863    pub owner_user_id: ::prost::alloc::string::String,
5864    /// Standing objective or time-bounded initiative. Defaults to
5865    /// OBJECTIVE_KIND_OBJECTIVE when unspecified.
5866    #[prost(enumeration="ObjectiveKind", tag="4")]
5867    pub kind: i32,
5868    /// For an initiative, the standing objective it contributes to.
5869    /// Optional; must be empty for a standing objective.
5870    #[prost(string, tag="5")]
5871    pub parent_objective_id: ::prost::alloc::string::String,
5872    /// For an initiative, its expected end. Must be unset for a standing
5873    /// objective.
5874    #[prost(message, optional, tag="6")]
5875    pub ends_at: ::core::option::Option<::prost_types::Timestamp>,
5876    /// Initial lifecycle state. Defaults to OBJECTIVE_STATE_DRAFT when
5877    /// unspecified. OBJECTIVE_STATE_ARCHIVED is rejected.
5878    #[prost(enumeration="ObjectiveState", tag="7")]
5879    pub state: i32,
5880}
5881/// Response after creating an objective.
5882#[derive(Clone, PartialEq, ::prost::Message)]
5883pub struct CreateObjectiveResponse {
5884    /// The newly created objective. Always present, including when
5885    /// advisories were raised.
5886    #[prost(message, optional, tag="1")]
5887    pub objective: ::core::option::Option<Objective>,
5888    /// Form problems found in the wording. Advisory only — the objective
5889    /// was stored regardless.
5890    #[prost(message, repeated, tag="2")]
5891    pub advisories: ::prost::alloc::vec::Vec<ObjectiveAdvisory>,
5892}
5893/// Request to update an objective.
5894///
5895/// Every mutable field carries explicit presence and they all follow one
5896/// rule: a field left absent leaves the stored value untouched, and a
5897/// field that is present replaces it — including when the value sent is
5898/// empty. Clearing a field is therefore expressible, which matters for
5899/// text an author wants gone rather than merely reworded.
5900#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5901pub struct UpdateObjectiveRequest {
5902    /// ID of the objective to update. Required.
5903    #[prost(string, tag="1")]
5904    pub objective_id: ::prost::alloc::string::String,
5905    /// New statement.
5906    /// Constraints: Max length 300 characters.
5907    #[prost(string, optional, tag="2")]
5908    pub title: ::core::option::Option<::prost::alloc::string::String>,
5909    /// New explanation.
5910    /// Constraints: Max length 4000 characters.
5911    #[prost(string, optional, tag="3")]
5912    pub description: ::core::option::Option<::prost::alloc::string::String>,
5913    /// New accountable user. Present and empty detaches the owner.
5914    #[prost(string, optional, tag="4")]
5915    pub owner_user_id: ::core::option::Option<::prost::alloc::string::String>,
5916    /// New lifecycle state. Archiving an objective is done here, by
5917    /// sending OBJECTIVE_STATE_ARCHIVED.
5918    #[prost(enumeration="ObjectiveState", optional, tag="5")]
5919    pub state: ::core::option::Option<i32>,
5920    /// New expected end for an initiative. Reclassifying to
5921    /// OBJECTIVE_KIND_OBJECTIVE clears it regardless of what is sent here,
5922    /// since a standing objective has no end.
5923    #[prost(message, optional, tag="6")]
5924    pub ends_at: ::core::option::Option<::prost_types::Timestamp>,
5925    /// Reclassify between a standing objective and a time-bounded
5926    /// initiative, so that an OBJECTIVE_WRITING_ISSUE_PROJECT_FORM
5927    /// advisory can be acted on without recreating the entry.
5928    #[prost(enumeration="ObjectiveKind", optional, tag="7")]
5929    pub kind: ::core::option::Option<i32>,
5930    /// For an initiative, the standing objective it contributes to.
5931    /// Present and empty detaches it and leaves the initiative standing
5932    /// alone.
5933    #[prost(string, optional, tag="8")]
5934    pub parent_objective_id: ::core::option::Option<::prost::alloc::string::String>,
5935}
5936/// Response after updating an objective.
5937#[derive(Clone, PartialEq, ::prost::Message)]
5938pub struct UpdateObjectiveResponse {
5939    /// The updated objective.
5940    #[prost(message, optional, tag="1")]
5941    pub objective: ::core::option::Option<Objective>,
5942    /// Form problems found in the new wording. Advisory only — the update
5943    /// was applied regardless.
5944    #[prost(message, repeated, tag="2")]
5945    pub advisories: ::prost::alloc::vec::Vec<ObjectiveAdvisory>,
5946}
5947/// Request to retrieve one objective with its indicators.
5948#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5949pub struct GetObjectiveRequest {
5950    /// ID of the objective to retrieve. Required.
5951    #[prost(string, tag="1")]
5952    pub objective_id: ::prost::alloc::string::String,
5953}
5954/// Response containing the requested objective.
5955#[derive(Clone, PartialEq, ::prost::Message)]
5956pub struct GetObjectiveResponse {
5957    /// The requested objective.
5958    #[prost(message, optional, tag="1")]
5959    pub objective: ::core::option::Option<Objective>,
5960    /// Indicators attached to it, ordered by creation time.
5961    #[prost(message, repeated, tag="2")]
5962    pub indicators: ::prost::alloc::vec::Vec<Indicator>,
5963}
5964/// Request to list the organization's objectives with pagination.
5965#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
5966pub struct ListObjectivesRequest {
5967    /// Pagination parameters.
5968    #[prost(message, optional, tag="1")]
5969    pub pagination: ::core::option::Option<Pagination>,
5970    /// Return only objectives in this state. Unspecified returns every
5971    /// state except OBJECTIVE_STATE_ARCHIVED.
5972    #[prost(enumeration="ObjectiveState", tag="2")]
5973    pub state: i32,
5974    /// Return only entries of this kind. Unspecified returns both kinds.
5975    #[prost(enumeration="ObjectiveKind", tag="3")]
5976    pub kind: i32,
5977}
5978/// Response containing a page of objectives.
5979#[derive(Clone, PartialEq, ::prost::Message)]
5980pub struct ListObjectivesResponse {
5981    /// Objectives in this page.
5982    #[prost(message, repeated, tag="1")]
5983    pub objectives: ::prost::alloc::vec::Vec<Objective>,
5984    /// Pagination metadata for fetching subsequent pages.
5985    #[prost(message, optional, tag="2")]
5986    pub pagination_meta: ::core::option::Option<PaginationMeta>,
5987}
5988/// Request to attach an indicator to an objective.
5989#[derive(Clone, PartialEq, ::prost::Message)]
5990pub struct AddIndicatorRequest {
5991    /// Objective the indicator hangs from. Required.
5992    #[prost(string, tag="1")]
5993    pub objective_id: ::prost::alloc::string::String,
5994    /// Short name. Required.
5995    /// Constraints: Max length 200 characters.
5996    #[prost(string, tag="2")]
5997    pub name: ::prost::alloc::string::String,
5998    /// Unit the readings are expressed in. Optional.
5999    /// Constraints: Max length 50 characters.
6000    #[prost(string, tag="3")]
6001    pub unit: ::prost::alloc::string::String,
6002    /// Desired direction of movement.
6003    #[prost(enumeration="IndicatorDirection", tag="4")]
6004    pub direction: i32,
6005    /// Expected reading cadence.
6006    #[prost(enumeration="IndicatorFrequency", tag="5")]
6007    pub frequency: i32,
6008    /// Accountable user. Optional.
6009    #[prost(string, tag="6")]
6010    pub owner_user_id: ::prost::alloc::string::String,
6011    /// Where readings come from. Required.
6012    #[prost(message, optional, tag="7")]
6013    pub evidence_source: ::core::option::Option<EvidenceSource>,
6014    /// Why this indicator was chosen. Optional.
6015    /// Constraints: Max length 2000 characters.
6016    #[prost(string, tag="8")]
6017    pub rationale: ::prost::alloc::string::String,
6018    /// What it is meant to say about the objective. Optional.
6019    /// Constraints: Max length 2000 characters.
6020    #[prost(string, tag="9")]
6021    pub strategic_meaning: ::prost::alloc::string::String,
6022    /// How a reading should be read. Optional.
6023    /// Constraints: Max length 2000 characters.
6024    #[prost(string, tag="10")]
6025    pub interpretation_guidance: ::prost::alloc::string::String,
6026    /// Behaviour the indicator could encourage if optimized on its own.
6027    /// Optional; the server pre-fills it when left empty and the evidence
6028    /// source implies one.
6029    /// Constraints: Max length 2000 characters.
6030    #[prost(string, tag="11")]
6031    pub perverse_behavior_note: ::prost::alloc::string::String,
6032    /// The value being aimed for, expressed in `unit`. Optional.
6033    #[prost(double, optional, tag="12")]
6034    pub target: ::core::option::Option<f64>,
6035    /// Level of unit a verification question about this indicator is put
6036    /// at. Optional; unspecified follows the organization's default rather
6037    /// than selecting a level.
6038    #[prost(enumeration="VerificationUnitLevel", tag="13")]
6039    pub verification_unit_level: i32,
6040}
6041/// Response after attaching an indicator.
6042#[derive(Clone, PartialEq, ::prost::Message)]
6043pub struct AddIndicatorResponse {
6044    /// The newly created indicator.
6045    #[prost(message, optional, tag="1")]
6046    pub indicator: ::core::option::Option<Indicator>,
6047    /// What follows from declaring a verification campaign as the evidence
6048    /// source, given the shape of the organization. Empty for every other
6049    /// evidence kind, and empty when nothing follows. Advisory only — the
6050    /// indicator was stored regardless.
6051    #[prost(message, repeated, tag="2")]
6052    pub notices: ::prost::alloc::vec::Vec<VerificationSetupNotice>,
6053}
6054/// Request to update an indicator.
6055///
6056/// Every mutable field carries explicit presence and they all follow one
6057/// rule: a field left absent leaves the stored value untouched, and a
6058/// field that is present replaces it — including when the value sent is
6059/// empty. This is what lets an author delete server-pre-filled text such
6060/// as `perverse_behavior_note` instead of only overwriting it.
6061#[derive(Clone, PartialEq, ::prost::Message)]
6062pub struct UpdateIndicatorRequest {
6063    /// ID of the indicator to update. Required.
6064    #[prost(string, tag="1")]
6065    pub indicator_id: ::prost::alloc::string::String,
6066    /// New name.
6067    /// Constraints: Max length 200 characters.
6068    #[prost(string, optional, tag="2")]
6069    pub name: ::core::option::Option<::prost::alloc::string::String>,
6070    /// New unit.
6071    /// Constraints: Max length 50 characters.
6072    #[prost(string, optional, tag="3")]
6073    pub unit: ::core::option::Option<::prost::alloc::string::String>,
6074    /// New direction.
6075    #[prost(enumeration="IndicatorDirection", optional, tag="4")]
6076    pub direction: ::core::option::Option<i32>,
6077    /// New cadence.
6078    #[prost(enumeration="IndicatorFrequency", optional, tag="5")]
6079    pub frequency: ::core::option::Option<i32>,
6080    /// New accountable user. Present and empty detaches the owner.
6081    #[prost(string, optional, tag="6")]
6082    pub owner_user_id: ::core::option::Option<::prost::alloc::string::String>,
6083    /// New evidence source.
6084    #[prost(message, optional, tag="7")]
6085    pub evidence_source: ::core::option::Option<EvidenceSource>,
6086    /// New rationale.
6087    /// Constraints: Max length 2000 characters.
6088    #[prost(string, optional, tag="8")]
6089    pub rationale: ::core::option::Option<::prost::alloc::string::String>,
6090    /// New strategic meaning.
6091    /// Constraints: Max length 2000 characters.
6092    #[prost(string, optional, tag="9")]
6093    pub strategic_meaning: ::core::option::Option<::prost::alloc::string::String>,
6094    /// New interpretation guidance.
6095    /// Constraints: Max length 2000 characters.
6096    #[prost(string, optional, tag="10")]
6097    pub interpretation_guidance: ::core::option::Option<::prost::alloc::string::String>,
6098    /// New note on encouraged behaviour. Present and empty deletes the
6099    /// note, which is how an author rejects the server's pre-filled text.
6100    /// Constraints: Max length 2000 characters.
6101    #[prost(string, optional, tag="11")]
6102    pub perverse_behavior_note: ::core::option::Option<::prost::alloc::string::String>,
6103    /// New target.
6104    #[prost(double, optional, tag="12")]
6105    pub target: ::core::option::Option<f64>,
6106    /// New unit level. Absent leaves the current selection untouched;
6107    /// present with VERIFICATION_UNIT_LEVEL_UNSPECIFIED drops the override
6108    /// and returns this indicator to following the organization's default,
6109    /// which is how a per-indicator selection is undone rather than merely
6110    /// overwritten.
6111    #[prost(enumeration="VerificationUnitLevel", optional, tag="13")]
6112    pub verification_unit_level: ::core::option::Option<i32>,
6113}
6114/// Response after updating an indicator.
6115#[derive(Clone, PartialEq, ::prost::Message)]
6116pub struct UpdateIndicatorResponse {
6117    /// The updated indicator. Notices are recomputed on every update, so
6118    /// an evidence source switched onto or off a verification campaign
6119    /// gets the current answer rather than the one from creation time.
6120    #[prost(message, optional, tag="1")]
6121    pub indicator: ::core::option::Option<Indicator>,
6122    /// What follows from the evidence source as it now stands. Advisory
6123    /// only — the update was applied regardless.
6124    #[prost(message, repeated, tag="2")]
6125    pub notices: ::prost::alloc::vec::Vec<VerificationSetupNotice>,
6126}
6127/// Request to detach an indicator from its objective.
6128#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6129pub struct RemoveIndicatorRequest {
6130    /// ID of the indicator to remove. Required.
6131    #[prost(string, tag="1")]
6132    pub indicator_id: ::prost::alloc::string::String,
6133}
6134/// Response after removing an indicator.
6135#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6136pub struct RemoveIndicatorResponse {
6137}
6138/// Request to declare that a campaign serves an objective.
6139#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6140pub struct LinkCampaignToObjectiveRequest {
6141    /// Campaign to link. Required.
6142    #[prost(string, tag="1")]
6143    pub campaign_id: ::prost::alloc::string::String,
6144    /// Objective the campaign serves. Required.
6145    #[prost(string, tag="2")]
6146    pub objective_id: ::prost::alloc::string::String,
6147    /// How the link came to be. Defaults to LINK_ORIGIN_DECLARED when
6148    /// unspecified.
6149    #[prost(enumeration="LinkOrigin", tag="3")]
6150    pub origin: i32,
6151}
6152/// Response after linking a campaign to an objective.
6153#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6154pub struct LinkCampaignToObjectiveResponse {
6155    /// The recorded link. Linking an already-linked pair is idempotent and
6156    /// returns the existing link.
6157    #[prost(message, optional, tag="1")]
6158    pub link: ::core::option::Option<CampaignObjectiveLink>,
6159}
6160/// Request to remove the declaration that a campaign serves an objective.
6161#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6162pub struct UnlinkCampaignFromObjectiveRequest {
6163    /// Campaign to unlink. Required.
6164    #[prost(string, tag="1")]
6165    pub campaign_id: ::prost::alloc::string::String,
6166    /// Objective to unlink it from. Required.
6167    #[prost(string, tag="2")]
6168    pub objective_id: ::prost::alloc::string::String,
6169}
6170/// Response after unlinking a campaign from an objective.
6171#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6172pub struct UnlinkCampaignFromObjectiveResponse {
6173}
6174/// Request to list campaign-to-objective links, from either end of the
6175/// relationship. Exactly one of `objective_id` and `campaign_id` must be
6176/// set; sending both, or neither, returns INVALID_ARGUMENT.
6177#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6178pub struct ListCampaignObjectiveLinksRequest {
6179    /// List the campaigns that serve this objective.
6180    #[prost(string, optional, tag="1")]
6181    pub objective_id: ::core::option::Option<::prost::alloc::string::String>,
6182    /// Pagination parameters.
6183    #[prost(message, optional, tag="2")]
6184    pub pagination: ::core::option::Option<Pagination>,
6185    /// List the objectives this campaign serves.
6186    #[prost(string, optional, tag="3")]
6187    pub campaign_id: ::core::option::Option<::prost::alloc::string::String>,
6188}
6189/// Response containing a page of campaign links.
6190#[derive(Clone, PartialEq, ::prost::Message)]
6191pub struct ListCampaignObjectiveLinksResponse {
6192    /// Links in this page, newest first.
6193    #[prost(message, repeated, tag="1")]
6194    pub links: ::prost::alloc::vec::Vec<CampaignObjectiveLink>,
6195    /// Pagination metadata for fetching subsequent pages.
6196    #[prost(message, optional, tag="2")]
6197    pub pagination_meta: ::core::option::Option<PaginationMeta>,
6198}
6199/// A candidate way of observing an objective, offered for a person to
6200/// accept, edit or throw away.
6201///
6202/// A suggestion is not an indicator and carries no identifier, because
6203/// nothing has been created. Proposing how an objective might be
6204/// observed is a bounded generative task and the platform is useful at
6205/// it; deciding that the proposed measure actually moves with the
6206/// objective is not something any model can settle, and only accumulated
6207/// readings can. Keeping the two apart is the point of this message
6208/// existing separately from Indicator.
6209#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6210pub struct IndicatorSuggestion {
6211    /// Proposed name for the indicator.
6212    #[prost(string, tag="1")]
6213    pub name: ::prost::alloc::string::String,
6214    /// Proposed unit the readings would be expressed in.
6215    #[prost(string, tag="2")]
6216    pub unit: ::prost::alloc::string::String,
6217    /// Proposed direction of desired movement.
6218    #[prost(enumeration="IndicatorDirection", tag="3")]
6219    pub direction: i32,
6220    /// Where readings would have to come from for this measure to exist.
6221    /// Part of the suggestion because a measure nobody can source is not a
6222    /// usable proposal.
6223    #[prost(enumeration="EvidenceSourceKind", tag="4")]
6224    pub evidence_source_kind: i32,
6225    /// Why this measure was proposed for this objective, in plain
6226    /// language, so the reader can reject it on the reasoning rather than
6227    /// on the wording.
6228    #[prost(string, tag="5")]
6229    pub rationale: ::prost::alloc::string::String,
6230}
6231/// Request for candidate indicators for a declared objective.
6232#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6233pub struct SuggestIndicatorsRequest {
6234    /// Objective to propose indicators for. Required.
6235    #[prost(string, tag="1")]
6236    pub objective_id: ::prost::alloc::string::String,
6237}
6238/// Response containing candidate indicators.
6239#[derive(Clone, PartialEq, ::prost::Message)]
6240pub struct SuggestIndicatorsResponse {
6241    /// Candidates, most relevant first. Never applied by the server —
6242    /// acting on one means calling AddIndicator with its contents, and the
6243    /// indicator that results is unverified like any other.
6244    ///
6245    /// Empty when no candidate could be produced, including when the
6246    /// organization has model-assisted features turned off. Suggestions
6247    /// are a convenience and nothing in the contract depends on them, so
6248    /// their absence is not an error.
6249    #[prost(message, repeated, tag="1")]
6250    pub suggestions: ::prost::alloc::vec::Vec<IndicatorSuggestion>,
6251}
6252// ─── Enums ──────────────────────────────────────────────────────────────────
6253
6254/// Lifecycle state of an objective.
6255#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6256#[repr(i32)]
6257pub enum ObjectiveState {
6258    Unspecified = 0,
6259    /// Being drafted. Not yet part of the organization's declared set and
6260    /// excluded from any analysis that reads the set as a whole.
6261    Draft = 1,
6262    /// Declared and in force.
6263    Active = 2,
6264    /// Withdrawn. Kept for history and for links already recorded against
6265    /// it, but no longer part of the declared set.
6266    Archived = 3,
6267}
6268impl ObjectiveState {
6269    /// String value of the enum field names used in the ProtoBuf definition.
6270    ///
6271    /// The values are not transformed in any way and thus are considered stable
6272    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6273    pub fn as_str_name(&self) -> &'static str {
6274        match self {
6275            Self::Unspecified => "OBJECTIVE_STATE_UNSPECIFIED",
6276            Self::Draft => "OBJECTIVE_STATE_DRAFT",
6277            Self::Active => "OBJECTIVE_STATE_ACTIVE",
6278            Self::Archived => "OBJECTIVE_STATE_ARCHIVED",
6279        }
6280    }
6281    /// Creates an enum from field names used in the ProtoBuf definition.
6282    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6283        match value {
6284            "OBJECTIVE_STATE_UNSPECIFIED" => Some(Self::Unspecified),
6285            "OBJECTIVE_STATE_DRAFT" => Some(Self::Draft),
6286            "OBJECTIVE_STATE_ACTIVE" => Some(Self::Active),
6287            "OBJECTIVE_STATE_ARCHIVED" => Some(Self::Archived),
6288            _ => None,
6289        }
6290    }
6291}
6292/// Whether the entry is a standing desired state or a time-bounded
6293/// effort. The distinction is structural, not cosmetic: analyses that
6294/// read the declared set as a whole (coverage, overlap, gaps) apply only
6295/// to standing objectives, because a time-bounded effort is expected to
6296/// end and would distort them.
6297#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6298#[repr(i32)]
6299pub enum ObjectiveKind {
6300    Unspecified = 0,
6301    /// A desired state with no end date, written as a condition rather
6302    /// than as a change or a target.
6303    Objective = 1,
6304    /// A time-bounded effort with an explicit end. May stand alone or hang
6305    /// off a standing objective.
6306    Initiative = 2,
6307}
6308impl ObjectiveKind {
6309    /// String value of the enum field names used in the ProtoBuf definition.
6310    ///
6311    /// The values are not transformed in any way and thus are considered stable
6312    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6313    pub fn as_str_name(&self) -> &'static str {
6314        match self {
6315            Self::Unspecified => "OBJECTIVE_KIND_UNSPECIFIED",
6316            Self::Objective => "OBJECTIVE_KIND_OBJECTIVE",
6317            Self::Initiative => "OBJECTIVE_KIND_INITIATIVE",
6318        }
6319    }
6320    /// Creates an enum from field names used in the ProtoBuf definition.
6321    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6322        match value {
6323            "OBJECTIVE_KIND_UNSPECIFIED" => Some(Self::Unspecified),
6324            "OBJECTIVE_KIND_OBJECTIVE" => Some(Self::Objective),
6325            "OBJECTIVE_KIND_INITIATIVE" => Some(Self::Initiative),
6326            _ => None,
6327        }
6328    }
6329}
6330/// A form problem detected in an objective's wording. Advisory only —
6331/// servers never reject a write because of one, and clients present the
6332/// finding alongside the suggested rewrite while still allowing the save.
6333#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6334#[repr(i32)]
6335pub enum ObjectiveWritingIssue {
6336    Unspecified = 0,
6337    /// Phrased as a change ("improve", "reduce", "increase") rather than
6338    /// as the state that should hold once the change has happened.
6339    ChangeVerb = 1,
6340    /// Carries a number, percentage or date inside the statement, which
6341    /// makes it a target rather than a state. Targets belong on
6342    /// indicators.
6343    EmbeddedTarget = 2,
6344    /// Phrased as a project ("launch", "roll out", "migrate"), which has
6345    /// an end and therefore describes an initiative rather than a
6346    /// standing objective.
6347    ProjectForm = 3,
6348}
6349impl ObjectiveWritingIssue {
6350    /// String value of the enum field names used in the ProtoBuf definition.
6351    ///
6352    /// The values are not transformed in any way and thus are considered stable
6353    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6354    pub fn as_str_name(&self) -> &'static str {
6355        match self {
6356            Self::Unspecified => "OBJECTIVE_WRITING_ISSUE_UNSPECIFIED",
6357            Self::ChangeVerb => "OBJECTIVE_WRITING_ISSUE_CHANGE_VERB",
6358            Self::EmbeddedTarget => "OBJECTIVE_WRITING_ISSUE_EMBEDDED_TARGET",
6359            Self::ProjectForm => "OBJECTIVE_WRITING_ISSUE_PROJECT_FORM",
6360        }
6361    }
6362    /// Creates an enum from field names used in the ProtoBuf definition.
6363    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6364        match value {
6365            "OBJECTIVE_WRITING_ISSUE_UNSPECIFIED" => Some(Self::Unspecified),
6366            "OBJECTIVE_WRITING_ISSUE_CHANGE_VERB" => Some(Self::ChangeVerb),
6367            "OBJECTIVE_WRITING_ISSUE_EMBEDDED_TARGET" => Some(Self::EmbeddedTarget),
6368            "OBJECTIVE_WRITING_ISSUE_PROJECT_FORM" => Some(Self::ProjectForm),
6369            _ => None,
6370        }
6371    }
6372}
6373/// Whether a higher or a lower reading of an indicator is the desired
6374/// direction.
6375#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6376#[repr(i32)]
6377pub enum IndicatorDirection {
6378    Unspecified = 0,
6379    HigherIsBetter = 1,
6380    LowerIsBetter = 2,
6381}
6382impl IndicatorDirection {
6383    /// String value of the enum field names used in the ProtoBuf definition.
6384    ///
6385    /// The values are not transformed in any way and thus are considered stable
6386    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6387    pub fn as_str_name(&self) -> &'static str {
6388        match self {
6389            Self::Unspecified => "INDICATOR_DIRECTION_UNSPECIFIED",
6390            Self::HigherIsBetter => "INDICATOR_DIRECTION_HIGHER_IS_BETTER",
6391            Self::LowerIsBetter => "INDICATOR_DIRECTION_LOWER_IS_BETTER",
6392        }
6393    }
6394    /// Creates an enum from field names used in the ProtoBuf definition.
6395    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6396        match value {
6397            "INDICATOR_DIRECTION_UNSPECIFIED" => Some(Self::Unspecified),
6398            "INDICATOR_DIRECTION_HIGHER_IS_BETTER" => Some(Self::HigherIsBetter),
6399            "INDICATOR_DIRECTION_LOWER_IS_BETTER" => Some(Self::LowerIsBetter),
6400            _ => None,
6401        }
6402    }
6403}
6404/// How often an indicator is expected to be read.
6405#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6406#[repr(i32)]
6407pub enum IndicatorFrequency {
6408    Unspecified = 0,
6409    Daily = 1,
6410    Weekly = 2,
6411    Monthly = 3,
6412    Quarterly = 4,
6413    Annually = 5,
6414    /// Read on demand, with no fixed cadence.
6415    AdHoc = 6,
6416}
6417impl IndicatorFrequency {
6418    /// String value of the enum field names used in the ProtoBuf definition.
6419    ///
6420    /// The values are not transformed in any way and thus are considered stable
6421    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6422    pub fn as_str_name(&self) -> &'static str {
6423        match self {
6424            Self::Unspecified => "INDICATOR_FREQUENCY_UNSPECIFIED",
6425            Self::Daily => "INDICATOR_FREQUENCY_DAILY",
6426            Self::Weekly => "INDICATOR_FREQUENCY_WEEKLY",
6427            Self::Monthly => "INDICATOR_FREQUENCY_MONTHLY",
6428            Self::Quarterly => "INDICATOR_FREQUENCY_QUARTERLY",
6429            Self::Annually => "INDICATOR_FREQUENCY_ANNUALLY",
6430            Self::AdHoc => "INDICATOR_FREQUENCY_AD_HOC",
6431        }
6432    }
6433    /// Creates an enum from field names used in the ProtoBuf definition.
6434    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6435        match value {
6436            "INDICATOR_FREQUENCY_UNSPECIFIED" => Some(Self::Unspecified),
6437            "INDICATOR_FREQUENCY_DAILY" => Some(Self::Daily),
6438            "INDICATOR_FREQUENCY_WEEKLY" => Some(Self::Weekly),
6439            "INDICATOR_FREQUENCY_MONTHLY" => Some(Self::Monthly),
6440            "INDICATOR_FREQUENCY_QUARTERLY" => Some(Self::Quarterly),
6441            "INDICATOR_FREQUENCY_ANNUALLY" => Some(Self::Annually),
6442            "INDICATOR_FREQUENCY_AD_HOC" => Some(Self::AdHoc),
6443            _ => None,
6444        }
6445    }
6446}
6447/// Where an indicator's readings come from. Each kind is an adapter over
6448/// the same contract; kinds that are not yet implemented are rejected
6449/// with UNIMPLEMENTED rather than silently accepted.
6450#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6451#[repr(i32)]
6452pub enum EvidenceSourceKind {
6453    Unspecified = 0,
6454    /// Signals produced inside the product by the audience of the message
6455    /// itself (acknowledgment, poll answer, and so on). Carries
6456    /// InAppEvidence.
6457    InApp = 1,
6458    /// A deferred follow-up message sent to someone other than the
6459    /// audience, whose answer is stored as a reading of this indicator.
6460    /// Carries VerificationCampaignEvidence.
6461    VerificationCampaign = 2,
6462    /// The organization pushes the operational fact from one of its own
6463    /// systems. Carries WebhookEvidence. Returns UNIMPLEMENTED until the
6464    /// adapter is built.
6465    Webhook = 3,
6466    /// Readings entered by hand or imported from a spreadsheet. Carries
6467    /// ManualEntryEvidence. Returns UNIMPLEMENTED until the adapter is
6468    /// built.
6469    ManualEntry = 4,
6470}
6471impl EvidenceSourceKind {
6472    /// String value of the enum field names used in the ProtoBuf definition.
6473    ///
6474    /// The values are not transformed in any way and thus are considered stable
6475    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6476    pub fn as_str_name(&self) -> &'static str {
6477        match self {
6478            Self::Unspecified => "EVIDENCE_SOURCE_KIND_UNSPECIFIED",
6479            Self::InApp => "EVIDENCE_SOURCE_KIND_IN_APP",
6480            Self::VerificationCampaign => "EVIDENCE_SOURCE_KIND_VERIFICATION_CAMPAIGN",
6481            Self::Webhook => "EVIDENCE_SOURCE_KIND_WEBHOOK",
6482            Self::ManualEntry => "EVIDENCE_SOURCE_KIND_MANUAL_ENTRY",
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            "EVIDENCE_SOURCE_KIND_UNSPECIFIED" => Some(Self::Unspecified),
6489            "EVIDENCE_SOURCE_KIND_IN_APP" => Some(Self::InApp),
6490            "EVIDENCE_SOURCE_KIND_VERIFICATION_CAMPAIGN" => Some(Self::VerificationCampaign),
6491            "EVIDENCE_SOURCE_KIND_WEBHOOK" => Some(Self::Webhook),
6492            "EVIDENCE_SOURCE_KIND_MANUAL_ENTRY" => Some(Self::ManualEntry),
6493            _ => None,
6494        }
6495    }
6496}
6497/// Whether an evidence source observes the whole population or a sample
6498/// of it.
6499#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6500#[repr(i32)]
6501pub enum EvidenceCoverage {
6502    Unspecified = 0,
6503    Full = 1,
6504    Sampled = 2,
6505}
6506impl EvidenceCoverage {
6507    /// String value of the enum field names used in the ProtoBuf definition.
6508    ///
6509    /// The values are not transformed in any way and thus are considered stable
6510    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6511    pub fn as_str_name(&self) -> &'static str {
6512        match self {
6513            Self::Unspecified => "EVIDENCE_COVERAGE_UNSPECIFIED",
6514            Self::Full => "EVIDENCE_COVERAGE_FULL",
6515            Self::Sampled => "EVIDENCE_COVERAGE_SAMPLED",
6516        }
6517    }
6518    /// Creates an enum from field names used in the ProtoBuf definition.
6519    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6520        match value {
6521            "EVIDENCE_COVERAGE_UNSPECIFIED" => Some(Self::Unspecified),
6522            "EVIDENCE_COVERAGE_FULL" => Some(Self::Full),
6523            "EVIDENCE_COVERAGE_SAMPLED" => Some(Self::Sampled),
6524            _ => None,
6525        }
6526    }
6527}
6528/// How the recipients of a verification message are derived from the
6529/// audience of the message being verified.
6530#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6531#[repr(i32)]
6532pub enum VerifierDerivation {
6533    Unspecified = 0,
6534    /// Each audience member's manager, deduplicated. Self-targets are
6535    /// dropped.
6536    Manager = 1,
6537}
6538impl VerifierDerivation {
6539    /// String value of the enum field names used in the ProtoBuf definition.
6540    ///
6541    /// The values are not transformed in any way and thus are considered stable
6542    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6543    pub fn as_str_name(&self) -> &'static str {
6544        match self {
6545            Self::Unspecified => "VERIFIER_DERIVATION_UNSPECIFIED",
6546            Self::Manager => "VERIFIER_DERIVATION_MANAGER",
6547        }
6548    }
6549    /// Creates an enum from field names used in the ProtoBuf definition.
6550    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6551        match value {
6552            "VERIFIER_DERIVATION_UNSPECIFIED" => Some(Self::Unspecified),
6553            "VERIFIER_DERIVATION_MANAGER" => Some(Self::Manager),
6554            _ => None,
6555        }
6556    }
6557}
6558/// Whether an indicator has ever been corroborated by evidence outside
6559/// of the declaration that created it.
6560///
6561/// Recording readings is not part of this service. An indicator becomes
6562/// verified when an IndicatorReading is stored against it, which the
6563/// platform does from campaign outcomes; no RPC defined here can move
6564/// the state, so every indicator created or updated via
6565/// ObjectivesService stays UNVERIFIED.
6566#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6567#[repr(i32)]
6568pub enum IndicatorVerificationState {
6569    Unspecified = 0,
6570    /// No corroborating reading has been recorded. This is the state of
6571    /// every newly created indicator, including one whose wording was
6572    /// suggested by a model: a suggestion is not evidence, and callers
6573    /// must not present an unverified indicator as one that is known to
6574    /// track its objective.
6575    Unverified = 1,
6576    /// At least one reading from the declared evidence source has been
6577    /// recorded against this indicator. The state says evidence exists,
6578    /// not that the evidence was favourable — an indicator corroborated by
6579    /// a negative reading is verified all the same.
6580    Verified = 2,
6581}
6582impl IndicatorVerificationState {
6583    /// String value of the enum field names used in the ProtoBuf definition.
6584    ///
6585    /// The values are not transformed in any way and thus are considered stable
6586    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6587    pub fn as_str_name(&self) -> &'static str {
6588        match self {
6589            Self::Unspecified => "INDICATOR_VERIFICATION_STATE_UNSPECIFIED",
6590            Self::Unverified => "INDICATOR_VERIFICATION_STATE_UNVERIFIED",
6591            Self::Verified => "INDICATOR_VERIFICATION_STATE_VERIFIED",
6592        }
6593    }
6594    /// Creates an enum from field names used in the ProtoBuf definition.
6595    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6596        match value {
6597            "INDICATOR_VERIFICATION_STATE_UNSPECIFIED" => Some(Self::Unspecified),
6598            "INDICATOR_VERIFICATION_STATE_UNVERIFIED" => Some(Self::Unverified),
6599            "INDICATOR_VERIFICATION_STATE_VERIFIED" => Some(Self::Verified),
6600            _ => None,
6601        }
6602    }
6603}
6604/// How a campaign came to be linked to an objective.
6605#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
6606#[repr(i32)]
6607pub enum LinkOrigin {
6608    Unspecified = 0,
6609    /// Chosen explicitly by a person.
6610    Declared = 1,
6611    /// Proposed by the system from content similarity and confirmed by a
6612    /// person.
6613    Suggested = 2,
6614    /// Applied in bulk over historical campaigns when the objective set
6615    /// was first configured.
6616    Backfill = 3,
6617}
6618impl LinkOrigin {
6619    /// String value of the enum field names used in the ProtoBuf definition.
6620    ///
6621    /// The values are not transformed in any way and thus are considered stable
6622    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
6623    pub fn as_str_name(&self) -> &'static str {
6624        match self {
6625            Self::Unspecified => "LINK_ORIGIN_UNSPECIFIED",
6626            Self::Declared => "LINK_ORIGIN_DECLARED",
6627            Self::Suggested => "LINK_ORIGIN_SUGGESTED",
6628            Self::Backfill => "LINK_ORIGIN_BACKFILL",
6629        }
6630    }
6631    /// Creates an enum from field names used in the ProtoBuf definition.
6632    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
6633        match value {
6634            "LINK_ORIGIN_UNSPECIFIED" => Some(Self::Unspecified),
6635            "LINK_ORIGIN_DECLARED" => Some(Self::Declared),
6636            "LINK_ORIGIN_SUGGESTED" => Some(Self::Suggested),
6637            "LINK_ORIGIN_BACKFILL" => Some(Self::Backfill),
6638            _ => None,
6639        }
6640    }
6641}
6642// ─── Messages ───────────────────────────────────────────────────────────────
6643
6644/// A single non-retired pepper version. Returned by GetPeppers.
6645///
6646/// During a rotation overlap, multiple versions are returned — callers
6647/// (e.g. pidgr-integrations) compute lookup hashes under EVERY returned
6648/// version to write or match against `identifier_lookup_hash_v1` and
6649/// `identifier_lookup_hash_v2` on the reachability registry.
6650#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6651pub struct Pepper {
6652    /// Monotonically-increasing version number. Lower versions retire first.
6653    #[prost(int32, tag="1")]
6654    pub version: i32,
6655    /// Raw HMAC key material. Sensitive — callers MUST NOT log or persist
6656    /// this value to disk. In-memory caching keyed on (org_id, version) with
6657    /// a short TTL is permitted and expected.
6658    #[prost(bytes="vec", tag="2")]
6659    pub key_material: ::prost::alloc::vec::Vec<u8>,
6660}
6661/// Request to fetch the active (non-retired) peppers for one org/purpose.
6662///
6663/// Auth: internal-mTLS only. This RPC exposes raw cryptographic key material
6664/// and MUST NOT be reachable from the public ingress or from JWT-authenticated
6665/// clients. The server SHALL reject any caller whose mTLS identity is not on
6666/// the configured allowlist.
6667#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6668pub struct GetPeppersRequest {
6669    /// Organization whose peppers are requested.
6670    #[prost(string, tag="1")]
6671    pub org_id: ::prost::alloc::string::String,
6672    /// Purpose identifier scoping which key family to return. Use
6673    /// `"reachability_lookup"` for the pidgr-integrations registry lookup hash.
6674    #[prost(string, tag="2")]
6675    pub purpose: ::prost::alloc::string::String,
6676}
6677#[derive(Clone, PartialEq, ::prost::Message)]
6678pub struct GetPeppersResponse {
6679    /// All non-retired pepper versions for the (org_id, purpose) pair, in
6680    /// ascending version order. Typically exactly one entry; two during a
6681    /// rotation overlap window; zero only when no pepper has ever been
6682    /// generated for this (org, purpose).
6683    #[prost(message, repeated, tag="1")]
6684    pub peppers: ::prost::alloc::vec::Vec<Pepper>,
6685}
6686// ─── Messages ───────────────────────────────────────────────────────────────
6687
6688/// Maps an identity provider claim to a user profile field.
6689/// Used for automatic profile population when users authenticate via SSO/SAML.
6690#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6691pub struct SsoAttributeMapping {
6692    /// Claim name from the identity provider (e.g. "urn:oid:2.5.4.11", "given_name").
6693    /// Constraints: Max length 500 characters.
6694    #[prost(string, tag="1")]
6695    pub idp_claim: ::prost::alloc::string::String,
6696    /// Target UserProfile field name (e.g. "department", "first_name").
6697    /// For custom attributes, use "custom:" prefix (e.g. "custom:cost_center").
6698    /// Constraints: Max length 100 characters.
6699    #[prost(string, tag="2")]
6700    pub profile_field: ::prost::alloc::string::String,
6701}
6702/// An organization (tenant) in the Pidgr platform.
6703#[derive(Clone, PartialEq, ::prost::Message)]
6704pub struct Organization {
6705    /// Unique identifier for the organization.
6706    #[prost(string, tag="1")]
6707    pub id: ::prost::alloc::string::String,
6708    /// Organization display name.
6709    /// Constraints: Max length 200 characters.
6710    #[prost(string, tag="2")]
6711    pub name: ::prost::alloc::string::String,
6712    /// Default workflow used when campaigns don't specify one.
6713    #[prost(message, optional, tag="3")]
6714    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
6715    /// Timestamp when the organization was created.
6716    #[prost(message, optional, tag="4")]
6717    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
6718    /// Industry vertical.
6719    #[prost(enumeration="Industry", tag="5")]
6720    pub industry: i32,
6721    /// Employee headcount range.
6722    #[prost(enumeration="CompanySize", tag="6")]
6723    pub company_size: i32,
6724    /// SSO identity provider claim-to-profile mappings.
6725    /// Empty when the organization does not use SSO.
6726    #[prost(message, repeated, tag="7")]
6727    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
6728    /// Default language for new users in this organization.
6729    /// Empty means no org default (users auto-detect from device/browser).
6730    /// Valid values: en, es, pt-BR, zh, ja.
6731    #[prost(string, tag="8")]
6732    pub default_locale: ::prost::alloc::string::String,
6733    /// Organization lifecycle type.
6734    #[prost(enumeration="OrgType", tag="9")]
6735    pub org_type: i32,
6736    /// Expiration time for sandbox organizations. Empty for standard orgs.
6737    #[prost(message, optional, tag="10")]
6738    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
6739    /// Data governance framework (EU, LATAM, BR, APAC, US).
6740    /// Determines legal framework, DPA template, and Bedrock endpoint routing.
6741    #[prost(string, tag="11")]
6742    pub data_governance_region: ::prost::alloc::string::String,
6743    /// AWS region for content storage (resolved from data_governance_region).
6744    /// e.g., "eu-west-1", "us-east-1".
6745    #[prost(string, tag="12")]
6746    pub data_content_region: ::prost::alloc::string::String,
6747    /// ─── ML pipeline settings ──────────────────────────────────────────────────
6748    /// Cold-start threshold: completed campaigns below this count trigger immediate
6749    /// retraining. At or above, the org is flagged for the weekly cron.
6750    /// Default 10, range 1-100.
6751    #[prost(int32, tag="13")]
6752    pub ml_retrain_cold_threshold: i32,
6753    /// Whether cancelled campaigns count toward the training counter. Default true.
6754    #[prost(bool, tag="14")]
6755    pub ml_cancelled_counts: bool,
6756    /// Monthly limit on manual retrain triggers. Default 3, range 0-10.
6757    #[prost(int32, tag="15")]
6758    pub ml_manual_limit_monthly: i32,
6759    /// Number of manual retrains used in the current month (resets monthly).
6760    #[prost(int32, tag="16")]
6761    pub ml_manual_retrains_used: i32,
6762    /// Whether the org is flagged for the next weekly cron run.
6763    #[prost(bool, tag="17")]
6764    pub ml_needs_retrain: bool,
6765    /// Campaigns completed since the last ML training run.
6766    #[prost(int32, tag="18")]
6767    pub campaigns_since_last_training: i32,
6768    /// Total campaigns completed across the organization lifetime.
6769    #[prost(int32, tag="19")]
6770    pub total_completed_campaigns: i32,
6771    /// Timestamp of the most recent successful ML training. Empty if never trained.
6772    #[prost(message, optional, tag="20")]
6773    pub last_ml_training_at: ::core::option::Option<::prost_types::Timestamp>,
6774    /// Controls whether aggregate stats (campaign recipient/ack/missed counts)
6775    /// include synthetic data. Unset = default by org type: sandbox orgs include,
6776    /// standard orgs exclude. Derived intelligence (ML, analytics, attestation
6777    /// evidence) always excludes synthetic regardless of this setting.
6778    #[prost(bool, optional, tag="21")]
6779    pub include_synthetic_in_aggregates: ::core::option::Option<bool>,
6780    /// Whether the organization has opted into provisional (rule-based,
6781    /// low-confidence) archetypes for groups that don't yet have trained
6782    /// ML archetypes. Only meaningful for ORG_TYPE_STANDARD — sandbox
6783    /// organizations are always eligible regardless of this setting.
6784    /// Default false: production analytics stay conservative.
6785    #[prost(bool, tag="22")]
6786    pub provisional_archetypes_enabled: bool,
6787    /// The level of organizational unit verification questions are put at
6788    /// across the organization, applied to every indicator that does not
6789    /// override it.
6790    ///
6791    /// The default lives here because the shape of the organization is the
6792    /// organization's own fact and does not change from one indicator to
6793    /// the next; the override lives on the indicator because how close the
6794    /// respondent must be to the work is a property of what is being
6795    /// measured. Unset means no default has been declared and the platform
6796    /// applies VERIFICATION_UNIT_LEVEL_DERIVED_UNIT, which is the most
6797    /// sensitive level and is already bounded by the size floor.
6798    #[prost(enumeration="VerificationUnitLevel", tag="23")]
6799    pub default_verification_unit_level: i32,
6800}
6801/// Request to create a new organization.
6802/// JWT auth only — the authenticated caller becomes the initial admin. Additional
6803/// admins are added via CreateInviteLink after the org exists.
6804#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6805pub struct CreateOrganizationRequest {
6806    /// Name for the new organization.
6807    /// Constraints: Max length 200 characters.
6808    #[prost(string, tag="1")]
6809    pub name: ::prost::alloc::string::String,
6810    /// Industry vertical for the organization.
6811    #[prost(enumeration="Industry", tag="2")]
6812    pub industry: i32,
6813    /// Employee headcount range.
6814    #[prost(enumeration="CompanySize", tag="3")]
6815    pub company_size: i32,
6816    /// Access code required during early access.
6817    /// Format: PIDGR-XXXXXXXX (8 alphanumeric characters).
6818    #[prost(string, tag="4")]
6819    pub access_code: ::prost::alloc::string::String,
6820    /// Data governance framework. Defaults to "US" if omitted.
6821    /// Valid values: EU, LATAM, BR, APAC, US.
6822    #[prost(string, tag="5")]
6823    pub data_governance_region: ::prost::alloc::string::String,
6824    /// Optional bootstrap fixture to seed the organization with starter data.
6825    /// Empty string means the default fixture.
6826    #[prost(string, tag="6")]
6827    pub fixture_id: ::prost::alloc::string::String,
6828}
6829/// Response after creating an organization.
6830#[derive(Clone, PartialEq, ::prost::Message)]
6831pub struct CreateOrganizationResponse {
6832    /// The newly created organization.
6833    #[prost(message, optional, tag="1")]
6834    pub organization: ::core::option::Option<Organization>,
6835    /// The admin user created for the organization.
6836    #[prost(message, optional, tag="2")]
6837    pub admin_user: ::core::option::Option<User>,
6838}
6839/// Request to retrieve the organization for the authenticated user.
6840#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6841pub struct GetOrganizationRequest {
6842}
6843/// Response containing the organization.
6844#[derive(Clone, PartialEq, ::prost::Message)]
6845pub struct GetOrganizationResponse {
6846    /// The organization the authenticated user belongs to.
6847    #[prost(message, optional, tag="1")]
6848    pub organization: ::core::option::Option<Organization>,
6849}
6850/// Request to update organization settings.
6851#[derive(Clone, PartialEq, ::prost::Message)]
6852pub struct UpdateOrganizationRequest {
6853    /// New organization name. Empty string leaves unchanged.
6854    /// Constraints: Max length 200 characters.
6855    #[prost(string, tag="1")]
6856    pub name: ::prost::alloc::string::String,
6857    /// New default workflow definition. Null leaves unchanged.
6858    #[prost(message, optional, tag="2")]
6859    pub default_workflow: ::core::option::Option<WorkflowDefinition>,
6860    /// New industry vertical. UNSPECIFIED leaves unchanged.
6861    #[prost(enumeration="Industry", tag="3")]
6862    pub industry: i32,
6863    /// New employee headcount range. UNSPECIFIED leaves unchanged.
6864    #[prost(enumeration="CompanySize", tag="4")]
6865    pub company_size: i32,
6866    /// New default language for new users. Empty string leaves unchanged.
6867    /// Valid values: en, es, pt-BR, zh, ja.
6868    #[prost(string, tag="5")]
6869    pub default_locale: ::prost::alloc::string::String,
6870    /// New ML cold-start threshold. 0 leaves unchanged, otherwise must be in \[1, 100\].
6871    #[prost(int32, tag="6")]
6872    pub ml_retrain_cold_threshold: i32,
6873    /// New ML cancelled-counts flag. Uses google.protobuf.BoolValue-style semantics
6874    /// via optional to distinguish "not provided" from "set to false".
6875    #[prost(bool, optional, tag="7")]
6876    pub ml_cancelled_counts: ::core::option::Option<bool>,
6877    /// New ML monthly manual limit. Negative leaves unchanged, otherwise must be in \[0, 10\].
6878    /// Encoded as int32 with -1 meaning "leave unchanged".
6879    #[prost(int32, tag="8")]
6880    pub ml_manual_limit_monthly: i32,
6881    /// Set the synthetic-aggregates override; unset leaves it unchanged.
6882    #[prost(bool, optional, tag="9")]
6883    pub include_synthetic_in_aggregates: ::core::option::Option<bool>,
6884    /// New provisional-archetypes opt-in for standard organizations.
6885    /// Unset leaves unchanged. Rejected for sandbox organizations, which
6886    /// are always eligible automatically.
6887    #[prost(bool, optional, tag="10")]
6888    pub provisional_archetypes_enabled: ::core::option::Option<bool>,
6889    /// New organization-wide default for the level of unit verification
6890    /// questions are put at. UNSPECIFIED leaves unchanged. Changing it moves
6891    /// every indicator that has not overridden the default, and applies to
6892    /// questions asked from then on — readings already stored were taken at
6893    /// the level in force when they were collected and are not restated.
6894    #[prost(enumeration="VerificationUnitLevel", tag="11")]
6895    pub default_verification_unit_level: i32,
6896}
6897/// Response after updating the organization.
6898#[derive(Clone, PartialEq, ::prost::Message)]
6899pub struct UpdateOrganizationResponse {
6900    /// The updated organization.
6901    #[prost(message, optional, tag="1")]
6902    pub organization: ::core::option::Option<Organization>,
6903}
6904/// Request to replace all SSO attribute mappings for the organization.
6905#[derive(Clone, PartialEq, ::prost::Message)]
6906pub struct UpdateSsoAttributeMappingsRequest {
6907    /// Complete list of SSO mappings (replaces all existing mappings).
6908    #[prost(message, repeated, tag="1")]
6909    pub sso_attribute_mappings: ::prost::alloc::vec::Vec<SsoAttributeMapping>,
6910}
6911/// Response after updating SSO attribute mappings.
6912#[derive(Clone, PartialEq, ::prost::Message)]
6913pub struct UpdateSsoAttributeMappingsResponse {
6914    /// The updated organization with the new SSO mappings.
6915    #[prost(message, optional, tag="1")]
6916    pub organization: ::core::option::Option<Organization>,
6917}
6918/// Request to rotate the analytics salt and optionally increase the bucket count.
6919#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6920pub struct RotateAnalyticsSaltRequest {
6921    /// New bucket count. Must be >= current bucket count. 0 means keep current.
6922    #[prost(int32, tag="1")]
6923    pub new_bucket_count: i32,
6924}
6925/// Response after rotating the analytics salt.
6926#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
6927pub struct RotateAnalyticsSaltResponse {
6928    /// The new bucket count after rotation.
6929    #[prost(int32, tag="1")]
6930    pub bucket_count: i32,
6931}
6932/// Request to update the analytics epsilon (differential privacy parameter).
6933#[derive(Clone, Copy, PartialEq, ::prost::Message)]
6934pub struct UpdateAnalyticsEpsilonRequest {
6935    /// New epsilon value. Must be in range \[0.5, 5.0\].
6936    #[prost(float, tag="1")]
6937    pub epsilon: f32,
6938}
6939/// Response after updating the analytics epsilon.
6940#[derive(Clone, Copy, PartialEq, ::prost::Message)]
6941pub struct UpdateAnalyticsEpsilonResponse {
6942    /// The new epsilon value.
6943    #[prost(float, tag="1")]
6944    pub epsilon: f32,
6945}
6946/// Request to create a sandbox organization for testing.
6947#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6948pub struct CreateSandboxOrganizationRequest {
6949    /// Name for the sandbox organization.
6950    /// Constraints: Max length 200 characters.
6951    #[prost(string, tag="1")]
6952    pub name: ::prost::alloc::string::String,
6953    /// Required expiration time. Max 30 days from now for interactive callers;
6954    /// API-key callers may set shorter TTLs for ephemeral test sandboxes.
6955    #[prost(message, optional, tag="2")]
6956    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
6957    /// Data governance framework. Defaults to "US" if omitted.
6958    /// Valid values: EU, LATAM, BR, APAC, US.
6959    #[prost(string, tag="3")]
6960    pub data_governance_region: ::prost::alloc::string::String,
6961    /// Optional bootstrap fixture to seed the sandbox with starter data.
6962    /// Empty string means the default fixture.
6963    /// Must match an id returned by ListSandboxFixtures.
6964    #[prost(string, tag="4")]
6965    pub fixture_id: ::prost::alloc::string::String,
6966}
6967/// Response after creating a sandbox organization.
6968#[derive(Clone, PartialEq, ::prost::Message)]
6969pub struct CreateSandboxOrganizationResponse {
6970    /// The newly created sandbox organization (org_type: SANDBOX).
6971    #[prost(message, optional, tag="1")]
6972    pub organization: ::core::option::Option<Organization>,
6973    /// The admin user created for the sandbox.
6974    #[prost(message, optional, tag="2")]
6975    pub admin_user: ::core::option::Option<User>,
6976}
6977/// Request to delete a sandbox organization. Only callable for orgs with
6978/// org_type=SANDBOX. Allowed for super admins of the sandbox or the creator.
6979#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6980pub struct DeleteSandboxOrganizationRequest {
6981    /// ID of the sandbox organization to delete.
6982    #[prost(string, tag="1")]
6983    pub org_id: ::prost::alloc::string::String,
6984}
6985/// Response after requesting deletion. Deletion runs asynchronously via
6986/// the DeleteOrgWorkflow; a success response means the workflow started.
6987#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6988pub struct DeleteSandboxOrganizationResponse {
6989    /// ID of the Temporal workflow handling the deletion.
6990    #[prost(string, tag="1")]
6991    pub workflow_id: ::prost::alloc::string::String,
6992}
6993/// A bootstrap fixture that can be applied when creating a new organization.
6994#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
6995pub struct SandboxFixture {
6996    /// Stable slug for referencing this fixture (e.g. "starter", "empty",
6997    /// "fintech", "sales"). Pass it back as the fixture_id on create.
6998    #[prost(string, tag="1")]
6999    pub id: ::prost::alloc::string::String,
7000    /// Display name for admin UI (e.g. "Starter").
7001    #[prost(string, tag="2")]
7002    pub name: ::prost::alloc::string::String,
7003    /// Description shown alongside the fixture option in the UI.
7004    #[prost(string, tag="3")]
7005    pub description: ::prost::alloc::string::String,
7006    /// Exactly one fixture has is_default=true. Clients that show a simple
7007    /// "seed initial data" control select this fixture's id by default.
7008    #[prost(bool, tag="4")]
7009    pub is_default: bool,
7010}
7011/// Request to list all bootstrap fixtures available for seeding.
7012/// No parameters — catalog is the same for all callers.
7013#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7014pub struct ListSandboxFixturesRequest {
7015}
7016/// Response containing the bootstrap fixture catalog.
7017#[derive(Clone, PartialEq, ::prost::Message)]
7018pub struct ListSandboxFixturesResponse {
7019    /// All registered fixtures, ordered by name.
7020    #[prost(message, repeated, tag="1")]
7021    pub fixtures: ::prost::alloc::vec::Vec<SandboxFixture>,
7022}
7023/// Request to list all organizations the authenticated user belongs to.
7024/// No parameters — user identity is extracted from the JWT sub claim.
7025#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7026pub struct ListUserOrganizationsRequest {
7027}
7028/// Response containing all organizations the authenticated user belongs to.
7029#[derive(Clone, PartialEq, ::prost::Message)]
7030pub struct ListUserOrganizationsResponse {
7031    /// Organizations the user belongs to, ordered by created_at ascending.
7032    /// Excludes expired sandbox organizations.
7033    #[prost(message, repeated, tag="1")]
7034    pub organizations: ::prost::alloc::vec::Vec<Organization>,
7035}
7036/// Request to list only the sandbox organizations the authenticated user
7037/// belongs to (i.e. orgs where org_type = SANDBOX, filtered from the full
7038/// membership set). No parameters — user identity is extracted from the JWT
7039/// sub claim.
7040#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7041pub struct ListUserSandboxesRequest {
7042}
7043/// Response containing the user's sandbox organizations.
7044#[derive(Clone, PartialEq, ::prost::Message)]
7045pub struct ListUserSandboxesResponse {
7046    /// Sandbox organizations the user belongs to, ordered by expires_at
7047    /// ascending (soonest-expiring first — matches the admin UI
7048    /// /organization/sandboxes ordering). Excludes already-expired sandboxes
7049    /// (those are pending cleanup by SandboxCleanupWorkflow).
7050    #[prost(message, repeated, tag="1")]
7051    pub sandboxes: ::prost::alloc::vec::Vec<Organization>,
7052}
7053/// A single org-level data-processing toggle with consent-trace metadata.
7054/// The metadata records who flipped the toggle last and when, so the admin
7055/// consent-trace UI can show a verifiable change trail.
7056#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7057pub struct OrgPrivacyToggle {
7058    /// Whether this category of processing is enabled for the organization.
7059    #[prost(bool, tag="1")]
7060    pub enabled: bool,
7061    /// Email of the admin who last changed this toggle.
7062    /// Empty if the toggle has never been changed from its default.
7063    #[prost(string, tag="2")]
7064    pub last_changed_by_email: ::prost::alloc::string::String,
7065    /// When this toggle was last changed.
7066    /// Empty if the toggle has never been changed from its default.
7067    #[prost(message, optional, tag="3")]
7068    pub last_changed_at: ::core::option::Option<::prost_types::Timestamp>,
7069}
7070/// Org-level data-processing settings (compliance consent surface).
7071/// Each toggle gates an entire category of processing for every user in
7072/// the organization.
7073#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7074pub struct OrgPrivacySettings {
7075    /// Gates ML archetype clustering and ACK predictions.
7076    #[prost(message, optional, tag="1")]
7077    pub ai_clustering: ::core::option::Option<OrgPrivacyToggle>,
7078    /// Gates behavioral analytics (session replay, heatmaps, dwell metrics).
7079    #[prost(message, optional, tag="2")]
7080    pub behavioral_analytics: ::core::option::Option<OrgPrivacyToggle>,
7081    /// Gates third-party notification channel dispatch (email, Slack, SMS, …).
7082    #[prost(message, optional, tag="3")]
7083    pub third_party_channels: ::core::option::Option<OrgPrivacyToggle>,
7084}
7085/// Request to retrieve the org-level privacy settings.
7086/// The organization is extracted from the JWT.
7087#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7088pub struct GetOrgPrivacySettingsRequest {
7089}
7090/// Response containing the org-level privacy settings with consent-trace
7091/// metadata for each toggle.
7092#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7093pub struct GetOrgPrivacySettingsResponse {
7094    /// The organization's current privacy settings.
7095    #[prost(message, optional, tag="1")]
7096    pub settings: ::core::option::Option<OrgPrivacySettings>,
7097}
7098/// Request to update org-level privacy settings. Only the provided fields
7099/// are changed; unset fields leave the corresponding toggle unchanged.
7100#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7101pub struct UpdateOrgPrivacySettingsRequest {
7102    /// Enable or disable ML archetype clustering and ACK predictions.
7103    /// Unset leaves unchanged.
7104    #[prost(bool, optional, tag="1")]
7105    pub ai_clustering_enabled: ::core::option::Option<bool>,
7106    /// Enable or disable behavioral analytics. Unset leaves unchanged.
7107    #[prost(bool, optional, tag="2")]
7108    pub behavioral_analytics_enabled: ::core::option::Option<bool>,
7109    /// Enable or disable third-party notification channels.
7110    /// Unset leaves unchanged.
7111    #[prost(bool, optional, tag="3")]
7112    pub third_party_channels_enabled: ::core::option::Option<bool>,
7113}
7114/// Response after updating org-level privacy settings.
7115#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7116pub struct UpdateOrgPrivacySettingsResponse {
7117    /// The organization's privacy settings after the update, with refreshed
7118    /// consent-trace metadata.
7119    #[prost(message, optional, tag="1")]
7120    pub settings: ::core::option::Option<OrgPrivacySettings>,
7121}
7122// ─── Enums ───────────────────────────────────────────────────────────────────
7123
7124/// Industry vertical for an organization.
7125#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7126#[repr(i32)]
7127pub enum Industry {
7128    Unspecified = 0,
7129    Technology = 1,
7130    Finance = 2,
7131    Healthcare = 3,
7132    Education = 4,
7133    Retail = 5,
7134    Manufacturing = 6,
7135    Media = 7,
7136    Other = 8,
7137}
7138impl Industry {
7139    /// String value of the enum field names used in the ProtoBuf definition.
7140    ///
7141    /// The values are not transformed in any way and thus are considered stable
7142    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7143    pub fn as_str_name(&self) -> &'static str {
7144        match self {
7145            Self::Unspecified => "INDUSTRY_UNSPECIFIED",
7146            Self::Technology => "INDUSTRY_TECHNOLOGY",
7147            Self::Finance => "INDUSTRY_FINANCE",
7148            Self::Healthcare => "INDUSTRY_HEALTHCARE",
7149            Self::Education => "INDUSTRY_EDUCATION",
7150            Self::Retail => "INDUSTRY_RETAIL",
7151            Self::Manufacturing => "INDUSTRY_MANUFACTURING",
7152            Self::Media => "INDUSTRY_MEDIA",
7153            Self::Other => "INDUSTRY_OTHER",
7154        }
7155    }
7156    /// Creates an enum from field names used in the ProtoBuf definition.
7157    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7158        match value {
7159            "INDUSTRY_UNSPECIFIED" => Some(Self::Unspecified),
7160            "INDUSTRY_TECHNOLOGY" => Some(Self::Technology),
7161            "INDUSTRY_FINANCE" => Some(Self::Finance),
7162            "INDUSTRY_HEALTHCARE" => Some(Self::Healthcare),
7163            "INDUSTRY_EDUCATION" => Some(Self::Education),
7164            "INDUSTRY_RETAIL" => Some(Self::Retail),
7165            "INDUSTRY_MANUFACTURING" => Some(Self::Manufacturing),
7166            "INDUSTRY_MEDIA" => Some(Self::Media),
7167            "INDUSTRY_OTHER" => Some(Self::Other),
7168            _ => None,
7169        }
7170    }
7171}
7172/// Employee headcount range for an organization.
7173#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7174#[repr(i32)]
7175pub enum CompanySize {
7176    Unspecified = 0,
7177    CompanySize1200 = 1,
7178    CompanySize200500 = 2,
7179    CompanySize5001000 = 3,
7180    CompanySize10005000 = 4,
7181    CompanySize5000Plus = 5,
7182}
7183impl CompanySize {
7184    /// String value of the enum field names used in the ProtoBuf definition.
7185    ///
7186    /// The values are not transformed in any way and thus are considered stable
7187    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7188    pub fn as_str_name(&self) -> &'static str {
7189        match self {
7190            Self::Unspecified => "COMPANY_SIZE_UNSPECIFIED",
7191            Self::CompanySize1200 => "COMPANY_SIZE_1_200",
7192            Self::CompanySize200500 => "COMPANY_SIZE_200_500",
7193            Self::CompanySize5001000 => "COMPANY_SIZE_500_1000",
7194            Self::CompanySize10005000 => "COMPANY_SIZE_1000_5000",
7195            Self::CompanySize5000Plus => "COMPANY_SIZE_5000_PLUS",
7196        }
7197    }
7198    /// Creates an enum from field names used in the ProtoBuf definition.
7199    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7200        match value {
7201            "COMPANY_SIZE_UNSPECIFIED" => Some(Self::Unspecified),
7202            "COMPANY_SIZE_1_200" => Some(Self::CompanySize1200),
7203            "COMPANY_SIZE_200_500" => Some(Self::CompanySize200500),
7204            "COMPANY_SIZE_500_1000" => Some(Self::CompanySize5001000),
7205            "COMPANY_SIZE_1000_5000" => Some(Self::CompanySize10005000),
7206            "COMPANY_SIZE_5000_PLUS" => Some(Self::CompanySize5000Plus),
7207            _ => None,
7208        }
7209    }
7210}
7211/// Classification of an organization's lifecycle type.
7212#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7213#[repr(i32)]
7214pub enum OrgType {
7215    Unspecified = 0,
7216    Standard = 1,
7217    Sandbox = 2,
7218    /// Reserved for platform operations. At most one per deployment, seeded
7219    /// by migration. Cannot be created via CreateOrganization.
7220    Staff = 3,
7221}
7222impl OrgType {
7223    /// String value of the enum field names used in the ProtoBuf definition.
7224    ///
7225    /// The values are not transformed in any way and thus are considered stable
7226    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7227    pub fn as_str_name(&self) -> &'static str {
7228        match self {
7229            Self::Unspecified => "ORG_TYPE_UNSPECIFIED",
7230            Self::Standard => "ORG_TYPE_STANDARD",
7231            Self::Sandbox => "ORG_TYPE_SANDBOX",
7232            Self::Staff => "ORG_TYPE_STAFF",
7233        }
7234    }
7235    /// Creates an enum from field names used in the ProtoBuf definition.
7236    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7237        match value {
7238            "ORG_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
7239            "ORG_TYPE_STANDARD" => Some(Self::Standard),
7240            "ORG_TYPE_SANDBOX" => Some(Self::Sandbox),
7241            "ORG_TYPE_STAFF" => Some(Self::Staff),
7242            _ => None,
7243        }
7244    }
7245}
7246// ─── Messages ───────────────────────────────────────────────────────────────
7247
7248/// Per-user rendering context containing variable substitutions.
7249#[derive(Clone, PartialEq, ::prost::Message)]
7250pub struct UserRenderContext {
7251    /// ID of the user being rendered for.
7252    #[prost(string, tag="1")]
7253    pub user_id: ::prost::alloc::string::String,
7254    /// Variable name-value pairs to substitute into the template.
7255    /// Constraints: Max 100 entries. Key max length 100 characters, value max length 10000 characters.
7256    #[prost(map="string, string", tag="2")]
7257    pub variables: ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>,
7258}
7259/// Request to render a template for a batch of users.
7260#[derive(Clone, PartialEq, ::prost::Message)]
7261pub struct RenderBatchRequest {
7262    /// ID of the template to render.
7263    #[prost(string, tag="1")]
7264    pub template_id: ::prost::alloc::string::String,
7265    /// Version of the template to render.
7266    #[prost(int32, tag="2")]
7267    pub version: i32,
7268    /// Per-user rendering contexts with variable substitutions.
7269    /// Constraints: Max 10000 users per batch.
7270    #[prost(message, repeated, tag="3")]
7271    pub users: ::prost::alloc::vec::Vec<UserRenderContext>,
7272}
7273/// Streamed response for each user's rendered message.
7274/// One response is emitted per user in the batch.
7275#[derive(Clone, PartialEq, ::prost::Message)]
7276pub struct RenderBatchResponse {
7277    /// ID of the user this result is for.
7278    #[prost(string, tag="1")]
7279    pub user_id: ::prost::alloc::string::String,
7280    /// The rendered message (set on success).
7281    #[prost(message, optional, tag="2")]
7282    pub message: ::core::option::Option<Message>,
7283    /// Error message if rendering failed for this user (empty on success).
7284    #[prost(string, tag="3")]
7285    pub error: ::prost::alloc::string::String,
7286}
7287// ─── Messages ───────────────────────────────────────────────────────────────
7288
7289/// A session recording summary from the analytics provider.
7290/// Anonymous: no user identifiers are included.
7291#[derive(Clone, PartialEq, ::prost::Message)]
7292pub struct SessionRecording {
7293    /// Recording ID from the analytics provider.
7294    #[prost(string, tag="1")]
7295    pub id: ::prost::alloc::string::String,
7296    /// Timestamp when the recording started.
7297    #[prost(message, optional, tag="2")]
7298    pub start_time: ::core::option::Option<::prost_types::Timestamp>,
7299    /// Timestamp when the recording ended.
7300    #[prost(message, optional, tag="3")]
7301    pub end_time: ::core::option::Option<::prost_types::Timestamp>,
7302    /// Duration of the recording in seconds.
7303    #[prost(int32, tag="4")]
7304    pub duration_seconds: i32,
7305    /// Activity score (0.0–1.0).
7306    #[prost(float, tag="5")]
7307    pub activity_score: f32,
7308}
7309/// Request to list session recordings.
7310#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7311pub struct ListSessionRecordingsRequest {
7312    /// Optional: filter recordings by campaign ID (mapped to analytics property filter).
7313    /// Constraints: UUID format (36 characters).
7314    #[prost(string, tag="1")]
7315    pub campaign_id: ::prost::alloc::string::String,
7316    /// Optional: start of the time range filter (inclusive).
7317    #[prost(message, optional, tag="2")]
7318    pub date_from: ::core::option::Option<::prost_types::Timestamp>,
7319    /// Optional: end of the time range filter (inclusive).
7320    #[prost(message, optional, tag="3")]
7321    pub date_to: ::core::option::Option<::prost_types::Timestamp>,
7322    /// Pagination parameters.
7323    #[prost(message, optional, tag="4")]
7324    pub pagination: ::core::option::Option<Pagination>,
7325}
7326/// Response containing a page of session recordings.
7327#[derive(Clone, PartialEq, ::prost::Message)]
7328pub struct ListSessionRecordingsResponse {
7329    /// List of session recordings in this page.
7330    #[prost(message, repeated, tag="1")]
7331    pub recordings: ::prost::alloc::vec::Vec<SessionRecording>,
7332    /// Pagination metadata for fetching subsequent pages.
7333    #[prost(message, optional, tag="2")]
7334    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7335}
7336/// Request to fetch rrweb snapshot events for a recording.
7337#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7338pub struct GetSessionSnapshotsRequest {
7339    /// Recording ID from the analytics provider.
7340    /// Constraints: Max length 200 characters.
7341    #[prost(string, tag="1")]
7342    pub recording_id: ::prost::alloc::string::String,
7343}
7344/// Response containing rrweb snapshot events.
7345#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7346pub struct GetSessionSnapshotsResponse {
7347    /// JSON-encoded array of rrweb eventWithTime objects.
7348    /// Clients parse this JSON to feed into rrweb-player.
7349    #[prost(string, tag="1")]
7350    pub snapshot_data: ::prost::alloc::string::String,
7351}
7352// ─── Messages ───────────────────────────────────────────────────────────────
7353
7354/// Request to list all roles in the caller's organization.
7355#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7356pub struct ListRolesRequest {
7357}
7358/// Response containing the organization's roles.
7359#[derive(Clone, PartialEq, ::prost::Message)]
7360pub struct ListRolesResponse {
7361    /// All roles in the organization, including their permission sets.
7362    #[prost(message, repeated, tag="1")]
7363    pub roles: ::prost::alloc::vec::Vec<Role>,
7364}
7365/// Request to create a new role in the caller's organization.
7366#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7367pub struct CreateRoleRequest {
7368    /// Display name for the role (e.g. "Team Lead"). Required.
7369    /// A slug is auto-generated from the name.
7370    #[prost(string, tag="1")]
7371    pub name: ::prost::alloc::string::String,
7372    /// Initial permission set for the role.
7373    /// PERMISSION_UNSPECIFIED values are rejected.
7374    #[prost(enumeration="Permission", repeated, tag="2")]
7375    pub permissions: ::prost::alloc::vec::Vec<i32>,
7376}
7377/// Response after creating a role.
7378#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7379pub struct CreateRoleResponse {
7380    /// The newly created role with its generated slug and permission set.
7381    #[prost(message, optional, tag="1")]
7382    pub role: ::core::option::Option<Role>,
7383}
7384/// Request to update a role's name and/or permissions.
7385#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7386pub struct UpdateRoleRequest {
7387    /// ID of the role to update. Required.
7388    #[prost(string, tag="1")]
7389    pub role_id: ::prost::alloc::string::String,
7390    /// New display name. If empty, the name is not changed.
7391    #[prost(string, tag="2")]
7392    pub name: ::prost::alloc::string::String,
7393    /// New permission set (replaces existing permissions entirely).
7394    /// If empty, permissions are not changed.
7395    /// PERMISSION_UNSPECIFIED values are rejected.
7396    #[prost(enumeration="Permission", repeated, tag="3")]
7397    pub permissions: ::prost::alloc::vec::Vec<i32>,
7398}
7399/// Response after updating a role.
7400#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7401pub struct UpdateRoleResponse {
7402    /// The updated role.
7403    #[prost(message, optional, tag="1")]
7404    pub role: ::core::option::Option<Role>,
7405}
7406/// Request to delete a role.
7407#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7408pub struct DeleteRoleRequest {
7409    /// ID of the role to delete. Required.
7410    #[prost(string, tag="1")]
7411    pub role_id: ::prost::alloc::string::String,
7412}
7413/// Response after deleting a role.
7414#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7415pub struct DeleteRoleResponse {
7416}
7417// ─── Messages ───────────────────────────────────────────────────────────────
7418
7419/// Custom SAML attribute name overrides for identity providers that use
7420/// non-standard attribute names. When provided, these override the
7421/// auto-detected values from the metadata URL host.
7422#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7423pub struct SamlAttributeNames {
7424    /// SAML attribute name for the user's email address.
7425    #[prost(string, tag="1")]
7426    pub email: ::prost::alloc::string::String,
7427    /// SAML attribute name for the user's first name.
7428    #[prost(string, tag="2")]
7429    pub given_name: ::prost::alloc::string::String,
7430    /// SAML attribute name for the user's last name.
7431    #[prost(string, tag="3")]
7432    pub family_name: ::prost::alloc::string::String,
7433}
7434/// An SSO identity provider configured for an organization.
7435#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7436pub struct SsoProvider {
7437    /// Unique identifier for the provider.
7438    #[prost(string, tag="1")]
7439    pub id: ::prost::alloc::string::String,
7440    /// Email domain that triggers this SSO provider (e.g. "acme.com").
7441    /// Constraints: Max length 253 characters (RFC 1035).
7442    #[prost(string, tag="2")]
7443    pub domain: ::prost::alloc::string::String,
7444    /// Type of identity provider.
7445    #[prost(enumeration="SsoProviderType", tag="3")]
7446    pub r#type: i32,
7447    /// SAML metadata URL or OIDC discovery URL.
7448    /// Constraints: Max length 2048 characters. HTTPS required.
7449    #[prost(string, tag="4")]
7450    pub metadata_url: ::prost::alloc::string::String,
7451    /// Name of the identity provider (used for signInWithRedirect).
7452    /// Set by the API when the IdP is created.
7453    #[prost(string, tag="5")]
7454    pub idp_provider_name: ::prost::alloc::string::String,
7455    /// Timestamp when the provider was created.
7456    #[prost(message, optional, tag="6")]
7457    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7458    /// Timestamp when the provider was last updated.
7459    #[prost(message, optional, tag="7")]
7460    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
7461    /// Optional custom SAML attribute name overrides.
7462    #[prost(message, optional, tag="8")]
7463    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
7464}
7465/// Request to check if an email domain has SSO configured.
7466/// This RPC is pre-authentication — no JWT required.
7467#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7468pub struct CheckSsoByDomainRequest {
7469    /// Email address to check. The domain part is extracted.
7470    /// Constraints: Max length 254 characters (RFC 5321).
7471    #[prost(string, tag="1")]
7472    pub email: ::prost::alloc::string::String,
7473}
7474/// Response for SSO domain check.
7475#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7476pub struct CheckSsoByDomainResponse {
7477    /// Whether SSO is enabled for the email's domain.
7478    #[prost(bool, tag="1")]
7479    pub sso_enabled: bool,
7480    /// Identity provider name for signInWithRedirect.
7481    /// Empty if sso_enabled is false.
7482    #[prost(string, tag="2")]
7483    pub provider_name: ::prost::alloc::string::String,
7484}
7485/// Request to create an SSO provider for the organization.
7486#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7487pub struct CreateSsoProviderRequest {
7488    /// Email domain to associate (e.g. "acme.com").
7489    /// Constraints: Max length 253 characters (RFC 1035).
7490    #[prost(string, tag="1")]
7491    pub domain: ::prost::alloc::string::String,
7492    /// Type of identity provider.
7493    #[prost(enumeration="SsoProviderType", tag="2")]
7494    pub r#type: i32,
7495    /// SAML metadata URL or OIDC discovery URL.
7496    /// Constraints: Max length 2048 characters. HTTPS required.
7497    #[prost(string, tag="3")]
7498    pub metadata_url: ::prost::alloc::string::String,
7499    /// Optional custom SAML attribute name overrides.
7500    /// When omitted, attribute names are auto-detected from the metadata URL.
7501    #[prost(message, optional, tag="4")]
7502    pub attribute_mapping: ::core::option::Option<SamlAttributeNames>,
7503}
7504/// Response after creating an SSO provider.
7505#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7506pub struct CreateSsoProviderResponse {
7507    /// The newly created SSO provider.
7508    #[prost(message, optional, tag="1")]
7509    pub provider: ::core::option::Option<SsoProvider>,
7510}
7511/// Request to get the SSO provider for the organization.
7512/// Returns the provider if one is configured, or empty if not.
7513#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7514pub struct GetSsoProviderRequest {
7515}
7516/// Response containing the organization's SSO provider.
7517#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7518pub struct GetSsoProviderResponse {
7519    /// The organization's SSO provider, or null if not configured.
7520    #[prost(message, optional, tag="1")]
7521    pub provider: ::core::option::Option<SsoProvider>,
7522}
7523/// Request to delete the organization's SSO provider.
7524#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7525pub struct DeleteSsoProviderRequest {
7526    /// ID of the provider to delete.
7527    #[prost(string, tag="1")]
7528    pub provider_id: ::prost::alloc::string::String,
7529}
7530/// Response after deleting an SSO provider.
7531#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7532pub struct DeleteSsoProviderResponse {
7533}
7534// ─── Enums ──────────────────────────────────────────────────────────────────
7535
7536/// Type of SSO identity provider.
7537#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
7538#[repr(i32)]
7539pub enum SsoProviderType {
7540    /// Default value; not a valid type.
7541    Unspecified = 0,
7542    /// SAML 2.0 identity provider (e.g. Okta, Azure AD).
7543    Saml = 1,
7544    /// OpenID Connect identity provider (e.g. Google Workspace, Auth0).
7545    Oidc = 2,
7546}
7547impl SsoProviderType {
7548    /// String value of the enum field names used in the ProtoBuf definition.
7549    ///
7550    /// The values are not transformed in any way and thus are considered stable
7551    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
7552    pub fn as_str_name(&self) -> &'static str {
7553        match self {
7554            Self::Unspecified => "SSO_PROVIDER_TYPE_UNSPECIFIED",
7555            Self::Saml => "SSO_PROVIDER_TYPE_SAML",
7556            Self::Oidc => "SSO_PROVIDER_TYPE_OIDC",
7557        }
7558    }
7559    /// Creates an enum from field names used in the ProtoBuf definition.
7560    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
7561        match value {
7562            "SSO_PROVIDER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
7563            "SSO_PROVIDER_TYPE_SAML" => Some(Self::Saml),
7564            "SSO_PROVIDER_TYPE_OIDC" => Some(Self::Oidc),
7565            _ => None,
7566        }
7567    }
7568}
7569// ─── Messages ───────────────────────────────────────────────────────────────
7570
7571/// An organizational unit within an organization (e.g. department, division).
7572/// Teams represent the organizational structure and can serve as sender identity
7573/// in campaigns.
7574#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7575pub struct Team {
7576    /// Unique identifier for the team.
7577    #[prost(string, tag="1")]
7578    pub id: ::prost::alloc::string::String,
7579    /// Human-readable display name (unique within the organization).
7580    /// Constraints: Max length 200 characters.
7581    #[prost(string, tag="2")]
7582    pub name: ::prost::alloc::string::String,
7583    /// Optional description of the team's purpose.
7584    /// Constraints: Max length 1000 characters.
7585    #[prost(string, tag="3")]
7586    pub description: ::prost::alloc::string::String,
7587    /// Number of users currently in the team.
7588    #[prost(int32, tag="4")]
7589    pub member_count: i32,
7590    /// Timestamp when the team was created.
7591    #[prost(message, optional, tag="5")]
7592    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7593    /// Timestamp when the team was last updated.
7594    #[prost(message, optional, tag="6")]
7595    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
7596    /// Whether this is the organization's default team (cannot be deleted or renamed).
7597    #[prost(bool, tag="7")]
7598    pub is_default: bool,
7599    /// ID of the user who created this team. Empty for system-seeded defaults.
7600    #[prost(string, tag="8")]
7601    pub created_by: ::prost::alloc::string::String,
7602}
7603/// Request to create a new team.
7604#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7605pub struct CreateTeamRequest {
7606    /// Display name for the team. Required.
7607    /// Constraints: Max length 200 characters.
7608    #[prost(string, tag="1")]
7609    pub name: ::prost::alloc::string::String,
7610    /// Optional description.
7611    /// Constraints: Max length 1000 characters.
7612    #[prost(string, tag="2")]
7613    pub description: ::prost::alloc::string::String,
7614}
7615/// Response after creating a team.
7616#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7617pub struct CreateTeamResponse {
7618    /// The newly created team.
7619    #[prost(message, optional, tag="1")]
7620    pub team: ::core::option::Option<Team>,
7621}
7622/// Request to retrieve a team by ID.
7623#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7624pub struct GetTeamRequest {
7625    /// ID of the team to retrieve. Required.
7626    #[prost(string, tag="1")]
7627    pub team_id: ::prost::alloc::string::String,
7628}
7629/// Response containing the requested team.
7630#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7631pub struct GetTeamResponse {
7632    /// The requested team.
7633    #[prost(message, optional, tag="1")]
7634    pub team: ::core::option::Option<Team>,
7635}
7636/// Request to list teams in the organization with pagination.
7637#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7638pub struct ListTeamsRequest {
7639    /// Pagination parameters.
7640    #[prost(message, optional, tag="1")]
7641    pub pagination: ::core::option::Option<Pagination>,
7642}
7643/// Response containing a page of teams.
7644#[derive(Clone, PartialEq, ::prost::Message)]
7645pub struct ListTeamsResponse {
7646    /// Teams in this page.
7647    #[prost(message, repeated, tag="1")]
7648    pub teams: ::prost::alloc::vec::Vec<Team>,
7649    /// Pagination metadata for fetching subsequent pages.
7650    #[prost(message, optional, tag="2")]
7651    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7652}
7653/// Request to update a team's name and/or description.
7654#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7655pub struct UpdateTeamRequest {
7656    /// ID of the team to update. Required.
7657    #[prost(string, tag="1")]
7658    pub team_id: ::prost::alloc::string::String,
7659    /// New display name. If empty, the name is not changed.
7660    /// Default teams cannot be renamed.
7661    /// Constraints: Max length 200 characters.
7662    #[prost(string, tag="2")]
7663    pub name: ::prost::alloc::string::String,
7664    /// New description. If empty, the description is not changed.
7665    /// Constraints: Max length 1000 characters.
7666    #[prost(string, tag="3")]
7667    pub description: ::prost::alloc::string::String,
7668}
7669/// Response after updating a team.
7670#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7671pub struct UpdateTeamResponse {
7672    /// The updated team.
7673    #[prost(message, optional, tag="1")]
7674    pub team: ::core::option::Option<Team>,
7675}
7676/// Request to delete a team.
7677#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7678pub struct DeleteTeamRequest {
7679    /// ID of the team to delete. Required.
7680    /// Default teams cannot be deleted.
7681    #[prost(string, tag="1")]
7682    pub team_id: ::prost::alloc::string::String,
7683}
7684/// Response after deleting a team.
7685#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)]
7686pub struct DeleteTeamResponse {
7687}
7688/// Request to add users to a team.
7689#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7690pub struct AddTeamMembersRequest {
7691    /// ID of the team to add members to. Required.
7692    #[prost(string, tag="1")]
7693    pub team_id: ::prost::alloc::string::String,
7694    /// IDs of users to add. Must belong to the same organization.
7695    /// Adding an existing member is a no-op (idempotent).
7696    /// Constraints: Max 100 user IDs per request.
7697    #[prost(string, repeated, tag="2")]
7698    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
7699}
7700/// Response after adding team members.
7701#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7702pub struct AddTeamMembersResponse {
7703    /// The team with updated member_count.
7704    #[prost(message, optional, tag="1")]
7705    pub team: ::core::option::Option<Team>,
7706}
7707/// Request to remove users from a team.
7708#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7709pub struct RemoveTeamMembersRequest {
7710    /// ID of the team to remove members from. Required.
7711    #[prost(string, tag="1")]
7712    pub team_id: ::prost::alloc::string::String,
7713    /// IDs of users to remove. Removing a non-member is a no-op (idempotent).
7714    /// Constraints: Max 100 user IDs per request.
7715    #[prost(string, repeated, tag="2")]
7716    pub user_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
7717}
7718/// Response after removing team members.
7719#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7720pub struct RemoveTeamMembersResponse {
7721    /// The team with updated member_count.
7722    #[prost(message, optional, tag="1")]
7723    pub team: ::core::option::Option<Team>,
7724}
7725/// Request to list members of a team with pagination.
7726#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7727pub struct ListTeamMembersRequest {
7728    /// ID of the team whose members to list. Required.
7729    #[prost(string, tag="1")]
7730    pub team_id: ::prost::alloc::string::String,
7731    /// Pagination parameters.
7732    #[prost(message, optional, tag="2")]
7733    pub pagination: ::core::option::Option<Pagination>,
7734}
7735/// Response containing a page of team members.
7736#[derive(Clone, PartialEq, ::prost::Message)]
7737pub struct ListTeamMembersResponse {
7738    /// Users in this page.
7739    #[prost(message, repeated, tag="1")]
7740    pub users: ::prost::alloc::vec::Vec<User>,
7741    /// Pagination metadata for fetching subsequent pages.
7742    #[prost(message, optional, tag="2")]
7743    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7744}
7745// ─── Messages ───────────────────────────────────────────────────────────────
7746
7747/// A variable placeholder within a template that gets substituted during rendering.
7748#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7749pub struct TemplateVariable {
7750    /// Variable name used in the template body (e.g. "employee_name").
7751    /// Constraints: Max length 100 characters.
7752    #[prost(string, tag="1")]
7753    pub name: ::prost::alloc::string::String,
7754    /// Human-readable description of what this variable represents.
7755    /// Constraints: Max length 500 characters.
7756    #[prost(string, tag="2")]
7757    pub description: ::prost::alloc::string::String,
7758    /// Whether this variable must be provided during rendering.
7759    #[prost(bool, tag="3")]
7760    pub required: bool,
7761    /// Where this variable's value comes from (profile attribute or campaign config).
7762    #[prost(enumeration="TemplateVariableSource", tag="4")]
7763    pub source: i32,
7764    /// Fallback value used when the source does not provide a value.
7765    /// Constraints: Max length 1000 characters.
7766    #[prost(string, tag="5")]
7767    pub default_value: ::prost::alloc::string::String,
7768    /// When true, this variable's rendered value is masked in session replay
7769    /// and heatmap screenshots. Org admin controls per variable.
7770    #[prost(bool, tag="6")]
7771    pub pii: bool,
7772}
7773/// A versioned message template with variable placeholders.
7774/// Templates are append-only — updates create new versions.
7775#[derive(Clone, PartialEq, ::prost::Message)]
7776pub struct Template {
7777    /// Unique identifier for the template.
7778    #[prost(string, tag="1")]
7779    pub id: ::prost::alloc::string::String,
7780    /// Human-readable template name (admin-facing label).
7781    /// Constraints: Max length 200 characters.
7782    #[prost(string, tag="2")]
7783    pub name: ::prost::alloc::string::String,
7784    /// Template body with {{variable}} placeholders for substitution.
7785    /// Constraints: Max length 50000 characters.
7786    #[prost(string, tag="3")]
7787    pub body: ::prost::alloc::string::String,
7788    /// Variables that can be substituted into the template body.
7789    #[prost(message, repeated, tag="4")]
7790    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
7791    /// Version number (auto-incremented on each update).
7792    #[prost(int32, tag="5")]
7793    pub version: i32,
7794    /// Timestamp when this version was created.
7795    #[prost(message, optional, tag="6")]
7796    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7797    /// Timestamp of the most recent update (same as created_at for the latest version).
7798    #[prost(message, optional, tag="7")]
7799    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
7800    /// User-facing title shown as the message subject to recipients.
7801    /// Serves as the default title; campaigns can override it.
7802    /// Constraints: Max length 200 characters.
7803    #[prost(string, tag="8")]
7804    pub title: ::prost::alloc::string::String,
7805    /// Content format of this template (markdown, rich, HTML).
7806    /// UNSPECIFIED is treated as MARKDOWN for backward compatibility.
7807    #[prost(enumeration="TemplateType", tag="9")]
7808    pub r#type: i32,
7809    /// Language of the template body content (e.g., "en", "es", "ja").
7810    /// Defaults to the org's default_locale, falling back to "en".
7811    /// Translations are created as locale variants of this source.
7812    #[prost(string, tag="10")]
7813    pub source_locale: ::prost::alloc::string::String,
7814}
7815/// A locale-specific translation of a template's title and body.
7816/// Translations are created per template version and go through a review workflow.
7817#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7818pub struct TemplateTranslation {
7819    /// Unique identifier for this translation.
7820    #[prost(string, tag="1")]
7821    pub id: ::prost::alloc::string::String,
7822    /// ID of the source template.
7823    #[prost(string, tag="2")]
7824    pub template_id: ::prost::alloc::string::String,
7825    /// Version of the source template this translation is for.
7826    #[prost(int32, tag="3")]
7827    pub version: i32,
7828    /// Target locale (e.g., "es", "pt-BR", "zh", "ja").
7829    #[prost(string, tag="4")]
7830    pub locale: ::prost::alloc::string::String,
7831    /// Translated title.
7832    /// Constraints: Max length 200 characters.
7833    #[prost(string, tag="5")]
7834    pub title: ::prost::alloc::string::String,
7835    /// Translated body content with {{variable}} placeholders preserved.
7836    /// Constraints: Max length 50000 characters.
7837    #[prost(string, tag="6")]
7838    pub body: ::prost::alloc::string::String,
7839    /// Current review status.
7840    #[prost(enumeration="TranslationStatus", tag="7")]
7841    pub status: i32,
7842    /// Who created this translation ("ai:bedrock", "ai:deepl", or user UUID).
7843    #[prost(string, tag="8")]
7844    pub translated_by: ::prost::alloc::string::String,
7845    /// User who approved the translation. Empty until approved.
7846    #[prost(string, tag="9")]
7847    pub reviewed_by: ::prost::alloc::string::String,
7848    /// When the translation was approved.
7849    #[prost(message, optional, tag="10")]
7850    pub reviewed_at: ::core::option::Option<::prost_types::Timestamp>,
7851    /// When the translation was created.
7852    #[prost(message, optional, tag="11")]
7853    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
7854}
7855/// Request to create a new template.
7856#[derive(Clone, PartialEq, ::prost::Message)]
7857pub struct CreateTemplateRequest {
7858    /// Human-readable template name (admin-facing label).
7859    /// Constraints: Max length 200 characters.
7860    #[prost(string, tag="1")]
7861    pub name: ::prost::alloc::string::String,
7862    /// Template body with {{variable}} placeholders.
7863    /// Constraints: Max length 50000 characters.
7864    #[prost(string, tag="2")]
7865    pub body: ::prost::alloc::string::String,
7866    /// Variables available for substitution in the body.
7867    #[prost(message, repeated, tag="3")]
7868    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
7869    /// User-facing title shown as the message subject to recipients.
7870    /// Constraints: Max length 200 characters.
7871    #[prost(string, tag="4")]
7872    pub title: ::prost::alloc::string::String,
7873    /// Content format of the template. Defaults to MARKDOWN if unspecified.
7874    #[prost(enumeration="TemplateType", tag="5")]
7875    pub r#type: i32,
7876    /// Language of the template body content. Defaults to org's default_locale.
7877    /// Valid values: en, es, pt-BR, zh, ja.
7878    #[prost(string, tag="6")]
7879    pub source_locale: ::prost::alloc::string::String,
7880}
7881/// Response after creating a template.
7882#[derive(Clone, PartialEq, ::prost::Message)]
7883pub struct CreateTemplateResponse {
7884    /// The newly created template (version 1).
7885    #[prost(message, optional, tag="1")]
7886    pub template: ::core::option::Option<Template>,
7887}
7888/// Request to update a template, creating a new version.
7889#[derive(Clone, PartialEq, ::prost::Message)]
7890pub struct UpdateTemplateRequest {
7891    /// ID of the template to update.
7892    #[prost(string, tag="1")]
7893    pub template_id: ::prost::alloc::string::String,
7894    /// New template body with {{variable}} placeholders.
7895    /// Constraints: Max length 50000 characters.
7896    #[prost(string, tag="2")]
7897    pub body: ::prost::alloc::string::String,
7898    /// Updated variables for substitution.
7899    #[prost(message, repeated, tag="3")]
7900    pub variables: ::prost::alloc::vec::Vec<TemplateVariable>,
7901}
7902/// Response after updating a template.
7903#[derive(Clone, PartialEq, ::prost::Message)]
7904pub struct UpdateTemplateResponse {
7905    /// The updated template with incremented version number.
7906    #[prost(message, optional, tag="1")]
7907    pub template: ::core::option::Option<Template>,
7908}
7909/// Request to retrieve a specific template version.
7910#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7911pub struct GetTemplateRequest {
7912    /// ID of the template to retrieve.
7913    #[prost(string, tag="1")]
7914    pub template_id: ::prost::alloc::string::String,
7915    /// Version to retrieve. 0 returns the latest version.
7916    #[prost(int32, tag="2")]
7917    pub version: i32,
7918}
7919/// Response containing the requested template.
7920#[derive(Clone, PartialEq, ::prost::Message)]
7921pub struct GetTemplateResponse {
7922    /// The requested template.
7923    #[prost(message, optional, tag="1")]
7924    pub template: ::core::option::Option<Template>,
7925}
7926/// Request to list templates with pagination.
7927#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7928pub struct ListTemplatesRequest {
7929    /// Pagination parameters.
7930    #[prost(message, optional, tag="1")]
7931    pub pagination: ::core::option::Option<Pagination>,
7932    /// Filter by template type. UNSPECIFIED returns all templates.
7933    #[prost(enumeration="TemplateType", tag="2")]
7934    pub r#type: i32,
7935}
7936/// Response containing a page of templates.
7937#[derive(Clone, PartialEq, ::prost::Message)]
7938pub struct ListTemplatesResponse {
7939    /// List of templates in this page (latest version of each).
7940    #[prost(message, repeated, tag="1")]
7941    pub templates: ::prost::alloc::vec::Vec<Template>,
7942    /// Pagination metadata for fetching subsequent pages.
7943    #[prost(message, optional, tag="2")]
7944    pub pagination_meta: ::core::option::Option<PaginationMeta>,
7945}
7946/// Request to create a translation for a template.
7947#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7948pub struct CreateTemplateTranslationRequest {
7949    /// ID of the template to translate.
7950    #[prost(string, tag="1")]
7951    pub template_id: ::prost::alloc::string::String,
7952    /// Version of the template to translate.
7953    #[prost(int32, tag="2")]
7954    pub version: i32,
7955    /// Target locale.
7956    #[prost(string, tag="3")]
7957    pub locale: ::prost::alloc::string::String,
7958    /// Translated title.
7959    #[prost(string, tag="4")]
7960    pub title: ::prost::alloc::string::String,
7961    /// Translated body content.
7962    #[prost(string, tag="5")]
7963    pub body: ::prost::alloc::string::String,
7964    /// Who created this translation ("ai:bedrock" or user UUID).
7965    #[prost(string, tag="6")]
7966    pub translated_by: ::prost::alloc::string::String,
7967    /// Initial status (typically DRAFT or AI_TRANSLATED).
7968    #[prost(enumeration="TranslationStatus", tag="7")]
7969    pub status: i32,
7970}
7971/// Response after creating a template translation.
7972#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7973pub struct CreateTemplateTranslationResponse {
7974    /// The created translation.
7975    #[prost(message, optional, tag="1")]
7976    pub translation: ::core::option::Option<TemplateTranslation>,
7977}
7978/// Request to update an existing template translation.
7979#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7980pub struct UpdateTemplateTranslationRequest {
7981    /// ID of the translation to update.
7982    #[prost(string, tag="1")]
7983    pub translation_id: ::prost::alloc::string::String,
7984    /// Updated title. Empty leaves unchanged.
7985    #[prost(string, tag="2")]
7986    pub title: ::prost::alloc::string::String,
7987    /// Updated body. Empty leaves unchanged.
7988    #[prost(string, tag="3")]
7989    pub body: ::prost::alloc::string::String,
7990    /// Updated status.
7991    #[prost(enumeration="TranslationStatus", tag="4")]
7992    pub status: i32,
7993}
7994/// Response after updating a template translation.
7995#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
7996pub struct UpdateTemplateTranslationResponse {
7997    /// The updated translation.
7998    #[prost(message, optional, tag="1")]
7999    pub translation: ::core::option::Option<TemplateTranslation>,
8000}
8001/// Request to list translations for a template version.
8002#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8003pub struct ListTemplateTranslationsRequest {
8004    /// ID of the template.
8005    #[prost(string, tag="1")]
8006    pub template_id: ::prost::alloc::string::String,
8007    /// Version of the template. 0 returns translations for the latest version.
8008    #[prost(int32, tag="2")]
8009    pub version: i32,
8010}
8011/// Response containing all translations for a template version.
8012#[derive(Clone, PartialEq, ::prost::Message)]
8013pub struct ListTemplateTranslationsResponse {
8014    /// Translations for the requested template version.
8015    #[prost(message, repeated, tag="1")]
8016    pub translations: ::prost::alloc::vec::Vec<TemplateTranslation>,
8017}
8018/// Request to approve a template translation.
8019#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8020pub struct ApproveTemplateTranslationRequest {
8021    /// ID of the translation to approve.
8022    #[prost(string, tag="1")]
8023    pub translation_id: ::prost::alloc::string::String,
8024}
8025/// Response after approving a template translation.
8026#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8027pub struct ApproveTemplateTranslationResponse {
8028    /// The approved translation (status: APPROVED, reviewed_by and reviewed_at set).
8029    #[prost(message, optional, tag="1")]
8030    pub translation: ::core::option::Option<TemplateTranslation>,
8031}
8032// ─── Enums ──────────────────────────────────────────────────────────────────
8033
8034/// Content format of a template, determining which editor and renderer to use.
8035#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8036#[repr(i32)]
8037pub enum TemplateType {
8038    /// Default value; treated as MARKDOWN for backward compatibility.
8039    Unspecified = 0,
8040    /// Markdown with {{variable}} placeholders.
8041    Markdown = 1,
8042    /// Rich text format (reserved for future use).
8043    Rich = 2,
8044    /// Raw HTML format (reserved for future use).
8045    Html = 3,
8046}
8047impl TemplateType {
8048    /// String value of the enum field names used in the ProtoBuf definition.
8049    ///
8050    /// The values are not transformed in any way and thus are considered stable
8051    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8052    pub fn as_str_name(&self) -> &'static str {
8053        match self {
8054            Self::Unspecified => "TEMPLATE_TYPE_UNSPECIFIED",
8055            Self::Markdown => "TEMPLATE_TYPE_MARKDOWN",
8056            Self::Rich => "TEMPLATE_TYPE_RICH",
8057            Self::Html => "TEMPLATE_TYPE_HTML",
8058        }
8059    }
8060    /// Creates an enum from field names used in the ProtoBuf definition.
8061    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8062        match value {
8063            "TEMPLATE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
8064            "TEMPLATE_TYPE_MARKDOWN" => Some(Self::Markdown),
8065            "TEMPLATE_TYPE_RICH" => Some(Self::Rich),
8066            "TEMPLATE_TYPE_HTML" => Some(Self::Html),
8067            _ => None,
8068        }
8069    }
8070}
8071/// Source from which a template variable's value is resolved at render time.
8072#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8073#[repr(i32)]
8074pub enum TemplateVariableSource {
8075    /// Default value; treated as CUSTOM for backward compatibility.
8076    Unspecified = 0,
8077    /// Auto-resolved from the target user's profile attributes.
8078    Profile = 1,
8079    /// Provided manually in the campaign or workflow step configuration.
8080    Custom = 2,
8081}
8082impl TemplateVariableSource {
8083    /// String value of the enum field names used in the ProtoBuf definition.
8084    ///
8085    /// The values are not transformed in any way and thus are considered stable
8086    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8087    pub fn as_str_name(&self) -> &'static str {
8088        match self {
8089            Self::Unspecified => "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED",
8090            Self::Profile => "TEMPLATE_VARIABLE_SOURCE_PROFILE",
8091            Self::Custom => "TEMPLATE_VARIABLE_SOURCE_CUSTOM",
8092        }
8093    }
8094    /// Creates an enum from field names used in the ProtoBuf definition.
8095    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8096        match value {
8097            "TEMPLATE_VARIABLE_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
8098            "TEMPLATE_VARIABLE_SOURCE_PROFILE" => Some(Self::Profile),
8099            "TEMPLATE_VARIABLE_SOURCE_CUSTOM" => Some(Self::Custom),
8100            _ => None,
8101        }
8102    }
8103}
8104/// Review status of a template translation.
8105#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8106#[repr(i32)]
8107pub enum TranslationStatus {
8108    Unspecified = 0,
8109    /// Translation draft, not yet reviewed.
8110    Draft = 1,
8111    /// Translation generated by AI, pending human review.
8112    AiTranslated = 2,
8113    /// Translation is being reviewed by a human.
8114    InReview = 3,
8115    /// Translation has been approved for use.
8116    Approved = 4,
8117}
8118impl TranslationStatus {
8119    /// String value of the enum field names used in the ProtoBuf definition.
8120    ///
8121    /// The values are not transformed in any way and thus are considered stable
8122    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8123    pub fn as_str_name(&self) -> &'static str {
8124        match self {
8125            Self::Unspecified => "TRANSLATION_STATUS_UNSPECIFIED",
8126            Self::Draft => "TRANSLATION_STATUS_DRAFT",
8127            Self::AiTranslated => "TRANSLATION_STATUS_AI_TRANSLATED",
8128            Self::InReview => "TRANSLATION_STATUS_IN_REVIEW",
8129            Self::Approved => "TRANSLATION_STATUS_APPROVED",
8130        }
8131    }
8132    /// Creates an enum from field names used in the ProtoBuf definition.
8133    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8134        match value {
8135            "TRANSLATION_STATUS_UNSPECIFIED" => Some(Self::Unspecified),
8136            "TRANSLATION_STATUS_DRAFT" => Some(Self::Draft),
8137            "TRANSLATION_STATUS_AI_TRANSLATED" => Some(Self::AiTranslated),
8138            "TRANSLATION_STATUS_IN_REVIEW" => Some(Self::InReview),
8139            "TRANSLATION_STATUS_APPROVED" => Some(Self::Approved),
8140            _ => None,
8141        }
8142    }
8143}
8144// ─── Messages ───────────────────────────────────────────────────────────────
8145
8146/// Decoded deeplink-token payload. Populated by ValidateDeeplinkToken
8147/// only when validation succeeds.
8148#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8149pub struct DeeplinkTokenPayload {
8150    /// Campaign UUID the deeplink targets. The native app uses this for the
8151    /// authenticated GetCampaign follow-up post-recipient-auth.
8152    #[prost(string, tag="1")]
8153    pub campaign_id: ::prost::alloc::string::String,
8154    /// Recipient UUID the token authorizes. The token does not authenticate
8155    /// the recipient (that's the auth flow's job); it authorizes "this
8156    /// deeplink path is for this recipient" so the native app can refuse
8157    /// to render a token whose embedded recipient mismatches the signed-in
8158    /// user.
8159    #[prost(string, tag="2")]
8160    pub recipient_user_id: ::prost::alloc::string::String,
8161    /// Step kind the deeplink targets — REMINDER vs ESCALATION. Lets the
8162    /// native app pick the right campaign-card variant before the auth
8163    /// gate.
8164    #[prost(enumeration="ChannelStepKind", tag="3")]
8165    pub step_kind: i32,
8166    /// Expiry the token carries. Validation rejects tokens past this time
8167    /// even if the signature checks out.
8168    #[prost(message, optional, tag="4")]
8169    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
8170}
8171#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8172pub struct SignDeeplinkTokenRequest {
8173    /// Campaign whose deeplink this token authorizes. Constraints: required,
8174    /// must be a UUID and exist within the caller's organization.
8175    #[prost(string, tag="1")]
8176    pub campaign_id: ::prost::alloc::string::String,
8177    /// Recipient the token authorizes. Constraints: required, must be a UUID
8178    /// and a member of the campaign's audience.
8179    #[prost(string, tag="2")]
8180    pub recipient_user_id: ::prost::alloc::string::String,
8181    /// Step kind the deeplink targets. Required.
8182    #[prost(enumeration="ChannelStepKind", tag="3")]
8183    pub step_kind: i32,
8184    /// Token lifetime in seconds from now. Constraints: required, must be
8185    /// in (0, 30 * 24 * 3600] (1 second to 30 days). 30 days matches the
8186    /// platform's outer bound on actionable campaign lifetimes; longer
8187    /// tokens are not signed.
8188    #[prost(int64, tag="4")]
8189    pub ttl_seconds: i64,
8190}
8191#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8192pub struct SignDeeplinkTokenResponse {
8193    /// The signed token, ready to URL-embed in
8194    /// links.pidgr.com/c/{short_code}?t={token}. Format: base64url-encoded
8195    /// payload (JSON) + base64url-encoded HMAC-SHA256 trailer, joined by
8196    /// a single dot. Implementation detail — clients SHOULD NOT parse or
8197    /// mutate the token; they pass it back to ValidateDeeplinkToken.
8198    #[prost(string, tag="1")]
8199    pub token: ::prost::alloc::string::String,
8200    /// The expiry the token carries. Echoed back so clients don't need to
8201    /// redo the time-math the caller passed in via ttl_seconds.
8202    #[prost(message, optional, tag="2")]
8203    pub expires_at: ::core::option::Option<::prost_types::Timestamp>,
8204    /// The platform key version used to sign. Clients MAY record for
8205    /// telemetry but SHOULD NOT branch logic on it — the platform manages
8206    /// overlap windows during rotation transparently.
8207    #[prost(int32, tag="3")]
8208    pub key_version: i32,
8209}
8210#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8211pub struct ValidateDeeplinkTokenRequest {
8212    /// The token bytes from the deeplink URL's `t` query parameter.
8213    /// Constraints: required, non-empty.
8214    #[prost(string, tag="1")]
8215    pub token: ::prost::alloc::string::String,
8216    /// Campaign UUID embedded in the URL path (translated from the
8217    /// short-code by the native app via CampaignService.GetCampaignByShortCode).
8218    /// Validation rejects when the token's embedded campaign_id does not
8219    /// match — defense against replay attacks that swap the short-code
8220    /// path component while reusing a signed token from a different
8221    /// campaign.
8222    #[prost(string, tag="2")]
8223    pub campaign_id: ::prost::alloc::string::String,
8224}
8225#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8226pub struct ValidateDeeplinkTokenResponse {
8227    /// True when signature + expiry both check out under any active or
8228    /// overlap-window key version.
8229    #[prost(bool, tag="1")]
8230    pub valid: bool,
8231    /// Reason validation failed. Set only when valid=false; UNSPECIFIED
8232    /// when valid=true. The native app uses this to drive UX (silent retry
8233    /// vs. "this link expired" message vs. "this link looks tampered").
8234    #[prost(enumeration="ValidationFailureReason", tag="2")]
8235    pub failure_reason: i32,
8236    /// Decoded payload. Populated only when valid=true. The native app
8237    /// SHOULD compare payload.recipient_user_id against the signed-in user
8238    /// and refuse to render the campaign card on mismatch.
8239    #[prost(message, optional, tag="3")]
8240    pub payload: ::core::option::Option<DeeplinkTokenPayload>,
8241}
8242// ─── Enums ──────────────────────────────────────────────────────────────────
8243
8244/// Reason a deeplink-token validation failed. Empty when valid=true.
8245#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8246#[repr(i32)]
8247pub enum ValidationFailureReason {
8248    Unspecified = 0,
8249    /// Token bytes parsed but the HMAC signature did not verify under any
8250    /// active or overlap-window key version.
8251    InvalidSignature = 1,
8252    /// Token signature verified but its embedded expiry has passed.
8253    Expired = 2,
8254    /// Signature would have verified, but the key version that signed the
8255    /// token is past the rotation overlap window and has been hard-deleted.
8256    /// This means the token is older than the platform's retention bound
8257    /// (rotation cadence + overlap window) — operationally equivalent to
8258    /// EXPIRED but distinguishable for telemetry.
8259    KeyRetired = 3,
8260    /// Token bytes could not be parsed at all (not base64url, wrong length,
8261    /// missing payload separator, etc.). Indicates a tampered or
8262    /// truncated URL.
8263    Malformed = 4,
8264}
8265impl ValidationFailureReason {
8266    /// String value of the enum field names used in the ProtoBuf definition.
8267    ///
8268    /// The values are not transformed in any way and thus are considered stable
8269    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8270    pub fn as_str_name(&self) -> &'static str {
8271        match self {
8272            Self::Unspecified => "VALIDATION_FAILURE_REASON_UNSPECIFIED",
8273            Self::InvalidSignature => "VALIDATION_FAILURE_REASON_INVALID_SIGNATURE",
8274            Self::Expired => "VALIDATION_FAILURE_REASON_EXPIRED",
8275            Self::KeyRetired => "VALIDATION_FAILURE_REASON_KEY_RETIRED",
8276            Self::Malformed => "VALIDATION_FAILURE_REASON_MALFORMED",
8277        }
8278    }
8279    /// Creates an enum from field names used in the ProtoBuf definition.
8280    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8281        match value {
8282            "VALIDATION_FAILURE_REASON_UNSPECIFIED" => Some(Self::Unspecified),
8283            "VALIDATION_FAILURE_REASON_INVALID_SIGNATURE" => Some(Self::InvalidSignature),
8284            "VALIDATION_FAILURE_REASON_EXPIRED" => Some(Self::Expired),
8285            "VALIDATION_FAILURE_REASON_KEY_RETIRED" => Some(Self::KeyRetired),
8286            "VALIDATION_FAILURE_REASON_MALFORMED" => Some(Self::Malformed),
8287            _ => None,
8288        }
8289    }
8290}
8291// ─── Messages ───────────────────────────────────────────────────────────────
8292
8293/// One recorded observation of an indicator over a period.
8294///
8295/// A reading records what was reported and nothing else. Reading it
8296/// together with the response rate of the campaign it followed produces
8297/// an interpretation — for instance that a well-acknowledged message
8298/// nonetheless changed nothing, which says the gap was never one of
8299/// direction. That crossing is analysis and belongs to the diagnosis
8300/// layer; storing it here would make the record and its interpretation
8301/// impossible to tell apart, and would freeze one interpretation into
8302/// data that later analysis cannot revisit.
8303#[derive(Clone, PartialEq, ::prost::Message)]
8304pub struct IndicatorReading {
8305    /// Unique identifier for the reading.
8306    #[prost(string, tag="1")]
8307    pub id: ::prost::alloc::string::String,
8308    /// Indicator this reading was recorded against.
8309    #[prost(string, tag="2")]
8310    pub indicator_id: ::prost::alloc::string::String,
8311    /// Kind of source that produced it.
8312    #[prost(enumeration="ReadingSource", tag="3")]
8313    pub source: i32,
8314    /// What the reading says.
8315    #[prost(enumeration="ReadingOutcome", tag="4")]
8316    pub outcome: i32,
8317    /// Start of the period the reading covers.
8318    #[prost(message, optional, tag="5")]
8319    pub period_start: ::core::option::Option<::prost_types::Timestamp>,
8320    /// End of the period the reading covers.
8321    #[prost(message, optional, tag="6")]
8322    pub period_end: ::core::option::Option<::prost_types::Timestamp>,
8323    /// Verification run that produced it. Set only when `source` is
8324    /// READING_SOURCE_VERIFICATION_CAMPAIGN, and the way to check the
8325    /// reading: the run carries how many verifiers were asked and over
8326    /// what window, never who they were. The identities are deliberately
8327    /// not recorded, because the reading is about a unit and not about its
8328    /// members, and keeping the two apart is what stops a stored answer
8329    /// from becoming one person's judgement of another.
8330    #[prost(string, tag="7")]
8331    pub verification_run_id: ::prost::alloc::string::String,
8332    /// Campaign whose responses produced it. For an in-app reading this is
8333    /// the campaign the audience answered; for a verification reading it
8334    /// is the follow-up that was sent to the verifiers.
8335    #[prost(string, tag="8")]
8336    pub campaign_id: ::prost::alloc::string::String,
8337    /// How many responses fed this reading. For a verification reading the
8338    /// unit of count is the organizational unit that answered, not the
8339    /// person: the question is asked once per unit.
8340    ///
8341    /// Absent for a source that does not count responses at all, such as a
8342    /// figure pushed from another system. Absence and a count of none are
8343    /// different facts and the field carries presence so they stay
8344    /// different.
8345    #[prost(int32, optional, tag="9")]
8346    pub response_count: ::core::option::Option<i32>,
8347    /// How many responses were expected over the same period. Travels with
8348    /// `response_count` so that the reading carries its own denominator
8349    /// and can be judged without a second lookup, and carries presence for
8350    /// the same reason.
8351    #[prost(int32, optional, tag="10")]
8352    pub expected_response_count: ::core::option::Option<i32>,
8353    /// Timestamp when the reading was stored.
8354    #[prost(message, optional, tag="11")]
8355    pub recorded_at: ::core::option::Option<::prost_types::Timestamp>,
8356    /// The measured figure, expressed in the indicator's unit and read
8357    /// together with its direction and target.
8358    ///
8359    /// Present only for a source that produces a number: a figure pushed
8360    /// from one of the organization's own systems, or one entered by hand.
8361    /// A verification-campaign reading never carries one, because the
8362    /// question put to a verifier is whether the behaviour changed and an
8363    /// answer to that has no magnitude — deriving a figure from it would
8364    /// manufacture precision the answer does not contain. Absent for every
8365    /// source that has no number to report, which is not the same as a
8366    /// measurement of zero.
8367    #[prost(double, optional, tag="12")]
8368    pub value: ::core::option::Option<f64>,
8369    /// The number of people in the smallest organizational unit any answer
8370    /// in this reading was about.
8371    ///
8372    /// A reading aggregates several verifiers answering about several
8373    /// units, so it has no single unit size and does not claim one. The
8374    /// smallest is what it carries, because that is the only figure that
8375    /// answers the question a stored reading has to survive: if the size
8376    /// below which a unit may not be asked about is raised to some larger
8377    /// number, which readings already taken fall below it? Without this the
8378    /// question is unanswerable in retrospect and a raised floor can only
8379    /// apply forward.
8380    ///
8381    /// Carries presence. Absent means the size was not knowable — a reading
8382    /// recorded before sizes were kept, or a source with no units behind it
8383    /// at all — and absent MUST NOT be read as a small unit, nor as a large
8384    /// one; it is the absence of the fact.
8385    ///
8386    /// This is a size and deliberately nothing else. The reading records no
8387    /// unit identity, so the figure cannot be attached to any unit, and
8388    /// consumers MUST NOT use it to rank, compare or otherwise set units
8389    /// against one another: comparing organizational units is not something
8390    /// this contract carries, and size without identity is what keeps a
8391    /// later re-reading of the floor possible without reopening it.
8392    /// Consumers MUST NOT present a reading whose smallest unit is below
8393    /// the floor in force as a judgement about that unit.
8394    #[prost(int32, optional, tag="13")]
8395    pub min_unit_size: ::core::option::Option<i32>,
8396}
8397/// A scheduled follow-up that asks whether the behaviour a campaign was
8398/// trying to change actually changed, and lands the answer on an
8399/// indicator.
8400///
8401/// The question is asked about an organizational unit, never about a
8402/// named person. A run therefore never produces a third party's judgement
8403/// of an individual, which is a category of data this contract does not
8404/// carry.
8405#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8406pub struct VerificationRun {
8407    /// Unique identifier for the run.
8408    #[prost(string, tag="1")]
8409    pub id: ::prost::alloc::string::String,
8410    /// Campaign whose effect is being verified.
8411    #[prost(string, tag="2")]
8412    pub campaign_id: ::prost::alloc::string::String,
8413    /// Indicator the answers are recorded against.
8414    #[prost(string, tag="3")]
8415    pub indicator_id: ::prost::alloc::string::String,
8416    /// Objective the indicator hangs from, carried here so a run can be
8417    /// listed and read at the objective level without resolving the
8418    /// indicator first.
8419    #[prost(string, tag="4")]
8420    pub objective_id: ::prost::alloc::string::String,
8421    /// Lifecycle state.
8422    #[prost(enumeration="VerificationRunState", tag="5")]
8423    pub state: i32,
8424    /// The follow-up campaign sent to the verifiers. Empty while the run
8425    /// is VERIFICATION_RUN_STATE_PENDING, because it does not exist yet.
8426    #[prost(string, tag="6")]
8427    pub verification_campaign_id: ::prost::alloc::string::String,
8428    /// When the follow-up is due, derived from the wait declared on the
8429    /// indicator's evidence source. Known from the moment the run is
8430    /// created.
8431    #[prost(message, optional, tag="7")]
8432    pub scheduled_for: ::core::option::Option<::prost_types::Timestamp>,
8433    /// When the follow-up actually went out and collection opened. Unset
8434    /// while the run is pending.
8435    #[prost(message, optional, tag="8")]
8436    pub window_start: ::core::option::Option<::prost_types::Timestamp>,
8437    /// When collection closed. Unset until the run is complete.
8438    #[prost(message, optional, tag="9")]
8439    pub window_end: ::core::option::Option<::prost_types::Timestamp>,
8440    /// How many people the follow-up asks. Verifiers are derived from the
8441    /// audience being measured — each audience member's manager,
8442    /// deduplicated, dropping anyone who is inside that audience — and
8443    /// each verifier's affirmation is recorded as an ordinary per-delivery
8444    /// acknowledgement of the follow-up campaign. No folding of units too
8445    /// small to be asked about on their own into the level above them
8446    /// takes place.
8447    #[prost(int32, tag="10")]
8448    pub verifier_count: i32,
8449    /// Reading this run produced. Empty until the run completes, and
8450    /// empty on a completed run that produced none — a run nobody answered
8451    /// leaves the indicator without evidence rather than with a zero.
8452    #[prost(string, tag="11")]
8453    pub reading_id: ::prost::alloc::string::String,
8454    /// Timestamp when the run was created.
8455    #[prost(message, optional, tag="12")]
8456    pub created_at: ::core::option::Option<::prost_types::Timestamp>,
8457    /// Timestamp when the run was last updated.
8458    #[prost(message, optional, tag="13")]
8459    pub updated_at: ::core::option::Option<::prost_types::Timestamp>,
8460}
8461/// Request to schedule a verification run for a campaign and one of the
8462/// indicators it should move.
8463#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8464pub struct StartVerificationRunRequest {
8465    /// Campaign whose effect is to be verified. Required.
8466    #[prost(string, tag="1")]
8467    pub campaign_id: ::prost::alloc::string::String,
8468    /// Indicator the answers will be recorded against. Required. Its
8469    /// evidence source must be the verification-campaign kind; any other
8470    /// kind returns FAILED_PRECONDITION, because the wait, the verifier
8471    /// derivation and the follow-up template all come from that
8472    /// configuration and have nowhere else to come from.
8473    #[prost(string, tag="2")]
8474    pub indicator_id: ::prost::alloc::string::String,
8475}
8476/// Response after scheduling a verification run.
8477#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8478pub struct StartVerificationRunResponse {
8479    /// The scheduled run. Scheduling a run for a pair that already has one
8480    /// that has not completed is idempotent and returns the existing run.
8481    #[prost(message, optional, tag="1")]
8482    pub run: ::core::option::Option<VerificationRun>,
8483}
8484/// Request to retrieve one verification run.
8485#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8486pub struct GetVerificationRunRequest {
8487    /// ID of the run to retrieve. Required.
8488    #[prost(string, tag="1")]
8489    pub verification_run_id: ::prost::alloc::string::String,
8490}
8491/// Response containing the requested verification run.
8492#[derive(Clone, PartialEq, ::prost::Message)]
8493pub struct GetVerificationRunResponse {
8494    /// The requested run.
8495    #[prost(message, optional, tag="1")]
8496    pub run: ::core::option::Option<VerificationRun>,
8497    /// The reading it produced, when it produced one. Absent while the run
8498    /// is still open and absent on a completed run that collected nothing.
8499    #[prost(message, optional, tag="2")]
8500    pub reading: ::core::option::Option<IndicatorReading>,
8501}
8502/// Request to list verification runs. Exactly one of `objective_id`,
8503/// `indicator_id` and `campaign_id` must be set; sending more than one,
8504/// or none, returns INVALID_ARGUMENT.
8505#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8506pub struct ListVerificationRunsRequest {
8507    /// List the runs recorded against the indicators of this objective.
8508    #[prost(string, optional, tag="1")]
8509    pub objective_id: ::core::option::Option<::prost::alloc::string::String>,
8510    /// List the runs recorded against this indicator.
8511    #[prost(string, optional, tag="2")]
8512    pub indicator_id: ::core::option::Option<::prost::alloc::string::String>,
8513    /// List the runs verifying this campaign.
8514    #[prost(string, optional, tag="3")]
8515    pub campaign_id: ::core::option::Option<::prost::alloc::string::String>,
8516    /// Return only runs in this state. Unspecified returns every state.
8517    #[prost(enumeration="VerificationRunState", tag="4")]
8518    pub state: i32,
8519    /// Pagination parameters.
8520    #[prost(message, optional, tag="5")]
8521    pub pagination: ::core::option::Option<Pagination>,
8522}
8523/// Response containing a page of verification runs.
8524#[derive(Clone, PartialEq, ::prost::Message)]
8525pub struct ListVerificationRunsResponse {
8526    /// Runs in this page, newest first.
8527    #[prost(message, repeated, tag="1")]
8528    pub runs: ::prost::alloc::vec::Vec<VerificationRun>,
8529    /// Pagination metadata for fetching subsequent pages.
8530    #[prost(message, optional, tag="2")]
8531    pub pagination_meta: ::core::option::Option<PaginationMeta>,
8532}
8533/// Request to list the readings recorded against one indicator.
8534#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)]
8535pub struct ListIndicatorReadingsRequest {
8536    /// Indicator whose readings to list. Required.
8537    #[prost(string, tag="1")]
8538    pub indicator_id: ::prost::alloc::string::String,
8539    /// Return only readings from this kind of source. Unspecified returns
8540    /// every kind.
8541    #[prost(enumeration="ReadingSource", tag="2")]
8542    pub source: i32,
8543    /// Pagination parameters.
8544    #[prost(message, optional, tag="3")]
8545    pub pagination: ::core::option::Option<Pagination>,
8546    /// Return only readings whose period ends at or after this instant.
8547    /// Unset leaves the range open at that end.
8548    #[prost(message, optional, tag="4")]
8549    pub period_start_after: ::core::option::Option<::prost_types::Timestamp>,
8550    /// Return only readings whose period starts at or before this instant.
8551    /// Unset leaves the range open at that end.
8552    #[prost(message, optional, tag="5")]
8553    pub period_end_before: ::core::option::Option<::prost_types::Timestamp>,
8554}
8555/// Response containing a page of readings.
8556#[derive(Clone, PartialEq, ::prost::Message)]
8557pub struct ListIndicatorReadingsResponse {
8558    /// Readings in this page, newest period first. An empty page means no
8559    /// reading exists for the filter, which is a statement about evidence
8560    /// and not about the indicator's value.
8561    #[prost(message, repeated, tag="1")]
8562    pub readings: ::prost::alloc::vec::Vec<IndicatorReading>,
8563    /// Pagination metadata for fetching subsequent pages.
8564    #[prost(message, optional, tag="2")]
8565    pub pagination_meta: ::core::option::Option<PaginationMeta>,
8566}
8567// ─── Enums ──────────────────────────────────────────────────────────────────
8568
8569/// Where a reading came from. One value per evidence adapter, so that a
8570/// reading can always be traced back to the kind of source that produced
8571/// it without consulting the indicator's current configuration — an
8572/// indicator's evidence source can be changed after readings exist, and
8573/// past readings keep saying how they were actually obtained.
8574#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8575#[repr(i32)]
8576pub enum ReadingSource {
8577    Unspecified = 0,
8578    /// Produced by responses from the audience of the message itself.
8579    InApp = 1,
8580    /// Produced by a deferred follow-up message asking someone other than
8581    /// the audience whether the behaviour changed.
8582    VerificationCampaign = 2,
8583    /// Pushed by the organization from one of its own systems.
8584    Webhook = 3,
8585    /// Entered by hand or imported from a spreadsheet.
8586    ManualEntry = 4,
8587}
8588impl ReadingSource {
8589    /// String value of the enum field names used in the ProtoBuf definition.
8590    ///
8591    /// The values are not transformed in any way and thus are considered stable
8592    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8593    pub fn as_str_name(&self) -> &'static str {
8594        match self {
8595            Self::Unspecified => "READING_SOURCE_UNSPECIFIED",
8596            Self::InApp => "READING_SOURCE_IN_APP",
8597            Self::VerificationCampaign => "READING_SOURCE_VERIFICATION_CAMPAIGN",
8598            Self::Webhook => "READING_SOURCE_WEBHOOK",
8599            Self::ManualEntry => "READING_SOURCE_MANUAL_ENTRY",
8600        }
8601    }
8602    /// Creates an enum from field names used in the ProtoBuf definition.
8603    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8604        match value {
8605            "READING_SOURCE_UNSPECIFIED" => Some(Self::Unspecified),
8606            "READING_SOURCE_IN_APP" => Some(Self::InApp),
8607            "READING_SOURCE_VERIFICATION_CAMPAIGN" => Some(Self::VerificationCampaign),
8608            "READING_SOURCE_WEBHOOK" => Some(Self::Webhook),
8609            "READING_SOURCE_MANUAL_ENTRY" => Some(Self::ManualEntry),
8610            _ => None,
8611        }
8612    }
8613}
8614/// What a reading says about the indicator it was recorded against.
8615/// Every reading carries one, whatever produced it, so that sources of
8616/// different shapes remain comparable on the only question the indicator
8617/// is there to answer.
8618///
8619/// For a verification-campaign reading this is the whole of it. A
8620/// verifier is asked whether the behaviour changed for a unit, not to
8621/// grade it, so a three-way judgement is all the answer contains and
8622/// anything finer would be invented; those readings therefore carry no
8623/// figure. A source that genuinely measures something — a system of the
8624/// organization's own, or a figure entered by hand — reports the number
8625/// in `value` in addition, and the outcome then says how that number
8626/// reads against the indicator's direction and target.
8627#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8628#[repr(i32)]
8629pub enum ReadingOutcome {
8630    Unspecified = 0,
8631    /// The behaviour the indicator describes was reported as happening.
8632    Positive = 1,
8633    /// The behaviour the indicator describes was reported as not
8634    /// happening. A negative reading is a finding, not a failure to
8635    /// collect.
8636    Negative = 2,
8637    /// Answers were collected but they do not support either reading —
8638    /// too few came back, or they disagreed.
8639    ///
8640    /// Distinct from no reading at all. When nobody answers, no reading is
8641    /// recorded and the indicator simply has no evidence for that period;
8642    /// silence is never stored as an outcome, and never as a zero.
8643    Insufficient = 3,
8644}
8645impl ReadingOutcome {
8646    /// String value of the enum field names used in the ProtoBuf definition.
8647    ///
8648    /// The values are not transformed in any way and thus are considered stable
8649    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8650    pub fn as_str_name(&self) -> &'static str {
8651        match self {
8652            Self::Unspecified => "READING_OUTCOME_UNSPECIFIED",
8653            Self::Positive => "READING_OUTCOME_POSITIVE",
8654            Self::Negative => "READING_OUTCOME_NEGATIVE",
8655            Self::Insufficient => "READING_OUTCOME_INSUFFICIENT",
8656        }
8657    }
8658    /// Creates an enum from field names used in the ProtoBuf definition.
8659    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8660        match value {
8661            "READING_OUTCOME_UNSPECIFIED" => Some(Self::Unspecified),
8662            "READING_OUTCOME_POSITIVE" => Some(Self::Positive),
8663            "READING_OUTCOME_NEGATIVE" => Some(Self::Negative),
8664            "READING_OUTCOME_INSUFFICIENT" => Some(Self::Insufficient),
8665            _ => None,
8666        }
8667    }
8668}
8669/// Lifecycle of a verification run.
8670#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
8671#[repr(i32)]
8672pub enum VerificationRunState {
8673    Unspecified = 0,
8674    /// Scheduled. The wait after the original message has not elapsed and
8675    /// the follow-up has not been sent.
8676    Pending = 1,
8677    /// The follow-up has been sent and answers are being collected.
8678    Collecting = 2,
8679    /// Collection is closed. The run either produced a reading or produced
8680    /// none; both are terminal, and the second is not an error.
8681    Complete = 3,
8682}
8683impl VerificationRunState {
8684    /// String value of the enum field names used in the ProtoBuf definition.
8685    ///
8686    /// The values are not transformed in any way and thus are considered stable
8687    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
8688    pub fn as_str_name(&self) -> &'static str {
8689        match self {
8690            Self::Unspecified => "VERIFICATION_RUN_STATE_UNSPECIFIED",
8691            Self::Pending => "VERIFICATION_RUN_STATE_PENDING",
8692            Self::Collecting => "VERIFICATION_RUN_STATE_COLLECTING",
8693            Self::Complete => "VERIFICATION_RUN_STATE_COMPLETE",
8694        }
8695    }
8696    /// Creates an enum from field names used in the ProtoBuf definition.
8697    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
8698        match value {
8699            "VERIFICATION_RUN_STATE_UNSPECIFIED" => Some(Self::Unspecified),
8700            "VERIFICATION_RUN_STATE_PENDING" => Some(Self::Pending),
8701            "VERIFICATION_RUN_STATE_COLLECTING" => Some(Self::Collecting),
8702            "VERIFICATION_RUN_STATE_COMPLETE" => Some(Self::Complete),
8703            _ => None,
8704        }
8705    }
8706}
8707include!("pidgr.v1.tonic.rs");
8708// @@protoc_insertion_point(module)