148 lines
7.2 KiB
Go
148 lines
7.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
func ensureRuntimeDeviceSchema(ctx context.Context, db *pgxpool.Pool) error {
|
|
queries := []string{
|
|
`CREATE EXTENSION IF NOT EXISTS pgcrypto`,
|
|
`ALTER TABLE IF EXISTS devices ADD COLUMN IF NOT EXISTS phone_number TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS devices ADD COLUMN IF NOT EXISTS computer_name TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS devices ADD COLUMN IF NOT EXISTS device_category TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS devices ADD COLUMN IF NOT EXISTS loaned_to_user_id UUID REFERENCES users(id) ON DELETE SET NULL`,
|
|
`ALTER TABLE IF EXISTS devices ADD COLUMN IF NOT EXISTS loaned_until DATE`,
|
|
`ALTER TABLE IF EXISTS operations ADD COLUMN IF NOT EXISTS completed_at TIMESTAMPTZ`,
|
|
`ALTER TABLE IF EXISTS conversations ADD COLUMN IF NOT EXISTS is_public BOOLEAN NOT NULL DEFAULT false`,
|
|
`ALTER TABLE IF EXISTS conversations ADD COLUMN IF NOT EXISTS disappearing_seconds INTEGER NOT NULL DEFAULT 0`,
|
|
`ALTER TABLE IF EXISTS conversation_members ADD COLUMN IF NOT EXISTS muted BOOLEAN NOT NULL DEFAULT false`,
|
|
`ALTER TABLE IF EXISTS conversation_members ADD COLUMN IF NOT EXISTS last_cleared_at TIMESTAMPTZ`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS message_reactions (
|
|
message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
emoji TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (message_id, user_id)
|
|
)
|
|
`,
|
|
`
|
|
DELETE FROM message_reactions mr
|
|
USING (
|
|
SELECT ctid
|
|
FROM (
|
|
SELECT ctid,
|
|
ROW_NUMBER() OVER (
|
|
PARTITION BY message_id, user_id
|
|
ORDER BY created_at DESC, emoji ASC
|
|
) AS row_number
|
|
FROM message_reactions
|
|
) ranked_reactions
|
|
WHERE row_number > 1
|
|
) duplicate_reactions
|
|
WHERE mr.ctid = duplicate_reactions.ctid
|
|
`,
|
|
`CREATE INDEX IF NOT EXISTS idx_message_reactions_message_id ON message_reactions(message_id)`,
|
|
`CREATE INDEX IF NOT EXISTS idx_message_reactions_user_id ON message_reactions(user_id)`,
|
|
`CREATE UNIQUE INDEX IF NOT EXISTS idx_message_reactions_message_user_unique ON message_reactions(message_id, user_id)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS device_relations (
|
|
device_id UUID NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
|
related_device_id UUID NOT NULL REFERENCES devices(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (device_id, related_device_id),
|
|
CONSTRAINT device_relations_no_self_reference CHECK (device_id <> related_device_id)
|
|
)
|
|
`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS milestone_hardware_child_devices (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
milestone_hardware_id TEXT NOT NULL,
|
|
milestone_device_id TEXT NOT NULL,
|
|
device_type TEXT NOT NULL,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
display_name TEXT NOT NULL DEFAULT '',
|
|
short_name TEXT NOT NULL DEFAULT '',
|
|
enabled BOOLEAN NOT NULL DEFAULT true,
|
|
recording_enabled BOOLEAN NOT NULL DEFAULT false,
|
|
recording_storage_id TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (milestone_hardware_id, milestone_device_id, device_type)
|
|
)
|
|
`,
|
|
`ALTER TABLE IF EXISTS milestone_hardware_child_devices ADD COLUMN IF NOT EXISTS recording_enabled BOOLEAN NOT NULL DEFAULT false`,
|
|
`ALTER TABLE IF EXISTS milestone_hardware_child_devices ADD COLUMN IF NOT EXISTS recording_storage_id TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS server_folders_storage_root_label TEXT NOT NULL DEFAULT 'Storage D'`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS server_folders_storage_root_path TEXT NOT NULL DEFAULT 'D:/Milestone-Speicher'`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS server_folders_archive_root_label TEXT NOT NULL DEFAULT 'Archive E'`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS server_folders_archive_root_path TEXT NOT NULL DEFAULT 'E:/'`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS backup_nas_host TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS backup_nas_share TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS backup_nas_username TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS backup_nas_password_encrypted BYTEA`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS backup_log_root_path TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS active_directory_server_url TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS active_directory_base_dn TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS active_directory_bind_username TEXT NOT NULL DEFAULT ''`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS active_directory_bind_password_encrypted BYTEA`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS active_directory_user_group TEXT NOT NULL DEFAULT 'SE_Sachbearbeitung'`,
|
|
`ALTER TABLE IF EXISTS milestone_settings ADD COLUMN IF NOT EXISTS active_directory_skip_tls_verify BOOLEAN NOT NULL DEFAULT false`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS calendar_events (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
title TEXT NOT NULL,
|
|
start_at TIMESTAMP NOT NULL,
|
|
end_at TIMESTAMP NOT NULL,
|
|
all_day BOOLEAN NOT NULL DEFAULT false,
|
|
location TEXT NOT NULL DEFAULT '',
|
|
description TEXT NOT NULL DEFAULT '',
|
|
color TEXT NOT NULL DEFAULT 'indigo'
|
|
CHECK (color IN ('indigo', 'blue', 'emerald', 'amber', 'rose', 'slate')),
|
|
recurrence TEXT NOT NULL DEFAULT 'none',
|
|
recurrence_weekday INTEGER,
|
|
recurrence_ordinal INTEGER,
|
|
recurrence_exceptions JSONB NOT NULL DEFAULT '[]'::JSONB,
|
|
created_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
updated_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT calendar_events_valid_range CHECK (end_at > start_at)
|
|
)
|
|
`,
|
|
`
|
|
DO $$
|
|
DECLARE
|
|
constraint_name TEXT;
|
|
BEGIN
|
|
FOR constraint_name IN
|
|
SELECT c.conname
|
|
FROM pg_constraint c
|
|
JOIN pg_class t ON t.oid = c.conrelid
|
|
WHERE t.relname = 'calendar_events'
|
|
AND c.contype = 'c'
|
|
AND pg_get_constraintdef(c.oid) ILIKE '%recurrence%'
|
|
LOOP
|
|
EXECUTE format('ALTER TABLE calendar_events DROP CONSTRAINT %I', constraint_name);
|
|
END LOOP;
|
|
END
|
|
$$
|
|
`,
|
|
`ALTER TABLE IF EXISTS calendar_events ADD COLUMN IF NOT EXISTS recurrence_weekday INTEGER`,
|
|
`ALTER TABLE IF EXISTS calendar_events ADD COLUMN IF NOT EXISTS recurrence_ordinal INTEGER`,
|
|
`ALTER TABLE IF EXISTS calendar_events ADD COLUMN IF NOT EXISTS recurrence_exceptions JSONB NOT NULL DEFAULT '[]'::JSONB`,
|
|
`UPDATE calendar_events SET recurrence_exceptions = '[]'::JSONB WHERE recurrence_exceptions IS NULL`,
|
|
`CREATE INDEX IF NOT EXISTS idx_calendar_events_start_at ON calendar_events(start_at)`,
|
|
}
|
|
|
|
for _, query := range queries {
|
|
if _, err := db.Exec(ctx, query); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|