T05: Calendar plugin backend — appointments + tasks + kanban + ICS + resources + recurrence — 69 tests, 86.87% coverage
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
CREATE TABLE IF NOT EXISTS calendars (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
color VARCHAR(20) DEFAULT '#3B82F6',
|
||||
type VARCHAR(20) DEFAULT 'personal',
|
||||
owner_id UUID NOT NULL,
|
||||
ics_token VARCHAR(64),
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_calendars_tenant ON calendars(tenant_id) WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS calendar_entries (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
calendar_id UUID REFERENCES calendars(id) ON DELETE CASCADE,
|
||||
entry_type VARCHAR(15) NOT NULL,
|
||||
subtype VARCHAR(20) DEFAULT 'normal',
|
||||
title VARCHAR(500) NOT NULL,
|
||||
description TEXT,
|
||||
start_at TIMESTAMPTZ,
|
||||
end_at TIMESTAMPTZ,
|
||||
all_day BOOLEAN DEFAULT false,
|
||||
location VARCHAR(500),
|
||||
due_date TIMESTAMPTZ,
|
||||
priority VARCHAR(10) DEFAULT 'medium',
|
||||
status VARCHAR(15) DEFAULT 'open',
|
||||
assigned_to UUID,
|
||||
reminder JSONB,
|
||||
recurrence JSONB,
|
||||
source_mail_id UUID,
|
||||
created_by UUID NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
deleted_at TIMESTAMPTZ
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_tenant_cal ON calendar_entries(tenant_id, calendar_id) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_tenant_start ON calendar_entries(tenant_id, start_at) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_tenant_due ON calendar_entries(tenant_id, due_date) WHERE deleted_at IS NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_entries_assigned ON calendar_entries(tenant_id, assigned_to, status) WHERE deleted_at IS NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS calendar_entry_links (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
||||
entity_type VARCHAR(50) NOT NULL,
|
||||
entity_id UUID NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_entry_links_entry ON calendar_entry_links(entry_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS calendar_shares (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
calendar_id UUID REFERENCES calendars(id) ON DELETE CASCADE,
|
||||
user_id UUID,
|
||||
group_id UUID,
|
||||
permission VARCHAR(10) NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_calendar_shares_cal ON calendar_shares(calendar_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_calendar_visibility (
|
||||
user_id UUID NOT NULL,
|
||||
calendar_id UUID NOT NULL,
|
||||
tenant_id UUID NOT NULL,
|
||||
visible BOOLEAN DEFAULT true,
|
||||
PRIMARY KEY (user_id, calendar_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS subtasks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
completed BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_subtasks_entry ON subtasks(entry_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS resources (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
type VARCHAR(50) NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_resources_tenant ON resources(tenant_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS resource_bookings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id UUID NOT NULL,
|
||||
resource_id UUID REFERENCES resources(id) ON DELETE CASCADE,
|
||||
entry_id UUID REFERENCES calendar_entries(id) ON DELETE CASCADE,
|
||||
start_at TIMESTAMPTZ NOT NULL,
|
||||
end_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_bookings_resource ON resource_bookings(resource_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_bookings_entry ON resource_bookings(entry_id);
|
||||
Reference in New Issue
Block a user