MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-83

2.2.9 Restore default workflow — re-add missing default statuses + transitions

Done
Description

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.

Acceptance criteria

  • 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).
  • Initial-status rule: if the project has no initial status, restore makes 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).
  • A custom status the admin added survives the restore unchanged; a renamed default (e.g. "In Review" → "QA") is matched by key and NOT reverted.
  • UI: admin-only "Restore defaults" button + confirm modal + success toast + revalidate; non-admins don't see it and a direct Server-Action call is rejected server-side.
  • Vitest (real Postgres): delete 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.
  • Quality gates green (tsc + eslint + prettier + vitest).

Context refs

  • lib/workflows/defaultWorkflow.ts (2.2.2) — DEFAULT_STATUSES / DEFAULT_TRANSITIONS source of truth
  • lib/services/workflowsService.ts (2.2.2/2.2.5) — seedDefaultWorkflow / createStatus / assertProjectAdmin / the repo write methods to reuse
  • app/(authed)/settings/project/workflow/ (2.2.5) — the settings UI + Server Actions to extend
  • lib/workItems/positioning.tskeyForAppend for the re-added statuses' positions