150 lines
7.5 KiB
MySQL
150 lines
7.5 KiB
MySQL
|
|
-- ========= МОДУЛЬ РАЗВИТИЯ: МИГРАЦИЯ =========
|
|||
|
|
-- Создание таблиц для модуля "Отдел развития"
|
|||
|
|
|
|||
|
|
-- 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();
|