mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 08:01:25 +00:00
fix(drafts): deploy only wipes the deployer's draft, not everyone else's
Script / flow / app deploys ran an unconditional DELETE on every draft at the path, so a teammate's deploy silently destroyed any other user's pending draft. After the wipe, the other user's tab kept auto-saving — re-creating the row at a NOW timestamp newer than the deploy — and StaleDraftModal never fired because draft_saved_at had been bumped past the deploy. Filter the DELETE to email = deployer (plus the legacy NULL row), so other users' drafts persist and the stale-draft prompt actually fires on their next reload. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'flow' AND (email = $3 OR email IS NULL)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "3d7456e11d8686210169bfe26931f924bd4483c8f70095c05720bc4eb2d8df81"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'app' AND (email = $3 OR email IS NULL)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "8bba7bec4f5f09a90da3eecaab4cf4386eb97e4e00c7431ff2860b225d212780"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'script' AND (email = $3 OR email IS NULL)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text",
|
||||
"Text",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "c241ee7efe2cbb9024792f6dc67cde48c5517ab36acd543a1f0a6119c34ce453"
|
||||
}
|
||||
@@ -657,12 +657,17 @@ async fn create_flow(
|
||||
).execute(&mut *tx).await?;
|
||||
|
||||
// CLI / git-sync deploys ask us to preserve any existing user draft at this
|
||||
// path instead of wiping it as part of the deploy.
|
||||
// path instead of wiping it as part of the deploy. Only wipe the deployer's
|
||||
// own draft (plus the legacy NULL-email workspace draft) — other users'
|
||||
// drafts are independent and should fire the StaleDraftModal on their next
|
||||
// reload, not vanish silently.
|
||||
if !nf.skip_draft_deletion.unwrap_or(false) {
|
||||
sqlx::query!(
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'flow'",
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'flow' \
|
||||
AND (email = $3 OR email IS NULL)",
|
||||
nf.path,
|
||||
&w_id
|
||||
&w_id,
|
||||
&authed.email,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
@@ -1246,12 +1251,16 @@ async fn update_flow(
|
||||
}
|
||||
|
||||
// CLI / git-sync deploys ask us to preserve any existing user draft at this
|
||||
// path instead of wiping it as part of the deploy.
|
||||
// path instead of wiping it as part of the deploy. Only wipe the deployer's
|
||||
// own draft (plus the legacy NULL-email row) — other users' drafts surface
|
||||
// as stale on their next reload instead of disappearing silently.
|
||||
if !nf.skip_draft_deletion.unwrap_or(false) {
|
||||
sqlx::query!(
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'flow'",
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'flow' \
|
||||
AND (email = $3 OR email IS NULL)",
|
||||
flow_path,
|
||||
&w_id
|
||||
&w_id,
|
||||
&authed.email,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
@@ -1353,10 +1353,18 @@ async fn create_script_internal<'c>(
|
||||
let p_path_opt = parent_hashes_and_perms.as_ref().map(|x| x.p_path.clone());
|
||||
if let Some(ref p_path) = p_path_opt {
|
||||
if !skip_draft_deletion {
|
||||
// Only wipe the deployer's own draft (plus the legacy
|
||||
// NULL-email workspace draft, if any). Other users' drafts
|
||||
// are independent — they should NOT vanish silently when a
|
||||
// teammate deploys. The home-page badge surfaces them, and
|
||||
// the StaleDraftModal fires on their next reload because
|
||||
// the draft now predates the new deploy.
|
||||
sqlx::query!(
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'script'",
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'script' \
|
||||
AND (email = $3 OR email IS NULL)",
|
||||
p_path,
|
||||
&w_id
|
||||
&w_id,
|
||||
&authed.email,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
@@ -1440,10 +1448,14 @@ async fn create_script_internal<'c>(
|
||||
}
|
||||
}
|
||||
} else if !skip_draft_deletion {
|
||||
// See the matching branch above — only wipe the deployer's own
|
||||
// draft (plus the legacy NULL-email row).
|
||||
sqlx::query!(
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'script'",
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'script' \
|
||||
AND (email = $3 OR email IS NULL)",
|
||||
ns.path,
|
||||
&w_id
|
||||
&w_id,
|
||||
&authed.email,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
@@ -1448,12 +1448,16 @@ async fn create_app_internal<'a>(
|
||||
}
|
||||
}
|
||||
// CLI / git-sync deploys ask us to preserve any existing user draft at this
|
||||
// path instead of wiping it as part of the deploy.
|
||||
// path instead of wiping it as part of the deploy. Only wipe the deployer's
|
||||
// own draft (plus the legacy NULL-email row) — other users' drafts surface
|
||||
// as stale on their next reload instead of disappearing silently.
|
||||
if !app.skip_draft_deletion.unwrap_or(false) {
|
||||
sqlx::query!(
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'app'",
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'app' \
|
||||
AND (email = $3 OR email IS NULL)",
|
||||
&app.path,
|
||||
&w_id
|
||||
&w_id,
|
||||
&authed.email,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
@@ -2057,12 +2061,15 @@ async fn update_app_internal<'a>(
|
||||
}
|
||||
};
|
||||
// CLI / git-sync deploys ask us to preserve any existing user draft at this
|
||||
// path instead of wiping it as part of the deploy.
|
||||
// path instead of wiping it as part of the deploy. Only wipe the deployer's
|
||||
// own draft (plus the legacy NULL-email row) — see create_app_internal.
|
||||
if !ns.skip_draft_deletion.unwrap_or(false) {
|
||||
sqlx::query!(
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'app'",
|
||||
"DELETE FROM draft WHERE path = $1 AND workspace_id = $2 AND typ = 'app' \
|
||||
AND (email = $3 OR email IS NULL)",
|
||||
path,
|
||||
&w_id
|
||||
&w_id,
|
||||
&authed.email,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
Reference in New Issue
Block a user