-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added schema and crl apis for organisation #322
Conversation
c27e5b4
to
e9347bb
Compare
name = "organisation" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
|
||
[dependencies] | ||
service_utils = { path = "../../service_utils" } | ||
superposition_types = { path = "../../superposition_types", features = [ | ||
"result", | ||
"diesel_derives", | ||
]} | ||
serde = { workspace = true } | ||
serde_json = { workspace = true } | ||
chrono = { workspace = true } | ||
actix-web = { workspace = true } | ||
anyhow = { workspace = true } | ||
diesel = { workspace = true , features = ["numeric"]} | ||
idgenerator = "2.0.0" | ||
log = { workspace = true } | ||
superposition_macros = { path = "../../superposition_macros" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need a crate for org, it can just be a module
actix-web = { workspace = true } | ||
anyhow = { workspace = true } | ||
diesel = { workspace = true , features = ["numeric"]} | ||
idgenerator = "2.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
idgenerator seems to use snowflake internally, can we just use the snowflake generator internally?
https://crates.io/crates/idgenerator
mut db_conn: DbConnection, | ||
) -> superposition::Result<HttpResponse> { | ||
let org_id = | ||
db_conn.transaction::<_, superposition::AppError, _>(|transaction_conn| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a transaction for a single insert?
mut db_conn: DbConnection, | ||
) -> superposition::Result<HttpResponse> { | ||
let org = | ||
db_conn.transaction::<_, superposition::AppError, _>(|transaction_conn| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why a transaction for a get request?
created_by VARCHAR(255) NOT NULL, | ||
admin_email VARCHAR(255) NOT NULL, | ||
status superposition.org_status NOT NULL DEFAULT 'ACTIVE', | ||
contact_details JSONB, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this column anymore since we flattened it out right?
sector VARCHAR(100), | ||
industry VARCHAR(100), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add this later? A business can span multiple sectors and industries
778257c
to
ba5455a
Compare
crates/superposition/src/main.rs
Outdated
@@ -44,6 +45,13 @@ async fn main() -> Result<()> { | |||
let service_prefix: String = | |||
get_from_env_unsafe("SERVICE_PREFIX").expect("SERVICE_PREFIX is not set"); | |||
|
|||
let options = IdGeneratorOptions::new() | |||
.worker_id(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we expect worker id in the env?
|
||
CREATE TABLE IF NOT EXISTS superposition.organisation ( | ||
id VARCHAR(30) PRIMARY KEY NOT NULL, | ||
country_code VARCHAR(10), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't country code supposed to be 2/3 characters, depending on the format?
Source: https://en.wikipedia.org/wiki/Country_code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have created a ticket for country code validation to be picked up later.
} | ||
|
||
#[derive(Deserialize)] | ||
pub enum SortBy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: SortBy
followed by an order, ascending/descending sounds quite odd, as it's an adjective in the place of a noun. It makes sense to sort-by length, size, color etc., but not by an ordering itself, as it can't be the property of a subject. As in this case, an organization can a have size or length, but it can't possibly be ascending or descending by some magnitude.
I know that this term has already been used in the system for this use-case, but since it's going to be present in API contracts(& maybe UI), I feel like we should seriously consider changing it to Order
or OrderBy
.
} | ||
|
||
#[derive(Deserialize, Default)] | ||
pub struct OrganisationFilters { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you see if you can use PaginationParams
instead of your own type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these types are redundant, I will remove them
@sauraww - If any of the comments will/is taking too much time to resolve, ping me, we can take a call on whether to take it up later. |
ba5455a
to
098dde5
Compare
098dde5
to
0fe5e68
Compare
diesel::table! { | ||
use diesel::sql_types::*; | ||
use super::sql_types::OrgStatus; | ||
|
||
organisation (id) { | ||
#[max_length = 30] | ||
id -> Varchar, | ||
#[max_length = 10] | ||
country_code -> Nullable<Varchar>, | ||
#[max_length = 255] | ||
contact_email -> Nullable<Varchar>, | ||
#[max_length = 15] | ||
contact_phone -> Nullable<Varchar>, | ||
#[max_length = 255] | ||
created_by -> Varchar, | ||
#[max_length = 255] | ||
admin_email -> Varchar, | ||
status -> OrgStatus, | ||
#[max_length = 100] | ||
sector -> Nullable<Varchar>, | ||
created_at -> Timestamp, | ||
updated_at -> Timestamp, | ||
#[max_length = 255] | ||
updated_by -> Varchar, | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sauraww since this is inside superposition schema, it should look different
pub mod superposition {
pub mod sql_types {
#[derive(diesel::sql_types::SqlType)]
#[diesel(postgres_type(name = "workspace_status", schema = "superposition"))]
pub struct WorkspaceStatus;
}
diesel::table! {
use diesel::sql_types::*;
use super::sql_types::WorkspaceStatus;
superposition.workspaces (organization_id, workspace_name) {
organization_id -> Text,
organization_name -> Text,
workspace_name -> Text,
workspace_schema_name -> Text,
workspace_status -> WorkspaceStatus,
workspace_admin_email -> Text,
created_by -> Text,
last_modified_by -> Text,
last_modified_at -> Timestamp,
created_at -> Timestamp,
mandatory_dimensions -> Nullable<Array<Text>>,
}
}
}
This is what workspace looks like for the same create statement as yours.
You have to change diesel.toml to reflect this:
[print_schema.superposition]
file = "src/superposition_schema.rs"
patch_file = "schema.patch"
#[cfg_attr(feature = "diesel_derives", diesel(check_for_backend(diesel::pg::Pg)))] | ||
#[cfg_attr(feature = "diesel_derives", diesel(primary_key(id)))] | ||
#[cfg_attr(feature = "diesel_derives", diesel(treat_none_as_null = true))] | ||
#[cfg_attr(feature = "diesel_derives", diesel(table_name = organisation))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the table name be organisations
?
@@ -2,3 +2,5 @@ pub mod cac; | |||
|
|||
#[cfg(feature = "experimentation")] | |||
pub mod experimentation; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we please avoid these newlines
-- up.sql | ||
CREATE SCHEMA IF NOT EXISTS superposition; | ||
|
||
CREATE TYPE superposition.org_status AS ENUM ('ACTIVE', 'INACTIVE', 'PENDINGKYB'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should it be PENDING_KYB
?
#[derive(Serialize)] | ||
pub struct OrganisationResponse { | ||
id: String, | ||
country_code: Option<String>, | ||
contact_email: Option<String>, | ||
contact_phone: Option<String>, | ||
admin_email: String, | ||
status: OrgStatus, | ||
sector: Option<String>, | ||
created_at: chrono::NaiveDateTime, | ||
updated_at: chrono::NaiveDateTime, | ||
created_by: String, | ||
updated_by: String, | ||
} | ||
|
||
impl From<Organisation> for OrganisationResponse { | ||
fn from(org: Organisation) -> Self { | ||
OrganisationResponse { | ||
id: org.id, | ||
country_code: org.country_code, | ||
contact_email: org.contact_email, | ||
contact_phone: org.contact_phone, | ||
admin_email: org.admin_email, | ||
status: org.status, | ||
sector: org.sector, | ||
created_at: org.created_at, | ||
updated_at: org.updated_at, | ||
created_by: org.created_by, | ||
updated_by: org.updated_by, | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this separately, its same as Organisation
type, can we please reuse that
type unification was done to avoid these things 😭
crates/superposition/Cargo.toml
Outdated
serde_json = { workspace = true } | ||
service_utils = { path = "../service_utils" } | ||
superposition_types = { path = "../superposition_types" } | ||
toml = { workspace = true } | ||
idgenerator = "2.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add this also in alphabetical order
} | ||
})?; | ||
|
||
Ok(HttpResponse::Ok().json(OrganisationResponse::from(org))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we can remove the OrganisationResponse
and directly use Organisation
type then we can simplify it here to:
Ok(HttpResponse::Ok().json(OrganisationResponse::from(org))) | |
Ok(HttpResponse::Ok().json(org)) |
pub country_code: Option<String>, | ||
pub contact_email: Option<String>, | ||
pub contact_phone: Option<String>, | ||
pub created_by: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should not be a request param, this should be taken from the User's username
country_code: req.country_code.clone(), | ||
contact_email: req.contact_email.clone(), | ||
contact_phone: req.contact_phone.clone(), | ||
created_by: req.created_by.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should not be a request param, this should be taken from the User's username
let DbConnection(mut conn) = db_conn; | ||
|
||
// Generating a numeric ID from IdInstance and prefixing it with `orgid` | ||
let numeric_id = IdInstance::next_id(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we planned to keep the org id of fixed length 25 right ?
to allow for some buffer in future?
orgid
is 5 characters, wanted to just know that how is IdInstance::next_id()
making sure that the length of the string given is of 20 characters exact ?
or are we keeping the id value dynamic and not fixed length, because I was of the impression that we planned to keep the id fixed length
CREATE TYPE superposition.org_status AS ENUM ('ACTIVE', 'INACTIVE', 'PENDINGKYB'); | ||
|
||
CREATE TABLE IF NOT EXISTS superposition.organisation ( | ||
id VARCHAR(30) PRIMARY KEY NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we planned to keep the org id of fixed length 25 right ?
to allow for some buffer in future?
0fe5e68
to
c7cafec
Compare
@@ -181,6 +192,11 @@ async fn main() -> Result<()> { | |||
AppExecutionScopeMiddlewareFactory::new(AppScope::EXPERIMENTATION), | |||
), | |||
) | |||
.service( | |||
scope("/organisation") | |||
.wrap(AppExecutionScopeMiddlewareFactory::new(AppScope::SUPERPOSITION)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has to be cleaned up later
c7cafec
to
2a09fb1
Compare
@@ -29,7 +29,7 @@ | |||
devShells.default = pkgs.mkShell { | |||
inputsFrom = [ | |||
self'.devShells.rust | |||
self'.devShells.haskell | |||
# self'.devShells.haskell |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please uncomment this later on
Problem
Describe the problem you are trying to solve here
Solution
Provide a brief summary of your solution so that reviewers can understand your code
Environment variable changes
What ENVs need to be added or changed
Pre-deployment activity
Things needed to be done before deploying this change (if any)
Post-deployment activity
Things needed to be done after deploying this change (if any)
API changes
Possible Issues in the future
Describe any possible issues that could occur because of this change