refactor(drafts): type UserDraftOverlay.other_drafts_users in the OpenAPI

The backend response carried other_drafts_users on every get-by-path
that supports the draft overlay, but the OpenAPI schema didn't declare
the field. Each route had to cast the typed response to `any` to read
it (and the sibling draft_saved_at), which obscured the real shape from
the type system and rotted the discoverability of the draft surface.

Add it to UserDraftOverlay. Frontend casts collapse to plain property
reads in the three editor routes.
This commit is contained in:
Diego Imbert
2026-06-08 15:35:25 +02:00
parent 4f21fd871e
commit 4264c3d9a7
4 changed files with 25 additions and 6 deletions
+19
View File
@@ -21049,6 +21049,25 @@ components:
draft:
type: object
additionalProperties: true
other_drafts_users:
description: |
Other workspace users (and the legacy NULL-email row, if any)
with a saved draft at the same path. Populated only on the
authed user's "get by path" responses for kinds the editor
surfaces a fork banner for (script, flow, app, raw_app).
Empty / omitted for kinds without that UI.
type: array
items:
type: object
properties:
username:
type: string
email:
type: string
draft_saved_at:
type: string
format: date-time
required: [draft_saved_at]
required: [is_draft]
UserDraftItemKind:
type: string
@@ -100,11 +100,11 @@
getDraft
})
if (tok !== loadAppToken) return
otherDraftsUsers = ((backendApp as any).other_drafts_users ?? []) as OtherDraftUser[]
otherDraftsUsers = (backendApp.other_drafts_users ?? []) as OtherDraftUser[]
if ($workspaceStore && path) {
UserDraftDbSyncer.recordRemoteSync(
{ workspace: $workspaceStore, itemKind: 'app', path },
(backendApp as any).draft_saved_at as string | undefined
backendApp.draft_saved_at
)
}
// Apply the user's saved draft to `.value`. The autosave for apps
@@ -203,11 +203,11 @@
getDraft
})
if (tok !== loadFlowToken) return
otherDraftsUsers = ((backendFlow as any).other_drafts_users ?? []) as OtherDraftUser[]
otherDraftsUsers = (backendFlow.other_drafts_users ?? []) as OtherDraftUser[]
if ($workspaceStore && flowDraftPath) {
UserDraftDbSyncer.recordRemoteSync(
{ workspace: $workspaceStore, itemKind: 'flow', path: flowDraftPath },
(backendFlow as any).draft_saved_at as string | undefined
backendFlow.draft_saved_at
)
}
// Re-evaluate the "new flow" signal on each load — flips to
@@ -148,7 +148,7 @@
getDraft
})
if (tok !== loadScriptToken) return
otherDraftsUsers = ((backendScript as any).other_drafts_users ?? []) as OtherDraftUser[]
otherDraftsUsers = (backendScript.other_drafts_users ?? []) as OtherDraftUser[]
// Seed the per-tab `last_sync` map with the server's draft
// timestamp so the next autosave attaches a matching
// `last_sync` and the backend can reject stale writes.
@@ -157,7 +157,7 @@
if ($workspaceStore && page.params.path) {
UserDraftDbSyncer.recordRemoteSync(
{ workspace: $workspaceStore, itemKind: 'script', path: page.params.path },
(backendScript as any).draft_saved_at as string | undefined
backendScript.draft_saved_at
)
}
if (backendScript.is_draft) {