From 2001fc5ba664663dd1c38670197c1004961cab5c Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Fri, 2 May 2025 16:34:18 +0200
Subject: [PATCH 02/11] WIP
---
...3ad006fa930dc0889dfd841e51f8568a1bca3.json | 77 ++++++++++++++++
...6bfe60b2721c76ccc9764d5b725198bfd920.json} | 24 +++--
...65f81288607e86b0882cda2a101519c187ab.json} | 42 +++++----
...91c2542daf46dca9e057d4ba487477f0c888e.json | 78 ++++++++++++++++
...49c067bdd1f33166522f80d4c161d33a1450.json} | 24 +++--
...7b71b180ff3d9a76bcf030e258b310b2e138.json} | 24 +++--
...429a7ef74e0bf9cc129e0b0231ba76c92814.json} | 6 +-
...9884486cdec1a48068a4ed6fcbebd708e9fa.json} | 24 +++--
api/src/api.yml | 4 +
api/src/api/admin.rs | 5 +-
api/src/api/scope.rs | 5 +
api/src/api/types.rs | 3 +
api/src/db/database.rs | 72 +++++++++++++--
.../@[scope]/(_components)/ScopeHeader.tsx | 13 ++-
.../(_islands)/ScopeDescriptionForm.tsx | 92 +++++++++++++++++++
frontend/routes/@[scope]/~/settings.tsx | 15 +++
frontend/utils/api_types.ts | 1 +
17 files changed, 439 insertions(+), 70 deletions(-)
create mode 100644 api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json
rename api/.sqlx/{query-49430df890473cb2dd99a3461ec495a4b51eac2aa95df8b9d2f057668e704e79.json => query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json} (73%)
rename api/.sqlx/{query-0b1bcc717b88e251ca9bcfc5ba771c44d369a7fc3a49d83a99116a36644331f8.json => query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json} (68%)
create mode 100644 api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json
rename api/.sqlx/{query-500d0cd93fa62096e30d12d646afd18f9880a4b033ea3bf79e989e9f6cb1260e.json => query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json} (74%)
rename api/.sqlx/{query-24d150e096a117abbeabc5f42029ad38eee8d37928c557141d6526f8bf5ce320.json => query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json} (73%)
rename api/.sqlx/{query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json => query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json} (70%)
rename api/.sqlx/{query-d8211a55290446499c4a2de2defbeaad13728e8811eee2befea96524c2367a1d.json => query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json} (74%)
create mode 100644 frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
diff --git a/api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json b/api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json
new file mode 100644
index 000000000..13422f2e2
--- /dev/null
+++ b/api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json
@@ -0,0 +1,77 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n UPDATE scopes SET description = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description,\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 ",
+ "describe": {
+ "columns": [
+ {
+ "ordinal": 0,
+ "name": "scope: ScopeName",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 1,
+ "name": "description",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
+ "name": "creator",
+ "type_info": "Uuid"
+ },
+ {
+ "ordinal": 3,
+ "name": "package_limit",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 4,
+ "name": "new_package_per_week_limit",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 5,
+ "name": "publish_attempts_per_week_limit",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 6,
+ "name": "verify_oidc_actor",
+ "type_info": "Bool"
+ },
+ {
+ "ordinal": 7,
+ "name": "require_publishing_from_ci",
+ "type_info": "Bool"
+ },
+ {
+ "ordinal": 8,
+ "name": "updated_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 9,
+ "name": "created_at",
+ "type_info": "Timestamptz"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Text",
+ "Text"
+ ]
+ },
+ "nullable": [
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false
+ ]
+ },
+ "hash": "072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3"
+}
diff --git a/api/.sqlx/query-49430df890473cb2dd99a3461ec495a4b51eac2aa95df8b9d2f057668e704e79.json b/api/.sqlx/query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json
similarity index 73%
rename from api/.sqlx/query-49430df890473cb2dd99a3461ec495a4b51eac2aa95df8b9d2f057668e704e79.json
rename to api/.sqlx/query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json
index aa14e2900..e5e36fe11 100644
--- a/api/.sqlx/query-49430df890473cb2dd99a3461ec495a4b51eac2aa95df8b9d2f057668e704e79.json
+++ b/api/.sqlx/query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "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 scopes WHERE creator = $1\n ORDER BY scope ASC",
+ "query": "SELECT\n scope as \"scope: ScopeName\",\n description,\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 scopes WHERE creator = $1\n ORDER BY scope ASC",
"describe": {
"columns": [
{
@@ -10,41 +10,46 @@
},
{
"ordinal": 1,
+ "name": "description",
+ "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": "49430df890473cb2dd99a3461ec495a4b51eac2aa95df8b9d2f057668e704e79"
+ "hash": "7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920"
}
diff --git a/api/.sqlx/query-0b1bcc717b88e251ca9bcfc5ba771c44d369a7fc3a49d83a99116a36644331f8.json b/api/.sqlx/query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json
similarity index 68%
rename from api/.sqlx/query-0b1bcc717b88e251ca9bcfc5ba771c44d369a7fc3a49d83a99116a36644331f8.json
rename to api/.sqlx/query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json
index d426e0644..b185e1bbf 100644
--- a/api/.sqlx/query-0b1bcc717b88e251ca9bcfc5ba771c44d369a7fc3a49d83a99116a36644331f8.json
+++ b/api/.sqlx/query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n WITH usage AS (\n SELECT\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1) AS package,\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1 AND created_at > now() - '1 week'::interval) AS new_package_per_week,\n (SELECT COUNT(created_at) FROM publishing_tasks WHERE package_scope = $1 AND created_at > now() - '1 week'::interval) AS publish_attempts_per_week\n )\n SELECT\n scopes.scope as \"scope_scope: ScopeName\",\n scopes.creator as \"scope_creator\",\n scopes.package_limit as \"scope_package_limit\",\n scopes.new_package_per_week_limit as \"scope_new_package_per_week_limit\",\n scopes.publish_attempts_per_week_limit as \"scope_publish_attempts_per_week_limit\",\n scopes.verify_oidc_actor as \"scope_verify_oidc_actor\",\n scopes.require_publishing_from_ci as \"scope_require_publishing_from_ci\",\n scopes.updated_at as \"scope_updated_at\",\n scopes.created_at as \"scope_created_at\",\n users.id as \"user_id\", users.name as \"user_name\", users.avatar_url as \"user_avatar_url\", users.github_id as \"user_github_id\", users.updated_at as \"user_updated_at\", users.created_at as \"user_created_at\",\n usage.package as \"usage_package\", usage.new_package_per_week as \"usage_new_package_per_week\", usage.publish_attempts_per_week as \"usage_publish_attempts_per_week\"\n FROM scopes\n LEFT JOIN users ON scopes.creator = users.id\n CROSS JOIN usage\n WHERE scopes.scope = $1\n ",
+ "query": "\n WITH usage AS (\n SELECT\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1) AS package,\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1 AND created_at > now() - '1 week'::interval) AS new_package_per_week,\n (SELECT COUNT(created_at) FROM publishing_tasks WHERE package_scope = $1 AND created_at > now() - '1 week'::interval) AS publish_attempts_per_week\n )\n SELECT\n scopes.scope as \"scope_scope: ScopeName\",\n scopes.description as \"scope_description\",\n scopes.creator as \"scope_creator\",\n scopes.package_limit as \"scope_package_limit\",\n scopes.new_package_per_week_limit as \"scope_new_package_per_week_limit\",\n scopes.publish_attempts_per_week_limit as \"scope_publish_attempts_per_week_limit\",\n scopes.verify_oidc_actor as \"scope_verify_oidc_actor\",\n scopes.require_publishing_from_ci as \"scope_require_publishing_from_ci\",\n scopes.updated_at as \"scope_updated_at\",\n scopes.created_at as \"scope_created_at\",\n users.id as \"user_id\", users.name as \"user_name\", users.avatar_url as \"user_avatar_url\", users.github_id as \"user_github_id\", users.updated_at as \"user_updated_at\", users.created_at as \"user_created_at\",\n usage.package as \"usage_package\", usage.new_package_per_week as \"usage_new_package_per_week\", usage.publish_attempts_per_week as \"usage_publish_attempts_per_week\"\n FROM scopes\n LEFT JOIN users ON scopes.creator = users.id\n CROSS JOIN usage\n WHERE scopes.scope = $1\n ",
"describe": {
"columns": [
{
@@ -10,86 +10,91 @@
},
{
"ordinal": 1,
+ "name": "scope_description",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
"name": "scope_creator",
"type_info": "Uuid"
},
{
- "ordinal": 2,
+ "ordinal": 3,
"name": "scope_package_limit",
"type_info": "Int4"
},
{
- "ordinal": 3,
+ "ordinal": 4,
"name": "scope_new_package_per_week_limit",
"type_info": "Int4"
},
{
- "ordinal": 4,
+ "ordinal": 5,
"name": "scope_publish_attempts_per_week_limit",
"type_info": "Int4"
},
{
- "ordinal": 5,
+ "ordinal": 6,
"name": "scope_verify_oidc_actor",
"type_info": "Bool"
},
{
- "ordinal": 6,
+ "ordinal": 7,
"name": "scope_require_publishing_from_ci",
"type_info": "Bool"
},
{
- "ordinal": 7,
+ "ordinal": 8,
"name": "scope_updated_at",
"type_info": "Timestamptz"
},
{
- "ordinal": 8,
+ "ordinal": 9,
"name": "scope_created_at",
"type_info": "Timestamptz"
},
{
- "ordinal": 9,
+ "ordinal": 10,
"name": "user_id",
"type_info": "Uuid"
},
{
- "ordinal": 10,
+ "ordinal": 11,
"name": "user_name",
"type_info": "Text"
},
{
- "ordinal": 11,
+ "ordinal": 12,
"name": "user_avatar_url",
"type_info": "Text"
},
{
- "ordinal": 12,
+ "ordinal": 13,
"name": "user_github_id",
"type_info": "Int8"
},
{
- "ordinal": 13,
+ "ordinal": 14,
"name": "user_updated_at",
"type_info": "Timestamptz"
},
{
- "ordinal": 14,
+ "ordinal": 15,
"name": "user_created_at",
"type_info": "Timestamptz"
},
{
- "ordinal": 15,
+ "ordinal": 16,
"name": "usage_package",
"type_info": "Int8"
},
{
- "ordinal": 16,
+ "ordinal": 17,
"name": "usage_new_package_per_week",
"type_info": "Int8"
},
{
- "ordinal": 17,
+ "ordinal": 18,
"name": "usage_publish_attempts_per_week",
"type_info": "Int8"
}
@@ -101,6 +106,7 @@
},
"nullable": [
false,
+ true,
false,
false,
false,
@@ -120,5 +126,5 @@
null
]
},
- "hash": "0b1bcc717b88e251ca9bcfc5ba771c44d369a7fc3a49d83a99116a36644331f8"
+ "hash": "7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab"
}
diff --git a/api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json b/api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json
new file mode 100644
index 000000000..35cd5f2dd
--- /dev/null
+++ b/api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json
@@ -0,0 +1,78 @@
+{
+ "db_name": "PostgreSQL",
+ "query": "\n WITH ins_scope AS (\n INSERT INTO scopes (scope, creator, description) VALUES ($1, $2, $3)\n RETURNING\n scope,\n description,\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 description,\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": "description",
+ "type_info": "Text"
+ },
+ {
+ "ordinal": 2,
+ "name": "creator",
+ "type_info": "Uuid"
+ },
+ {
+ "ordinal": 3,
+ "name": "package_limit",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 4,
+ "name": "new_package_per_week_limit",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 5,
+ "name": "publish_attempts_per_week_limit",
+ "type_info": "Int4"
+ },
+ {
+ "ordinal": 6,
+ "name": "verify_oidc_actor",
+ "type_info": "Bool"
+ },
+ {
+ "ordinal": 7,
+ "name": "require_publishing_from_ci",
+ "type_info": "Bool"
+ },
+ {
+ "ordinal": 8,
+ "name": "updated_at",
+ "type_info": "Timestamptz"
+ },
+ {
+ "ordinal": 9,
+ "name": "created_at",
+ "type_info": "Timestamptz"
+ }
+ ],
+ "parameters": {
+ "Left": [
+ "Text",
+ "Uuid",
+ "Text"
+ ]
+ },
+ "nullable": [
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false
+ ]
+ },
+ "hash": "95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e"
+}
diff --git a/api/.sqlx/query-500d0cd93fa62096e30d12d646afd18f9880a4b033ea3bf79e989e9f6cb1260e.json b/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
similarity index 74%
rename from api/.sqlx/query-500d0cd93fa62096e30d12d646afd18f9880a4b033ea3bf79e989e9f6cb1260e.json
rename to api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
index 47040b29c..dcf395524 100644
--- a/api/.sqlx/query-500d0cd93fa62096e30d12d646afd18f9880a4b033ea3bf79e989e9f6cb1260e.json
+++ b/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "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 scopes WHERE scope = $1",
+ "query": "SELECT\n scope as \"scope: ScopeName\",\n description,\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 scopes WHERE scope = $1",
"describe": {
"columns": [
{
@@ -10,41 +10,46 @@
},
{
"ordinal": 1,
+ "name": "description",
+ "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": "500d0cd93fa62096e30d12d646afd18f9880a4b033ea3bf79e989e9f6cb1260e"
+ "hash": "a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450"
}
diff --git a/api/.sqlx/query-24d150e096a117abbeabc5f42029ad38eee8d37928c557141d6526f8bf5ce320.json b/api/.sqlx/query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json
similarity index 73%
rename from api/.sqlx/query-24d150e096a117abbeabc5f42029ad38eee8d37928c557141d6526f8bf5ce320.json
rename to api/.sqlx/query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json
index 096b8ac99..a45ec64ca 100644
--- a/api/.sqlx/query-24d150e096a117abbeabc5f42029ad38eee8d37928c557141d6526f8bf5ce320.json
+++ b/api/.sqlx/query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n UPDATE scopes SET require_publishing_from_ci = $1 WHERE scope = $2\n RETURNING\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\n ",
+ "query": "\n UPDATE scopes SET require_publishing_from_ci = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description,\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 ",
"describe": {
"columns": [
{
@@ -10,41 +10,46 @@
},
{
"ordinal": 1,
+ "name": "description",
+ "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"
}
@@ -57,6 +62,7 @@
},
"nullable": [
false,
+ true,
false,
false,
false,
@@ -67,5 +73,5 @@
false
]
},
- "hash": "24d150e096a117abbeabc5f42029ad38eee8d37928c557141d6526f8bf5ce320"
+ "hash": "be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138"
}
diff --git a/api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json b/api/.sqlx/query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json
similarity index 70%
rename from api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json
rename to api/.sqlx/query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json
index 1f3aeb23f..478aec851 100644
--- a/api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json
+++ b/api/.sqlx/query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "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",
+ "query": "SELECT\n scopes.scope as \"scope: ScopeName\",\n scopes.description,\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,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description: ScopeDescription",
+ "name": "description",
"type_info": "Text"
},
{
@@ -72,5 +72,5 @@
false
]
},
- "hash": "fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c"
+ "hash": "f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814"
}
diff --git a/api/.sqlx/query-d8211a55290446499c4a2de2defbeaad13728e8811eee2befea96524c2367a1d.json b/api/.sqlx/query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json
similarity index 74%
rename from api/.sqlx/query-d8211a55290446499c4a2de2defbeaad13728e8811eee2befea96524c2367a1d.json
rename to api/.sqlx/query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json
index db9899d16..02424a786 100644
--- a/api/.sqlx/query-d8211a55290446499c4a2de2defbeaad13728e8811eee2befea96524c2367a1d.json
+++ b/api/.sqlx/query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n UPDATE scopes SET verify_oidc_actor = $1 WHERE scope = $2\n RETURNING\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\n ",
+ "query": "\n UPDATE scopes SET verify_oidc_actor = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description,\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 ",
"describe": {
"columns": [
{
@@ -10,41 +10,46 @@
},
{
"ordinal": 1,
+ "name": "description",
+ "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"
}
@@ -57,6 +62,7 @@
},
"nullable": [
false,
+ true,
false,
false,
false,
@@ -67,5 +73,5 @@
false
]
},
- "hash": "d8211a55290446499c4a2de2defbeaad13728e8811eee2befea96524c2367a1d"
+ "hash": "f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa"
}
diff --git a/api/src/api.yml b/api/src/api.yml
index f45ffd181..b54063a6e 100644
--- a/api/src/api.yml
+++ b/api/src/api.yml
@@ -1560,6 +1560,10 @@ components:
properties:
scope:
$ref: "#/components/schemas/ScopeName"
+ description:
+ type: string
+ description: The description of the scope.
+
required:
- name
diff --git a/api/src/api/admin.rs b/api/src/api/admin.rs
index 89f49daa5..d2d565fcf 100644
--- a/api/src/api/admin.rs
+++ b/api/src/api/admin.rs
@@ -186,9 +186,10 @@ pub async fn patch_scopes(mut req: Request) -> ApiResult
{
fields(scope, user_id)
)]
pub async fn assign_scope(mut req: Request) -> ApiResult {
- let ApiAssignScopeRequest { scope, user_id } = decode_json(&mut req).await?;
+ let ApiAssignScopeRequest { scope, user_id, description } = decode_json(&mut req).await?;
Span::current().record("scope", field::display(&scope));
Span::current().record("user_id", field::display(&user_id));
+ Span::current().record("description", field::display(description.as_deref().unwrap_or("")));
let iam = req.iam();
let staff = iam.check_admin_access()?;
@@ -202,7 +203,7 @@ pub async fn assign_scope(mut req: Request) -> ApiResult {
}
let scope = db
- .create_scope(&staff.id, true, &scope, user_id, None)
+ .create_scope(&staff.id, true, &scope, user_id, description)
.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 3319b2d19..a4fa7c07b 100644
--- a/api/src/api/scope.rs
+++ b/api/src/api/scope.rs
@@ -164,6 +164,11 @@ async fn update_handler(
)
.await?
}
+ ApiUpdateScopeRequest::Description(description) => {
+ let (user, sudo) = iam.check_scope_admin_access(&scope).await?;
+ db.scope_set_description(&user.id, sudo, &scope, description)
+ .await?
+ }
};
let user = db
diff --git a/api/src/api/types.rs b/api/src/api/types.rs
index 33b908e4e..8e7226575 100644
--- a/api/src/api/types.rs
+++ b/api/src/api/types.rs
@@ -725,6 +725,8 @@ pub enum ApiUpdateScopeRequest {
GhActionsVerifyActor(bool),
#[serde(rename = "requirePublishingFromCI")]
RequirePublishingFromCI(bool),
+ #[serde(rename = "description")]
+ Description(Option),
}
#[derive(Debug, Serialize, Deserialize)]
@@ -973,6 +975,7 @@ pub struct ApiCreatedToken {
#[serde(rename_all = "camelCase")]
pub struct ApiAssignScopeRequest {
pub scope: ScopeName,
+ pub description: Option,
pub user_id: Uuid,
}
diff --git a/api/src/db/database.rs b/api/src/db/database.rs
index 2de6a3ea3..830d5f108 100644
--- a/api/src/db/database.rs
+++ b/api/src/db/database.rs
@@ -923,7 +923,7 @@ impl Database {
&self,
actor_id: &Uuid,
is_sudo: bool,
- scope: &ScopeName,
+ scope_name: &ScopeName,
user_id: Uuid,
scope_description: Option,
) -> Result {
@@ -939,7 +939,7 @@ impl Database {
"create_scope"
},
json!({
- "scope": scope,
+ "scope": scope_name,
"user_id": user_id,
}),
)
@@ -949,7 +949,7 @@ impl Database {
Scope,
r#"
WITH ins_scope AS (
- INSERT INTO scopes (scope, description, creator) VALUES ($1, $2, $3)
+ INSERT INTO scopes (scope, creator, description) VALUES ($1, $2, $3)
RETURNING
scope,
description,
@@ -968,6 +968,7 @@ impl Database {
)
SELECT
scope as "scope: ScopeName",
+ description,
creator,
package_limit,
new_package_per_week_limit,
@@ -978,9 +979,9 @@ impl Database {
created_at
FROM ins_scope
"#,
- scope as _,
- description = scope_description,
- user_id
+ scope_name,
+ user_id,
+ scope_description,
)
.fetch_one(&mut *tx)
.await?;
@@ -1079,6 +1080,7 @@ impl Database {
)
SELECT
scopes.scope as "scope_scope: ScopeName",
+ scopes.description as "scope_description",
scopes.creator as "scope_creator",
scopes.package_limit as "scope_package_limit",
scopes.new_package_per_week_limit as "scope_new_package_per_week_limit",
@@ -1211,6 +1213,7 @@ impl Database {
Scope,
r#"SELECT
scope as "scope: ScopeName",
+ description,
creator,
package_limit,
new_package_per_week_limit,
@@ -1233,6 +1236,7 @@ impl Database {
Scope,
r#"SELECT
scope as "scope: ScopeName",
+ description,
creator,
package_limit,
new_package_per_week_limit,
@@ -1242,7 +1246,7 @@ impl Database {
updated_at,
created_at
FROM scopes WHERE scope = $1"#,
- scope as _
+ scope
)
.fetch_optional(&self.pool)
.await
@@ -1296,6 +1300,7 @@ impl Database {
UPDATE scopes SET verify_oidc_actor = $1 WHERE scope = $2
RETURNING
scope as "scope: ScopeName",
+ description,
creator,
package_limit,
new_package_per_week_limit,
@@ -1349,6 +1354,7 @@ impl Database {
UPDATE scopes SET require_publishing_from_ci = $1 WHERE scope = $2
RETURNING
scope as "scope: ScopeName",
+ description,
creator,
package_limit,
new_package_per_week_limit,
@@ -1370,6 +1376,56 @@ impl Database {
Ok(scope)
}
+ #[instrument(name = "Database::scope_set_description", skip(self), err)]
+ pub async fn scope_set_description(
+ &self,
+ actor_id: &Uuid,
+ is_sudo: bool,
+ scope: &ScopeName,
+ description: Option,
+ ) -> Result {
+ let mut tx = self.pool.begin().await?;
+
+ audit_log(
+ &mut tx,
+ actor_id,
+ is_sudo,
+ "scope_set_description",
+ json!({
+ "scope": scope,
+ "description": description,
+ }),
+ )
+ .await?;
+
+ let scope = sqlx::query_as!(
+ Scope,
+ r#"
+ UPDATE scopes SET description = $1 WHERE scope = $2
+ RETURNING
+ scope as "scope: ScopeName",
+ description,
+ creator,
+ package_limit,
+ new_package_per_week_limit,
+ publish_attempts_per_week_limit,
+ verify_oidc_actor,
+ require_publishing_from_ci,
+ updated_at,
+ created_at
+
+ "#,
+ description,
+ scope as _
+ )
+ .fetch_one(&mut *tx)
+ .await?;
+
+ tx.commit().await?;
+
+ Ok(scope)
+ }
+
#[instrument(name = "Database::list_packages_by_scope", skip(self), err)]
pub async fn list_packages_by_scope(
&self,
@@ -2329,7 +2385,7 @@ impl Database {
Scope,
r#"SELECT
scopes.scope as "scope: ScopeName",
- scopes.description as "description: ScopeDescription",
+ scopes.description,
scopes.creator,
scopes.package_limit,
scopes.new_package_per_week_limit,
diff --git a/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx b/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx
index e161ed2a0..7021f4735 100644
--- a/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx
+++ b/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx
@@ -7,8 +7,15 @@ export interface ScopeHeaderProps {
export function ScopeHeader(props: ScopeHeaderProps) {
return (
-
- @{props.scope.scope}
-
+ <>
+
+ @{props.scope.scope}
+
+ {props.scope.description && (
+
+ {props.scope.description}
+
+ )}
+ >
);
}
diff --git a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
new file mode 100644
index 000000000..ad8c420d1
--- /dev/null
+++ b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
@@ -0,0 +1,92 @@
+import { useSignal } from "@preact/signals";
+import { useState } from "preact/hooks";
+import { api, path } from "../../../utils/api.ts";
+import type { FullScope } from "../../../utils/api_types.ts";
+
+interface ScopeDescriptionFormProps {
+ scope: FullScope;
+}
+
+export function ScopeDescriptionForm(
+ { scope: initialScope }: ScopeDescriptionFormProps,
+) {
+ const scope = useSignal(initialScope);
+ const isEditing = useSignal(false);
+ const editedDescription = useSignal(scope.value.description ?? "");
+ const [error, setError] = useState(null);
+ const [isLoading, setIsLoading] = useState(false);
+
+ async function handleSave() {
+ setIsLoading(true);
+ setError(null);
+ const resp = await api.patch(path`/scopes/${scope.value.scope}`, {
+ description: editedDescription.value,
+ });
+ console.log("Response from API:", resp);
+ setIsLoading(false);
+ if (resp.ok) {
+ // Update the local scope signal with the new description
+ scope.value = { ...scope.value, description: editedDescription.value };
+ isEditing.value = false;
+ } else {
+ setError(resp.message ?? "Failed to update description.");
+ console.error("Failed to save scope description:", resp);
+ }
+ }
+
+ function handleCancel() {
+ editedDescription.value = scope.value.description ?? "";
+ isEditing.value = false;
+ setError(null);
+ }
+
+ if (isEditing.value) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+ {scope.value.description || No description provided.}
+
+
+
+ );
+}
diff --git a/frontend/routes/@[scope]/~/settings.tsx b/frontend/routes/@[scope]/~/settings.tsx
index d0715487f..cb975e757 100644
--- a/frontend/routes/@[scope]/~/settings.tsx
+++ b/frontend/routes/@[scope]/~/settings.tsx
@@ -4,6 +4,7 @@ import { ComponentChildren } from "preact";
import { define } from "../../../util.ts";
import { ScopeHeader } from "../(_components)/ScopeHeader.tsx";
import { ScopeNav } from "../(_components)/ScopeNav.tsx";
+import { ScopeDescriptionForm } from "../(_islands)/ScopeDescriptionForm.tsx";
import { FullScope, User } from "../../../utils/api_types.ts";
import { scopeDataWithMember } from "../../../utils/data.ts";
import { path } from "../../../utils/api.ts";
@@ -19,6 +20,7 @@ export default define.page(function ScopeSettingsPage(
+
@@ -27,6 +29,19 @@ export default define.page
(function ScopeSettingsPage(
);
});
+function ScopeDescription({ scope }: { scope: FullScope }) {
+ return (
+
+
Description
+
+ The description of the scope{" "}
+ @{scope.scope}
:
+
+
+
+ );
+}
+
function ScopeQuotas({ scope, user }: { scope: FullScope; user: User }) {
return (
diff --git a/frontend/utils/api_types.ts b/frontend/utils/api_types.ts
index fff2f25b2..763109435 100644
--- a/frontend/utils/api_types.ts
+++ b/frontend/utils/api_types.ts
@@ -20,6 +20,7 @@ export interface FullUser extends User {
export interface Scope {
scope: string;
+ description: string | null;
updatedAt: string;
createdAt: string;
}
From 19f59a25f29ca1d1a9572b090cc895103f122231 Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Fri, 2 May 2025 17:17:21 +0200
Subject: [PATCH 03/11] finish
---
...1630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json} | 6 +++---
api/src/api/types.rs | 4 ++++
frontend/routes/@[scope]/(_components)/ScopeHeader.tsx | 2 +-
.../routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx | 6 +++++-
frontend/routes/@[scope]/~/settings.tsx | 3 ++-
5 files changed, 15 insertions(+), 6 deletions(-)
rename api/.sqlx/{query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json => query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json} (77%)
diff --git a/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json b/api/.sqlx/query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json
similarity index 77%
rename from api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
rename to api/.sqlx/query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json
index dcf395524..697c0fb5f 100644
--- a/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
+++ b/api/.sqlx/query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "SELECT\n scope as \"scope: ScopeName\",\n description,\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 scopes WHERE scope = $1",
+ "query": "SELECT\n scope as \"scope: ScopeName\",\n description as \"description: String\",\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 scopes WHERE scope = $1",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: String",
"type_info": "Text"
},
{
@@ -72,5 +72,5 @@
false
]
},
- "hash": "a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450"
+ "hash": "5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799"
}
diff --git a/api/src/api/types.rs b/api/src/api/types.rs
index 8e7226575..19be42dac 100644
--- a/api/src/api/types.rs
+++ b/api/src/api/types.rs
@@ -192,6 +192,7 @@ impl From
for ApiFullUser {
#[serde(rename_all = "camelCase")]
pub struct ApiScope {
pub scope: ScopeName,
+ pub description: Option,
pub updated_at: DateTime,
pub created_at: DateTime,
}
@@ -200,6 +201,7 @@ impl From for ApiScope {
fn from(scope: Scope) -> Self {
Self {
scope: scope.scope,
+ description: scope.description,
updated_at: scope.updated_at,
created_at: scope.created_at,
}
@@ -221,6 +223,7 @@ pub struct ApiScopeQuotas {
#[serde(rename_all = "camelCase")]
pub struct ApiFullScope {
pub scope: ScopeName,
+ pub description: Option,
pub creator: ApiUser,
pub updated_at: DateTime,
pub created_at: DateTime,
@@ -235,6 +238,7 @@ impl From<(Scope, ScopeUsage, UserPublic)> for ApiFullScope {
assert_eq!(scope.creator, user.id);
Self {
scope: scope.scope,
+ description: scope.description,
creator: user.into(),
updated_at: scope.updated_at,
created_at: scope.created_at,
diff --git a/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx b/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx
index 7021f4735..3e42cc20c 100644
--- a/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx
+++ b/frontend/routes/@[scope]/(_components)/ScopeHeader.tsx
@@ -12,7 +12,7 @@ export function ScopeHeader(props: ScopeHeaderProps) {
@{props.scope.scope}
{props.scope.description && (
-
+
{props.scope.description}
)}
diff --git a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
index ad8c420d1..13a3dcfb1 100644
--- a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
+++ b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
@@ -1,5 +1,6 @@
import { useSignal } from "@preact/signals";
import { useState } from "preact/hooks";
+import { TbPencil, TbCheck, TbX } from "tb-icons";
import { api, path } from "../../../utils/api.ts";
import type { FullScope } from "../../../utils/api_types.ts";
@@ -22,7 +23,7 @@ export function ScopeDescriptionForm(
const resp = await api.patch(path`/scopes/${scope.value.scope}`, {
description: editedDescription.value,
});
- console.log("Response from API:", resp);
+
setIsLoading(false);
if (resp.ok) {
// Update the local scope signal with the new description
@@ -59,6 +60,7 @@ export function ScopeDescriptionForm(
onClick={handleSave}
disabled={isLoading}
>
+
{isLoading ? "Saving..." : "Save"}
@@ -85,6 +88,7 @@ export function ScopeDescriptionForm(
onClick={() => isEditing.value = true}
aria-label="Edit description"
>
+
Edit
diff --git a/frontend/routes/@[scope]/~/settings.tsx b/frontend/routes/@[scope]/~/settings.tsx
index cb975e757..af98b36b2 100644
--- a/frontend/routes/@[scope]/~/settings.tsx
+++ b/frontend/routes/@[scope]/~/settings.tsx
@@ -1,6 +1,7 @@
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
import { HttpError } from "fresh";
import { ComponentChildren } from "preact";
+import { TbCheck, TbTrash } from "tb-icons";
import { define } from "../../../util.ts";
import { ScopeHeader } from "../(_components)/ScopeHeader.tsx";
import { ScopeNav } from "../(_components)/ScopeNav.tsx";
@@ -9,7 +10,6 @@ import { FullScope, User } from "../../../utils/api_types.ts";
import { scopeDataWithMember } from "../../../utils/data.ts";
import { path } from "../../../utils/api.ts";
import { QuotaCard } from "../../../components/QuotaCard.tsx";
-import TbCheck from "tb-icons/TbCheck";
import { scopeIAM } from "../../../utils/iam.ts";
import { TicketModal } from "../../../islands/TicketModal.tsx";
@@ -279,6 +279,7 @@ function DeleteScope({ scope }: { scope: FullScope }) {
name="action"
value="deleteScope"
>
+
Delete scope
{!isEmpty && (
From 6bdede96020263db32cc8c5a218f59f8d1812593 Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Fri, 2 May 2025 18:46:17 +0200
Subject: [PATCH 04/11] test + clean
---
...49c067bdd1f33166522f80d4c161d33a1450.json} | 6 +-
api/src/api/admin.rs | 11 ++-
api/src/api/package.rs | 2 +-
api/src/api/scope.rs | 72 +++++++++++--------
api/src/db/tests.rs | 10 +--
api/src/tasks.rs | 4 +-
api/src/util.rs | 2 +-
.../(_islands)/ScopeDescriptionForm.tsx | 20 +++---
8 files changed, 73 insertions(+), 54 deletions(-)
rename api/.sqlx/{query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json => query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json} (77%)
diff --git a/api/.sqlx/query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json b/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
similarity index 77%
rename from api/.sqlx/query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json
rename to api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
index 697c0fb5f..dcf395524 100644
--- a/api/.sqlx/query-5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799.json
+++ b/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "SELECT\n scope as \"scope: ScopeName\",\n description as \"description: String\",\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 scopes WHERE scope = $1",
+ "query": "SELECT\n scope as \"scope: ScopeName\",\n description,\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 scopes WHERE scope = $1",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description: String",
+ "name": "description",
"type_info": "Text"
},
{
@@ -72,5 +72,5 @@
false
]
},
- "hash": "5511db25b394f91630ad90a3ce03a182e657c0c39bd43edb231aa3da3cbb1799"
+ "hash": "a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450"
}
diff --git a/api/src/api/admin.rs b/api/src/api/admin.rs
index d2d565fcf..a748917f2 100644
--- a/api/src/api/admin.rs
+++ b/api/src/api/admin.rs
@@ -186,10 +186,17 @@ pub async fn patch_scopes(mut req: Request) -> ApiResult {
fields(scope, user_id)
)]
pub async fn assign_scope(mut req: Request) -> ApiResult {
- let ApiAssignScopeRequest { scope, user_id, description } = decode_json(&mut req).await?;
+ let ApiAssignScopeRequest {
+ scope,
+ user_id,
+ description,
+ } = decode_json(&mut req).await?;
Span::current().record("scope", field::display(&scope));
Span::current().record("user_id", field::display(&user_id));
- Span::current().record("description", field::display(description.as_deref().unwrap_or("")));
+ Span::current().record(
+ "description",
+ field::display(description.as_deref().unwrap_or("")),
+ );
let iam = req.iam();
let staff = iam.check_admin_access()?;
diff --git a/api/src/api/package.rs b/api/src/api/package.rs
index af59f9db8..1a8fa5b3e 100644
--- a/api/src/api/package.rs
+++ b/api/src/api/package.rs
@@ -2585,7 +2585,7 @@ mod test {
// create scope2 for user2, try creating a package with user1
let scope2 = ScopeName::new("scope2".into()).unwrap();
t.db()
- .create_scope(&t.user2.user.id, false, &scope2, t.user2.user.id)
+ .create_scope(&t.user2.user.id, false, &scope2, t.user2.user.id, None)
.await
.unwrap();
let mut resp = t
diff --git a/api/src/api/scope.rs b/api/src/api/scope.rs
index a4fa7c07b..cc6dddda0 100644
--- a/api/src/api/scope.rs
+++ b/api/src/api/scope.rs
@@ -63,9 +63,13 @@ 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, description } = 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("")));
+ Span::current().record(
+ "description",
+ field::display(description.as_deref().unwrap_or("")),
+ );
let db = req.data::().unwrap();
@@ -517,7 +521,9 @@ pub mod tests {
let mut resp = t
.http()
.post("/api/scopes")
- .body_json(json!({ "scope": "scope1" }))
+ .body_json(
+ json!({ "scope": "scope1", "description": "Super scope 🐢 !!!" }),
+ )
.call()
.await
.unwrap();
@@ -780,7 +786,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
let members = list_members(&mut t).await;
@@ -844,7 +850,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -893,7 +899,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -942,7 +948,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1005,7 +1011,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1070,7 +1076,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1131,7 +1137,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1176,7 +1182,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1223,7 +1229,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1285,7 +1291,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1347,7 +1353,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1417,7 +1423,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1487,7 +1493,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1559,7 +1565,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1630,7 +1636,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1685,7 +1691,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1727,7 +1733,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1771,7 +1777,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1830,7 +1836,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1892,7 +1898,7 @@ pub mod tests {
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1975,7 +1981,7 @@ pub mod tests {
// create scope
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -1996,7 +2002,7 @@ pub mod tests {
// create scope
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
t.db()
@@ -2037,7 +2043,7 @@ pub mod tests {
// create scope
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
@@ -2074,7 +2080,7 @@ pub mod tests {
// create scope and package
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
let name = PackageName::new("foo".to_owned()).unwrap();
@@ -2097,7 +2103,7 @@ pub mod tests {
// create scope and package
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
t.db()
@@ -2125,14 +2131,20 @@ pub mod tests {
// create scope
let scope_name = ScopeName::try_from("scope1").unwrap();
t.db()
- .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id)
+ .create_scope(&t.user1.user.id, false, &scope_name, t.user1.user.id, None)
.await
.unwrap();
for i in 0..3 {
let scope_name = ScopeName::try_from(format!("temp{i}")).unwrap();
t.db()
- .create_scope(&t.user2.user.id, false, &scope_name, t.user2.user.id)
+ .create_scope(
+ &t.user2.user.id,
+ false,
+ &scope_name,
+ t.user2.user.id,
+ None,
+ )
.await
.unwrap();
}
diff --git a/api/src/db/tests.rs b/api/src/db/tests.rs
index d679b2654..83e5d5aa8 100644
--- a/api/src/db/tests.rs
+++ b/api/src/db/tests.rs
@@ -19,7 +19,7 @@ async fn publishing_tasks() {
let config_file = "/jsr.json".try_into().unwrap();
let _scope = db
- .create_scope(&user_id, false, &scope_name, user_id)
+ .create_scope(&user_id, false, &scope_name, user_id, None)
.await
.unwrap();
let res = db.create_package(&scope_name, &package_name).await.unwrap();
@@ -217,7 +217,7 @@ async fn packages() {
let scope_name = "scope".try_into().unwrap();
let package_name = "testpkg".try_into().unwrap();
- db.create_scope(&alice.id, false, &scope_name, alice.id)
+ db.create_scope(&alice.id, false, &scope_name, alice.id, None)
.await
.unwrap();
@@ -285,7 +285,7 @@ async fn scope_members() {
let scope_name = "scope".try_into().unwrap();
- db.create_scope(&bob.id, false, &scope_name, bob.id)
+ db.create_scope(&bob.id, false, &scope_name, bob.id, None)
.await
.unwrap();
@@ -350,7 +350,7 @@ async fn create_package_version_and_finalize_publishing_task() {
.await
.unwrap();
- db.create_scope(&bob.id, false, &scope, bob.id)
+ db.create_scope(&bob.id, false, &scope, bob.id, None)
.await
.unwrap();
@@ -461,7 +461,7 @@ async fn package_files() {
let package_name = "testpkg".try_into().unwrap();
let version = "1.2.3".try_into().unwrap();
- db.create_scope(&user.id, false, &scope_name, user.id)
+ db.create_scope(&user.id, false, &scope_name, user.id, None)
.await
.unwrap();
diff --git a/api/src/tasks.rs b/api/src/tasks.rs
index 0da287dc7..4c2cb6c6f 100644
--- a/api/src/tasks.rs
+++ b/api/src/tasks.rs
@@ -551,10 +551,10 @@ mod tests {
let v0_219_3 = Version::new("0.219.3").unwrap();
let v1_0_0 = Version::new("1.0.0").unwrap();
- db.create_scope(&Uuid::nil(), false, &std, Uuid::nil())
+ db.create_scope(&Uuid::nil(), false, &std, Uuid::nil(), None)
.await
.unwrap();
- db.create_scope(&Uuid::nil(), false, &luca, Uuid::nil())
+ db.create_scope(&Uuid::nil(), false, &luca, Uuid::nil(), None)
.await
.unwrap();
db.create_package(&std, &fs).await.unwrap();
diff --git a/api/src/util.rs b/api/src/util.rs
index 77ce011c1..bb2ff93e4 100644
--- a/api/src/util.rs
+++ b/api/src/util.rs
@@ -552,7 +552,7 @@ pub mod test {
let scope_name = "scope".try_into().unwrap();
- db.create_scope(&user1.user.id, false, &scope_name, user1.user.id)
+ db.create_scope(&user1.user.id, false, &scope_name, user1.user.id, None)
.await
.unwrap();
let (scope, _, _) = db
diff --git a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
index 13a3dcfb1..4bf6b71ee 100644
--- a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
+++ b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
@@ -1,6 +1,6 @@
import { useSignal } from "@preact/signals";
import { useState } from "preact/hooks";
-import { TbPencil, TbCheck, TbX } from "tb-icons";
+import { TbCheck, TbPencil, TbX } from "tb-icons";
import { api, path } from "../../../utils/api.ts";
import type { FullScope } from "../../../utils/api_types.ts";
@@ -82,15 +82,15 @@ export function ScopeDescriptionForm(
{scope.value.description || No description provided.}
-
+
);
}
From 0ea05f504b542bc4835b12c70a736e7a7397f2b4 Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Fri, 2 May 2025 18:51:40 +0200
Subject: [PATCH 05/11] fix: license
---
frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
index 4bf6b71ee..9e7ed4cda 100644
--- a/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
+++ b/frontend/routes/@[scope]/(_islands)/ScopeDescriptionForm.tsx
@@ -1,3 +1,4 @@
+// Copyright 2024 the JSR authors. All rights reserved. MIT license.
import { useSignal } from "@preact/signals";
import { useState } from "preact/hooks";
import { TbCheck, TbPencil, TbX } from "tb-icons";
From 8d298fe99b551c0f7eeeb20c8c314099be9a9928 Mon Sep 17 00:00:00 2001
From: Augustin Mauroy <97875033+AugustinMauroy@users.noreply.github.com>
Date: Sat, 3 May 2025 14:53:10 +0200
Subject: [PATCH 06/11] update from feedback
---
...8fff256a3e5a07e39e5f085f17a4be108717.json} | 8 +-
...8dfe51e9edc309c346baaea94470cace57af.json} | 8 +-
...1393155d5b4efa8c953c64b6a323a660c51b.json} | 8 +-
...a70f27bdc3fd4e9334032d61ab85b72768a6.json} | 8 +-
...dfd4b84fd990ac8f1f558057212427383aab.json} | 8 +-
...0ce70d75216e6252b4ceebc75c0c6d542afb.json} | 8 +-
...aef03f54e1b6984b94c97cd337389be406f3.json} | 8 +-
...d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json} | 8 +-
...502114042_adding_description_to_scrope.sql | 2 +-
api/src/api/admin.rs | 19 +-
api/src/api/package.rs | 9 +-
api/src/api/scope.rs | 218 +++++++++++++++---
api/src/api/types.rs | 8 +-
api/src/db/database.rs | 23 +-
api/src/db/models.rs | 3 +-
api/src/db/tests.rs | 47 +++-
api/src/ids.rs | 120 ++++++++++
api/src/tasks.rs | 24 +-
api/src/util.rs | 13 +-
frontend/islands/new.tsx | 49 ++--
.../(_islands)/ScopeDescriptionForm.tsx | 11 +
frontend/utils/ids.ts | 42 ++++
22 files changed, 516 insertions(+), 136 deletions(-)
rename api/.sqlx/{query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json => query-01ca44880c8b3e17c17ba86868f98fff256a3e5a07e39e5f085f17a4be108717.json} (80%)
rename api/.sqlx/{query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json => query-0ddb2cf66ee7e7d2c7341713b39b8dfe51e9edc309c346baaea94470cace57af.json} (74%)
rename api/.sqlx/{query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json => query-103d72977104cf3702fcaa8ea92f1393155d5b4efa8c953c64b6a323a660c51b.json} (69%)
rename api/.sqlx/{query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json => query-17a9974ea1d81a38a5ab39b4ad95a70f27bdc3fd4e9334032d61ab85b72768a6.json} (75%)
rename api/.sqlx/{query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json => query-a83536c60d9f16008602be1f0111dfd4b84fd990ac8f1f558057212427383aab.json} (75%)
rename api/.sqlx/{query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json => query-d88d885e4a737dbe4602a46b83cf0ce70d75216e6252b4ceebc75c0c6d542afb.json} (75%)
rename api/.sqlx/{query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json => query-e5ed4e2eecd3d05da017201d5450aef03f54e1b6984b94c97cd337389be406f3.json} (75%)
rename api/.sqlx/{query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json => query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json} (69%)
create mode 100644 frontend/utils/ids.ts
diff --git a/api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json b/api/.sqlx/query-01ca44880c8b3e17c17ba86868f98fff256a3e5a07e39e5f085f17a4be108717.json
similarity index 80%
rename from api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json
rename to api/.sqlx/query-01ca44880c8b3e17c17ba86868f98fff256a3e5a07e39e5f085f17a4be108717.json
index 35cd5f2dd..11ee8dd6a 100644
--- a/api/.sqlx/query-95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e.json
+++ b/api/.sqlx/query-01ca44880c8b3e17c17ba86868f98fff256a3e5a07e39e5f085f17a4be108717.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n WITH ins_scope AS (\n INSERT INTO scopes (scope, creator, description) VALUES ($1, $2, $3)\n RETURNING\n scope,\n description,\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 description,\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 ",
+ "query": "\n WITH ins_scope AS (\n INSERT INTO scopes (scope, creator, description) VALUES ($1, $2, $3)\n RETURNING\n scope,\n description,\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 description as \"description: ScopeDescription\",\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": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -63,7 +63,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -74,5 +74,5 @@
false
]
},
- "hash": "95493f168335a0b106f222e75c891c2542daf46dca9e057d4ba487477f0c888e"
+ "hash": "01ca44880c8b3e17c17ba86868f98fff256a3e5a07e39e5f085f17a4be108717"
}
diff --git a/api/.sqlx/query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json b/api/.sqlx/query-0ddb2cf66ee7e7d2c7341713b39b8dfe51e9edc309c346baaea94470cace57af.json
similarity index 74%
rename from api/.sqlx/query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json
rename to api/.sqlx/query-0ddb2cf66ee7e7d2c7341713b39b8dfe51e9edc309c346baaea94470cace57af.json
index e5e36fe11..902544274 100644
--- a/api/.sqlx/query-7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920.json
+++ b/api/.sqlx/query-0ddb2cf66ee7e7d2c7341713b39b8dfe51e9edc309c346baaea94470cace57af.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "SELECT\n scope as \"scope: ScopeName\",\n description,\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 scopes WHERE creator = $1\n ORDER BY scope ASC",
+ "query": "SELECT\n scope as \"scope: ScopeName\",\n description as \"description: ScopeDescription\",\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 scopes WHERE creator = $1\n ORDER BY scope ASC",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -61,7 +61,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -72,5 +72,5 @@
false
]
},
- "hash": "7d3a8329590b30d813f2fdc0d2476bfe60b2721c76ccc9764d5b725198bfd920"
+ "hash": "0ddb2cf66ee7e7d2c7341713b39b8dfe51e9edc309c346baaea94470cace57af"
}
diff --git a/api/.sqlx/query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json b/api/.sqlx/query-103d72977104cf3702fcaa8ea92f1393155d5b4efa8c953c64b6a323a660c51b.json
similarity index 69%
rename from api/.sqlx/query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json
rename to api/.sqlx/query-103d72977104cf3702fcaa8ea92f1393155d5b4efa8c953c64b6a323a660c51b.json
index b185e1bbf..2d3ecd6de 100644
--- a/api/.sqlx/query-7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab.json
+++ b/api/.sqlx/query-103d72977104cf3702fcaa8ea92f1393155d5b4efa8c953c64b6a323a660c51b.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n WITH usage AS (\n SELECT\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1) AS package,\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1 AND created_at > now() - '1 week'::interval) AS new_package_per_week,\n (SELECT COUNT(created_at) FROM publishing_tasks WHERE package_scope = $1 AND created_at > now() - '1 week'::interval) AS publish_attempts_per_week\n )\n SELECT\n scopes.scope as \"scope_scope: ScopeName\",\n scopes.description as \"scope_description\",\n scopes.creator as \"scope_creator\",\n scopes.package_limit as \"scope_package_limit\",\n scopes.new_package_per_week_limit as \"scope_new_package_per_week_limit\",\n scopes.publish_attempts_per_week_limit as \"scope_publish_attempts_per_week_limit\",\n scopes.verify_oidc_actor as \"scope_verify_oidc_actor\",\n scopes.require_publishing_from_ci as \"scope_require_publishing_from_ci\",\n scopes.updated_at as \"scope_updated_at\",\n scopes.created_at as \"scope_created_at\",\n users.id as \"user_id\", users.name as \"user_name\", users.avatar_url as \"user_avatar_url\", users.github_id as \"user_github_id\", users.updated_at as \"user_updated_at\", users.created_at as \"user_created_at\",\n usage.package as \"usage_package\", usage.new_package_per_week as \"usage_new_package_per_week\", usage.publish_attempts_per_week as \"usage_publish_attempts_per_week\"\n FROM scopes\n LEFT JOIN users ON scopes.creator = users.id\n CROSS JOIN usage\n WHERE scopes.scope = $1\n ",
+ "query": "\n WITH usage AS (\n SELECT\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1) AS package,\n (SELECT COUNT(created_at) FROM packages WHERE scope = $1 AND created_at > now() - '1 week'::interval) AS new_package_per_week,\n (SELECT COUNT(created_at) FROM publishing_tasks WHERE package_scope = $1 AND created_at > now() - '1 week'::interval) AS publish_attempts_per_week\n )\n SELECT\n scopes.scope as \"scope_scope: ScopeName\",\n scopes.description as \"scope_description: ScopeDescription\",\n scopes.creator as \"scope_creator\",\n scopes.package_limit as \"scope_package_limit\",\n scopes.new_package_per_week_limit as \"scope_new_package_per_week_limit\",\n scopes.publish_attempts_per_week_limit as \"scope_publish_attempts_per_week_limit\",\n scopes.verify_oidc_actor as \"scope_verify_oidc_actor\",\n scopes.require_publishing_from_ci as \"scope_require_publishing_from_ci\",\n scopes.updated_at as \"scope_updated_at\",\n scopes.created_at as \"scope_created_at\",\n users.id as \"user_id\", users.name as \"user_name\", users.avatar_url as \"user_avatar_url\", users.github_id as \"user_github_id\", users.updated_at as \"user_updated_at\", users.created_at as \"user_created_at\",\n usage.package as \"usage_package\", usage.new_package_per_week as \"usage_new_package_per_week\", usage.publish_attempts_per_week as \"usage_publish_attempts_per_week\"\n FROM scopes\n LEFT JOIN users ON scopes.creator = users.id\n CROSS JOIN usage\n WHERE scopes.scope = $1\n ",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "scope_description",
+ "name": "scope_description: ScopeDescription",
"type_info": "Text"
},
{
@@ -106,7 +106,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -126,5 +126,5 @@
null
]
},
- "hash": "7ebcc680dbab8fe731e35e03719465f81288607e86b0882cda2a101519c187ab"
+ "hash": "103d72977104cf3702fcaa8ea92f1393155d5b4efa8c953c64b6a323a660c51b"
}
diff --git a/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json b/api/.sqlx/query-17a9974ea1d81a38a5ab39b4ad95a70f27bdc3fd4e9334032d61ab85b72768a6.json
similarity index 75%
rename from api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
rename to api/.sqlx/query-17a9974ea1d81a38a5ab39b4ad95a70f27bdc3fd4e9334032d61ab85b72768a6.json
index dcf395524..9df0ae8f4 100644
--- a/api/.sqlx/query-a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450.json
+++ b/api/.sqlx/query-17a9974ea1d81a38a5ab39b4ad95a70f27bdc3fd4e9334032d61ab85b72768a6.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "SELECT\n scope as \"scope: ScopeName\",\n description,\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 scopes WHERE scope = $1",
+ "query": "SELECT\n scope as \"scope: ScopeName\",\n description as \"description: ScopeDescription\",\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 scopes WHERE scope = $1",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -61,7 +61,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -72,5 +72,5 @@
false
]
},
- "hash": "a6b80b7702715b4fd844dd9858ad49c067bdd1f33166522f80d4c161d33a1450"
+ "hash": "17a9974ea1d81a38a5ab39b4ad95a70f27bdc3fd4e9334032d61ab85b72768a6"
}
diff --git a/api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json b/api/.sqlx/query-a83536c60d9f16008602be1f0111dfd4b84fd990ac8f1f558057212427383aab.json
similarity index 75%
rename from api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json
rename to api/.sqlx/query-a83536c60d9f16008602be1f0111dfd4b84fd990ac8f1f558057212427383aab.json
index 13422f2e2..d60a587b5 100644
--- a/api/.sqlx/query-072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3.json
+++ b/api/.sqlx/query-a83536c60d9f16008602be1f0111dfd4b84fd990ac8f1f558057212427383aab.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n UPDATE scopes SET description = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description,\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 ",
+ "query": "\n UPDATE scopes SET description = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description as \"description: ScopeDescription\",\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 ",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -62,7 +62,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -73,5 +73,5 @@
false
]
},
- "hash": "072f758accf1076a6746ccf46b83ad006fa930dc0889dfd841e51f8568a1bca3"
+ "hash": "a83536c60d9f16008602be1f0111dfd4b84fd990ac8f1f558057212427383aab"
}
diff --git a/api/.sqlx/query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json b/api/.sqlx/query-d88d885e4a737dbe4602a46b83cf0ce70d75216e6252b4ceebc75c0c6d542afb.json
similarity index 75%
rename from api/.sqlx/query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json
rename to api/.sqlx/query-d88d885e4a737dbe4602a46b83cf0ce70d75216e6252b4ceebc75c0c6d542afb.json
index a45ec64ca..1e53e8624 100644
--- a/api/.sqlx/query-be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138.json
+++ b/api/.sqlx/query-d88d885e4a737dbe4602a46b83cf0ce70d75216e6252b4ceebc75c0c6d542afb.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n UPDATE scopes SET require_publishing_from_ci = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description,\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 ",
+ "query": "\n UPDATE scopes SET require_publishing_from_ci = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description as \"description: ScopeDescription\",\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 ",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -62,7 +62,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -73,5 +73,5 @@
false
]
},
- "hash": "be0c572fe2c3a99aa3bfa208ab767b71b180ff3d9a76bcf030e258b310b2e138"
+ "hash": "d88d885e4a737dbe4602a46b83cf0ce70d75216e6252b4ceebc75c0c6d542afb"
}
diff --git a/api/.sqlx/query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json b/api/.sqlx/query-e5ed4e2eecd3d05da017201d5450aef03f54e1b6984b94c97cd337389be406f3.json
similarity index 75%
rename from api/.sqlx/query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json
rename to api/.sqlx/query-e5ed4e2eecd3d05da017201d5450aef03f54e1b6984b94c97cd337389be406f3.json
index 02424a786..1e8c2f3eb 100644
--- a/api/.sqlx/query-f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa.json
+++ b/api/.sqlx/query-e5ed4e2eecd3d05da017201d5450aef03f54e1b6984b94c97cd337389be406f3.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "\n UPDATE scopes SET verify_oidc_actor = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description,\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 ",
+ "query": "\n UPDATE scopes SET verify_oidc_actor = $1 WHERE scope = $2\n RETURNING\n scope as \"scope: ScopeName\",\n description as \"description: ScopeDescription\",\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 ",
"describe": {
"columns": [
{
@@ -10,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -62,7 +62,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -73,5 +73,5 @@
false
]
},
- "hash": "f1c3032cde5445d62fbaf598ab0f9884486cdec1a48068a4ed6fcbebd708e9fa"
+ "hash": "e5ed4e2eecd3d05da017201d5450aef03f54e1b6984b94c97cd337389be406f3"
}
diff --git a/api/.sqlx/query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json b/api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json
similarity index 69%
rename from api/.sqlx/query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json
rename to api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json
index 478aec851..077446c45 100644
--- a/api/.sqlx/query-f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814.json
+++ b/api/.sqlx/query-fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c.json
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
- "query": "SELECT\n scopes.scope as \"scope: ScopeName\",\n scopes.description,\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,7 +10,7 @@
},
{
"ordinal": 1,
- "name": "description",
+ "name": "description: ScopeDescription",
"type_info": "Text"
},
{
@@ -61,7 +61,7 @@
},
"nullable": [
false,
- true,
+ false,
false,
false,
false,
@@ -72,5 +72,5 @@
false
]
},
- "hash": "f109dc5f436100132ef1b331e8cf429a7ef74e0bf9cc129e0b0231ba76c92814"
+ "hash": "fff5990a48eda487a16c71fb6454d5c2b983a82f4c5c5eccb92e1ecc1dfe063c"
}
diff --git a/api/migrations/20250502114042_adding_description_to_scrope.sql b/api/migrations/20250502114042_adding_description_to_scrope.sql
index 1adc7f86e..a6139dd13 100644
--- a/api/migrations/20250502114042_adding_description_to_scrope.sql
+++ b/api/migrations/20250502114042_adding_description_to_scrope.sql
@@ -1 +1 @@
-ALTER TABLE scopes ADD COLUMN description TEXT;
+ALTER TABLE scopes ADD COLUMN description TEXT NOT NULL DEFAULT '';
diff --git a/api/src/api/admin.rs b/api/src/api/admin.rs
index a748917f2..caf001ea5 100644
--- a/api/src/api/admin.rs
+++ b/api/src/api/admin.rs
@@ -15,6 +15,7 @@ use tracing::Span;
use crate::db::*;
use crate::iam::ReqIamExt;
+use crate::ids::ScopeDescription;
use crate::publish::publish_task;
use crate::util;
use crate::util::decode_json;
@@ -186,17 +187,9 @@ pub async fn patch_scopes(mut req: Request) -> ApiResult