Add letter and user id
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
BEGIN;
|
||||
|
||||
-- Drop triggers first
|
||||
DROP TRIGGER IF EXISTS trg_letter_outgoing_discussions_updated_at ON letter_outgoing_discussions;
|
||||
DROP TRIGGER IF EXISTS trg_approval_flow_steps_updated_at ON approval_flow_steps;
|
||||
DROP TRIGGER IF EXISTS trg_approval_flows_updated_at ON approval_flows;
|
||||
DROP TRIGGER IF EXISTS trg_letters_outgoing_updated_at ON letters_outgoing;
|
||||
|
||||
-- Drop tables in reverse order (due to foreign key constraints)
|
||||
DROP TABLE IF EXISTS letter_outgoing_activity_logs;
|
||||
DROP TABLE IF EXISTS letter_outgoing_discussion_attachments;
|
||||
DROP TABLE IF EXISTS letter_outgoing_discussions;
|
||||
DROP TABLE IF EXISTS letter_outgoing_approvals;
|
||||
DROP TABLE IF EXISTS letter_outgoing_attachments;
|
||||
DROP TABLE IF EXISTS letter_outgoing_labels;
|
||||
DROP TABLE IF EXISTS letter_outgoing_recipients;
|
||||
DROP TABLE IF EXISTS letters_outgoing;
|
||||
DROP TABLE IF EXISTS approval_flow_steps;
|
||||
DROP TABLE IF EXISTS approval_flows;
|
||||
|
||||
-- Drop sequence
|
||||
DROP SEQUENCE IF EXISTS letters_outgoing_seq;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,199 @@
|
||||
BEGIN;
|
||||
|
||||
-- =======================
|
||||
-- SEQUENCE FOR LETTER NUMBER
|
||||
-- =======================
|
||||
CREATE SEQUENCE IF NOT EXISTS letters_outgoing_seq;
|
||||
|
||||
-- =======================
|
||||
-- APPROVAL FLOWS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS approval_flows (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
department_id UUID NOT NULL REFERENCES departments(id) ON DELETE RESTRICT,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_approval_flows_department ON approval_flows(department_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_approval_flows_active ON approval_flows(is_active);
|
||||
|
||||
CREATE TRIGGER trg_approval_flows_updated_at
|
||||
BEFORE UPDATE ON approval_flows
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- APPROVAL FLOW STEPS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS approval_flow_steps (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
flow_id UUID NOT NULL REFERENCES approval_flows(id) ON DELETE CASCADE,
|
||||
step_order INT NOT NULL,
|
||||
parallel_group INT DEFAULT 1,
|
||||
approver_role_id UUID REFERENCES roles(id) ON DELETE SET NULL,
|
||||
approver_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
required BOOLEAN NOT NULL DEFAULT true,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(flow_id, step_order, parallel_group, approver_role_id, approver_user_id),
|
||||
CHECK ((approver_role_id IS NOT NULL) OR (approver_user_id IS NOT NULL))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_approval_flow_steps_flow ON approval_flow_steps(flow_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_approval_flow_steps_order ON approval_flow_steps(flow_id, step_order);
|
||||
|
||||
CREATE TRIGGER trg_approval_flow_steps_updated_at
|
||||
BEFORE UPDATE ON approval_flow_steps
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- LETTERS OUTGOING
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letters_outgoing (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_number TEXT NOT NULL UNIQUE DEFAULT ('OUT-' || lpad(nextval('letters_outgoing_seq')::text, 8, '0')),
|
||||
reference_number TEXT,
|
||||
subject TEXT NOT NULL,
|
||||
description TEXT,
|
||||
priority_id UUID REFERENCES priorities(id) ON DELETE SET NULL,
|
||||
receiver_institution_id UUID REFERENCES institutions(id) ON DELETE SET NULL,
|
||||
issue_date DATE NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','pending_approval','approved','sent','archived')),
|
||||
approval_flow_id UUID REFERENCES approval_flows(id) ON DELETE SET NULL,
|
||||
created_by UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP WITHOUT TIME ZONE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_status ON letters_outgoing(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_issue_date ON letters_outgoing(issue_date);
|
||||
CREATE INDEX IF NOT EXISTS idx_letters_outgoing_approval_flow ON letters_outgoing(approval_flow_id);
|
||||
|
||||
CREATE TRIGGER trg_letters_outgoing_updated_at
|
||||
BEFORE UPDATE ON letters_outgoing
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING RECIPIENTS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_recipients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_outgoing(id) ON DELETE CASCADE,
|
||||
recipient_name TEXT NOT NULL,
|
||||
recipient_email TEXT,
|
||||
recipient_position TEXT,
|
||||
recipient_institution TEXT,
|
||||
is_primary BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_recipients_letter ON letter_outgoing_recipients(letter_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING LABELS (M:N)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_labels (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_outgoing(id) ON DELETE CASCADE,
|
||||
label_id UUID NOT NULL REFERENCES labels(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (letter_id, label_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_labels_letter ON letter_outgoing_labels(letter_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING ATTACHMENTS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_attachments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_outgoing(id) ON DELETE CASCADE,
|
||||
file_url TEXT NOT NULL,
|
||||
file_name TEXT NOT NULL,
|
||||
file_type TEXT NOT NULL,
|
||||
uploaded_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
uploaded_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_attachments_letter ON letter_outgoing_attachments(letter_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING APPROVALS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_approvals (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_outgoing(id) ON DELETE CASCADE,
|
||||
step_id UUID NOT NULL REFERENCES approval_flow_steps(id) ON DELETE CASCADE,
|
||||
approver_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','approved','rejected')),
|
||||
remarks TEXT,
|
||||
acted_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_approvals_letter ON letter_outgoing_approvals(letter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_approvals_step ON letter_outgoing_approvals(step_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_approvals_status ON letter_outgoing_approvals(status);
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING DISCUSSIONS (Threaded)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_discussions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_outgoing(id) ON DELETE CASCADE,
|
||||
parent_id UUID REFERENCES letter_outgoing_discussions(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
|
||||
message TEXT NOT NULL,
|
||||
mentions JSONB,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
edited_at TIMESTAMP WITHOUT TIME ZONE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_discussions_letter ON letter_outgoing_discussions(letter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_discussions_parent ON letter_outgoing_discussions(parent_id);
|
||||
|
||||
CREATE TRIGGER trg_letter_outgoing_discussions_updated_at
|
||||
BEFORE UPDATE ON letter_outgoing_discussions
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING DISCUSSION ATTACHMENTS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_discussion_attachments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
discussion_id UUID NOT NULL REFERENCES letter_outgoing_discussions(id) ON DELETE CASCADE,
|
||||
file_url TEXT NOT NULL,
|
||||
file_name TEXT NOT NULL,
|
||||
file_type TEXT NOT NULL,
|
||||
uploaded_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
uploaded_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_discussion_attachments_discussion ON letter_outgoing_discussion_attachments(discussion_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER OUTGOING ACTIVITY LOGS (Immutable)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_outgoing_activity_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_outgoing(id) ON DELETE CASCADE,
|
||||
action_type TEXT NOT NULL,
|
||||
actor_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
actor_department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
||||
target_type TEXT,
|
||||
target_id UUID,
|
||||
from_status TEXT,
|
||||
to_status TEXT,
|
||||
context JSONB,
|
||||
occurred_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_activity_logs_letter ON letter_outgoing_activity_logs(letter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_outgoing_activity_logs_action ON letter_outgoing_activity_logs(action_type);
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user