summaryrefslogtreecommitdiff
path: root/migrations
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-09-20 07:47:48 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-09-20 07:47:48 +0000
commitc5ab2f9a7f6a0b1e456e13934268d1509504c55a (patch)
treebc1e74b6b07341246aaa71ee498b6c3513e2231d /migrations
parentb970be11ee895c34e019231022e9e5244e4aec2f (diff)
Drop Trello as a shopping source, importing the two groups worth keeping
The Trello "Shopping" board had become a dumping ground: of 24 cards, 13 had no list at all (rendering as "Uncategorized"), and the rest were spread across Costco, Hardware Store, "Perennial " (trailing space, so a separate store from "Perennial") and online. Its items were read-only in doot — no rename, no move, no delete, only hide — and its list names were doubling as an accidental store registry, which is the only reason stores like Hardware Store existed at all. Migration 032 imports the two groups asked for, Hardware Store and the unlisted cards, into user_shopping_items. Costco, Perennial and online cards are left behind. Nothing is destroyed: the cards remain in Trello, this only stops doot displaying them. Imported rows become ordinary user items, so they also become editable, which Trello-sourced items never were. Trello remains the source for the other eight boards; this is only the Shopping board feeding the shopping list. Also updated the quick-action modal's Shopping tab, which posted source=trello with a Trello list_id. Left alone it would have kept creating cards that no longer appear anywhere. It now posts source=shopping with a store name, handled by a new case in HandleUnifiedAdd, and its picker reads from a new /partials/shopping-stores endpoint. The Trello-lists endpoint it used to call is deleted along with its route. Note for the edit feature still to come: stores have no existence independent of items, so a store with nothing in it cannot be chosen. That was previously masked by Trello's lists persisting. "Move between stores and sections" needs a real stores/sections table. Migration tested against a seeded snapshot of the real board, including the trailing-space store name, other boards, replay safety and the empty-cache no-op. Two existing tests asserting Trello check-state in shopping mode were updated to plantoeat, the only remaining external source. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'migrations')
-rw-r--r--migrations/032_import_trello_shopping_items.sql46
-rw-r--r--migrations/README.md3
2 files changed, 48 insertions, 1 deletions
diff --git a/migrations/032_import_trello_shopping_items.sql b/migrations/032_import_trello_shopping_items.sql
new file mode 100644
index 0000000..a12a675
--- /dev/null
+++ b/migrations/032_import_trello_shopping_items.sql
@@ -0,0 +1,46 @@
+-- One-time import of Trello Shopping-board cards into user shopping items,
+-- ahead of removing the Trello source from the shopping list entirely.
+--
+-- The Trello "Shopping" board had become a dumping ground: of its 24 cards, 13
+-- had no list at all (rendering as "Uncategorized") and the rest were spread
+-- over Costco, Hardware Store, "Perennial " (note the trailing space, which
+-- made it a separate store from "Perennial") and online.
+--
+-- Only the two groups worth keeping are imported: Hardware Store, and the
+-- unlisted cards. Costco, Perennial and online cards are deliberately left
+-- behind — they stop appearing once the Trello source is removed. Nothing is
+-- destroyed by that: the cards remain in Trello, this only stops doot
+-- displaying them.
+--
+-- Imported rows become ordinary user items, which means they also become fully
+-- editable (rename, move store, delete) — Trello-sourced items never were.
+--
+-- Reads from the local `cards` cache rather than the Trello API. On any
+-- database where that cache is empty (a fresh dev DB, a restore predating a
+-- sync) this is simply a no-op, which is the correct outcome there.
+
+INSERT INTO user_shopping_items (name, store)
+SELECT
+ c.name,
+ CASE
+ WHEN TRIM(COALESCE(c.list_name, '')) = '' THEN 'Uncategorized'
+ ELSE TRIM(c.list_name)
+ END AS store_name
+FROM cards c
+JOIN boards b ON c.board_id = b.id
+WHERE LOWER(b.name) = 'shopping'
+ AND (
+ TRIM(COALESCE(c.list_name, '')) = ''
+ OR LOWER(TRIM(c.list_name)) = 'hardware store'
+ )
+ -- Guard against creating a duplicate of something already added by hand.
+ -- Migrations are tracked by filename so this runs once, but the guard makes
+ -- the statement safe to replay against a partially-imported database.
+ AND NOT EXISTS (
+ SELECT 1 FROM user_shopping_items u
+ WHERE u.name = c.name
+ AND u.store = CASE
+ WHEN TRIM(COALESCE(c.list_name, '')) = '' THEN 'Uncategorized'
+ ELSE TRIM(c.list_name)
+ END
+ );
diff --git a/migrations/README.md b/migrations/README.md
index e849b9c..a98efa2 100644
--- a/migrations/README.md
+++ b/migrations/README.md
@@ -27,10 +27,11 @@ Migration 007 was reserved during development but never implemented. The gap is
## Running Migrations
Migrations are applied automatically on application startup via `store.RunMigrations()`. The `schema_migrations` table tracks which migrations have been applied.
+| 032 | `032_import_trello_shopping_items.sql` | One-time import of Trello Shopping-board cards (Hardware Store + unlisted) into user items, ahead of removing Trello as a shopping source |
## Creating New Migrations
-1. Create file: `migrations/NNN_description.sql` (next number is 014)
+1. Create file: `migrations/NNN_description.sql` (next number is 033)
2. Write idempotent SQL (use `IF NOT EXISTS` where possible)
3. Test locally: `go run cmd/dashboard/main.go`
4. Verify: Check `schema_migrations` table for new entry