feat: enhanced capture queue with multi-type conversion, and bottom menu bar for cell phones
This commit is contained in:
358
project-docs/lifeos_schema_r1.sql
Normal file
358
project-docs/lifeos_schema_r1.sql
Normal file
@@ -0,0 +1,358 @@
|
||||
-- =============================================================================
|
||||
-- Life OS - Release 1 Schema
|
||||
-- Self-hosted PostgreSQL on defiant-01 (Hetzner)
|
||||
-- =============================================================================
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Context Types
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE context_types (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
label TEXT NOT NULL,
|
||||
description TEXT,
|
||||
is_system BOOLEAN NOT NULL DEFAULT true,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- ORGANIZATIONAL HIERARCHY
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE domains (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
color TEXT,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE areas (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
domain_id UUID NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE projects (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
domain_id UUID NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
|
||||
area_id UUID REFERENCES areas(id) ON DELETE SET NULL,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
priority INTEGER NOT NULL DEFAULT 3,
|
||||
start_date DATE,
|
||||
target_date DATE,
|
||||
completed_at TIMESTAMPTZ,
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE tasks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
domain_id UUID NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
|
||||
area_id UUID REFERENCES areas(id) ON DELETE SET NULL,
|
||||
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
|
||||
parent_id UUID REFERENCES tasks(id) ON DELETE SET NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
priority INTEGER NOT NULL DEFAULT 3,
|
||||
status TEXT NOT NULL DEFAULT 'open',
|
||||
due_date DATE,
|
||||
deadline TIMESTAMPTZ,
|
||||
recurrence TEXT,
|
||||
tags TEXT[],
|
||||
context TEXT,
|
||||
is_custom_context BOOLEAN NOT NULL DEFAULT false,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
completed_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE notes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
domain_id UUID NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
|
||||
title TEXT NOT NULL,
|
||||
body TEXT,
|
||||
content_format TEXT NOT NULL DEFAULT 'rich',
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE lists (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
domain_id UUID NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
|
||||
area_id UUID REFERENCES areas(id) ON DELETE SET NULL,
|
||||
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
|
||||
name TEXT NOT NULL,
|
||||
list_type TEXT NOT NULL DEFAULT 'checklist',
|
||||
description TEXT,
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE list_items (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
list_id UUID NOT NULL REFERENCES lists(id) ON DELETE CASCADE,
|
||||
parent_item_id UUID REFERENCES list_items(id) ON DELETE SET NULL,
|
||||
content TEXT NOT NULL,
|
||||
completed BOOLEAN NOT NULL DEFAULT false,
|
||||
completed_at TIMESTAMPTZ,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE links (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
domain_id UUID NOT NULL REFERENCES domains(id) ON DELETE CASCADE,
|
||||
area_id UUID REFERENCES areas(id) ON DELETE SET NULL,
|
||||
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
|
||||
label TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
description TEXT,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE files (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
filename TEXT NOT NULL,
|
||||
original_filename TEXT NOT NULL,
|
||||
storage_path TEXT NOT NULL,
|
||||
mime_type TEXT,
|
||||
size_bytes INTEGER,
|
||||
description TEXT,
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Contacts
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE contacts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
company TEXT,
|
||||
role TEXT,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
notes TEXT,
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Appointments
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE appointments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
location TEXT,
|
||||
start_at TIMESTAMPTZ NOT NULL,
|
||||
end_at TIMESTAMPTZ,
|
||||
all_day BOOLEAN NOT NULL DEFAULT false,
|
||||
recurrence TEXT,
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Weblink Directory
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE weblink_folders (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
parent_id UUID REFERENCES weblink_folders(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
auto_generated BOOLEAN NOT NULL DEFAULT false,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE weblinks (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
label TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
description TEXT,
|
||||
tags TEXT[],
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Daily Focus
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE daily_focus (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
focus_date DATE NOT NULL,
|
||||
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
slot INTEGER,
|
||||
completed BOOLEAN NOT NULL DEFAULT false,
|
||||
note TEXT,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Capture Queue
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE capture (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
raw_text TEXT NOT NULL,
|
||||
processed BOOLEAN NOT NULL DEFAULT false,
|
||||
converted_to_type TEXT,
|
||||
converted_to_id UUID,
|
||||
area_id UUID REFERENCES areas(id) ON DELETE SET NULL,
|
||||
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
|
||||
list_id UUID REFERENCES lists(id) ON DELETE SET NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- SYSTEM LEVEL: Reminders
|
||||
-- =============================================================================
|
||||
|
||||
CREATE TABLE reminders (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
remind_at TIMESTAMPTZ NOT NULL,
|
||||
delivered BOOLEAN NOT NULL DEFAULT false,
|
||||
channel TEXT NOT NULL DEFAULT 'web',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- JUNCTION TABLES
|
||||
-- =============================================================================
|
||||
|
||||
-- Notes <-> Projects (M2M)
|
||||
CREATE TABLE note_projects (
|
||||
note_id UUID NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
|
||||
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
||||
is_primary BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (note_id, project_id)
|
||||
);
|
||||
|
||||
-- Files <-> any entity (polymorphic M2M)
|
||||
CREATE TABLE file_mappings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
file_id UUID NOT NULL REFERENCES files(id) ON DELETE CASCADE,
|
||||
context_type TEXT NOT NULL,
|
||||
context_id UUID NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
UNIQUE (file_id, context_type, context_id)
|
||||
);
|
||||
|
||||
-- Contacts <-> Tasks
|
||||
CREATE TABLE contact_tasks (
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
role TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (contact_id, task_id)
|
||||
);
|
||||
|
||||
-- Contacts <-> Lists
|
||||
CREATE TABLE contact_lists (
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
list_id UUID NOT NULL REFERENCES lists(id) ON DELETE CASCADE,
|
||||
role TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (contact_id, list_id)
|
||||
);
|
||||
|
||||
-- Contacts <-> List Items
|
||||
CREATE TABLE contact_list_items (
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
list_item_id UUID NOT NULL REFERENCES list_items(id) ON DELETE CASCADE,
|
||||
role TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (contact_id, list_item_id)
|
||||
);
|
||||
|
||||
-- Contacts <-> Projects
|
||||
CREATE TABLE contact_projects (
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
||||
role TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (contact_id, project_id)
|
||||
);
|
||||
|
||||
-- Contacts <-> Appointments
|
||||
CREATE TABLE contact_appointments (
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
appointment_id UUID NOT NULL REFERENCES appointments(id) ON DELETE CASCADE,
|
||||
role TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (contact_id, appointment_id)
|
||||
);
|
||||
|
||||
-- Weblinks <-> Folders (M2M)
|
||||
CREATE TABLE folder_weblinks (
|
||||
folder_id UUID NOT NULL REFERENCES weblink_folders(id) ON DELETE CASCADE,
|
||||
weblink_id UUID NOT NULL REFERENCES weblinks(id) ON DELETE CASCADE,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (folder_id, weblink_id)
|
||||
);
|
||||
|
||||
-- =============================================================================
|
||||
-- INDEXES
|
||||
-- =============================================================================
|
||||
|
||||
-- Sort order indexes (used on every list render)
|
||||
CREATE INDEX idx_domains_sort ON domains(sort_order);
|
||||
CREATE INDEX idx_areas_sort ON areas(domain_id, sort_order);
|
||||
CREATE INDEX idx_projects_sort ON projects(domain_id, sort_order);
|
||||
CREATE INDEX idx_projects_area_sort ON projects(area_id, sort_order);
|
||||
CREATE INDEX idx_tasks_project_sort ON tasks(project_id, sort_order);
|
||||
CREATE INDEX idx_tasks_parent_sort ON tasks(parent_id, sort_order);
|
||||
CREATE INDEX idx_tasks_domain_sort ON tasks(domain_id, sort_order);
|
||||
CREATE INDEX idx_list_items_sort ON list_items(list_id, sort_order);
|
||||
CREATE INDEX idx_list_items_parent_sort ON list_items(parent_item_id, sort_order);
|
||||
CREATE INDEX idx_weblinks_sort ON weblink_folders(parent_id, sort_order);
|
||||
|
||||
-- Lookup indexes
|
||||
CREATE INDEX idx_tasks_status ON tasks(status);
|
||||
CREATE INDEX idx_tasks_due_date ON tasks(due_date);
|
||||
CREATE INDEX idx_tasks_priority ON tasks(priority);
|
||||
CREATE INDEX idx_projects_status ON projects(status);
|
||||
CREATE INDEX idx_daily_focus_date ON daily_focus(focus_date);
|
||||
CREATE INDEX idx_appointments_start ON appointments(start_at);
|
||||
CREATE INDEX idx_capture_processed ON capture(processed);
|
||||
CREATE INDEX idx_file_mappings_context ON file_mappings(context_type, context_id);
|
||||
|
||||
Reference in New Issue
Block a user