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

-- 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;