admin creation functions

This commit is contained in:
Franklin 2023-03-10 06:03:27 -04:00
parent 1e3c395f92
commit f92b077f56
18 changed files with 882 additions and 41 deletions

2
.env
View File

@ -1,2 +1,2 @@
DATABASE_URL="postgres://root:NMWrHZcu9QCu6wlmRUeEw1vXUYq7JhQYSPICTnl5yN9Pu5NIHUOcaj2noV9ejhFgfk5AfKIM2e9x97rbGCwbgTpVa3Fe8nfHgrYLZ2B36sOININQG60T2vIsQX3gkE6U@backend.blancoinfante.com:9102/postgres" DATABASE_URL="postgres://root:NMWrHZcu9QCu6wlmRUeEw1vXUYq7JhQYSPICTnl5yN9Pu5NIHUOcaj2noV9ejhFgfk5AfKIM2e9x97rbGCwbgTpVa3Fe8nfHgrYLZ2B36sOININQG60T2vIsQX3gkE6U@backend.blancoinfante.com:9102/postgres"
SQLX_OFFLINE=FALSE SQLX_OFFLINE=TRUE

6
Cargo.lock generated
View File

@ -680,6 +680,9 @@ name = "either"
version = "1.8.1" version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "encoding_rs" name = "encoding_rs"
@ -1788,9 +1791,12 @@ dependencies = [
"dotenvy", "dotenvy",
"either", "either",
"heck", "heck",
"hex",
"once_cell", "once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"serde",
"serde_json",
"sha2", "sha2",
"sqlx-core", "sqlx-core",
"sqlx-rt", "sqlx-rt",

View File

@ -14,7 +14,7 @@ chrono = "0.4.23"
chrono-tz = "0.8" chrono-tz = "0.8"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.88" serde_json = "1.0.88"
sqlx = { version = "0.6.0", features = [ "runtime-tokio-rustls", "postgres", "chrono", "uuid" ] } sqlx = { version = "0.6.0", features = [ "runtime-tokio-rustls", "postgres", "chrono", "uuid", "offline" ] }
dotenv = { version = "0.15.0" } dotenv = { version = "0.15.0" }
actix-web = {version = "4.1.0"} actix-web = {version = "4.1.0"}
actix-cors = "0.6.2" actix-cors = "0.6.2"

View File

@ -3,9 +3,6 @@ by Franklin Blanco
### Todo's ### Todo's
- [x] Add properties - [x] Dao's made
- [x] Add agents - [ ] Admin functions in service
- [ ] Fetch them both - [ ] Admin functions in routes
- [ ] Delete, update
- [ ] Admin panel functions
- [ ] Pictures?

View File

@ -1,7 +1,7 @@
CREATE TABLE IF NOT EXISTS "contact_info" ( CREATE TABLE IF NOT EXISTS "contact_info" (
agent_id UUID PRIMARY KEY, agent_id UUID PRIMARY KEY,
phone_number VARCHAR NOT NULL, phone_number VARCHAR NOT NULL,
email VARCHAR NOT NULL, email VARCHAR,
profile_picture_url TEXT, profile_picture_url TEXT,
default_message TEXT default_message TEXT
); );

680
sqlx-data.json Normal file
View File

@ -0,0 +1,680 @@
{
"db": "PostgreSQL",
"044ecd955f880a5d7e3185b6dc5217c01cb88100d2e94dea5323ee0a10a45fc0": {
"describe": {
"columns": [
{
"name": "agent_id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "phone_number",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "email",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "profile_picture_url",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "default_message",
"ordinal": 4,
"type_info": "Text"
}
],
"nullable": [
false,
false,
true,
true,
true
],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Varchar",
"Text",
"Text"
]
}
},
"query": "INSERT INTO contact_info (\n agent_id, phone_number, email, profile_picture_url, default_message\n) VALUES (\n $1, $2, $3, $4, $5\n) RETURNING *"
},
"1338558f1d37cc1542fd505c891158f8ab5e8f3792dbb44a534d64ff05ffa62e": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "country",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "province",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "city",
"ordinal": 3,
"type_info": "Varchar"
},
{
"name": "district",
"ordinal": 4,
"type_info": "Varchar"
},
{
"name": "google_maps_url",
"ordinal": 5,
"type_info": "Text"
}
],
"nullable": [
false,
false,
false,
false,
true,
true
],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Varchar",
"Varchar",
"Varchar",
"Text"
]
}
},
"query": "INSERT INTO location (\n id, country, province, city, district, google_maps_url\n) VALUES (\n $1, $2, $3, $4, $5, $6\n) RETURNING *"
},
"22cbe3af73d11e22b94e5b35b53004aae874b1a6286774a5569598ff8eb36ebc": {
"describe": {
"columns": [
{
"name": "agent_id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "phone_number",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "email",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "profile_picture_url",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "default_message",
"ordinal": 4,
"type_info": "Text"
}
],
"nullable": [
false,
false,
true,
true,
true
],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Text",
"Text"
]
}
},
"query": "UPDATE contact_info SET \n phone_number = $1,\n email = $2,\n profile_picture_url = $3,\n default_message = $4\nRETURNING *"
},
"2a7d2d72bb220e7c948cf7939e88524f5c29f68405a38e66be759493581b67f6": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "title",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "description",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "agent_id",
"ordinal": 3,
"type_info": "Uuid"
},
{
"name": "state: _",
"ordinal": 4,
"type_info": "Bytea"
},
{
"name": "time_created",
"ordinal": 5,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 6,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Varchar",
"Uuid",
"Bytea",
"Timestamptz"
]
}
},
"query": "INSERT INTO property (\n id,\n title,\n description,\n agent_id,\n state,\n time_created,\n last_updated\n) VALUES (\n $1,\n $2,\n $3,\n $4,\n $5,\n $6,\n $6\n) RETURNING\nid,\ntitle,\ndescription,\nagent_id,\nstate as \"state: _\",\ntime_created,\nlast_updated;"
},
"403be6e4c7b32698eb9dd9c43f9c13f7f03dc95671f1c81a5391df05c51a92fc": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "title",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "description",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "agent_id",
"ordinal": 3,
"type_info": "Uuid"
},
{
"name": "state: _",
"ordinal": 4,
"type_info": "Bytea"
},
{
"name": "time_created",
"ordinal": 5,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 6,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Varchar",
"Varchar",
"Uuid",
"Bytea",
"Timestamptz"
]
}
},
"query": "UPDATE property SET\n title = $1,\n description = $2,\n agent_id = $3,\n state = $4,\n last_updated = $5\nRETURNING\n id,\n title,\n description,\n agent_id,\n state as \"state: _\",\n time_created,\n last_updated;"
},
"428b88c19683cb7862ad8c9ef22a52a793f1dc303e11a7aebc6d2719357147bf": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "full_name",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "time_created",
"ordinal": 2,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 3,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false
],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Timestamptz"
]
}
},
"query": "INSERT INTO agent (\n id, full_name, time_created, last_updated\n) VALUES (\n $1, $2, $3, $3\n) RETURNING *"
},
"75508bc7b114d6f9915cadf9708c376d2ca1a6dcdd6bff24b1a717cba0ec2fca": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "title",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "description",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "agent_id",
"ordinal": 3,
"type_info": "Uuid"
},
{
"name": "state: _",
"ordinal": 4,
"type_info": "Bytea"
},
{
"name": "time_created",
"ordinal": 5,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 6,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"UuidArray"
]
}
},
"query": "SELECT \nid,\ntitle,\ndescription,\nagent_id,\nstate as \"state: _\",\ntime_created,\nlast_updated\nFROM property where id = ANY($1);"
},
"a05953d6326a1fa6da0444234846b6ee761c8c38c69145b84a2f8d321d879289": {
"describe": {
"columns": [
{
"name": "property_id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "meters",
"ordinal": 1,
"type_info": "Float4"
},
{
"name": "listing_type: _",
"ordinal": 2,
"type_info": "Bytea"
},
{
"name": "photo_urls: _",
"ordinal": 3,
"type_info": "Bytea"
},
{
"name": "location_id",
"ordinal": 4,
"type_info": "Uuid"
}
],
"nullable": [
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Uuid",
"Float4",
"Bytea",
"Bytea",
"Uuid"
]
}
},
"query": "INSERT INTO property_details (\n property_id,\n meters,\n listing_type,\n photo_urls,\n location_id\n) VALUES (\n $1,\n $2,\n $3,\n $4,\n $5\n) RETURNING\nproperty_id,\nmeters,\nlisting_type as \"listing_type: _\",\nphoto_urls as \"photo_urls: _\",\nlocation_id;"
},
"ad03e2715180d060696b5c01717a70c64e635e4521ee958fc027b6a95568a8f0": {
"describe": {
"columns": [
{
"name": "property_id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "meters",
"ordinal": 1,
"type_info": "Float4"
},
{
"name": "listing_type: _",
"ordinal": 2,
"type_info": "Bytea"
},
{
"name": "photo_urls: _",
"ordinal": 3,
"type_info": "Bytea"
},
{
"name": "location_id",
"ordinal": 4,
"type_info": "Uuid"
}
],
"nullable": [
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"UuidArray"
]
}
},
"query": "SELECT \nproperty_id,\nmeters,\nlisting_type as \"listing_type: _\",\nphoto_urls as \"photo_urls: _\",\nlocation_id\nFROM property_details where property_id = ANY($1);"
},
"ad2a4218c9f1bfdf669734ee14a797c4f66d9095fe1bfbba4c8d47b16bfb4f2c": {
"describe": {
"columns": [
{
"name": "property_id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "meters",
"ordinal": 1,
"type_info": "Float4"
},
{
"name": "listing_type: _",
"ordinal": 2,
"type_info": "Bytea"
},
{
"name": "photo_urls: _",
"ordinal": 3,
"type_info": "Bytea"
},
{
"name": "location_id",
"ordinal": 4,
"type_info": "Uuid"
}
],
"nullable": [
false,
false,
false,
false,
false
],
"parameters": {
"Left": [
"Float4",
"Bytea",
"Bytea",
"Uuid"
]
}
},
"query": "UPDATE property_details SET\n meters = $1,\n listing_type = $2,\n photo_urls = $3,\n location_id = $4\nRETURNING\n property_id,\n meters,\n listing_type as \"listing_type: _\",\n photo_urls as \"photo_urls: _\",\n location_id"
},
"b45175d105229ca747253412acd6769726bfce4a511d75fd71238a7835b54669": {
"describe": {
"columns": [
{
"name": "agent_id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "phone_number",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "email",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "profile_picture_url",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "default_message",
"ordinal": 4,
"type_info": "Text"
}
],
"nullable": [
false,
false,
true,
true,
true
],
"parameters": {
"Left": [
"UuidArray"
]
}
},
"query": "SELECT * FROM contact_info where agent_id = ANY($1);"
},
"ccda00295a22931d00484841a95cb74c9541bc8d1c7f63069b6a069b8b6e942a": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "full_name",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "time_created",
"ordinal": 2,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 3,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false
],
"parameters": {
"Left": [
"UuidArray"
]
}
},
"query": "SELECT * FROM agent WHERE id = ANY($1);"
},
"d556cb1971f386a7997c2e3dbce191cde2d488c55c05edbfe3746208a782d5f6": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "country",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "province",
"ordinal": 2,
"type_info": "Varchar"
},
{
"name": "city",
"ordinal": 3,
"type_info": "Varchar"
},
{
"name": "district",
"ordinal": 4,
"type_info": "Varchar"
},
{
"name": "google_maps_url",
"ordinal": 5,
"type_info": "Text"
}
],
"nullable": [
false,
false,
false,
false,
true,
true
],
"parameters": {
"Left": [
"Uuid"
]
}
},
"query": "SELECT * FROM location WHERE id = $1;"
},
"f129da55e85f8ab1fbae9ec9553203b0e5083022003a35a370edc313b23b8007": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Uuid"
},
{
"name": "full_name",
"ordinal": 1,
"type_info": "Varchar"
},
{
"name": "time_created",
"ordinal": 2,
"type_info": "Timestamptz"
},
{
"name": "last_updated",
"ordinal": 3,
"type_info": "Timestamptz"
}
],
"nullable": [
false,
false,
false,
false
],
"parameters": {
"Left": [
"Varchar",
"Timestamptz"
]
}
},
"query": "UPDATE agent set \nfull_name = $1,\nlast_updated = $2\nRETURNING *"
}
}

