Files
iistwin/migrations/0059_medschedule_tables.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;