initial site
This commit is contained in:
commit
da5b259d06
167 files changed
+34157
No files matched your search
@@ -0,0 +1,84 @@
|
||||
-- -*- coding: utf-8 -*-
|
||||
-- ============================================================================
|
||||
-- НЕОН CRM — доски заметок/задач (общая + приватные «владелец ↔ админ»).
|
||||
--
|
||||
-- Идемпотентна: повторный запуск не падает и не меняет данные.
|
||||
-- CRM применяет этот же DDL автоматически при старте (SCHEMA в storage.py,
|
||||
-- сид общей доски — boards_seed_shared()); файл нужен для ручного применения
|
||||
-- и как канонический список объектов.
|
||||
--
|
||||
-- Применить вручную:
|
||||
-- docker compose exec -T db psql -U neon -d neon_crm \
|
||||
-- -v ON_ERROR_STOP=1 < crm/migrate/notes_boards.sql
|
||||
--
|
||||
-- Откат (теряются все заметки и история!):
|
||||
-- docker compose exec -T db psql -U neon -d neon_crm \
|
||||
-- -c "DROP TABLE IF EXISTS note_activity, notes, board_members, boards CASCADE"
|
||||
--
|
||||
-- Отступление от исходного ТЗ: пользователи в этой базе — crm_users с текстовым
|
||||
-- PK login (целочисленного users.id не существует), поэтому все ссылки идут
|
||||
-- на crm_users(login).
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS boards (
|
||||
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
kind TEXT NOT NULL CHECK (kind IN ('shared', 'private')),
|
||||
title TEXT NOT NULL,
|
||||
created_by_login TEXT NOT NULL REFERENCES crm_users(login),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- участники приватных досок; для kind='shared' не используется —
|
||||
-- общая доска доступна всем ролям без проверки
|
||||
CREATE TABLE IF NOT EXISTS board_members (
|
||||
board_id INTEGER NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
||||
user_login TEXT NOT NULL REFERENCES crm_users(login) ON DELETE CASCADE,
|
||||
PRIMARY KEY (board_id, user_login)
|
||||
);
|
||||
|
||||
-- заметка = задача: заголовок, текст, исполнитель, срок, «важно», статус.
|
||||
-- К сменам не привязана — доступна в любое время по факту логина.
|
||||
-- Логины автора/исполнителя без FK (как orders.waiter в storage.py):
|
||||
-- удаление сотрудника не должно ломать его задачи.
|
||||
CREATE TABLE IF NOT EXISTS notes (
|
||||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
board_id INTEGER NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
||||
author_login TEXT NOT NULL,
|
||||
assignee_login TEXT,
|
||||
title TEXT NOT NULL,
|
||||
body TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'in_progress', 'done')),
|
||||
important BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
due_date DATE,
|
||||
done_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_notes_board ON notes (board_id, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_notes_assignee ON notes (assignee_login) WHERE status <> 'done';
|
||||
|
||||
-- журнал действий: created/status/assigned/edited/deleted/board_created.
|
||||
-- details: для assigned — логин исполнителя, для deleted — id заметки.
|
||||
-- note_id REFERENCES ... ON DELETE SET NULL: сама запись переживает удаление
|
||||
-- заметки, id удалённой сохраняется в details (для синхронизации клиентов).
|
||||
-- user_login без FK — журнал переживает удаление сотрудника.
|
||||
CREATE TABLE IF NOT EXISTS note_activity (
|
||||
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||
board_id INTEGER NOT NULL REFERENCES boards(id) ON DELETE CASCADE,
|
||||
note_id BIGINT REFERENCES notes(id) ON DELETE SET NULL,
|
||||
user_login TEXT NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
details TEXT NOT NULL DEFAULT '',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- одна общая доска на базу; владелец = первый по логину owner (база после
|
||||
-- seed CRM уже содержит учётки). Повторный запуск ничего не добавляет.
|
||||
INSERT INTO boards (kind, title, created_by_login)
|
||||
SELECT 'shared', 'Общая', u.login
|
||||
FROM crm_users u
|
||||
WHERE u.role = 'owner'
|
||||
AND NOT EXISTS (SELECT 1 FROM boards WHERE kind = 'shared')
|
||||
ORDER BY u.login
|
||||
LIMIT 1;
|
||||
Reference in new issue
Block a user