Add init
This commit is contained in:
@@ -1,60 +0,0 @@
|
||||
-- =======================
|
||||
-- TITLES
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS titles (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL, -- e.g., "Senior Software Engineer"
|
||||
code TEXT UNIQUE, -- e.g., "senior-software-engineer"
|
||||
description TEXT, -- optional: extra details
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Trigger for updated_at
|
||||
CREATE TRIGGER trg_titles_updated_at
|
||||
BEFORE UPDATE ON titles
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- Perwira Tinggi (High-ranking Officers)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Jenderal', 'jenderal', 'Pangkat tertinggi di TNI AD'),
|
||||
('Letnan Jenderal', 'letnan-jenderal', 'Pangkat tinggi di bawah Jenderal'),
|
||||
('Mayor Jenderal', 'mayor-jenderal', 'Pangkat tinggi di bawah Letnan Jenderal'),
|
||||
('Brigadir Jenderal', 'brigadir-jenderal', 'Pangkat tinggi di bawah Mayor Jenderal');
|
||||
|
||||
-- Perwira Menengah (Middle-ranking Officers)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Kolonel', 'kolonel', 'Pangkat perwira menengah tertinggi'),
|
||||
('Letnan Kolonel', 'letnan-kolonel', 'Pangkat perwira menengah di bawah Kolonel'),
|
||||
('Mayor', 'mayor', 'Pangkat perwira menengah di bawah Letnan Kolonel');
|
||||
|
||||
-- Perwira Pertama (Junior Officers)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Kapten', 'kapten', 'Pangkat perwira pertama tertinggi'),
|
||||
('Letnan Satu', 'letnan-satu', 'Pangkat perwira pertama di bawah Kapten'),
|
||||
('Letnan Dua', 'letnan-dua', 'Pangkat perwira pertama di bawah Letnan Satu');
|
||||
|
||||
-- Bintara Tinggi (Senior NCOs)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Pembantu Letnan Satu', 'pembantu-letnan-satu', 'Pangkat bintara tinggi tertinggi'),
|
||||
('Pembantu Letnan Dua', 'pembantu-letnan-dua', 'Pangkat bintara tinggi di bawah Pelda');
|
||||
|
||||
-- Bintara (NCOs)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Sersan Mayor', 'sersan-mayor', 'Pangkat bintara di bawah Pelda'),
|
||||
('Sersan Kepala', 'sersan-kepala', 'Pangkat bintara di bawah Serma'),
|
||||
('Sersan Satu', 'sersan-satu', 'Pangkat bintara di bawah Serka'),
|
||||
('Sersan Dua', 'sersan-dua', 'Pangkat bintara di bawah Sertu');
|
||||
|
||||
-- Tamtama Tinggi (Senior Enlisted)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Kopral Kepala', 'kopral-kepala', 'Pangkat tamtama tinggi tertinggi'),
|
||||
('Kopral Satu', 'kopral-satu', 'Pangkat tamtama tinggi di bawah Kopka'),
|
||||
('Kopral Dua', 'kopral-dua', 'Pangkat tamtama tinggi di bawah Koptu');
|
||||
|
||||
-- Tamtama (Enlisted)
|
||||
INSERT INTO titles (name, code, description) VALUES
|
||||
('Prajurit Kepala', 'prajurit-kepala', 'Pangkat tamtama di bawah Kopda'),
|
||||
('Prajurit Satu', 'prajurit-satu', 'Pangkat tamtama di bawah Prada'),
|
||||
('Prajurit Dua', 'prajurit-dua', 'Pangkat tamtama terendah');
|
||||
@@ -1,7 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS institutions;
|
||||
DROP TABLE IF EXISTS priorities;
|
||||
DROP TABLE IF EXISTS labels;
|
||||
|
||||
COMMIT;
|
||||
@@ -1,52 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
-- =======================
|
||||
-- LABELS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS labels (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
color VARCHAR(16), -- HEX color code (e.g., #FF0000)
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TRIGGER trg_labels_updated_at
|
||||
BEFORE UPDATE ON labels
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- PRIORITIES
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS priorities (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
level INT NOT NULL,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TRIGGER trg_priorities_updated_at
|
||||
BEFORE UPDATE ON priorities
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- INSTITUTIONS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS institutions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type TEXT NOT NULL CHECK (type IN ('government','private','ngo','individual')),
|
||||
address TEXT,
|
||||
contact_person VARCHAR(255),
|
||||
phone VARCHAR(50),
|
||||
email VARCHAR(255),
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TRIGGER trg_institutions_updated_at
|
||||
BEFORE UPDATE ON institutions
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
COMMIT;
|
||||
@@ -1,5 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS disposition_actions;
|
||||
|
||||
COMMIT;
|
||||
@@ -1,23 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
-- =======================
|
||||
-- DISPOSITION ACTIONS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS disposition_actions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
code TEXT UNIQUE NOT NULL,
|
||||
label TEXT NOT NULL,
|
||||
description TEXT,
|
||||
requires_note BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
group_name TEXT,
|
||||
sort_order INT,
|
||||
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 TRIGGER trg_disposition_actions_updated_at
|
||||
BEFORE UPDATE ON disposition_actions
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
COMMIT;
|
||||
@@ -1,16 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS letter_incoming_activity_logs;
|
||||
DROP TABLE IF EXISTS letter_incoming_discussion_attachments;
|
||||
DROP TABLE IF EXISTS letter_incoming_discussions;
|
||||
DROP TABLE IF EXISTS letter_disposition_actions;
|
||||
DROP TABLE IF EXISTS disposition_notes;
|
||||
DROP TABLE IF EXISTS letter_dispositions;
|
||||
DROP TABLE IF EXISTS letter_incoming_attachments;
|
||||
DROP TABLE IF EXISTS letter_incoming_labels;
|
||||
DROP TABLE IF EXISTS letter_incoming_recipients;
|
||||
DROP TABLE IF EXISTS letters_incoming;
|
||||
|
||||
DROP SEQUENCE IF EXISTS letters_incoming_seq;
|
||||
|
||||
COMMIT;
|
||||
@@ -1,189 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
-- =======================
|
||||
-- SEQUENCE FOR LETTER NUMBER
|
||||
-- =======================
|
||||
CREATE SEQUENCE IF NOT EXISTS letters_incoming_seq;
|
||||
|
||||
-- =======================
|
||||
-- LETTERS INCOMING
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letters_incoming (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_number TEXT NOT NULL UNIQUE DEFAULT ('IN-' || lpad(nextval('letters_incoming_seq')::text, 8, '0')),
|
||||
reference_number TEXT,
|
||||
subject TEXT NOT NULL,
|
||||
description TEXT,
|
||||
priority_id UUID REFERENCES priorities(id) ON DELETE SET NULL,
|
||||
sender_institution_id UUID REFERENCES institutions(id) ON DELETE SET NULL,
|
||||
received_date DATE NOT NULL,
|
||||
due_date DATE,
|
||||
status TEXT NOT NULL DEFAULT 'new' CHECK (status IN ('new','in_progress','completed')),
|
||||
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_incoming_status ON letters_incoming(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_letters_incoming_received_date ON letters_incoming(received_date);
|
||||
|
||||
CREATE TRIGGER trg_letters_incoming_updated_at
|
||||
BEFORE UPDATE ON letters_incoming
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- LETTER INCOMING RECIPIENTS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_incoming_recipients (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_incoming(id) ON DELETE CASCADE,
|
||||
recipient_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
recipient_department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
||||
status TEXT NOT NULL DEFAULT 'new' CHECK (status IN ('new','read','completed')),
|
||||
read_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
completed_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_incoming_recipients_letter ON letter_incoming_recipients(letter_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER INCOMING LABELS (M:N)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_incoming_labels (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_incoming(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_incoming_labels_letter ON letter_incoming_labels(letter_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER INCOMING ATTACHMENTS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_incoming_attachments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_incoming(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_incoming_attachments_letter ON letter_incoming_attachments(letter_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER DISPOSITIONS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_dispositions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_incoming(id) ON DELETE CASCADE,
|
||||
from_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
from_department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
||||
to_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
to_department_id UUID REFERENCES departments(id) ON DELETE SET NULL,
|
||||
notes TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','read','rejected','completed')),
|
||||
created_by UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
read_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
completed_at TIMESTAMP WITHOUT TIME ZONE,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_dispositions_letter ON letter_dispositions(letter_id);
|
||||
|
||||
CREATE TRIGGER trg_letter_dispositions_updated_at
|
||||
BEFORE UPDATE ON letter_dispositions
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- DISPOSITION NOTES
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS disposition_notes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
disposition_id UUID NOT NULL REFERENCES letter_dispositions(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
note TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_disposition_notes_disposition ON disposition_notes(disposition_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER DISPOSITION ACTIONS (Selections)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_disposition_actions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
disposition_id UUID NOT NULL REFERENCES letter_dispositions(id) ON DELETE CASCADE,
|
||||
action_id UUID NOT NULL REFERENCES disposition_actions(id) ON DELETE RESTRICT,
|
||||
note TEXT,
|
||||
created_by UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (disposition_id, action_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_disposition_actions_disposition ON letter_disposition_actions(disposition_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER INCOMING DISCUSSIONS (Threaded)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_incoming_discussions (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_incoming(id) ON DELETE CASCADE,
|
||||
parent_id UUID REFERENCES letter_incoming_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_incoming_discussions_letter ON letter_incoming_discussions(letter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_incoming_discussions_parent ON letter_incoming_discussions(parent_id);
|
||||
|
||||
CREATE TRIGGER trg_letter_incoming_discussions_updated_at
|
||||
BEFORE UPDATE ON letter_incoming_discussions
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- =======================
|
||||
-- LETTER INCOMING DISCUSSION ATTACHMENTS
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_incoming_discussion_attachments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
discussion_id UUID NOT NULL REFERENCES letter_incoming_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_incoming_discussion_attachments_discussion ON letter_incoming_discussion_attachments(discussion_id);
|
||||
|
||||
-- =======================
|
||||
-- LETTER INCOMING ACTIVITY LOGS (Immutable)
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS letter_incoming_activity_logs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
letter_id UUID NOT NULL REFERENCES letters_incoming(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_incoming_activity_logs_letter ON letter_incoming_activity_logs(letter_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_letter_incoming_activity_logs_action ON letter_incoming_activity_logs(action_type);
|
||||
|
||||
COMMIT;
|
||||
@@ -1,5 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS disposition_routes;
|
||||
|
||||
COMMIT;
|
||||
@@ -1,27 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
-- =======================
|
||||
-- DISPOSITION ROUTES
|
||||
-- =======================
|
||||
CREATE TABLE IF NOT EXISTS disposition_routes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
from_department_id UUID NOT NULL REFERENCES departments(id) ON DELETE CASCADE,
|
||||
to_department_id UUID NOT NULL REFERENCES departments(id) ON DELETE CASCADE,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
allowed_actions JSONB,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_disposition_routes_from_dept ON disposition_routes(from_department_id);
|
||||
|
||||
-- Prevent duplicate active routes from -> to
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_disposition_routes_active
|
||||
ON disposition_routes(from_department_id, to_department_id)
|
||||
WHERE is_active = TRUE;
|
||||
|
||||
CREATE TRIGGER trg_disposition_routes_updated_at
|
||||
BEFORE UPDATE ON disposition_routes
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
COMMIT;
|
||||
@@ -1,4 +0,0 @@
|
||||
BEGIN;
|
||||
DROP TRIGGER IF EXISTS trg_app_settings_updated_at ON app_settings;
|
||||
DROP TABLE IF EXISTS app_settings;
|
||||
COMMIT;
|
||||
@@ -1,21 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS app_settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TRIGGER trg_app_settings_updated_at
|
||||
BEFORE UPDATE ON app_settings
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
INSERT INTO app_settings(key, value)
|
||||
VALUES
|
||||
('INCOMING_LETTER_PREFIX', '{"value": "ESLI"}'::jsonb),
|
||||
('INCOMING_LETTER_SEQUENCE', '{"value": 0}'::jsonb),
|
||||
('INCOMING_LETTER_RECIPIENTS', '{"department_codes": ["aslog"]}'::jsonb)
|
||||
ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- Drop Voting System Tables
|
||||
|
||||
DROP TABLE IF EXISTS votes;
|
||||
DROP TABLE IF EXISTS candidates;
|
||||
DROP TABLE IF EXISTS vote_events;
|
||||
@@ -0,0 +1,51 @@
|
||||
-- Voting System Tables
|
||||
|
||||
-- Vote Events Table
|
||||
CREATE TABLE IF NOT EXISTS vote_events (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
start_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
|
||||
end_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
|
||||
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 TRIGGER trg_vote_events_updated_at
|
||||
BEFORE UPDATE ON vote_events
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
-- Candidates Table
|
||||
CREATE TABLE IF NOT EXISTS candidates (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
vote_event_id UUID NOT NULL REFERENCES vote_events(id) ON DELETE CASCADE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
image_url VARCHAR(500),
|
||||
description TEXT,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TRIGGER trg_candidates_updated_at
|
||||
BEFORE UPDATE ON candidates
|
||||
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_candidates_vote_event_id ON candidates(vote_event_id);
|
||||
|
||||
-- Votes Table
|
||||
CREATE TABLE IF NOT EXISTS votes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
vote_event_id UUID NOT NULL REFERENCES vote_events(id) ON DELETE CASCADE,
|
||||
candidate_id UUID NOT NULL REFERENCES candidates(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Ensure one vote per user per event
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS uq_votes_user_event
|
||||
ON votes(user_id, vote_event_id);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_votes_vote_event_id ON votes(vote_event_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_votes_candidate_id ON votes(candidate_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_votes_user_id ON votes(user_id);
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Remove results_open column from vote_events table
|
||||
ALTER TABLE vote_events
|
||||
DROP COLUMN IF EXISTS results_open;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- Add results_open column to vote_events table
|
||||
ALTER TABLE vote_events
|
||||
ADD COLUMN results_open BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
Reference in New Issue
Block a user