Merge remote-tracking branch 'origin/main' into di/data-tables

This commit is contained in:
Diego Imbert
2025-12-03 10:40:42 +01:00
7 changed files with 102 additions and 66 deletions
@@ -1,24 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "SELECT flow.path FROM flow\n LEFT JOIN flow_version\n ON flow_version.path = flow.path AND flow_version.workspace_id = flow.workspace_id\n WHERE flow.path = $1 AND flow.workspace_id = $2 AND flow_version.id = $3",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "path",
"type_info": "Varchar"
}
],
"parameters": {
"Left": [
"Text",
"Text",
"Int8"
]
},
"nullable": [
false
]
},
"hash": "79464d5ef46a05ff9c05a4f1f4419ffac7e82c985d59a2e20e5c616461dbfe7b"
}
+1 -1
View File
@@ -1 +1 @@
5e950542fed5ce5d6154932b3bc6b2172cb32c73
5e950542fed5ce5d6154932b3bc6b2172cb32c73
+2 -4
View File
@@ -6796,7 +6796,7 @@ paths:
items:
type: string
/w/{workspace}/flows/get/v/{version}/p/{path}:
/w/{workspace}/flows/get/v/{version}:
get:
summary: get flow version
operationId: getFlowVersion
@@ -6807,7 +6807,6 @@ paths:
required: true
schema:
type: number
- $ref: "#/components/parameters/ScriptPath"
tags:
- flow
responses:
@@ -6818,7 +6817,7 @@ paths:
schema:
$ref: "#/components/schemas/Flow"
/w/{workspace}/flows/history_update/v/{version}/p/{path}:
/w/{workspace}/flows/history_update/v/{version}:
post:
summary: update flow history
operationId: updateFlowHistory
@@ -6829,7 +6828,6 @@ paths:
required: true
schema:
type: number
- $ref: "#/components/parameters/ScriptPath"
requestBody:
description: Flow deployment message
required: true
+89 -24
View File
@@ -69,10 +69,8 @@ pub fn workspaced_service() -> Router {
"/list_paths_from_workspace_runnable/:runnable_kind/*path",
get(list_paths_from_workspace_runnable),
)
.route(
"/history_update/v/:version/p/*path",
post(update_flow_history),
)
.route("/history_update/v/:version", post(update_flow_history))
.route("/get/v/:version", get(get_flow_version_by_id))
.route("/get/v/:version/p/*path", get(get_flow_version))
.route(
"/toggle_workspace_error_handler/*path",
@@ -709,6 +707,73 @@ async fn get_flow_version(
Ok(Json(flow))
}
async fn get_flow_version_by_id(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Path((w_id, version)): Path<(String, i64)>,
) -> JsonResult<Flow> {
let mut tx = user_db.begin(&authed).await?;
// First, fetch the path to perform authorization check early
let path: Option<String> = sqlx::query_scalar(
"SELECT path FROM flow_version WHERE id = $1 AND workspace_id = $2",
)
.bind(version)
.bind(&w_id)
.fetch_optional(&mut *tx)
.await?;
let path = not_found_if_none(
path,
"Flow version",
format!("{} in workspace {}", version, w_id),
)?;
// Perform authorization check before fetching full data
check_scopes(&authed, || format!("flows:read:{}", path))?;
// Now fetch the full flow data with INNER JOIN to ensure flow exists
let flow = sqlx::query_as::<_, Flow>(
"SELECT
flow.workspace_id,
flow.path,
flow.summary,
flow.description,
flow.archived,
flow.extra_perms,
flow.draft_only,
flow.dedicated_worker,
flow.tag,
flow.ws_error_handler_muted,
flow.timeout,
flow.visible_to_runner_only,
flow.on_behalf_of_email,
flow_version.schema,
flow_version.value,
flow_version.created_at as edited_at,
flow_version.created_by as edited_by
FROM flow
INNER JOIN flow_version
ON flow_version.path = flow.path
AND flow_version.workspace_id = flow.workspace_id
WHERE flow_version.id = $1 AND flow.workspace_id = $2",
)
.bind(version)
.bind(&w_id)
.fetch_optional(&mut *tx)
.await?;
tx.commit().await?;
let flow = not_found_if_none(
flow,
"Flow",
format!("for version {} (flow may have been deleted)", version),
)?;
Ok(Json(flow))
}
#[derive(Deserialize)]
pub struct FlowHistoryUpdate {
pub deployment_msg: String,
@@ -717,42 +782,42 @@ pub struct FlowHistoryUpdate {
async fn update_flow_history(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Path((w_id, version, path)): Path<(String, i64, StripPath)>,
Path((w_id, version)): Path<(String, i64)>,
Json(history_update): Json<FlowHistoryUpdate>,
) -> Result<()> {
let path = path.to_path();
check_scopes(&authed, || format!("flows:write:{}", path))?;
let mut tx = user_db.begin(&authed).await?;
let path_o = sqlx::query_scalar!(
"SELECT flow.path FROM flow
LEFT JOIN flow_version
ON flow_version.path = flow.path AND flow_version.workspace_id = flow.workspace_id
WHERE flow.path = $1 AND flow.workspace_id = $2 AND flow_version.id = $3",
path,
w_id,
version
// Fetch path and perform authorization check early
let path: Option<String> = sqlx::query_scalar(
"SELECT path FROM flow_version WHERE workspace_id = $1 AND id = $2",
)
.bind(&w_id)
.bind(version)
.fetch_optional(&mut *tx)
.await?;
if path_o.is_none() {
tx.commit().await?;
return Err(Error::NotFound(
format!("Flow version {version} for path {path} not found").to_string(),
));
}
let path = not_found_if_none(
path,
"Flow version",
format!("{} in workspace {}", version, w_id),
)?;
// Perform authorization check before any modifications
check_scopes(&authed, || format!("flows:write:{}", path))?;
// Insert or update deployment metadata
sqlx::query!(
"INSERT INTO deployment_metadata (workspace_id, path, flow_version, deployment_msg) VALUES ($1, $2, $3, $4) ON CONFLICT (workspace_id, path, flow_version) WHERE flow_version IS NOT NULL DO UPDATE SET deployment_msg = EXCLUDED.deployment_msg",
w_id,
path_o.unwrap(),
&w_id,
path,
version,
history_update.deployment_msg,
)
.fetch_optional(&mut *tx)
.await?;
tx.commit().await?;
return Ok(());
Ok(())
}
async fn update_flow(
Generated
+9 -9
View File
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1753694789,
"narHash": "sha256-cKgvtz6fKuK1Xr5LQW/zOUiAC0oSQoA9nOISB0pJZqM=",
"lastModified": 1764517877,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "dc9637876d0dcc8c9e5e22986b857632effeb727",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c",
"type": "github"
},
"original": {
@@ -35,11 +35,11 @@
},
"nixpkgs-claude": {
"locked": {
"lastModified": 1763421233,
"narHash": "sha256-Stk9ZYRkGrnnpyJ4eqt9eQtdFWRRIvMxpNRf4sIegnw=",
"lastModified": 1764517877,
"narHash": "sha256-pp3uT4hHijIC8JUK5MEqeAWmParJrgBVzHLNfJDZxg4=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648",
"rev": "2d293cbfa5a793b4c50d17c05ef9e385b90edf6c",
"type": "github"
},
"original": {
@@ -93,11 +93,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1753757591,
"narHash": "sha256-3okLvry8fRWZhJZP75pPC9P6U1dcu84VOCPhPLXYozI=",
"lastModified": 1764643237,
"narHash": "sha256-6Ezx9DqVv5UZ7DBK9rcNwBuQUENFyWPS7M09I+FvNao=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "b372cf71b4125d420d7648cbd898ab8f5c355be2",
"rev": "e66d6b924ac59e6c722f69332f6540ea57c69233",
"type": "github"
},
"original": {
@@ -29,8 +29,7 @@
async function loadFlow(version: number) {
selected = await FlowService.getFlowVersion({
workspace: $workspaceStore!,
version,
path
version
})
}
@@ -54,7 +53,6 @@
await FlowService.updateFlowHistory({
workspace: $workspaceStore!,
version,
path,
requestBody: {
deployment_msg: deploymentMsgUpdate!
}
@@ -113,7 +113,6 @@
if (templateId) {
template = await FlowService.getFlowVersion({
workspace: $workspaceStore!,
path: templatePath,
version: parseInt(templateId)
})
} else {