Files
boc/backend/db/migrations/004_contracts.sql
T

163 lines
5.7 KiB
PL/PgSQL
Raw Normal View History

-- =====================================================
-- Migration 004: Contracts & Legal Structure
-- =====================================================
-- Huvudtabell för avtal
CREATE TABLE IF NOT EXISTS boc_contracts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID REFERENCES boc_tenants(id),
template_type VARCHAR(50) NOT NULL,
name VARCHAR(255) NOT NULL,
description TEXT,
-- Motpart
counterparty VARCHAR(255) NOT NULL,
counterparty_org VARCHAR(255),
counterparty_org_number VARCHAR(20),
counterparty_address TEXT,
counterparty_contact VARCHAR(255),
counterparty_email VARCHAR(255),
-- Avtalsstatus
status VARCHAR(20) DEFAULT 'draft', -- draft, pending_signature, active, expired, terminated, disputed
-- Ekonomi
value DECIMAL(15,2),
currency VARCHAR(3) DEFAULT 'SEK',
payment_terms VARCHAR(50),
-- Tidsperiod
start_date DATE,
end_date DATE,
renewal_date DATE,
notice_period VARCHAR(20),
auto_renewal BOOLEAN DEFAULT false,
-- Ansvarig
responsible UUID REFERENCES boc_users(id),
legal_contact UUID REFERENCES boc_users(id),
-- Produktkoppling
product_id VARCHAR(100),
product_module VARCHAR(50),
-- Avtalsinnehåll
sections JSONB DEFAULT '[]',
clauses JSONB DEFAULT '[]',
variables JSONB DEFAULT '{}',
terms JSONB DEFAULT '{}',
-- Dokument
document_url VARCHAR(500),
signed_document_url VARCHAR(500),
-- Signering
signature_status VARCHAR(20) DEFAULT 'pending', -- pending, partially_signed, signed
signed_by_tenant_at TIMESTAMP WITH TIME ZONE,
signed_by_counterparty_at TIMESTAMP WITH TIME ZONE,
-- Metadata
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_by UUID REFERENCES boc_users(id),
version INTEGER DEFAULT 1
);
-- Index för snabb sökning
CREATE INDEX IF NOT EXISTS idx_contracts_tenant ON boc_contracts(tenant_id);
CREATE INDEX IF NOT EXISTS idx_contracts_status ON boc_contracts(status);
CREATE INDEX IF NOT EXISTS idx_contracts_template ON boc_contracts(template_type);
CREATE INDEX IF NOT EXISTS idx_contracts_product ON boc_contracts(product_id);
CREATE INDEX IF NOT EXISTS idx_contracts_counterparty ON boc_contracts(counterparty);
CREATE INDEX IF NOT EXISTS idx_contracts_dates ON boc_contracts(start_date, end_date);
-- Avtalsändringar/historik
CREATE TABLE IF NOT EXISTS boc_contract_revisions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contract_id UUID NOT NULL REFERENCES boc_contracts(id) ON DELETE CASCADE,
revision_number INTEGER NOT NULL,
changes JSONB NOT NULL,
changed_by UUID REFERENCES boc_users(id),
change_reason TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_contract_revisions_contract ON boc_contract_revisions(contract_id);
-- Påminnelser för avtal (förnyelse, uppsägning, etc.)
CREATE TABLE IF NOT EXISTS boc_contract_reminders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contract_id UUID NOT NULL REFERENCES boc_contracts(id) ON DELETE CASCADE,
reminder_type VARCHAR(50) NOT NULL, -- renewal, expiration, payment, review
reminder_date DATE NOT NULL,
status VARCHAR(20) DEFAULT 'pending', -- pending, sent, acknowledged
notified_users UUID[],
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_contract_reminders_date ON boc_contract_reminders(reminder_date);
CREATE INDEX IF NOT EXISTS idx_contract_reminders_status ON boc_contract_reminders(status);
-- Bilagor till avtal
CREATE TABLE IF NOT EXISTS boc_contract_attachments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contract_id UUID NOT NULL REFERENCES boc_contracts(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
file_url VARCHAR(500),
file_type VARCHAR(50),
file_size INTEGER,
description TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
created_by UUID REFERENCES boc_users(id)
);
-- Standardavtal (templates) - lagras som JSON för flexibilitet
CREATE TABLE IF NOT EXISTS boc_contract_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
type VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
description TEXT,
category VARCHAR(50), -- aamos, quixzoom, legal, hr
product_module VARCHAR(50),
version VARCHAR(10) DEFAULT '1.0',
status VARCHAR(20) DEFAULT 'active',
language VARCHAR(5) DEFAULT 'sv',
jurisdiction VARCHAR(50) DEFAULT 'Sweden',
content JSONB NOT NULL,
default_terms JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Produkt-avtal kopplingar
CREATE TABLE IF NOT EXISTS boc_product_contract_links (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
product_id VARCHAR(100) NOT NULL,
product_name VARCHAR(255) NOT NULL,
product_type VARCHAR(50) NOT NULL,
required_templates JSONB DEFAULT '[]',
optional_templates JSONB DEFAULT '[]',
default_terms JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Skapa unikt index
CREATE UNIQUE INDEX IF NOT EXISTS idx_product_contract_links_product
ON boc_product_contract_links(product_id);
-- Triggers för updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
DROP TRIGGER IF EXISTS update_contracts_updated_at ON boc_contracts;
CREATE TRIGGER update_contracts_updated_at
BEFORE UPDATE ON boc_contracts
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();