diff --git a/rfd-model/migrations/2023-10-06-001455_add_rfd_visibility/down.sql b/rfd-model/migrations/2023-10-06-001455_add_rfd_visibility/down.sql new file mode 100644 index 0000000..2ef10da --- /dev/null +++ b/rfd-model/migrations/2023-10-06-001455_add_rfd_visibility/down.sql @@ -0,0 +1,3 @@ +ALTER TABLE rfd DROP COLUMN visibility; + +DROP TYPE RFD_VISIBILITY; \ No newline at end of file diff --git a/rfd-model/migrations/2023-10-06-001455_add_rfd_visibility/up.sql b/rfd-model/migrations/2023-10-06-001455_add_rfd_visibility/up.sql new file mode 100644 index 0000000..d52985b --- /dev/null +++ b/rfd-model/migrations/2023-10-06-001455_add_rfd_visibility/up.sql @@ -0,0 +1,3 @@ +CREATE TYPE RFD_VISIBILITY as ENUM('public', 'private'); + +ALTER TABLE rfd ADD COLUMN visibility RFD_VISIBILITY NOT NULL DEFAULT 'private'; diff --git a/rfd-model/src/db.rs b/rfd-model/src/db.rs index 52eec67..d800a3e 100644 --- a/rfd-model/src/db.rs +++ b/rfd-model/src/db.rs @@ -11,7 +11,7 @@ use crate::{ login_attempt, mapper, oauth_client, oauth_client_redirect_uri, oauth_client_secret, rfd, rfd_pdf, rfd_revision, }, - schema_ext::{ContentFormat, LoginAttemptState, PdfSource}, + schema_ext::{ContentFormat, LoginAttemptState, PdfSource, Visibility}, }; #[derive(Debug, Deserialize, Serialize, Queryable, Insertable)] @@ -20,11 +20,10 @@ pub struct RfdModel { pub id: Uuid, pub rfd_number: i32, pub link: Option, - // pub relevant_components: Vec>, - // pub milestones: Vec>, pub created_at: DateTime, pub updated_at: DateTime, pub deleted_at: Option>, + pub visibility: Visibility, } #[derive(Debug, Deserialize, Serialize, Queryable, Insertable)] diff --git a/rfd-model/src/lib.rs b/rfd-model/src/lib.rs index 7f8c65b..ce56ef9 100644 --- a/rfd-model/src/lib.rs +++ b/rfd-model/src/lib.rs @@ -10,7 +10,7 @@ use db::{ }; use partial_struct::partial; use permissions::Permissions; -use schema_ext::{ContentFormat, LoginAttemptState, PdfSource}; +use schema_ext::{ContentFormat, LoginAttemptState, PdfSource, Visibility}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -30,14 +30,13 @@ pub struct Rfd { pub id: Uuid, pub rfd_number: i32, pub link: Option, - // pub relevant_components: Vec>, - // pub milestones: Vec>, #[partial(NewRfd(skip))] pub created_at: DateTime, #[partial(NewRfd(skip))] pub updated_at: DateTime, #[partial(NewRfd(skip))] pub deleted_at: Option>, + pub visibility: Visibility, } impl From for Rfd { @@ -46,11 +45,10 @@ impl From for Rfd { id: value.id, rfd_number: value.rfd_number, link: value.link, - // relevant_components: value.relevant_components, - // milestones: value.milestones, created_at: value.created_at, updated_at: value.updated_at, deleted_at: value.deleted_at, + visibility: value.visibility, } } } diff --git a/rfd-model/src/schema.rs b/rfd-model/src/schema.rs index ce6efd5..4d03b1b 100644 --- a/rfd-model/src/schema.rs +++ b/rfd-model/src/schema.rs @@ -12,6 +12,10 @@ pub mod sql_types { #[derive(diesel::sql_types::SqlType)] #[diesel(postgres_type(name = "rfd_pdf_source"))] pub struct RfdPdfSource; + + #[derive(diesel::sql_types::SqlType)] + #[diesel(postgres_type(name = "rfd_visibility"))] + pub struct RfdVisibility; } diesel::table! { @@ -154,6 +158,9 @@ diesel::table! { } diesel::table! { + use diesel::sql_types::*; + use super::sql_types::RfdVisibility; + rfd (id) { id -> Uuid, rfd_number -> Int4, @@ -161,6 +168,7 @@ diesel::table! { created_at -> Timestamptz, updated_at -> Timestamptz, deleted_at -> Nullable, + visibility -> RfdVisibility, } } diff --git a/rfd-model/src/schema_ext.rs b/rfd-model/src/schema_ext.rs index ce2e16a..50efc54 100644 --- a/rfd-model/src/schema_ext.rs +++ b/rfd-model/src/schema_ext.rs @@ -16,7 +16,7 @@ use std::{ use crate::{ permissions::Permissions, - schema::sql_types::{AttemptState, RfdContentFormat, RfdPdfSource}, + schema::sql_types::{AttemptState, RfdContentFormat, RfdPdfSource, RfdVisibility}, }; macro_rules! sql_conversion { @@ -150,3 +150,26 @@ impl Default for LoginAttemptState { Self::New } } + +#[derive(Debug, PartialEq, Clone, FromSqlRow, AsExpression, Serialize, Deserialize, JsonSchema)] +#[diesel(sql_type = RfdVisibility)] +#[serde(rename_all = "lowercase")] +pub enum Visibility { + Public, + Private, +} + +sql_conversion! { + RfdVisibility => Visibility, + Public => b"public", + Private => b"private", +} + +impl Display for Visibility { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Visibility::Public => write!(f, "public"), + Visibility::Private => write!(f, "private"), + } + } +} \ No newline at end of file diff --git a/rfd-model/src/storage/postgres.rs b/rfd-model/src/storage/postgres.rs index 2ada60f..3ba1a9a 100644 --- a/rfd-model/src/storage/postgres.rs +++ b/rfd-model/src/storage/postgres.rs @@ -133,17 +133,15 @@ impl RfdStore for PostgresStore { rfd::id.eq(new_rfd.id), rfd::rfd_number.eq(new_rfd.rfd_number.clone()), rfd::link.eq(new_rfd.link.clone()), - // rfd::relevant_components.eq(new_rfd.relevant_components.clone()), - // rfd::milestones.eq(new_rfd.milestones.clone()), + rfd::visibility.eq(new_rfd.visibility.clone()), )) .on_conflict(rfd::id) .do_update() .set(( rfd::rfd_number.eq(excluded(rfd::rfd_number)), rfd::link.eq(excluded(rfd::link)), - // rfd::relevant_components.eq(excluded(rfd::relevant_components)), - // rfd::milestones.eq(excluded(rfd::milestones)), rfd::updated_at.eq(Utc::now()), + rfd::visibility.eq(excluded(rfd::visibility)), )) .get_result_async(&self.conn) .await?; diff --git a/rfd-processor/src/rfd.rs b/rfd-processor/src/rfd.rs index e8292af..06bbdf9 100644 --- a/rfd-processor/src/rfd.rs +++ b/rfd-processor/src/rfd.rs @@ -4,7 +4,7 @@ use chrono::{DateTime, Utc}; use octorust::{Client, ClientError}; use rfd_data::RfdNumber; use rfd_model::{ - schema_ext::ContentFormat, + schema_ext::{ContentFormat, Visibility}, storage::{ ListPagination, RfdFilter, RfdRevisionFilter, RfdRevisionStore, RfdStore, StoreError, }, @@ -267,7 +267,7 @@ impl RemoteRfd { let number = self.number; let payload = self.into_payload()?; - let id = RfdStore::list( + let (id, visibility) = RfdStore::list( storage, RfdFilter::default().rfd_number(Some(vec![payload.number.into()])), &ListPagination::latest(), @@ -275,8 +275,8 @@ impl RemoteRfd { .await? .into_iter() .next() - .map(|rfd| rfd.id) - .unwrap_or_else(|| Uuid::new_v4()); + .map(|rfd| (rfd.id, rfd.visibility)) + .unwrap_or_else(|| (Uuid::new_v4(), Visibility::Private)); let rfd = RfdStore::upsert( storage, @@ -284,8 +284,7 @@ impl RemoteRfd { id, rfd_number: payload.number.into(), link: payload.link.into(), - // relevant_components: vec![], - // milestones: vec![], + visibility, }, ) .await?;