bmc_hub/migrations/150_sag_tidsforbrug_v1.sql

110 lines
4.6 KiB
SQL

-- Migration 150: Sag tidsforbrug v1 foundation
-- Formål: Udvide tmodule_times med felter til live timer, faktisk/fakturerbar minutter,
-- status-flow og type/kilde uden at bryde eksisterende timetracking-flow.
ALTER TABLE tmodule_times
ADD COLUMN IF NOT EXISTS start_tid TIMESTAMP,
ADD COLUMN IF NOT EXISTS slut_tid TIMESTAMP,
ADD COLUMN IF NOT EXISTS faktisk_tid_min INTEGER,
ADD COLUMN IF NOT EXISTS fakturerbar_tid_min INTEGER,
ADD COLUMN IF NOT EXISTS entry_type VARCHAR(32) DEFAULT 'ukendt',
ADD COLUMN IF NOT EXISTS kilde VARCHAR(32) DEFAULT 'manuel',
ADD COLUMN IF NOT EXISTS entry_status VARCHAR(32) DEFAULT 'afventer',
ADD COLUMN IF NOT EXISTS medarbejder_id INTEGER,
ADD COLUMN IF NOT EXISTS aktiv_timer BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS round_block_min INTEGER DEFAULT 30,
ADD COLUMN IF NOT EXISTS ikke_placeret BOOLEAN DEFAULT FALSE;
-- Optional settings per customer/type (fx mail default minutter)
CREATE TABLE IF NOT EXISTS tmodule_time_defaults (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES tmodule_customers(id) ON DELETE CASCADE,
entry_type VARCHAR(32) NOT NULL,
default_minutes INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT tmodule_time_defaults_default_minutes_positive CHECK (default_minutes > 0),
CONSTRAINT tmodule_time_defaults_unique UNIQUE (customer_id, entry_type)
);
-- Backfill for existing rows so gamle data stadig virker i ny UI/API.
UPDATE tmodule_times
SET
entry_type = COALESCE(entry_type, 'ukendt'),
kilde = COALESCE(kilde, 'api'),
entry_status = COALESCE(
entry_status,
CASE
WHEN status = 'approved' THEN 'godkendt'
WHEN status = 'pending' THEN 'afventer'
WHEN status = 'billed' THEN 'godkendt'
ELSE 'kladde'
END
),
faktisk_tid_min = COALESCE(faktisk_tid_min, CEIL(COALESCE(original_hours, 0)::numeric * 60)::int),
fakturerbar_tid_min = COALESCE(
fakturerbar_tid_min,
CEIL(COALESCE(approved_hours, original_hours, 0)::numeric * 60)::int
),
round_block_min = COALESCE(round_block_min, 30),
aktiv_timer = COALESCE(aktiv_timer, FALSE),
ikke_placeret = COALESCE(ikke_placeret, FALSE);
-- Guards
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'tmodule_times_faktisk_tid_min_positive'
AND conrelid = 'tmodule_times'::regclass
) THEN
ALTER TABLE tmodule_times
ADD CONSTRAINT tmodule_times_faktisk_tid_min_positive CHECK (faktisk_tid_min IS NULL OR faktisk_tid_min >= 0);
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'tmodule_times_fakturerbar_tid_min_positive'
AND conrelid = 'tmodule_times'::regclass
) THEN
ALTER TABLE tmodule_times
ADD CONSTRAINT tmodule_times_fakturerbar_tid_min_positive CHECK (fakturerbar_tid_min IS NULL OR fakturerbar_tid_min >= 0);
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'tmodule_times_entry_status_check'
AND conrelid = 'tmodule_times'::regclass
) THEN
ALTER TABLE tmodule_times
ADD CONSTRAINT tmodule_times_entry_status_check CHECK (entry_status IN ('kladde', 'afventer', 'godkendt'));
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'tmodule_times_entry_type_check'
AND conrelid = 'tmodule_times'::regclass
) THEN
ALTER TABLE tmodule_times
ADD CONSTRAINT tmodule_times_entry_type_check CHECK (entry_type IN ('opkald', 'mail', 'indedesk', 'manuel', 'ukendt'));
END IF;
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'tmodule_times_kilde_check'
AND conrelid = 'tmodule_times'::regclass
) THEN
ALTER TABLE tmodule_times
ADD CONSTRAINT tmodule_times_kilde_check CHECK (kilde IN ('auto', 'manuel', 'api'));
END IF;
END $$;
CREATE INDEX IF NOT EXISTS idx_tmodule_times_start_tid ON tmodule_times(start_tid);
CREATE INDEX IF NOT EXISTS idx_tmodule_times_medarbejder_id ON tmodule_times(medarbejder_id);
CREATE INDEX IF NOT EXISTS idx_tmodule_times_entry_status ON tmodule_times(entry_status);
CREATE INDEX IF NOT EXISTS idx_tmodule_times_aktiv_timer ON tmodule_times(aktiv_timer);
CREATE INDEX IF NOT EXISTS idx_tmodule_time_defaults_customer ON tmodule_time_defaults(customer_id);
CREATE UNIQUE INDEX IF NOT EXISTS uq_tmodule_times_active_timer_per_user
ON tmodule_times(medarbejder_id)
WHERE aktiv_timer = TRUE AND slut_tid IS NULL;