You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
2.2 KiB
66 lines
2.2 KiB
-- Kanban Labels System |
|
-- Adds label/tag support to kanban cards for categorization and filtering |
|
|
|
-- Labels table (org-scoped) |
|
CREATE TABLE IF NOT EXISTS kanban_labels ( |
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(), |
|
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, |
|
name TEXT NOT NULL, |
|
color TEXT NOT NULL DEFAULT '#6366f1', |
|
created_at TIMESTAMPTZ DEFAULT now(), |
|
UNIQUE(org_id, name) |
|
); |
|
|
|
-- Card-Label junction table (many-to-many) |
|
CREATE TABLE IF NOT EXISTS card_labels ( |
|
card_id UUID NOT NULL REFERENCES kanban_cards(id) ON DELETE CASCADE, |
|
label_id UUID NOT NULL REFERENCES kanban_labels(id) ON DELETE CASCADE, |
|
created_at TIMESTAMPTZ DEFAULT now(), |
|
PRIMARY KEY (card_id, label_id) |
|
); |
|
|
|
-- Enable RLS |
|
ALTER TABLE kanban_labels ENABLE ROW LEVEL SECURITY; |
|
ALTER TABLE card_labels ENABLE ROW LEVEL SECURITY; |
|
|
|
-- Labels accessible to org members |
|
CREATE POLICY "Labels accessible to org members" ON kanban_labels |
|
FOR ALL USING ( |
|
EXISTS ( |
|
SELECT 1 FROM org_members m |
|
WHERE m.org_id = kanban_labels.org_id |
|
AND m.user_id = auth.uid() |
|
) |
|
); |
|
|
|
-- Card labels inherit card access |
|
CREATE POLICY "Card labels inherit card access" ON card_labels |
|
FOR ALL USING ( |
|
EXISTS ( |
|
SELECT 1 FROM kanban_cards c |
|
JOIN kanban_columns col ON c.column_id = col.id |
|
JOIN kanban_boards b ON col.board_id = b.id |
|
JOIN org_members m ON b.org_id = m.org_id |
|
WHERE c.id = card_labels.card_id |
|
AND m.user_id = auth.uid() |
|
) |
|
); |
|
|
|
-- Indexes for performance |
|
CREATE INDEX IF NOT EXISTS idx_kanban_labels_org ON kanban_labels(org_id); |
|
CREATE INDEX IF NOT EXISTS idx_card_labels_card ON card_labels(card_id); |
|
CREATE INDEX IF NOT EXISTS idx_card_labels_label ON card_labels(label_id); |
|
|
|
-- Seed default labels for existing organizations |
|
INSERT INTO kanban_labels (org_id, name, color) |
|
SELECT DISTINCT o.id, label.name, label.color |
|
FROM organizations o |
|
CROSS JOIN ( |
|
VALUES |
|
('Bug', '#ef4444'), |
|
('Feature', '#22c55e'), |
|
('Enhancement', '#3b82f6'), |
|
('Documentation', '#a855f7'), |
|
('Urgent', '#f97316') |
|
) AS label(name, color) |
|
ON CONFLICT (org_id, name) DO NOTHING;
|
|
|