feat: map shapes, image persistence, grab tool, layer rename/delete, i18n, page metadata
This commit is contained in:
210
supabase/migrations/036_finance_enhancements.sql
Normal file
210
supabase/migrations/036_finance_enhancements.sql
Normal file
@@ -0,0 +1,210 @@
|
||||
-- Finance enhancements: planned budgets per department, sponsor allocations,
|
||||
-- org-wide contacts, and department contact pinning
|
||||
|
||||
-- ============================================================
|
||||
-- 1. Add planned_budget to event_departments
|
||||
-- ============================================================
|
||||
ALTER TABLE event_departments
|
||||
ADD COLUMN IF NOT EXISTS planned_budget NUMERIC(12,2) NOT NULL DEFAULT 0;
|
||||
|
||||
-- ============================================================
|
||||
-- 2. Sponsor Allocations
|
||||
-- Tracks how sponsor money is allocated to departments.
|
||||
-- A sponsor (confirmed/active) has an amount; the finance lead
|
||||
-- distributes portions of that to specific departments.
|
||||
-- ============================================================
|
||||
CREATE TABLE sponsor_allocations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
sponsor_id UUID NOT NULL REFERENCES sponsors(id) ON DELETE CASCADE,
|
||||
department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE,
|
||||
allocated_amount NUMERIC(12,2) NOT NULL DEFAULT 0,
|
||||
used_amount NUMERIC(12,2) NOT NULL DEFAULT 0,
|
||||
notes TEXT,
|
||||
created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sponsor_alloc_sponsor ON sponsor_allocations(sponsor_id);
|
||||
CREATE INDEX idx_sponsor_alloc_dept ON sponsor_allocations(department_id);
|
||||
-- Prevent duplicate allocations of the same sponsor to the same department
|
||||
CREATE UNIQUE INDEX idx_sponsor_alloc_unique ON sponsor_allocations(sponsor_id, department_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 3. Org-wide Contacts
|
||||
-- Contacts that belong to the organization, not a department.
|
||||
-- Departments can "pin" contacts from this list.
|
||||
-- ============================================================
|
||||
CREATE TABLE org_contacts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
role TEXT,
|
||||
company TEXT,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
website TEXT,
|
||||
notes TEXT,
|
||||
category TEXT DEFAULT 'general',
|
||||
color TEXT DEFAULT '#00A3E0',
|
||||
created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_org_contacts_org ON org_contacts(org_id);
|
||||
CREATE INDEX idx_org_contacts_category ON org_contacts(category);
|
||||
|
||||
-- ============================================================
|
||||
-- 4. Department pinned contacts (junction table)
|
||||
-- Links org_contacts to departments for quick access
|
||||
-- ============================================================
|
||||
CREATE TABLE department_pinned_contacts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
department_id UUID NOT NULL REFERENCES event_departments(id) ON DELETE CASCADE,
|
||||
contact_id UUID NOT NULL REFERENCES org_contacts(id) ON DELETE CASCADE,
|
||||
pinned_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_dept_pinned_unique ON department_pinned_contacts(department_id, contact_id);
|
||||
CREATE INDEX idx_dept_pinned_dept ON department_pinned_contacts(department_id);
|
||||
CREATE INDEX idx_dept_pinned_contact ON department_pinned_contacts(contact_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 5. RLS Policies
|
||||
-- ============================================================
|
||||
|
||||
-- Sponsor Allocations
|
||||
ALTER TABLE sponsor_allocations ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY "sponsor_allocations_select" ON sponsor_allocations FOR SELECT
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "sponsor_allocations_insert" ON sponsor_allocations FOR INSERT
|
||||
WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "sponsor_allocations_update" ON sponsor_allocations FOR UPDATE
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "sponsor_allocations_delete" ON sponsor_allocations FOR DELETE
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = sponsor_allocations.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
-- Org Contacts
|
||||
ALTER TABLE org_contacts ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY "org_contacts_select" ON org_contacts FOR SELECT
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM org_members om
|
||||
WHERE om.org_id = org_contacts.org_id
|
||||
AND om.user_id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "org_contacts_insert" ON org_contacts FOR INSERT
|
||||
WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM org_members om
|
||||
WHERE om.org_id = org_contacts.org_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "org_contacts_update" ON org_contacts FOR UPDATE
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM org_members om
|
||||
WHERE om.org_id = org_contacts.org_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "org_contacts_delete" ON org_contacts FOR DELETE
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM org_members om
|
||||
WHERE om.org_id = org_contacts.org_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
-- Department Pinned Contacts
|
||||
ALTER TABLE department_pinned_contacts ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
CREATE POLICY "dept_pinned_contacts_select" ON department_pinned_contacts FOR SELECT
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "dept_pinned_contacts_insert" ON department_pinned_contacts FOR INSERT
|
||||
WITH CHECK (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
CREATE POLICY "dept_pinned_contacts_delete" ON department_pinned_contacts FOR DELETE
|
||||
USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM event_departments ed
|
||||
JOIN events e ON e.id = ed.event_id
|
||||
JOIN org_members om ON om.org_id = e.org_id
|
||||
WHERE ed.id = department_pinned_contacts.department_id
|
||||
AND om.user_id = auth.uid()
|
||||
AND om.role IN ('owner', 'admin', 'editor')
|
||||
)
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 6. Enable realtime for sponsor allocations
|
||||
-- ============================================================
|
||||
ALTER PUBLICATION supabase_realtime ADD TABLE sponsor_allocations;
|
||||
Reference in New Issue
Block a user