1use serde::{Deserialize, Serialize};
4
5use crate::schema::{IsoDateTime, NonEmptyString, RunxSchema};
6
7#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
8pub enum HandoffSignalSchema {
9 #[serde(rename = "runx.handoff_signal.v1")]
10 V1,
11}
12
13#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
14#[serde(rename_all = "snake_case")]
15pub enum HandoffSignalSource {
16 PullRequestComment,
17 PullRequestReview,
18 PullRequestState,
19 IssueComment,
20 DiscussionReply,
21 EmailReply,
22 DirectMessageReply,
23 ManualNote,
24 SystemEvent,
25}
26
27#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
28#[serde(rename_all = "snake_case")]
29pub enum HandoffDisposition {
30 Acknowledged,
31 Interested,
32 RequestedChanges,
33 Accepted,
34 ApprovedToSend,
35 Merged,
36 Declined,
37 RequestedNoContact,
38 Rerouted,
39}
40
41#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
43#[serde(deny_unknown_fields)]
44pub struct HandoffSignalActor {
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub actor_id: Option<NonEmptyString>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub display_name: Option<String>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub role: Option<NonEmptyString>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub provider_identity: Option<NonEmptyString>,
53}
54
55#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
58#[serde(deny_unknown_fields)]
59pub struct HandoffSignalSourceRef {
60 #[serde(rename = "type")]
61 pub ref_type: NonEmptyString,
62 pub uri: NonEmptyString,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub label: Option<String>,
65 #[serde(skip_serializing_if = "Option::is_none")]
66 pub recorded_at: Option<IsoDateTime>,
67}
68
69#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, RunxSchema)]
70#[serde(deny_unknown_fields)]
71#[runx_schema(id = "runx.handoff_signal.v1")]
72pub struct HandoffSignal {
73 pub schema: HandoffSignalSchema,
74 pub signal_id: NonEmptyString,
75 pub handoff_id: NonEmptyString,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub boundary_kind: Option<NonEmptyString>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub target_repo: Option<NonEmptyString>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub target_locator: Option<NonEmptyString>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub contact_locator: Option<NonEmptyString>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub thread_locator: Option<NonEmptyString>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub outbox_entry_id: Option<NonEmptyString>,
88 pub source: HandoffSignalSource,
89 pub disposition: HandoffDisposition,
90 pub recorded_at: IsoDateTime,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub actor: Option<HandoffSignalActor>,
93 #[serde(skip_serializing_if = "Option::is_none")]
94 pub notes: Option<String>,
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub labels: Option<Vec<NonEmptyString>>,
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub source_ref: Option<HandoffSignalSourceRef>,
99 #[serde(skip_serializing_if = "Option::is_none")]
100 pub metadata: Option<crate::JsonObject>,
101}
102
103#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
104pub enum HandoffStateSchema {
105 #[serde(rename = "runx.handoff_state.v1")]
106 V1,
107}
108
109#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
110#[serde(rename_all = "snake_case")]
111pub enum HandoffStatus {
112 AwaitingResponse,
113 Engaged,
114 NeedsRevision,
115 Accepted,
116 ApprovedToSend,
117 Completed,
118 Declined,
119 Rerouted,
120 Suppressed,
121}
122
123#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
124#[serde(rename_all = "snake_case")]
125pub enum SuppressionReason {
126 RequestedNoContact,
127 RemoveRequest,
128 OperatorBlock,
129 LegalRequest,
130}
131
132#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, RunxSchema)]
133#[serde(deny_unknown_fields)]
134#[runx_schema(id = "runx.handoff_state.v1")]
135pub struct HandoffState {
136 pub schema: HandoffStateSchema,
137 pub handoff_id: NonEmptyString,
138 #[serde(skip_serializing_if = "Option::is_none")]
139 pub boundary_kind: Option<NonEmptyString>,
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub target_repo: Option<NonEmptyString>,
142 #[serde(skip_serializing_if = "Option::is_none")]
143 pub target_locator: Option<NonEmptyString>,
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub contact_locator: Option<NonEmptyString>,
146 pub status: HandoffStatus,
147 pub signal_count: u64,
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub last_signal_id: Option<NonEmptyString>,
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub last_signal_at: Option<IsoDateTime>,
152 #[serde(skip_serializing_if = "Option::is_none")]
153 pub last_signal_disposition: Option<HandoffDisposition>,
154 #[serde(skip_serializing_if = "Option::is_none")]
155 pub suppression_record_id: Option<NonEmptyString>,
156 #[serde(skip_serializing_if = "Option::is_none")]
157 pub suppression_reason: Option<SuppressionReason>,
158 #[serde(skip_serializing_if = "Option::is_none")]
159 pub summary: Option<String>,
160}