feat: integrate dashboard modules and document history
This commit is contained in:
@@ -32,6 +32,48 @@ CREATE TABLE IF NOT EXISTS members (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_overrides (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
company TEXT,
|
||||
rank TEXT,
|
||||
role TEXT,
|
||||
department TEXT,
|
||||
grp TEXT,
|
||||
division TEXT,
|
||||
team TEXT,
|
||||
cell TEXT,
|
||||
work_status TEXT,
|
||||
work_time TEXT,
|
||||
phone TEXT,
|
||||
email TEXT,
|
||||
seat_label TEXT,
|
||||
photo_url TEXT,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_retirements (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id TEXT,
|
||||
name TEXT NOT NULL,
|
||||
note TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_aliases (
|
||||
id SERIAL PRIMARY KEY,
|
||||
alias_name TEXT NOT NULL UNIQUE,
|
||||
canonical_name TEXT NOT NULL,
|
||||
employee_id TEXT,
|
||||
note TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS seat_maps (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
@@ -76,11 +118,252 @@ CREATE TABLE IF NOT EXISTS seat_slots (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (seat_map_id, slot_key)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_import_batches (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source_key TEXT NOT NULL UNIQUE,
|
||||
source_name TEXT NOT NULL,
|
||||
source_path TEXT NOT NULL,
|
||||
imported_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
row_count INTEGER NOT NULL DEFAULT 0,
|
||||
meta_json JSONB NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_raw_organization_rows (
|
||||
id SERIAL PRIMARY KEY,
|
||||
batch_id INTEGER NOT NULL REFERENCES integration_import_batches(id) ON DELETE CASCADE,
|
||||
row_index INTEGER NOT NULL,
|
||||
row_json JSONB NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_raw_mh_rows (
|
||||
id SERIAL PRIMARY KEY,
|
||||
batch_id INTEGER NOT NULL REFERENCES integration_import_batches(id) ON DELETE CASCADE,
|
||||
row_index INTEGER NOT NULL,
|
||||
row_json JSONB NOT NULL,
|
||||
row_values_json JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_raw_mh_pm_rows (
|
||||
id SERIAL PRIMARY KEY,
|
||||
batch_id INTEGER NOT NULL REFERENCES integration_import_batches(id) ON DELETE CASCADE,
|
||||
row_index INTEGER NOT NULL,
|
||||
row_values_json JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_raw_payment_rows (
|
||||
id SERIAL PRIMARY KEY,
|
||||
batch_id INTEGER NOT NULL REFERENCES integration_import_batches(id) ON DELETE CASCADE,
|
||||
row_index INTEGER NOT NULL,
|
||||
row_json JSONB NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
project_code TEXT NOT NULL UNIQUE,
|
||||
project_name TEXT NOT NULL,
|
||||
display_name TEXT NOT NULL DEFAULT '',
|
||||
intranet_name TEXT NOT NULL DEFAULT '',
|
||||
business_area TEXT NOT NULL DEFAULT '',
|
||||
business_subarea TEXT NOT NULL DEFAULT '',
|
||||
project_nature TEXT NOT NULL DEFAULT '',
|
||||
main_category TEXT NOT NULL DEFAULT '',
|
||||
middle_category TEXT NOT NULL DEFAULT '',
|
||||
sub_category TEXT NOT NULL DEFAULT '',
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_project_aliases (
|
||||
id SERIAL PRIMARY KEY,
|
||||
project_id INTEGER NOT NULL REFERENCES integration_projects(id) ON DELETE CASCADE,
|
||||
alias_name TEXT NOT NULL,
|
||||
alias_type TEXT NOT NULL DEFAULT 'name',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (project_id, alias_name, alias_type)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_project_category_mappings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source_key TEXT NOT NULL DEFAULT 'ptj_csv',
|
||||
project_name TEXT NOT NULL,
|
||||
normalized_project_key TEXT NOT NULL,
|
||||
mapped_d1 TEXT NOT NULL DEFAULT '',
|
||||
mapped_d2 TEXT NOT NULL DEFAULT '',
|
||||
mapped_d3 TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (source_key, normalized_project_key)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_project_pm_assignments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
project_id INTEGER NOT NULL REFERENCES integration_projects(id) ON DELETE CASCADE,
|
||||
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
||||
pm_name TEXT NOT NULL,
|
||||
source_label TEXT NOT NULL DEFAULT 'mh_sheet2',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (project_id, source_label)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_work_logs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
work_date DATE NOT NULL,
|
||||
employee_id TEXT NOT NULL,
|
||||
member_id INTEGER REFERENCES members(id) ON DELETE SET NULL,
|
||||
member_name TEXT NOT NULL,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
team_category TEXT NOT NULL DEFAULT '',
|
||||
team_name TEXT NOT NULL DEFAULT '',
|
||||
user_state TEXT NOT NULL DEFAULT '',
|
||||
shift_hours NUMERIC(10, 2) NOT NULL DEFAULT 0,
|
||||
weekend_late_flag TEXT NOT NULL DEFAULT '',
|
||||
review_status TEXT NOT NULL DEFAULT '',
|
||||
source_row_index INTEGER NOT NULL DEFAULT 0,
|
||||
raw_batch_id INTEGER REFERENCES integration_import_batches(id) ON DELETE SET NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (work_date, employee_id, source_row_index)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_work_log_segments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
work_log_id INTEGER NOT NULL REFERENCES integration_work_logs(id) ON DELETE CASCADE,
|
||||
slot_name TEXT NOT NULL,
|
||||
project_id INTEGER REFERENCES integration_projects(id) ON DELETE SET NULL,
|
||||
project_code TEXT NOT NULL DEFAULT '',
|
||||
project_name TEXT NOT NULL DEFAULT '',
|
||||
business_type TEXT NOT NULL DEFAULT '',
|
||||
activity_code TEXT NOT NULL DEFAULT '',
|
||||
hours NUMERIC(10, 2) NOT NULL DEFAULT 0,
|
||||
overtime_hours_raw NUMERIC(10, 2) NOT NULL DEFAULT 0,
|
||||
overtime_hours_adjusted NUMERIC(10, 2) NOT NULL DEFAULT 0,
|
||||
is_overtime BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS integration_vouchers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
accounting_company TEXT NOT NULL DEFAULT '',
|
||||
claim_date DATE,
|
||||
issue_date DATE,
|
||||
issue_month TEXT NOT NULL DEFAULT '',
|
||||
account_code TEXT NOT NULL DEFAULT '',
|
||||
management_account_code TEXT NOT NULL DEFAULT '',
|
||||
account_name TEXT NOT NULL DEFAULT '',
|
||||
project_id INTEGER REFERENCES integration_projects(id) ON DELETE SET NULL,
|
||||
project_code TEXT NOT NULL DEFAULT '',
|
||||
project_name TEXT NOT NULL DEFAULT '',
|
||||
display_project_name TEXT NOT NULL DEFAULT '',
|
||||
intranet_project_name TEXT NOT NULL DEFAULT '',
|
||||
business_area TEXT NOT NULL DEFAULT '',
|
||||
business_subarea TEXT NOT NULL DEFAULT '',
|
||||
planning_dev_sales TEXT NOT NULL DEFAULT '',
|
||||
main_category TEXT NOT NULL DEFAULT '',
|
||||
middle_category TEXT NOT NULL DEFAULT '',
|
||||
sub_category TEXT NOT NULL DEFAULT '',
|
||||
department_name TEXT NOT NULL DEFAULT '',
|
||||
team_name TEXT NOT NULL DEFAULT '',
|
||||
customer_name TEXT NOT NULL DEFAULT '',
|
||||
summary_text TEXT NOT NULL DEFAULT '',
|
||||
debit_supply_amount NUMERIC(14, 2) NOT NULL DEFAULT 0,
|
||||
credit_supply_amount NUMERIC(14, 2) NOT NULL DEFAULT 0,
|
||||
expense_amount NUMERIC(14, 2) NOT NULL DEFAULT 0,
|
||||
income_amount NUMERIC(14, 2) NOT NULL DEFAULT 0,
|
||||
voucher_type TEXT NOT NULL DEFAULT '',
|
||||
project_nature TEXT NOT NULL DEFAULT '',
|
||||
raw_batch_id INTEGER REFERENCES integration_import_batches(id) ON DELETE SET NULL,
|
||||
source_row_index INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE SCHEMA IF NOT EXISTS auth;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth.users (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
display_name TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'admin',
|
||||
member_id INTEGER NULL REFERENCES members(id) ON DELETE SET NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_from TEXT NOT NULL DEFAULT 'manual',
|
||||
last_login_at TIMESTAMPTZ,
|
||||
password_changed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth.sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
revoked_at TIMESTAMPTZ,
|
||||
ip_address INET,
|
||||
user_agent TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth.login_audit_logs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
user_id BIGINT NULL REFERENCES auth.users(id) ON DELETE SET NULL,
|
||||
success BOOLEAN NOT NULL,
|
||||
failure_reason TEXT,
|
||||
ip_address INET,
|
||||
user_agent TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
"""
|
||||
|
||||
MIGRATION_SQL = """
|
||||
ALTER TABLE members ADD COLUMN IF NOT EXISTS employee_id TEXT;
|
||||
ALTER TABLE members ADD COLUMN IF NOT EXISTS sort_order INTEGER NOT NULL DEFAULT 0;
|
||||
CREATE TABLE IF NOT EXISTS member_overrides (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
company TEXT,
|
||||
rank TEXT,
|
||||
role TEXT,
|
||||
department TEXT,
|
||||
grp TEXT,
|
||||
division TEXT,
|
||||
team TEXT,
|
||||
cell TEXT,
|
||||
work_status TEXT,
|
||||
work_time TEXT,
|
||||
phone TEXT,
|
||||
email TEXT,
|
||||
seat_label TEXT,
|
||||
photo_url TEXT,
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_retirements (
|
||||
id SERIAL PRIMARY KEY,
|
||||
employee_id TEXT,
|
||||
name TEXT NOT NULL,
|
||||
note TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (name)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS member_aliases (
|
||||
id SERIAL PRIMARY KEY,
|
||||
alias_name TEXT NOT NULL UNIQUE,
|
||||
canonical_name TEXT NOT NULL,
|
||||
employee_id TEXT,
|
||||
note TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
ALTER TABLE seat_positions ADD COLUMN IF NOT EXISTS seat_map_id INTEGER REFERENCES seat_maps(id) ON DELETE CASCADE;
|
||||
ALTER TABLE seat_positions ADD COLUMN IF NOT EXISTS seat_slot_id INTEGER;
|
||||
ALTER TABLE seat_positions ADD COLUMN IF NOT EXISTS row_index INTEGER NOT NULL DEFAULT 0;
|
||||
@@ -136,14 +419,61 @@ BEGIN
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_name = 'integration_raw_mh_rows' AND column_name = 'row_values_json'
|
||||
) THEN
|
||||
ALTER TABLE integration_raw_mh_rows
|
||||
ADD COLUMN row_values_json JSONB NOT NULL DEFAULT '[]'::jsonb;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DROP INDEX IF EXISTS seat_positions_map_cell_idx;
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS seat_positions_map_cell_idx
|
||||
ON seat_positions (seat_map_id, row_index, col_index)
|
||||
WHERE seat_map_id IS NOT NULL;
|
||||
WHERE seat_map_id IS NOT NULL
|
||||
AND seat_slot_id IS NULL;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS member_overrides_employee_id_idx
|
||||
ON member_overrides (employee_id);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS member_retirements_name_idx
|
||||
ON member_retirements (name);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS member_aliases_alias_name_idx
|
||||
ON member_aliases (alias_name);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS seat_positions_slot_idx
|
||||
ON seat_positions (seat_slot_id)
|
||||
WHERE seat_slot_id IS NOT NULL;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS integration_raw_organization_rows_batch_row_idx
|
||||
ON integration_raw_organization_rows (batch_id, row_index);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS integration_raw_mh_rows_batch_row_idx
|
||||
ON integration_raw_mh_rows (batch_id, row_index);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS integration_raw_mh_pm_rows_batch_row_idx
|
||||
ON integration_raw_mh_pm_rows (batch_id, row_index);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS integration_raw_payment_rows_batch_row_idx
|
||||
ON integration_raw_payment_rows (batch_id, row_index);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS integration_work_logs_employee_idx
|
||||
ON integration_work_logs (employee_id, work_date);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS integration_work_log_segments_project_idx
|
||||
ON integration_work_log_segments (project_code, project_name);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS integration_vouchers_project_idx
|
||||
ON integration_vouchers (project_code, project_name);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS integration_project_category_mappings_key_idx
|
||||
ON integration_project_category_mappings (source_key, normalized_project_key);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
@@ -157,6 +487,58 @@ BEGIN
|
||||
FOREIGN KEY (seat_slot_id) REFERENCES seat_slots(id) ON DELETE CASCADE;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
CREATE SCHEMA IF NOT EXISTS auth;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth.users (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
display_name TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'admin',
|
||||
member_id INTEGER NULL REFERENCES members(id) ON DELETE SET NULL,
|
||||
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_from TEXT NOT NULL DEFAULT 'manual',
|
||||
last_login_at TIMESTAMPTZ,
|
||||
password_changed_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth.sessions (
|
||||
id UUID PRIMARY KEY,
|
||||
user_id BIGINT NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
revoked_at TIMESTAMPTZ,
|
||||
ip_address INET,
|
||||
user_agent TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS auth.login_audit_logs (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
user_id BIGINT NULL REFERENCES auth.users(id) ON DELETE SET NULL,
|
||||
success BOOLEAN NOT NULL,
|
||||
failure_reason TEXT,
|
||||
ip_address INET,
|
||||
user_agent TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS role TEXT NOT NULL DEFAULT 'admin';
|
||||
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS member_id INTEGER NULL REFERENCES members(id) ON DELETE SET NULL;
|
||||
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS is_active BOOLEAN NOT NULL DEFAULT TRUE;
|
||||
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS created_from TEXT NOT NULL DEFAULT 'manual';
|
||||
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS last_login_at TIMESTAMPTZ;
|
||||
ALTER TABLE auth.users ADD COLUMN IF NOT EXISTS password_changed_at TIMESTAMPTZ;
|
||||
ALTER TABLE auth.sessions ADD COLUMN IF NOT EXISTS revoked_at TIMESTAMPTZ;
|
||||
ALTER TABLE auth.sessions ADD COLUMN IF NOT EXISTS ip_address INET;
|
||||
ALTER TABLE auth.sessions ADD COLUMN IF NOT EXISTS user_agent TEXT;
|
||||
ALTER TABLE auth.login_audit_logs ADD COLUMN IF NOT EXISTS user_id BIGINT NULL REFERENCES auth.users(id) ON DELETE SET NULL;
|
||||
ALTER TABLE auth.login_audit_logs ADD COLUMN IF NOT EXISTS failure_reason TEXT;
|
||||
ALTER TABLE auth.login_audit_logs ADD COLUMN IF NOT EXISTS ip_address INET;
|
||||
ALTER TABLE auth.login_audit_logs ADD COLUMN IF NOT EXISTS user_agent TEXT;
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user