From 1f7e81ad3f47ddb91c54c562b1122da6cb8c3701 Mon Sep 17 00:00:00 2001 From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com> Date: Fri, 2 May 2025 13:42:49 +0200 Subject: [PATCH 01/11] WIP --- ...e045f29210264531695165d20e0e978a37069.json | 71 ------------------- ...d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json} | 24 ++++--- ...502114042_adding_description_to_scrope.sql | 1 + api/src/api/admin.rs | 2 +- api/src/api/scope.rs | 5 +- api/src/api/types.rs | 1 + api/src/db/database.rs | 7 +- api/src/db/models.rs | 2 + frontend/islands/new.tsx | 19 ++++- 9 files changed, 46 insertions(+), 86 deletions(-) delete mode 100644 api/.sqlx/query-133923c61b4021d34fb89119a11e045f29210264531695165d20e0e978a37069.json rename api/.sqlx/{query-353d93cde6d9eace115c2753931d4d706f9ac9c599db7ffa1e06ad6fc944faea.json => query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json} (86%) create mode 100644 api/migrations/20250502114042_adding_description_to_scrope.sql diff --git a/api/.sqlx/query-133923c61b4021d34fb89119a11e045f29210264531695165d20e0e978a37069.json b/api/.sqlx/query-133923c61b4021d34fb89119a11e045f29210264531695165d20e0e978a37069.json deleted file mode 100644 index 6a721201c..000000000 --- a/api/.sqlx/query-133923c61b4021d34fb89119a11e045f29210264531695165d20e0e978a37069.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n WITH ins_scope AS (\n INSERT INTO scopes (scope, creator) VALUES ($1, $2)\n RETURNING\n scope,\n creator,\n package_limit,\n new_package_per_week_limit,\n publish_attempts_per_week_limit,\n verify_oidc_actor,\n require_publishing_from_ci,\n updated_at,\n created_at\n ),\n ins_member AS (\n INSERT INTO scope_members (scope, user_id, is_admin)\n VALUES ($1, $2, true)\n )\n SELECT\n scope as \"scope: ScopeName\",\n creator,\n package_limit,\n new_package_per_week_limit,\n publish_attempts_per_week_limit,\n verify_oidc_actor,\n require_publishing_from_ci,\n updated_at,\n created_at\n FROM ins_scope\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "scope: ScopeName", - "type_info": "Text" - }, - { - "ordinal": 1, - "name": "creator", - "type_info": "Uuid" - }, - { - "ordinal": 2, - "name": "package_limit", - "type_info": "Int4" - }, - { - "ordinal": 3, - "name": "new_package_per_week_limit", - "type_info": "Int4" - }, - { - "ordinal": 4, - "name": "publish_attempts_per_week_limit", - "type_info": "Int4" - }, - { - "ordinal": 5, - "name": "verify_oidc_actor", - "type_info": "Bool" - }, - { - "ordinal": 6, - "name": "require_publishing_from_ci", - "type_info": "Bool" - }, - { - "ordinal": 7, - "name": "updated_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 8, - "name": "created_at", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Text", - "Uuid" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - "hash": "133923c61b4021d34fb89119a11e045f29210264531695165d20e0e978a37069" -} diff --git a/api/.sqlx/query-353d93cde6d9eace115c2753931d4d706f9ac9c599db7ffa1e06ad6fc944faea.json b/api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json similarity index 86% rename from api/.sqlx/query-353d93cde6d9eace115c2753931d4d706f9ac9c599db7ffa1e06ad6fc944faea.json rename to api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json index 1e6de23ac..1f3aeb23f 100644 --- a/api/.sqlx/query-353d93cde6d9eace115c2753931d4d706f9ac9c599db7ffa1e06ad6fc944faea.json +++ b/api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n scopes.scope as \"scope: ScopeName\",\n scopes.creator,\n scopes.package_limit,\n scopes.new_package_per_week_limit,\n scopes.publish_attempts_per_week_limit,\n scopes.verify_oidc_actor,\n scopes.require_publishing_from_ci,\n scopes.updated_at,\n scopes.created_at\n FROM scopes\n LEFT JOIN scope_members ON scope_members.scope = scopes.scope\n WHERE user_id = $1", + "query": "SELECT\n scopes.scope as \"scope: ScopeName\",\n scopes.description as \"description: ScopeDescription\",\n scopes.creator,\n scopes.package_limit,\n scopes.new_package_per_week_limit,\n scopes.publish_attempts_per_week_limit,\n scopes.verify_oidc_actor,\n scopes.require_publishing_from_ci,\n scopes.updated_at,\n scopes.created_at\n FROM scopes\n LEFT JOIN scope_members ON scope_members.scope = scopes.scope\n WHERE user_id = $1", "describe": { "columns": [ { @@ -10,41 +10,46 @@ }, { "ordinal": 1, + "name": "description: ScopeDescription", + "type_info": "Text" + }, + { + "ordinal": 2, "name": "creator", "type_info": "Uuid" }, { - "ordinal": 2, + "ordinal": 3, "name": "package_limit", "type_info": "Int4" }, { - "ordinal": 3, + "ordinal": 4, "name": "new_package_per_week_limit", "type_info": "Int4" }, { - "ordinal": 4, + "ordinal": 5, "name": "publish_attempts_per_week_limit", "type_info": "Int4" }, { - "ordinal": 5, + "ordinal": 6, "name": "verify_oidc_actor", "type_info": "Bool" }, { - "ordinal": 6, + "ordinal": 7, "name": "require_publishing_from_ci", "type_info": "Bool" }, { - "ordinal": 7, + "ordinal": 8, "name": "updated_at", "type_info": "Timestamptz" }, { - "ordinal": 8, + "ordinal": 9, "name": "created_at", "type_info": "Timestamptz" } @@ -56,6 +61,7 @@ }, "nullable": [ false, + true, false, false, false, @@ -66,5 +72,5 @@ false ] }, - "hash": "353d93cde6d9eace115c2753931d4d706f9ac9c599db7ffa1e06ad6fc944faea" + "hash": "fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c" } diff --git a/api/migrations/20250502114042_adding_description_to_scrope.sql b/api/migrations/20250502114042_adding_description_to_scrope.sql new file mode 100644 index 000000000..1adc7f86e --- /dev/null +++ b/api/migrations/20250502114042_adding_description_to_scrope.sql @@ -0,0 +1 @@ +ALTER TABLE scopes ADD COLUMN description TEXT; diff --git a/api/src/api/admin.rs b/api/src/api/admin.rs index d34a0f4bb..89f49daa5 100644 --- a/api/src/api/admin.rs +++ b/api/src/api/admin.rs @@ -202,7 +202,7 @@ pub async fn assign_scope(mut req: Request) -> ApiResult { } let scope = db - .create_scope(&staff.id, true, &scope, user_id) + .create_scope(&staff.id, true, &scope, user_id, None) .await .map_err(|e| map_unique_violation(e, ApiError::ScopeAlreadyExists))?; diff --git a/api/src/api/scope.rs b/api/src/api/scope.rs index 9ecba9c22..3319b2d19 100644 --- a/api/src/api/scope.rs +++ b/api/src/api/scope.rs @@ -63,8 +63,9 @@ static RESERVED_SCOPES: OnceLock> = #[instrument(name = "POST /api/scopes", skip(req), err, fields(scope))] async fn create_handler(mut req: Request) -> ApiResult { - let ApiCreateScopeRequest { scope } = decode_json(&mut req).await?; + let ApiCreateScopeRequest { scope, description } = decode_json(&mut req).await?; Span::current().record("scope", field::display(&scope)); + Span::current().record("description", field::display(description.as_deref().unwrap_or(""))); let db = req.data::().unwrap(); @@ -94,7 +95,7 @@ async fn create_handler(mut req: Request) -> ApiResult { } let scope = db - .create_scope(&user.id, false, &scope, user.id) + .create_scope(&user.id, false, &scope, user.id, description) .await .map_err(|e| map_unique_violation(e, ApiError::ScopeAlreadyExists))?; diff --git a/api/src/api/types.rs b/api/src/api/types.rs index 4157f973b..33b908e4e 100644 --- a/api/src/api/types.rs +++ b/api/src/api/types.rs @@ -263,6 +263,7 @@ pub enum ApiScopeOrFullScope { #[serde(rename_all = "camelCase")] pub struct ApiCreateScopeRequest { pub scope: ScopeName, + pub description: Option, } #[derive(Debug, Serialize, Deserialize)] diff --git a/api/src/db/database.rs b/api/src/db/database.rs index 87026fc30..2de6a3ea3 100644 --- a/api/src/db/database.rs +++ b/api/src/db/database.rs @@ -925,6 +925,7 @@ impl Database { is_sudo: bool, scope: &ScopeName, user_id: Uuid, + scope_description: Option, ) -> Result { let mut tx = self.pool.begin().await?; @@ -948,9 +949,10 @@ impl Database { Scope, r#" WITH ins_scope AS ( - INSERT INTO scopes (scope, creator) VALUES ($1, $2) + INSERT INTO scopes (scope, description, creator) VALUES ($1, $2, $3) RETURNING scope, + description, creator, package_limit, new_package_per_week_limit, @@ -977,6 +979,7 @@ impl Database { FROM ins_scope "#, scope as _, + description = scope_description, user_id ) .fetch_one(&mut *tx) @@ -1096,6 +1099,7 @@ impl Database { .map(|r| { let scope = Scope { scope: r.scope_scope, + description: r.scope_description, creator: r.scope_creator, updated_at: r.scope_updated_at, created_at: r.scope_created_at, @@ -2325,6 +2329,7 @@ impl Database { Scope, r#"SELECT scopes.scope as "scope: ScopeName", + scopes.description as "description: ScopeDescription", scopes.creator, scopes.package_limit, scopes.new_package_per_week_limit, diff --git a/api/src/db/models.rs b/api/src/db/models.rs index 6c722ff61..cd471aa5c 100644 --- a/api/src/db/models.rs +++ b/api/src/db/models.rs @@ -208,6 +208,7 @@ pub struct NewPublishingTask<'s> { #[derive(Debug)] pub struct Scope { pub scope: ScopeName, + pub description: Option, pub creator: Uuid, pub updated_at: DateTime, pub created_at: DateTime, @@ -237,6 +238,7 @@ impl FromRow<'_, sqlx::postgres::PgRow> for Scope { fn from_row(row: &sqlx::postgres::PgRow) -> Result { Ok(Self { scope: try_get_row_or(row, "scope", "scope_scope")?, + description: try_get_row_or(row, "description", "scope_description")?, creator: try_get_row_or(row, "creator", "scope_creator")?, updated_at: try_get_row_or(row, "updated_at", "scope_updated_at")?, created_at: try_get_row_or(row, "created_at", "scope_created_at")?, diff --git a/frontend/islands/new.tsx b/frontend/islands/new.tsx index 1f3cacbba..f1a1a6623 100644 --- a/frontend/islands/new.tsx +++ b/frontend/islands/new.tsx @@ -158,12 +158,13 @@ export function ScopeSelect( function CreateScope( props: { initialValue: string | undefined; - onCreate: (scope: string) => void; + onCreate: (scope: string, description: string) => void; locked: boolean; user: User; }, ) { const newScope = useSignal(props.initialValue ?? ""); + const description = useSignal(""); const errorCode = useSignal(""); const error = useSignal(""); const message = useComputed(() => { @@ -188,9 +189,10 @@ function CreateScope( const resp = await api.post(path`/scopes`, { scope: newScope.value, + description: description.value, }); if (resp.ok) { - props.onCreate(newScope.value); + props.onCreate(newScope.value, description.value); } else { console.error(resp); errorCode.value = resp.code; @@ -224,6 +226,19 @@ function CreateScope( }} /> +