Files
mkd/backend/migrate_development_module.sql
2026-02-04 00:17:04 +05:00

150 lines
7.5 KiB
PL/PgSQL
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ========= МОДУЛЬ РАЗВИТИЯ: МИГРАЦИЯ =========
-- Создание таблиц для модуля "Отдел развития"
-- 1. Воронка потенциальных объектов
CREATE TABLE IF NOT EXISTS development_pipeline (
id VARCHAR(50) PRIMARY KEY,
address TEXT NOT NULL,
type VARCHAR(10) NOT NULL CHECK (type IN ('old', 'new')),
floors INTEGER NOT NULL,
area NUMERIC(10, 2) NOT NULL,
apartments INTEGER NOT NULL,
status VARCHAR(30) NOT NULL CHECK (status IN ('incoming', 'analysis', 'agenda_approval', 'in_person', 'absentee', 'protocol_formation', 'protocol_to_gzhi', 'gzhi_order', 'success', 'failure')),
probability INTEGER NOT NULL CHECK (probability >= 0 AND probability <= 100),
expected_revenue NUMERIC(15, 2) NOT NULL DEFAULT 0,
manager TEXT NOT NULL,
building_id VARCHAR(50) REFERENCES buildings(id) ON DELETE SET NULL,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dev_pipeline_status ON development_pipeline(status);
CREATE INDEX IF NOT EXISTS idx_dev_pipeline_building ON development_pipeline(building_id);
-- 2. Собрания собственников (ОСС)
CREATE TABLE IF NOT EXISTS development_oss_sessions (
id VARCHAR(50) PRIMARY KEY,
building_id VARCHAR(50) REFERENCES buildings(id) ON DELETE CASCADE,
address TEXT NOT NULL,
start_date DATE NOT NULL,
end_date DATE NOT NULL,
quorum_current NUMERIC(10, 2) NOT NULL DEFAULT 0,
quorum_total NUMERIC(10, 2) NOT NULL,
status VARCHAR(20) NOT NULL CHECK (status IN ('active', 'planned', 'completed')),
type VARCHAR(20) NOT NULL CHECK (type IN ('annual', 'extraordinary')),
description TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dev_oss_building ON development_oss_sessions(building_id);
CREATE INDEX IF NOT EXISTS idx_dev_oss_status ON development_oss_sessions(status);
CREATE INDEX IF NOT EXISTS idx_dev_oss_dates ON development_oss_sessions(start_date, end_date);
-- 3. Технические аудиты
CREATE TABLE IF NOT EXISTS development_audits (
id VARCHAR(50) PRIMARY KEY,
building_id VARCHAR(50) REFERENCES buildings(id) ON DELETE CASCADE,
address TEXT NOT NULL,
wear_percent INTEGER NOT NULL CHECK (wear_percent >= 0 AND wear_percent <= 100),
roof_condition VARCHAR(10) NOT NULL CHECK (roof_condition IN ('good', 'poor', 'fair')),
basement_condition VARCHAR(10) NOT NULL CHECK (basement_condition IN ('good', 'poor', 'fair')),
calculated_tariff NUMERIC(10, 2) NOT NULL,
projected_margin NUMERIC(5, 2) NOT NULL,
audit_date DATE NOT NULL DEFAULT CURRENT_DATE,
auditor_name TEXT,
defect_list_url TEXT,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dev_audits_building ON development_audits(building_id);
CREATE INDEX IF NOT EXISTS idx_dev_audits_date ON development_audits(audit_date DESC);
-- 4. Маркетинговые активности
CREATE TABLE IF NOT EXISTS development_marketing_activities (
id VARCHAR(50) PRIMARY KEY,
building_id VARCHAR(50) REFERENCES buildings(id) ON DELETE CASCADE,
address TEXT NOT NULL,
activists_count INTEGER NOT NULL DEFAULT 0,
meetings_held INTEGER NOT NULL DEFAULT 0,
ads_distributed INTEGER NOT NULL DEFAULT 0,
competitor TEXT,
status VARCHAR(20) NOT NULL CHECK (status IN ('voting', 'my_house', 'competitor_house')),
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dev_marketing_building ON development_marketing_activities(building_id);
CREATE INDEX IF NOT EXISTS idx_dev_marketing_status ON development_marketing_activities(status);
-- 5. Координаты зданий для карты присутствия
CREATE TABLE IF NOT EXISTS development_building_locations (
id BIGSERIAL PRIMARY KEY,
building_id VARCHAR(50) REFERENCES buildings(id) ON DELETE CASCADE,
address TEXT NOT NULL,
latitude NUMERIC(10, 7),
longitude NUMERIC(10, 7),
status VARCHAR(20) NOT NULL CHECK (status IN ('ours', 'voting', 'competitor')),
competitor_name TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(building_id)
);
CREATE INDEX IF NOT EXISTS idx_dev_locations_building ON development_building_locations(building_id);
CREATE INDEX IF NOT EXISTS idx_dev_locations_status ON development_building_locations(status);
-- 6. Реестр участников ОСС
CREATE TABLE IF NOT EXISTS development_oss_registry (
id BIGSERIAL PRIMARY KEY,
oss_session_id VARCHAR(50) NOT NULL REFERENCES development_oss_sessions(id) ON DELETE CASCADE,
apartment TEXT NOT NULL,
owner_name TEXT,
area NUMERIC(10, 2) NOT NULL,
ballot_submitted BOOLEAN DEFAULT FALSE,
ballot_date DATE,
vote_result VARCHAR(20) CHECK (vote_result IN ('for', 'against', 'abstain')),
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_dev_oss_registry_session ON development_oss_registry(oss_session_id);
-- Триггеры для автоматического обновления 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_dev_pipeline_updated_at ON development_pipeline;
CREATE TRIGGER update_dev_pipeline_updated_at BEFORE UPDATE ON development_pipeline
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_dev_oss_sessions_updated_at ON development_oss_sessions;
CREATE TRIGGER update_dev_oss_sessions_updated_at BEFORE UPDATE ON development_oss_sessions
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_dev_audits_updated_at ON development_audits;
CREATE TRIGGER update_dev_audits_updated_at BEFORE UPDATE ON development_audits
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_dev_marketing_activities_updated_at ON development_marketing_activities;
CREATE TRIGGER update_dev_marketing_activities_updated_at BEFORE UPDATE ON development_marketing_activities
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_dev_building_locations_updated_at ON development_building_locations;
CREATE TRIGGER update_dev_building_locations_updated_at BEFORE UPDATE ON development_building_locations
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
DROP TRIGGER IF EXISTS update_dev_oss_registry_updated_at ON development_oss_registry;
CREATE TRIGGER update_dev_oss_registry_updated_at BEFORE UPDATE ON development_oss_registry
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();