- Executed it_audit_migration.sql against DEV PostgreSQL (localhost:5433) - Created it_audits and it_collaboration_matches tables - Created 12 indexes for performance optimization - Created 4 views: v_company_it_overview, v_it_audit_history, v_it_collaboration_overview, v_it_technology_stats - Added missing document_management column to match SQLAlchemy model - Applied grants for nordabiz_app user Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
448 lines
18 KiB
PL/PgSQL
448 lines
18 KiB
PL/PgSQL
-- ============================================================
|
|
-- NordaBiz - Migration: IT Infrastructure Audit Tables
|
|
-- ============================================================
|
|
-- Created: 2026-01-09
|
|
-- Description:
|
|
-- - Creates it_audits table for storing IT infrastructure audit results
|
|
-- - Creates it_collaboration_matches table for company cooperation matching
|
|
-- - Tracks security, collaboration, and completeness scores
|
|
-- - Stores form data and AI-generated recommendations as JSONB
|
|
-- - Includes indexes and helpful views
|
|
--
|
|
-- Usage:
|
|
-- PostgreSQL: psql -h localhost -U nordabiz_app -d nordabiz -f it_audit_migration.sql
|
|
-- SQLite: Not fully supported (JSONB columns, TEXT[] arrays)
|
|
-- ============================================================
|
|
|
|
-- ============================================================
|
|
-- 1. MAIN IT_AUDITS TABLE
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS it_audits (
|
|
id SERIAL PRIMARY KEY,
|
|
|
|
-- Company reference
|
|
company_id INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
|
|
-- Audit timestamp and metadata
|
|
audit_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
audit_source VARCHAR(50) DEFAULT 'form', -- form, api_sync
|
|
audited_by INTEGER REFERENCES users(id),
|
|
|
|
-- Scores (0-100)
|
|
overall_score INTEGER,
|
|
completeness_score INTEGER,
|
|
security_score INTEGER,
|
|
collaboration_score INTEGER,
|
|
maturity_level VARCHAR(20), -- basic, developing, established, advanced
|
|
|
|
-- ========================================
|
|
-- Cloud & Identity (Section 2)
|
|
-- ========================================
|
|
has_azure_ad BOOLEAN DEFAULT FALSE,
|
|
azure_tenant_name VARCHAR(255),
|
|
azure_user_count VARCHAR(20), -- 1-10, 11-50, 51-100, 100+
|
|
has_m365 BOOLEAN DEFAULT FALSE,
|
|
m365_plans TEXT[], -- business_basic, business_standard, business_premium, e3, e5
|
|
teams_usage TEXT[], -- chat, meetings, channels, phone_system
|
|
has_google_workspace BOOLEAN DEFAULT FALSE,
|
|
|
|
-- ========================================
|
|
-- Server Infrastructure (Section 3)
|
|
-- ========================================
|
|
server_count VARCHAR(20), -- 0, 1-5, 6-10, 11-20, 20+
|
|
server_types TEXT[], -- physical, virtual, cloud_vm
|
|
virtualization_platform VARCHAR(50), -- proxmox, vmware, hyperv, none
|
|
server_os TEXT[], -- windows_server, ubuntu, debian, centos, other_linux
|
|
network_firewall_brand VARCHAR(100),
|
|
|
|
-- ========================================
|
|
-- Endpoints (Section 4)
|
|
-- ========================================
|
|
employee_count VARCHAR(20), -- 1-10, 11-25, 26-50, 51-100, 100+
|
|
computer_count VARCHAR(20), -- same ranges
|
|
desktop_os TEXT[], -- windows_10, windows_11, macos, linux
|
|
has_mdm BOOLEAN DEFAULT FALSE,
|
|
mdm_solution VARCHAR(50), -- intune, jamf, other
|
|
|
|
-- ========================================
|
|
-- Security (Section 5) - Highest weight
|
|
-- ========================================
|
|
antivirus_solution VARCHAR(50), -- windows_defender, eset, kaspersky, bitdefender, other
|
|
has_edr BOOLEAN DEFAULT FALSE,
|
|
edr_solution VARCHAR(100), -- crowdstrike, sentinel_one, defender_atp, other
|
|
has_vpn BOOLEAN DEFAULT FALSE,
|
|
vpn_solution VARCHAR(50), -- openvpn, wireguard, fortinet, cisco_anyconnect, other
|
|
has_mfa BOOLEAN DEFAULT FALSE,
|
|
mfa_scope TEXT[], -- email, vpn, admin_panels, all_apps
|
|
|
|
-- ========================================
|
|
-- Backup & Disaster Recovery (Section 6)
|
|
-- ========================================
|
|
backup_solution VARCHAR(50), -- veeam, acronis, proxmox_pbs, bacula, other
|
|
backup_targets TEXT[], -- local, nas, cloud, offsite
|
|
backup_frequency VARCHAR(20), -- daily, weekly, continuous, none
|
|
has_proxmox_pbs BOOLEAN DEFAULT FALSE,
|
|
has_dr_plan BOOLEAN DEFAULT FALSE,
|
|
|
|
-- ========================================
|
|
-- Monitoring (Section 7)
|
|
-- ========================================
|
|
monitoring_solution VARCHAR(50), -- zabbix, prometheus, prtg, datadog, none
|
|
zabbix_integration JSONB, -- {hostname: "...", api_enabled: true}
|
|
|
|
-- ========================================
|
|
-- Business Applications (Section 8)
|
|
-- ========================================
|
|
ticketing_system VARCHAR(50), -- jira, freshdesk, zendesk, none
|
|
erp_system VARCHAR(50), -- sap, optima, enova, wfmag, other, none
|
|
crm_system VARCHAR(50), -- salesforce, pipedrive, hubspot, other, none
|
|
document_management VARCHAR(50), -- none, sharepoint, google_drive, dropbox, other
|
|
|
|
-- ========================================
|
|
-- Active Directory (Section 3 extension)
|
|
-- ========================================
|
|
has_local_ad BOOLEAN DEFAULT FALSE,
|
|
ad_domain_name VARCHAR(255),
|
|
has_ad_azure_sync BOOLEAN DEFAULT FALSE,
|
|
|
|
-- ========================================
|
|
-- Collaboration Flags (Section 9)
|
|
-- ========================================
|
|
open_to_shared_licensing BOOLEAN DEFAULT FALSE,
|
|
open_to_backup_replication BOOLEAN DEFAULT FALSE,
|
|
open_to_teams_federation BOOLEAN DEFAULT FALSE,
|
|
open_to_shared_monitoring BOOLEAN DEFAULT FALSE,
|
|
open_to_collective_purchasing BOOLEAN DEFAULT FALSE,
|
|
open_to_knowledge_sharing BOOLEAN DEFAULT FALSE,
|
|
|
|
-- ========================================
|
|
-- IT Contact (Section 1)
|
|
-- ========================================
|
|
it_contact_name VARCHAR(255),
|
|
it_contact_email VARCHAR(255),
|
|
has_it_manager BOOLEAN DEFAULT FALSE,
|
|
it_outsourced BOOLEAN DEFAULT FALSE,
|
|
it_provider_name VARCHAR(255),
|
|
|
|
-- ========================================
|
|
-- Raw Data and AI Recommendations
|
|
-- ========================================
|
|
form_data JSONB, -- Complete form data for backup/debugging
|
|
recommendations JSONB, -- AI-generated improvement recommendations
|
|
audit_errors TEXT,
|
|
|
|
-- Timestamps
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
COMMENT ON TABLE it_audits IS 'IT infrastructure audit results for companies';
|
|
COMMENT ON COLUMN it_audits.overall_score IS 'Weighted overall score 0-100 (Security 50%, Collaboration 30%, Completeness 20%)';
|
|
COMMENT ON COLUMN it_audits.security_score IS 'Security posture score 0-100 (EDR, MFA, firewall, backup, DR, VPN, monitoring)';
|
|
COMMENT ON COLUMN it_audits.collaboration_score IS 'Collaboration readiness score 0-100 (flags + Azure AD + M365 + PBS + Zabbix)';
|
|
COMMENT ON COLUMN it_audits.completeness_score IS 'Form completeness score 0-100 (percentage of filled fields)';
|
|
COMMENT ON COLUMN it_audits.maturity_level IS 'IT maturity: basic (0-39), developing (40-59), established (60-79), advanced (80-100)';
|
|
COMMENT ON COLUMN it_audits.audit_source IS 'How audit was triggered: form (user input), api_sync (future Zabbix integration)';
|
|
COMMENT ON COLUMN it_audits.form_data IS 'Complete form data as JSONB for backup and debugging';
|
|
COMMENT ON COLUMN it_audits.recommendations IS 'AI-generated improvement recommendations as JSON array';
|
|
COMMENT ON COLUMN it_audits.zabbix_integration IS 'Zabbix integration settings (hostname, API key placeholder)';
|
|
|
|
-- ============================================================
|
|
-- 2. IT_COLLABORATION_MATCHES TABLE
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS it_collaboration_matches (
|
|
id SERIAL PRIMARY KEY,
|
|
|
|
-- Company pair (company_a_id < company_b_id to avoid duplicates)
|
|
company_a_id INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
company_b_id INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
|
|
-- Match details
|
|
match_type VARCHAR(50) NOT NULL, -- shared_licensing, backup_replication, teams_federation, shared_monitoring, collective_purchasing, knowledge_sharing
|
|
match_reason TEXT, -- Human-readable explanation
|
|
match_score INTEGER, -- 0-100 compatibility score
|
|
|
|
-- Status management
|
|
status VARCHAR(20) DEFAULT 'suggested', -- suggested, contacted, in_progress, completed, rejected
|
|
|
|
-- Shared attributes for this match
|
|
shared_attributes JSONB, -- {"common_platform": "M365", "both_have_pbs": true, ...}
|
|
|
|
-- Timestamps
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
-- Ensure unique match per type between company pairs
|
|
UNIQUE(company_a_id, company_b_id, match_type),
|
|
|
|
-- Prevent self-matching
|
|
CONSTRAINT no_self_match CHECK (company_a_id <> company_b_id)
|
|
);
|
|
|
|
COMMENT ON TABLE it_collaboration_matches IS 'Cross-company collaboration opportunities based on IT audit data';
|
|
COMMENT ON COLUMN it_collaboration_matches.match_type IS 'Type of collaboration: shared_licensing, backup_replication, teams_federation, shared_monitoring, collective_purchasing, knowledge_sharing';
|
|
COMMENT ON COLUMN it_collaboration_matches.match_reason IS 'Human-readable explanation of why these companies match';
|
|
COMMENT ON COLUMN it_collaboration_matches.match_score IS 'Compatibility score 0-100 based on matching criteria';
|
|
COMMENT ON COLUMN it_collaboration_matches.status IS 'Match status: suggested, contacted, in_progress, completed, rejected';
|
|
COMMENT ON COLUMN it_collaboration_matches.shared_attributes IS 'JSON object with common attributes that triggered the match';
|
|
|
|
-- ============================================================
|
|
-- 3. INDEXES FOR PERFORMANCE
|
|
-- ============================================================
|
|
|
|
-- IT Audits indexes
|
|
CREATE INDEX IF NOT EXISTS idx_it_audits_company ON it_audits(company_id);
|
|
CREATE INDEX IF NOT EXISTS idx_it_audits_date ON it_audits(audit_date DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_it_audits_overall_score ON it_audits(overall_score);
|
|
CREATE INDEX IF NOT EXISTS idx_it_audits_company_date ON it_audits(company_id, audit_date DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_it_audits_maturity ON it_audits(maturity_level);
|
|
|
|
-- Collaboration matches indexes
|
|
CREATE INDEX IF NOT EXISTS idx_it_collab_company_a ON it_collaboration_matches(company_a_id);
|
|
CREATE INDEX IF NOT EXISTS idx_it_collab_company_b ON it_collaboration_matches(company_b_id);
|
|
CREATE INDEX IF NOT EXISTS idx_it_collab_match_type ON it_collaboration_matches(match_type);
|
|
CREATE INDEX IF NOT EXISTS idx_it_collab_status ON it_collaboration_matches(status);
|
|
|
|
-- ============================================================
|
|
-- 4. UPDATE TRIGGERS FOR updated_at
|
|
-- ============================================================
|
|
|
|
-- IT Audits trigger
|
|
CREATE OR REPLACE FUNCTION it_audits_update_timestamp()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
DROP TRIGGER IF EXISTS trigger_it_audits_update ON it_audits;
|
|
CREATE TRIGGER trigger_it_audits_update
|
|
BEFORE UPDATE ON it_audits
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION it_audits_update_timestamp();
|
|
|
|
-- Collaboration matches trigger
|
|
CREATE OR REPLACE FUNCTION it_collab_matches_update_timestamp()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
DROP TRIGGER IF EXISTS trigger_it_collab_matches_update ON it_collaboration_matches;
|
|
CREATE TRIGGER trigger_it_collab_matches_update
|
|
BEFORE UPDATE ON it_collaboration_matches
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION it_collab_matches_update_timestamp();
|
|
|
|
-- ============================================================
|
|
-- 5. IT AUDIT OVERVIEW VIEW
|
|
-- ============================================================
|
|
|
|
CREATE OR REPLACE VIEW v_company_it_overview AS
|
|
SELECT
|
|
c.id,
|
|
c.name,
|
|
c.slug,
|
|
c.website,
|
|
cat.name as category_name,
|
|
ia.overall_score,
|
|
ia.security_score,
|
|
ia.collaboration_score,
|
|
ia.completeness_score,
|
|
ia.maturity_level,
|
|
ia.has_azure_ad,
|
|
ia.has_m365,
|
|
ia.has_edr,
|
|
ia.has_mfa,
|
|
ia.has_proxmox_pbs,
|
|
ia.monitoring_solution,
|
|
ia.audit_date,
|
|
ia.audit_source,
|
|
-- Score category (same as maturity_level but for display)
|
|
CASE
|
|
WHEN ia.overall_score >= 80 THEN 'advanced'
|
|
WHEN ia.overall_score >= 60 THEN 'established'
|
|
WHEN ia.overall_score >= 40 THEN 'developing'
|
|
WHEN ia.overall_score IS NOT NULL THEN 'basic'
|
|
ELSE 'not_audited'
|
|
END as score_category,
|
|
-- Count collaboration flags
|
|
(COALESCE(ia.open_to_shared_licensing::int, 0) +
|
|
COALESCE(ia.open_to_backup_replication::int, 0) +
|
|
COALESCE(ia.open_to_teams_federation::int, 0) +
|
|
COALESCE(ia.open_to_shared_monitoring::int, 0) +
|
|
COALESCE(ia.open_to_collective_purchasing::int, 0) +
|
|
COALESCE(ia.open_to_knowledge_sharing::int, 0)) as collaboration_flags_count
|
|
FROM companies c
|
|
LEFT JOIN categories cat ON c.category_id = cat.id
|
|
LEFT JOIN LATERAL (
|
|
SELECT * FROM it_audits
|
|
WHERE company_id = c.id
|
|
ORDER BY audit_date DESC
|
|
LIMIT 1
|
|
) ia ON TRUE
|
|
ORDER BY ia.overall_score DESC NULLS LAST;
|
|
|
|
COMMENT ON VIEW v_company_it_overview IS 'Latest IT audit results per company for admin dashboard';
|
|
|
|
-- ============================================================
|
|
-- 6. IT AUDIT HISTORY VIEW
|
|
-- ============================================================
|
|
|
|
CREATE OR REPLACE VIEW v_it_audit_history AS
|
|
SELECT
|
|
ia.id as audit_id,
|
|
c.id as company_id,
|
|
c.name as company_name,
|
|
c.slug as company_slug,
|
|
ia.overall_score,
|
|
ia.security_score,
|
|
ia.collaboration_score,
|
|
ia.completeness_score,
|
|
ia.maturity_level,
|
|
ia.audit_date,
|
|
ia.audit_source,
|
|
-- Previous score for comparison
|
|
LAG(ia.overall_score) OVER (
|
|
PARTITION BY ia.company_id
|
|
ORDER BY ia.audit_date
|
|
) as previous_score,
|
|
-- Score change
|
|
ia.overall_score - LAG(ia.overall_score) OVER (
|
|
PARTITION BY ia.company_id
|
|
ORDER BY ia.audit_date
|
|
) as score_change
|
|
FROM it_audits ia
|
|
JOIN companies c ON ia.company_id = c.id
|
|
ORDER BY ia.audit_date DESC;
|
|
|
|
COMMENT ON VIEW v_it_audit_history IS 'IT audit history with score trend tracking';
|
|
|
|
-- ============================================================
|
|
-- 7. COLLABORATION MATCHES VIEW
|
|
-- ============================================================
|
|
|
|
CREATE OR REPLACE VIEW v_it_collaboration_overview AS
|
|
SELECT
|
|
m.id as match_id,
|
|
m.match_type,
|
|
m.match_score,
|
|
m.match_reason,
|
|
m.status,
|
|
m.created_at,
|
|
ca.id as company_a_id,
|
|
ca.name as company_a_name,
|
|
ca.slug as company_a_slug,
|
|
cb.id as company_b_id,
|
|
cb.name as company_b_name,
|
|
cb.slug as company_b_slug,
|
|
m.shared_attributes,
|
|
-- Match type display name
|
|
CASE m.match_type
|
|
WHEN 'shared_licensing' THEN 'Wspólne licencje M365'
|
|
WHEN 'backup_replication' THEN 'Replikacja backup (PBS)'
|
|
WHEN 'teams_federation' THEN 'Federacja Teams'
|
|
WHEN 'shared_monitoring' THEN 'Wspólny monitoring (Zabbix)'
|
|
WHEN 'collective_purchasing' THEN 'Zakupy grupowe'
|
|
WHEN 'knowledge_sharing' THEN 'Wymiana wiedzy'
|
|
ELSE m.match_type
|
|
END as match_type_display
|
|
FROM it_collaboration_matches m
|
|
JOIN companies ca ON m.company_a_id = ca.id
|
|
JOIN companies cb ON m.company_b_id = cb.id
|
|
ORDER BY m.match_score DESC NULLS LAST, m.created_at DESC;
|
|
|
|
COMMENT ON VIEW v_it_collaboration_overview IS 'Collaboration matches with company names for admin dashboard';
|
|
|
|
-- ============================================================
|
|
-- 8. TECHNOLOGY STATISTICS VIEW
|
|
-- ============================================================
|
|
|
|
CREATE OR REPLACE VIEW v_it_technology_stats AS
|
|
SELECT
|
|
'azure_ad' as technology,
|
|
COUNT(*) FILTER (WHERE ia.has_azure_ad = TRUE) as company_count,
|
|
ROUND(100.0 * COUNT(*) FILTER (WHERE ia.has_azure_ad = TRUE) / NULLIF(COUNT(*), 0), 1) as percentage
|
|
FROM it_audits ia
|
|
WHERE ia.id IN (
|
|
SELECT DISTINCT ON (company_id) id FROM it_audits ORDER BY company_id, audit_date DESC
|
|
)
|
|
UNION ALL
|
|
SELECT
|
|
'm365' as technology,
|
|
COUNT(*) FILTER (WHERE ia.has_m365 = TRUE),
|
|
ROUND(100.0 * COUNT(*) FILTER (WHERE ia.has_m365 = TRUE) / NULLIF(COUNT(*), 0), 1)
|
|
FROM it_audits ia
|
|
WHERE ia.id IN (
|
|
SELECT DISTINCT ON (company_id) id FROM it_audits ORDER BY company_id, audit_date DESC
|
|
)
|
|
UNION ALL
|
|
SELECT
|
|
'edr' as technology,
|
|
COUNT(*) FILTER (WHERE ia.has_edr = TRUE),
|
|
ROUND(100.0 * COUNT(*) FILTER (WHERE ia.has_edr = TRUE) / NULLIF(COUNT(*), 0), 1)
|
|
FROM it_audits ia
|
|
WHERE ia.id IN (
|
|
SELECT DISTINCT ON (company_id) id FROM it_audits ORDER BY company_id, audit_date DESC
|
|
)
|
|
UNION ALL
|
|
SELECT
|
|
'mfa' as technology,
|
|
COUNT(*) FILTER (WHERE ia.has_mfa = TRUE),
|
|
ROUND(100.0 * COUNT(*) FILTER (WHERE ia.has_mfa = TRUE) / NULLIF(COUNT(*), 0), 1)
|
|
FROM it_audits ia
|
|
WHERE ia.id IN (
|
|
SELECT DISTINCT ON (company_id) id FROM it_audits ORDER BY company_id, audit_date DESC
|
|
)
|
|
UNION ALL
|
|
SELECT
|
|
'proxmox_pbs' as technology,
|
|
COUNT(*) FILTER (WHERE ia.has_proxmox_pbs = TRUE),
|
|
ROUND(100.0 * COUNT(*) FILTER (WHERE ia.has_proxmox_pbs = TRUE) / NULLIF(COUNT(*), 0), 1)
|
|
FROM it_audits ia
|
|
WHERE ia.id IN (
|
|
SELECT DISTINCT ON (company_id) id FROM it_audits ORDER BY company_id, audit_date DESC
|
|
);
|
|
|
|
COMMENT ON VIEW v_it_technology_stats IS 'Technology adoption statistics across audited companies';
|
|
|
|
-- ============================================================
|
|
-- 9. GRANTS FOR APPLICATION USER
|
|
-- ============================================================
|
|
|
|
-- Grant permissions on tables
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE it_audits TO nordabiz_app;
|
|
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE it_collaboration_matches TO nordabiz_app;
|
|
|
|
-- Grant permissions on sequences
|
|
GRANT USAGE, SELECT ON SEQUENCE it_audits_id_seq TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE it_collaboration_matches_id_seq TO nordabiz_app;
|
|
|
|
-- Grant permissions on views
|
|
GRANT SELECT ON v_company_it_overview TO nordabiz_app;
|
|
GRANT SELECT ON v_it_audit_history TO nordabiz_app;
|
|
GRANT SELECT ON v_it_collaboration_overview TO nordabiz_app;
|
|
GRANT SELECT ON v_it_technology_stats TO nordabiz_app;
|
|
|
|
-- ============================================================
|
|
-- MIGRATION COMPLETE
|
|
-- ============================================================
|
|
|
|
-- Verify migration (PostgreSQL only)
|
|
DO $$
|
|
BEGIN
|
|
RAISE NOTICE 'IT Audit migration completed successfully!';
|
|
RAISE NOTICE 'Created:';
|
|
RAISE NOTICE ' - Table: it_audits (IT infrastructure audit storage)';
|
|
RAISE NOTICE ' - Table: it_collaboration_matches (cross-company matching)';
|
|
RAISE NOTICE ' - Indexes: company_id, audit_date, scores, maturity level, match types';
|
|
RAISE NOTICE ' - Triggers: updated_at auto-update for both tables';
|
|
RAISE NOTICE ' - Views: v_company_it_overview, v_it_audit_history, v_it_collaboration_overview, v_it_technology_stats';
|
|
RAISE NOTICE ' - Grants: nordabiz_app permissions on all objects';
|
|
END $$;
|