Skip to content

bug: restoring an archived workspace does not restore publication state of files and fonts #373

Description

@evan-zhang11

Description

When a workspace is deleted (delete_workspace), the handler unpublishes all files and fonts:

  • Deletes rows from published_files
  • Sets files.is_public = FALSE
  • Sets fonts.is_public = FALSE, clears fonts.slug = NULL, fonts.published_at = NULL

However, when a workspace is restored (restore_workspace), only the workspaces table is updated (deleted_at = NULL, new name/slug). The publication state of files and fonts is not restored. All public URLs (slugs) are permanently lost.

Location

backend/src/workspace_handlers.rs:

delete_workspace (lines ~640-680):

conn.execute("DELETE FROM published_files WHERE file_id IN (SELECT id FROM files WHERE workspace_id = ?)", ...)?;
conn.execute("UPDATE files SET is_public = FALSE WHERE workspace_id = ?", ...)?;
conn.execute("UPDATE fonts SET is_public = FALSE, slug = NULL, published_at = NULL WHERE workspace_id = ?", ...)?;

restore_workspace (lines ~730-760):

// Only updates workspaces table — does NOT undo any of the above
conn.execute("UPDATE workspaces SET name = ?, slug = ?, deleted_at = NULL WHERE id = ?", ...)?;

Impact

Data loss (Medium-High): After restoring a workspace:

  • All previously published files have lost their public slugs — old URLs return 404 permanently
  • All previously published fonts have lost their public slugs
  • Users must manually re-publish every file and font after a restore
  • The published_files entries are gone, so there is no way to recover the original slugs

This is particularly painful because workspace deletion is designed to be reversible (soft delete + restore), but the reversal is incomplete.

Suggested Fix

Option A: Soft-delete publications instead of hard-deleting

During delete_workspace, don't delete published_files rows or null out slugs. Instead, rely on the workspace's deleted_at to gate access. Public endpoints already check w.deleted_at IS NULL, so the data would be automatically hidden while archived and restored on un-archive.

Option B: Backup and restore publication state

During deletion, back up publication data (as done for workspace members). During restore, re-insert the backed-up data.

Option C (minimal): Document the limitation

If this is intentional, add a clear warning in the API response when restoring: "Workspace restored, but all file and font publications have been removed. Please re-publish them."

Recommendation: Option A is cleanest. The public tile endpoints already filter on deleted_at IS NULL, so soft-deleting publications is unnecessary if we just keep the rows in place.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions