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)