Implement full online membership application workflow: - 3-step wizard form with KRS/CEIDG auto-fill - Admin panel for application review (approve/reject/request changes) - Company data update requests for existing members - Dashboard CTA for users without company - API endpoints for NIP lookup and draft management New files: - database/migrations/042_membership_applications.sql - blueprints/membership/ (routes, templates) - blueprints/admin/routes_membership.py - blueprints/api/routes_membership.py - templates/membership/ and templates/admin/membership*.html Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
184 lines
7.2 KiB
SQL
184 lines
7.2 KiB
SQL
-- ============================================================
|
|
-- 042_membership_applications.sql
|
|
-- System Zgłoszeń Członkowskich (Membership Application)
|
|
-- ============================================================
|
|
-- Created: 2026-02-01
|
|
-- Description:
|
|
-- - Creates membership_applications table for new member applications
|
|
-- - Creates company_data_requests table for data update requests
|
|
-- - Full workflow support: draft -> submitted -> approved/rejected
|
|
-- ============================================================
|
|
|
|
-- ============================================================
|
|
-- 1. MEMBERSHIP APPLICATIONS TABLE
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS membership_applications (
|
|
id SERIAL PRIMARY KEY,
|
|
|
|
-- Kto złożył
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
-- Status workflow
|
|
-- draft: zapisany szkic
|
|
-- submitted: wysłany do rozpatrzenia
|
|
-- under_review: w trakcie rozpatrywania
|
|
-- changes_requested: prośba o poprawki
|
|
-- approved: zatwierdzony
|
|
-- rejected: odrzucony
|
|
status VARCHAR(20) NOT NULL DEFAULT 'draft',
|
|
|
|
-- Dane firmy (strona 1 - Deklaracja)
|
|
company_name VARCHAR(255) NOT NULL,
|
|
nip VARCHAR(10) NOT NULL,
|
|
address_postal_code VARCHAR(6),
|
|
address_city VARCHAR(100),
|
|
address_street VARCHAR(200),
|
|
address_number VARCHAR(50),
|
|
|
|
-- Delegaci do Walnego Zgromadzenia
|
|
delegate_1 VARCHAR(150),
|
|
delegate_2 VARCHAR(150),
|
|
delegate_3 VARCHAR(150),
|
|
|
|
-- Kontakt (strona 2 - Karta Informacyjna)
|
|
website VARCHAR(255),
|
|
email VARCHAR(255) NOT NULL,
|
|
phone VARCHAR(30),
|
|
short_name VARCHAR(100),
|
|
|
|
-- Informacje dodatkowe
|
|
description TEXT,
|
|
founded_date DATE,
|
|
employee_count INTEGER,
|
|
show_employee_count BOOLEAN DEFAULT FALSE,
|
|
annual_revenue VARCHAR(50),
|
|
related_companies JSONB, -- ["Firma A", "Firma B"]
|
|
|
|
-- Sekcje i typ działalności (strona 3)
|
|
-- Sekcje: turystyka, szkolnictwo, budownictwo, produkcja, handel, uslugi, inna
|
|
sections JSONB NOT NULL DEFAULT '[]',
|
|
sections_other VARCHAR(200), -- jeśli wybrano "inna"
|
|
|
|
-- Typ działalności
|
|
-- jdg, spolka_cywilna, spolka_jawna, spolka_partnerska, spolka_komandytowa,
|
|
-- spolka_komandytowo_akcyjna, sp_z_oo_komandytowa, spolka_akcyjna, sp_z_oo, inna
|
|
business_type VARCHAR(50) NOT NULL DEFAULT 'sp_z_oo',
|
|
business_type_other VARCHAR(100),
|
|
|
|
-- Zgody RODO
|
|
consent_email BOOLEAN NOT NULL DEFAULT FALSE,
|
|
consent_email_address VARCHAR(255),
|
|
consent_sms BOOLEAN DEFAULT FALSE,
|
|
consent_sms_phone VARCHAR(30),
|
|
|
|
-- Oświadczenie końcowe
|
|
declaration_accepted BOOLEAN NOT NULL DEFAULT FALSE,
|
|
declaration_accepted_at TIMESTAMP,
|
|
declaration_ip_address VARCHAR(45), -- IPv4/IPv6
|
|
|
|
-- Dane z rejestru KRS/CEIDG
|
|
registry_source VARCHAR(20), -- 'KRS', 'CEIDG', 'manual'
|
|
registry_data JSONB, -- surowe dane z API
|
|
krs_number VARCHAR(10), -- numer KRS jeśli dotyczy
|
|
regon VARCHAR(14),
|
|
|
|
-- Workflow timestamps
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW(),
|
|
submitted_at TIMESTAMP,
|
|
reviewed_at TIMESTAMP,
|
|
reviewed_by_id INTEGER REFERENCES users(id),
|
|
review_comment TEXT,
|
|
|
|
-- Po zatwierdzeniu
|
|
company_id INTEGER REFERENCES companies(id),
|
|
member_number VARCHAR(20) -- Nr ewidencyjny członka
|
|
);
|
|
|
|
-- Indeksy
|
|
CREATE INDEX IF NOT EXISTS idx_membership_app_status ON membership_applications(status);
|
|
CREATE INDEX IF NOT EXISTS idx_membership_app_user ON membership_applications(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_membership_app_nip ON membership_applications(nip);
|
|
CREATE INDEX IF NOT EXISTS idx_membership_app_created ON membership_applications(created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_membership_app_submitted ON membership_applications(submitted_at DESC);
|
|
|
|
-- Komentarze
|
|
COMMENT ON TABLE membership_applications IS 'Deklaracje przystąpienia do Izby NORDA';
|
|
COMMENT ON COLUMN membership_applications.status IS 'Status: draft, submitted, under_review, changes_requested, approved, rejected';
|
|
COMMENT ON COLUMN membership_applications.sections IS 'JSON array sekcji tematycznych: turystyka, szkolnictwo, budownictwo, produkcja, handel, uslugi, inna';
|
|
COMMENT ON COLUMN membership_applications.registry_source IS 'Źródło danych: KRS, CEIDG lub manual (ręcznie)';
|
|
COMMENT ON COLUMN membership_applications.member_number IS 'Numer ewidencyjny członka nadawany przy zatwierdzeniu';
|
|
|
|
-- ============================================================
|
|
-- 2. COMPANY DATA REQUESTS TABLE
|
|
-- ============================================================
|
|
-- Prostsza tabela dla uzupełnienia danych istniejącej firmy
|
|
|
|
CREATE TABLE IF NOT EXISTS company_data_requests (
|
|
id SERIAL PRIMARY KEY,
|
|
|
|
-- Typ zgłoszenia
|
|
-- update_data: uzupełnienie danych istniejącej firmy (np. brak NIP)
|
|
-- claim_company: przejęcie firmy bez właściciela
|
|
request_type VARCHAR(30) NOT NULL DEFAULT 'update_data',
|
|
|
|
-- Kto zgłasza
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
|
|
-- Firma (jeśli istnieje)
|
|
company_id INTEGER REFERENCES companies(id) ON DELETE SET NULL,
|
|
|
|
-- NIP wprowadzony przez użytkownika
|
|
nip VARCHAR(10) NOT NULL,
|
|
|
|
-- Dane pobrane z KRS/CEIDG
|
|
registry_source VARCHAR(20), -- 'KRS', 'CEIDG'
|
|
fetched_data JSONB,
|
|
|
|
-- Status
|
|
-- pending: oczekuje na rozpatrzenie
|
|
-- approved: zatwierdzono, dane zaktualizowane
|
|
-- rejected: odrzucono
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
|
|
-- Workflow
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
reviewed_at TIMESTAMP,
|
|
reviewed_by_id INTEGER REFERENCES users(id),
|
|
review_comment TEXT,
|
|
|
|
-- Notatka użytkownika
|
|
user_note TEXT,
|
|
|
|
-- Które pola zostały zaktualizowane (przy approve)
|
|
applied_fields JSONB
|
|
);
|
|
|
|
-- Indeksy
|
|
CREATE INDEX IF NOT EXISTS idx_data_request_status ON company_data_requests(status);
|
|
CREATE INDEX IF NOT EXISTS idx_data_request_user ON company_data_requests(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_data_request_company ON company_data_requests(company_id);
|
|
CREATE INDEX IF NOT EXISTS idx_data_request_nip ON company_data_requests(nip);
|
|
CREATE INDEX IF NOT EXISTS idx_data_request_created ON company_data_requests(created_at DESC);
|
|
|
|
-- Komentarze
|
|
COMMENT ON TABLE company_data_requests IS 'Zgłoszenia uzupełnienia danych firmy przez użytkowników';
|
|
COMMENT ON COLUMN company_data_requests.request_type IS 'Typ: update_data (uzupełnienie), claim_company (przejęcie)';
|
|
COMMENT ON COLUMN company_data_requests.fetched_data IS 'Dane pobrane z KRS/CEIDG jako JSON';
|
|
COMMENT ON COLUMN company_data_requests.applied_fields IS 'Lista pól zaktualizowanych przy zatwierdzeniu';
|
|
|
|
-- ============================================================
|
|
-- 3. GRANT PERMISSIONS
|
|
-- ============================================================
|
|
|
|
GRANT ALL ON TABLE membership_applications TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE membership_applications_id_seq TO nordabiz_app;
|
|
|
|
GRANT ALL ON TABLE company_data_requests TO nordabiz_app;
|
|
GRANT USAGE, SELECT ON SEQUENCE company_data_requests_id_seq TO nordabiz_app;
|
|
|
|
-- ============================================================
|
|
-- MIGRATION COMPLETE
|
|
-- ============================================================
|