mirror of
https://github.com/TronoSfera/Law.git
synced 2026-05-18 10:03:45 +03:00
fix speed up 05
This commit is contained in:
parent
2b7043a89e
commit
c686d304c3
11 changed files with 120 additions and 11 deletions
50
alembic/versions/0036_add_message_author_admin_user_id.py
Normal file
50
alembic/versions/0036_add_message_author_admin_user_id.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
"""add author admin user id to messages
|
||||||
|
|
||||||
|
Revision ID: 0036_message_author_admin_id
|
||||||
|
Revises: 0035_workspace_perf_indexes
|
||||||
|
Create Date: 2026-03-17
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
|
||||||
|
revision = "0036_message_author_admin_id"
|
||||||
|
down_revision = "0035_workspace_perf_indexes"
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def _has_column(inspector: sa.Inspector, table: str, column_name: str) -> bool:
|
||||||
|
return any(str(column.get("name")) == column_name for column in inspector.get_columns(table))
|
||||||
|
|
||||||
|
|
||||||
|
def _has_index(inspector: sa.Inspector, table: str, index_name: str) -> bool:
|
||||||
|
return any(str(index.get("name")) == index_name for index in inspector.get_indexes(table))
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
bind = op.get_bind()
|
||||||
|
inspector = sa.inspect(bind)
|
||||||
|
|
||||||
|
if not _has_column(inspector, "messages", "author_admin_user_id"):
|
||||||
|
op.add_column("messages", sa.Column("author_admin_user_id", postgresql.UUID(as_uuid=True), nullable=True))
|
||||||
|
|
||||||
|
inspector = sa.inspect(bind)
|
||||||
|
if not _has_index(inspector, "messages", "ix_messages_author_admin_user_id"):
|
||||||
|
op.create_index("ix_messages_author_admin_user_id", "messages", ["author_admin_user_id"], unique=False)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
bind = op.get_bind()
|
||||||
|
inspector = sa.inspect(bind)
|
||||||
|
|
||||||
|
if _has_index(inspector, "messages", "ix_messages_author_admin_user_id"):
|
||||||
|
op.drop_index("ix_messages_author_admin_user_id", table_name="messages")
|
||||||
|
|
||||||
|
inspector = sa.inspect(bind)
|
||||||
|
if _has_column(inspector, "messages", "author_admin_user_id"):
|
||||||
|
op.drop_column("messages", "author_admin_user_id")
|
||||||
|
|
@ -16,6 +16,7 @@ class Message(Base, UUIDMixin, TimestampMixin):
|
||||||
)
|
)
|
||||||
request_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), index=True, nullable=False)
|
request_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), index=True, nullable=False)
|
||||||
author_type: Mapped[str] = mapped_column(String(20), nullable=False) # CLIENT|LAWYER|SYSTEM
|
author_type: Mapped[str] = mapped_column(String(20), nullable=False) # CLIENT|LAWYER|SYSTEM
|
||||||
|
author_admin_user_id: Mapped[uuid.UUID | None] = mapped_column(UUID(as_uuid=True), nullable=True, index=True)
|
||||||
author_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
author_name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||||
body: Mapped[str | None] = mapped_column(Text, nullable=True)
|
body: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||||
immutable: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
immutable: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,7 @@ def serialize_message(row: Message, *, body: str | None = None, body_loaded: boo
|
||||||
"id": str(row.id),
|
"id": str(row.id),
|
||||||
"request_id": str(row.request_id),
|
"request_id": str(row.request_id),
|
||||||
"author_type": row.author_type,
|
"author_type": row.author_type,
|
||||||
|
"author_admin_user_id": str(row.author_admin_user_id) if row.author_admin_user_id else None,
|
||||||
"author_name": row.author_name,
|
"author_name": row.author_name,
|
||||||
"body": body,
|
"body": body,
|
||||||
"body_loaded": bool(body_loaded),
|
"body_loaded": bool(body_loaded),
|
||||||
|
|
@ -281,6 +282,16 @@ def _normalize_admin_uuid(value: str | None) -> str | None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_admin_uuid_value(value: str | None) -> uuid.UUID | None:
|
||||||
|
normalized = _normalize_admin_uuid(value)
|
||||||
|
if not normalized:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return uuid.UUID(normalized)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _register_chat_participant(request: Request, admin_user_id: str | None) -> None:
|
def _register_chat_participant(request: Request, admin_user_id: str | None) -> None:
|
||||||
normalized = _normalize_admin_uuid(admin_user_id)
|
normalized = _normalize_admin_uuid(admin_user_id)
|
||||||
if not normalized:
|
if not normalized:
|
||||||
|
|
@ -525,6 +536,7 @@ def create_admin_or_lawyer_message(
|
||||||
row = Message(
|
row = Message(
|
||||||
request_id=request.id,
|
request_id=request.id,
|
||||||
author_type=author_type,
|
author_type=author_type,
|
||||||
|
author_admin_user_id=_normalize_admin_uuid_value(actor_admin_user_id),
|
||||||
author_name=str(actor_name or "").strip() or author_type,
|
author_name=str(actor_name or "").strip() or author_type,
|
||||||
body=message_body,
|
body=message_body,
|
||||||
responsible=responsible,
|
responsible=responsible,
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Административная панель • Правовой трекер</title>
|
<title>Административная панель • Правовой трекер</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=20260302-01">
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=20260302-01">
|
||||||
<link rel="stylesheet" href="/admin.css?v=20260303-05">
|
<link rel="stylesheet" href="/admin.css?v=20260317-01">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="admin-root"></div>
|
<div id="admin-root"></div>
|
||||||
<script src="/vendor/react.production.min.js"></script>
|
<script src="/vendor/react.production.min.js"></script>
|
||||||
<script src="/vendor/react-dom.production.min.js"></script>
|
<script src="/vendor/react-dom.production.min.js"></script>
|
||||||
<script src="/admin.js?v=20260303-05"></script>
|
<script src="/admin.js?v=20260317-01"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -3688,6 +3688,8 @@
|
||||||
function RequestWorkspace({
|
function RequestWorkspace({
|
||||||
viewerRole,
|
viewerRole,
|
||||||
viewerUserId,
|
viewerUserId,
|
||||||
|
viewerUserEmail,
|
||||||
|
viewerUserName,
|
||||||
loading,
|
loading,
|
||||||
trackNumber,
|
trackNumber,
|
||||||
requestData,
|
requestData,
|
||||||
|
|
@ -4848,7 +4850,17 @@
|
||||||
const authorType = String(payload?.author_type || "").trim().toUpperCase();
|
const authorType = String(payload?.author_type || "").trim().toUpperCase();
|
||||||
if (!authorType) return false;
|
if (!authorType) return false;
|
||||||
if (viewerRoleCode === "CLIENT") return authorType === "CLIENT";
|
if (viewerRoleCode === "CLIENT") return authorType === "CLIENT";
|
||||||
return authorType !== "CLIENT";
|
if (authorType === "CLIENT") return false;
|
||||||
|
const authorAdminUserId = String(payload?.author_admin_user_id || "").trim();
|
||||||
|
const currentViewerUserId = String(viewerUserId || "").trim();
|
||||||
|
if (authorAdminUserId && currentViewerUserId) return authorAdminUserId === currentViewerUserId;
|
||||||
|
const authorName = String(payload?.author_name || "").trim().toLowerCase();
|
||||||
|
const viewerName = String(viewerUserName || "").trim().toLowerCase();
|
||||||
|
const viewerEmail = String(viewerUserEmail || "").trim().toLowerCase();
|
||||||
|
if (authorName && (viewerName && authorName === viewerName || viewerEmail && authorName === viewerEmail)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !viewerName && !viewerEmail ? authorType !== "CLIENT" : false;
|
||||||
};
|
};
|
||||||
const renderMessageMeta = (payload) => {
|
const renderMessageMeta = (payload) => {
|
||||||
const timeLabel = fmtTimeOnly(payload?.created_at);
|
const timeLabel = fmtTimeOnly(payload?.created_at);
|
||||||
|
|
@ -5108,7 +5120,8 @@
|
||||||
const serviceMessageContent = resolveServiceMessageContent(entry.payload);
|
const serviceMessageContent = resolveServiceMessageContent(entry.payload);
|
||||||
const requestDataInteractive = isRequestDataMessage && (canRequestData || canFillRequestData);
|
const requestDataInteractive = isRequestDataMessage && (canRequestData || canFillRequestData);
|
||||||
const bubbleClass = "chat-message-bubble" + (isRequestDataMessage ? " chat-request-data-bubble" : "") + (entry.payload?.request_data_all_filled ? " all-filled" : "") + (isRequestDataMessage && canFillRequestData ? " request-data-message-btn" : "");
|
const bubbleClass = "chat-message-bubble" + (isRequestDataMessage ? " chat-request-data-bubble" : "") + (entry.payload?.request_data_all_filled ? " all-filled" : "") + (isRequestDataMessage && canFillRequestData ? " request-data-message-btn" : "");
|
||||||
const itemClass = "chat-message " + (String(entry.payload?.author_type || "").toUpperCase() === "CLIENT" ? "incoming" : "outgoing") + (isRequestDataMessage && canFillRequestData ? " request-data-item" + (entry.payload?.request_data_all_filled ? " done" : "") : "");
|
const isOutgoing = isOutgoingForViewer(entry.payload);
|
||||||
|
const itemClass = "chat-message " + (isOutgoing ? "outgoing" : "incoming") + (isRequestDataMessage && canFillRequestData ? " request-data-item" + (entry.payload?.request_data_all_filled ? " done" : "") : "");
|
||||||
return /* @__PURE__ */ React.createElement("li", { key: entry.key, className: itemClass }, /* @__PURE__ */ React.createElement("div", { className: "chat-message-author" }, String(entry.payload?.author_name || entry.payload?.author_type || "\u0421\u0438\u0441\u0442\u0435\u043C\u0430")), /* @__PURE__ */ React.createElement(
|
return /* @__PURE__ */ React.createElement("li", { key: entry.key, className: itemClass }, /* @__PURE__ */ React.createElement("div", { className: "chat-message-author" }, String(entry.payload?.author_name || entry.payload?.author_type || "\u0421\u0438\u0441\u0442\u0435\u043C\u0430")), /* @__PURE__ */ React.createElement(
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
|
|
@ -10210,6 +10223,8 @@
|
||||||
{
|
{
|
||||||
viewerRole: role,
|
viewerRole: role,
|
||||||
viewerUserId: userId,
|
viewerUserId: userId,
|
||||||
|
viewerUserEmail: email,
|
||||||
|
viewerUserName: dictionaries.users?.find((item) => String(item?.id || "") === String(userId || ""))?.name || "",
|
||||||
loading: requestModal.loading,
|
loading: requestModal.loading,
|
||||||
trackNumber: requestModal.trackNumber,
|
trackNumber: requestModal.trackNumber,
|
||||||
requestData: requestModal.requestData,
|
requestData: requestModal.requestData,
|
||||||
|
|
|
||||||
|
|
@ -3999,6 +3999,8 @@ const NEW_REQUEST_CLIENT_OPTION = "__new_client__";
|
||||||
<RequestWorkspace
|
<RequestWorkspace
|
||||||
viewerRole={role}
|
viewerRole={role}
|
||||||
viewerUserId={userId}
|
viewerUserId={userId}
|
||||||
|
viewerUserEmail={email}
|
||||||
|
viewerUserName={dictionaries.users?.find((item) => String(item?.id || "") === String(userId || ""))?.name || ""}
|
||||||
loading={requestModal.loading}
|
loading={requestModal.loading}
|
||||||
trackNumber={requestModal.trackNumber}
|
trackNumber={requestModal.trackNumber}
|
||||||
requestData={requestModal.requestData}
|
requestData={requestModal.requestData}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import {
|
||||||
export function RequestWorkspace({
|
export function RequestWorkspace({
|
||||||
viewerRole,
|
viewerRole,
|
||||||
viewerUserId,
|
viewerUserId,
|
||||||
|
viewerUserEmail,
|
||||||
|
viewerUserName,
|
||||||
loading,
|
loading,
|
||||||
trackNumber,
|
trackNumber,
|
||||||
requestData,
|
requestData,
|
||||||
|
|
@ -1297,7 +1299,17 @@ export function RequestWorkspace({
|
||||||
const authorType = String(payload?.author_type || "").trim().toUpperCase();
|
const authorType = String(payload?.author_type || "").trim().toUpperCase();
|
||||||
if (!authorType) return false;
|
if (!authorType) return false;
|
||||||
if (viewerRoleCode === "CLIENT") return authorType === "CLIENT";
|
if (viewerRoleCode === "CLIENT") return authorType === "CLIENT";
|
||||||
return authorType !== "CLIENT";
|
if (authorType === "CLIENT") return false;
|
||||||
|
const authorAdminUserId = String(payload?.author_admin_user_id || "").trim();
|
||||||
|
const currentViewerUserId = String(viewerUserId || "").trim();
|
||||||
|
if (authorAdminUserId && currentViewerUserId) return authorAdminUserId === currentViewerUserId;
|
||||||
|
const authorName = String(payload?.author_name || "").trim().toLowerCase();
|
||||||
|
const viewerName = String(viewerUserName || "").trim().toLowerCase();
|
||||||
|
const viewerEmail = String(viewerUserEmail || "").trim().toLowerCase();
|
||||||
|
if (authorName && ((viewerName && authorName === viewerName) || (viewerEmail && authorName === viewerEmail))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !viewerName && !viewerEmail ? authorType !== "CLIENT" : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderMessageMeta = (payload) => {
|
const renderMessageMeta = (payload) => {
|
||||||
|
|
@ -1719,9 +1731,10 @@ export function RequestWorkspace({
|
||||||
(isRequestDataMessage ? " chat-request-data-bubble" : "") +
|
(isRequestDataMessage ? " chat-request-data-bubble" : "") +
|
||||||
(entry.payload?.request_data_all_filled ? " all-filled" : "") +
|
(entry.payload?.request_data_all_filled ? " all-filled" : "") +
|
||||||
(isRequestDataMessage && canFillRequestData ? " request-data-message-btn" : "");
|
(isRequestDataMessage && canFillRequestData ? " request-data-message-btn" : "");
|
||||||
|
const isOutgoing = isOutgoingForViewer(entry.payload);
|
||||||
const itemClass =
|
const itemClass =
|
||||||
"chat-message " +
|
"chat-message " +
|
||||||
(String(entry.payload?.author_type || "").toUpperCase() === "CLIENT" ? "incoming" : "outgoing") +
|
(isOutgoing ? "outgoing" : "incoming") +
|
||||||
(isRequestDataMessage && canFillRequestData ? " request-data-item" + (entry.payload?.request_data_all_filled ? " done" : "") : "");
|
(isRequestDataMessage && canFillRequestData ? " request-data-item" + (entry.payload?.request_data_all_filled ? " done" : "") : "");
|
||||||
return (
|
return (
|
||||||
<li key={entry.key} className={itemClass}>
|
<li key={entry.key} className={itemClass}>
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Страница клиента • Правовой трекер</title>
|
<title>Страница клиента • Правовой трекер</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=20260302-01">
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=20260302-01">
|
||||||
<link rel="stylesheet" href="/admin.css?v=20260303-05">
|
<link rel="stylesheet" href="/admin.css?v=20260317-01">
|
||||||
<link rel="stylesheet" href="/client.css">
|
<link rel="stylesheet" href="/client.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="client-root"></div>
|
<div id="client-root"></div>
|
||||||
<script src="/vendor/react.production.min.js"></script>
|
<script src="/vendor/react.production.min.js"></script>
|
||||||
<script src="/vendor/react-dom.production.min.js"></script>
|
<script src="/vendor/react-dom.production.min.js"></script>
|
||||||
<script src="/client.js?v=20260303-05"></script>
|
<script src="/client.js?v=20260317-01"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,8 @@
|
||||||
function RequestWorkspace({
|
function RequestWorkspace({
|
||||||
viewerRole,
|
viewerRole,
|
||||||
viewerUserId,
|
viewerUserId,
|
||||||
|
viewerUserEmail,
|
||||||
|
viewerUserName,
|
||||||
loading,
|
loading,
|
||||||
trackNumber,
|
trackNumber,
|
||||||
requestData,
|
requestData,
|
||||||
|
|
@ -1348,7 +1350,14 @@
|
||||||
const authorType = String(payload?.author_type || "").trim().toUpperCase();
|
const authorType = String(payload?.author_type || "").trim().toUpperCase();
|
||||||
if (!authorType) return false;
|
if (!authorType) return false;
|
||||||
if (viewerRoleCode === "CLIENT") return authorType === "CLIENT";
|
if (viewerRoleCode === "CLIENT") return authorType === "CLIENT";
|
||||||
return authorType !== "CLIENT";
|
if (authorType === "CLIENT") return false;
|
||||||
|
const authorName = String(payload?.author_name || "").trim().toLowerCase();
|
||||||
|
const viewerName = String(viewerUserName || "").trim().toLowerCase();
|
||||||
|
const viewerEmail = String(viewerUserEmail || "").trim().toLowerCase();
|
||||||
|
if (authorName && (viewerName && authorName === viewerName || viewerEmail && authorName === viewerEmail)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !viewerName && !viewerEmail ? authorType !== "CLIENT" : false;
|
||||||
};
|
};
|
||||||
const renderMessageMeta = (payload) => {
|
const renderMessageMeta = (payload) => {
|
||||||
const timeLabel = fmtTimeOnly(payload?.created_at);
|
const timeLabel = fmtTimeOnly(payload?.created_at);
|
||||||
|
|
@ -1608,7 +1617,8 @@
|
||||||
const serviceMessageContent = resolveServiceMessageContent(entry.payload);
|
const serviceMessageContent = resolveServiceMessageContent(entry.payload);
|
||||||
const requestDataInteractive = isRequestDataMessage && (canRequestData || canFillRequestData);
|
const requestDataInteractive = isRequestDataMessage && (canRequestData || canFillRequestData);
|
||||||
const bubbleClass = "chat-message-bubble" + (isRequestDataMessage ? " chat-request-data-bubble" : "") + (entry.payload?.request_data_all_filled ? " all-filled" : "") + (isRequestDataMessage && canFillRequestData ? " request-data-message-btn" : "");
|
const bubbleClass = "chat-message-bubble" + (isRequestDataMessage ? " chat-request-data-bubble" : "") + (entry.payload?.request_data_all_filled ? " all-filled" : "") + (isRequestDataMessage && canFillRequestData ? " request-data-message-btn" : "");
|
||||||
const itemClass = "chat-message " + (String(entry.payload?.author_type || "").toUpperCase() === "CLIENT" ? "incoming" : "outgoing") + (isRequestDataMessage && canFillRequestData ? " request-data-item" + (entry.payload?.request_data_all_filled ? " done" : "") : "");
|
const isOutgoing = isOutgoingForViewer(entry.payload);
|
||||||
|
const itemClass = "chat-message " + (isOutgoing ? "outgoing" : "incoming") + (isRequestDataMessage && canFillRequestData ? " request-data-item" + (entry.payload?.request_data_all_filled ? " done" : "") : "");
|
||||||
return /* @__PURE__ */ React.createElement("li", { key: entry.key, className: itemClass }, /* @__PURE__ */ React.createElement("div", { className: "chat-message-author" }, String(entry.payload?.author_name || entry.payload?.author_type || "\u0421\u0438\u0441\u0442\u0435\u043C\u0430")), /* @__PURE__ */ React.createElement(
|
return /* @__PURE__ */ React.createElement("li", { key: entry.key, className: itemClass }, /* @__PURE__ */ React.createElement("div", { className: "chat-message-author" }, String(entry.payload?.author_name || entry.payload?.author_type || "\u0421\u0438\u0441\u0442\u0435\u043C\u0430")), /* @__PURE__ */ React.createElement(
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -552,6 +552,7 @@ class AdminLawyerChatTests(AdminUniversalCrudBase):
|
||||||
)
|
)
|
||||||
self.assertEqual(own_create.status_code, 201)
|
self.assertEqual(own_create.status_code, 201)
|
||||||
self.assertEqual(own_create.json()["author_type"], "LAWYER")
|
self.assertEqual(own_create.json()["author_type"], "LAWYER")
|
||||||
|
self.assertEqual(own_create.json().get("author_admin_user_id"), self_id)
|
||||||
|
|
||||||
unassigned_create = self.chat_client.post(
|
unassigned_create = self.chat_client.post(
|
||||||
f"/api/admin/chat/requests/{unassigned_id}/messages",
|
f"/api/admin/chat/requests/{unassigned_id}/messages",
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ class MigrationTests(unittest.TestCase):
|
||||||
def test_alembic_version_is_set(self):
|
def test_alembic_version_is_set(self):
|
||||||
with self.engine.connect() as conn:
|
with self.engine.connect() as conn:
|
||||||
version = conn.execute(text("SELECT version_num FROM alembic_version")).scalar_one()
|
version = conn.execute(text("SELECT version_num FROM alembic_version")).scalar_one()
|
||||||
self.assertEqual(version, "0035_workspace_perf_indexes")
|
self.assertEqual(version, "0036_message_author_admin_id")
|
||||||
|
|
||||||
def test_responsible_column_exists_in_all_domain_tables(self):
|
def test_responsible_column_exists_in_all_domain_tables(self):
|
||||||
tables = {
|
tables = {
|
||||||
|
|
@ -214,9 +214,14 @@ class MigrationTests(unittest.TestCase):
|
||||||
attachment_indexes = {index["name"] for index in self.inspector.get_indexes("attachments")}
|
attachment_indexes = {index["name"] for index in self.inspector.get_indexes("attachments")}
|
||||||
invoice_indexes = {index["name"] for index in self.inspector.get_indexes("invoices")}
|
invoice_indexes = {index["name"] for index in self.inspector.get_indexes("invoices")}
|
||||||
self.assertIn("ix_messages_request_created_id", message_indexes)
|
self.assertIn("ix_messages_request_created_id", message_indexes)
|
||||||
|
self.assertIn("ix_messages_author_admin_user_id", message_indexes)
|
||||||
self.assertIn("ix_attachments_request_created_id", attachment_indexes)
|
self.assertIn("ix_attachments_request_created_id", attachment_indexes)
|
||||||
self.assertIn("ix_invoices_request_issued_id", invoice_indexes)
|
self.assertIn("ix_invoices_request_issued_id", invoice_indexes)
|
||||||
|
|
||||||
|
def test_messages_contains_author_admin_user_id_column(self):
|
||||||
|
columns = {column["name"] for column in self.inspector.get_columns("messages")}
|
||||||
|
self.assertIn("author_admin_user_id", columns)
|
||||||
|
|
||||||
def test_data_retention_policies_contains_core_columns(self):
|
def test_data_retention_policies_contains_core_columns(self):
|
||||||
columns = {column["name"] for column in self.inspector.get_columns("data_retention_policies")}
|
columns = {column["name"] for column in self.inspector.get_columns("data_retention_policies")}
|
||||||
self.assertIn("id", columns)
|
self.assertIn("id", columns)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue