269 lines
9.2 KiB
SQL
269 lines
9.2 KiB
SQL
CREATE TABLE IF NOT EXISTS committee (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
name VARCHAR(120) NOT NULL,
|
|
committee_type VARCHAR(50) NOT NULL DEFAULT 'general',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS app_user (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
full_name VARCHAR(120) NOT NULL,
|
|
email VARCHAR(255) UNIQUE NOT NULL,
|
|
password_hash TEXT NOT NULL DEFAULT '',
|
|
role role_type NOT NULL DEFAULT 'member',
|
|
committee_id BIGINT REFERENCES committee(id),
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
security_classification VARCHAR(30) NOT NULL DEFAULT 'standard',
|
|
force_password_reset BOOLEAN NOT NULL DEFAULT FALSE,
|
|
two_factor_enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
last_mfa_at TIMESTAMPTZ,
|
|
last_login_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS refresh_token (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL REFERENCES app_user(id) ON DELETE CASCADE,
|
|
token_hash TEXT NOT NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS br_case (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
case_number VARCHAR(50) UNIQUE NOT NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
case_type VARCHAR(50) NOT NULL,
|
|
status VARCHAR(50) NOT NULL DEFAULT 'neu',
|
|
priority VARCHAR(20) NOT NULL DEFAULT 'mittel',
|
|
confidentiality_level conf_level NOT NULL DEFAULT 'intern',
|
|
summary TEXT,
|
|
affected_employee_name VARCHAR(120),
|
|
department VARCHAR(120),
|
|
committee_id BIGINT REFERENCES committee(id),
|
|
owner_user_id BIGINT NOT NULL REFERENCES app_user(id),
|
|
legal_hold BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created_by BIGINT REFERENCES app_user(id),
|
|
updated_by BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS deadline (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
case_id BIGINT REFERENCES br_case(id) ON DELETE CASCADE,
|
|
title VARCHAR(255) NOT NULL,
|
|
deadline_type VARCHAR(50) NOT NULL,
|
|
due_date TIMESTAMPTZ NOT NULL,
|
|
status VARCHAR(30) NOT NULL DEFAULT 'offen',
|
|
remind_days_before INTEGER NOT NULL DEFAULT 2,
|
|
created_by BIGINT REFERENCES app_user(id),
|
|
updated_by BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS meeting (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
meeting_number VARCHAR(50) UNIQUE NOT NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
meeting_type VARCHAR(50) NOT NULL DEFAULT 'ordentlich',
|
|
meeting_date DATE NOT NULL,
|
|
start_time TIME,
|
|
end_time TIME,
|
|
location VARCHAR(255),
|
|
status VARCHAR(30) NOT NULL DEFAULT 'geplant',
|
|
protocol_text TEXT,
|
|
is_quorate BOOLEAN,
|
|
quorum_recorded_at TIMESTAMPTZ,
|
|
quorum_recorded_by BIGINT REFERENCES app_user(id),
|
|
committee_id BIGINT REFERENCES committee(id),
|
|
chair_user_id BIGINT REFERENCES app_user(id),
|
|
secretary_user_id BIGINT REFERENCES app_user(id),
|
|
created_by BIGINT REFERENCES app_user(id),
|
|
updated_by BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS meeting_agenda_item (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
meeting_id BIGINT NOT NULL REFERENCES meeting(id) ON DELETE CASCADE,
|
|
agenda_number VARCHAR(20) NOT NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
duration_minutes INTEGER,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS decision (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
decision_number VARCHAR(50) UNIQUE NOT NULL,
|
|
meeting_id BIGINT REFERENCES meeting(id) ON DELETE SET NULL,
|
|
agenda_item_id BIGINT REFERENCES meeting_agenda_item(id) ON DELETE SET NULL,
|
|
case_id BIGINT REFERENCES br_case(id) ON DELETE SET NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
decision_text TEXT NOT NULL,
|
|
status VARCHAR(30) NOT NULL DEFAULT 'offen',
|
|
votes_yes INTEGER NOT NULL DEFAULT 0,
|
|
votes_no INTEGER NOT NULL DEFAULT 0,
|
|
votes_abstain INTEGER NOT NULL DEFAULT 0,
|
|
responsible_user_id BIGINT REFERENCES app_user(id),
|
|
due_date TIMESTAMPTZ,
|
|
created_by BIGINT REFERENCES app_user(id),
|
|
updated_by BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS task (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
title VARCHAR(255) NOT NULL,
|
|
description TEXT,
|
|
status VARCHAR(30) NOT NULL DEFAULT 'offen',
|
|
priority VARCHAR(20) NOT NULL DEFAULT 'mittel',
|
|
assigned_user_id BIGINT REFERENCES app_user(id),
|
|
backup_user_id BIGINT REFERENCES app_user(id),
|
|
case_id BIGINT REFERENCES br_case(id) ON DELETE SET NULL,
|
|
meeting_id BIGINT REFERENCES meeting(id) ON DELETE SET NULL,
|
|
decision_id BIGINT REFERENCES decision(id) ON DELETE SET NULL,
|
|
due_date TIMESTAMPTZ,
|
|
confidentiality_level conf_level NOT NULL DEFAULT 'intern',
|
|
created_by BIGINT REFERENCES app_user(id),
|
|
updated_by BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS document_item (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
document_number VARCHAR(50) UNIQUE NOT NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
document_type VARCHAR(50) NOT NULL,
|
|
description TEXT,
|
|
version_label VARCHAR(30) NOT NULL DEFAULT 'v1',
|
|
file_name VARCHAR(255),
|
|
storage_path TEXT,
|
|
storage_provider VARCHAR(20) NOT NULL DEFAULT 'local',
|
|
mime_type VARCHAR(100),
|
|
size_bytes BIGINT,
|
|
sha256_hash VARCHAR(64),
|
|
confidentiality_level conf_level NOT NULL DEFAULT 'intern',
|
|
case_id BIGINT REFERENCES br_case(id) ON DELETE SET NULL,
|
|
meeting_id BIGINT REFERENCES meeting(id) ON DELETE SET NULL,
|
|
decision_id BIGINT REFERENCES decision(id) ON DELETE SET NULL,
|
|
uploaded_by BIGINT REFERENCES app_user(id),
|
|
is_signed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
scan_status scan_status_type NOT NULL DEFAULT 'pending',
|
|
scan_engine VARCHAR(50),
|
|
scan_result TEXT,
|
|
uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS document_scan_event (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
document_id BIGINT NOT NULL REFERENCES document_item(id) ON DELETE CASCADE,
|
|
scanned_by_user_id BIGINT REFERENCES app_user(id),
|
|
status scan_status_type NOT NULL,
|
|
engine VARCHAR(50) NOT NULL,
|
|
result_text TEXT,
|
|
scanned_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS comment_item (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
entity_type VARCHAR(50) NOT NULL,
|
|
entity_id BIGINT NOT NULL,
|
|
comment_text TEXT NOT NULL,
|
|
visibility VARCHAR(30) NOT NULL DEFAULT 'intern',
|
|
author_user_id BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS template_item (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
title VARCHAR(255) NOT NULL,
|
|
category VARCHAR(50) NOT NULL,
|
|
description TEXT,
|
|
content TEXT NOT NULL,
|
|
version_label VARCHAR(30) NOT NULL DEFAULT 'v1',
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_by BIGINT REFERENCES app_user(id),
|
|
updated_by BIGINT REFERENCES app_user(id),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS notification_item (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL REFERENCES app_user(id) ON DELETE CASCADE,
|
|
notification_type VARCHAR(50) NOT NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
entity_type VARCHAR(50),
|
|
entity_id BIGINT,
|
|
is_read BOOLEAN NOT NULL DEFAULT FALSE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS audit_log (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
actor_user_id BIGINT REFERENCES app_user(id),
|
|
action VARCHAR(100) NOT NULL,
|
|
entity_type VARCHAR(50),
|
|
entity_id BIGINT,
|
|
metadata JSONB,
|
|
ip_address INET,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS auth_challenge (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL REFERENCES app_user(id) ON DELETE CASCADE,
|
|
challenge_type VARCHAR(40) NOT NULL,
|
|
challenge_value TEXT NOT NULL,
|
|
metadata JSONB,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
used_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS webauthn_challenge (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL REFERENCES app_user(id) ON DELETE CASCADE,
|
|
flow_type VARCHAR(40) NOT NULL,
|
|
challenge TEXT NOT NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
used_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS webauthn_credential (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL REFERENCES app_user(id) ON DELETE CASCADE,
|
|
credential_id TEXT NOT NULL UNIQUE,
|
|
public_key TEXT NOT NULL,
|
|
counter BIGINT NOT NULL DEFAULT 0,
|
|
transports JSONB,
|
|
credential_device_type VARCHAR(50),
|
|
credential_backed_up BOOLEAN NOT NULL DEFAULT FALSE,
|
|
nickname VARCHAR(120),
|
|
last_used_at TIMESTAMPTZ,
|
|
revoked_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS user_totp_secret (
|
|
user_id BIGINT PRIMARY KEY REFERENCES app_user(id) ON DELETE CASCADE,
|
|
secret_base32 TEXT NOT NULL,
|
|
is_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
verified_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|