nordabiz/database/migrations/003_membership_fees.sql
Maciej Pienczyn 055d9c1cfa Add company logos, migration and docs
- Add 80+ company logo images (webp/svg)
- Add membership_fees migration SQL
- Add incident report doc
- Update .gitignore for worktrees

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 22:31:17 +01:00

121 lines
4.2 KiB
SQL

-- ============================================================
-- NordaBiz - Migration 003: Membership Fees Management
-- ============================================================
-- Created: 2026-01-04
-- Description:
-- - Creates membership_fees table for tracking monthly payments
-- - Creates membership_fee_config for fee amount configuration
-- - Creates announcements table for board communications
-- ============================================================
-- ============================================================
-- 1. MEMBERSHIP FEES TABLE
-- ============================================================
CREATE TABLE IF NOT EXISTS membership_fees (
id SERIAL PRIMARY KEY,
company_id INTEGER NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
-- Period
fee_year INTEGER NOT NULL,
fee_month INTEGER NOT NULL CHECK (fee_month >= 1 AND fee_month <= 12),
-- Amounts
amount NUMERIC(10, 2) NOT NULL,
amount_paid NUMERIC(10, 2) DEFAULT 0,
-- Status: pending, paid, partial, overdue, waived
status VARCHAR(20) DEFAULT 'pending',
-- Payment details
payment_date DATE,
payment_method VARCHAR(50),
payment_reference VARCHAR(100),
-- Admin tracking
recorded_by INTEGER REFERENCES users(id),
recorded_at TIMESTAMP,
notes TEXT,
-- Timestamps
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- Unique constraint: one fee record per company per month
CONSTRAINT uq_company_fee_period UNIQUE (company_id, fee_year, fee_month)
);
CREATE INDEX IF NOT EXISTS idx_membership_fees_company ON membership_fees(company_id);
CREATE INDEX IF NOT EXISTS idx_membership_fees_period ON membership_fees(fee_year, fee_month);
CREATE INDEX IF NOT EXISTS idx_membership_fees_status ON membership_fees(status);
COMMENT ON TABLE membership_fees IS 'Monthly membership fee tracking for Norda Biznes companies';
-- ============================================================
-- 2. FEE CONFIGURATION TABLE
-- ============================================================
CREATE TABLE IF NOT EXISTS membership_fee_config (
id SERIAL PRIMARY KEY,
scope VARCHAR(20) NOT NULL, -- 'global', 'category', 'company'
category_id INTEGER REFERENCES categories(id),
company_id INTEGER REFERENCES companies(id),
monthly_amount NUMERIC(10, 2) NOT NULL,
valid_from DATE NOT NULL,
valid_until DATE,
created_by INTEGER REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW(),
notes TEXT
);
CREATE INDEX IF NOT EXISTS idx_fee_config_scope ON membership_fee_config(scope);
CREATE INDEX IF NOT EXISTS idx_fee_config_validity ON membership_fee_config(valid_from, valid_until);
-- Insert default global fee (100 PLN)
INSERT INTO membership_fee_config (scope, monthly_amount, valid_from, notes)
VALUES ('global', 100.00, '2026-01-01', 'Domyslna skladka miesieczna')
ON CONFLICT DO NOTHING;
COMMENT ON TABLE membership_fee_config IS 'Configuration for membership fee amounts';
-- ============================================================
-- 3. ANNOUNCEMENTS TABLE
-- ============================================================
CREATE TABLE IF NOT EXISTS announcements (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
-- Types: general, fees, event, important, urgent
announcement_type VARCHAR(50) DEFAULT 'general',
is_published BOOLEAN DEFAULT FALSE,
is_pinned BOOLEAN DEFAULT FALSE,
publish_date TIMESTAMP,
expire_date TIMESTAMP,
-- Target: all, fee_pending, fee_overdue
target_audience VARCHAR(50) DEFAULT 'all',
author_id INTEGER NOT NULL REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_announcements_published ON announcements(is_published);
CREATE INDEX IF NOT EXISTS idx_announcements_type ON announcements(announcement_type);
CREATE INDEX IF NOT EXISTS idx_announcements_dates ON announcements(publish_date, expire_date);
COMMENT ON TABLE announcements IS 'Board announcements visible to logged-in members';
-- ============================================================
-- MIGRATION COMPLETE
-- ============================================================