Added get agent with id route

This commit is contained in:
Franklin 2023-04-25 08:47:48 -04:00
parent ca01d8d8ab
commit a9d6545322
8 changed files with 178 additions and 113 deletions

View File

@ -7,7 +7,8 @@ SELECT
(SELECT (SELECT u.price_usd FROM unit u WHERE u.project_id = p.id ORDER BY u.price_usd DESC LIMIT 1)) as starts_from,
l.district,
p.finish_date,
p.media as "media: _"
p.media as "media: _",
p.admin_tag
FROM project p, location l
WHERE p.location_id = l.id
-- Filters here:

View File

@ -12,80 +12,6 @@
},
"query": "DELETE FROM agent WHERE id = $1;"
},
"11b388533d1cece58959754172768a0fa4bfd430ad29a3bf0eca81bbbe7ecc22": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "project_state: _",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "project_type: _",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "project_condition: _",
"ordinal": 3,
"type_info": "Varchar"
},
{
"name": "city",
"ordinal": 4,
"type_info": "Varchar"
},
{
"name": "starts_from",
"ordinal": 5,
"type_info": "Float8"
},
{
"name": "district",
"ordinal": 6,
"type_info": "Varchar"
},
{
"name": "finish_date",
"ordinal": 7,
"type_info": "Timestamp"
},
{
"name": "media: _",
"ordinal": 8,
"type_info": "Text"
}
],
"nullable": [
false,
false,
false,
false,
false,
null,
false,
false,
false
],
"parameters": {
"Left": [
"Text",
"Text",
"Text",
"Text",
"Text",
"Int2",
"Int8"
]
}
},
"query": "SELECT \n p.id,\n p.project_state as \"project_state: _\",\n p.project_type as \"project_type: _\",\n p.project_condition as \"project_condition: _\",\n l.city,\n (SELECT (SELECT u.price_usd FROM unit u WHERE u.project_id = p.id ORDER BY u.price_usd DESC LIMIT 1)) as starts_from,\n l.district,\n p.finish_date,\n p.media as \"media: _\"\nFROM project p, location l\nWHERE p.location_id = l.id\n-- Filters here:\nAND (LOWER(l.city) LIKE '%' || LOWER($1) || '%' OR $1 IS null) -- City Filter\nAND (LOWER(l.district) LIKE '%' || LOWER($2) || '%' OR $2 IS null) -- District Filter\nAND (p.project_type = $3 OR $3 IS null) -- ProjectType\nAND (p.project_condition = $4 OR $4 IS null) -- ProjectCondition\nAND (p.project_state = $5 OR $5 IS null) -- ProjectState\nAND ((SELECT COUNT(*) FROM unit u WHERE u.project_id = p.id AND u.rooms = $6) > 0 OR $6 IS NULL)\n-- End of filters\nORDER BY p.time_created DESC\nLIMIT 50 OFFSET $7;"
},
"19a20556f5e3621438cd583aae4984c8cf510f359f65ec599f8a6b46d9153ec4": {
"describe": {
"columns": [
@ -620,6 +546,86 @@
},
"query": "INSERT INTO agent (\n id, shortcode, full_name, credential, credential_type, profile_picture_url, time_created, last_updated\n) VALUES (\n $1, $2, $3, $4, $5, $6, $7, $7\n) RETURNING\nid,\nshortcode,\nfull_name,\ncredential,\ncredential_type as \"credential_type: _\",\nprofile_picture_url,\ntime_created,\nlast_updated;"
},
"919dc414e70785bed4b999412b2ce5c46cb07e4aefb6a8c74bde23fcca9a4759": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "project_state: _",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "project_type: _",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "project_condition: _",
"ordinal": 3,
"type_info": "Varchar"
},
{
"name": "city",
"ordinal": 4,
"type_info": "Varchar"
},
{
"name": "starts_from",
"ordinal": 5,
"type_info": "Float8"
},
{
"name": "district",
"ordinal": 6,
"type_info": "Varchar"
},
{
"name": "finish_date",
"ordinal": 7,
"type_info": "Timestamp"
},
{
"name": "media: _",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "admin_tag",
"ordinal": 9,
"type_info": "Varchar"
}
],
"nullable": [
false,
false,
false,
false,
false,
null,
false,
false,
false,
true
],
"parameters": {
"Left": [
"Text",
"Text",
"Text",
"Text",
"Text",
"Int2",
"Int8"
]
}
},
"query": "SELECT \n p.id,\n p.project_state as \"project_state: _\",\n p.project_type as \"project_type: _\",\n p.project_condition as \"project_condition: _\",\n l.city,\n (SELECT (SELECT u.price_usd FROM unit u WHERE u.project_id = p.id ORDER BY u.price_usd DESC LIMIT 1)) as starts_from,\n l.district,\n p.finish_date,\n p.media as \"media: _\",\n p.admin_tag\nFROM project p, location l\nWHERE p.location_id = l.id\n-- Filters here:\nAND (LOWER(l.city) LIKE '%' || LOWER($1) || '%' OR $1 IS null) -- City Filter\nAND (LOWER(l.district) LIKE '%' || LOWER($2) || '%' OR $2 IS null) -- District Filter\nAND (p.project_type = $3 OR $3 IS null) -- ProjectType\nAND (p.project_condition = $4 OR $4 IS null) -- ProjectCondition\nAND (p.project_state = $5 OR $5 IS null) -- ProjectState\nAND ((SELECT COUNT(*) FROM unit u WHERE u.project_id = p.id AND u.rooms = $6) > 0 OR $6 IS NULL)\n-- End of filters\nORDER BY p.time_created DESC\nLIMIT 50 OFFSET $7;"
},
"924abcf88270de74ab6524fbd4247b2c23ab96b4569c8b81ff6b0e1d7dacada7": {
"describe": {
"columns": [

View File

@ -12,19 +12,19 @@ use jl_types::{
unit::Unit,
},
dto::{
item::Item,
payloads::{
agent::{NewAgentPayload, UpdateAgentPayload},
location::NewLocationPayload,
project::{NewProjectPayload, UpdateProjectPayload},
unit::{NewUnitPayload, UpdateUnitPayload},
},
item::Item,
}
},
};
use sqlx::PgPool;
use uuid::Uuid;
use crate::{services};
use crate::services;
#[post("/agent")]
pub async fn create_new_agent_profile(
@ -129,7 +129,11 @@ pub async fn get_all_contacts(db_conn: web::Data<Arc<PgPool>>) -> TypedHttpRespo
services::admin::get_all_contacts(&db_conn).await
}
#[post("images/{item}/{id}")]
pub async fn upload_image(aws_client: web::Data<Arc<aws_sdk_s3::Client>>, path_vars: Path<(Item, Uuid)>, multipart: Multipart) -> TypedHttpResponse<String> {
services::admin::upload_image(&aws_client, path_vars.0.clone(), path_vars.1, multipart).await
#[post("images/{item}")]
pub async fn upload_image(
aws_client: web::Data<Arc<aws_sdk_s3::Client>>,
path_vars: Path<Item>,
multipart: Multipart,
) -> TypedHttpResponse<String> {
services::admin::upload_image(&aws_client, path_vars.clone(), multipart).await
}

View File

@ -1,7 +1,10 @@
use std::sync::Arc;
use actix_cors::Cors;
use actix_web::{web::{self}, App, HttpServer};
use actix_web::{
web::{self},
App, HttpServer,
};
use chrono::Utc;
use reqwest::Client;
use sqlx::PgPool;
@ -38,7 +41,7 @@ pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(
.service(super::admin::get_all_contacts)
.service(super::admin::get_contacts_count)
.service(super::admin::get_visits_count)
.service(super::admin::upload_image)
.service(super::admin::upload_image),
)
.service(
web::scope("/read")
@ -48,7 +51,9 @@ pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(
.service(super::read::get_projects_paged)
.service(super::read::get_project_data)
.service(super::read::create_contact_request)
.service(super::read::get_agent_with_shortcode),
.service(super::read::get_agent_with_shortcode)
.service(super::read::get_location_with_city_and_district)
.service(super::read::get_agent_with_id),
)
})
.bind((HOST_ADDR, HOST_PORT))?

View File

@ -12,7 +12,10 @@ use actix_web::{
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use err::MessageResource;
use jl_types::{
domain::{agent::Agent, project_condition::ProjectCondition, project_type::ProjectType},
domain::{
agent::Agent, location::Location, project_condition::ProjectCondition,
project_type::ProjectType,
},
dto::{
filters::Filter, listing::Listing, payloads::contact::ContactPayload,
project_card::ProjectCardDto,
@ -28,6 +31,11 @@ pub async fn get_all_agents(db_conn: web::Data<Arc<PgPool>>) -> TypedHttpRespons
services::read::get_all_agents(&db_conn).await
}
#[get("/agent/{id}")]
pub async fn get_agent_with_id(db_conn: web::Data<Arc<PgPool>>, id: Path<Uuid>) -> TypedHttpResponse<Agent> {
services::read::get_agent_with_id(&db_conn, &id).await
}
#[get("/agent/{shortcode}")]
pub async fn get_agent_with_shortcode(
db_conn: web::Data<Arc<PgPool>>,
@ -50,7 +58,13 @@ pub async fn get_locations_in_city(
) -> TypedHttpResponse<HashSet<String>> {
services::read::get_all_locations_in_city(&db_conn, &city).await
}
#[get("/location/{city}/{district}")]
pub async fn get_location_with_city_and_district(
db_conn: web::Data<Arc<PgPool>>,
path_vars: Path<(String, String)>,
) -> TypedHttpResponse<Location> {
services::read::get_location_with_city_and_district(&db_conn, &path_vars.0, &path_vars.1).await
}
#[get("/projects/{page}")]
pub async fn get_projects_paged(
request: HttpRequest,

View File

@ -1,28 +1,30 @@
use actix_multipart::Multipart;
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use err::MessageResource;
use futures::StreamExt as _;
use jl_types::{
domain::{
agent::Agent, contact::Contact, count::Count, location::Location, project::Project,
unit::Unit,
},
dto::{
item::Item,
payloads::{
agent::{NewAgentPayload, UpdateAgentPayload},
location::NewLocationPayload,
project::{NewProjectPayload, UpdateProjectPayload},
unit::{NewUnitPayload, UpdateUnitPayload},
},
item::Item,
}
},
};
use futures::StreamExt as _;
use sqlx::PgPool;
use uuid::Uuid;
use crate::{dao, handle_db_read_op, handle_db_write_op, handle_tx, success, unwrap_or_not_found, utils::s3::{self}};
use crate::{
dao, handle_db_read_op, handle_db_write_op, handle_tx, success, unwrap_or_not_found,
utils::s3::{self},
};
//
// Insert Methods
@ -203,20 +205,29 @@ pub async fn get_contact_count(conn: &PgPool) -> TypedHttpResponse<Count> {
success!(count)
}
pub async fn upload_image(client: &aws_sdk_s3::Client, item: Item, id: Uuid, mut multipart: Multipart) -> TypedHttpResponse<String> {
pub async fn upload_image(
client: &aws_sdk_s3::Client,
item: Item,
mut multipart: Multipart,
) -> TypedHttpResponse<String> {
let mut bytes: Vec<u8> = Vec::new();
match multipart.next().await {
Some(item) => {
let mut field = match item {
Ok(field) => field,
Err(error) => return TypedHttpResponse::return_standard_error(400, MessageResource::new_from_string(error.to_string())),
Err(error) => {
return TypedHttpResponse::return_standard_error(
400,
MessageResource::new_from_string(error.to_string()),
)
}
};
// Field in turn is stream of *Bytes* object
while let Some(chunk) = field.next().await {
bytes.append(&mut chunk.unwrap().to_vec());
}
},
}
None => {
return TypedHttpResponse::return_empty_response(400);
}
@ -226,8 +237,13 @@ pub async fn upload_image(client: &aws_sdk_s3::Client, item: Item, id: Uuid, mut
return TypedHttpResponse::return_empty_response(400);
}
match s3::upload_image(client, id, item, Uuid::new_v4().to_string(), bytes).await {
match s3::upload_image(client, item, Uuid::new_v4().to_string(), bytes).await {
Ok(url) => success!(url),
Err(error) => return TypedHttpResponse::return_standard_error(400, MessageResource::new_from_string(error.to_string())),
Err(error) => {
return TypedHttpResponse::return_standard_error(
400,
MessageResource::new_from_string(error.to_string()),
)
}
};
}

View File

@ -2,7 +2,7 @@ use std::collections::HashSet;
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use jl_types::{
domain::agent::Agent,
domain::{agent::Agent, location::Location},
dto::{
filters::Filter, listing::Listing, payloads::contact::ContactPayload,
project_card::ProjectCardDto,
@ -27,6 +27,16 @@ pub async fn get_agent_with_shortcode(
))
}
pub async fn get_agent_with_id(
conn: &PgPool,
id: &Uuid,
) -> TypedHttpResponse<Agent> {
success!(unwrap_or_not_found!(
handle_db_read_op!(dao::agent::get_agent_with_id(conn, id)),
"agents"
))
}
pub async fn get_all_locations(conn: &PgPool) -> TypedHttpResponse<HashSet<String>> {
let locations: HashSet<String> = handle_db_read_op!(dao::location::fetch_all_locations(conn))
.into_iter()
@ -47,7 +57,18 @@ pub async fn get_all_locations_in_city(
.collect()
)
}
pub async fn get_location_with_city_and_district(
conn: &PgPool,
city: &String,
district: &String,
) -> TypedHttpResponse<Location> {
success!(unwrap_or_not_found!(
handle_db_read_op!(dao::location::get_locations_in_city(conn, city))
.into_iter()
.find(|loc| &loc.district == district),
"locations"
))
}
pub async fn get_projects_paged(
conn: &PgPool,
page: &i64,

View File

@ -1,11 +1,7 @@
use jl_types::dto::item::Item;
use aws_sdk_s3::{
error::SdkError,
operation::put_object::{PutObjectError},
primitives::ByteStream,
Client,
error::SdkError, operation::put_object::PutObjectError, primitives::ByteStream, Client,
};
use uuid::Uuid;
use jl_types::dto::item::Item;
pub async fn init_aws_client() -> Client {
dotenv::dotenv().expect("Failed loading env");
@ -15,12 +11,11 @@ pub async fn init_aws_client() -> Client {
pub async fn upload_image(
client: &Client,
id: Uuid,
item: Item,
file_name: String,
multipart: Vec<u8>,
) -> Result<String, SdkError<PutObjectError>> {
let path = format!("jl-images/{item}/{id}/{file_name}");
let path = format!("jl-images/{item}/{file_name}");
match client
.put_object()
.bucket("jorge-ledesma-bucket")
@ -28,8 +23,11 @@ pub async fn upload_image(
.body(ByteStream::from(multipart))
.acl(aws_sdk_s3::types::ObjectCannedAcl::PublicRead)
.send()
.await {
Ok(_) => Ok(format!("https://jorge-ledesma-bucket.s3.us-east-2.amazonaws.com/{path}")),
Err(error) => Err(error),
}
.await
{
Ok(_) => Ok(format!(
"https://jorge-ledesma-bucket.s3.us-east-2.amazonaws.com/{path}"
)),
Err(error) => Err(error),
}
}