151 lines
6.5 KiB
SQL
151 lines
6.5 KiB
SQL
-- Контентные разделы: публикации, отзывы, документы, галерея, меню, страницы.
|
||
|
||
-- Новости, статьи и акции устроены одинаково, различаются только kind.
|
||
-- У акций дополнительно работают starts_at / ends_at.
|
||
CREATE TABLE posts (
|
||
id bigserial PRIMARY KEY,
|
||
kind text NOT NULL
|
||
CHECK (kind IN ('news', 'article', 'promo')),
|
||
slug text NOT NULL,
|
||
title text NOT NULL,
|
||
lead text NOT NULL DEFAULT '',
|
||
blocks jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||
image_id bigint REFERENCES media (id) ON DELETE SET NULL,
|
||
starts_at date,
|
||
ends_at date,
|
||
published boolean NOT NULL DEFAULT true,
|
||
published_at timestamptz NOT NULL DEFAULT now(),
|
||
seo_title text NOT NULL DEFAULT '',
|
||
seo_description text NOT NULL DEFAULT '',
|
||
seo_h1 text NOT NULL DEFAULT '',
|
||
legacy_id bigint,
|
||
created_at timestamptz NOT NULL DEFAULT now(),
|
||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||
deleted_at timestamptz
|
||
);
|
||
|
||
CREATE UNIQUE INDEX posts_kind_slug_idx ON posts (kind, slug) WHERE deleted_at IS NULL;
|
||
CREATE INDEX posts_kind_published_idx ON posts (kind, published, published_at DESC);
|
||
|
||
CREATE TABLE reviews (
|
||
id bigserial PRIMARY KEY,
|
||
author_name text NOT NULL,
|
||
author_photo_id bigint REFERENCES media (id) ON DELETE SET NULL,
|
||
rating int CHECK (rating BETWEEN 1 AND 5),
|
||
text text NOT NULL,
|
||
doctor_id bigint REFERENCES doctors (id) ON DELETE SET NULL,
|
||
service_id bigint REFERENCES services (id) ON DELETE SET NULL,
|
||
source text NOT NULL DEFAULT 'site' -- site | yandex | prodoctorov | manual
|
||
CHECK (source IN ('site', 'yandex', 'prodoctorov', 'manual')),
|
||
status text NOT NULL DEFAULT 'pending'
|
||
CHECK (status IN ('pending', 'published', 'rejected')),
|
||
reply text NOT NULL DEFAULT '', -- ответ клиники
|
||
moderated_at timestamptz,
|
||
legacy_id bigint,
|
||
created_at timestamptz NOT NULL DEFAULT now(),
|
||
updated_at timestamptz NOT NULL DEFAULT now()
|
||
);
|
||
|
||
CREATE INDEX reviews_status_idx ON reviews (status, created_at DESC);
|
||
CREATE INDEX reviews_doctor_idx ON reviews (doctor_id) WHERE doctor_id IS NOT NULL;
|
||
|
||
CREATE TABLE faq (
|
||
id bigserial PRIMARY KEY,
|
||
question text NOT NULL,
|
||
answer text NOT NULL,
|
||
service_id bigint REFERENCES services (id) ON DELETE CASCADE, -- NULL = общий вопрос
|
||
sort int NOT NULL DEFAULT 100,
|
||
published boolean NOT NULL DEFAULT true,
|
||
legacy_id bigint
|
||
);
|
||
|
||
CREATE TABLE vacancies (
|
||
id bigserial PRIMARY KEY,
|
||
slug text NOT NULL UNIQUE,
|
||
title text NOT NULL,
|
||
description text NOT NULL DEFAULT '',
|
||
requirements text NOT NULL DEFAULT '',
|
||
conditions text NOT NULL DEFAULT '',
|
||
salary text NOT NULL DEFAULT '',
|
||
branch_id bigint REFERENCES branches (id) ON DELETE SET NULL,
|
||
sort int NOT NULL DEFAULT 100,
|
||
published boolean NOT NULL DEFAULT true,
|
||
legacy_id bigint,
|
||
created_at timestamptz NOT NULL DEFAULT now(),
|
||
updated_at timestamptz NOT NULL DEFAULT now()
|
||
);
|
||
|
||
-- Лицензии, сертификаты, сведения о надзорных органах и прочие документы.
|
||
CREATE TABLE documents (
|
||
id bigserial PRIMARY KEY,
|
||
kind text NOT NULL
|
||
CHECK (kind IN ('license', 'certificate', 'supervisor', 'other')),
|
||
title text NOT NULL,
|
||
body text NOT NULL DEFAULT '',
|
||
file_id bigint REFERENCES media (id) ON DELETE SET NULL,
|
||
preview_id bigint REFERENCES media (id) ON DELETE SET NULL,
|
||
issued_at date,
|
||
sort int NOT NULL DEFAULT 100,
|
||
published boolean NOT NULL DEFAULT true,
|
||
legacy_id bigint
|
||
);
|
||
|
||
CREATE TABLE partners (
|
||
id bigserial PRIMARY KEY,
|
||
name text NOT NULL,
|
||
url text NOT NULL DEFAULT '',
|
||
logo_id bigint REFERENCES media (id) ON DELETE SET NULL,
|
||
sort int NOT NULL DEFAULT 100,
|
||
published boolean NOT NULL DEFAULT true,
|
||
legacy_id bigint
|
||
);
|
||
|
||
CREATE TABLE gallery_albums (
|
||
id bigserial PRIMARY KEY,
|
||
slug text NOT NULL UNIQUE,
|
||
title text NOT NULL,
|
||
branch_id bigint REFERENCES branches (id) ON DELETE SET NULL,
|
||
sort int NOT NULL DEFAULT 100,
|
||
published boolean NOT NULL DEFAULT true
|
||
);
|
||
|
||
CREATE TABLE gallery_photos (
|
||
id bigserial PRIMARY KEY,
|
||
album_id bigint NOT NULL REFERENCES gallery_albums (id) ON DELETE CASCADE,
|
||
media_id bigint NOT NULL REFERENCES media (id) ON DELETE CASCADE,
|
||
caption text NOT NULL DEFAULT '',
|
||
sort int NOT NULL DEFAULT 100
|
||
);
|
||
|
||
-- Меню редактируется в админке, а не зашито в шаблон.
|
||
CREATE TABLE menu_items (
|
||
id bigserial PRIMARY KEY,
|
||
menu text NOT NULL DEFAULT 'main' -- main | footer | mobile
|
||
CHECK (menu IN ('main', 'footer', 'mobile')),
|
||
parent_id bigint REFERENCES menu_items (id) ON DELETE CASCADE,
|
||
title text NOT NULL,
|
||
url text NOT NULL DEFAULT '',
|
||
-- если задан service_id, ссылка строится автоматически по услуге
|
||
service_id bigint REFERENCES services (id) ON DELETE CASCADE,
|
||
icon text NOT NULL DEFAULT '',
|
||
wide boolean NOT NULL DEFAULT false, -- пункт раскрывается мегаменю
|
||
sort int NOT NULL DEFAULT 100,
|
||
published boolean NOT NULL DEFAULT true
|
||
);
|
||
|
||
CREATE INDEX menu_items_menu_idx ON menu_items (menu, parent_id, sort);
|
||
|
||
-- Произвольные страницы: о клинике, юридические документы, главная.
|
||
CREATE TABLE pages (
|
||
id bigserial PRIMARY KEY,
|
||
slug text NOT NULL UNIQUE,
|
||
title text NOT NULL,
|
||
blocks jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||
published boolean NOT NULL DEFAULT true,
|
||
seo_title text NOT NULL DEFAULT '',
|
||
seo_description text NOT NULL DEFAULT '',
|
||
seo_h1 text NOT NULL DEFAULT '',
|
||
created_at timestamptz NOT NULL DEFAULT now(),
|
||
updated_at timestamptz NOT NULL DEFAULT now()
|
||
);
|