From 19c99157fec338460f8e7de4d067cc7c7a811a8a Mon Sep 17 00:00:00 2001 From: cavidelizade Date: Fri, 17 Jul 2026 00:00:36 +0400 Subject: [PATCH] fix(api): seed default Cancelled state in the "cancelled" group The default Cancelled state was seeded with the group "canceled" (one L) while the rest of the app matches on "cancelled" (two L). For every new project that made auto-close a silent no-op, kept cancelled issues out of auto-archive, and mis-bucketed them as backlog in cycle/module/epic progress, and it made cancelled issues read as open in open/closed filters. Fix the seed and add migration 000013 to correct existing rows. A test now asserts every default state uses a group in validStateGroups so this class of typo can't come back. Closes #333 Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/api/internal/service/state.go | 2 +- .../internal/service/state_default_test.go | 29 +++++++++++++++++++ .../000013_fix_cancelled_state_group.down.sql | 5 ++++ .../000013_fix_cancelled_state_group.up.sql | 6 ++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 apps/api/internal/service/state_default_test.go create mode 100644 apps/api/migrations/000013_fix_cancelled_state_group.down.sql create mode 100644 apps/api/migrations/000013_fix_cancelled_state_group.up.sql diff --git a/apps/api/internal/service/state.go b/apps/api/internal/service/state.go index 3543417..8bb19db 100644 --- a/apps/api/internal/service/state.go +++ b/apps/api/internal/service/state.go @@ -80,7 +80,7 @@ var defaultProjectStates = []struct { {name: "Todo", color: "#60646C", sequence: 25000, group: "unstarted"}, {name: "In Progress", color: "#F59E0B", sequence: 35000, group: "started"}, {name: "Done", color: "#46A758", sequence: 45000, group: "completed"}, - {name: "Cancelled", color: "#9AA4BC", sequence: 55000, group: "canceled"}, + {name: "Cancelled", color: "#9AA4BC", sequence: 55000, group: "cancelled"}, } func (s *StateService) ensureDefaultStates(ctx context.Context, projectID, workspaceID uuid.UUID) error { diff --git a/apps/api/internal/service/state_default_test.go b/apps/api/internal/service/state_default_test.go new file mode 100644 index 0000000..48b7549 --- /dev/null +++ b/apps/api/internal/service/state_default_test.go @@ -0,0 +1,29 @@ +package service + +import "testing" + +// Every seeded default state must use a group the app actually recognises. +// This guards against typos like "canceled" vs "cancelled", which silently +// broke auto-close, auto-archive and progress bucketing for every new project. +func TestDefaultProjectStatesUseValidGroups(t *testing.T) { + for _, st := range defaultProjectStates { + if !validStateGroups[st.group] { + t.Errorf("default state %q has group %q which is not in validStateGroups", st.name, st.group) + } + } + + // The Cancelled state specifically must be in the "cancelled" group so + // auto-close/archive and progress charts pick it up. + var found bool + for _, st := range defaultProjectStates { + if st.name == "Cancelled" { + found = true + if st.group != "cancelled" { + t.Errorf("Cancelled state group = %q; want \"cancelled\"", st.group) + } + } + } + if !found { + t.Fatal("no default Cancelled state found") + } +} diff --git a/apps/api/migrations/000013_fix_cancelled_state_group.down.sql b/apps/api/migrations/000013_fix_cancelled_state_group.down.sql new file mode 100644 index 0000000..be4945e --- /dev/null +++ b/apps/api/migrations/000013_fix_cancelled_state_group.down.sql @@ -0,0 +1,5 @@ +-- This migration fixes a typo in existing data. There is no safe way to +-- reverse it: we can't tell which "cancelled" rows were the mistyped default +-- versus states that were always spelled correctly, and reintroducing the typo +-- would just bring the bug back. Intentionally a no-op. +SELECT 1; diff --git a/apps/api/migrations/000013_fix_cancelled_state_group.up.sql b/apps/api/migrations/000013_fix_cancelled_state_group.up.sql new file mode 100644 index 0000000..e81db3d --- /dev/null +++ b/apps/api/migrations/000013_fix_cancelled_state_group.up.sql @@ -0,0 +1,6 @@ +-- Every project's default "Cancelled" state was seeded with the group +-- "canceled" (one L) while the rest of the app matches on "cancelled" (two L). +-- That mismatch made auto-close a no-op, kept cancelled issues out of +-- auto-archive, and mis-bucketed them as "backlog" in every progress chart. +-- Correct the existing rows so they line up with the seed fix. +UPDATE states SET "group" = 'cancelled' WHERE "group" = 'canceled';