The unit field had no edit path under the redesign (only name + qty
remain in the row; the double-tap overlay is name-only). Users can encode
the unit inside the name when it matters — e.g. "Milk 1L", "Eggs 1 doz".
Changes
supabase/migrations/011_drop_shopping_items_unit.sql — DROP COLUMN
supabase/seed.sql — unit values folded into names where relevant
supabase/tests/002_item_frequency_trigger.sql — remove unit from INSERT
packages/types — remove unit from ShoppingItem Row/Insert/Update
apps/web/src/lib/stores/lists.ts — addItem/updateItem signatures
apps/web/src/routes/(app)/lists/[id]/+page.svelte — purge newUnit /
editUnit state + inputs + display
apps/web/src/routes/(app)/lists/[id]/session/+page.svelte — simplify
quantity-only render
apps/web/messages/{en,es}.json — remove list_unit_label
Verification
just test-db → 34 pgTAP green
just test-integration → 140 + 2 skipped
just test-unit → 11 green
just test-e2e → 39 + 2 skipped
The generated search tsvector on shopping_items.search already indexes
only `name`, so full-text search coverage is unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
83 lines
2.9 KiB
PL/PgSQL
83 lines
2.9 KiB
PL/PgSQL
-- pgTAP: fn_record_item_frequency trigger — D/E-series
|
|
-- Verifies the SECURITY DEFINER trigger populates item_frequency correctly.
|
|
-- Run with: psql -U postgres -d postgres -f supabase/tests/002_item_frequency_trigger.sql
|
|
|
|
CREATE EXTENSION IF NOT EXISTS pgtap;
|
|
|
|
-- Note: tests E-02/E-03/E-04 (RLS rejection of direct writes) are covered by
|
|
-- the Vitest integration suite (packages/test-utils/tests/rls-frequency.test.ts)
|
|
-- which connects as an authenticated role. The postgres superuser bypasses RLS
|
|
-- entirely, so pgTAP cannot assert those policies here.
|
|
|
|
BEGIN;
|
|
SELECT plan(3);
|
|
|
|
-- Setup: temporary list for item insertion
|
|
INSERT INTO public.shopping_lists (id, collective_id, name, status, created_by)
|
|
VALUES (
|
|
'cccccccc-cccc-cccc-cccc-cccccccccccc',
|
|
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
|
'Trigger test list',
|
|
'active',
|
|
'11111111-1111-1111-1111-111111111111'
|
|
) ON CONFLICT (id) DO NOTHING;
|
|
|
|
-- D-13: Inserting an item creates a new frequency row (normalized name)
|
|
INSERT INTO public.shopping_items (list_id, name, quantity, sort_order, created_by)
|
|
VALUES ('cccccccc-cccc-cccc-cccc-cccccccccccc', ' Butter ', 1, 50, '11111111-1111-1111-1111-111111111111');
|
|
|
|
SELECT ok(
|
|
EXISTS (
|
|
SELECT 1 FROM public.item_frequency
|
|
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
|
AND name = 'butter'
|
|
),
|
|
'D-13: trigger normalises name (lower+trim) and inserts into item_frequency'
|
|
);
|
|
|
|
-- D-14: Inserting the same item again increments use_count
|
|
DO $$
|
|
DECLARE v_count_before integer;
|
|
BEGIN
|
|
SELECT use_count INTO v_count_before
|
|
FROM public.item_frequency
|
|
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
|
AND name = 'butter';
|
|
|
|
INSERT INTO public.shopping_items (list_id, name, sort_order, created_by)
|
|
VALUES ('cccccccc-cccc-cccc-cccc-cccccccccccc', 'Butter', 51, '11111111-1111-1111-1111-111111111111');
|
|
END $$;
|
|
|
|
SELECT ok(
|
|
(SELECT use_count FROM public.item_frequency
|
|
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
|
AND name = 'butter') >= 2,
|
|
'D-14: use_count increments on repeated INSERT'
|
|
);
|
|
|
|
-- D-15: Trigger does not fire on UPDATE (only on INSERT)
|
|
-- (PostgreSQL does not allow LIMIT on UPDATE — use a ctid subquery instead.)
|
|
DO $$
|
|
BEGIN
|
|
UPDATE public.shopping_items
|
|
SET name = 'Butter'
|
|
WHERE ctid = (
|
|
SELECT ctid FROM public.shopping_items
|
|
WHERE list_id = 'cccccccc-cccc-cccc-cccc-cccccccccccc'
|
|
AND name = 'Butter'
|
|
LIMIT 1
|
|
);
|
|
END $$;
|
|
|
|
-- We can't easily compare before/after in a single statement in pgTAP without
|
|
-- a custom helper. Instead just verify the count is still reasonable (> 0).
|
|
SELECT ok(
|
|
(SELECT use_count FROM public.item_frequency
|
|
WHERE collective_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
|
AND name = 'butter') > 0,
|
|
'D-15: item_frequency still intact after item UPDATE'
|
|
);
|
|
|
|
SELECT * FROM finish();
|
|
ROLLBACK;
|