nordabiz/database/migrations/013_krs_audit.sql
Maciej Pienczyn de52e6991c feat: Add KRS Audit panel with full PDF parsing
- New admin panel /admin/krs-audit for KRS data extraction
- Full PDF parser extracting: company data, capital, shares, PKD codes,
  management board, shareholders, procurators, financial reports
- API endpoints for single/batch audits and PDF download
- Company profile shows "Odpis PDF" button and last audit date
- Database migration for krs_audits, company_pkd, company_financial_reports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 16:46:54 +01:00

137 lines
5.9 KiB
SQL

-- ============================================================
-- Migration: 013_krs_audit.sql
-- Date: 2026-01-13
-- Description: Add KRS Audit table for tracking KRS data extracts
-- ============================================================
-- KRS Audit table - tracks audit history and PDF sources
CREATE TABLE IF NOT EXISTS krs_audits (
id SERIAL PRIMARY KEY,
company_id INTEGER REFERENCES companies(id) ON DELETE CASCADE NOT NULL,
-- Audit timing
audit_date TIMESTAMP DEFAULT NOW() NOT NULL,
-- PDF source info
pdf_filename VARCHAR(255), -- np. "odpis_pelny_0000882964.pdf"
pdf_path TEXT, -- full path to stored PDF
pdf_downloaded_at TIMESTAMP, -- when PDF was fetched from EKRS
-- Extraction status
status VARCHAR(20) DEFAULT 'pending', -- pending, downloading, parsing, completed, error
progress_percent INTEGER DEFAULT 0,
progress_message TEXT,
error_message TEXT,
-- Extracted data summary (for quick display)
extracted_krs VARCHAR(10),
extracted_nazwa TEXT,
extracted_nip VARCHAR(10),
extracted_regon VARCHAR(14),
extracted_forma_prawna VARCHAR(255),
extracted_data_rejestracji DATE,
extracted_kapital_zakladowy NUMERIC(15, 2),
extracted_waluta VARCHAR(3) DEFAULT 'PLN',
extracted_liczba_udzialow INTEGER,
extracted_sposob_reprezentacji TEXT,
-- Counts for quick stats
zarzad_count INTEGER DEFAULT 0,
wspolnicy_count INTEGER DEFAULT 0,
prokurenci_count INTEGER DEFAULT 0,
pkd_count INTEGER DEFAULT 0,
-- Full parsed data as JSON (for reference)
parsed_data JSONB,
-- Audit metadata
audit_version VARCHAR(20) DEFAULT '1.0',
audit_source VARCHAR(50) DEFAULT 'ekrs.ms.gov.pl',
-- Timestamps
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_krs_audits_company_id ON krs_audits(company_id);
CREATE INDEX IF NOT EXISTS idx_krs_audits_audit_date ON krs_audits(audit_date DESC);
CREATE INDEX IF NOT EXISTS idx_krs_audits_status ON krs_audits(status);
-- Company table extensions for KRS data
ALTER TABLE companies ADD COLUMN IF NOT EXISTS krs_registration_date DATE;
ALTER TABLE companies ADD COLUMN IF NOT EXISTS krs_company_agreement_date DATE;
ALTER TABLE companies ADD COLUMN IF NOT EXISTS krs_duration VARCHAR(100);
ALTER TABLE companies ADD COLUMN IF NOT EXISTS krs_representation_rules TEXT;
ALTER TABLE companies ADD COLUMN IF NOT EXISTS capital_currency VARCHAR(3) DEFAULT 'PLN';
ALTER TABLE companies ADD COLUMN IF NOT EXISTS capital_shares_count INTEGER;
ALTER TABLE companies ADD COLUMN IF NOT EXISTS capital_share_value NUMERIC(15, 2);
ALTER TABLE companies ADD COLUMN IF NOT EXISTS is_opp BOOLEAN DEFAULT FALSE;
ALTER TABLE companies ADD COLUMN IF NOT EXISTS krs_last_audit_at TIMESTAMP;
ALTER TABLE companies ADD COLUMN IF NOT EXISTS krs_pdf_path TEXT;
-- PKD codes table (multiple PKD codes per company)
CREATE TABLE IF NOT EXISTS company_pkd (
id SERIAL PRIMARY KEY,
company_id INTEGER REFERENCES companies(id) ON DELETE CASCADE NOT NULL,
pkd_code VARCHAR(10) NOT NULL, -- np. "62.03.Z"
pkd_description TEXT,
is_primary BOOLEAN DEFAULT FALSE, -- przeważający PKD
source VARCHAR(50) DEFAULT 'ekrs', -- ekrs, ceidg
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(company_id, pkd_code)
);
CREATE INDEX IF NOT EXISTS idx_company_pkd_company_id ON company_pkd(company_id);
CREATE INDEX IF NOT EXISTS idx_company_pkd_code ON company_pkd(pkd_code);
CREATE INDEX IF NOT EXISTS idx_company_pkd_primary ON company_pkd(company_id, is_primary);
-- Financial reports table (sprawozdania finansowe)
CREATE TABLE IF NOT EXISTS company_financial_reports (
id SERIAL PRIMARY KEY,
company_id INTEGER REFERENCES companies(id) ON DELETE CASCADE NOT NULL,
period_start DATE,
period_end DATE,
filed_at DATE,
report_type VARCHAR(50) DEFAULT 'annual', -- annual, quarterly
source VARCHAR(50) DEFAULT 'ekrs',
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(company_id, period_start, period_end, report_type)
);
CREATE INDEX IF NOT EXISTS idx_company_financial_reports_company_id ON company_financial_reports(company_id);
-- Add comments
COMMENT ON TABLE krs_audits IS 'KRS audit history - tracks PDF downloads and data extraction';
COMMENT ON COLUMN krs_audits.pdf_path IS 'Full path to stored PDF file on server';
COMMENT ON COLUMN krs_audits.status IS 'Audit status: pending, downloading, parsing, completed, error';
COMMENT ON COLUMN krs_audits.parsed_data IS 'Full extracted data in JSON format';
COMMENT ON TABLE company_pkd IS 'PKD codes for companies - multiple codes per company allowed';
COMMENT ON COLUMN company_pkd.is_primary IS 'TRUE for main business activity (PKD przeważający)';
COMMENT ON TABLE company_financial_reports IS 'Financial reports (sprawozdania finansowe) filed with KRS';
COMMENT ON COLUMN companies.krs_registration_date IS 'Date of first entry in KRS registry';
COMMENT ON COLUMN companies.krs_representation_rules IS 'Rules for company representation from KRS';
COMMENT ON COLUMN companies.krs_last_audit_at IS 'Date of last KRS audit';
COMMENT ON COLUMN companies.krs_pdf_path IS 'Path to latest KRS PDF file';
-- Grant permissions
GRANT ALL ON TABLE krs_audits TO nordabiz_app;
GRANT ALL ON TABLE company_pkd TO nordabiz_app;
GRANT ALL ON TABLE company_financial_reports TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE krs_audits_id_seq TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE company_pkd_id_seq TO nordabiz_app;
GRANT USAGE, SELECT ON SEQUENCE company_financial_reports_id_seq TO nordabiz_app;
-- ============================================================
-- Verification query (run after migration):
-- SELECT c.name, ka.audit_date, ka.status, ka.extracted_kapital_zakladowy
-- FROM companies c
-- LEFT JOIN krs_audits ka ON c.id = ka.company_id
-- WHERE c.krs IS NOT NULL
-- LIMIT 10;
-- ============================================================