From 96782b52cdafba1a541b55c829781b2d7fc1229b Mon Sep 17 00:00:00 2001 From: Jai A Date: Fri, 8 Nov 2024 17:42:41 -0800 Subject: [PATCH] Initial draft --- .../20241108221437_shared-instances.sql | 47 +++++++++++ apps/labrinth/src/database/models/mod.rs | 1 + .../database/models/shared_instance_item.rs | 4 + apps/labrinth/src/models/mod.rs | 1 + apps/labrinth/src/models/v3/ids.rs | 7 ++ apps/labrinth/src/models/v3/mod.rs | 1 + .../src/models/v3/shared_instances.rs | 79 +++++++++++++++++++ apps/labrinth/src/routes/v3/mod.rs | 1 + .../src/routes/v3/shared_instances.rs | 26 ++++++ 9 files changed, 167 insertions(+) create mode 100644 apps/labrinth/migrations/20241108221437_shared-instances.sql create mode 100644 apps/labrinth/src/database/models/shared_instance_item.rs create mode 100644 apps/labrinth/src/models/v3/shared_instances.rs create mode 100644 apps/labrinth/src/routes/v3/shared_instances.rs diff --git a/apps/labrinth/migrations/20241108221437_shared-instances.sql b/apps/labrinth/migrations/20241108221437_shared-instances.sql new file mode 100644 index 000000000..b897c969f --- /dev/null +++ b/apps/labrinth/migrations/20241108221437_shared-instances.sql @@ -0,0 +1,47 @@ +CREATE TABLE shared_instances ( + id bigint PRIMARY KEY, + creator_id bigint REFERENCES users NOT NULL, + icon_url text NOT NULL, + name text NOT NULL, + status text NOT NULL, + created timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + updated timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + include_paths text[] NOT NULL, + exclude_paths text[] NOT NULL, +); + +CREATE TABLE shared_instance_invites ( + id bigint PRIMARY KEY, + creator_id bigint REFERENCES users NOT NULL, + shared_instance_id bigint REFERENCES shared_instances NOT NULL, + + created timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL, + expires timestamptz NULL, + last_used timestamptz NOT NULL, + max_users bigint NULL, + uses integer NOT NULL DEFAULT 0, +) + +CREATE TABLE shared_instances_users ( + shared_instance_id bigint REFERENCES shared_instances NOT NULL, + user_id bigint REFERENCES users NOT NULL, + + PRIMARY KEY (shared_instance_id, user_id), +); + +CREATE TABLE shared_instances_files ( + id bigint PRIMARY KEY, + shared_instance_id bigint REFERENCES shared_instances NOT NULL, + install_path text not null, + side_type text not null, + + override_id bigint REFERENCES shared_instances_overrides, + file_id bigint REFERENCES files, +); + +CREATE TABLE shared_instances_overrides ( + id bigint PRIMARY KEY, + size integer NOT NULL, + -- blake3 hash of file for lookup + hash bytea NOT NULL, +); \ No newline at end of file diff --git a/apps/labrinth/src/database/models/mod.rs b/apps/labrinth/src/database/models/mod.rs index dabcfdda6..050cd02e1 100644 --- a/apps/labrinth/src/database/models/mod.rs +++ b/apps/labrinth/src/database/models/mod.rs @@ -24,6 +24,7 @@ pub mod thread_item; pub mod user_item; pub mod user_subscription_item; pub mod version_item; +mod shared_instance_item; pub use collection_item::Collection; pub use ids::*; diff --git a/apps/labrinth/src/database/models/shared_instance_item.rs b/apps/labrinth/src/database/models/shared_instance_item.rs new file mode 100644 index 000000000..7db6c89f4 --- /dev/null +++ b/apps/labrinth/src/database/models/shared_instance_item.rs @@ -0,0 +1,4 @@ + +pub struct SharedInstanceItem { + +} \ No newline at end of file diff --git a/apps/labrinth/src/models/mod.rs b/apps/labrinth/src/models/mod.rs index aea510d79..acf95a51c 100644 --- a/apps/labrinth/src/models/mod.rs +++ b/apps/labrinth/src/models/mod.rs @@ -19,3 +19,4 @@ pub use v3::sessions; pub use v3::teams; pub use v3::threads; pub use v3::users; +pub use v3::shared_instances; \ No newline at end of file diff --git a/apps/labrinth/src/models/v3/ids.rs b/apps/labrinth/src/models/v3/ids.rs index 5a2997c80..9980373b4 100644 --- a/apps/labrinth/src/models/v3/ids.rs +++ b/apps/labrinth/src/models/v3/ids.rs @@ -16,6 +16,10 @@ pub use super::users::UserId; pub use crate::models::billing::{ ChargeId, ProductId, ProductPriceId, UserSubscriptionId, }; +pub use crate::models::shared_instances::{ + SharedInstanceFileId, SharedInstanceId, + SharedInstanceInviteId, +}; use thiserror::Error; /// Generates a random 64 bit integer that is exactly `n` characters @@ -143,6 +147,9 @@ base62_id_impl!(ProductId, ProductId); base62_id_impl!(ProductPriceId, ProductPriceId); base62_id_impl!(UserSubscriptionId, UserSubscriptionId); base62_id_impl!(ChargeId, ChargeId); +base62_id_impl!(SharedInstanceId, SharedInstanceId); +base62_id_impl!(SharedInstanceInviteId, SharedInstanceInviteId); +base62_id_impl!(SharedInstanceFileId, SharedInstanceFileId); pub mod base62_impl { use serde::de::{self, Deserializer, Visitor}; diff --git a/apps/labrinth/src/models/v3/mod.rs b/apps/labrinth/src/models/v3/mod.rs index d9ffb8451..808615f5b 100644 --- a/apps/labrinth/src/models/v3/mod.rs +++ b/apps/labrinth/src/models/v3/mod.rs @@ -15,3 +15,4 @@ pub mod sessions; pub mod teams; pub mod threads; pub mod users; +pub mod shared_instances; diff --git a/apps/labrinth/src/models/v3/shared_instances.rs b/apps/labrinth/src/models/v3/shared_instances.rs new file mode 100644 index 000000000..ec8b18997 --- /dev/null +++ b/apps/labrinth/src/models/v3/shared_instances.rs @@ -0,0 +1,79 @@ +use serde::{Deserialize, Serialize}; +use chrono::{DateTime, Utc}; +use crate::models::ids::UserId; + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Debug)] +#[serde(from = "Base62Id")] +#[serde(into = "Base62Id")] +pub struct SharedInstanceId(pub u64); + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Debug)] +#[serde(from = "Base62Id")] +#[serde(into = "Base62Id")] +pub struct SharedInstanceInviteId(pub u64); + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, Debug)] +#[serde(from = "Base62Id")] +#[serde(into = "Base62Id")] +pub struct SharedInstanceFileId(pub u64); + +#[derive(Serialize, Deserialize, Clone)] +pub struct SharedInstance { + pub id: SharedInstanceId, + pub creator_id: UserId, + pub icon_url: String, + pub name: String, + pub status: SharedInstanceStatus, + pub created: DateTime, + pub updated: DateTime, + + pub include_paths: Vec, + pub exclude_paths: Vec, +} + +#[derive(Serialize, Deserialize, Clone)] +pub enum SharedInstanceStatus { + Active, + Rejected, +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct SharedInstanceInvite { + pub id: SharedInstanceInviteId, + pub creator_id: UserId, + pub shared_instance_id: SharedInstanceId, + + pub created: DateTime, + pub expires: Option>, + pub last_used: Option>, + pub max_users: Option, + pub uses: u64, +} + +#[derive(Serialize, Deserialize, Clone)] +pub struct SharedInstanceFile { + pub id: SharedInstanceFileId, + pub size: u64, + pub install_path: String, + pub side: SharedInstanceFileSide, + pub source: SharedInstanceFileSource, +} + +#[derive(Serialize, Deserialize, Clone)] +#[serde(tag = "type", rename_all = "kebab-case")] +pub enum SharedInstanceFileSource { + Modrinth { + url: String, + }, + File { + hash: String, + } +} + +#[derive(Serialize, Deserialize, Clone)] +#[serde(rename_all = "kebab-case")] +pub enum SharedInstanceFileSide { + ClientOnly, + ServerOnly, + Universal, +} \ No newline at end of file diff --git a/apps/labrinth/src/routes/v3/mod.rs b/apps/labrinth/src/routes/v3/mod.rs index 23a92a00b..f4bbc780b 100644 --- a/apps/labrinth/src/routes/v3/mod.rs +++ b/apps/labrinth/src/routes/v3/mod.rs @@ -22,6 +22,7 @@ pub mod version_file; pub mod versions; pub mod oauth_clients; +mod shared_instances; pub fn config(cfg: &mut web::ServiceConfig) { cfg.service( diff --git a/apps/labrinth/src/routes/v3/shared_instances.rs b/apps/labrinth/src/routes/v3/shared_instances.rs new file mode 100644 index 000000000..343142e2b --- /dev/null +++ b/apps/labrinth/src/routes/v3/shared_instances.rs @@ -0,0 +1,26 @@ + +// shared instance flow: +// create a new shared instance +// get user-owned shared instances +// update shared instance +// remove / delete shared instance + +// invite flow: +// get invite +// join shared instance +// get joined shared instances +// leave / remove shared instance + +// manage invites flow: +//.get joined users +// remove user +// get invites +// create invite +// update invite +// remove invites + +// install / file flow: +// request install details / files +// add files +// update file +// remove files \ No newline at end of file