Skip to main content

linear_queries/
types.rs

1use crate::scalars::DateTime;
2use crate::scalars::TimelessDate;
3use linear_schema::linear as schema;
4
5#[derive(cynic::QueryFragment, Debug, Clone)]
6#[cynic(schema = "linear")]
7pub struct User {
8    pub id: cynic::Id,
9    pub name: String,
10    #[cynic(rename = "displayName")]
11    pub display_name: String,
12    pub email: String,
13}
14
15#[derive(cynic::QueryFragment, Debug, Clone)]
16#[cynic(schema = "linear")]
17pub struct Team {
18    pub id: cynic::Id,
19    pub key: String,
20    pub name: String,
21}
22
23#[derive(cynic::QueryFragment, Debug, Clone)]
24#[cynic(schema = "linear")]
25pub struct WorkflowState {
26    pub id: cynic::Id,
27    pub name: String,
28    #[cynic(rename = "type")]
29    pub state_type: String,
30}
31
32#[derive(cynic::QueryFragment, Debug, Clone)]
33#[cynic(schema = "linear")]
34pub struct Project {
35    pub id: cynic::Id,
36    pub name: String,
37}
38
39/// Minimal parent issue fragment to avoid recursive Issue expansion.
40#[derive(cynic::QueryFragment, Debug, Clone)]
41#[cynic(schema = "linear", graphql_type = "Issue")]
42pub struct ParentIssue {
43    pub id: cynic::Id,
44    pub identifier: String,
45}
46
47#[derive(cynic::QueryFragment, Debug, Clone)]
48#[cynic(schema = "linear")]
49pub struct Issue {
50    pub id: cynic::Id,
51    pub identifier: String,
52    pub title: String,
53    pub description: Option<String>,
54    pub priority: f64,
55    #[cynic(rename = "priorityLabel")]
56    pub priority_label: String,
57    #[cynic(rename = "labelIds")]
58    pub label_ids: Vec<String>,
59    #[cynic(rename = "dueDate")]
60    pub due_date: Option<TimelessDate>,
61    pub url: String,
62    #[cynic(rename = "createdAt")]
63    pub created_at: DateTime,
64    #[cynic(rename = "updatedAt")]
65    pub updated_at: DateTime,
66
67    // Details-only metadata (still fetched on Issue fragment)
68    pub estimate: Option<f64>,
69    pub parent: Option<ParentIssue>,
70    #[cynic(rename = "startedAt")]
71    pub started_at: Option<DateTime>,
72    #[cynic(rename = "completedAt")]
73    pub completed_at: Option<DateTime>,
74    #[cynic(rename = "canceledAt")]
75    pub canceled_at: Option<DateTime>,
76
77    pub creator: Option<User>,
78    pub team: Team,
79    pub state: Option<WorkflowState>,
80    pub assignee: Option<User>,
81    pub project: Option<Project>,
82}
83
84#[derive(cynic::QueryFragment, Debug, Clone)]
85#[cynic(schema = "linear")]
86pub struct PageInfo {
87    #[cynic(rename = "hasNextPage")]
88    pub has_next_page: bool,
89    #[cynic(rename = "endCursor")]
90    pub end_cursor: Option<String>,
91}
92
93#[derive(cynic::QueryFragment, Debug, Clone)]
94#[cynic(schema = "linear")]
95pub struct IssueConnection {
96    pub nodes: Vec<Issue>,
97    #[cynic(rename = "pageInfo")]
98    pub page_info: PageInfo,
99}
100
101/// IssueSearchResult from searchIssues query - has issue fields directly.
102/// NOTE: Duplicates subset of Issue fields; keep in sync.
103/// Nullability differs (e.g., state is non-null here).
104#[derive(cynic::QueryFragment, Debug, Clone)]
105#[cynic(schema = "linear")]
106pub struct IssueSearchResult {
107    pub id: cynic::Id,
108    pub identifier: String,
109    pub title: String,
110    pub description: Option<String>,
111    pub priority: f64,
112    #[cynic(rename = "priorityLabel")]
113    pub priority_label: String,
114    #[cynic(rename = "labelIds")]
115    pub label_ids: Vec<String>,
116    #[cynic(rename = "dueDate")]
117    pub due_date: Option<TimelessDate>,
118    pub url: String,
119    #[cynic(rename = "createdAt")]
120    pub created_at: DateTime,
121    #[cynic(rename = "updatedAt")]
122    pub updated_at: DateTime,
123    pub creator: Option<User>,
124    pub team: Team,
125    pub state: WorkflowState,
126    pub assignee: Option<User>,
127    pub project: Option<Project>,
128}
129
130#[derive(cynic::QueryFragment, Debug, Clone)]
131#[cynic(schema = "linear")]
132pub struct IssueSearchPayload {
133    pub nodes: Vec<IssueSearchResult>,
134    #[cynic(rename = "pageInfo")]
135    pub page_info: PageInfo,
136}
137
138// ============================================================================
139// Metadata query types
140// ============================================================================
141
142#[derive(cynic::QueryFragment, Debug, Clone)]
143#[cynic(schema = "linear")]
144pub struct IssueLabel {
145    pub id: cynic::Id,
146    pub name: String,
147    pub team: Option<Team>,
148}
149
150#[derive(cynic::QueryFragment, Debug, Clone)]
151#[cynic(schema = "linear")]
152pub struct UserConnection {
153    pub nodes: Vec<User>,
154    #[cynic(rename = "pageInfo")]
155    pub page_info: PageInfo,
156}
157
158#[derive(cynic::QueryFragment, Debug, Clone)]
159#[cynic(schema = "linear")]
160pub struct TeamConnection {
161    pub nodes: Vec<Team>,
162    #[cynic(rename = "pageInfo")]
163    pub page_info: PageInfo,
164}
165
166#[derive(cynic::QueryFragment, Debug, Clone)]
167#[cynic(schema = "linear")]
168pub struct ProjectConnection {
169    pub nodes: Vec<Project>,
170    #[cynic(rename = "pageInfo")]
171    pub page_info: PageInfo,
172}
173
174#[derive(cynic::QueryFragment, Debug, Clone)]
175#[cynic(schema = "linear")]
176pub struct WorkflowStateConnection {
177    pub nodes: Vec<WorkflowState>,
178    #[cynic(rename = "pageInfo")]
179    pub page_info: PageInfo,
180}
181
182#[derive(cynic::QueryFragment, Debug, Clone)]
183#[cynic(schema = "linear")]
184pub struct IssueLabelConnection {
185    pub nodes: Vec<IssueLabel>,
186    #[cynic(rename = "pageInfo")]
187    pub page_info: PageInfo,
188}