🚀 MVP: FastAPI + React форма с SMS верификацией
✅ Инфраструктура: PostgreSQL, Redis, RabbitMQ, S3 ✅ Backend: SMS сервис + API endpoints ✅ Frontend: React форма (3 шага) + SMS верификация
This commit is contained in:
306
backend/db/init.sql
Normal file
306
backend/db/init.sql
Normal file
@@ -0,0 +1,306 @@
|
||||
-- ERV Platform Database Initialization Script
|
||||
-- PostgreSQL 16+
|
||||
|
||||
-- Enable extensions
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: claims (Основные заявки)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS claims (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
claim_number VARCHAR(50) UNIQUE NOT NULL,
|
||||
|
||||
-- Тип страхования
|
||||
insurance_type VARCHAR(50) NOT NULL DEFAULT 'erv_travel',
|
||||
case_type VARCHAR(100), -- например: 'flight_delay', 'medical', 'baggage_loss'
|
||||
|
||||
-- Данные клиента
|
||||
client_phone VARCHAR(20) NOT NULL,
|
||||
client_email VARCHAR(255),
|
||||
client_inn VARCHAR(12),
|
||||
client_full_name VARCHAR(500),
|
||||
|
||||
-- Данные полиса
|
||||
policy_number VARCHAR(100),
|
||||
policy_series VARCHAR(50),
|
||||
|
||||
-- Статус обработки
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'draft', -- draft, processing, crm_sent, completed, error
|
||||
crm_id VARCHAR(100), -- ID в Vtiger CRM
|
||||
|
||||
-- Данные для аналитики
|
||||
source VARCHAR(100), -- откуда пришла заявка: 'web_form', 'api', 'mobile_app'
|
||||
user_agent TEXT,
|
||||
ip_address INET,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
submitted_at TIMESTAMP WITH TIME ZONE,
|
||||
completed_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- JSON поля для гибкости
|
||||
form_data JSONB, -- все данные формы
|
||||
metadata JSONB -- дополнительные метаданные
|
||||
);
|
||||
|
||||
-- Индексы для claims
|
||||
CREATE INDEX idx_claims_claim_number ON claims(claim_number);
|
||||
CREATE INDEX idx_claims_status ON claims(status);
|
||||
CREATE INDEX idx_claims_created_at ON claims(created_at DESC);
|
||||
CREATE INDEX idx_claims_client_phone ON claims(client_phone);
|
||||
CREATE INDEX idx_claims_policy_number ON claims(policy_number);
|
||||
CREATE INDEX idx_claims_insurance_type ON claims(insurance_type);
|
||||
CREATE INDEX idx_claims_form_data_gin ON claims USING gin(form_data);
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: claim_files (Файлы к заявкам)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS claim_files (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
claim_id UUID NOT NULL REFERENCES claims(id) ON DELETE CASCADE,
|
||||
|
||||
-- Файл
|
||||
file_name VARCHAR(255) NOT NULL,
|
||||
file_path VARCHAR(500) NOT NULL,
|
||||
file_size BIGINT,
|
||||
mime_type VARCHAR(100),
|
||||
file_type VARCHAR(50), -- 'passport', 'ticket', 'receipt', 'medical_doc', etc.
|
||||
|
||||
-- S3 данные (если используется)
|
||||
s3_bucket VARCHAR(255),
|
||||
s3_key VARCHAR(500),
|
||||
s3_url TEXT,
|
||||
|
||||
-- OCR/AI обработка
|
||||
ocr_status VARCHAR(50), -- 'pending', 'processing', 'completed', 'error'
|
||||
ocr_text TEXT,
|
||||
ai_extracted_data JSONB,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
processed_at TIMESTAMP WITH TIME ZONE
|
||||
);
|
||||
|
||||
-- Индексы для claim_files
|
||||
CREATE INDEX idx_claim_files_claim_id ON claim_files(claim_id);
|
||||
CREATE INDEX idx_claim_files_file_type ON claim_files(file_type);
|
||||
CREATE INDEX idx_claim_files_ocr_status ON claim_files(ocr_status);
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: processing_logs (Логи обработки)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS processing_logs (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
claim_id UUID REFERENCES claims(id) ON DELETE CASCADE,
|
||||
|
||||
-- Лог
|
||||
level VARCHAR(20) NOT NULL, -- 'debug', 'info', 'warning', 'error', 'critical'
|
||||
message TEXT NOT NULL,
|
||||
context JSONB, -- дополнительный контекст
|
||||
|
||||
-- Источник
|
||||
source VARCHAR(100), -- 'ocr_service', 'ai_service', 'flight_api', 'crm_integration', etc.
|
||||
function_name VARCHAR(200),
|
||||
|
||||
-- Ошибки
|
||||
error_type VARCHAR(100),
|
||||
error_traceback TEXT,
|
||||
|
||||
-- Timestamp
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Индексы для processing_logs
|
||||
CREATE INDEX idx_processing_logs_claim_id ON processing_logs(claim_id);
|
||||
CREATE INDEX idx_processing_logs_level ON processing_logs(level);
|
||||
CREATE INDEX idx_processing_logs_created_at ON processing_logs(created_at DESC);
|
||||
CREATE INDEX idx_processing_logs_source ON processing_logs(source);
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: api_calls (Логи внешних API вызовов)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS api_calls (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
claim_id UUID REFERENCES claims(id) ON DELETE SET NULL,
|
||||
|
||||
-- API детали
|
||||
api_name VARCHAR(100) NOT NULL, -- 'ocr_service', 'openrouter_ai', 'flightaware', 'nspk_banks', etc.
|
||||
endpoint VARCHAR(500),
|
||||
method VARCHAR(10), -- 'GET', 'POST', etc.
|
||||
|
||||
-- Запрос
|
||||
request_headers JSONB,
|
||||
request_body JSONB,
|
||||
|
||||
-- Ответ
|
||||
response_status INTEGER,
|
||||
response_headers JSONB,
|
||||
response_body JSONB,
|
||||
|
||||
-- Производительность
|
||||
duration_ms INTEGER, -- длительность запроса в миллисекундах
|
||||
|
||||
-- Результат
|
||||
success BOOLEAN DEFAULT FALSE,
|
||||
error_message TEXT,
|
||||
|
||||
-- Timestamp
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Индексы для api_calls
|
||||
CREATE INDEX idx_api_calls_claim_id ON api_calls(claim_id);
|
||||
CREATE INDEX idx_api_calls_api_name ON api_calls(api_name);
|
||||
CREATE INDEX idx_api_calls_success ON api_calls(success);
|
||||
CREATE INDEX idx_api_calls_created_at ON api_calls(created_at DESC);
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: queue_tasks (Задачи в очереди RabbitMQ)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS queue_tasks (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
claim_id UUID REFERENCES claims(id) ON DELETE CASCADE,
|
||||
|
||||
-- Задача
|
||||
task_type VARCHAR(100) NOT NULL, -- 'ocr_processing', 'ai_extraction', 'flight_check', etc.
|
||||
queue_name VARCHAR(100) NOT NULL,
|
||||
priority INTEGER DEFAULT 5, -- 1-10, где 10 - максимальный приоритет
|
||||
|
||||
-- Данные
|
||||
task_data JSONB,
|
||||
|
||||
-- Статус
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'pending', -- pending, processing, completed, failed, retry
|
||||
attempts INTEGER DEFAULT 0,
|
||||
max_attempts INTEGER DEFAULT 3,
|
||||
|
||||
-- Результат
|
||||
result JSONB,
|
||||
error_message TEXT,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
started_at TIMESTAMP WITH TIME ZONE,
|
||||
completed_at TIMESTAMP WITH TIME ZONE,
|
||||
next_retry_at TIMESTAMP WITH TIME ZONE
|
||||
);
|
||||
|
||||
-- Индексы для queue_tasks
|
||||
CREATE INDEX idx_queue_tasks_claim_id ON queue_tasks(claim_id);
|
||||
CREATE INDEX idx_queue_tasks_status ON queue_tasks(status);
|
||||
CREATE INDEX idx_queue_tasks_task_type ON queue_tasks(task_type);
|
||||
CREATE INDEX idx_queue_tasks_created_at ON queue_tasks(created_at DESC);
|
||||
CREATE INDEX idx_queue_tasks_next_retry ON queue_tasks(next_retry_at) WHERE status = 'retry';
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: metrics (Метрики системы)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS metrics (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
-- Метрика
|
||||
metric_name VARCHAR(100) NOT NULL,
|
||||
metric_value NUMERIC(20, 4),
|
||||
metric_unit VARCHAR(50), -- 'ms', 'count', 'bytes', '%', etc.
|
||||
|
||||
-- Теги для группировки
|
||||
tags JSONB,
|
||||
|
||||
-- Timestamp
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Индексы для metrics
|
||||
CREATE INDEX idx_metrics_metric_name ON metrics(metric_name);
|
||||
CREATE INDEX idx_metrics_created_at ON metrics(created_at DESC);
|
||||
CREATE INDEX idx_metrics_tags_gin ON metrics USING gin(tags);
|
||||
|
||||
-- ============================================
|
||||
-- ТАБЛИЦА: cache_entries (Кеш для редких запросов)
|
||||
-- ============================================
|
||||
CREATE TABLE IF NOT EXISTS cache_entries (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
|
||||
-- Ключ-значение
|
||||
cache_key VARCHAR(255) UNIQUE NOT NULL,
|
||||
cache_value JSONB,
|
||||
|
||||
-- TTL
|
||||
expires_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Индексы для cache_entries
|
||||
CREATE INDEX idx_cache_entries_key ON cache_entries(cache_key);
|
||||
CREATE INDEX idx_cache_entries_expires ON cache_entries(expires_at);
|
||||
|
||||
-- Автоматическая очистка устаревшего кеша
|
||||
CREATE OR REPLACE FUNCTION cleanup_expired_cache()
|
||||
RETURNS void AS $$
|
||||
BEGIN
|
||||
DELETE FROM cache_entries WHERE expires_at < CURRENT_TIMESTAMP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- ============================================
|
||||
-- ТРИГГЕРЫ
|
||||
-- ============================================
|
||||
|
||||
-- Автоматическое обновление updated_at для claims
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER update_claims_updated_at
|
||||
BEFORE UPDATE ON claims
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- ============================================
|
||||
-- ПРЕДСТАВЛЕНИЯ (VIEWS)
|
||||
-- ============================================
|
||||
|
||||
-- Статистика по заявкам
|
||||
CREATE OR REPLACE VIEW claims_statistics AS
|
||||
SELECT
|
||||
DATE(created_at) as date,
|
||||
insurance_type,
|
||||
status,
|
||||
COUNT(*) as count,
|
||||
AVG(EXTRACT(EPOCH FROM (completed_at - created_at))) as avg_processing_time_seconds
|
||||
FROM claims
|
||||
GROUP BY DATE(created_at), insurance_type, status;
|
||||
|
||||
-- Статистика по API вызовам
|
||||
CREATE OR REPLACE VIEW api_performance AS
|
||||
SELECT
|
||||
api_name,
|
||||
DATE(created_at) as date,
|
||||
COUNT(*) as total_calls,
|
||||
SUM(CASE WHEN success THEN 1 ELSE 0 END) as successful_calls,
|
||||
AVG(duration_ms) as avg_duration_ms,
|
||||
MAX(duration_ms) as max_duration_ms
|
||||
FROM api_calls
|
||||
GROUP BY api_name, DATE(created_at);
|
||||
|
||||
-- ============================================
|
||||
-- НАЧАЛЬНЫЕ ДАННЫЕ
|
||||
-- ============================================
|
||||
|
||||
-- Можно добавить тестовые данные для разработки
|
||||
-- INSERT INTO claims (claim_number, client_phone, insurance_type, status)
|
||||
-- VALUES ('TEST-001', '+79001234567', 'erv_travel', 'draft');
|
||||
|
||||
-- Завершение
|
||||
SELECT 'Database initialized successfully!' as message;
|
||||
|
||||
Reference in New Issue
Block a user