Refactor Toggl API types
Significant renaming and data type changes to Toggl API types occurred to improve identification and consistency. For example, 'Current' is renamed to 'TimeEntry', 'ProjectClient' is renamed to 'Client', and 'TogglQuery' is renamed to 'TogglReportQuery'. Changes affected multiple sections of the codebase, including routes and DB access.
This commit is contained in:
parent
9cfe56b3ce
commit
90457155aa
@ -1,5 +1,5 @@
|
|||||||
use crate::entity::{client, project, time_entry};
|
use crate::entity::{client, project, time_entry};
|
||||||
use crate::toggl_api::types::{Project, ProjectClient, ReportRow};
|
use crate::toggl_api::types::{Project, Client, ReportRow};
|
||||||
use sea_orm::sea_query::OnConflict;
|
use sea_orm::sea_query::OnConflict;
|
||||||
use sea_orm::{NotSet, Set};
|
use sea_orm::{NotSet, Set};
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ impl ReportRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectClient {
|
impl Client {
|
||||||
pub fn as_model(&self) -> client::ActiveModel {
|
pub fn as_model(&self) -> client::ActiveModel {
|
||||||
client::ActiveModel {
|
client::ActiveModel {
|
||||||
id: Set(self.id),
|
id: Set(self.id),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::toggl_api::TogglApiClient;
|
use crate::toggl_api::TogglApiClient;
|
||||||
use crate::entity::{client, project};
|
use crate::entity::{client, project};
|
||||||
use crate::toggl_api::types::{Project, ProjectClient, TogglQuery};
|
use crate::toggl_api::types::{Project, Client, TogglReportQuery};
|
||||||
use sea_orm::{DatabaseConnection, EntityTrait, QuerySelect};
|
use sea_orm::{DatabaseConnection, EntityTrait, QuerySelect};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
@ -42,7 +42,7 @@ pub async fn perform_poll(
|
|||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
let report = client
|
let report = client
|
||||||
.full_report(&TogglQuery {
|
.full_report(&TogglReportQuery {
|
||||||
start_date: Some(today_string.clone()),
|
start_date: Some(today_string.clone()),
|
||||||
end_date: Some(today_string.clone()),
|
end_date: Some(today_string.clone()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -64,8 +64,8 @@ pub async fn perform_poll(
|
|||||||
if new_projects {
|
if new_projects {
|
||||||
let clients = client.fetch_clients().await?;
|
let clients = client.fetch_clients().await?;
|
||||||
|
|
||||||
client::Entity::insert_many(clients.iter().map(ProjectClient::as_model))
|
client::Entity::insert_many(clients.iter().map(Client::as_model))
|
||||||
.on_conflict(ProjectClient::grafting_conflict_statement())
|
.on_conflict(Client::grafting_conflict_statement())
|
||||||
.exec(db)
|
.exec(db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use chrono::{NaiveDate};
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use crate::entity::time_entry::{Entity as TimeEntry};
|
use crate::entity::time_entry::{Entity as TimeEntry};
|
||||||
use crate::toggl_api::TogglApiClient;
|
use crate::toggl_api::TogglApiClient;
|
||||||
use crate::toggl_api::types::{Current, Project, ProjectClient, ReportRow, TogglQuery};
|
use crate::toggl_api::types::{self, Project, Client, ReportRow, TogglReportQuery};
|
||||||
use crate::{entity, utils};
|
use crate::{entity, utils};
|
||||||
use crate::entity::time_entry;
|
use crate::entity::time_entry;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ use crate::entity::time_entry;
|
|||||||
pub async fn report(
|
pub async fn report(
|
||||||
Extension(toggl_client): Extension<TogglApiClient>,
|
Extension(toggl_client): Extension<TogglApiClient>,
|
||||||
Extension(db): Extension<DatabaseConnection>,
|
Extension(db): Extension<DatabaseConnection>,
|
||||||
Json(query): Json<TogglQuery>,
|
Json(query): Json<TogglReportQuery>,
|
||||||
) -> utils::Result<Json<Vec<ReportRow>>> {
|
) -> utils::Result<Json<Vec<ReportRow>>> {
|
||||||
let report = toggl_client.full_report(&query).await?;
|
let report = toggl_client.full_report(&query).await?;
|
||||||
debug!("Returned results: {:?}", report);
|
debug!("Returned results: {:?}", report);
|
||||||
@ -73,7 +73,7 @@ pub async fn cache_report(
|
|||||||
#[instrument(skip(toggl_client))]
|
#[instrument(skip(toggl_client))]
|
||||||
pub async fn current(
|
pub async fn current(
|
||||||
Extension(toggl_client): Extension<TogglApiClient>,
|
Extension(toggl_client): Extension<TogglApiClient>,
|
||||||
) -> utils::Result<Json<Option<Current>>> {
|
) -> utils::Result<Json<Option<types::TimeEntry>>> {
|
||||||
Ok(toggl_client.fetch_current_time_entry().await.map(Json)?)
|
Ok(toggl_client.fetch_current_time_entry().await.map(Json)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,10 +106,10 @@ pub async fn projects(
|
|||||||
pub async fn clients(
|
pub async fn clients(
|
||||||
Extension(db): Extension<DatabaseConnection>,
|
Extension(db): Extension<DatabaseConnection>,
|
||||||
Extension(toggl_client): Extension<TogglApiClient>,
|
Extension(toggl_client): Extension<TogglApiClient>,
|
||||||
) -> utils::Result<Json<Vec<ProjectClient>>> {
|
) -> utils::Result<Json<Vec<Client>>> {
|
||||||
let clients = toggl_client.fetch_clients().await?;
|
let clients = toggl_client.fetch_clients().await?;
|
||||||
entity::client::Entity::insert_many(clients.iter().map(ProjectClient::as_model))
|
entity::client::Entity::insert_many(clients.iter().map(Client::as_model))
|
||||||
.on_conflict(ProjectClient::grafting_conflict_statement())
|
.on_conflict(Client::grafting_conflict_statement())
|
||||||
.exec(&db)
|
.exec(&db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ pub async fn refresh(
|
|||||||
let start_date_query_string = start_date.unwrap_or(end_date_query_string.clone());
|
let start_date_query_string = start_date.unwrap_or(end_date_query_string.clone());
|
||||||
let start_date = NaiveDate::parse_from_str(&start_date_query_string, "%Y-%m-%d")?;
|
let start_date = NaiveDate::parse_from_str(&start_date_query_string, "%Y-%m-%d")?;
|
||||||
|
|
||||||
let query = TogglQuery {
|
let query = TogglReportQuery {
|
||||||
start_date: Some(start_date_query_string),
|
start_date: Some(start_date_query_string),
|
||||||
end_date: Some(end_date_query_string),
|
end_date: Some(end_date_query_string),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use hyper::HeaderMap;
|
|||||||
use reqwest::header::HeaderValue;
|
use reqwest::header::HeaderValue;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
use tracing::log::debug;
|
use tracing::log::debug;
|
||||||
use crate::toggl_api::types::{Current, Project, ProjectClient, ReportRow, TogglQuery};
|
use crate::toggl_api::types::{TimeEntry, Project, Client as ProjectClient, ReportRow, TogglReportQuery};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TogglApiClient {
|
pub struct TogglApiClient {
|
||||||
@ -100,7 +100,7 @@ impl TogglApiClient {
|
|||||||
Ok(clients)
|
Ok(clients)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_current_time_entry(&self) -> crate::Result<Option<Current>> {
|
pub async fn fetch_current_time_entry(&self) -> crate::Result<Option<TimeEntry>> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{base_url}/me/time_entries/current",
|
"{base_url}/me/time_entries/current",
|
||||||
base_url = self.base_url
|
base_url = self.base_url
|
||||||
@ -110,14 +110,14 @@ impl TogglApiClient {
|
|||||||
.client
|
.client
|
||||||
.get(url))
|
.get(url))
|
||||||
.await?
|
.await?
|
||||||
.json::<Option<Current>>()
|
.json::<Option<TimeEntry>>()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paginate_filters(original_filters: &TogglQuery, last_row_id: u64) -> TogglQuery {
|
fn paginate_filters(original_filters: &TogglReportQuery, last_row_id: u64) -> TogglReportQuery {
|
||||||
let mut filters: TogglQuery = original_filters.clone();
|
let mut filters: TogglReportQuery = original_filters.clone();
|
||||||
filters.first_row_number = Some(last_row_id + 1);
|
filters.first_row_number = Some(last_row_id + 1);
|
||||||
filters
|
filters
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ impl TogglApiClient {
|
|||||||
#[instrument(skip(self, filters))]
|
#[instrument(skip(self, filters))]
|
||||||
pub async fn full_report(
|
pub async fn full_report(
|
||||||
&self,
|
&self,
|
||||||
filters: &TogglQuery,
|
filters: &TogglReportQuery,
|
||||||
) -> anyhow::Result<Vec<ReportRow>> {
|
) -> anyhow::Result<Vec<ReportRow>> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{base_url}/workspace/{workspace_id}/search/time_entries",
|
"{base_url}/workspace/{workspace_id}/search/time_entries",
|
||||||
|
|||||||
@ -30,19 +30,28 @@ pub struct ReportRowInnerTimeEntry {
|
|||||||
pub at: String,
|
pub at: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Current {
|
pub struct TimeEntry {
|
||||||
pub id: u64,
|
pub id: i64,
|
||||||
pub workspace_id: u64,
|
pub workspace_id: i64,
|
||||||
pub project_id: Option<u64>,
|
pub project_id: Option<i64>,
|
||||||
pub task_id: Option<u64>,
|
pub task_id: Option<Value>,
|
||||||
pub billable: bool,
|
pub billable: bool,
|
||||||
pub start: String,
|
pub start: String,
|
||||||
pub stop: Option<String>,
|
pub stop: Option<String>,
|
||||||
pub duration: i64,
|
pub duration: i64,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub tags: Vec<String>,
|
pub tags: Vec<String>,
|
||||||
pub tag_ids: Vec<u64>,
|
pub tag_ids: Vec<i64>,
|
||||||
|
pub at: String,
|
||||||
|
pub server_deleted_at: Option<String>,
|
||||||
|
pub user_id: i64,
|
||||||
|
|
||||||
|
// Ignored fields
|
||||||
|
// duronly: bool,
|
||||||
|
// uid: i64,
|
||||||
|
// wid: i64,
|
||||||
|
// pid: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@ -59,7 +68,7 @@ pub struct Project {
|
|||||||
|
|
||||||
/// Represents a client in Toggl.
|
/// Represents a client in Toggl.
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct ProjectClient {
|
pub struct Client {
|
||||||
/// Indicates whether the client is archived or not.
|
/// Indicates whether the client is archived or not.
|
||||||
pub archived: bool,
|
pub archived: bool,
|
||||||
|
|
||||||
@ -81,7 +90,7 @@ pub struct ProjectClient {
|
|||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Serialize, Deserialize, Clone, Default)]
|
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||||
pub struct TogglQuery {
|
pub struct TogglReportQuery {
|
||||||
pub billable: Option<bool>,
|
pub billable: Option<bool>,
|
||||||
pub client_ids: Option<Vec<u64>>,
|
pub client_ids: Option<Vec<u64>>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
@ -115,7 +124,7 @@ pub struct TogglQuery {
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
impl fmt::Debug for TogglQuery {
|
impl fmt::Debug for TogglReportQuery {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut ds = f.debug_struct("TogglQuery");
|
let mut ds = f.debug_struct("TogglQuery");
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user