Files
amcs/migrations/_old/015_professional_crm.sql
Hein 927a118338
Some checks failed
CI / build-and-test (push) Failing after -31m53s
feat(ui): add maintenance page for task management
* Implement maintenance page with task and log display
* Add backfill and metadata retry functionality
* Integrate grid component for project display in thoughts page
* Update types for maintenance tasks and logs
* Enhance sidebar and shell for new maintenance navigation
2026-04-26 23:13:41 +02:00

72 lines
3.1 KiB
PL/PgSQL

-- Extension 5: Professional CRM
-- Contacts, interaction logs, and opportunities (single-user, no RLS)
CREATE TABLE IF NOT EXISTS professional_contacts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
company TEXT,
title TEXT,
email TEXT,
phone TEXT,
linkedin_url TEXT,
how_we_met TEXT,
tags TEXT[] NOT NULL DEFAULT '{}',
notes TEXT,
last_contacted TIMESTAMPTZ,
follow_up_date DATE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS contact_interactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID NOT NULL REFERENCES professional_contacts(id) ON DELETE CASCADE,
interaction_type TEXT NOT NULL CHECK (interaction_type IN ('meeting', 'email', 'call', 'coffee', 'event', 'linkedin', 'other')),
occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
summary TEXT NOT NULL,
follow_up_needed BOOLEAN NOT NULL DEFAULT false,
follow_up_notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE IF NOT EXISTS opportunities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID REFERENCES professional_contacts(id) ON DELETE SET NULL,
title TEXT NOT NULL,
description TEXT,
stage TEXT NOT NULL DEFAULT 'identified' CHECK (stage IN ('identified', 'in_conversation', 'proposal', 'negotiation', 'won', 'lost')),
value DECIMAL(12, 2),
expected_close_date DATE,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS idx_contacts_last_contacted ON professional_contacts(last_contacted);
CREATE INDEX IF NOT EXISTS idx_contacts_follow_up ON professional_contacts(follow_up_date) WHERE follow_up_date IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_interactions_contact ON contact_interactions(contact_id, occurred_at DESC);
CREATE INDEX IF NOT EXISTS idx_opportunities_stage ON opportunities(stage);
DROP TRIGGER IF EXISTS update_professional_contacts_updated_at ON professional_contacts;
CREATE TRIGGER update_professional_contacts_updated_at
BEFORE UPDATE ON professional_contacts
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_opportunities_updated_at ON opportunities;
CREATE TRIGGER update_opportunities_updated_at
BEFORE UPDATE ON opportunities
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE OR REPLACE FUNCTION update_last_contacted()
RETURNS TRIGGER AS $$
BEGIN
UPDATE professional_contacts SET last_contacted = NEW.occurred_at WHERE id = NEW.contact_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS update_contact_last_contacted ON contact_interactions;
CREATE TRIGGER update_contact_last_contacted
AFTER INSERT ON contact_interactions
FOR EACH ROW EXECUTE FUNCTION update_last_contacted();