67 lines
2.2 KiB
SQL
67 lines
2.2 KiB
SQL
-- 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;
|