chore: каркас проекта — контракты, справочник услуг, синтетические фикстуры
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
-- Схема MedArchive. Четыре сущности из ТЗ §3, адаптированные под реальные данные:
|
||||
-- многотарифные цены (резидент/нерезидент/СНГ/…) хранятся в prices (jsonb),
|
||||
-- а два главных тарифа продублированы отдельными колонками под ТЗ и API.
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS vector; -- pgvector для семантического сопоставления
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm; -- триграммы для нечёткого поиска
|
||||
|
||||
-- Эталонный справочник услуг (1281 позиция, загружается из xlsx).
|
||||
CREATE TABLE service (
|
||||
service_id text PRIMARY KEY, -- «<ID>-<Code>» из справочника
|
||||
specialty text NOT NULL DEFAULT '', -- специальность = категория + сужение поиска
|
||||
name_ru text NOT NULL,
|
||||
name_norm text NOT NULL, -- нормализованная форма для точного совпадения
|
||||
tarificator_code text, -- код тарификатора, если задан
|
||||
synonyms jsonb NOT NULL DEFAULT '[]'::jsonb, -- наращиваем при ручной верификации
|
||||
embedding vector(384), -- эмбеддинг name_ru (multilingual)
|
||||
is_active boolean NOT NULL DEFAULT true
|
||||
);
|
||||
CREATE INDEX service_tarificator_idx ON service (tarificator_code) WHERE tarificator_code IS NOT NULL;
|
||||
CREATE INDEX service_name_trgm_idx ON service USING gin (name_ru gin_trgm_ops);
|
||||
CREATE INDEX service_embedding_idx ON service USING hnsw (embedding vector_cosine_ops);
|
||||
|
||||
-- Клиника-партнёр.
|
||||
CREATE TABLE partner (
|
||||
partner_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name text NOT NULL,
|
||||
city text,
|
||||
address text,
|
||||
bin varchar(12), -- БИН организации, для дедупликации
|
||||
contact_email text,
|
||||
contact_phone text,
|
||||
is_active boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE UNIQUE INDEX partner_bin_idx ON partner (bin) WHERE bin IS NOT NULL;
|
||||
|
||||
-- Исходный прайс-документ (один файл = прайс одной клиники на дату).
|
||||
CREATE TABLE price_document (
|
||||
doc_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
partner_id uuid NOT NULL REFERENCES partner(partner_id),
|
||||
file_name text NOT NULL,
|
||||
file_format text NOT NULL, -- pdf / scan_pdf / docx / xlsx / xls
|
||||
effective_date date, -- дата вступления в силу (год из имени файла)
|
||||
parsed_at timestamptz,
|
||||
parse_status text NOT NULL DEFAULT 'pending', -- pending/processing/done/error/needs_review
|
||||
parse_log text,
|
||||
raw_content text -- сырой извлечённый текст для аудита
|
||||
);
|
||||
|
||||
-- Позиция прайса (услуга + цены). Это рабочая лошадка системы.
|
||||
CREATE TABLE price_item (
|
||||
item_id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
doc_id uuid NOT NULL REFERENCES price_document(doc_id),
|
||||
partner_id uuid NOT NULL REFERENCES partner(partner_id), -- денормализация ради скорости
|
||||
service_name_raw text NOT NULL, -- название как в документе
|
||||
service_code_source text, -- код из источника (внутренний или тарификатора)
|
||||
service_id text REFERENCES service(service_id), -- нормализованная услуга (nullable)
|
||||
prices jsonb NOT NULL DEFAULT '{}'::jsonb, -- {resident, nonresident, cis, far, insurance, partner}
|
||||
price_resident_kzt numeric, -- главный тариф, продублирован под ТЗ/API
|
||||
price_nonresident_kzt numeric,
|
||||
currency_original text NOT NULL DEFAULT 'KZT',
|
||||
unit text,
|
||||
effective_date date,
|
||||
map_method text, -- code/exact/embedding/fuzzy/manual
|
||||
map_confidence numeric,
|
||||
is_verified boolean NOT NULL DEFAULT false,
|
||||
verification_note text,
|
||||
is_active boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX price_item_service_idx ON price_item (service_id);
|
||||
CREATE INDEX price_item_partner_idx ON price_item (partner_id);
|
||||
CREATE INDEX price_item_unmatched_idx ON price_item (service_id) WHERE service_id IS NULL;
|
||||
CREATE INDEX price_item_raw_trgm_idx ON price_item USING gin (service_name_raw gin_trgm_ops);
|
||||
-- Активная позиция уникальна по клинике, названию и дате прайса (версионирование — через is_active).
|
||||
CREATE UNIQUE INDEX price_item_active_idx
|
||||
ON price_item (partner_id, service_name_raw, effective_date) WHERE is_active;
|
||||
Reference in New Issue
Block a user