126 lines
4.8 KiB
SQL
126 lines
4.8 KiB
SQL
-- Migration 011: Create project sessions and related media tables
|
|
-- ProjectSession: active work session during a project
|
|
-- During session: task completions, notes, photos, videos
|
|
|
|
-- Project work session
|
|
CREATE TABLE project_sessions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
customer_id UUID NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
|
|
scope_id UUID NOT NULL REFERENCES project_scopes(id) ON DELETE RESTRICT,
|
|
|
|
-- Optional location (projects may or may not have a location)
|
|
account_id UUID REFERENCES accounts(id) ON DELETE SET NULL,
|
|
account_address_id UUID REFERENCES account_addresses(id) ON DELETE SET NULL,
|
|
|
|
date DATE NOT NULL,
|
|
start TIMESTAMPTZ NOT NULL,
|
|
"end" TIMESTAMPTZ,
|
|
|
|
created_by_id UUID NOT NULL REFERENCES team_profiles(id) ON DELETE RESTRICT,
|
|
closed_by_id UUID REFERENCES team_profiles(id) ON DELETE SET NULL,
|
|
|
|
-- Constraint: end must be after start (or null for active sessions)
|
|
CONSTRAINT project_session_end_gt_start_or_null CHECK ("end" IS NULL OR "end" > start)
|
|
);
|
|
|
|
-- Project task completion record
|
|
CREATE TABLE project_task_completions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
task_id UUID NOT NULL REFERENCES project_scope_tasks(id) ON DELETE CASCADE,
|
|
|
|
-- Optional location context
|
|
account_id UUID REFERENCES accounts(id) ON DELETE SET NULL,
|
|
account_address_id UUID REFERENCES account_addresses(id) ON DELETE SET NULL,
|
|
|
|
completed_by_id UUID NOT NULL REFERENCES team_profiles(id) ON DELETE RESTRICT,
|
|
completed_at TIMESTAMPTZ NOT NULL,
|
|
|
|
notes TEXT
|
|
);
|
|
|
|
-- M2M: Session to task completions
|
|
CREATE TABLE project_session_completed_tasks (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
session_id UUID NOT NULL REFERENCES project_sessions(id) ON DELETE CASCADE,
|
|
task_completion_id UUID NOT NULL REFERENCES project_task_completions(id) ON DELETE CASCADE,
|
|
|
|
UNIQUE (session_id, task_completion_id)
|
|
);
|
|
|
|
-- Session notes
|
|
CREATE TABLE project_session_notes (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
session_id UUID NOT NULL REFERENCES project_sessions(id) ON DELETE CASCADE,
|
|
|
|
content TEXT NOT NULL,
|
|
author_id UUID REFERENCES team_profiles(id) ON DELETE SET NULL,
|
|
internal BOOLEAN NOT NULL DEFAULT FALSE
|
|
);
|
|
|
|
-- Session images
|
|
CREATE TABLE project_session_images (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
session_id UUID NOT NULL REFERENCES project_sessions(id) ON DELETE CASCADE,
|
|
|
|
title VARCHAR(255) NOT NULL,
|
|
image VARCHAR(100) NOT NULL,
|
|
thumbnail VARCHAR(100),
|
|
|
|
content_type VARCHAR(100) NOT NULL,
|
|
width INTEGER NOT NULL CHECK (width >= 0),
|
|
height INTEGER NOT NULL CHECK (height >= 0),
|
|
|
|
uploaded_by_team_profile_id UUID REFERENCES team_profiles(id) ON DELETE SET NULL,
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
internal BOOLEAN NOT NULL DEFAULT FALSE
|
|
);
|
|
|
|
-- Session videos
|
|
CREATE TABLE project_session_videos (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
session_id UUID NOT NULL REFERENCES project_sessions(id) ON DELETE CASCADE,
|
|
|
|
title VARCHAR(255) NOT NULL,
|
|
video VARCHAR(100) NOT NULL,
|
|
thumbnail VARCHAR(100),
|
|
|
|
content_type VARCHAR(100) NOT NULL,
|
|
width INTEGER NOT NULL CHECK (width >= 0),
|
|
height INTEGER NOT NULL CHECK (height >= 0),
|
|
duration_seconds INTEGER NOT NULL CHECK (duration_seconds >= 0),
|
|
file_size_bytes BIGINT NOT NULL CHECK (file_size_bytes >= 0),
|
|
|
|
uploaded_by_team_profile_id UUID REFERENCES team_profiles(id) ON DELETE SET NULL,
|
|
notes TEXT NOT NULL DEFAULT '',
|
|
internal BOOLEAN NOT NULL DEFAULT FALSE
|
|
);
|
|
|
|
-- Indexes
|
|
CREATE INDEX idx_project_sessions_project ON project_sessions(project_id);
|
|
CREATE INDEX idx_project_sessions_date ON project_sessions(date);
|
|
CREATE INDEX idx_project_sessions_created_by ON project_sessions(created_by_id);
|
|
CREATE INDEX idx_project_task_completions_project ON project_task_completions(project_id);
|
|
CREATE INDEX idx_project_task_completions_task ON project_task_completions(task_id);
|
|
CREATE INDEX idx_project_session_notes_session ON project_session_notes(session_id);
|
|
CREATE INDEX idx_project_session_images_session ON project_session_images(session_id);
|
|
CREATE INDEX idx_project_session_videos_session ON project_session_videos(session_id);
|