wacrm/supabase/migrations/002_pipelines_enhancements.sql
Arnas Donauskas f1eafd5d27
feat(pipelines): Kanban drag-drop, analytics, deal sheet, contact deals tab
Rebuild the Pipelines page to match spec.

Highlights:
- Drag-and-drop deal cards between stages via @dnd-kit (200ms drop animation,
  emerald dashed drop zone, opacity fade while dragging)
- First-visit seed: auto-creates "Sales Pipeline" with spec-defined stages
  (New Lead / Qualified / Proposal Sent / Negotiation / Won)
- Top bar: always-visible pipeline dropdown with "Manage Pipelines" option,
  plus "Add Pipeline" and emerald "Add Deal" buttons
- Deal form converted from Dialog to right-side Sheet, adds assigned_to
  (profile FK), "Link to Conversation" shortcut, "Mark as Won/Lost" status
  buttons, and "Delete Deal"
- Pipeline settings modal: drag-to-reorder stages (@dnd-kit sortable),
  per-stage color picker, "Create new pipeline" shortcut, archive
  confirmation copy
- Analytics bar below board: total deals, pipeline value, avg deal size,
  weighted pipeline value (probability interpolated across stages),
  won/lost this month
- Contact detail sheet gains a "Deals" tab showing all deals for that
  contact (value + stage badge + status)
- Migration 002: adds deals.assigned_to FK→profiles, normalizes status
  CHECK to ('open','won','lost')

Note: spec called for light-gray Kanban columns (#f9fafb) + white cards
inside an otherwise-dark app. Followed spec literally; easy to retheme.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 22:38:45 +03:00

35 lines
1.2 KiB
SQL

-- ============================================================
-- Pipeline enhancements:
-- * deals.assigned_to — optional FK to profiles.id
-- * deals.status — CHECK constraint ('open', 'won', 'lost')
-- (replaces the old default 'active' with spec-compliant values)
--
-- Idempotent: safe to run multiple times.
-- ============================================================
-- Add assigned_to (nullable, FK to profiles)
ALTER TABLE deals
ADD COLUMN IF NOT EXISTS assigned_to UUID REFERENCES profiles(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_deals_assigned_to ON deals(assigned_to);
-- Normalize status values: any existing 'active' row becomes 'open'
UPDATE deals SET status = 'open' WHERE status = 'active' OR status IS NULL;
-- Replace the old default and enforce allowed values
ALTER TABLE deals ALTER COLUMN status SET DEFAULT 'open';
-- Drop prior CHECK if any (none in 001, but be idempotent)
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'deals_status_check' AND conrelid = 'deals'::regclass
) THEN
ALTER TABLE deals DROP CONSTRAINT deals_status_check;
END IF;
END $$;
ALTER TABLE deals
ADD CONSTRAINT deals_status_check CHECK (status IN ('open', 'won', 'lost'));