Skip to content

Commit

Permalink
backend, frontend: revamp utoipa/ts types
Browse files Browse the repository at this point in the history
  • Loading branch information
ElysaSrc committed Sep 14, 2024
1 parent b11b32f commit 351df4c
Show file tree
Hide file tree
Showing 21 changed files with 402 additions and 235 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

2 changes: 1 addition & 1 deletion backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jsonwebtoken = "9"
tracing = "0.1"
tower-http = { version = "0.5", features = ["fs", "trace", "cors"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
utoipa = { version = "4.2.0", features = ["axum_extras", "uuid", "chrono"] }
utoipa = { version = "4", features = ["axum_extras", "uuid", "chrono"] }
clap = { version = "4", features = ["derive"] }
clap_derive = { version = "4" }
number_range = "0.3.2"
Expand Down
6 changes: 4 additions & 2 deletions backend/src/api/admin/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ pub struct AdminEntityWithRelations {
pub display_name: String,
pub category_id: Uuid,
pub family_id: Uuid,
#[schema(value_type = Object)]

#[schema(value_type = Vec<UnprocessedLocation>)]
pub locations: sqlx::types::Json<Vec<UnprocessedLocation>>,

pub data: Value,
pub tags: Vec<Uuid>,
pub hidden: bool,
Expand All @@ -64,7 +66,7 @@ pub struct AdminEntityWithRelations {
("page_size" = i64, Query, description = "Number of items per page (default: 20)")
),
responses(
(status = 200, description = "Search results for entities", body = PaginatedVec<AdminCachedEntity>),
(status = 200, description = "Search results for entities", body = AdminCachedEntitiesWithPagination),
(status = 401, description = "Invalid permissions", body = ErrorResponse),
)
)]
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/admin/statistics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub async fn admin_home_stats(
get,
path = "/api/admin/stats/count-comments-entities",
responses(
(status = 200, description = "Dicts of entities and comments counts by family and category id"),
(status = 200, description = "Dicts of entities and comments counts by family and category id", body = (HashMap<String, (u32, u32, u32, u32)>,HashMap<String, (u32, u32, u32, u32)>),),
(status = 401, description = "Invalid permissions", body = ErrorResponse),
)
)]
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ impl Display for SearchRequest {
path = "/api/map/search",
request_body = SearchRequest,
responses(
(status = 200, description = "List of entities", body = PaginatedVec<ViewerSearchedCachedEntity>),
(status = 200, description = "List of entities", body = ViewerCachedEntitiesWithPagination),
(status = 401, description = "Invalid token", body = ErrorResponse),
)
)]
Expand Down
6 changes: 2 additions & 4 deletions backend/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use crate::{
},
entity_cache::{
AdminCachedEntitiesWithPagination, AdminCachedEntity, Cluster, EntitiesAndClusters,
LocationRepresentation, PaginatedVec, ParentRepresentation,
ViewerCachedEntitiesWithPagination, ViewerCachedEntity, ViewerSearchedCachedEntity,
LocationRepresentation, ParentRepresentation, ViewerCachedEntitiesWithPagination,
ViewerCachedEntity, ViewerSearchedCachedEntity,
},
family::{Family, Field, FieldType, Form, NewOrUpdateFamily},
options::{
Expand Down Expand Up @@ -161,8 +161,6 @@ use utoipa::OpenApi;
PublicEntity,
PublicListedEntity,
PublicNewEntity,
PaginatedVec<ViewerSearchedCachedEntity>,
PaginatedVec<AdminCachedEntity>,
ViewerCachedEntity,
ViewerSearchedCachedEntity,
LocationRepresentation,
Expand Down
136 changes: 78 additions & 58 deletions backend/src/models/access_token.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use std::collections::{BTreeMap, HashMap};

use crate::{api::AppError, helpers::postgis_polygons::MultiPolygon};
use serde::{Deserialize, Serialize};
use serde_json::{to_value, Value};
use sqlx::{types::Json, PgConnection};
use serde_json::{json, to_value};
use sqlx::{
types::{Json, JsonValue},
PgConnection,
};
use utoipa::ToSchema;
use uuid::Uuid;

Expand Down Expand Up @@ -55,7 +60,7 @@ pub struct PermissionPolicy {
pub struct NewOrUpdateAccessToken {
pub title: String,
pub token: String,
#[schema(value_type = Object)]
#[schema(value_type = Permissions)]
pub permissions: Json<Permissions>,
pub active: bool,
}
Expand All @@ -65,19 +70,16 @@ pub struct AccessToken {
pub id: Uuid,
pub title: String,
pub token: String,
#[schema(value_type = Object)]
#[schema(value_type = Permissions)]
pub permissions: Json<Permissions>,
pub last_week_visits: i64,
pub active: bool,
}

#[derive(Deserialize, Serialize, ToSchema, Debug)]
pub struct AccessTokenStats {
#[schema(value_type = Object)]
pub origins: Json<Value>,

#[schema(value_type = Object)]
pub visits_30_days: Json<Value>,
pub origins: HashMap<String, u32>,
pub visits_30_days: BTreeMap<String, u32>,
}

impl AccessToken {
Expand Down Expand Up @@ -249,54 +251,72 @@ impl AccessToken {
access_token_id: Uuid,
conn: &mut PgConnection,
) -> Result<AccessTokenStats, AppError> {
sqlx::query_as!(
AccessTokenStats,
r#"
SELECT
COALESCE((
WITH origins AS (
SELECT DISTINCT(COALESCE(referrer, 'unknown')) AS referrer, COUNT(*) AS total
FROM access_tokens_visits
WHERE token_id = $1
GROUP BY referrer
)
SELECT json_object_agg(referrer, total) FROM origins
), '{}') as "origins!",
(
WITH date_series AS (
SELECT generate_series(
NOW()::date - INTERVAL '30 days',
NOW()::date,
INTERVAL '1 day'
)::date AS visit_date
),
aggregated_visits AS (
SELECT
ds.visit_date,
COALESCE(COUNT(atv.visited_at), 0) AS visit_count
FROM
date_series ds
LEFT JOIN
access_tokens_visits atv
ON
ds.visit_date = DATE(atv.visited_at)
AND atv.token_id = $1
GROUP BY
ds.visit_date
ORDER BY
ds.visit_date
)
SELECT COALESCE(json_object_agg(
TO_CHAR(visit_date, 'YYYY-MM-DD'),
visit_count
), '{}') AS visits
FROM aggregated_visits
) as "visits_30_days!";
"#,
access_token_id
)
.fetch_one(conn)
.await
.map_err(AppError::Database)
let result = sqlx::query!(
r#"
SELECT
COALESCE((
WITH origins AS (
SELECT DISTINCT(COALESCE(referrer, 'unknown')) AS referrer, COUNT(*) AS total
FROM access_tokens_visits
WHERE token_id = $1
GROUP BY referrer
)
SELECT json_object_agg(referrer, total) FROM origins
), '{}') as "origins: JsonValue",
(
WITH date_series AS (
SELECT generate_series(
NOW()::date - INTERVAL '30 days',
NOW()::date,
INTERVAL '1 day'
)::date AS visit_date
),
aggregated_visits AS (
SELECT
ds.visit_date,
COALESCE(COUNT(atv.visited_at), 0) AS visit_count
FROM
date_series ds
LEFT JOIN
access_tokens_visits atv
ON
ds.visit_date = DATE(atv.visited_at)
AND atv.token_id = $1
GROUP BY
ds.visit_date
ORDER BY
ds.visit_date
)
SELECT COALESCE(json_object_agg(
TO_CHAR(visit_date, 'YYYY-MM-DD'),
visit_count
), '{}') AS visits
FROM aggregated_visits
) as "visits_30_days: JsonValue"
"#,
access_token_id
)
.fetch_one(conn)
.await
.map_err(AppError::Database)?;

// Provide a default empty object if origins is None
let origins_json: JsonValue = result.origins.unwrap_or_else(|| json!({}));
let visits_30_days_json: JsonValue = result.visits_30_days.unwrap_or_else(|| json!({}));

// Convert the JsonValue to HashMap<String, u32>
let origins: HashMap<String, u32> =
serde_json::from_value(origins_json).map_err(|err| {
AppError::Internal(format!("Failed to deserialize origins: {}", err).into())
})?;
let visits_30_days: BTreeMap<String, u32> = serde_json::from_value(visits_30_days_json)
.map_err(|err| {
AppError::Internal(format!("Failed to deserialize visits_30_days: {}", err).into())
})?;

Ok(AccessTokenStats {
origins,
visits_30_days,
})
}
}
10 changes: 5 additions & 5 deletions backend/src/models/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ pub struct PublicEntity {
pub display_name: String,
pub category_id: Uuid,
pub family_id: Uuid,
#[schema(value_type = Object)]
#[schema(value_type = Vec<UnprocessedLocation>)]
pub locations: Json<Vec<UnprocessedLocation>>,
pub data: Value,
pub tags: Vec<Uuid>,
#[schema(value_type = Object)]
#[schema(value_type = Form)]
pub entity_form: Json<Form>,
#[schema(value_type = Object)]
#[schema(value_type = Form)]
pub comment_form: Json<Form>,
pub created_at: chrono::NaiveDateTime,
pub updated_at: chrono::NaiveDateTime,
Expand Down Expand Up @@ -196,7 +196,7 @@ impl PublicEntity {
pub struct AdminNewOrUpdateEntity {
pub display_name: String,
pub category_id: Uuid,
#[schema(value_type = Object)]
#[schema(value_type = Vec<UnprocessedLocation>)]
pub locations: Json<Vec<UnprocessedLocation>>,
pub data: Value,
pub tags: Vec<Uuid>,
Expand Down Expand Up @@ -224,7 +224,7 @@ pub struct AdminEntity {
pub display_name: String,
pub category_id: Uuid,
pub family_id: Uuid,
#[schema(value_type = Object)]
#[schema(value_type = Vec<UnprocessedLocation>)]
pub locations: Json<Vec<UnprocessedLocation>>,
pub data: Value,
pub tags: Vec<Uuid>,
Expand Down
10 changes: 5 additions & 5 deletions backend/src/models/entity_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,19 @@ impl From<Vec<AdminPaginatedCachedEntity>> for AdminCachedEntitiesWithPagination
}
}

#[derive(Deserialize, Serialize, ToSchema, Debug)]
#[derive(Serialize, ToSchema, Debug)]
#[aliases(
ViewerCachedEntitiesWithPagination = PaginatedVec<ViewerSearchedCachedEntity>,
AdminCachedEntitiesWithPagination = PaginatedVec<AdminCachedEntity>
)]
pub struct PaginatedVec<T> {
#[schema(value_type = Object)]
pub entities: Vec<T>,

pub total_results: i64,
pub total_pages: i64,
pub response_current_page: i64,
}

pub type ViewerCachedEntitiesWithPagination = PaginatedVec<ViewerSearchedCachedEntity>;
pub type AdminCachedEntitiesWithPagination = PaginatedVec<AdminCachedEntity>;

#[derive(Deserialize, Serialize, ToSchema, Debug)]
pub struct CachedClusteredEntity {
pub id: Uuid,
Expand Down
6 changes: 3 additions & 3 deletions backend/src/models/family.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub struct Field {
/// only for the frontend. For instance, if the field is an enum
/// use it to store possible values. If it is a SingleLineText, specify
/// if it's an email, a phone number, etc...
#[schema(value_type = Object)]
#[schema(value_type = Value, additional_properties)]
pub field_type_metadata: Option<Value>,

/// Sets if the field is indexed (used in full text search, or constraints search)
Expand Down Expand Up @@ -80,9 +80,9 @@ pub struct Family {
pub id: Uuid,
pub title: String,
pub icon_hash: Option<String>,
#[schema(value_type = Object)]
#[schema(value_type = Form)]
pub entity_form: Json<Form>,
#[schema(value_type = Object)]
#[schema(value_type = Form)]
pub comment_form: Json<Form>,
pub sort_order: i32,
pub version: i32,
Expand Down
Loading

0 comments on commit 351df4c

Please sign in to comment.