-- ===================================================== -- 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();