release: v2.6.1
This commit is contained in:
parent
d0f27b78d5
commit
147451c259
21
MDfile/RELEASE_NOTES_v2.6.1.md
Normal file
21
MDfile/RELEASE_NOTES_v2.6.1.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Release Notes: v2.6.1
|
||||||
|
|
||||||
|
**Dato:** 25. august 2026
|
||||||
|
|
||||||
|
## Overblik
|
||||||
|
|
||||||
|
Version 2.6.1 retter genkørsel af fem ældre migrationer, som produktionsserverens schema-detektion korrekt fandt, men som ikke var fuldt idempotente.
|
||||||
|
|
||||||
|
## Databasemigrationer
|
||||||
|
|
||||||
|
- Settings- og ticket-triggers fjernes sikkert, før de genoprettes.
|
||||||
|
- `sag_salgsvarer` oprettes fra rod-migrationerne, hvis den modul-lokale grundmigration ikke tidligere er kørt.
|
||||||
|
- Produkt-, leverandørfaktura- og sporbarhedskolonner kan derefter tilføjes sikkert.
|
||||||
|
- Ticket-views med udvidede tabelkolonner genskabes sikkert ved genkørsel.
|
||||||
|
- Den forældede unikke CVR-regel er fjernet i overensstemmelse med den nuværende datamodel, hvor flere kundeposter må dele CVR-nummer.
|
||||||
|
|
||||||
|
## Verifikation
|
||||||
|
|
||||||
|
- De fem berørte migrationer er kørt samlet mod lokal PostgreSQL: **5 bestået**.
|
||||||
|
- Hele sættet er derefter genkørt: **5 bestået**, hvilket bekræfter idempotens.
|
||||||
|
- Diff-kontrol er gennemført.
|
||||||
@ -65,6 +65,7 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS settings_updated_at_trigger ON settings;
|
||||||
CREATE TRIGGER settings_updated_at_trigger
|
CREATE TRIGGER settings_updated_at_trigger
|
||||||
BEFORE UPDATE ON settings
|
BEFORE UPDATE ON settings
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
|
|||||||
@ -313,6 +313,7 @@ BEGIN
|
|||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS tticket_audit_changes ON tticket_tickets;
|
||||||
CREATE TRIGGER tticket_audit_changes
|
CREATE TRIGGER tticket_audit_changes
|
||||||
AFTER UPDATE ON tticket_tickets
|
AFTER UPDATE ON tticket_tickets
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
@ -323,6 +324,9 @@ CREATE TRIGGER tticket_audit_changes
|
|||||||
-- ============================================================================
|
-- ============================================================================
|
||||||
|
|
||||||
-- View for tickets with hierarchy info
|
-- View for tickets with hierarchy info
|
||||||
|
-- The view contains t.*, so later columns on tticket_tickets can shift the
|
||||||
|
-- expanded output. PostgreSQL cannot reconcile that with CREATE OR REPLACE.
|
||||||
|
DROP VIEW IF EXISTS tticket_tickets_with_hierarchy;
|
||||||
CREATE OR REPLACE VIEW tticket_tickets_with_hierarchy AS
|
CREATE OR REPLACE VIEW tticket_tickets_with_hierarchy AS
|
||||||
SELECT
|
SELECT
|
||||||
t.*,
|
t.*,
|
||||||
@ -334,6 +338,7 @@ FROM tticket_tickets t
|
|||||||
LEFT JOIN tticket_tickets parent ON t.parent_ticket_id = parent.id;
|
LEFT JOIN tticket_tickets parent ON t.parent_ticket_id = parent.id;
|
||||||
|
|
||||||
-- View for tickets with pending AI suggestions
|
-- View for tickets with pending AI suggestions
|
||||||
|
DROP VIEW IF EXISTS tticket_tickets_with_suggestions;
|
||||||
CREATE OR REPLACE VIEW tticket_tickets_with_suggestions AS
|
CREATE OR REPLACE VIEW tticket_tickets_with_suggestions AS
|
||||||
SELECT
|
SELECT
|
||||||
t.id,
|
t.id,
|
||||||
@ -348,6 +353,7 @@ LEFT JOIN tticket_calendar_events ce ON t.id = ce.ticket_id
|
|||||||
GROUP BY t.id, t.ticket_number, t.subject, t.status;
|
GROUP BY t.id, t.ticket_number, t.subject, t.status;
|
||||||
|
|
||||||
-- View for overdue tickets
|
-- View for overdue tickets
|
||||||
|
DROP VIEW IF EXISTS tticket_overdue_tickets;
|
||||||
CREATE OR REPLACE VIEW tticket_overdue_tickets AS
|
CREATE OR REPLACE VIEW tticket_overdue_tickets AS
|
||||||
SELECT
|
SELECT
|
||||||
t.id,
|
t.id,
|
||||||
|
|||||||
@ -1,5 +1,43 @@
|
|||||||
-- Migration 108: Add product_id to sag_salgsvarer
|
-- Migration 108: Add product_id to sag_salgsvarer
|
||||||
|
|
||||||
|
-- Some installations only execute migrations from the root migrations folder.
|
||||||
|
-- Bootstrap the module table here when the earlier module-local migration has
|
||||||
|
-- not been run. All statements remain safe when the table already exists.
|
||||||
|
CREATE TABLE IF NOT EXISTS sag_salgsvarer (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
sag_id INTEGER NOT NULL REFERENCES sag_sager(id) ON DELETE CASCADE,
|
||||||
|
type VARCHAR(20) NOT NULL DEFAULT 'sale',
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
quantity NUMERIC(12, 2),
|
||||||
|
unit VARCHAR(50),
|
||||||
|
unit_price NUMERIC(12, 2),
|
||||||
|
amount NUMERIC(12, 2) NOT NULL,
|
||||||
|
currency VARCHAR(10) NOT NULL DEFAULT 'DKK',
|
||||||
|
status VARCHAR(20) NOT NULL DEFAULT 'draft',
|
||||||
|
line_date DATE,
|
||||||
|
external_ref VARCHAR(100),
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sag_salgsvarer_sag_id ON sag_salgsvarer(sag_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sag_salgsvarer_type ON sag_salgsvarer(type);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_sag_salgsvarer_status ON sag_salgsvarer(status);
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION update_sag_salgsvarer_updated_at()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
BEGIN
|
||||||
|
NEW.updated_at = NOW();
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS trigger_sag_salgsvarer_updated_at ON sag_salgsvarer;
|
||||||
|
CREATE TRIGGER trigger_sag_salgsvarer_updated_at
|
||||||
|
BEFORE UPDATE ON sag_salgsvarer
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION update_sag_salgsvarer_updated_at();
|
||||||
|
|
||||||
ALTER TABLE sag_salgsvarer
|
ALTER TABLE sag_salgsvarer
|
||||||
ADD COLUMN IF NOT EXISTS product_id INTEGER REFERENCES products(id);
|
ADD COLUMN IF NOT EXISTS product_id INTEGER REFERENCES products(id);
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
-- Migration: Fix CVR Unique Constraint
|
-- Migration: Remove the legacy CVR uniqueness rule.
|
||||||
-- Allow multiple customers without CVR number (NULL or empty string)
|
-- CVR is company metadata and multiple e-conomic customer records may
|
||||||
|
-- legitimately share the same value. This mirrors migration 1000 and keeps
|
||||||
|
-- this historical migration safe when schema detection selects it again.
|
||||||
|
|
||||||
-- Drop old unique constraint
|
-- Drop old unique constraint
|
||||||
ALTER TABLE customers DROP CONSTRAINT IF EXISTS customers_cvr_number_key;
|
ALTER TABLE customers DROP CONSTRAINT IF EXISTS customers_cvr_number_key;
|
||||||
|
|
||||||
-- Create partial unique index - only enforce uniqueness for non-empty CVR numbers
|
DROP INDEX IF EXISTS customers_cvr_number_unique_idx;
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS customers_cvr_number_unique_idx
|
|
||||||
ON customers (cvr_number)
|
|
||||||
WHERE cvr_number IS NOT NULL AND cvr_number != '';
|
|
||||||
|
|
||||||
COMMENT ON INDEX customers_cvr_number_unique_idx IS
|
CREATE INDEX IF NOT EXISTS idx_customers_cvr
|
||||||
'Ensures CVR numbers are unique, but allows multiple customers without CVR';
|
ON customers(cvr_number)
|
||||||
|
WHERE cvr_number IS NOT NULL AND cvr_number <> '';
|
||||||
|
|
||||||
|
COMMENT ON COLUMN customers.cvr_number IS
|
||||||
|
'Danish CVR number. Informational/searchable; duplicates are allowed.';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user