Skip to main content

linear_queries/
types.rs

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