Skip to main content

comindly_api/
records.rs

1//! The ledger and conventions (`/api/v1/ledger`, `/remember`, `/review`, `/erase`,
2//! `/conventions`), and the queries of the read commands' answers (`/api/v1/answer/*`).
3
4use std::collections::BTreeMap;
5
6use serde::{Deserialize, Serialize};
7
8pub use crate::conventions::{Convention, Manual};
9pub use crate::ledger::Entry;
10pub use crate::preflight::Change;
11
12/// `GET /api/v1/conventions?repo=`.
13#[derive(Debug, Clone, Default, Serialize, Deserialize)]
14pub struct RepoQuery {
15    #[serde(default, skip_serializing_if = "Option::is_none")]
16    pub repo: Option<String>,
17}
18
19/// The conventions in effect, and the measured ones a person hid.
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct Conventions {
22    pub conventions: Vec<ShownConvention>,
23    pub hidden: Vec<Manual>,
24    /// Per repository, its commit page on GitHub or GitLab without the commit (append it).
25    pub commit_urls: BTreeMap<String, String>,
26}
27
28/// A convention with the handle edits use.
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct ShownConvention {
31    #[serde(flatten)]
32    pub convention: Convention,
33    pub id: String,
34    /// `Always`, `Usually`, `Often` or `Sometimes`; none for the team's own.
35    pub strength: Option<String>,
36    /// What it was measured from, e.g. `Followed by 412 of the 530 functions with parameters.`
37    pub evidence: Option<String>,
38    /// Too few instances to call it settled.
39    pub few: bool,
40}
41
42/// `POST /api/v1/conventions`: `add`, `edit`, `hide` or `restore`.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct ConventionChange {
45    pub action: String,
46    #[serde(default, skip_serializing_if = "String::is_empty")]
47    pub id: String,
48    #[serde(default, skip_serializing_if = "Option::is_none")]
49    pub repo: Option<String>,
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub dimension: Option<String>,
52    #[serde(default, skip_serializing_if = "String::is_empty")]
53    pub rule: String,
54}
55
56/// `POST /api/v1/review`: `confirm`, `archive`, `invalidate`, … a record by id or id prefix.
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct ReviewRequest {
59    pub id: String,
60    pub action: String,
61    #[serde(default)]
62    pub reason: String,
63}
64
65/// `POST /api/v1/remember`: a record written by a person.
66#[derive(Debug, Clone, Serialize, Deserialize)]
67pub struct RememberRequest {
68    pub kind: String,
69    /// Symbols the record is about: ids, names or `Class.method`.
70    pub on: Vec<String>,
71    pub title: String,
72    #[serde(default)]
73    pub body: String,
74    #[serde(default)]
75    pub trigger: Option<String>,
76    #[serde(default)]
77    pub evidence: Vec<String>,
78    #[serde(default)]
79    pub fields: BTreeMap<String, String>,
80    /// Code that shaped the record, stored with the indexed commit.
81    #[serde(default)]
82    pub snippets: Vec<crate::ledger::Snippet>,
83}
84
85/// The new record's id.
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct Remembered {
88    pub ok: bool,
89    pub id: String,
90}
91
92/// `answer/find` and `answer/search`: `repos` is a comma-separated list.
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct AnswerQuery {
95    pub q: String,
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub repos: Option<String>,
98    /// Only repositories of these teams: comma-separated names, `none` for unlabelled ones.
99    #[serde(default, skip_serializing_if = "Option::is_none")]
100    pub teams: Option<String>,
101}
102
103/// `answer/why`, `answer/flow` and `answer/explore`.
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct AnswerFocus {
106    pub focus: String,
107}
108
109/// `answer/hook`: `event` is `session-start` or `pre-edit`; `seen` the record ids shown already, comma-separated.
110#[derive(Debug, Clone, Default, Serialize, Deserialize)]
111pub struct HookQuery {
112    pub event: String,
113    pub cwd: String,
114    #[serde(default, skip_serializing_if = "Option::is_none")]
115    pub path: Option<String>,
116    #[serde(default, skip_serializing_if = "Option::is_none")]
117    pub seen: Option<String>,
118}
119
120/// `answer/ledger`.
121#[derive(Debug, Clone, Default, Serialize, Deserialize)]
122pub struct LedgerQuery {
123    #[serde(default)]
124    pub inbox: bool,
125    #[serde(default)]
126    pub check: bool,
127}
128
129/// `answer/contracts`.
130#[derive(Debug, Clone, Default, Serialize, Deserialize)]
131pub struct ContractsQuery {
132    #[serde(default, skip_serializing_if = "Option::is_none")]
133    pub kind: Option<String>,
134    #[serde(default)]
135    pub dangling: bool,
136}
137
138/// `answer/stats`: `repos` is a comma-separated list.
139#[derive(Debug, Clone, Default, Serialize, Deserialize)]
140pub struct StatsQuery {
141    #[serde(default, skip_serializing_if = "Option::is_none")]
142    pub repos: Option<String>,
143}
144
145/// `answer/packages`.
146#[derive(Debug, Clone, Default, Serialize, Deserialize)]
147pub struct PackagesQuery {
148    #[serde(default)]
149    pub skew: bool,
150}
151
152/// `POST answer/preflight`: the changed lines, read from git by the caller.
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct PreflightRequest {
155    pub changes: Vec<Change>,
156}