View File

@ -1,9 +1,9 @@
use remax_types::domain::agent::Agent; use remax_types::domain::agent::Agent;
use sqlx::PgPool; use sqlx::{PgPool, Postgres, Transaction};
use uuid::Uuid; use uuid::Uuid;
pub async fn insert_agent( pub async fn insert_agent(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
agent: &Agent, agent: &Agent,
) -> Result<Agent, sqlx::error::Error> { ) -> Result<Agent, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(
@ -16,7 +16,7 @@ pub async fn insert_agent(
.fetch_one(conn) .fetch_one(conn)
.await .await
} }
pub async fn get_properties_with_ids( pub async fn get_agents_with_ids(
conn: &PgPool, conn: &PgPool,
ids: &Vec<Uuid>, ids: &Vec<Uuid>,
) -> Result<Vec<Agent>, sqlx::error::Error> { ) -> Result<Vec<Agent>, sqlx::error::Error> {
@ -26,7 +26,7 @@ pub async fn get_properties_with_ids(
} }
pub async fn update_agent( pub async fn update_agent(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
agent: &Agent, agent: &Agent,
) -> Result<Agent, sqlx::error::Error> { ) -> Result<Agent, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(

View File

@ -1,9 +1,9 @@
use remax_types::domain::contact_info::ContactInformation; use remax_types::domain::contact_info::ContactInformation;
use sqlx::PgPool; use sqlx::{PgPool, Postgres, Transaction};
use uuid::Uuid; use uuid::Uuid;
pub async fn insert_contact_info( pub async fn insert_contact_info(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
contact_info: &ContactInformation, contact_info: &ContactInformation,
) -> Result<ContactInformation, sqlx::error::Error> { ) -> Result<ContactInformation, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(
@ -22,13 +22,17 @@ pub async fn get_properties_with_ids(
conn: &PgPool, conn: &PgPool,
ids: &Vec<Uuid>, ids: &Vec<Uuid>,
) -> Result<Vec<ContactInformation>, sqlx::error::Error> { ) -> Result<Vec<ContactInformation>, sqlx::error::Error> {
sqlx::query_file_as!(ContactInformation, "sql/contact_info/fetch_with_ids.sql", ids) sqlx::query_file_as!(
.fetch_all(conn) ContactInformation,
.await "sql/contact_info/fetch_with_ids.sql",
ids
)
.fetch_all(conn)
.await
} }
pub async fn update_contact_info( pub async fn update_contact_info(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
contact_info: &ContactInformation, contact_info: &ContactInformation,
) -> Result<ContactInformation, sqlx::error::Error> { ) -> Result<ContactInformation, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(

View File

@ -1,9 +1,9 @@
use remax_types::domain::location::Location; use remax_types::domain::location::Location;
use sqlx::PgPool; use sqlx::{PgPool, Postgres, Transaction};
use uuid::Uuid; use uuid::Uuid;
pub async fn insert_location( pub async fn insert_location(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
location: &Location, location: &Location,
) -> Result<Location, sqlx::error::Error> { ) -> Result<Location, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(
@ -22,8 +22,8 @@ pub async fn insert_location(
pub async fn get_location_with_id( pub async fn get_location_with_id(
conn: &PgPool, conn: &PgPool,
id: &Uuid, id: &Uuid,
) -> Result<Vec<Location>, sqlx::error::Error> { ) -> Result<Option<Location>, sqlx::error::Error> {
sqlx::query_file_as!(Location, "sql/location/get.sql", id) sqlx::query_file_as!(Location, "sql/location/get.sql", id)
.fetch_all(conn) .fetch_optional(conn)
.await .await
} }

View File

@ -1,6 +1,6 @@
pub mod agent; pub mod agent;
pub mod contact_info;
pub mod location;
pub mod main_dao; pub mod main_dao;
pub mod property; pub mod property;
pub mod location; pub mod property_details;
pub mod contact_info;
pub mod property_details;

View File

@ -1,9 +1,9 @@
use remax_types::domain::property::Property; use remax_types::domain::property::Property;
use sqlx::PgPool; use sqlx::{PgPool, Postgres, Transaction};
use uuid::Uuid; use uuid::Uuid;
pub async fn insert_property( pub async fn insert_property(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
property: &Property, property: &Property,
) -> Result<Property, sqlx::error::Error> { ) -> Result<Property, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(
@ -29,7 +29,7 @@ pub async fn get_properties_with_ids(
} }
pub async fn update_property( pub async fn update_property(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
property: &Property, property: &Property,
) -> Result<Property, sqlx::error::Error> { ) -> Result<Property, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(

View File

@ -1,9 +1,9 @@
use remax_types::domain::property_details::PropertyDetails; use remax_types::domain::property_details::PropertyDetails;
use sqlx::PgPool; use sqlx::{PgPool, Postgres, Transaction};
use uuid::Uuid; use uuid::Uuid;
pub async fn insert_property_details( pub async fn insert_property_details(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
property_details: &PropertyDetails, property_details: &PropertyDetails,
) -> Result<PropertyDetails, sqlx::error::Error> { ) -> Result<PropertyDetails, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(
@ -22,13 +22,17 @@ pub async fn get_properties_with_ids(
conn: &PgPool, conn: &PgPool,
ids: &Vec<Uuid>, ids: &Vec<Uuid>,
) -> Result<Vec<PropertyDetails>, sqlx::error::Error> { ) -> Result<Vec<PropertyDetails>, sqlx::error::Error> {
sqlx::query_file_as!(PropertyDetails, "sql/property_details/fetch_with_ids.sql", ids) sqlx::query_file_as!(
.fetch_all(conn) PropertyDetails,
.await "sql/property_details/fetch_with_ids.sql",
ids
)
.fetch_all(conn)
.await
} }
pub async fn update_property_details( pub async fn update_property_details(
conn: &PgPool, conn: &mut Transaction<'_, Postgres>,
property_details: &PropertyDetails, property_details: &PropertyDetails,
) -> Result<PropertyDetails, sqlx::error::Error> { ) -> Result<PropertyDetails, sqlx::error::Error> {
sqlx::query_file_as!( sqlx::query_file_as!(

View File

@ -1,10 +1,12 @@
pub mod dao; pub mod dao;
pub mod routes; pub mod routes;
pub mod service;
pub mod utils;
use std::sync::Arc; use std::sync::Arc;
use chrono::Utc; use chrono::Utc;
use dao::{main_dao}; use dao::main_dao;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {

View File

@ -10,15 +10,14 @@ pub const HOST_ADDR: &str = "0.0.0.0";
pub const HOST_PORT: u16 = 8095; pub const HOST_PORT: u16 = 8095;
pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(), std::io::Error> { pub async fn start_all_routes(start_time: i64, db_conn: Arc<PgPool>) -> Result<(), std::io::Error> {
let client_state = web::Data::new(Arc::new(Client::new())); let client_state = web::Data::new(Arc::new(Client::new()));
// Start server code that turns into a future to be executed below // Start server code that turns into a future to be executed below
let server_future = HttpServer::new(move || { let server_future = HttpServer::new(move || {
let cors_policy = Cors::permissive(); let cors_policy = Cors::permissive();
App::new() App::new()
.wrap(cors_policy) .wrap(cors_policy)
.app_data(client_state.clone()) .app_data(client_state.clone())
.app_data(db_conn.clone()) .app_data(db_conn.clone())
//.service(web::scope("/league").service(SERVICE_HERE)) //.service(web::scope("/league").service(SERVICE_HERE))
}) })
.bind((HOST_ADDR, HOST_PORT))? .bind((HOST_ADDR, HOST_PORT))?

92
src/service/admin.rs Normal file
View File

@ -0,0 +1,92 @@
use actix_web_utils::extensions::typed_response::TypedHttpResponse;
use remax_types::{
domain::location::Location,
dto::{
agent::AgentContainer,
payload::{
agent::{AgentWithContactInfo, NewAgentPayload},
location::NewLocationPayload,
property::{NewPropertyPayload, PropertyWithDetails},
},
property::PropertyContainer,
},
};
use sqlx::PgPool;
use crate::{dao, handle_db_read_op, handle_db_write_op, handle_tx, success, unwrap_or_not_found};
/// Needs to create a Property, a Property Details
/// Create or reference an existing Location
/// and an Agent
/// Needs to be given all the property details, agent details, location details
pub async fn create_new_property(
conn: &PgPool,
new_property_payload: NewPropertyPayload,
) -> TypedHttpResponse<PropertyContainer> {
let agent_ids = &vec![new_property_payload.agent_id];
let mut tx = handle_tx!(conn.begin());
let persisted_agents = handle_db_read_op!(dao::agent::get_agents_with_ids(conn, agent_ids));
let _ = unwrap_or_not_found!(persisted_agents.first(), "agents");
let persisted_location = unwrap_or_not_found!(
handle_db_read_op!(dao::location::get_location_with_id(
conn,
&new_property_payload.location_id
)),
"locations"
);
let property_with_details: PropertyWithDetails = new_property_payload.into();
let persisted_property = handle_db_write_op!(
dao::property::insert_property(&mut tx, &property_with_details.property),
tx
);
let persisted_property_details = handle_db_write_op!(
dao::property_details::insert_property_details(&mut tx, &property_with_details.details),
tx
);
handle_tx!(tx.commit());
success!(PropertyContainer {
property: persisted_property,
details: persisted_property_details,
location: persisted_location,
})
}
pub async fn create_new_agent_profile(
conn: &PgPool,
new_agent_payload: NewAgentPayload,
) -> TypedHttpResponse<AgentContainer> {
let agent_with_contact_info: AgentWithContactInfo = new_agent_payload.into();
let mut tx = handle_tx!(conn.begin());
let persisted_agent = handle_db_write_op!(
dao::agent::insert_agent(&mut tx, &agent_with_contact_info.agent),
tx
);
let persisted_contact_info = handle_db_write_op!(
dao::contact_info::insert_contact_info(&mut tx, &agent_with_contact_info.contact_info),
tx
);
handle_tx!(tx.commit());
success!(AgentContainer {
agent: persisted_agent,
contact: persisted_contact_info,
})
}
pub async fn create_new_location(
conn: &PgPool,
new_location_payload: NewLocationPayload,
) -> TypedHttpResponse<Location> {
let location: Location = new_location_payload.into();
let mut tx = handle_tx!(conn.begin());
let persisted_location =
handle_db_write_op!(dao::location::insert_location(&mut tx, &location), tx);
handle_tx!(tx.commit());
success!(persisted_location)
}

1
src/service/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod admin;

55
src/utils/macros.rs Normal file
View File

@ -0,0 +1,55 @@
/// This macro unwraps the value and if its an error it rolls back the transaction and returns a TypedHttpResponse with the corresponding erorr.
#[macro_export]
macro_rules! handle_db_write_op {
($e:expr, $tx:expr) => {
match $e.await {
Ok(value) => value,
Err(error) => {
handle_tx!($tx.rollback());
return actix_web_utils::extensions::typed_response::TypedHttpResponse::return_standard_error(400, err::MessageResource::new_from_string(error.to_string()));
}
}
};
}
#[macro_export]
macro_rules! handle_db_read_op {
($e:expr) => {
match $e.await {
Ok(value) => value,
Err(error) => return actix_web_utils::extensions::typed_response::TypedHttpResponse::return_standard_error(400, err::MessageResource::new_from_string(error.to_string())),
}
};
}
/// This macro calls await on whatever you give it and if it gets an error it returns a TypedHttpResponse with an InternalServerError status code (500) and an error message.
#[macro_export]
macro_rules! handle_tx {
($e:expr) => {
match $e.await {
Ok(value) => value,
Err(_) => {
return actix_web_utils::extensions::typed_response::TypedHttpResponse::return_standard_error(500, err::MessageResource::new_from_str("Failed to acquire, commit or rollback tx..."));
}
}
};
}
/// This macro just returns a TypedHttpResponse with a success status code (200) and whatever you give it inside.
#[macro_export]
macro_rules! success {
($e:expr) => {
return actix_web_utils::extensions::typed_response::TypedHttpResponse::return_standard_response(200, $e)
};
}
/// This macro just returns a TypedHttpResponse with a not found status code (404) and an error concatenated.
#[macro_export]
macro_rules! unwrap_or_not_found {
($e:expr, $what:literal) => {
match $e {
Some(value) => value,
None => return actix_web_utils::extensions::typed_response::TypedHttpResponse::return_standard_error(404, err::MessageResource::new_from_string(format!("No {} found with specified Id.", $what))),
}
};
}

1
src/utils/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod macros;