Files
spsays-bff/migrations/0062_feedback_categories.up.sql
Krispire AdminandClaude Opus 5.5 d76505772a Admin-managed feedback categories
Categories move from a hard-coded list to a feedback_categories table
(migration 0062), seeded with the four existing keys, labels and
descriptions so production feedback is untouched; any other key already in
use gets an archived category. Keys are fixed, so renames relabel past
feedback. Archive hides a category from the form; only unused categories
can be deleted. Submissions are validated against active categories, and
feedback responses carry category_label.

New: GET /feedback/categories (public); /admin/feedback/categories CRUD +
reorder behind the new feedback:categories permission (granted to Admin).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:47:09 +05:30

42 lines
2.2 KiB
SQL

-- Feedback categories, managed from the admin panel instead of hard-coded in
-- the app and the BFF.
--
-- `key` is what feedback.category stores, and never changes once created —
-- so renaming a category in the admin relabels every past submission too.
-- Archiving hides a category from the /feedback form while existing feedback
-- keeps its label. There is deliberately no foreign key from feedback: the
-- column predates this table, and the admin only hard-deletes categories
-- nothing uses.
CREATE TABLE IF NOT EXISTS feedback_categories (
key TEXT PRIMARY KEY,
label TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
sort_order INTEGER NOT NULL DEFAULT 0,
archived_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- The four categories the app offered until now, with the exact labels and
-- descriptions its form showed, in the form's order. Production feedback
-- already uses these keys, so they must stay byte-for-byte the same.
INSERT INTO feedback_categories (key, label, description, sort_order) VALUES
('general', 'General feedback', 'Thoughts, impressions, suggestions — anything else.', 0),
('bug', 'Bug report', 'Something is broken or behaving unexpectedly.', 1),
('feature', 'Feature request', 'An idea for something new on the site.', 2),
('other', 'Other', 'Doesn''t fit the above? Use this.', 3)
ON CONFLICT (key) DO NOTHING;
-- Safety net: any other key already present in feedback (from an older
-- client) gets a category too — archived, so it isn't offered on the form,
-- but its submissions still carry a readable label.
INSERT INTO feedback_categories (key, label, sort_order, archived_at)
SELECT DISTINCT f.category, initcap(replace(f.category, '_', ' ')), 100, now()
FROM feedback f
WHERE NOT EXISTS (SELECT 1 FROM feedback_categories c WHERE c.key = f.category)
ON CONFLICT (key) DO NOTHING;
-- The Admin role may manage them; Superadmin already has '*'.
UPDATE admin_roles
SET permissions = array_append(permissions, 'feedback:categories')
WHERE key = 'admin' AND NOT ('feedback:categories' = ANY(permissions));