151 lines
6.4 KiB
SQL
151 lines
6.4 KiB
SQL
-- MedSchedule — семейное медицинское расписание
|
|
|
|
CREATE TABLE IF NOT EXISTS med_family_groups (
|
|
id SERIAL PRIMARY KEY,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
invite_code TEXT NOT NULL UNIQUE,
|
|
created_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_family_groups_org_idx ON med_family_groups(organization_id);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS med_family_groups_invite_idx ON med_family_groups(invite_code);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_family_members (
|
|
id SERIAL PRIMARY KEY,
|
|
family_id INTEGER NOT NULL REFERENCES med_family_groups(id) ON DELETE CASCADE,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
|
profile_name TEXT NOT NULL,
|
|
profile_type TEXT NOT NULL DEFAULT 'person',
|
|
date_of_birth DATE,
|
|
gender TEXT,
|
|
notes TEXT,
|
|
telegram_chat_id TEXT,
|
|
max_chat_id TEXT,
|
|
role TEXT NOT NULL DEFAULT 'member',
|
|
created_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_family_members_family_idx ON med_family_members(family_id);
|
|
CREATE INDEX IF NOT EXISTS med_family_members_user_idx ON med_family_members(user_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_medications (
|
|
id SERIAL PRIMARY KEY,
|
|
family_id INTEGER NOT NULL REFERENCES med_family_groups(id) ON DELETE CASCADE,
|
|
member_id INTEGER NOT NULL REFERENCES med_family_members(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
dosage TEXT,
|
|
form TEXT,
|
|
schedule JSONB NOT NULL,
|
|
instructions TEXT,
|
|
color TEXT DEFAULT '#4CAF50',
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
created_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_medications_family_idx ON med_medications(family_id);
|
|
CREATE INDEX IF NOT EXISTS med_medications_member_idx ON med_medications(member_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_intake_logs (
|
|
id SERIAL PRIMARY KEY,
|
|
medication_id INTEGER NOT NULL REFERENCES med_medications(id) ON DELETE CASCADE,
|
|
member_id INTEGER NOT NULL REFERENCES med_family_members(id) ON DELETE CASCADE,
|
|
scheduled_at TIMESTAMP NOT NULL,
|
|
taken_at TIMESTAMP,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
note TEXT,
|
|
reminded_via TEXT[] DEFAULT '{}',
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_intake_logs_medication_idx ON med_intake_logs(medication_id);
|
|
CREATE INDEX IF NOT EXISTS med_intake_logs_member_idx ON med_intake_logs(member_id);
|
|
CREATE INDEX IF NOT EXISTS med_intake_logs_scheduled_idx ON med_intake_logs(scheduled_at);
|
|
CREATE INDEX IF NOT EXISTS med_intake_logs_status_idx ON med_intake_logs(status);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_cabinet_items (
|
|
id SERIAL PRIMARY KEY,
|
|
family_id INTEGER NOT NULL REFERENCES med_family_groups(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
form TEXT,
|
|
dosage TEXT,
|
|
quantity REAL DEFAULT 0,
|
|
unit TEXT DEFAULT 'шт',
|
|
expiry_date DATE,
|
|
indication TEXT,
|
|
location TEXT,
|
|
photo_url TEXT,
|
|
added_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_cabinet_items_family_idx ON med_cabinet_items(family_id);
|
|
CREATE INDEX IF NOT EXISTS med_cabinet_items_expiry_idx ON med_cabinet_items(expiry_date);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_cabinet_stock (
|
|
id SERIAL PRIMARY KEY,
|
|
cabinet_item_id INTEGER NOT NULL REFERENCES med_cabinet_items(id) ON DELETE CASCADE,
|
|
change REAL NOT NULL,
|
|
reason TEXT,
|
|
note TEXT,
|
|
changed_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_cabinet_stock_item_idx ON med_cabinet_stock(cabinet_item_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_medical_records (
|
|
id SERIAL PRIMARY KEY,
|
|
family_id INTEGER NOT NULL REFERENCES med_family_groups(id) ON DELETE CASCADE,
|
|
member_id INTEGER NOT NULL REFERENCES med_family_members(id) ON DELETE CASCADE,
|
|
title TEXT NOT NULL,
|
|
record_type TEXT NOT NULL,
|
|
record_date DATE,
|
|
doctor_name TEXT,
|
|
clinic_name TEXT,
|
|
raw_text TEXT,
|
|
ai_summary TEXT,
|
|
ai_findings JSONB,
|
|
file_urls TEXT[] DEFAULT '{}',
|
|
added_by INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_medical_records_family_idx ON med_medical_records(family_id);
|
|
CREATE INDEX IF NOT EXISTS med_medical_records_member_idx ON med_medical_records(member_id);
|
|
CREATE INDEX IF NOT EXISTS med_medical_records_date_idx ON med_medical_records(record_date);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_daily_checkins (
|
|
id SERIAL PRIMARY KEY,
|
|
family_id INTEGER NOT NULL REFERENCES med_family_groups(id) ON DELETE CASCADE,
|
|
member_id INTEGER REFERENCES med_family_members(id) ON DELETE CASCADE,
|
|
check_in_date DATE NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
question TEXT NOT NULL,
|
|
answer_text TEXT,
|
|
ai_summary TEXT,
|
|
ai_alert TEXT,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS med_daily_checkins_family_idx ON med_daily_checkins(family_id);
|
|
CREATE INDEX IF NOT EXISTS med_daily_checkins_member_idx ON med_daily_checkins(member_id);
|
|
CREATE INDEX IF NOT EXISTS med_daily_checkins_date_idx ON med_daily_checkins(check_in_date);
|
|
|
|
CREATE TABLE IF NOT EXISTS med_bot_bindings (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
organization_id INTEGER NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
telegram_chat_id TEXT,
|
|
max_chat_id TEXT,
|
|
telegram_username TEXT,
|
|
max_username TEXT,
|
|
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
|
);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS med_bot_bindings_user_org_idx ON med_bot_bindings(user_id, organization_id);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS med_bot_bindings_telegram_idx ON med_bot_bindings(organization_id, telegram_chat_id) WHERE telegram_chat_id IS NOT NULL;
|
|
CREATE UNIQUE INDEX IF NOT EXISTS med_bot_bindings_max_idx ON med_bot_bindings(organization_id, max_chat_id) WHERE max_chat_id IS NOT NULL;
|