Estimate: 16m · Depends on: 2.2.5
After an admin edits a workflow (deletes statuses, removes transitions, renames things), they need a way to get the defaults back without recreating each one by hand. Add a "Restore defaults" capability that re-adds any missing default statuses and transitions from 2.2.2's DEFAULT_STATUSES / DEFAULT_TRANSITIONS.
Durable shape — ADDITIVE merge, never destructive. Restoring defaults re-adds the six default statuses (matched by key) that are missing and the default transitions whose endpoints now exist — but it NEVER deletes a custom status the admin added, never removes their custom transitions, and never overwrites a renamed default's label/color. It is idempotent: on a pristine default-seeded project it's a no-op; running it twice changes nothing the second time. A separate destructive "reset to factory" (wipe + reseed) is explicitly OUT of scope here — flagged as a possible follow-up if the user wants it, but additive-restore is the safe default.
workflowsService.restoreDefaultWorkflow({ userId, workspaceId, projectId }) — admin-gated (same assertProjectAdmin as 2.2.5). In one transaction: read the project's current statuses + transitions; for each default status whose key is absent, insert it (appended position via the fractional-index helper, category/label from the default; isInitial only if the project currently has NO initial status — otherwise leave the existing initial untouched); then for each default transition pair whose both endpoints now exist, insert it if absent (idempotent on the 2.2.1 unique constraint).
UI: a "Restore defaults" button in the workflow-settings header (admin-only), behind a confirm modal that states it re-adds the standard statuses & transitions and does NOT remove customizations. Optimistic + toast, same pattern as 2.2.5.
workflowsService.restoreDefaultWorkflow re-adds missing default statuses (by key) + missing default transitions; idempotent (a second call is a no-op); never deletes or duplicates rows; admin-gated (NotProjectAdminError for a non-owner).todo initial; if it already has one (even a custom status), the existing initial is left untouched (the partial-unique index from 2.2.1 is never violated).in_review + cancelled and a transition, add a custom on_hold status, run restore → the two defaults + their transitions return, on_hold stays, no dupes; a second restore call is a no-op.lib/workflows/defaultWorkflow.ts (2.2.2) — DEFAULT_STATUSES / DEFAULT_TRANSITIONS source of truthlib/services/workflowsService.ts (2.2.2/2.2.5) — seedDefaultWorkflow / createStatus / assertProjectAdmin / the repo write methods to reuseapp/(authed)/settings/project/workflow/ (2.2.5) — the settings UI + Server Actions to extendlib/workItems/positioning.ts — keyForAppend for the re-added statuses' positions